From 7a8ea914bc78222193306aa28ca1eda709f7a650 Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Thu, 7 Jan 2010 21:46:51 +0100 Subject: [PATCH] add the modified files too --- makefile.inc | 1 + netconn.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++--- netconn.h | 3 ++ quakedef.h | 1 + server.h | 10 +++++ 5 files changed, 121 insertions(+), 6 deletions(-) diff --git a/makefile.inc b/makefile.inc index 22478d5d..9557a1ae 100644 --- a/makefile.inc +++ b/makefile.inc @@ -88,6 +88,7 @@ OBJ_NOCD=cd_null.o # Common objects OBJ_COMMON= \ + crypto.o \ cap_avi.o \ cap_ogg.o \ cd_shared.o \ diff --git a/netconn.c b/netconn.c index 657c5120..b1a234a9 100755 --- a/netconn.c +++ b/netconn.c @@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + #include "quakedef.h" #include "lhnet.h" @@ -118,6 +119,8 @@ static double serverlist_querywaittime = 0; static unsigned char sendbuffer[NET_HEADERSIZE+NET_MAXMESSAGE]; static unsigned char readbuffer[NET_HEADERSIZE+NET_MAXMESSAGE]; +static unsigned char cryptosendbuffer[NET_HEADERSIZE+NET_MAXMESSAGE+CRYPTO_HEADERSIZE]; +static unsigned char cryptoreadbuffer[NET_HEADERSIZE+NET_MAXMESSAGE+CRYPTO_HEADERSIZE]; static int cl_numsockets; static lhnetsocket_t *cl_sockets[16]; @@ -703,6 +706,8 @@ int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data, protocolvers unsigned int packetLen; unsigned int dataLen; unsigned int eom; + const void *sendme; + size_t sendmelen; // if a reliable message fragment has been lost, send it again if (conn->sendMessageLength && (realtime - conn->lastSendTime) > 1.0) @@ -726,7 +731,8 @@ int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data, protocolvers conn->outgoing_netgraph[conn->outgoing_packetcounter].reliablebytes += packetLen + 28; - if (NetConn_Write(conn->mysocket, (void *)&sendbuffer, packetLen, &conn->peeraddress) == (int)packetLen) + sendme = crypto_encryptpacket(&conn->crypto, &sendbuffer, packetLen, &cryptosendbuffer, &sendmelen, sizeof(cryptosendbuffer)); + if (NetConn_Write(conn->mysocket, sendme, sendmelen, &conn->peeraddress) == (int)packetLen) { conn->lastSendTime = realtime; packetsReSent++; @@ -776,7 +782,8 @@ int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data, protocolvers conn->outgoing_netgraph[conn->outgoing_packetcounter].reliablebytes += packetLen + 28; - NetConn_Write(conn->mysocket, (void *)&sendbuffer, packetLen, &conn->peeraddress); + sendme = crypto_encryptpacket(&conn->crypto, &sendbuffer, packetLen, &cryptosendbuffer, &sendmelen, sizeof(cryptosendbuffer)); + NetConn_Write(conn->mysocket, sendme, sendmelen, &conn->peeraddress); conn->lastSendTime = realtime; packetsSent++; @@ -804,7 +811,8 @@ int NetConn_SendUnreliableMessage(netconn_t *conn, sizebuf_t *data, protocolvers conn->outgoing_netgraph[conn->outgoing_packetcounter].unreliablebytes += packetLen + 28; - NetConn_Write(conn->mysocket, (void *)&sendbuffer, packetLen, &conn->peeraddress); + sendme = crypto_encryptpacket(&conn->crypto, &sendbuffer, packetLen, &cryptosendbuffer, &sendmelen, sizeof(cryptosendbuffer)); + NetConn_Write(conn->mysocket, sendme, sendmelen, &conn->peeraddress); packetsSent++; unreliableMessagesSent++; @@ -1075,7 +1083,7 @@ void NetConn_UpdateSockets(void) } } -static int NetConn_ReceivedMessage(netconn_t *conn, unsigned char *data, int length, protocolversion_t protocol, double newtimeout) +static int NetConn_ReceivedMessage(netconn_t *conn, const unsigned char *data, size_t length, protocolversion_t protocol, double newtimeout) { int originallength = length; if (length < 8) @@ -1159,7 +1167,14 @@ static int NetConn_ReceivedMessage(netconn_t *conn, unsigned char *data, int len unsigned int count; unsigned int flags; unsigned int sequence; - int qlength; + size_t qlength; + + data = crypto_decryptpacket(&conn->crypto, data, length, cryptoreadbuffer, &length, sizeof(cryptoreadbuffer)); + if(!data) + return 0; + originallength = length; + if(length < 8) + return 0; qlength = (unsigned int)BuffBigLong(data); flags = qlength & ~NETFLAG_LENGTH_MASK; @@ -1638,9 +1653,21 @@ static int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, unsigned char *dat // update the server IP in the userinfo (QW servers expect this, and it is used by the reconnect command) InfoString_SetValue(cls.userinfo, sizeof(cls.userinfo), "*ip", addressstring2); // TODO: add userinfo stuff here instead of using NQ commands? - NetConn_WriteString(mysocket, va("\377\377\377\377connect\\protocol\\darkplaces 3\\protocols\\%s\\challenge\\%s", protocolnames, string + 10), peeraddress); + if(crypto_rsaaes_pubkey) + NetConn_WriteString(mysocket, va("\377\377\377\377connect\\protocol\\darkplaces 3\\protocols\\%s\\challenge\\%s\\crypto\\rsa+aes\\crypto_rsaaes_pubkey\\%s", protocolnames, string + 10, crypto_rsaaes_pubkey), peeraddress); + else + NetConn_WriteString(mysocket, va("\377\377\377\377connect\\protocol\\darkplaces 3\\protocols\\%s\\challenge\\%s", protocolnames, string + 10), peeraddress); return true; } + if (length >= 24 && !memcmp(string, "crypto aes+dh serverkey ", 24)) + { + char buf[1400]; + int size; + crypto_rsaaes_handleserverkey(&cls.netcon->crypto, string + 24, length - 24); + memcpy(buf, "\377\377\377\377crypto aes+dh clientkey ", 28); + size = 28 + crypto_rsaaes_buildclientkey(&cls.netcon->crypto, buf + 28, sizeof(buf) - 28); + NetConn_Write(mysocket, buf, size, peeraddress); + } if (length == 6 && !memcmp(string, "accept", 6) && cls.connect_trying) { // darkplaces or quake3 @@ -2678,6 +2705,35 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat if (NetConn_PreventConnectFlood(peeraddress)) return true; + if((s = SearchInfostring(string, "crypto")) && !strcmp(s, "rsa+aes") && crypto_rsaaes_pubkey) + { + char buf[1400]; + int size; + int best = 0; + + // crypto connect + for(i = 0; i < MAX_CRYPTOCONNECTS; ++i) + { + if(LHNETADDRESS_Compare(peeraddress, &svs.cryptoconnects[i].address)) + { + best = i; + break; + } + if(svs.cryptoconnects[i].lasttime < svs.cryptoconnects[best].lasttime) + best = i; + } + + svs.cryptoconnects[best].lasttime = realtime; + svs.cryptoconnects[best].address = *peeraddress; + + memcpy(buf, "\377\377\377\377crypto aes+dh serverkey ", 28); + crypto_rsaaes_initwithclientkey(&svs.cryptoconnects[best].crypto, SearchInfostring(string, "crypto_key")); + size = 28 + crypto_rsaaes_buildserverkey(&svs.cryptoconnects[best].crypto, buf + 28, sizeof(buf) - 28); + NetConn_Write(mysocket, buf, size, peeraddress); + + return true; + } + // find an empty client slot for this new client for (clientnum = 0, client = svs.clients;clientnum < svs.maxclients;clientnum++, client++) { @@ -2687,12 +2743,14 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat // allocated connection if (developer_extra.integer) Con_Printf("Datagram_ParseConnectionless: sending \"accept\" to %s.\n", conn->address); + NetConn_WriteString(mysocket, "\377\377\377\377accept", peeraddress); // now set up the client SV_VM_Begin(); SV_ConnectClient(clientnum, conn); SV_VM_End(); NetConn_Heartbeat(1); + return true; } } @@ -2704,6 +2762,48 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat return true; } + if (length >= 24 && !memcmp(string, "crypto aes+dh clientkey ", 24)) + { + // crypto connect + for(i = 0; i < MAX_CRYPTOCONNECTS; ++i) + if(LHNETADDRESS_Compare(peeraddress, &svs.cryptoconnects[i].address)) + break; + + if(i < MAX_CRYPTOCONNECTS) + { + crypto_rsaaes_handleclientkey(&svs.cryptoconnects[i].crypto, string + 24, length - 24); + + // find an empty client slot for this new client + for (clientnum = 0, client = svs.clients;clientnum < svs.maxclients;clientnum++, client++) + { + netconn_t *conn; + if (!client->active && (conn = NetConn_Open(mysocket, peeraddress))) + { + // allocated connection + if (developer.integer >= 10) + Con_Printf("Datagram_ParseConnectionless: sending \"accept\" to %s.\n", conn->address); + + conn->crypto = svs.cryptoconnects[i].crypto; + + NetConn_WriteString(mysocket, "\377\377\377\377accept", peeraddress); + // now set up the client + SV_VM_Begin(); + SV_ConnectClient(clientnum, conn); + SV_VM_End(); + NetConn_Heartbeat(1); + + return true; + } + } + + // no empty slots found - server is full + if (developer.integer >= 10) + Con_Printf("Datagram_ParseConnectionless: sending \"reject Server is full.\" to %s.\n", addressstring2); + NetConn_WriteString(mysocket, "\377\377\377\377reject Server is full.", peeraddress); + + return true; + } + } if (length >= 7 && !memcmp(string, "getinfo", 7) && (islocal || sv_public.integer > -1)) { const char *challenge = NULL; diff --git a/netconn.h b/netconn.h index 9d4a912f..ce4fecb7 100755 --- a/netconn.h +++ b/netconn.h @@ -34,6 +34,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define NETFLAG_EOM 0x00080000 #define NETFLAG_UNRELIABLE 0x00100000 #define NETFLAG_CTL 0x80000000 +#define NETFLAG_CRYPTO 0x40000000 #define NET_PROTOCOL_VERSION 3 @@ -219,6 +220,8 @@ typedef struct netconn_s netgraphitem_t outgoing_netgraph[NETGRAPH_PACKETS]; char address[128]; + + crypto_t crypto; } netconn_t; extern netconn_t *netconn_list; diff --git a/quakedef.h b/quakedef.h index 5770616a..d4d89860 100644 --- a/quakedef.h +++ b/quakedef.h @@ -334,6 +334,7 @@ extern char engineversion[128]; #include "r_textures.h" +#include "crypto.h" #include "draw.h" #include "screen.h" #include "netconn.h" diff --git a/server.h b/server.h index 72ea9dee..ca48b8e0 100644 --- a/server.h +++ b/server.h @@ -22,6 +22,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef SERVER_H #define SERVER_H +#define MAX_CRYPTOCONNECTS 16 +typedef struct server_cryptoconnect_s +{ + double lasttime; + crypto_t crypto; + lhnetaddress_t address; +} +server_cryptoconnect_t; + typedef struct server_static_s { /// number of svs.clients slots (updated by maxplayers command) @@ -54,6 +63,7 @@ typedef struct server_static_s size_t csqc_progsize_deflated; unsigned char *csqc_progdata_deflated; + server_cryptoconnect_t cryptoconnects[MAX_CRYPTOCONNECTS]; } server_static_t; //============================================================================= -- 2.39.2