From 325e11662436abf060ecdb42b5a5b34c26abe2de Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 2 Sep 2017 08:18:24 +0300 Subject: [PATCH] Added API authorization via Bearer token. --- src/api/Httpd.cpp | 62 +++++++++++++++++++++++++++++++--------- src/api/Httpd.h | 8 ++++-- src/api/NetworkState.cpp | 1 - 3 files changed, 55 insertions(+), 16 deletions(-) diff --git a/src/api/Httpd.cpp b/src/api/Httpd.cpp index 29baa2f50..6a61ac74b 100644 --- a/src/api/Httpd.cpp +++ b/src/api/Httpd.cpp @@ -58,28 +58,64 @@ bool Httpd::start() } -int Httpd::handler(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls) +int Httpd::auth(const char *header) { - if (strcmp(method, "GET") != 0) { - return MHD_NO; + if (!m_accessToken) { + return MHD_HTTP_OK; } - struct MHD_Response *rsp; - - size_t size = 0; - int status = MHD_HTTP_OK; - const char *buf = Api::get(url, &size, &status); - - if (size) { - rsp = MHD_create_response_from_buffer(size, (void*) buf, MHD_RESPMEM_PERSISTENT); + if (m_accessToken && !header) { + return MHD_HTTP_UNAUTHORIZED; } - else { - rsp = MHD_create_response_from_buffer(k500Size, (void*) k500, MHD_RESPMEM_PERSISTENT); + + const size_t size = strlen(header); + if (size < 8 || strlen(m_accessToken) != size - 7 || memcmp("Bearer ", header, 7) != 0) { + return MHD_HTTP_FORBIDDEN; + } + + return strncmp(m_accessToken, header + 7, strlen(m_accessToken)) == 0 ? MHD_HTTP_OK : MHD_HTTP_FORBIDDEN; +} + + +int Httpd::done(MHD_Connection *connection, int status, MHD_Response *rsp) +{ + if (!rsp) { + rsp = MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_PERSISTENT); } MHD_add_response_header(rsp, "Content-Type", "application/json"); + MHD_add_response_header(rsp, "Access-Control-Allow-Origin", "*"); + MHD_add_response_header(rsp, "Access-Control-Allow-Methods", "GET"); + MHD_add_response_header(rsp, "Access-Control-Allow-Headers", "Authorization"); const int ret = MHD_queue_response(connection, status, rsp); MHD_destroy_response(rsp); return ret; } + + +int Httpd::handler(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls) +{ + if (strcmp(method, "OPTIONS") == 0) { + return done(connection, MHD_HTTP_OK, nullptr); + } + + if (strcmp(method, "GET") != 0) { + return MHD_NO; + } + + int status = static_cast(cls)->auth(MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Authorization")); + if (status != MHD_HTTP_OK) { + return done(connection, status, nullptr); + } + + MHD_Response *rsp = nullptr; + size_t size = 0; + const char *buf = Api::get(url, &size, &status); + + if (size) { + rsp = MHD_create_response_from_buffer(size, (void*) buf, MHD_RESPMEM_PERSISTENT); + } + + return done(connection, status, rsp); +} diff --git a/src/api/Httpd.h b/src/api/Httpd.h index 32750beb5..7a4dd9321 100644 --- a/src/api/Httpd.h +++ b/src/api/Httpd.h @@ -28,8 +28,9 @@ #include -struct MHD_Daemon; struct MHD_Connection; +struct MHD_Daemon; +struct MHD_Response; class Httpd @@ -39,7 +40,10 @@ public: bool start(); private: - static int handler(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls); + int auth(const char *header); + + static int done(MHD_Connection *connection, int status, MHD_Response *rsp); + static int handler(void *cls, MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls); const char *m_accessToken; const int m_port; diff --git a/src/api/NetworkState.cpp b/src/api/NetworkState.cpp index 2222b475a..e3c76ec14 100644 --- a/src/api/NetworkState.cpp +++ b/src/api/NetworkState.cpp @@ -26,7 +26,6 @@ #include - #include "api/NetworkState.h" #include "net/SubmitResult.h"