diff options
Diffstat (limited to 'NorthstarDedicatedTest/serverauthentication.cpp')
-rw-r--r-- | NorthstarDedicatedTest/serverauthentication.cpp | 35 |
1 files changed, 18 insertions, 17 deletions
diff --git a/NorthstarDedicatedTest/serverauthentication.cpp b/NorthstarDedicatedTest/serverauthentication.cpp index 98290b34..33a57c6a 100644 --- a/NorthstarDedicatedTest/serverauthentication.cpp +++ b/NorthstarDedicatedTest/serverauthentication.cpp @@ -5,6 +5,7 @@ #include "masterserver.h" #include "httplib.h" #include "gameutils.h" +#include "bansystem.h" #include <fstream> #include <filesystem> #include <thread> @@ -22,7 +23,6 @@ CBaseClient__ConnectType CBaseClient__Connect; typedef void(*CBaseClient__ActivatePlayerType)(void* self); CBaseClient__ActivatePlayerType CBaseClient__ActivatePlayer; -typedef void(*CBaseClient__DisconnectType)(void* self, uint32_t unknownButAlways1, const char* reason, ...); CBaseClient__DisconnectType CBaseClient__Disconnect; typedef char(*CGameClient__ExecuteStringCommandType)(void* self, uint32_t unknown, const char* pCommandString); @@ -117,7 +117,6 @@ void ServerAuthenticationManager::StopPlayerAuthServer() bool ServerAuthenticationManager::AuthenticatePlayer(void* player, int64_t uid, char* authToken) { std::string strUid = std::to_string(uid); - std::lock_guard<std::mutex> guard(m_authDataMutex); bool authFail = true; @@ -142,6 +141,9 @@ bool ServerAuthenticationManager::AuthenticatePlayer(void* player, int64_t uid, if (authFail) { + // set persistent data as ready, we use 0x3 internally to mark the client as using local persistence + *((char*)player + 0x4a0) = (char)0x3; + if (!CVar_ns_auth_allow_insecure->m_nValue) // no auth data and insecure connections aren't allowed, so dc the client return false; @@ -167,9 +169,6 @@ bool ServerAuthenticationManager::AuthenticatePlayer(void* player, int64_t uid, pdataStream.read((char*)player + 0x4FA, length); pdataStream.close(); - - // set persistent data as ready, we use 0x3 internally to mark the client as using local persistence - *((char*)player + 0x4a0) = (char)0x3; } return true; // auth successful, client stays on @@ -221,7 +220,7 @@ void ServerAuthenticationManager::WritePersistentData(void* player) // store these in vars so we can use them in CBaseClient::Connect // this is fine because ptrs won't decay by the time we use this, just don't use it outside of cbaseclient::connect char* nextPlayerToken; -int64_t nextPlayerUid; +uint64_t nextPlayerUid; void* CBaseServer__ConnectClientHook(void* server, void* a2, void* a3, uint32_t a4, uint32_t a5, int32_t a6, void* a7, void* a8, char* serverFilter, void* a10, char a11, void* a12, char a13, char a14, int64_t uid, uint32_t a16, uint32_t a17) { @@ -237,6 +236,13 @@ char CBaseClient__ConnectHook(void* self, char* name, __int64 netchan_ptr_arg, c // try to auth player, dc if it fails // we connect irregardless of auth, because returning bad from this function can fuck client state p bad char ret = CBaseClient__Connect(self, name, netchan_ptr_arg, b_fake_player_arg, a5, Buffer, a7); + + if (!g_ServerBanSystem->IsUIDAllowed(nextPlayerUid)) + { + CBaseClient__Disconnect(self, 1, "Banned from server"); + return ret; + } + if (strlen(name) >= 64) // fix for name overflow bug CBaseClient__Disconnect(self, 1, "Invalid name"); else if (!g_ServerAuthenticationManager->AuthenticatePlayer(self, nextPlayerUid, nextPlayerToken) && g_MasterServerManager->m_bRequireClientAuth) @@ -329,8 +335,8 @@ char __fastcall CNetChan___ProcessMessagesHook(void* self, void* buf) double startTime = Plat_FloatTime(); char ret = CNetChan___ProcessMessages(self, buf); - // check processing limit - if (Cvar_net_chan_limit_mode->m_nValue != 0) + // check processing limits, unless we're in a level transition + if (g_pHostState->m_iCurrentState == HostState_t::HS_RUN) { // player that sent the message void* sender = *(void**)((char*)self + 368); @@ -346,19 +352,14 @@ char __fastcall CNetChan___ProcessMessagesHook(void* self, void* buf) g_ServerAuthenticationManager->m_additionalPlayerData[sender].lastNetChanProcessingLimitStart = startTime; g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime = 0.0; } - g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime += (Plat_FloatTime() * 1000) - (startTime * 1000); - int32_t limit = Cvar_net_chan_limit_msec_per_sec->m_nValue; - if (g_pHostState->m_iCurrentState != HostState_t::HS_RUN) - limit *= 2; // give clients more headroom in these states, as alot of clients will tend to time out here - - if (g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime >= limit) + if (g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime >= Cvar_net_chan_limit_msec_per_sec->m_nValue) { spdlog::warn("Client {} hit netchan processing limit with {}ms of processing time this second (max is {})", (char*)sender + 0x16, g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime, Cvar_net_chan_limit_msec_per_sec->m_nValue); - // mode 1 = kick, mode 2 = log without kicking - if (Cvar_net_chan_limit_mode->m_nValue == 1) + // nonzero = kick, 0 = warn + if (Cvar_net_chan_limit_mode->m_nValue) { CBaseClient__Disconnect(sender, 1, "Exceeded net channel processing limit"); return false; @@ -434,7 +435,7 @@ void InitialiseServerAuthentication(HMODULE baseAddress) // literally just stolen from a fix valve used in csgo CVar_sv_quota_stringcmdspersecond = RegisterConVar("sv_quota_stringcmdspersecond", "60", FCVAR_GAMEDLL, "How many string commands per second clients are allowed to submit, 0 to disallow all string commands"); // https://blog.counter-strike.net/index.php/2019/07/24922/ but different because idk how to check what current tick number is - Cvar_net_chan_limit_mode = RegisterConVar("net_chan_limit_mode", "0", FCVAR_GAMEDLL, "The mode for netchan processing limits: 0 = none, 1 = kick, 2 = log"); + Cvar_net_chan_limit_mode = RegisterConVar("net_chan_limit_mode", "0", FCVAR_GAMEDLL, "The mode for netchan processing limits: 0 = log, 1 = kick"); Cvar_net_chan_limit_msec_per_sec = RegisterConVar("net_chan_limit_msec_per_sec", "0", FCVAR_GAMEDLL, "Netchannel processing is limited to so many milliseconds, abort connection if exceeding budget"); Cvar_ns_player_auth_port = RegisterConVar("ns_player_auth_port", "8081", FCVAR_GAMEDLL, ""); Cvar_sv_querylimit_per_sec = RegisterConVar("sv_querylimit_per_sec", "15", FCVAR_GAMEDLL, ""); |