From c772fb98d178ab3f5ecb71bae051996d46daf541 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Sat, 7 Feb 2026 20:34:52 +0500 Subject: [PATCH] engine: client: salt xashid with server address --- engine/client/cl_main.c | 15 ++++++----- engine/client/client.h | 2 +- engine/client/identification.c | 46 +++++++++++++++++++++++----------- 3 files changed, 41 insertions(+), 22 deletions(-) diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index d7eba21b..6e7a1ef7 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -1054,7 +1054,8 @@ static void CL_GetCDKey( char *protinfo, size_t protinfosize ) static void CL_WriteSteamTicket( sizebuf_t *send ) { - const char *s; + string key; + netadr_t adr = { .type = NA_LOOPBACK, }; // goldsrc servers don't get unique key as xashid isn't sent raw to them uint32_t crc; char buf[768] = { 0 }; // setti and steamemu return 768 int i = sizeof( buf ); @@ -1072,11 +1073,11 @@ static void CL_WriteSteamTicket( sizebuf_t *send ) // return; //} - s = ID_GetMD5(); + ID_GetMD5ForAddress( key, adr, sizeof( key )); CRC32_Init( &crc ); - CRC32_ProcessBuffer( &crc, s, Q_strlen( s )); + CRC32_ProcessBuffer( &crc, key, Q_strlen( key )); crc = CRC32_Final( crc ); - i = GenerateRevEmu2013( buf, s, crc ); + i = GenerateRevEmu2013( buf, key, crc ); MSG_WriteBytes( send, buf, i ); // RevEmu2013: pTicket[1] = revHash (low), pTicket[5] = 0x01100001 (high) @@ -1095,7 +1096,6 @@ connect. static void CL_SendConnectPacket( connprotocol_t proto, int challenge ) { char protinfo[MAX_INFO_STRING]; - const char *key = ID_GetMD5(); netadr_t adr = { 0 }; int input_devices; netadrtype_t adrtype; @@ -1158,6 +1158,9 @@ static void CL_SendConnectPacket( connprotocol_t proto, int challenge ) { const char *qport = Cvar_VariableString( "net_qport" ); int extensions = NET_EXT_SPLITSIZE; + string key; + + ID_GetMD5ForAddress( key, adr, sizeof( key )); // reset nickname from cvar value Info_SetValueForKey( cls.userinfo, "name", name.string, sizeof( cls.userinfo )); @@ -1167,7 +1170,7 @@ static void CL_SendConnectPacket( connprotocol_t proto, int challenge ) Info_SetValueForKey( protinfo, "uuid", key, sizeof( protinfo )); Info_SetValueForKey( protinfo, "qport", qport, sizeof( protinfo )); - Info_SetValueForKeyf( protinfo, "ext", sizeof( protinfo ), "%d", extensions); + Info_SetValueForKeyf( protinfo, "ext", sizeof( protinfo ), "%d", extensions ); Netchan_OutOfBandPrint( NS_CLIENT, adr, C2S_CONNECT" %i %i \"%s\" \"%s\"\n", PROTOCOL_VERSION, challenge, protinfo, cls.userinfo ); Con_Printf( "Trying to connect with modern protocol\n" ); diff --git a/engine/client/client.h b/engine/client/client.h index 808dc52a..73dbb624 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -1228,7 +1228,7 @@ void OSK_Draw( void ); // identification.c // void ID_Init( void ); -const char *ID_GetMD5( void ); +void ID_GetMD5ForAddress( char *key, netadr_t adr, size_t size ); extern rgba_t g_color_table[8]; extern triangleapi_t gTriApi; diff --git a/engine/client/identification.c b/engine/client/identification.c index fefbaee7..336205cf 100644 --- a/engine/client/identification.c +++ b/engine/client/identification.c @@ -22,8 +22,6 @@ GNU General Public License for more details. #include #endif -static char id_md5[33]; - /* ========================================================== @@ -634,17 +632,42 @@ static void ID_Check( void ) #endif } -const char *ID_GetMD5( void ) +void ID_GetMD5ForAddress( char *key, netadr_t adr, size_t size ) { - return id_md5; + MD5Context_t ctx; + byte buf[32], md5[16]; + size_t bufsize = 0; + bloomfilter_t value = id; + + switch( NET_NetadrType( &adr )) + { + // local server case + case NA_IP: + memcpy( buf, adr.ip, sizeof( adr.ip )); + memcpy( buf + sizeof( adr.ip ), &adr.port, sizeof( adr.port )); + bufsize = sizeof( adr.ip ) + sizeof( adr.port ); + break; + case NA_IP6: + NET_NetadrToIP6Bytes( buf, &adr ); + memcpy( buf + 16, &adr.port, sizeof( adr.port )); + bufsize = 16 + sizeof( adr.port ); + break; + default: + bufsize = 0; + break; + } + + if( bufsize != 0 ) + value = BloomFilter_Process( buf, bufsize ); + + MD5Init( &ctx ); + MD5Update( &ctx, (byte *)&value, sizeof( value )); + MD5Final( md5, &ctx ); + Q_strnlwr( MD5_Print( md5 ), key, size ); } void ID_Init( void ) { - MD5Context_t hash = { 0 }; - byte md5[16]; - int i; - Cmd_AddRestrictedCommand( "bloomfilter", ID_BloomFilter_f, "print bloomfilter raw value of arguments set"); Cmd_AddRestrictedCommand( "verifyhex", ID_VerifyHEX_f, "check if id source seems to be fake" ); #if XASH_LINUX @@ -703,13 +726,6 @@ void ID_Init( void ) if( !id ) id = ID_GenerateRawId(); - MD5Init( &hash ); - MD5Update( &hash, (byte *)&id, sizeof( id ) ); - MD5Final( (byte*)md5, &hash ); - - for( i = 0; i < 16; i++ ) - Q_snprintf( &id_md5[i*2], sizeof( id_md5 ) - i * 2, "%02hhx", md5[i] ); - #if XASH_ANDROID && !XASH_DEDICATED Android_SaveID( va("%016"PRIX64, id^SYSTEM_XOR_MASK ) ); #elif XASH_WIN32