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