From 33d493b502d00afe847c5b2efe311aadc29250c4 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Tue, 23 Feb 2016 02:03:05 +0100 Subject: [PATCH] Security feedback --- deps/protobuf | 2 +- src/Components/Modules/Auth.cpp | 100 +++++++++++++++++++++++++++++-- src/Components/Modules/Auth.hpp | 15 ++++- src/Components/Modules/Party.cpp | 4 +- 4 files changed, 113 insertions(+), 8 deletions(-) diff --git a/deps/protobuf b/deps/protobuf index 32daf513..8f67b165 160000 --- a/deps/protobuf +++ b/deps/protobuf @@ -1 +1 @@ -Subproject commit 32daf513ced8d51e8de6cc8d800cfc972c4df5d6 +Subproject commit 8f67b165f0a949219fafc48c533be3fbf53497b7 diff --git a/src/Components/Modules/Auth.cpp b/src/Components/Modules/Auth.cpp index c1024c27..b59772ce 100644 --- a/src/Components/Modules/Auth.cpp +++ b/src/Components/Modules/Auth.cpp @@ -3,6 +3,7 @@ namespace Components { Auth::AuthInfo Auth::ClientAuthInfo[18]; + Auth::TokenIncrementing Auth::TokenContainer; Utils::Cryptography::Token Auth::GuidToken; Utils::Cryptography::ECDSA::Key Auth::GuidKey; @@ -48,6 +49,39 @@ namespace Components } } } + + if (Auth::TokenContainer.generating) + { + Localization::Set("MPUI_SECURITY_INCREASE_MESSAGE", Utils::VA("Increasing security level from %d to %d"/* (approx. 1 min)"*/, Auth::GetSecurityLevel(), Auth::TokenContainer.targetLevel)); + } + else if(Auth::TokenContainer.thread) + { + if (Auth::TokenContainer.thread->joinable()) + { + Auth::TokenContainer.thread->join(); + } + + delete Auth::TokenContainer.thread; + Auth::TokenContainer.thread = nullptr; + Auth::TokenContainer.generating = false; + + Logger::Print("Security level is %d\n", Auth::GetSecurityLevel()); + Command::Execute("closemenu security_increase_popmenu", false); + + if (!Auth::TokenContainer.cancel) + { + if (Auth::TokenContainer.command.empty()) + { + Game::MessageBox(Utils::VA("Your new security level is now %d", Auth::GetSecurityLevel()), "Success"); + } + else + { + Command::Execute(Auth::TokenContainer.command, false); + } + } + + Auth::TokenContainer.cancel = false; + } } void Auth::RegisterClient(int clientNum) @@ -126,6 +160,35 @@ namespace Components return Auth::GetZeroBits(Auth::GuidToken, Auth::GuidKey.GetPublicKey()); } + void Auth::IncreaseSecurityLevel(uint32_t level, std::string command) + { + if (Auth::GetSecurityLevel() >= level) return; + + if (!Auth::TokenContainer.generating) + { + Auth::TokenContainer.cancel = false; + Auth::TokenContainer.targetLevel = level; + Auth::TokenContainer.command = command; + + // Open menu + Command::Execute("openmenu security_increase_popmenu", true); + + // Start thread + Auth::TokenContainer.thread = new std::thread([&level] () + { + Auth::TokenContainer.generating = true; + Auth::TokenContainer.startTime = Game::Com_Milliseconds(); + Auth::IncrementToken(Auth::GuidToken, Auth::GuidKey.GetPublicKey(), Auth::TokenContainer.targetLevel, &Auth::TokenContainer.cancel); + Auth::TokenContainer.generating = false; + + if (Auth::TokenContainer.cancel) + { + Logger::Print("Token incrementation thread terminated\n"); + } + }); + } + } + uint32_t Auth::GetZeroBits(Utils::Cryptography::Token token, std::string publicKey) { std::string message = publicKey + token.ToString(); @@ -156,7 +219,7 @@ namespace Components return bits; } - void Auth::IncrementToken(Utils::Cryptography::Token& token, std::string publicKey, uint32_t zeroBits) + void Auth::IncrementToken(Utils::Cryptography::Token& token, std::string publicKey, uint32_t zeroBits, bool* cancel) { if (zeroBits > 512) return; // Not possible, due to SHA512 @@ -178,6 +241,9 @@ namespace Components token = tempToken; lastLevel = level; } + + // Allow canceling that shit + if (cancel && *cancel) return; } while (level < zeroBits); @@ -186,6 +252,12 @@ namespace Components Auth::Auth() { + Auth::TokenContainer.cancel = false; + Auth::TokenContainer.generating = false; + Auth::TokenContainer.thread = nullptr; + + Localization::Set("MPUI_SECURITY_INCREASE_MESSAGE", ""); + Auth::LoadKey(true); // Only clients receive the auth request @@ -293,21 +365,39 @@ namespace Components if (params.Length() < 2) { Logger::Print("Your current security level is %d\n", Auth::GetZeroBits(Auth::GuidToken, Auth::GuidKey.GetPublicKey())); + Logger::Print("Your security token is: %s\n", Utils::DumpHex(Auth::GuidToken.ToString(), "").data()); } else { uint32_t level = static_cast(atoi(params[1])); - Logger::Print("Incrementing security level from %d to %d...\n", Auth::GetSecurityLevel(), level); - Auth::IncrementToken(Auth::GuidToken, Auth::GuidKey.GetPublicKey(), level); - Logger::Print("Your new security level is %d\n", Auth::GetSecurityLevel()); + Auth::IncreaseSecurityLevel(level); } + }); - Logger::Print("Your security token is: %s\n", Utils::DumpHex(Auth::GuidToken.ToString(), "").data()); + UIScript::Add("security_increase_cancel", [] () + { + Auth::TokenContainer.cancel = true; + Logger::Print("Token incrementation process canceled!\n"); }); } Auth::~Auth() { + Auth::TokenContainer.cancel = true; + Auth::TokenContainer.generating = false; + + // Terminate thread + if (Auth::TokenContainer.thread) + { + if (Auth::TokenContainer.thread->joinable()) + { + Auth::TokenContainer.thread->join(); + } + + delete Auth::TokenContainer.thread; + Auth::TokenContainer.thread = nullptr; + } + Auth::StoreKey(); } diff --git a/src/Components/Modules/Auth.hpp b/src/Components/Modules/Auth.hpp index 93dd1db5..64de02dd 100644 --- a/src/Components/Modules/Auth.hpp +++ b/src/Components/Modules/Auth.hpp @@ -13,8 +13,10 @@ namespace Components static unsigned int GetKeyHash(); static uint32_t GetSecurityLevel(); + static void IncreaseSecurityLevel(uint32_t level, std::string command = ""); + static uint32_t GetZeroBits(Utils::Cryptography::Token token, std::string publicKey); - static void IncrementToken(Utils::Cryptography::Token& token, std::string publicKey, uint32_t zeroBits); + static void IncrementToken(Utils::Cryptography::Token& token, std::string publicKey, uint32_t zeroBits, bool* cancel = nullptr); private: @@ -34,7 +36,18 @@ namespace Components int time; }; + struct TokenIncrementing + { + bool cancel; + bool generating; + std::thread* thread; + uint32_t targetLevel; + int startTime; + std::string command; + }; + static AuthInfo ClientAuthInfo[18]; + static TokenIncrementing TokenContainer; static Utils::Cryptography::Token GuidToken; static Utils::Cryptography::ECDSA::Key GuidKey; diff --git a/src/Components/Modules/Party.cpp b/src/Components/Modules/Party.cpp index f096a07a..93ef8c89 100644 --- a/src/Components/Modules/Party.cpp +++ b/src/Components/Modules/Party.cpp @@ -334,7 +334,9 @@ namespace Components } else if (securityLevel > Auth::GetSecurityLevel()) { - Party::ConnectError(Utils::VA("Your security level (%d) is lower than the server's (%d)", Auth::GetSecurityLevel(), securityLevel)); + //Party::ConnectError(Utils::VA("Your security level (%d) is lower than the server's (%d)", Auth::GetSecurityLevel(), securityLevel)); + Command::Execute("closemenu popup_reconnectingtoparty"); + Auth::IncreaseSecurityLevel(securityLevel, "reconnect"); } else if (!matchType) {