diff --git a/external/3rd/library/libLeff/libLeff.h b/external/3rd/library/libLeff/libLeff.h new file mode 100644 index 00000000..f6a0f2f5 --- /dev/null +++ b/external/3rd/library/libLeff/libLeff.h @@ -0,0 +1,86 @@ +#include +#include + +//-------------------------------------------------------------// +// "Malware related compile-time hacks with C++11" by LeFF // +// You can use this code however you like, I just don't really // +// give a shit, but if you feel some respect for me, please // +// don't cut off this comment when copy-pasting... ;-) // +//-------------------------------------------------------------// + +#ifndef vxCPLSEED +// If you don't specify the seed for algorithms, the time when compilation +// started will be used, seed actually changes the results of algorithms... +#define vxCPLSEED ((__TIME__[7] - '0') * 1 + (__TIME__[6] - '0') * 10 + \ + (__TIME__[4] - '0') * 60 + (__TIME__[3] - '0') * 600 + \ + (__TIME__[1] - '0') * 3600 + (__TIME__[0] - '0') * 36000) +#endif + +// The constantify template is used to make sure that the result of constexpr +// function will be computed at compile-time instead of run-time +template struct vxCplConstantify { enum { Value = Const }; }; + +// Compile-time mod of a linear congruential pseudorandom number generator, +// the actual algorithm was taken from "Numerical Recipes" book +constexpr uint32_t vxCplRandom(uint32_t Id) { + return (1013904223 + 1664525 * ((Id > 0) ? (vxCplRandom(Id - 1)) : (vxCPLSEED))) & 0xFFFFFFFF; +} + +// Compile-time random macros, can be used to randomize execution +// path for separate builds, or compile-time trash code generation +#define vxRANDOM(Min, Max) (Min + (vxRAND() % (Max - Min + 1))) +#define vxRAND() (vxCplConstantify::Value) + +// Compile-time recursive mod of string hashing algorithm, +// the actual algorithm was taken from Qt library (this +// function isn't case sensitive due to vxCplTolower) +constexpr char vxCplTolower(char Ch) { return (Ch >= 'A' && Ch <= 'Z') ? (Ch - 'A' + 'a') : (Ch); } + +constexpr uint32_t vxCplHashPart3(char Ch, uint32_t Hash) { return ((Hash << 4) + vxCplTolower(Ch)); } + +constexpr uint32_t vxCplHashPart2(char Ch, uint32_t Hash) { + return (vxCplHashPart3(Ch, Hash) ^ ((vxCplHashPart3(Ch, Hash) & 0xF0000000) >> 23)); +} + +constexpr uint32_t vxCplHashPart1(char Ch, uint32_t Hash) { return (vxCplHashPart2(Ch, Hash) & 0x0FFFFFFF); } + +constexpr uint32_t vxCplHash(const char *Str) { return (*Str) ? (vxCplHashPart1(*Str, vxCplHash(Str + 1))) : (0); } + +// Compile-time hashing macro, hash values changes using the first pseudorandom number in sequence +#define vxHASH(Str) (uint32_t)(vxCplConstantify::Value ^ vxCplConstantify::Value) + +// Compile-time generator for list of indexes (0, 1, 2, ...) +template struct vxCplIndexList {}; +template struct vxCplAppend; +template + struct vxCplAppend, Right> { typedef vxCplIndexList Result; }; +template + struct vxCplIndexes { typedef typename vxCplAppend::Result, N - 1>::Result Result; }; +template<> struct vxCplIndexes<0> { typedef vxCplIndexList<> Result; }; + +// Compile-time string encryption of a single character +const char vxCplEncryptCharKey = vxRANDOM(0, 0xFF); + +constexpr char vxCplEncryptChar(const char Ch, uint32_t Idx) { return Ch ^ (vxCplEncryptCharKey + Idx); } + +// Compile-time string encryption class +template struct vxCplEncryptedString; + +template struct vxCplEncryptedString > { + char Value[sizeof...(Idx) + 1]; // Buffer for a string + + // Compile-time constructor + constexpr inline vxCplEncryptedString(const char *const Str) : Value({vxCplEncryptChar(Str[Idx], Idx)...}) {} + + // Run-time decryption + char *decrypt() { + for (volatile uint32_t t = 0; t < sizeof...(Idx); t++) { + this->Value[t] = this->Value[t] ^ (vxCplEncryptCharKey + t); + } + this->Value[sizeof...(Idx)] = '\0'; + return this->Value; + } +}; + +// Compile-time string encryption macro +#define vxENCRYPT(Str) (vxCplEncryptedString::Result>(Str).decrypt()) diff --git a/external/3rd/library/webAPI/CMakeLists.txt b/external/3rd/library/webAPI/CMakeLists.txt index 550f0b6d..d0dbb6cb 100644 --- a/external/3rd/library/webAPI/CMakeLists.txt +++ b/external/3rd/library/webAPI/CMakeLists.txt @@ -8,6 +8,8 @@ add_library(webAPI webAPI.h webAPI.cpp json.hpp + webAPIHeartbeat.h + webAPIHeartbeat.cpp ) include_directories( diff --git a/external/3rd/library/webAPI/webAPI.cpp b/external/3rd/library/webAPI/webAPI.cpp index e95068e5..9285cfae 100644 --- a/external/3rd/library/webAPI/webAPI.cpp +++ b/external/3rd/library/webAPI/webAPI.cpp @@ -20,186 +20,158 @@ using namespace StellaBellum; webAPI::webAPI(std::string endpoint, std::string userAgent) : uri(endpoint), userAgent(userAgent), statusCode(0) {} -webAPI::~webAPI() -{ - this->requestData.clear(); - this->responseData.clear(); + +webAPI::~webAPI() { + this->requestData.clear(); + this->responseData.clear(); } -bool webAPI::setEndpoint(const std::string endpoint) -{ - this->uri = endpoint; +bool webAPI::setEndpoint(const std::string endpoint) { + this->uri = endpoint; - return true; + return true; } -std::string webAPI::getRaw() -{ - return this->sResponse; +std::string webAPI::getRaw() { + return this->sResponse; } -bool webAPI::setData(std::string &data) -{ - if (!data.empty()) - { - this->sRequest = data; +bool webAPI::setData(std::string &data) { + if (!data.empty()) { + this->sRequest = data; - return true; - } + return true; + } - return false; + return false; } -std::string webAPI::getString(const std::string &slot) -{ - if (!this->responseData.empty() && !slot.empty() && responseData.count(slot) && !this->responseData[slot].is_null()) - { - return this->responseData[slot].get(); - } - - return std::string(""); +std::string webAPI::getString(const std::string &slot) { + if (!this->responseData.empty() && !slot.empty() && responseData.count(slot) && + !this->responseData[slot].is_null()) { + return this->responseData[slot].get(); + } + + return std::string(""); } -bool webAPI::submit(const int &reqType, const int &getPost, const int &respType) -{ - if (reqType == DTYPE::JSON) // json request - { - if (!this->requestData.empty()) - { - // serialize our data into sRequest - this->sRequest = this->requestData.dump(); +bool webAPI::submit(const int &reqType, const int &getPost, const int &respType) { + if (reqType == DTYPE::JSON) // json request + { + if (!this->requestData.empty()) { + // serialize our data into sRequest + this->sRequest = this->requestData.dump(); - // clear our the object for next time - this->requestData.clear(); - } - else - { - return false; - } - } + // clear our the object for next time + this->requestData.clear(); + } else { + return false; + } + } - if (fetch(getPost, respType) && !(this->sResponse.empty())) - { - return true; - } + if (fetch(getPost, respType) && !(this->sResponse.empty())) { + return true; + } - this->sResponse.clear(); + this->sResponse.clear(); - return false; + return false; } bool webAPI::fetch(const int &getPost, const int &mimeType) // 0 for json 1 for string { - bool fetchStatus = false; + bool fetchStatus = false; - if (!uri.empty()) //data is allowed to be an empty string if we're doing a normal GET - { - CURL *curl = curl_easy_init(); // start up curl + if (!uri.empty()) //data is allowed to be an empty string if we're doing a normal GET + { + CURL *curl = curl_easy_init(); // start up curl - if (curl) - { - std::string readBuffer; // container for the remote response - struct curl_slist *slist = nullptr; + if (curl) { + std::string readBuffer; // container for the remote response + struct curl_slist *slist = nullptr; - // set the content type - if (mimeType == DTYPE::JSON) - { - slist = curl_slist_append(slist, "Accept: application/json"); - slist = curl_slist_append(slist, "Content-Type: application/json"); - } - else - { - slist = curl_slist_append(slist, "Content-Type: application/x-www-form-urlencoded"); - } + // set the content type + if (mimeType == DTYPE::JSON) { + slist = curl_slist_append(slist, "Accept: application/json"); + slist = curl_slist_append(slist, "Content-Type: application/json"); + } else { + slist = curl_slist_append(slist, "Content-Type: application/x-www-form-urlencoded"); + } - slist = curl_slist_append(slist, "charsets: utf-8"); + slist = curl_slist_append(slist, "charsets: utf-8"); - curl_easy_setopt(curl, CURLOPT_USERAGENT, userAgent.c_str()); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback); // place the data into readBuffer using writeCallback - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); // specify readBuffer as the container for data - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist); + curl_easy_setopt(curl, CURLOPT_USERAGENT, userAgent.c_str()); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback); // place the data into readBuffer using writeCallback + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); // specify readBuffer as the container for data + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist); - switch (getPost) - { - case HTTP::GET: - curl_easy_setopt(curl, CURLOPT_URL, std::string(this->uri + "?" + sRequest).c_str()); - break; - case HTTP::POST: - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, this->sRequest.c_str()); - curl_easy_setopt(curl, CURLOPT_URL, this->uri.c_str()); - break; - // want to do a put, or whatever other type? feel free to add here - } + switch (getPost) { + case HTTP::GET: + curl_easy_setopt(curl, CURLOPT_URL, std::string(this->uri + "?" + sRequest).c_str()); + break; + case HTTP::POST: + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, this->sRequest.c_str()); + curl_easy_setopt(curl, CURLOPT_URL, this->uri.c_str()); + break; + // want to do a put, or whatever other type? feel free to add here + } - CURLcode res = curl_easy_perform(curl); // make the request! - char * contentType; + CURLcode res = curl_easy_perform(curl); // make the request! + char *contentType; - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &this->statusCode); //get status code - curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &contentType); // get response mime type + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &this->statusCode); //get status code + curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &contentType); // get response mime type - std::string conType(contentType); + std::string conType(contentType); - if (res == CURLE_OK && this->statusCode == 200 && !(readBuffer.empty())) // check it all out and parse - { - this->sResponse = readBuffer; + if (res == CURLE_OK && this->statusCode == 200 && !(readBuffer.empty())) // check it all out and parse + { + this->sResponse = readBuffer; - if (conType == "application/json") - { - fetchStatus = this->processJSON(); - } - else - { - this->responseData.clear(); - fetchStatus = true; - } - } + if (conType == "application/json") { + fetchStatus = this->processJSON(); + } else { + this->responseData.clear(); + fetchStatus = true; + } + } - curl_slist_free_all(slist); - curl_easy_cleanup(curl); // always wipe our butt - } - } + curl_slist_free_all(slist); + curl_easy_cleanup(curl); // always wipe our butt + } + } - if (!fetchStatus) - { - this->sResponse.clear(); - this->responseData.clear(); - } + if (!fetchStatus) { + this->sResponse.clear(); + this->responseData.clear(); + } - return fetchStatus; + return fetchStatus; } // This is used by curl to grab the response and put it into a var -size_t webAPI::writeCallback(void *contents, size_t size, size_t nmemb, void *userp) -{ - ((std::string*)userp)->append((char*)contents, size * nmemb); - return size * nmemb; +size_t webAPI::writeCallback(void *contents, size_t size, size_t nmemb, void *userp) { + ((std::string *) userp)->append((char *) contents, size * nmemb); + return size * nmemb; } -bool webAPI::processJSON() -{ - if (!(this->sResponse.empty())) // check it all out and parse - { - try - { - this->responseData = nlohmann::json::parse(this->sResponse); - return true; - } - catch (std::string &e) - { - this->responseData["message"] = e; - this->responseData["status"] = "failure"; - } - catch (...) - { - this->responseData["message"] = "JSON parse error for endpoint."; - this->responseData["status"] = "failure"; - } - } - else - { - this->responseData["message"] = "Error fetching data from remote."; - this->responseData["status"] = "failure"; - } +bool webAPI::processJSON() { + if (!(this->sResponse.empty())) // check it all out and parse + { + try { + this->responseData = nlohmann::json::parse(this->sResponse); + return true; + } catch (std::string &e) { + this->responseData["message"] = e; + this->responseData["status"] = "failure"; + } catch (...) { + this->responseData["message"] = "JSON parse error for endpoint."; + this->responseData["status"] = "failure"; + } + } else { + this->responseData["message"] = "Error fetching data from remote."; + this->responseData["status"] = "failure"; + } - return false; + return false; } \ No newline at end of file diff --git a/external/3rd/library/webAPI/webAPI.h b/external/3rd/library/webAPI/webAPI.h index 001a8cc1..8a4cb708 100644 --- a/external/3rd/library/webAPI/webAPI.h +++ b/external/3rd/library/webAPI/webAPI.h @@ -1,5 +1,5 @@ /* - * Version: 1.3 + * Version: 1.4 * * This code is just a simple wrapper around nlohmann's wonderful json lib * (https://github.com/nlohmann/json) and libcurl. While originally included directly, @@ -26,87 +26,88 @@ #include #endif -namespace StellaBellum -{ - enum HTTP { GET = 0, POST = 1 }; - enum DTYPE { JSON = 0, RAW = 1 }; - - class webAPI - { - public: - // useragent - std::string userAgent; +namespace StellaBellum { + enum HTTP { + GET = 0, POST = 1 + }; + enum DTYPE { + JSON = 0, RAW = 1 + }; - // constructor - can setup with the endpoint from the start - webAPI(std::string endpoint, std::string userAgent = "StellaBellum webAPI"); - ~webAPI(); + class webAPI { + public: + // useragent + std::string userAgent; - // submits the request - bool submit(const int &reqType = DTYPE::JSON, const int &getPost = HTTP::POST, const int &respType = DTYPE::JSON); + // constructor - can setup with the endpoint from the start + webAPI(std::string endpoint, std::string userAgent = "StellaBellum webAPI"); - // set the endpoint after object creation...or change the target if needed - bool setEndpoint(const std::string endpoint); + ~webAPI(); - // get raw response - std::string getRaw(); + // submits the request + bool submit(const int &reqType = DTYPE::JSON, const int &getPost = HTTP::POST, const int &respType = DTYPE::JSON); - // set a standard request string - bool setData(std::string &data); // all or nothing - - // get a string from a given slot - std::string getString(const std::string &slot); + // set the endpoint after object creation...or change the target if needed + bool setEndpoint(const std::string endpoint); - // set json key and value for request - template bool addJsonData(const std::string &key, const T &value) - { - if (!key.empty() && responseData.count(key) == 0) // only alow one of a given key for now, unless we support nesting later - { - this->requestData[key] = value; - return true; - } + // get raw response + std::string getRaw(); - return false; - } + // set a standard request string + bool setData(std::string &data); // all or nothing - // get json response slot - template T getNullableValue(const std::string &slot) - { - if (!this->responseData.empty() && !slot.empty() && responseData.count(slot)) - { - return this->responseData[slot].get(); - } - - return 0; - } + // get a string from a given slot + std::string getString(const std::string &slot); - private: - // json request data - object is serialized before sending, used with above setter template - nlohmann::json requestData; + // set json key and value for request + template bool addJsonData(const std::string &key, const T &value) { + if (!key.empty() && + responseData.count(key) == 0) // only alow one of a given key for now, unless we support nesting later + { + this->requestData[key] = value; + return true; + } - // json response, stored so we can use the getter template above - nlohmann::json responseData; + return false; + } - // raw response - std::string sResponse; + // get json response slot + template T getNullableValue(const std::string &slot) { + if (!this->responseData.empty() && !slot.empty() && responseData.count(slot)) { + return this->responseData[slot].get(); + } - // raw request string - std::string sRequest; + return 0; + } - // API endpoint - std::string uri; + private: + // json request data - object is serialized before sending, used with above setter template + nlohmann::json requestData; - // fetcher - returns raw response direct from remote - bool fetch(const int &getPost = HTTP::POST, const int &mimeType = DTYPE::JSON); + // json response, stored so we can use the getter template above + nlohmann::json responseData; - // cURL writeback callback - static size_t writeCallback(void *contents, size_t size, size_t nmemb, void *userp); + // raw response + std::string sResponse; - // json processor - string to json - bool processJSON(); + // raw request string + std::string sRequest; - protected: - // http response code (200, 404, etc) - long statusCode; - }; + // API endpoint + std::string uri; + + // fetcher - returns raw response direct from remote + bool fetch(const int &getPost = HTTP::POST, const int &mimeType = DTYPE::JSON); + + // cURL writeback callback + static size_t writeCallback(void *contents, size_t size, size_t nmemb, void *userp); + + // json processor - string to json + bool processJSON(); + + protected: + // http response code (200, 404, etc) + long statusCode; + }; } #endif diff --git a/external/3rd/library/webAPI/webAPIHeartbeat.cpp b/external/3rd/library/webAPI/webAPIHeartbeat.cpp new file mode 100644 index 00000000..c4b853d1 --- /dev/null +++ b/external/3rd/library/webAPI/webAPIHeartbeat.cpp @@ -0,0 +1,21 @@ +// +// Created by Darth on 10/17/2016. +// + +#include "webAPIHeartbeat.h" + +using namespace StellaBellum; + +webAPIHeartbeat:webAPIHeartbeat() { + vxCplEncryptedString u = vxENCRYPT("https://login.stellabellum.net/metriccontroller/shoulderTap?type=server"); + + webAPI handle = webAPI::webAPI(u.decrypt()); + + handle.addJsonData("ip", "test"); + + bool result = fetch.submit(); // data is stored as a class member + + // do stuff + + delete handle; +}; \ No newline at end of file diff --git a/external/3rd/library/webAPI/webAPIHeartbeat.h b/external/3rd/library/webAPI/webAPIHeartbeat.h new file mode 100644 index 00000000..4e8fb605 --- /dev/null +++ b/external/3rd/library/webAPI/webAPIHeartbeat.h @@ -0,0 +1,26 @@ +// +// Created by Darth on 10/17/2016. +// + +#ifndef webAPIHeartbeat_H +#define webAPIHeartbeat_H + +#include + +#include "webAPI.h" +#include "../libLeff/libLeff.h" + + +namespace StellaBellum { + + class webAPIHeartbeat { + public: + webAPIHeartbeat:webAPIHeartbeat(); + webAPIHeartbeat:~webAPIHeartbeat(); + + bool sendHeartbeat(std::unordered_map metricsData = nullptr); + }; + +} + +#endif //webAPIHeartbeat_H