From f3f042ae63fc08744475863c71fafd70a541f9bd Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Sun, 15 Oct 2023 16:30:29 +0200 Subject: [PATCH] Add configurable server cvars for auth system The command execute is now guarded off on the client with the cvar 'sv_allowClientSideCfgExec' instead of 'sv_cheats'. --- src/common/callback.cpp | 4 ++-- src/common/global.cpp | 15 +++++++++++++++ src/common/global.h | 9 +++++++++ src/engine/client/client.cpp | 31 +++++++++++++++++-------------- 4 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/common/callback.cpp b/src/common/callback.cpp index a5fd14c1..7aba39e3 100644 --- a/src/common/callback.cpp +++ b/src/common/callback.cpp @@ -1508,10 +1508,10 @@ void Cmd_Exec_f(const CCommand& args) // Prevent users from running neo strafe commands and other quick hacks. // TODO: when reBar becomes a thing, we should verify this function and // flag users that patch them out. - if (!ThreadInServerFrameThread() && (!sv_cheats->GetBool() && g_pClientState->IsActive())) + if (!ThreadInServerFrameThread() && (!sv_allowClientSideCfgExec->GetBool() && g_pClientState->IsActive())) { DevWarning(eDLL_T::ENGINE, "Client is simulating and %s = false; dropped exec command: %s\n", - sv_cheats->GetName(), args.ArgS()); + sv_allowClientSideCfgExec->GetName(), args.ArgS()); return; } diff --git a/src/common/global.cpp b/src/common/global.cpp index bed9b0d3..0dc4456a 100644 --- a/src/common/global.cpp +++ b/src/common/global.cpp @@ -135,6 +135,13 @@ ConVar* sv_validatePersonaName = nullptr; ConVar* sv_minPersonaNameLength = nullptr; ConVar* sv_maxPersonaNameLength = nullptr; +ConVar* sv_onlineAuthEnable = nullptr; +ConVar* sv_onlineAuthValidateExpiry = nullptr; +ConVar* sv_onlineAuthExpiryTolerance = nullptr; + +ConVar* sv_onlineAuthValidateIssuedAt = nullptr; +ConVar* sv_onlineAuthIssuedAtTolerance = nullptr; + ConVar* sv_voiceEcho = nullptr; ConVar* sv_voiceenable = nullptr; ConVar* sv_alltalk = nullptr; @@ -153,6 +160,7 @@ ConVar* sv_rcon_maxpacketsize = nullptr; ConVar* sv_rcon_whitelist_address = nullptr; //#endif // DEDICATED #endif // !CLIENT_DLL +ConVar* sv_allowClientSideCfgExec = nullptr; ConVar* sv_cheats = nullptr; ConVar* sv_visualizetraces = nullptr; ConVar* sv_visualizetraces_duration = nullptr; @@ -371,10 +379,17 @@ void ConVar_StaticInit(void) sv_rcon_maxpacketsize = ConVar::StaticCreate("sv_rcon_maxpacketsize" , "1024", FCVAR_RELEASE, "Max number of bytes allowed in a command packet from a non-authenticated netconsole.", true, 0.f, false, 0.f, nullptr, nullptr); sv_rcon_whitelist_address = ConVar::StaticCreate("sv_rcon_whitelist_address", "" , FCVAR_RELEASE, "This address is not considered a 'redundant' socket and will never be banned for failed authentication attempts.", false, 0.f, false, 0.f, &RCON_WhiteListAddresChanged_f, "Format: '::ffff:127.0.0.1'"); + sv_allowClientSideCfgExec = ConVar::StaticCreate("sv_allowClientSideCfgExec", "0", FCVAR_REPLICATED | FCVAR_RELEASE, "Allow clients to execute script files while being connected to this server.", false, 0.f, false, 0.f, nullptr, nullptr); sv_quota_stringCmdsPerSecond = ConVar::StaticCreate("sv_quota_stringCmdsPerSecond", "16", FCVAR_RELEASE, "How many string commands per second clients are allowed to submit, 0 to disallow all string commands.", true, 0.f, false, 0.f, nullptr, nullptr); sv_validatePersonaName = ConVar::StaticCreate("sv_validatePersonaName" , "1" , FCVAR_RELEASE, "Validate the client's textual persona name on connect.", true, 0.f, false, 0.f, nullptr, nullptr); sv_minPersonaNameLength = ConVar::StaticCreate("sv_minPersonaNameLength", "4" , FCVAR_RELEASE, "The minimum length of the client's textual persona name.", true, 0.f, false, 0.f, nullptr, nullptr); sv_maxPersonaNameLength = ConVar::StaticCreate("sv_maxPersonaNameLength", "16", FCVAR_RELEASE, "The maximum length of the client's textual persona name.", true, 0.f, false, 0.f, nullptr, nullptr); + + sv_onlineAuthEnable = ConVar::StaticCreate("sv_onlineAuthEnable" , "1" , FCVAR_RELEASE, "Enables the online authentication system.", true, 0.f, true, 1.f, nullptr, nullptr); + sv_onlineAuthValidateExpiry = ConVar::StaticCreate("sv_onlineAuthValidateExpiry" , "1" , FCVAR_RELEASE, "Validate the online authentication token 'expiry' claim.", true, 0.f, true, 1.f, nullptr, nullptr); + sv_onlineAuthExpiryTolerance = ConVar::StaticCreate("sv_onlineAuthExpiryTolerance" , "1" , FCVAR_RELEASE, "The online authentication token 'expiry' claim tolerance in seconds.", true, 0.f, true, float(UINT8_MAX), nullptr, "Must range between [0,255]"); + sv_onlineAuthValidateIssuedAt = ConVar::StaticCreate("sv_onlineAuthValidateIssuedAt" , "1" , FCVAR_RELEASE, "Validate the online authentication token 'issued at' claim.", true, 0.f, true, 1.f, nullptr, nullptr); + sv_onlineAuthIssuedAtTolerance = ConVar::StaticCreate("sv_onlineAuthIssuedAtTolerance", "30", FCVAR_RELEASE, "The online authentication token 'issued at' claim tolerance in seconds.", true, 0.f, true, float(UINT8_MAX), nullptr, "Must range between [0,255]"); #endif // !CLIENT_DLL #if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) bhit_depth_test = ConVar::StaticCreate("bhit_depth_test", "0", FCVAR_DEVELOPMENTONLY | FCVAR_REPLICATED, "Use depth test for bullet ray trace overlay.", false, 0.f, false, 0.f, nullptr, nullptr); diff --git a/src/common/global.h b/src/common/global.h index 0463d290..586eef16 100644 --- a/src/common/global.h +++ b/src/common/global.h @@ -124,6 +124,14 @@ extern ConVar* sv_validatePersonaName; extern ConVar* sv_minPersonaNameLength; extern ConVar* sv_maxPersonaNameLength; +extern ConVar* sv_onlineAuthEnable; + +extern ConVar* sv_onlineAuthValidateExpiry; +extern ConVar* sv_onlineAuthExpiryTolerance; + +extern ConVar* sv_onlineAuthValidateIssuedAt; +extern ConVar* sv_onlineAuthIssuedAtTolerance; + extern ConVar* sv_voiceEcho; extern ConVar* sv_voiceenable; extern ConVar* sv_alltalk; @@ -142,6 +150,7 @@ extern ConVar* sv_rcon_maxpacketsize; extern ConVar* sv_rcon_whitelist_address; //#endif // DEDICATED #endif // CLIENT_DLL +extern ConVar* sv_allowClientSideCfgExec; extern ConVar* sv_cheats; extern ConVar* sv_visualizetraces; extern ConVar* sv_visualizetraces_duration; diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index e52c7b2d..819fefe6 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -62,9 +62,9 @@ bool CClient::Authenticate(const char* const playerName, char* const reasonBuf, #define FORMAT_ERROR_REASON(fmt, ...) V_snprintf(reasonBuf, reasonBufLen, fmt, ##__VA_ARGS__); - KeyValues* cl_onlineAuthTokenKv = this->m_ConVars->FindKey("cl_onlineAuthToken"); - KeyValues* cl_onlineAuthTokenSignature1Kv = this->m_ConVars->FindKey("cl_onlineAuthTokenSignature1"); - KeyValues* cl_onlineAuthTokenSignature2Kv = this->m_ConVars->FindKey("cl_onlineAuthTokenSignature2"); + KeyValues* const cl_onlineAuthTokenKv = this->m_ConVars->FindKey("cl_onlineAuthToken"); + KeyValues* const cl_onlineAuthTokenSignature1Kv = this->m_ConVars->FindKey("cl_onlineAuthTokenSignature1"); + KeyValues* const cl_onlineAuthTokenSignature2Kv = this->m_ConVars->FindKey("cl_onlineAuthTokenSignature2"); if (!cl_onlineAuthTokenKv || !cl_onlineAuthTokenSignature1Kv) { @@ -72,9 +72,9 @@ bool CClient::Authenticate(const char* const playerName, char* const reasonBuf, return false; } - const char* onlineAuthToken = cl_onlineAuthTokenKv->GetString(); - const char* onlineAuthTokenSignature1 = cl_onlineAuthTokenSignature1Kv->GetString(); - const char* onlineAuthTokenSignature2 = cl_onlineAuthTokenSignature2Kv->GetString(); + const char* const onlineAuthToken = cl_onlineAuthTokenKv->GetString(); + const char* const onlineAuthTokenSignature1 = cl_onlineAuthTokenSignature1Kv->GetString(); + const char* const onlineAuthTokenSignature2 = cl_onlineAuthTokenSignature2Kv->GetString(); const std::string fullToken = Format("%s.%s%s", onlineAuthToken, onlineAuthTokenSignature1, onlineAuthTokenSignature2); @@ -89,11 +89,11 @@ bool CClient::Authenticate(const char* const playerName, char* const reasonBuf, params.verification_key = (unsigned char*)JWT_PUBLIC_KEY; params.verification_key_length = strlen(JWT_PUBLIC_KEY); - params.validate_exp = 1; - params.exp_tolerance_seconds = 1; + params.validate_exp = sv_onlineAuthValidateExpiry->GetBool(); + params.exp_tolerance_seconds = (uint8_t)sv_onlineAuthExpiryTolerance->GetInt(); - params.validate_iat = 1; - params.iat_tolerance_seconds = 30; + params.validate_iat = sv_onlineAuthValidateIssuedAt->GetBool(); + params.iat_tolerance_seconds = (uint8_t)sv_onlineAuthIssuedAtTolerance->GetInt(); l8w8jwt_claim* claims = nullptr; size_t numClaims = 0; @@ -180,11 +180,14 @@ bool CClient::Connect(const char* szName, void* pNetChannel, bool bFakePlayer, #define REJECT_CONNECTION(fmt, ...) V_snprintf(szMessage, nMessageSize, fmt, ##__VA_ARGS__); - char authFailReason[512]; - if (!Authenticate(szName, authFailReason, sizeof(authFailReason))) + if (sv_onlineAuthEnable->GetBool()) { - REJECT_CONNECTION("Failed to verify authentication token [%s]", authFailReason); - return false; + char authFailReason[512]; + if (!Authenticate(szName, authFailReason, sizeof(authFailReason))) + { + REJECT_CONNECTION("Failed to verify authentication token [%s]", authFailReason); + return false; + } } #undef REJECT_CONNECTION