diff options
Diffstat (limited to 'src/client/cl_main.c')
-rw-r--r-- | src/client/cl_main.c | 114 |
1 files changed, 75 insertions, 39 deletions
diff --git a/src/client/cl_main.c b/src/client/cl_main.c index 47cf0196..16fbe56b 100644 --- a/src/client/cl_main.c +++ b/src/client/cl_main.c @@ -194,8 +194,10 @@ void CL_UpdateVoipIgnore(const char *idstr, qboolean ignore) ignore ? "ignore" : "unignore", id)); Com_Printf("VoIP: %s ignoring player #%d\n", ignore ? "Now" : "No longer", id); + return; } } + Com_Printf("VoIP: invalid player ID#\n"); } static @@ -234,7 +236,19 @@ void CL_Voip_f( void ) } else if (strcmp(cmd, "unignore") == 0) { CL_UpdateVoipIgnore(Cmd_Argv(2), qfalse); } else if (strcmp(cmd, "gain") == 0) { - CL_UpdateVoipGain(Cmd_Argv(2), atof(Cmd_Argv(3))); + if (Cmd_Argc() > 3) { + CL_UpdateVoipGain(Cmd_Argv(2), atof(Cmd_Argv(3))); + } else if (Q_isanumber(Cmd_Argv(2))) { + int id = atoi(Cmd_Argv(2)); + if (id >= 0 && id < MAX_CLIENTS) { + Com_Printf("VoIP: current gain for player #%d " + "is %f\n", id, clc.voipGain[id]); + } else { + Com_Printf("VoIP: invalid player ID#\n"); + } + } else { + Com_Printf("usage: voip gain <playerID#> [value]\n"); + } } else if (strcmp(cmd, "muteall") == 0) { Com_Printf("VoIP: muting incoming voice\n"); CL_AddReliableCommand("voip muteall"); @@ -243,6 +257,10 @@ void CL_Voip_f( void ) Com_Printf("VoIP: unmuting incoming voice\n"); CL_AddReliableCommand("voip unmuteall"); clc.voipMuteAll = qfalse; + } else { + Com_Printf("usage: voip [un]ignore <playerID#>\n" + " voip [un]muteall\n" + " voip gain <playerID#> [value]\n"); } } @@ -1354,11 +1372,7 @@ void CL_RequestMotd( void ) { NET_AdrToStringwPort( cls.updateServer ) ); info[0] = 0; - // NOTE TTimo xoring against Com_Milliseconds, otherwise we may not have a true randomization - // only srand I could catch before here is tr_noise.c l:26 srand(1001) - // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=382 - // NOTE: the Com_Milliseconds xoring only affects the lower 16-bit word, - // but I decided it was enough randomization + Com_sprintf( cls.updateChallenge, sizeof( cls.updateChallenge ), "%i", ((rand() << 16) ^ rand()) ^ Com_Milliseconds()); @@ -1531,10 +1545,14 @@ void CL_Connect_f( void ) { // if we aren't playing on a lan, we need to authenticate // with the cd key - if ( NET_IsLocalAddress( clc.serverAddress ) ) { + if(NET_IsLocalAddress(clc.serverAddress)) cls.state = CA_CHALLENGING; - } else { + else + { cls.state = CA_CONNECTING; + + // Set a client challenge number that ideally is mirrored back by the server. + clc.challenge = ((rand() << 16) ^ rand()) ^ Com_Milliseconds(); } Key_SetCatcher( 0 ); @@ -2129,7 +2147,11 @@ void CL_CheckForResend( void ) { switch ( cls.state ) { case CA_CONNECTING: // requesting a challenge - NET_OutOfBandPrint(NS_CLIENT, clc.serverAddress, "getchallenge"); + + // The challenge request shall be followed by a client challenge so no malicious server can hijack this connection. + Com_sprintf(data, sizeof(data), "getchallenge %d", clc.challenge); + + NET_OutOfBandPrint(NS_CLIENT, clc.serverAddress, "%s", data); break; case CA_CHALLENGING: @@ -2505,8 +2527,7 @@ Responses to broadcasts, etc */ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) { char *s; - char c[ BIG_INFO_STRING ]; - char arg1[ BIG_INFO_STRING ]; + char *c; MSG_BeginReadingOOB( msg ); MSG_ReadLong( msg ); // skip the -1 @@ -2515,27 +2536,44 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) { Cmd_TokenizeString( s ); - Q_strncpyz( c, Cmd_Argv( 0 ), BIG_INFO_STRING ); - Q_strncpyz( arg1, Cmd_Argv( 1 ), BIG_INFO_STRING ); + c = Cmd_Argv(0); Com_DPrintf ("CL packet %s: %s\n", NET_AdrToStringwPort(from), c); // challenge from the server we are connecting to - if ( !Q_stricmp(c, "challengeResponse") ) { - if ( cls.state != CA_CONNECTING ) { - Com_DPrintf( "Unwanted challenge response received. Ignored.\n" ); - } else { - // start sending challenge repsonse instead of challenge request packets - clc.challenge = atoi(arg1); - cls.state = CA_CHALLENGING; - clc.connectPacketCount = 0; - clc.connectTime = -99999; - - // take this address as the new server address. This allows - // a server proxy to hand off connections to multiple servers - clc.serverAddress = from; - Com_DPrintf ("challengeResponse: %d\n", clc.challenge); + if (!Q_stricmp(c, "challengeResponse")) + { + if (cls.state != CA_CONNECTING) + { + Com_DPrintf("Unwanted challenge response received. Ignored.\n"); + return; + } + + if(!NET_CompareAdr(from, clc.serverAddress)) + { + // This challenge response is not coming from the expected address. + // Check whether we have a matching client challenge to prevent + // connection hi-jacking. + + c = Cmd_Argv(2); + + if(!*c || atoi(c) != clc.challenge) + { + Com_DPrintf("Challenge response received from unexpected source. Ignored.\n"); + return; + } } + + // start sending challenge response instead of challenge request packets + clc.challenge = atoi(Cmd_Argv(1)); + cls.state = CA_CHALLENGING; + clc.connectPacketCount = 0; + clc.connectTime = -99999; + + // take this address as the new server address. This allows + // a server proxy to hand off connections to multiple servers + clc.serverAddress = from; + Com_DPrintf ("challengeResponse: %d\n", clc.challenge); return; } @@ -2546,13 +2584,11 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) { return; } if ( cls.state != CA_CHALLENGING ) { - Com_Printf ("connectResponse packet while not connecting. Ignored.\n"); + Com_Printf ("connectResponse packet while not connecting. Ignored.\n"); return; } - if ( !NET_CompareBaseAdr( from, clc.serverAddress ) ) { - Com_Printf( "connectResponse from a different address. Ignored.\n" ); - Com_Printf( "%s should have been %s\n", NET_AdrToStringwPort( from ), - NET_AdrToStringwPort( clc.serverAddress ) ); + if ( !NET_CompareAdr( from, clc.serverAddress ) ) { + Com_Printf( "connectResponse from wrong address. Ignored.\n" ); return; } Netchan_Setup (NS_CLIENT, &clc.netchan, from, Cvar_VariableValue( "net_qport" ) ); @@ -2582,7 +2618,7 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) { // echo request from server if ( !Q_stricmp(c, "echo") ) { - NET_OutOfBandPrint( NS_CLIENT, from, "%s", arg1 ); + NET_OutOfBandPrint( NS_CLIENT, from, "%s", Cmd_Argv(1) ); return; } @@ -3544,7 +3580,7 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) { if ( cl_pinglist[i].adr.port && !cl_pinglist[i].time && NET_CompareAdr( from, cl_pinglist[i].adr ) ) { // calc ping time - cl_pinglist[i].time = cls.realtime - cl_pinglist[i].start + 1; + cl_pinglist[i].time = Sys_Milliseconds() - cl_pinglist[i].start; Com_DPrintf( "ping time %dms from %s\n", cl_pinglist[i].time, NET_AdrToString( from ) ); // save of info @@ -3936,7 +3972,7 @@ void CL_GetPing( int n, char *buf, int buflen, int *pingtime ) if (!time) { // check for timeout - time = cls.realtime - cl_pinglist[n].start; + time = Sys_Milliseconds() - cl_pinglist[n].start; maxPing = Cvar_VariableIntegerValue( "cl_maxPing" ); if( maxPing < 100 ) { maxPing = 100; @@ -4043,7 +4079,7 @@ ping_t* CL_GetFreePing( void ) { if (!pingptr->time) { - if (cls.realtime - pingptr->start < 500) + if (Sys_Milliseconds() - pingptr->start < 500) { // still waiting for response continue; @@ -4068,7 +4104,7 @@ ping_t* CL_GetFreePing( void ) for (i=0; i<MAX_PINGREQUESTS; i++, pingptr++ ) { // scan for oldest - time = cls.realtime - pingptr->start; + time = Sys_Milliseconds() - pingptr->start; if (time > oldest) { oldest = time; @@ -4121,7 +4157,7 @@ void CL_Ping_f( void ) { pingptr = CL_GetFreePing(); memcpy( &pingptr->adr, &to, sizeof (netadr_t) ); - pingptr->start = cls.realtime; + pingptr->start = Sys_Milliseconds(); pingptr->time = 0; CL_SetServerInfoByAddress(pingptr->adr, NULL, 0); @@ -4193,7 +4229,7 @@ qboolean CL_UpdateVisiblePings_f(int source) { } } memcpy(&cl_pinglist[j].adr, &server[i].adr, sizeof(netadr_t)); - cl_pinglist[j].start = cls.realtime; + cl_pinglist[j].start = Sys_Milliseconds(); cl_pinglist[j].time = 0; NET_OutOfBandPrint( NS_CLIENT, cl_pinglist[j].adr, "getinfo xxx" ); slots++; |