Compare commits

...

8 Commits

Author SHA1 Message Date
Lion Kortlepel
dad469f800 CMake: Fix typo in SANITIZE codepath 2021-09-14 14:38:18 +02:00
Lion Kortlepel
c3012fcee7 CMake: Use gzipped debug info on linux 2021-09-14 13:38:00 +02:00
Lion Kortlepel
7250137935 Sentry: Properly store DSN 2021-09-14 13:03:27 +02:00
Lion Kortlepel
fa3cf9f5a7 Add cryptography header for the future 2021-09-14 12:52:19 +02:00
Lion Kortlepel
eed8326deb Http, Heartbeat: Process status < 0 differently, report as "Invalid
Response Code"
2021-09-14 12:34:28 +02:00
Lion Kortlepel
90c3aac0bc Http: Add Sentry error breadcrumbs on internal https POST errors 2021-09-14 12:32:30 +02:00
Lion Kortlepel
7a25377d4e Heartbeat: Dont report 200 + INVALID_KEY to Sentry 2021-09-14 12:18:31 +02:00
Lion Kortlepel
f4900189c0 Config: private by default 2021-09-14 12:16:31 +02:00
8 changed files with 136 additions and 17 deletions

View File

@@ -32,10 +32,10 @@ if (WIN32)
elseif (UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic -static-libstdc++")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -g")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -s -fno-builtin")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -gz -fno-builtin")
if (SANITIZE)
message(STATUS "sanitize is ON")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLanAGS} -fsanitize=undefined,thread")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined,thread")
endif (SANITIZE)
endif ()

View File

@@ -1,3 +1,7 @@
# v2.3.3
- CHANGED servers to be private by default
# v2.3.2
- ADDED Ctrl+C causes a graceful shutdown on windows (did already on linux)

View File

@@ -27,7 +27,7 @@ public:
, Resource("Resources")
, MapName("/levels/gridmap_v2/info.json")
, MaxPlayers(10)
, Private(false)
, Private(true)
, MaxCars(1)
, DebugModeEnabled(false)
, Port(30814)
@@ -87,6 +87,7 @@ void RegisterThread(const std::string& str);
#define KB 1024
#define MB (KB * 1024)
#define SSU_UNRAW SECRET_SENTRY_URL
#define _file_basename std::filesystem::path(__FILE__).filename().string()
#define _line std::to_string(__LINE__)
@@ -112,9 +113,11 @@ void RegisterThread(const std::string& str);
#else
#define _this_location (ThreadName() + _file_basename + ":" + _line + " ")
#endif
#define SU_RAW SSU_UNRAW
#else // !defined(DEBUG)
#define SU_RAW RAWIFY(SSU_UNRAW)
#define _this_location (ThreadName())
#endif // defined(DEBUG)
@@ -150,3 +153,5 @@ void LogChatMessage(const std::string& name, int id, const std::string& msg);
#define Biggest 30000
std::string Comp(std::string Data);
std::string DeComp(std::string Compressed);
#define S_DSN SU_RAW

114
include/Cryptography.h Normal file
View File

@@ -0,0 +1,114 @@
// Copyright Anonymous275 8/11/2020
#pragma once
#include <array>
#include <cstdarg>
#include <string>
namespace Crypto {
constexpr auto time = __TIME__;
constexpr auto seed = static_cast<int>(time[7]) + static_cast<int>(time[6]) * 10 + static_cast<int>(time[4]) * 60 + static_cast<int>(time[3]) * 600 + static_cast<int>(time[1]) * 3600 + static_cast<int>(time[0]) * 36000;
// 1988, Stephen Park and Keith Miller
// "Random Number Generators: Good Ones Are Hard To Find", considered as "minimal standard"
// Park-Miller 31 bit pseudo-random number generator, implemented with G. Carta's optimisation:
// with 32-bit math and without division
template <int N>
struct RandomGenerator {
private:
static constexpr unsigned a = 16807; // 7^5
static constexpr unsigned m = 2147483647; // 2^31 - 1
static constexpr unsigned s = RandomGenerator<N - 1>::value;
static constexpr unsigned lo = a * (s & 0xFFFFu); // Multiply lower 16 bits by 16807
static constexpr unsigned hi = a * (s >> 16u); // Multiply higher 16 bits by 16807
static constexpr unsigned lo2 = lo + ((hi & 0x7FFFu) << 16u); // Combine lower 15 bits of hi with lo's upper bits
static constexpr unsigned hi2 = hi >> 15u; // Discard lower 15 bits of hi
static constexpr unsigned lo3 = lo2 + hi;
public:
static constexpr unsigned max = m;
static constexpr unsigned value = lo3 > m ? lo3 - m : lo3;
};
template <>
struct RandomGenerator<0> {
static constexpr unsigned value = seed;
};
template <int N, int M>
struct RandomInt {
static constexpr auto value = RandomGenerator<N + 1>::value % M;
};
template <int N>
struct RandomChar {
static const char value = static_cast<char>(1 + RandomInt<N, 0x7F - 1>::value);
};
template <size_t N, int K, typename Char>
struct MangleString {
private:
const char _key;
std::array<Char, N + 1> _encrypted;
constexpr Char enc(Char c) const {
return c ^ _key;
}
Char dec(Char c) const {
return c ^ _key;
}
public:
template <size_t... Is>
constexpr MangleString(const Char* str, std::index_sequence<Is...>)
: _key(RandomChar<K>::value)
, _encrypted { enc(str[Is])... } { }
decltype(auto) decrypt() {
for (size_t i = 0; i < N; ++i) {
_encrypted[i] = dec(_encrypted[i]);
}
_encrypted[N] = '\0';
return _encrypted.data();
}
};
static auto w_printf = [](const char* fmt, ...) {
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
};
static auto w_printf_s = [](const char* fmt, ...) {
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
};
static auto w_sprintf_s = [](char* buf, size_t buf_size, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
vsprintf(buf, fmt, args);
va_end(args);
};
static auto w_sprintf_s_ret = [](char* buf, size_t buf_size, const char* fmt, ...) {
int ret;
va_list args;
va_start(args, fmt);
ret = vsprintf(buf, fmt, args);
va_end(args);
return ret;
};
#define XOR_C(s) [] { constexpr Crypto::MangleString< sizeof(s)/sizeof(char) - 1, __COUNTER__, char > expr( s, std::make_index_sequence< sizeof(s)/sizeof(char) - 1>() ); return expr; }().decrypt()
#define XOR_W(s) [] { constexpr Crypto::MangleString< sizeof(s)/sizeof(wchar_t) - 1, __COUNTER__, wchar_t > expr( s, std::make_index_sequence< sizeof(s)/sizeof(wchar_t) - 1>() ); return expr; }().decrypt()
#define RAWIFY(s) XOR_C(s)
}

