diff --git a/src/cc/Httpd.cpp b/src/cc/Httpd.cpp index f222b10a..887c6261 100644 --- a/src/cc/Httpd.cpp +++ b/src/cc/Httpd.cpp @@ -93,28 +93,29 @@ std::string Httpd::readFile(const std::string &fileName) return data.str(); } -unsigned Httpd::tokenAuth(struct MHD_Connection* connection) +unsigned Httpd::tokenAuth(struct MHD_Connection* connection, const std::string& clientIp) { if (!m_options->ccToken()) { - LOG_WARN("AccessToken not set. Access Granted!"); + LOG_WARN("[%s] AccessToken not set. Access Granted!", clientIp.c_str()); return MHD_HTTP_OK; } const char* header = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, MHD_HTTP_HEADER_AUTHORIZATION); if (m_options->ccToken() && !header) { + LOG_WARN("[%s] No auth header. Access Forbidden!", clientIp.c_str()); return MHD_HTTP_UNAUTHORIZED; } const size_t size = strlen(header); if (size < 8 || strlen(m_options->ccToken()) != size - 7 || memcmp("Bearer ", header, 7) != 0) { - LOG_WARN("AccessToken wrong. Access Forbidden!"); + LOG_ERR("[%s] AccessToken wrong. Access Forbidden!", clientIp.c_str()); return MHD_HTTP_FORBIDDEN; } return strncmp(m_options->ccToken(), header + 7, strlen(m_options->ccToken())) == 0 ? MHD_HTTP_OK : MHD_HTTP_FORBIDDEN; } -unsigned Httpd::basicAuth(struct MHD_Connection* connection, std::string& resp) +unsigned Httpd::basicAuth(struct MHD_Connection* connection, const std::string& clientIp, std::string& resp) { unsigned result = MHD_HTTP_OK; @@ -123,7 +124,7 @@ unsigned Httpd::basicAuth(struct MHD_Connection* connection, std::string& resp) "Please configure admin user and pass to view this Page." ""); - LOG_WARN("Admin user/password not set. Access Forbidden!"); + LOG_WARN("[%s] Admin user/password not set. Access Forbidden!", clientIp.c_str()); result = MHD_HTTP_FORBIDDEN; } else { @@ -136,7 +137,7 @@ unsigned Httpd::basicAuth(struct MHD_Connection* connection, std::string& resp) if (user == nullptr || strcmp(user, m_options->ccAdminUser()) != 0 || pass == nullptr || strcmp(pass, m_options->ccAdminPass()) != 0) { - LOG_WARN("Admin user/password wrong. Access Unauthorized!"); + LOG_ERR("[%s] Admin user/password wrong. Access Forbidden!", clientIp.c_str()); result = MHD_HTTP_UNAUTHORIZED; } @@ -148,6 +149,7 @@ unsigned Httpd::basicAuth(struct MHD_Connection* connection, std::string& resp) free(pass); } } else { + LOG_WARN("[%s] No auth header. Access Forbidden!", clientIp.c_str()); result = MHD_HTTP_UNAUTHORIZED; } } @@ -179,24 +181,36 @@ int Httpd::sendResponse(MHD_Connection* connection, unsigned status, MHD_Respons int Httpd::handler(void* httpd, MHD_Connection* connection, const char* url, const char* method, const char* version, const char* upload_data, size_t* upload_data_size, void** con_cls) { + std::string clientIp; + const MHD_ConnectionInfo *info = MHD_get_connection_info(connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS); + if (info) { + char clientHost[NI_MAXHOST]; + int ec = getnameinfo(info->client_addr, sizeof(*info->client_addr), clientHost, sizeof(clientHost), + 0, 0, NI_NUMERICHOST|NI_NUMERICSERV); + + if (ec == 0) { + clientIp = std::string(clientHost); + } + } + if (strcmp(method, MHD_HTTP_METHOD_OPTIONS) == 0) { - LOG_INFO("OPTIONS Requested"); + LOG_INFO("[%s] OPTIONS Requested", clientIp.c_str()); return sendResponse(connection, MHD_HTTP_OK, nullptr, CONTENT_TYPE_HTML); } if (strcmp(method, MHD_HTTP_METHOD_GET) != 0 && strcmp(method, MHD_HTTP_METHOD_POST) != 0) { - LOG_ERR("HTTP_METHOD_NOT_ALLOWED"); + LOG_ERR("[%s] HTTP_METHOD_NOT_ALLOWED (%s)", clientIp.c_str(), method); return sendResponse(connection, MHD_HTTP_METHOD_NOT_ALLOWED, nullptr, CONTENT_TYPE_HTML); } if (strstr(url, "/client/")) { - unsigned status = static_cast(httpd)->tokenAuth(connection); + unsigned status = static_cast(httpd)->tokenAuth(connection, clientIp); if (status != MHD_HTTP_OK) { return sendResponse(connection, status, nullptr, CONTENT_TYPE_JSON); } } else { std::string resp; - unsigned status = static_cast(httpd)->basicAuth(connection, resp); + unsigned status = static_cast(httpd)->basicAuth(connection, clientIp, resp); if (status != MHD_HTTP_OK) { MHD_Response* rsp = nullptr; if (!resp.empty()) { @@ -207,15 +221,15 @@ int Httpd::handler(void* httpd, MHD_Connection* connection, const char* url, con } if (strcmp(method, MHD_HTTP_METHOD_GET) == 0) { - return handleGET(static_cast(httpd), connection, url); + return handleGET(static_cast(httpd), connection, clientIp, url); } else { - return handlePOST(static_cast(httpd), connection, url, upload_data, upload_data_size, con_cls); + return handlePOST(static_cast(httpd), connection, clientIp, url, upload_data, upload_data_size, con_cls); } return MHD_NO; } -int Httpd::handleGET(const Httpd* httpd, struct MHD_Connection* connection, const char* urlPtr) +int Httpd::handleGET(const Httpd* httpd, struct MHD_Connection* connection, const std::string& clientIp, const char* urlPtr) { std::string resp; std::string url(urlPtr); @@ -227,7 +241,7 @@ int Httpd::handleGET(const Httpd* httpd, struct MHD_Connection* connection, cons clientId = std::string(clientIdPtr); } - unsigned status = Service::handleGET(httpd->m_options, url, clientId, resp); + unsigned status = Service::handleGET(httpd->m_options, url, clientIp, clientId, resp); MHD_Response* rsp = nullptr; if (!resp.empty()) { @@ -244,7 +258,7 @@ int Httpd::handleGET(const Httpd* httpd, struct MHD_Connection* connection, cons return sendResponse(connection, status, rsp, contentType); } -int Httpd::handlePOST(const Httpd* httpd, struct MHD_Connection* connection, const char* urlPtr, const char* upload_data, +int Httpd::handlePOST(const Httpd* httpd, struct MHD_Connection* connection, const std::string& clientIp, const char* urlPtr, const char* upload_data, size_t* upload_data_size, void** con_cls) { auto* cc = (ConnectionContext*)* con_cls; @@ -259,20 +273,8 @@ int Httpd::handlePOST(const Httpd* httpd, struct MHD_Connection* connection, con } else { std::string resp; std::string url(urlPtr); - std::string clientIp; std::string clientId; - const MHD_ConnectionInfo *info = MHD_get_connection_info(connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS); - if (info) { - char clientHost[NI_MAXHOST]; - int ec = getnameinfo(info->client_addr, sizeof(*info->client_addr), clientHost, sizeof(clientHost), - 0, 0, NI_NUMERICHOST|NI_NUMERICSERV); - - if (ec == 0) { - clientIp = std::string(clientHost); - } - } - const char* clientIdPtr = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "clientId"); if (clientIdPtr) { clientId = std::string(clientIdPtr); diff --git a/src/cc/Httpd.h b/src/cc/Httpd.h index 8d3ee6fe..fcec7d83 100644 --- a/src/cc/Httpd.h +++ b/src/cc/Httpd.h @@ -51,12 +51,12 @@ private: static int sendResponse(MHD_Connection* connection, unsigned status, MHD_Response* rsp, const char* contentType); - unsigned basicAuth(MHD_Connection* connection, std::string &resp); - unsigned tokenAuth(MHD_Connection* connection); + unsigned basicAuth(MHD_Connection* connection, const std::string& clientIp, std::string &resp); + unsigned tokenAuth(MHD_Connection* connection, const std::string& clientIp); static int handler(void* httpd, MHD_Connection* connection, const char* url, const char* method, const char* version, const char* upload_data, size_t* upload_data_size, void**con_cls); - static int handleGET(const Httpd* httpd, MHD_Connection* connection, const char* url); - static int handlePOST(const Httpd* httpd, MHD_Connection* connection, const char* url, const char* upload_data, size_t* upload_data_size, void** con_cls); + static int handleGET(const Httpd* httpd, MHD_Connection* connection, const std::string& clientIp, const char* url); + static int handlePOST(const Httpd* httpd, MHD_Connection* connection, const std::string& clientIp, const char* url, const char* upload_data, size_t* upload_data_size, void** con_cls); static std::string readFile(const std::string &fileName); diff --git a/src/cc/Service.cpp b/src/cc/Service.cpp index a12d44be..e02e584f 100644 --- a/src/cc/Service.cpp +++ b/src/cc/Service.cpp @@ -62,13 +62,20 @@ void Service::release() uv_mutex_unlock(&m_mutex); } -unsigned Service::handleGET(const Options* options, const std::string& url, const std::string& clientId, std::string& resp) +unsigned Service::handleGET(const Options* options, const std::string& url, const std::string& clientIp, const std::string& clientId, std::string& resp) { uv_mutex_lock(&m_mutex); unsigned resultCode = MHD_HTTP_NOT_FOUND; - LOG_INFO("GET(url='%s', clientId='%s')", url.c_str(), clientId.c_str()); + std::string params; + if (!clientId.empty()) + { + params += "?clientId="; + params += clientId; + } + + LOG_INFO("[%s] GET '%s%s'", clientIp.c_str(), url.c_str(), params.c_str()); if (url == "/") { resultCode = getAdminPage(options, resp); @@ -82,10 +89,12 @@ unsigned Service::handleGET(const Options* options, const std::string& url, cons resultCode = getClientCommand(clientId, resp); } else if (url.rfind("/admin/getClientLog", 0) == 0) { resultCode = getClientLog(clientId, resp); + } else { + LOG_WARN("[%s] METHOD_NOT_FOUND (%s)", clientIp.c_str(), url.c_str()); } } else { - LOG_ERR("Request does not contain clientId: %s", url.c_str()); + LOG_ERR("[%s] Request does not contain clientId: %s", clientIp.c_str(), url.c_str()); } } @@ -101,17 +110,32 @@ unsigned Service::handlePOST(const Options* options, const std::string& url, con unsigned resultCode = MHD_HTTP_NOT_FOUND; - LOG_INFO("POST(url='%s', clientIp='%s', clientId='%s', dataLen='%d')", - url.c_str(), clientIp.c_str(), clientId.c_str(), data.length()); + std::string params; + if (!clientId.empty()) + { + params += "?clientId="; + params += clientId; + } - if (url.rfind("/client/setClientStatus", 0) == 0) { - resultCode = setClientStatus(options, clientIp, clientId, data, resp); - } else if (url.rfind("/admin/setClientConfig", 0) == 0 || url.rfind("/client/setClientConfig", 0) == 0) { - resultCode = setClientConfig(options, clientId, data, resp); - } else if (url.rfind("/admin/setClientCommand", 0) == 0) { - resultCode = setClientCommand(clientId, data, resp); - } else if (url.rfind("/admin/resetClientStatusList", 0) == 0) { - resultCode = resetClientStatusList(data, resp); + LOG_INFO("[%s] POST '%s%s', dataLen='%d'", + clientIp.c_str(), url.c_str(), params.c_str(), data.length()); + + if (!clientId.empty()) { + if (url.rfind("/client/setClientStatus", 0) == 0) { + resultCode = setClientStatus(options, clientIp, clientId, data, resp); + } else if (url.rfind("/admin/setClientConfig", 0) == 0 || url.rfind("/client/setClientConfig", 0) == 0) { + resultCode = setClientConfig(options, clientId, data, resp); + } else if (url.rfind("/admin/setClientCommand", 0) == 0) { + resultCode = setClientCommand(clientId, data, resp); + } else { + LOG_WARN("[%s] METHOD_NOT_FOUND (%s)", clientIp.c_str(), url.c_str()); + } + } else { + if (url.rfind("/admin/resetClientStatusList", 0) == 0) { + resultCode = resetClientStatusList(data, resp); + } else { + LOG_WARN("[%s] METHOD_NOT_FOUND (%s)", clientIp.c_str(), url.c_str()); + } } uv_mutex_unlock(&m_mutex); @@ -227,8 +251,6 @@ unsigned Service::setClientStatus(const Options* options, const std::string& cli rapidjson::Document document; if (!document.Parse(data.c_str()).HasParseError()) { - LOG_INFO("Status from client: %s", clientId.c_str()); - ClientStatus clientStatus; clientStatus.parseFromJson(document); clientStatus.setExternalIp(clientIp); @@ -245,7 +267,8 @@ unsigned Service::setClientStatus(const Options* options, const std::string& cli m_clientCommand.erase(clientId); } } else { - LOG_ERR("Parse Error Occured: %d", document.GetParseError()); + LOG_ERR("[%s] ClientStatus for client '%s' - Parse Error Occured: %d", + clientIp.c_str(), clientId.c_str(), document.GetParseError()); } return resultCode; diff --git a/src/cc/Service.h b/src/cc/Service.h index e909debd..b4e7d610 100644 --- a/src/cc/Service.h +++ b/src/cc/Service.h @@ -42,7 +42,7 @@ public: static bool start(); static void release(); - static unsigned handleGET(const Options* options, const std::string& url, const std::string& clientId, std::string& resp); + static unsigned handleGET(const Options* options, const std::string& url, const std::string& clientIp, const std::string& clientId, std::string& resp); static unsigned handlePOST(const Options* options, const std::string& url, const std::string& clientIp, const std::string& clientId, const std::string& data, std::string& resp); private: