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 */