summaryrefslogtreecommitdiff
path: root/src/server/sv_client.c
diff options
context:
space:
mode:
authorThilo Schulz <arny@ats.s.bawue.de>2011-04-27 16:03:35 +0000
committerTim Angus <tim@ngus.net>2013-01-09 17:07:53 +0000
commit0d5fef7f5c33fd4176b27c79d9cef7512801f471 (patch)
tree235166fccae70dcc97fca64b64a676a8e847a96e /src/server/sv_client.c
parentc4186224a16b1dc238775bbe9ff3af4362c7d5eb (diff)
- Harden the client and server protocol against UDP spoofing attacks. This will defend ioquake3 against http://aluigi.altervista.org/papers/q3noclient.txt (#3041) - Retains full compatibility to the old but unsecure protocol between clients and servers - Harden the connection process against DoS attacks, possibly connected to UDP spoofing
Diffstat (limited to 'src/server/sv_client.c')
-rw-r--r--src/server/sv_client.c47
1 files changed, 33 insertions, 14 deletions
diff --git a/src/server/sv_client.c b/src/server/sv_client.c
index a79fc2bc..f69155c6 100644
--- a/src/server/sv_client.c
+++ b/src/server/sv_client.c
@@ -56,19 +56,36 @@ void SV_GetChallenge(netadr_t from)
int i;
int oldest;
int oldestTime;
- const char *clientChallenge = Cmd_Argv(1);
+ int oldestClientTime;
+ int clientChallenge;
challenge_t *challenge;
+ qboolean wasfound = qfalse;
oldest = 0;
- oldestTime = 0x7fffffff;
+ oldestClientTime = oldestTime = 0x7fffffff;
// see if we already have a challenge for this ip
challenge = &svs.challenges[0];
- for (i = 0 ; i < MAX_CHALLENGES ; i++, challenge++) {
- if (!challenge->connected && NET_CompareAdr( from, challenge->adr ) ) {
+ clientChallenge = atoi(Cmd_Argv(1));
+
+ for(i = 0 ; i < MAX_CHALLENGES ; i++, challenge++)
+ {
+ if(!challenge->connected && NET_CompareAdr(from, challenge->adr))
+ {
+ wasfound = qtrue;
+
+ if(challenge->time < oldestClientTime)
+ oldestClientTime = challenge->time;
+ }
+
+ if(wasfound && i >= MAX_CHALLENGES_MULTI)
+ {
+ i = MAX_CHALLENGES;
break;
}
- if ( challenge->time < oldestTime ) {
+
+ if(challenge->time < oldestTime)
+ {
oldestTime = challenge->time;
oldest = i;
}
@@ -78,10 +95,9 @@ void SV_GetChallenge(netadr_t from)
{
// this is the first time this client has asked for a challenge
challenge = &svs.challenges[oldest];
- challenge->clientChallenge = 0;
+ challenge->clientChallenge = clientChallenge;
challenge->adr = from;
challenge->firstTime = svs.time;
- challenge->time = svs.time;
challenge->connected = qfalse;
}
@@ -89,8 +105,9 @@ void SV_GetChallenge(netadr_t from)
challenge->challenge = ( (rand() << 16) ^ rand() ) ^ svs.time;
challenge->wasrefused = qfalse;
+ challenge->time = svs.time;
challenge->pingTime = svs.time;
- NET_OutOfBandPrint( NS_SERVER, challenge->adr, "challengeResponse %i %s", challenge->challenge, clientChallenge);
+ NET_OutOfBandPrint( NS_SERVER, challenge->adr, "challengeResponse %i %d", challenge->challenge, clientChallenge);
}
/*
@@ -120,10 +137,12 @@ void SV_DirectConnect( netadr_t from ) {
Q_strncpyz( userinfo, Cmd_Argv(1), sizeof(userinfo) );
- version = atoi( Info_ValueForKey( userinfo, "protocol" ) );
- if ( version != PROTOCOL_VERSION ) {
- NET_OutOfBandPrint( NS_SERVER, from, "print\nServer uses protocol version %i\n", PROTOCOL_VERSION );
- Com_DPrintf (" rejected connect from version %i\n", version);
+ version = atoi(Info_ValueForKey(userinfo, "protocol"));
+ if(version != PROTOCOL_VERSION)
+ {
+ NET_OutOfBandPrint(NS_SERVER, from, "print\nServer uses protocol version %i "
+ "(yours is %i).\n", com_protocol->integer, version);
+ Com_DPrintf(" rejected connect from version %i\n", version);
return;
}
@@ -291,7 +310,7 @@ gotnewcl:
newcl->challenge = challenge;
// save the address
- Netchan_Setup (NS_SERVER, &newcl->netchan , from, qport);
+ Netchan_Setup(NS_SERVER, &newcl->netchan, from, qport, challenge);
// init the netchan queue
newcl->netchan_end_queue = &newcl->netchan_start_queue;
@@ -312,7 +331,7 @@ gotnewcl:
SV_UserinfoChanged( newcl );
// send the connect packet to the client
- NET_OutOfBandPrint( NS_SERVER, from, "connectResponse" );
+ NET_OutOfBandPrint(NS_SERVER, from, "connectResponse %d", challenge);
Com_DPrintf( "Going from CS_FREE to CS_CONNECTED for %s\n", newcl->name );