aboutsummaryrefslogtreecommitdiffstats
path: root/code
diff options
context:
space:
mode:
Diffstat (limited to 'code')
-rw-r--r--code/client/cl_main.c68
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" ) );