diff options
| author | thilo <thilo@edf5b092-35ff-0310-97b2-ce42778d08ea> | 2009-06-01 05:29:28 +0000 | 
|---|---|---|
| committer | thilo <thilo@edf5b092-35ff-0310-97b2-ce42778d08ea> | 2009-06-01 05:29:28 +0000 | 
| commit | 799f155f23a3dcbe32089d18b1bb8150648f4192 (patch) | |
| tree | ddbe737b1ad6189359978648e248c93f556484c2 | |
| parent | 98980bd0cd93725f1b8e076b90cbeda132fd20a1 (diff) | |
| download | ioquake3-aero-799f155f23a3dcbe32089d18b1bb8150648f4192.tar.gz ioquake3-aero-799f155f23a3dcbe32089d18b1bb8150648f4192.zip  | |
Make client send a random challenge number in getchallenge requests
git-svn-id: svn://svn.icculus.org/quake3/trunk@1567 edf5b092-35ff-0310-97b2-ce42778d08ea
| -rw-r--r-- | code/client/cl_main.c | 68 | 
1 files changed, 46 insertions, 22 deletions
diff --git a/code/client/cl_main.c b/code/client/cl_main.c index 814e7ab..b4d3d9b 100644 --- a/code/client/cl_main.c +++ b/code/client/cl_main.c @@ -1561,10 +1561,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 ); @@ -2078,7 +2082,11 @@ void CL_CheckForResend( void ) {  		if (!Cvar_VariableIntegerValue("com_standalone") && clc.serverAddress.type == NA_IP && !Sys_IsLANAddress( clc.serverAddress ) )  			CL_RequestAuthorization();  #endif -		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, data);  		break;  	case CA_CHALLENGING: @@ -2328,21 +2336,39 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {  	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(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); +	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;  	} @@ -2353,13 +2379,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" ) );  | 
