From c6177d9c737e4f0c29d4c0a18f070d2201e29746 Mon Sep 17 00:00:00 2001 From: Exynox Date: Thu, 5 Sep 2024 21:53:32 +0300 Subject: [PATCH] Added Laravel-style URL signing for mall authentication --- docker/conf/game.conf.tmpl | 3 ++- src/game/src/cmd_general.cpp | 34 +++++++++++++++++++++++++++++----- src/game/src/config.cpp | 25 ++++++++++++++++++++++--- src/game/src/config.h | 3 ++- 4 files changed, 55 insertions(+), 10 deletions(-) diff --git a/docker/conf/game.conf.tmpl b/docker/conf/game.conf.tmpl index dbf8e37..3c4dd4b 100644 --- a/docker/conf/game.conf.tmpl +++ b/docker/conf/game.conf.tmpl @@ -24,7 +24,8 @@ MAX_LEVEL: ${GAME_MAX_LEVEL} PK_PROTECT_LEVEL: 15 SPAM_BLOCK_MAX_LEVEL: 90 GOLD_DROP_LIMIT_TIME: 10 -MALL_URL: ${GAME_MALL_URL} +WEB_APP_URL: ${WEB_APP_URL} +WEB_APP_KEY: ${WEB_APP_KEY} CHECK_MULTIHACK: 0 SPEEDHACK_LIMIT_COUNT: 300 diff --git a/src/game/src/cmd_general.cpp b/src/game/src/cmd_general.cpp index 9af2aba..7098001 100644 --- a/src/game/src/cmd_general.cpp +++ b/src/game/src/cmd_general.cpp @@ -28,6 +28,11 @@ #include "threeway_war.h" #include "log.h" #include +#include +#include +#include +#include +#include #ifdef __AUCTION__ #include "auction_manager.h" #endif @@ -2231,13 +2236,32 @@ ACMD(do_cube) ACMD(do_in_game_mall) { - char country_code[3]; - country_code[0] = 'd'; country_code[1] = 'e'; country_code[2] = '\0'; + // Build the URL + const auto expire_time = std::chrono::system_clock::now() + std::chrono::minutes(1); + const auto expire_timestamp = std::chrono::duration_cast(expire_time.time_since_epoch()).count(); + std::string url = fmt::format("{}/mall/auth?pid={}&sid={}&expires={}", g_strWebAppURL, ch->GetPlayerID(), g_server_id, expire_timestamp); + + // Compute hex-encoded SHA-256 URL signature + std::string mac, encoded; + try { + CryptoPP::HMAC hmac((CryptoPP::byte*) g_strWebAppKey.c_str(), g_strWebAppKey.size()); + CryptoPP::StringSource ss(url, true, new CryptoPP::HashFilter(hmac, new CryptoPP::StringSink(mac))); + + encoded.clear(); + CryptoPP::StringSource(mac, true, new CryptoPP::HexEncoder(new CryptoPP::StringSink(encoded), false)); + } + catch (const CryptoPP::Exception& e) { + SPDLOG_ERROR("Failed to create HMAC signature: {}", e.what()); + return; + } + + // Add the signature to the URL + url += fmt::format("&signature={}", encoded); + + // Send the command to the player char buf[512+1]; - - snprintf(buf, sizeof(buf), "mall http://%s/ishop?pid=%u&c=%s&sid=%d", - g_strWebMallURL.c_str(), ch->GetPlayerID(), country_code, g_server_id); + snprintf(buf, sizeof(buf), "mall %s", url.c_str()); ch->ChatPacket(CHAT_TYPE_COMMAND, buf); } diff --git a/src/game/src/config.cpp b/src/game/src/config.cpp index b30bd97..48d09f7 100644 --- a/src/game/src/config.cpp +++ b/src/game/src/config.cpp @@ -104,7 +104,8 @@ int VIEW_RANGE = 5000; int VIEW_BONUS_RANGE = 500; int g_server_id = 0; -string g_strWebMallURL = "www.metin2.de"; +string g_strWebAppURL = ""; +string g_strWebAppKey = ""; unsigned int g_uiSpamBlockDuration = 60 * 15; // 기본 15분 unsigned int g_uiSpamBlockScore = 100; // 기본 100점 @@ -961,9 +962,14 @@ void config_init(const string& st_localeServiceName) str_to_number(g_server_id, value_string); } - TOKEN("mall_url") + TOKEN("web_app_url") { - g_strWebMallURL = value_string; + g_strWebAppURL = value_string; + } + + TOKEN("web_app_key") + { + g_strWebAppKey = value_string; } TOKEN("view_range") @@ -1057,6 +1063,19 @@ void config_init(const string& st_localeServiceName) exit(EXIT_FAILURE); } + // Validate web app configuration + if (g_strWebAppURL.empty()) + { + SPDLOG_CRITICAL("WEB_APP_URL must be configured."); + exit(EXIT_FAILURE); + } + + if (g_strWebAppKey.empty()) + { + SPDLOG_CRITICAL("WEB_APP_KEY must be configured."); + exit(EXIT_FAILURE); + } + // LOCALE_SERVICE LocaleService_LoadLocaleStringFile(); LocaleService_TransferDefaultSetting(); diff --git a/src/game/src/config.h b/src/game/src/config.h index 6d0a264..b577e3b 100644 --- a/src/game/src/config.h +++ b/src/game/src/config.h @@ -90,7 +90,8 @@ extern int SPEEDHACK_LIMIT_BONUS; extern int g_iSyncHackLimitCount; extern int g_server_id; -extern std::string g_strWebMallURL; +extern std::string g_strWebAppURL; +extern std::string g_strWebAppKey; extern int VIEW_RANGE; extern int VIEW_BONUS_RANGE;