diff options
author | Thilo Schulz <arny@ats.s.bawue.de> | 2011-04-27 16:03:35 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2013-01-09 17:07:53 +0000 |
commit | 0d5fef7f5c33fd4176b27c79d9cef7512801f471 (patch) | |
tree | 235166fccae70dcc97fca64b64a676a8e847a96e /src/qcommon/net_chan.c | |
parent | c4186224a16b1dc238775bbe9ff3af4362c7d5eb (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/qcommon/net_chan.c')
-rw-r--r-- | src/qcommon/net_chan.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/src/qcommon/net_chan.c b/src/qcommon/net_chan.c index 4aacfa7e..67ef54e0 100644 --- a/src/qcommon/net_chan.c +++ b/src/qcommon/net_chan.c @@ -84,7 +84,8 @@ Netchan_Setup called to open a channel to a remote system ============== */ -void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport ) { +void Netchan_Setup(netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, int challenge) +{ Com_Memset (chan, 0, sizeof(*chan)); chan->sock = sock; @@ -191,17 +192,21 @@ void Netchan_TransmitNextFragment( netchan_t *chan ) { msg_t send; byte send_buf[MAX_PACKETLEN]; int fragmentLength; + int outgoingSequence; // write the packet header MSG_InitOOB (&send, send_buf, sizeof(send_buf)); // <-- only do the oob here - MSG_WriteLong( &send, chan->outgoingSequence | FRAGMENT_BIT ); + outgoingSequence = chan->outgoingSequence | FRAGMENT_BIT; + MSG_WriteLong(&send, outgoingSequence); // send the qport if we are a client if ( chan->sock == NS_CLIENT ) { MSG_WriteShort( &send, qport->integer ); } + MSG_WriteLong(&send, NETCHAN_GENCHECKSUM(chan->challenge, chan->outgoingSequence)); + // copy the reliable message to the packet first fragmentLength = FRAGMENT_SIZE; if ( chan->unsentFragmentStart + fragmentLength > chan->unsentLength ) { @@ -269,12 +274,14 @@ void Netchan_Transmit( netchan_t *chan, int length, const byte *data ) { MSG_InitOOB (&send, send_buf, sizeof(send_buf)); MSG_WriteLong( &send, chan->outgoingSequence ); - chan->outgoingSequence++; // send the qport if we are a client - if ( chan->sock == NS_CLIENT ) { - MSG_WriteShort( &send, qport->integer ); - } + if(chan->sock == NS_CLIENT) + MSG_WriteShort(&send, qport->integer); + + MSG_WriteLong(&send, NETCHAN_GENCHECKSUM(chan->challenge, chan->outgoingSequence)); + + chan->outgoingSequence++; MSG_WriteData( &send, data, length ); @@ -328,6 +335,12 @@ qboolean Netchan_Process( netchan_t *chan, msg_t *msg ) { qport = MSG_ReadShort( msg ); } + int checksum = MSG_ReadLong(msg); + + // UDP spoofing protection + if(NETCHAN_GENCHECKSUM(chan->challenge, sequence) != checksum) + return qfalse; + // read the fragment information if ( fragmented ) { fragmentStart = MSG_ReadShort( msg ); |