* (bug 3027) don't trust the "ip" value in the userinfo string since a client

could set this.  disconnect (or disallow connection for) a client that
  has a userinfo string that's too full for "ip" to be added properly.
  (Richard Stanway)
This commit is contained in:
Tony J. White = 2007-02-14 23:14:25 +00:00
parent 7379c3920f
commit da75e9fda8
1 changed files with 32 additions and 16 deletions

View File

@ -238,6 +238,7 @@ void SV_DirectConnect( netadr_t from ) {
int startIndex; int startIndex;
intptr_t denied; intptr_t denied;
int count; int count;
char *ip;
Com_DPrintf ("SVC_DirectConnect ()\n"); Com_DPrintf ("SVC_DirectConnect ()\n");
@ -270,6 +271,19 @@ void SV_DirectConnect( netadr_t from ) {
} }
} }
// don't let "ip" overflow userinfo string
if ( NET_IsLocalAddress (from) )
ip = "localhost";
else
ip = (char *)NET_AdrToString( from );
if( ( strlen( ip ) + strlen( userinfo ) + 4 ) >= MAX_INFO_STRING ) {
NET_OutOfBandPrint( NS_SERVER, from,
"print\nUserinfo string length exceeded. "
"Try removing setu cvars from your config.\n" );
return;
}
Info_SetValueForKey( userinfo, "ip", ip );
// see if the challenge is valid (LAN clients don't need to challenge) // see if the challenge is valid (LAN clients don't need to challenge)
if ( !NET_IsLocalAddress (from) ) { if ( !NET_IsLocalAddress (from) ) {
int ping; int ping;
@ -285,8 +299,6 @@ void SV_DirectConnect( netadr_t from ) {
NET_OutOfBandPrint( NS_SERVER, from, "print\nNo or bad challenge for address.\n" ); NET_OutOfBandPrint( NS_SERVER, from, "print\nNo or bad challenge for address.\n" );
return; return;
} }
// force the IP key/value pair so the game can filter based on ip
Info_SetValueForKey( userinfo, "ip", NET_AdrToString( from ) );
ping = svs.time - svs.challenges[i].pingTime; ping = svs.time - svs.challenges[i].pingTime;
Com_Printf( "Client %i connecting with %i challenge ping\n", i, ping ); Com_Printf( "Client %i connecting with %i challenge ping\n", i, ping );
@ -309,9 +321,6 @@ void SV_DirectConnect( netadr_t from ) {
return; return;
} }
} }
} else {
// force the "ip" info key to "localhost"
Info_SetValueForKey( userinfo, "ip", "localhost" );
} }
newcl = &temp; newcl = &temp;
@ -1165,7 +1174,9 @@ into a more C friendly form.
*/ */
void SV_UserinfoChanged( client_t *cl ) { void SV_UserinfoChanged( client_t *cl ) {
char *val; char *val;
char *ip;
int i; int i;
int len;
// name for C code // name for C code
Q_strncpyz( cl->name, Info_ValueForKey (cl->userinfo, "name"), sizeof(cl->name) ); Q_strncpyz( cl->name, Info_ValueForKey (cl->userinfo, "name"), sizeof(cl->name) );
@ -1214,18 +1225,23 @@ void SV_UserinfoChanged( client_t *cl ) {
// TTimo // TTimo
// maintain the IP information // maintain the IP information
// this is set in SV_DirectConnect (directly on the server, not transmitted), may be lost when client updates it's userinfo
// the banning code relies on this being consistently present // the banning code relies on this being consistently present
val = Info_ValueForKey (cl->userinfo, "ip"); if( NET_IsLocalAddress(cl->netchan.remoteAddress) )
if (!val[0]) ip = "localhost";
{ else
//Com_DPrintf("Maintain IP in userinfo for '%s'\n", cl->name); ip = (char*)NET_AdrToString( cl->netchan.remoteAddress );
if ( !NET_IsLocalAddress(cl->netchan.remoteAddress) )
Info_SetValueForKey( cl->userinfo, "ip", NET_AdrToString( cl->netchan.remoteAddress ) ); val = Info_ValueForKey( cl->userinfo, "ip" );
else if( val[0] )
// force the "ip" info key to "localhost" for local clients len = strlen( ip ) - strlen( val ) + strlen( cl->userinfo );
Info_SetValueForKey( cl->userinfo, "ip", "localhost" ); else
} len = strlen( ip ) + 4 + strlen( cl->userinfo );
if( len >= MAX_INFO_STRING )
SV_DropClient( cl, "userinfo string length exceeded" );
else
Info_SetValueForKey( cl->userinfo, "ip", ip );
} }