Skip to content

Commit

Permalink
Move --skip-ssl-verify into options
Browse files Browse the repository at this point in the history
  • Loading branch information
WiserTixx committed Oct 5, 2024
1 parent 57422a6 commit a1cdc8c
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 59 deletions.
1 change: 0 additions & 1 deletion include/Http.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,4 @@ class HTTP {
static void StartProxy();
public:
static bool isDownload;
static inline bool SkipSslVerify = false;
};
1 change: 1 addition & 0 deletions include/Options.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
struct Options {
std::string executable_name = "BeamMP-Launcher.exe";
unsigned int port = 4444;
bool skip_ssl_verify = false;
bool verbose = false;
bool no_download = false;
bool no_update = false;
Expand Down
154 changes: 103 additions & 51 deletions src/Network/Http.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,17 @@

#include "Http.h"
#include <Logger.h>
#include <Network/network.hpp>
#include <Startup.h>
#include <Utils.h>
#include <cmath>
#include <curl/curl.h>
#include <curl/easy.h>
#include <filesystem>
#include <fstream>
#include <httplib.h>
#include <iostream>
#include <mutex>
#include <nlohmann/json.hpp>
#include <Startup.h>
#include <Network/network.hpp>
#include <Utils.h>
#include <Options.h>

void WriteHttpDebug(const httplib::Client& client, const std::string& method, const std::string& target, const httplib::Result& result) try {
const std::filesystem::path folder = ".https_debug";
Expand Down Expand Up @@ -61,74 +60,126 @@ void WriteHttpDebug(const httplib::Client& client, const std::string& method, co
error(e.what());
}

static size_t CurlWriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
std::string* Result = reinterpret_cast<std::string*>(userp);
std::string NewContents(reinterpret_cast<char*>(contents), size * nmemb);
*Result += NewContents;
return size * nmemb;
}

bool HTTP::isDownload = false;
std::string HTTP::Get(const std::string& IP) {
static std::mutex Lock;
std::scoped_lock Guard(Lock);

auto pos = IP.find('/', 10);

httplib::Client cli(IP.substr(0, pos).c_str());
cli.set_connection_timeout(std::chrono::seconds(10));
cli.set_follow_location(true);
if (options.skip_ssl_verify) {
debug("Skipping SSL server validation via --skip-ssl-verify");
cli.enable_server_certificate_verification(false);
}
auto res = cli.Get(IP.substr(pos).c_str(), ProgressBar);
std::string Ret;
static thread_local CURL* curl = curl_easy_init();
if (curl) {
CURLcode res;
curl_easy_setopt(curl, CURLOPT_URL, IP.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&Ret);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10); // seconds
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
error("GET to " + IP + " failed: " + std::string(curl_easy_strerror(res)));
return "";

if (res) {
if (res->status == 200) {
Ret = res->body;
} else {
WriteHttpDebug(cli, "GET", IP, res);
error("Failed to GET (status " + std::to_string(res->status) + ") '" + IP + "': " + res->reason + ", ssl verify = " + std::to_string(cli.get_openssl_verify_result()));
}
} else {
error("Curl easy init failed");
return "";
if (isDownload) {
std::cout << "\n";
}
auto result = cli.get_openssl_verify_result();
std::string verify_error;
if (result) {
verify_error = X509_verify_cert_error_string(result);
}

WriteHttpDebug(cli, "GET", IP, res);
error("HTTP Get failed on " + to_string(res.error()) + ", ssl verify = " + verify_error);
}

return Ret;
}

std::string HTTP::Post(const std::string& IP, const std::string& Fields) {
static std::mutex Lock;
std::scoped_lock Guard(Lock);

auto pos = IP.find('/', 10);

httplib::Client cli(IP.substr(0, pos).c_str());
cli.set_connection_timeout(std::chrono::seconds(10));
if (options.skip_ssl_verify) {
debug("Skipping SSL server validation via --skip-ssl-verify");
cli.enable_server_certificate_verification(false);
}
std::string Ret;
static thread_local CURL* curl = curl_easy_init();
if (curl) {
CURLcode res;
curl_easy_setopt(curl, CURLOPT_URL, IP.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&Ret);
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, Fields.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, Fields.size());
struct curl_slist* list = nullptr;
list = curl_slist_append(list, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10); // seconds
res = curl_easy_perform(curl);
curl_slist_free_all(list);
if (res != CURLE_OK) {
error("POST to " + IP + " failed: " + std::string(curl_easy_strerror(res)));
return "";

if (!Fields.empty()) {
httplib::Result res = cli.Post(IP.substr(pos).c_str(), Fields, "application/json");

if (res) {
if (res->status != 200) {
error(res->reason);
}
Ret = res->body;
} else {
WriteHttpDebug(cli, "POST", IP, res);
error("HTTP Post failed on " + to_string(res.error()) + ", ssl verify = " + std::to_string(cli.get_openssl_verify_result()));
}
} else {
error("Curl easy init failed");
return "";
httplib::Result res = cli.Post(IP.substr(pos).c_str());
if (res) {
if (res->status != 200) {
error(res->reason);
}
Ret = res->body;
} else {
auto result = cli.get_openssl_verify_result();
std::string verify_error;
if (result) {
verify_error = X509_verify_cert_error_string(result);
}
WriteHttpDebug(cli, "POST", IP, res);
error("HTTP Post failed on " + to_string(res.error()) + ", ssl verify = " + verify_error);
}
}
return Ret;

if (Ret.empty())
return "-1";
else
return Ret;
}

bool HTTP::ProgressBar(size_t c, size_t t) {
if (isDownload) {
static double last_progress, progress_bar_adv;
progress_bar_adv = round(c / double(t) * 25);
std::cout << "\r";
std::cout << "Progress : [ ";
std::cout << round(c / double(t) * 100);
std::cout << "% ] [";
int i;
for (i = 0; i <= progress_bar_adv; i++)
std::cout << "#";
for (i = 0; i < 25 - progress_bar_adv; i++)
std::cout << ".";
std::cout << "]";
last_progress = round(c / double(t) * 100);
}
return true;
}

bool HTTP::Download(const std::string& IP, const std::string& Path) {
static std::mutex Lock;
std::scoped_lock Guard(Lock);

info("Downloading an update (this may take a while)");
isDownload = true;
std::string Ret = Get(IP);
isDownload = false;

if (Ret.empty()) {
error("Download failed");
if (Ret.empty())
return false;
}

std::ofstream File(Path, std::ios::binary);
if (File.is_open()) {
Expand All @@ -150,6 +201,7 @@ void set_headers(httplib::Response& res) {
res.set_header("Access-Control-Request-Headers", "X-API-Version");
}


void HTTP::StartProxy() {
std::thread proxy([&]() {
httplib::Server HTTPProxy;
Expand Down Expand Up @@ -204,7 +256,7 @@ void HTTP::StartProxy() {
if (std::stoi(path[2]) > 0)
avatar_size = path[2];

} catch (std::exception&) { }
} catch (std::exception&) {}
}

httplib::Result summary_res;
Expand Down
3 changes: 3 additions & 0 deletions src/Options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ void InitOptions(int argc, char *argv[], Options &options) {
options.no_download = true;
options.no_launch = true;
options.no_update = true;
} else if (argument == "--skip-ssl-verify") {
options.skip_ssl_verify = true;
warn("SSL verification skip enabled");
} else if (argument == "--") {
options.game_arguments = &argv[i + 1];
options.game_arguments_length = argc - i - 1;
Expand Down
7 changes: 0 additions & 7 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,6 @@ int main(int argc, char** argv) try {

GetEP(argv[0]);

for (int i = 0; i < argc; ++i) {
if (std::string_view(argv[i]) == "--skip-ssl-verify") {
info("SSL verification skip enabled");
HTTP::SkipSslVerify = true;
}
}

InitOptions(argc, argv, options);
InitLauncher();

Expand Down

0 comments on commit a1cdc8c

Please sign in to comment.