View File

@@ -2,6 +2,7 @@
#include "commandline/commandline.h"
#include "TLuaFile.h"
#include "Cryptography.h"
#include <atomic>
#include <fstream>

View File

@@ -127,6 +127,7 @@ std::string Http::POST(const std::string& host, const std::string& target, const
bool ok = try_connect_with_protocol(tcp::v4());
if (!ok) {
Application::Console().Write("[ERROR] failed to resolve or connect in POST " + host + target);
Sentry.AddErrorBreadcrumb("failed to resolve or connect to " + host + target, __FILE__, std::to_string(__LINE__)); // FIXME: this is ugly.
return "-1";
}
//}
@@ -202,12 +203,14 @@ std::string Http::POST(const std::string& host, const std::string& target, const
} catch (const std::exception& e) {
Application::Console().Write(e.what());
Sentry.AddErrorBreadcrumb(e.what(), __FILE__, std::to_string(__LINE__)); // FIXME: this is ugly.
return "-1";
}
}
// RFC 2616, RFC 7231
static std::map<size_t, const char*> Map = {
{ -1, "Invalid Response Code"},
{ 100, "Continue" },
{ 101, "Switching Protocols" },
{ 102, "Processing" },

View File

@@ -36,9 +36,6 @@ void THeartbeatThread::operator()() {
Body += "&pps=" + Application::PPS();
auto SentryReportError = [&](const std::string& transaction, int status) {
if (status < 0) {
status = 0;
}
auto Lock = Sentry.CreateExclusiveContext();
Sentry.SetContext("heartbeat",
{ { "response-body", T },
@@ -52,16 +49,16 @@ void THeartbeatThread::operator()() {
int ResponseCode = -1;
T = Http::POST(Application::GetBackendHostname(), Target, {}, Body, false, &ResponseCode);
if (T.substr(0, 2) != "20" || ResponseCode != 200) {
if ((T.substr(0, 2) != "20" && ResponseCode != 200) || ResponseCode != 200) {
trace("got " + T + " from backend");
SentryReportError(Application::GetBackendHostname() + Target, ResponseCode);
std::this_thread::sleep_for(std::chrono::milliseconds(500));
T = Http::POST(Application::GetBackup1Hostname(), Target, {}, Body, false, &ResponseCode);
if (T.substr(0, 2) != "20" || ResponseCode != 200) {
if ((T.substr(0, 2) != "20" && ResponseCode != 200) || ResponseCode != 200) {
SentryReportError(Application::GetBackup1Hostname() + Target, ResponseCode);
std::this_thread::sleep_for(std::chrono::milliseconds(500));
T = Http::POST(Application::GetBackup2Hostname(), Target, {}, Body, false, &ResponseCode);
if (T.substr(0, 2) != "20" || ResponseCode != 200) {
if ((T.substr(0, 2) != "20" && ResponseCode != 200) || ResponseCode != 200) {
warn("Backend system refused server! Server will not show in the public server list.");
isAuth = false;
SentryReportError(Application::GetBackup2Hostname() + Target, ResponseCode);

View File

@@ -1,22 +1,17 @@
#include "TSentry.h"
#include "Common.h"
#include <cstring>
#include <sentry.h>
#include <sstream>
// compile-time length of a string/array
template <size_t N>
constexpr size_t ConstexprLength(char const (&)[N]) {
return N - 1;
}
TSentry::TSentry() {
if constexpr (ConstexprLength(SECRET_SENTRY_URL) == 0) {
if (std::strlen(S_DSN) == 0) {
mValid = false;
} else {
mValid = true;
sentry_options_t* options = sentry_options_new();
sentry_options_set_dsn(options, SECRET_SENTRY_URL);
sentry_options_set_dsn(options, S_DSN);
sentry_options_set_debug(options, false); // needs to always be false
sentry_options_set_symbolize_stacktraces(options, true);
auto ReleaseString = "BeamMP-Server@" + Application::ServerVersion();