shithub: choc

Download patch

ref: 501b13786b024388b3cd7a21c8be8501dbfffb02
parent: f7ecbd1449871a448daa7b96ce121f3fe9d19aed
author: Simon Howard <fraggle@gmail.com>
date: Sun Oct 28 06:41:45 EDT 2012

Add functions for network signature requests. These request the signed
messages from the master server, to be used at the start and end of
recording a secure demo.

Subversion-branch: /trunk/chocolate-doom
Subversion-revision: 2535

--- a/src/net_defs.h
+++ b/src/net_defs.h
@@ -118,7 +118,13 @@
     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 
--- 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 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)
@@ -795,5 +801,126 @@
     {
         return NULL;
     }
+}
+
+// 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;
 }
 
--- 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 @@
 {
     int p;
 
+    if (initted)
+        return true;
+
     //!
     // @category net
     // @arg <n>
@@ -189,6 +193,8 @@
     srand(time(NULL));
 #endif
 
+    initted = true;
+
     return true;
 }
 
@@ -195,7 +201,10 @@
 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]);
@@ -213,6 +222,8 @@
 #ifdef DROP_PACKETS
     srand(time(NULL));
 #endif
+
+    initted = true;
 
     return true;
 }
--- a/src/net_structrw.c
+++ b/src/net_structrw.c
@@ -321,12 +321,12 @@
     }
 }
 
-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))
         {
@@ -333,19 +333,39 @@
             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));
 }
 
--- 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"
@@ -42,6 +43,9 @@
 
 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 */