From 2d45e6c02cfe002ff4c5a3aa6a360f918ee54e61 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Thu, 6 Apr 2006 17:53:43 +0000 Subject: Sanity check data received by the server. Send version string earlier in SYN packets to allow the fields that follow to be changed later on if necessary. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 461 --- src/net_client.c | 4 ++-- src/net_common.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++- src/net_common.h | 6 ++++- src/net_server.c | 71 ++++++++++++++++++++++++++++++++++++++++++-------------- 4 files changed, 129 insertions(+), 21 deletions(-) diff --git a/src/net_client.c b/src/net_client.c index 097b2f44..95a3f81b 100644 --- a/src/net_client.c +++ b/src/net_client.c @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: net_client.c 455 2006-03-30 19:08:37Z fraggle $ +// $Id: net_client.c 461 2006-04-06 17:53:43Z fraggle $ // // Copyright(C) 2005 Simon Howard // @@ -1012,11 +1012,11 @@ static void NET_CL_SendSYN(void) packet = NET_NewPacket(10); NET_WriteInt16(packet, NET_PACKET_TYPE_SYN); NET_WriteInt32(packet, NET_MAGIC_NUMBER); + NET_WriteString(packet, PACKAGE_STRING); NET_WriteInt16(packet, gamemode); NET_WriteInt16(packet, gamemission); NET_WriteInt8(packet, lowres_turn); NET_WriteString(packet, net_player_name); - NET_WriteString(packet, PACKAGE_STRING); NET_Conn_SendPacket(&client_connection, packet); NET_FreePacket(packet); } diff --git a/src/net_common.c b/src/net_common.c index 35bc67e1..ba8d24bf 100644 --- a/src/net_common.c +++ b/src/net_common.c @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: net_common.c 456 2006-03-30 19:13:20Z fraggle $ +// $Id: net_common.c 461 2006-04-06 17:53:43Z fraggle $ // // Copyright(C) 2005 Simon Howard // @@ -557,4 +557,71 @@ void NET_SafePuts(char *s) putchar('\n'); } +// Check that a gamemode+gamemission received over the network is valid. + +boolean NET_ValidGameMode(GameMode_t mode, GameMission_t mission) +{ + if (mode == shareware || mode == registered || mode == retail) + { + return true; + } + else if (mode == commercial) + { + return mission == doom2 || mission == pack_tnt || mission == pack_plut; + } + else + { + return false; + } +} + +// Check that game settings are valid + +boolean NET_ValidGameSettings(GameMode_t mode, GameMission_t mission, + net_gamesettings_t *settings) +{ + if (settings->ticdup <= 0) + return false; + + if (settings->extratics < 0) + return false; + + if (settings->deathmatch < 0 || settings->deathmatch > 2) + return false; + + if (settings->skill < sk_noitems || settings->skill > sk_nightmare) + return false; + + if (settings->gameversion < exe_doom_1_9 || settings->gameversion > exe_final) + return false; + + if (mode == shareware || mode == retail || mode == registered) + { + if (settings->map < 1 || settings->map > 9) + return false; + } + else + { + if (settings->map < 1 || settings->map > 32) + return false; + } + + if (mode == shareware) + { + if (settings->episode != 1) + return false; + } + else if (mode == registered) + { + if (settings->episode < 1 || settings->episode > 3) + return false; + } + else if (mode == retail) + { + if (settings->episode < 1 || settings->episode > 4) + return false; + } + + return true; +} diff --git a/src/net_common.h b/src/net_common.h index 973a66e6..d645b002 100644 --- a/src/net_common.h +++ b/src/net_common.h @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: net_common.h 412 2006-03-07 18:24:12Z fraggle $ +// $Id: net_common.h 461 2006-04-06 17:53:43Z fraggle $ // // Copyright(C) 2005 Simon Howard // @@ -135,5 +135,9 @@ net_packet_t *NET_Conn_NewReliable(net_connection_t *conn, int packet_type); void NET_SafePuts(char *msg); unsigned int NET_ExpandTicNum(unsigned int relative, unsigned int b); +boolean NET_ValidGameMode(GameMode_t mode, GameMission_t mission); +boolean NET_ValidGameSettings(GameMode_t mode, GameMission_t mission, + net_gamesettings_t *settings); + #endif /* #ifndef NET_COMMON_H */ diff --git a/src/net_server.c b/src/net_server.c index 8ecc4aa0..3a01f3b9 100644 --- a/src/net_server.c +++ b/src/net_server.c @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: net_server.c 460 2006-04-01 20:16:43Z fraggle $ +// $Id: net_server.c 461 2006-04-06 17:53:43Z fraggle $ // // Copyright(C) 2005 Simon Howard // @@ -544,6 +544,21 @@ static void NET_SV_ParseSYN(net_packet_t *packet, return; } + // Check the client version is the same as the server + // + client_version = NET_ReadString(packet); + + if (client_version == NULL) + { + return; + } + + if (strcmp(client_version, PACKAGE_STRING) != 0) + { + NET_SV_SendReject(addr, "Different versions cannot play a network game!"); + return; + } + // read the game mode and mission if (!NET_ReadInt16(packet, &cl_gamemode) @@ -553,18 +568,16 @@ static void NET_SV_ParseSYN(net_packet_t *packet, return; } - // read the player's name - - player_name = NET_ReadString(packet); - - if (player_name == NULL) + if (!NET_ValidGameMode(cl_gamemode, cl_gamemission)) { return; } - client_version = NET_ReadString(packet); + // read the player's name - if (client_version == NULL) + player_name = NET_ReadString(packet); + + if (player_name == NULL) { return; } @@ -576,6 +589,7 @@ static void NET_SV_ParseSYN(net_packet_t *packet, if (server_state != SERVER_WAITING_START) { NET_SV_SendReject(addr, "Server is not currently accepting connections"); + return; } // allocate a client slot if there isn't one already @@ -626,12 +640,6 @@ static void NET_SV_ParseSYN(net_packet_t *packet, return; } - if (strcmp(client_version, PACKAGE_STRING) != 0) - { - NET_SV_SendReject(addr, "Different versions cannot play a network game!"); - return; - } - // TODO: Add server option to allow rejecting clients which // set lowres_turn. This is potentially desirable as the // presence of such clients affects turning resolution. @@ -689,6 +697,13 @@ static void NET_SV_ParseGameStart(net_packet_t *packet, net_client_t *client) return; } + // Check the game settings are valid + + if (!NET_ValidGameSettings(sv_gamemode, sv_gamemission, &settings)) + { + return; + } + if (server_state != SERVER_WAITING_START) { // Can only start a game if we are in the waiting start state. @@ -1003,8 +1018,9 @@ static void NET_SV_SendTics(net_client_t *client, int start, int end) static void NET_SV_ParseResendRequest(net_packet_t *packet, net_client_t *client) { - static unsigned int start; - static unsigned int num_tics; + unsigned int start, last; + unsigned int num_tics; + int i; // Read the starting tic and number of tics @@ -1016,9 +1032,30 @@ static void NET_SV_ParseResendRequest(net_packet_t *packet, net_client_t *client //printf("SV: %p: resend %i-%i\n", client, start, start+num_tics-1); + // Check we have all the requested tics + + last = start + num_tics - 1; + + for (i=start; i<=last; ++i) + { + net_full_ticcmd_t *cmd; + + cmd = &client->sendqueue[i % BACKUPTICS]; + + if (i != cmd->seq) + { + // We do not have the requested tic (any more) + // This is pretty fatal. We could disconnect the client, + // but then again this could be a spoofed packet. Just + // ignore it. + + return; + } + } + // Resend those tics - NET_SV_SendTics(client, start, start + num_tics - 1); + NET_SV_SendTics(client, start, last); } -- cgit v1.2.3