Make client send a random challenge number in getchallenge requests

This commit is contained in:
Thilo Schulz 2009-06-01 05:29:28 +00:00
parent 18cc7c1ed3
commit 02195ea8bd
1 changed files with 46 additions and 22 deletions

View File

@ -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" ) );