diff --git a/CMakeLists.txt b/CMakeLists.txt index 1fe5e207..c81b65f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ find_package(Perl REQUIRED) find_package(Threads) find_package(ZLIB REQUIRED) find_package(CURL REQUIRED) +find_package(OpenSSL REQUIRED) # c++14 yeah! set(CMAKE_CXX_STANDARD 14) diff --git a/external/3rd/library/webAPI/CMakeLists.txt b/external/3rd/library/webAPI/CMakeLists.txt index d0dbb6cb..0aa15c87 100644 --- a/external/3rd/library/webAPI/CMakeLists.txt +++ b/external/3rd/library/webAPI/CMakeLists.txt @@ -2,8 +2,6 @@ cmake_minimum_required(VERSION 2.8) project(webAPI) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) - add_library(webAPI webAPI.h webAPI.cpp @@ -13,5 +11,7 @@ add_library(webAPI ) include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} ${CURL_INCLUDE_DIRS} + ${OPENSSL_INCLUDE_DIR} ) diff --git a/external/3rd/library/webAPI/webAPI.cpp b/external/3rd/library/webAPI/webAPI.cpp index 43d817ff..6b7c87c0 100644 --- a/external/3rd/library/webAPI/webAPI.cpp +++ b/external/3rd/library/webAPI/webAPI.cpp @@ -26,6 +26,57 @@ webAPI::~webAPI() { this->responseData.clear(); } +CURLcode* webAPI::sslctx_function(CURL *curl, void *sslctx, void *parm) { + X509_STORE *store; + X509 *cert = NULL; + BIO *bio; + char *mypem = /* this is the cloudflare self signed for stellabellum.net, good for 30 years */ + "-----BEGIN CERTIFICATE-----\n"\ + "MIIEojCCA4qgAwIBAgIUJ88p38SKi9SeyVOF0AQne1O6Vs4wDQYJKoZIhvcNAQEL\n"\ + "BQAwgYsxCzAJBgNVBAYTAlVTMRkwFwYDVQQKExBDbG91ZEZsYXJlLCBJbmMuMTQw\n"\ + "MgYDVQQLEytDbG91ZEZsYXJlIE9yaWdpbiBTU0wgQ2VydGlmaWNhdGUgQXV0aG9y\n"\ + "aXR5MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlh\n"\ + "MB4XDTE2MTIzMTA1MDcwMFoXDTMxMTIyODA1MDcwMFowYjEZMBcGA1UEChMQQ2xv\n"\ + "dWRGbGFyZSwgSW5jLjEdMBsGA1UECxMUQ2xvdWRGbGFyZSBPcmlnaW4gQ0ExJjAk\n"\ + "BgNVBAMTHUNsb3VkRmxhcmUgT3JpZ2luIENlcnRpZmljYXRlMIIBIjANBgkqhkiG\n"\ + "9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwv0X8DT+AvVAWeLZvBZ+uQXFA5SEmY3w47uT\n"\ + "cwR/KCIrty7JLlswDv7iGV4f58vDAcNZq3Rs85eBY2kEatYZUBEFw+FhQDw76R9r\n"\ + "ZRj/gRfKyjkoHmmJ9ItP6YEIGHW5GGvSsB0PqV52pAESfIc4ABSUQVghLCmXCHPv\n"\ + "vMQjnTgAxgRQ0tvy52At9E39qClk+4uofMHzwk4bOKRUA9aLHLdZJQDEKR7EdZY1\n"\ + "qPIh3Rkari0aTVBf+0mnXQJ0xnIvVPc+GPYVotQ0tutISUtVPzpia0PmmbhHN4uE\n"\ + "ZVS53gOjgPz1dT/yivrsKw5i0vBqRcwMZ4dU+yfAL4uibJqwOwIDAQABo4IBJDCC\n"\ + "ASAwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB\n"\ + "/wQCMAAwHQYDVR0OBBYEFCjf0EvN/w5pDVLXf4dk4yfU5A02MB8GA1UdIwQYMBaA\n"\ + "FCToU1ddfDRAh6nrlNu64RZ4/CmkMEAGCCsGAQUFBwEBBDQwMjAwBggrBgEFBQcw\n"\ + "AYYkaHR0cDovL29jc3AuY2xvdWRmbGFyZS5jb20vb3JpZ2luX2NhMC8GA1UdEQQo\n"\ + "MCaCEiouc3RlbGxhYmVsbHVtLm5ldIIQc3RlbGxhYmVsbHVtLm5ldDA4BgNVHR8E\n"\ + "MTAvMC2gK6AphidodHRwOi8vY3JsLmNsb3VkZmxhcmUuY29tL29yaWdpbl9jYS5j\n"\ + "cmwwDQYJKoZIhvcNAQELBQADggEBAGXNQW26rnr4k+2hfOxkuGGMXBuYAzLcCwbg\n"\ + "H5KRH3HoJg1FmkjGC07nptDk2EAkqp6DphwTangyw0oREEIU/l2k8AvkX0WVFXdx\n"\ + "FnVWq5IenZF8dX0m9oQyH/CsF89dkvU+zksP4wzJAMvGiB8Tmc8bKWmIfBnusj3D\n"\ + "npbKvZL2ch+hwY4SZspJLoKJ4iz5wWSHihwNYxm+KGsJpt2moV15gAuObmDg7nu6\n"\ + "owOLXtbf62tQOXnXee2peBN1JX/mCHKUSL1mu+wJXjitBEgXJRGSnZl4IGv/m8Q5\n"\ + "KDeA44tJg2f/le+MertWN/+aTYhK8exu4v/7SaEJHNCwbXCJICg=\n"\ + "-----END CERTIFICATE-----\n"; + + bio = BIO_new_mem_buf(mypem, -1); + PEM_read_bio_X509(bio, &cert, 0, NULL); + if (cert == NULL) { + printf("PEM_read_bio_X509 failed...\n"); + } + + store = SSL_CTX_get_cert_store((SSL_CTX *) sslctx); + + if (X509_STORE_add_cert(store, cert) == 0) { + printf("error adding certificate\n"); + } + + X509_free(cert); + BIO_free(bio); + + return CURLE_OK; +} + bool webAPI::setEndpoint(const std::string endpoint) { this->uri = endpoint; @@ -61,14 +112,14 @@ std::unordered_map webAPI::getStringMap(const std::string &slo if (!this->responseData.empty() && !slot.empty() && responseData.count(slot) && !this->responseData[slot].is_null()) { - nlohmann::json j = this->responseData[slot]; + nlohmann::json j = this->responseData[slot]; - for (nlohmann::json::iterator it = j.begin(); it != j.end(); ++it) { - int k = std::stoi(it.key()); - std::string val = it.value(); + for (nlohmann::json::iterator it = j.begin(); it != j.end(); ++it) { + int k = std::stoi(it.key()); + std::string val = it.value(); - ret.insert({k, val}); - } + ret.insert({k, val}); + } } return ret; @@ -121,8 +172,12 @@ bool webAPI::fetch(const int &getPost, const int &mimeType) // 0 for json 1 for 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_SSL_VERIFYHOST, 0); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); + + if (this->uri.find("login.stellabellum.net") != std::string::npos) { + curl_easy_setopt(ch, CURLOPT_SSLCERTTYPE, "PEM"); + curl_easy_setopt(ch, CURLOPT_SSL_VERIFYPEER, 1L); + curl_easy_setopt(ch, CURLOPT_SSL_CTX_FUNCTION, this->sslctx_function); + } switch (getPost) { case HTTP::GET: diff --git a/external/3rd/library/webAPI/webAPI.h b/external/3rd/library/webAPI/webAPI.h index ac5bf6d9..3dd415cd 100644 --- a/external/3rd/library/webAPI/webAPI.h +++ b/external/3rd/library/webAPI/webAPI.h @@ -25,6 +25,7 @@ #else #include +#include #include #endif @@ -47,6 +48,9 @@ namespace StellaBellum { ~webAPI(); + // pin our key + CURLcode* sslctx_function(CURL *curl, void *sslctx, void *parm); + // submits the request bool submit(const int &reqType = DTYPE::JSON, const int &getPost = HTTP::POST, const int &respType = DTYPE::JSON);