diff options
-rw-r--r-- | src/net_defs.h | 8 | ||||
-rw-r--r-- | src/net_query.c | 127 | ||||
-rw-r--r-- | src/net_sdl.c | 13 | ||||
-rw-r--r-- | src/net_structrw.c | 32 | ||||
-rw-r--r-- | src/net_structrw.h | 4 |
5 files changed, 176 insertions, 8 deletions
diff --git a/src/net_defs.h b/src/net_defs.h index d9e3b920..c2d4d561 100644 --- a/src/net_defs.h +++ b/src/net_defs.h @@ -118,7 +118,13 @@ typedef enum NET_MASTER_PACKET_TYPE_ADD, NET_MASTER_PACKET_TYPE_ADD_RESPONSE, NET_MASTER_PACKET_TYPE_QUERY, - NET_MASTER_PACKET_TYPE_QUERY_RESPONSE + NET_MASTER_PACKET_TYPE_QUERY_RESPONSE, + NET_MASTER_PACKET_TYPE_GET_METADATA, + NET_MASTER_PACKET_TYPE_GET_METADATA_RESPONSE, + NET_MASTER_PACKET_TYPE_SIGN_START, + NET_MASTER_PACKET_TYPE_SIGN_START_RESPONSE, + NET_MASTER_PACKET_TYPE_SIGN_END, + NET_MASTER_PACKET_TYPE_SIGN_END_RESPONSE, } net_master_packet_type_t; typedef struct diff --git a/src/net_query.c b/src/net_query.c index 0262791b..475fa98f 100644 --- a/src/net_query.c +++ b/src/net_query.c @@ -44,6 +44,10 @@ #define QUERY_TIMEOUT_SECS 2 +// Time to wait for secure demo signatures before declaring a timeout. + +#define SIGNATURE_TIMEOUT_SECS 5 + // Number of query attempts to make before giving up on a server. #define QUERY_MAX_ATTEMPTS 3 @@ -87,6 +91,8 @@ static boolean query_loop_running = false; static boolean printed_header = false; static int last_query_time = 0; +static char *securedemo_start_message = NULL; + // Resolve the master server address. net_addr_t *NET_Query_ResolveMaster(net_context_t *context) @@ -797,3 +803,124 @@ net_addr_t *NET_FindLANServer(void) } } +// Block until a packet of the given type is received from the given +// address. + +static net_packet_t *BlockForPacket(net_addr_t *addr, unsigned int packet_type, + unsigned int timeout_ms) +{ + net_packet_t *packet; + net_addr_t *packet_src; + unsigned int read_packet_type; + unsigned int start_time; + + start_time = I_GetTimeMS(); + + while (I_GetTimeMS() < start_time + timeout_ms) + { + if (!NET_RecvPacket(query_context, &packet_src, &packet)) + { + I_Sleep(20); + continue; + } + + if (packet_src == addr + && NET_ReadInt16(packet, &read_packet_type) + && packet_type == read_packet_type) + { + return packet; + } + + NET_FreePacket(packet); + } + + // Timeout - no response. + + return NULL; +} + +// Query master server for secure demo start seed value. + +boolean NET_StartSecureDemo(prng_seed_t seed) +{ + net_packet_t *request, *response; + net_addr_t *master_addr; + char *signature; + boolean result; + + NET_Query_Init(); + master_addr = NET_Query_ResolveMaster(query_context); + + // Send request packet to master server. + + request = NET_NewPacket(10); + NET_WriteInt16(request, NET_MASTER_PACKET_TYPE_SIGN_START); + NET_SendPacket(master_addr, request); + NET_FreePacket(request); + + // Block for response and read contents. + // The signed start message will be saved for later. + + response = BlockForPacket(master_addr, + NET_MASTER_PACKET_TYPE_SIGN_START_RESPONSE, + SIGNATURE_TIMEOUT_SECS * 1000); + + result = false; + + if (response != NULL) + { + if (NET_ReadPRNGSeed(response, seed)) + { + signature = NET_ReadString(response); + + if (signature != NULL) + { + securedemo_start_message = strdup(signature); + result = true; + } + } + + NET_FreePacket(response); + } + + return result; +} + +// Query master server for secure demo end signature. + +char *NET_EndSecureDemo(sha1_digest_t demo_hash) +{ + net_packet_t *request, *response; + net_addr_t *master_addr; + char *signature; + + master_addr = NET_Query_ResolveMaster(query_context); + + // Construct end request and send to master server. + + request = NET_NewPacket(10); + NET_WriteInt16(request, NET_MASTER_PACKET_TYPE_SIGN_END); + NET_WriteSHA1Sum(request, demo_hash); + NET_WriteString(request, securedemo_start_message); + NET_SendPacket(master_addr, request); + NET_FreePacket(request); + + // Block for response. The response packet simply contains a string + // with the ASCII signature. + + response = BlockForPacket(master_addr, + NET_MASTER_PACKET_TYPE_SIGN_END_RESPONSE, + SIGNATURE_TIMEOUT_SECS * 1000); + + if (response == NULL) + { + return NULL; + } + + signature = NET_ReadString(response); + + NET_FreePacket(response); + + return signature; +} + diff --git a/src/net_sdl.c b/src/net_sdl.c index 2589540d..2f7eaa6f 100644 --- a/src/net_sdl.c +++ b/src/net_sdl.c @@ -44,6 +44,7 @@ #define DEFAULT_PORT 2342 +static boolean initted = false; static int port = DEFAULT_PORT; static UDPsocket udpsocket; static UDPpacket *recvpacket; @@ -162,6 +163,9 @@ static boolean NET_SDL_InitClient(void) { int p; + if (initted) + return true; + //! // @category net // @arg <n> @@ -189,13 +193,18 @@ static boolean NET_SDL_InitClient(void) srand(time(NULL)); #endif + initted = true; + return true; } static boolean NET_SDL_InitServer(void) { int p; - + + if (initted) + return true; + p = M_CheckParmWithArgs("-port", 1); if (p > 0) port = atoi(myargv[p+1]); @@ -214,6 +223,8 @@ static boolean NET_SDL_InitServer(void) srand(time(NULL)); #endif + initted = true; + return true; } diff --git a/src/net_structrw.c b/src/net_structrw.c index bba08212..818766e4 100644 --- a/src/net_structrw.c +++ b/src/net_structrw.c @@ -321,31 +321,51 @@ void NET_WriteFullTiccmd(net_packet_t *packet, net_full_ticcmd_t *cmd, boolean l } } -boolean NET_ReadSHA1Sum(net_packet_t *packet, sha1_digest_t digest) +static boolean NET_ReadBlob(net_packet_t *packet, uint8_t *buf, size_t len) { unsigned int b; int i; - for (i=0; i<sizeof(sha1_digest_t); ++i) + for (i=0; i<len; ++i) { if (!NET_ReadInt8(packet, &b)) { return false; } - digest[i] = b; + buf[i] = b; } return true; } -void NET_WriteSHA1Sum(net_packet_t *packet, sha1_digest_t digest) +static void NET_WriteBlob(net_packet_t *packet, uint8_t *buf, size_t len) { int i; - for (i=0; i<sizeof(sha1_digest_t); ++i) + for (i=0; i<len; ++i) { - NET_WriteInt8(packet, digest[i]); + NET_WriteInt8(packet, buf[i]); } } +boolean NET_ReadSHA1Sum(net_packet_t *packet, sha1_digest_t digest) +{ + return NET_ReadBlob(packet, digest, sizeof(sha1_digest_t)); +} + +void NET_WriteSHA1Sum(net_packet_t *packet, sha1_digest_t digest) +{ + NET_WriteBlob(packet, digest, sizeof(sha1_digest_t)); +} + +boolean NET_ReadPRNGSeed(net_packet_t *packet, prng_seed_t seed) +{ + return NET_ReadBlob(packet, seed, sizeof(prng_seed_t)); +} + +void NET_WritePRNGSeed(net_packet_t *packet, prng_seed_t seed) +{ + NET_WriteBlob(packet, seed, sizeof(prng_seed_t)); +} + diff --git a/src/net_structrw.h b/src/net_structrw.h index 4331074b..23bd67a1 100644 --- a/src/net_structrw.h +++ b/src/net_structrw.h @@ -22,6 +22,7 @@ #ifndef NET_STRUCTRW_H #define NET_STRUCTRW_H +#include "aes_prng.h" #include "sha1.h" #include "net_defs.h" #include "net_packet.h" @@ -43,5 +44,8 @@ void NET_WriteFullTiccmd(net_packet_t *packet, net_full_ticcmd_t *cmd, boolean l boolean NET_ReadSHA1Sum(net_packet_t *packet, sha1_digest_t digest); void NET_WriteSHA1Sum(net_packet_t *packet, sha1_digest_t digest); +boolean NET_ReadPRNGSeed(net_packet_t *packet, prng_seed_t seed); +void NET_WritePRNGSeed(net_packet_t *packet, prng_seed_t seed); + #endif /* #ifndef NET_STRUCTRW_H */ |