From 163d4a0e72d68fa62e45357fc893651be5f6d8e9 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Sun, 29 Mar 2026 13:54:25 -0400 Subject: [PATCH] Actually on second thought, I do want splitscreen --- src/d_clisrv.c | 83 ++++++++++++++++++++++++++++++++------------------ src/d_clisrv.h | 13 ++++---- src/d_main.cpp | 56 ++++++++++++++++++---------------- src/d_main.h | 4 +-- src/d_net.c | 11 +++++-- src/d_netfil.c | 2 +- 6 files changed, 101 insertions(+), 68 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 81cf76a18..553cdbb11 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -183,8 +183,8 @@ char connectedserverdescription[MAXSERVERDESCRIPTION]; /// \todo WORK! boolean acceptnewnode = true; -uint8_t lastReceivedKey[MAXNETNODES][32]; -uint8_t lastSentChallenge[MAXNETNODES][32]; +uint8_t lastReceivedKey[MAXNETNODES][MAXSPLITSCREENPLAYERS][32]; +uint8_t lastSentChallenge[MAXNETNODES][MAXSPLITSCREENPLAYERS][32]; boolean serverisfull = false; //lets us be aware if the server was full after we check files, but before downloading, so we can ask if the user still wants to download or not tic_t firstconnectattempttime = 0; @@ -920,11 +920,13 @@ static boolean CL_SendJoin(void) // Don't leak old signatures from prior sessions. memset(&netbuffer->u.clientcfg.challengeResponse, 0, sizeof(((clientconfig_pak *)0)->challengeResponse)); - uint8_t signature[64]; - crypto_eddsa_sign(signature, secret_key, awaitingChallenge, 32); + for (i = 0; i <= splitscreen; i++) + { + uint8_t signature[64]; - if (crypto_eddsa_check(signature, public_key, awaitingChallenge, 32) != 0) - I_Error("Couldn't verify own key, may be corrupted?"); + crypto_eddsa_sign(signature, secret_key[i], awaitingChallenge, 32); + if (crypto_eddsa_check(signature, public_key[i], awaitingChallenge, 32) != 0) + I_Error("Couldn't self-verify key associated with player %d.\nkey may be corrupted.\n", i); // I guess this is the most reasonable way to catch a malformed key. #ifdef DEVELOP if (cv_sigfail.value) @@ -934,20 +936,26 @@ static boolean CL_SendJoin(void) } #endif - // Testing - // memset(signature, 0, sizeof(signature)); + // Testing + // memset(signature, 0, sizeof(signature)); - memcpy(&netbuffer->u.clientcfg.challengeResponse, signature, sizeof(signature)); + memcpy(&netbuffer->u.clientcfg.challengeResponse[i], signature, sizeof(signature)); + } return HSendPacket(servernode, false, 0, sizeof (clientconfig_pak)); } static boolean CL_SendKey(void) { + int i; doomdata_t *netbuffer = DOOMCOM_DATA(doomcom); netbuffer->packettype = PT_CLIENTKEY; - memcpy(netbuffer->u.clientkey.key, public_key, sizeof(public_key)); + memset(netbuffer->u.clientkey.key, 0, sizeof(((clientkey_pak *)0)->key)); + for (i = 0; i <= splitscreen; i++) + { + memcpy(netbuffer->u.clientkey.key[i], public_key[i], 32); + } return HSendPacket(servernode, false, 0, sizeof (clientkey_pak) ); } @@ -3996,8 +4004,8 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) D_SendPlayerConfig(splitscreenplayer); addedtogame = true; - CONS_Printf("It's me, node %d, with ID %s! (This is uninitialized memory because Tyron is a nice person :)!)\n", node, GetPrettyRRID(lastReceivedKey[node], true)); - memcpy(lastReceivedKey[node], public_key, 32); + CONS_Printf("It's me, node %d, with ID %s! (This is uninitialized memory because Tyron is a nice person :) )\n", node, GetPrettyRRID(lastReceivedKey[node][splitscreenplayer], true)); + memcpy(lastReceivedKey[node][splitscreenplayer], public_key[splitscreenplayer], 32); } players[newplayernum].splitscreenindex = splitscreenplayer; @@ -4005,8 +4013,8 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) // player_t is the only place in the game that a key is null-terminated, for ease of Lua push. memset(players[newplayernum].public_key, 0, 32 + 1); - CONS_Printf("Adding player from node %d with ID %s\n", node, GetPrettyRRID(lastReceivedKey[node], true)); - memcpy(players[newplayernum].public_key, lastReceivedKey[node], 32); + CONS_Printf("Adding player from node %d with ID %s\n", node, GetPrettyRRID(lastReceivedKey[node][splitscreenplayer], true)); + memcpy(players[newplayernum].public_key, lastReceivedKey[node][splitscreenplayer], sizeof(players[newplayernum].public_key)); CONS_Printf("Node %d now has ID %s\n", node, GetPrettyRRID(players[newplayernum].public_key, true)); // Previously called at the top of this function, commented as @@ -4566,14 +4574,15 @@ static void HandleConnect(SINT8 node) if (node == 0) // Server { - memcpy(lastReceivedKey[node], public_key, sizeof(lastReceivedKey[node])); - CONS_Printf("Adding SERVER. Setting lastReceivedKey on node %d to %s\n", node, GetPrettyRRID(lastReceivedKey[node], true)); + memcpy(lastReceivedKey[node][i], public_key[i], sizeof(lastReceivedKey[node][i])); + CONS_Printf("We're SERVER! Setting lastReceivedKey on node %d to %s\n", node, GetPrettyRRID(lastReceivedKey[node][i], true)); + } else { - CONS_Printf("Adding client. Doing sigcheck for node %d, ID %s\n", node, GetPrettyRRID(lastReceivedKey[node], true)); + CONS_Printf("Adding client. Doing sigcheck for node %d, ID %s\n", node, GetPrettyRRID(lastReceivedKey[i][node], true)); - sigcheck = crypto_eddsa_check(netbuffer->u.clientcfg.challengeResponse, lastReceivedKey[node], lastSentChallenge[node], 32); + sigcheck = crypto_eddsa_check(netbuffer->u.clientcfg.challengeResponse[i], lastReceivedKey[node][i], lastSentChallenge[node][i], 32); if (netgame && sigcheck != 0) { @@ -5707,20 +5716,34 @@ static void HandlePacketFromPlayer(SINT8 node) if (netconsole >= MAXPLAYERS) I_Error("bad table nodetoplayer: node %d player %d", doomcom->remotenode, netconsole); #endif - - uint8_t allzero[32]; - memset(allzero, 0, sizeof(allzero)); - - if (IsPacketSigned(netbuffer->packettype)) + if (server) { - const void* message = &netbuffer->u; - if (crypto_eddsa_check(netbuffer->signature, lastReceivedKey[node], message, doomcom->datalength - BASEPACKETSIZE)) + int splitnodes; + if (IsPacketSigned(netbuffer->packettype)) { - //CONS_Alert(CONS_ERROR, "SIGFAIL! Packet type %d from node %d \nkey %s size %d\n", - //netbuffer->packettype, node, - //GetPrettyRRID(lastReceivedKey[node], true), doomcom->datalength - BASEPACKETSIZE); - // SendKick(netconsole, KICK_MSG_CON_FAIL); - return; + for (splitnodes = 0; splitnodes < MAXSPLITSCREENPLAYERS; splitnodes++) + { + // Don't try to enforce signatures for players that aren't present. + if (splitnodes > 0 && nodetoplayer2[node] <= 0) + break; + if (splitnodes > 1 && nodetoplayer3[node] <= 0) + break; + if (splitnodes > 2 && nodetoplayer4[node] <= 0) + break; + + const void* message = &netbuffer->u; + if (crypto_eddsa_check(netbuffer->signature[splitnodes], lastReceivedKey[node][splitnodes], message, doomcom->datalength - BASEPACKETSIZE)) + { + CONS_Alert(CONS_ERROR, "SIGFAIL! Packet type %d from node %d player %d\nkey %s size %d netconsole %d\n", + netbuffer->packettype, node, splitnodes, + GetPrettyRRID(lastReceivedKey[node][splitnodes], true), doomcom->datalength - BASEPACKETSIZE, netconsole); + if (netconsole != -1) // NO IDEA. + SendKick(netconsole, KICK_MSG_SIGFAIL); + Net_CloseConnection(node); + nodeingame[node] = false; + return; + } + } } } diff --git a/src/d_clisrv.h b/src/d_clisrv.h index b50122a20..bf3cf9b27 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -17,6 +17,7 @@ #include "d_net.h" #include "d_netcmd.h" #include "d_net.h" +#include "doomdef.h" #include "tables.h" #include "d_player.h" #include "mserv.h" @@ -294,7 +295,7 @@ struct clientconfig_pak UINT8 mode; char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME]; UINT8 availabilities[MAXAVAILABILITY]; - uint8_t challengeResponse[64]; + uint8_t challengeResponse[MAXSPLITSCREENPLAYERS][64]; } ATTRPACK; #define SV_SPEEDMASK 0x03 // used to send kartspeed @@ -391,12 +392,12 @@ struct reqmapqueue_pak struct clientkey_pak { - char key[32]; + char key[MAXSPLITSCREENPLAYERS][32]; } ATTRPACK; struct serverchallenge_pak { - char secret[32]; + char secret[MAXSPLITSCREENPLAYERS][32]; } ATTRPACK; struct netinfo_pak @@ -424,7 +425,7 @@ struct doomdata_t UINT8 ackreturn; // The return of the ack number UINT8 packettype; - uint8_t signature[64]; + uint8_t signature[MAXSPLITSCREENPLAYERS][64]; UINT8 packetindex; union { @@ -701,8 +702,8 @@ void DoSayPacket(SINT8 target, UINT8 flags, UINT8 source, char *message); void DoSayPacketFromCommand(SINT8 target, size_t usedargs, UINT8 flags); void SendServerNotice(SINT8 target, char *message); -extern uint8_t lastReceivedKey[MAXNETNODES][32]; -extern uint8_t lastSentChallenge[MAXNETNODES][32]; +extern uint8_t lastReceivedKey[MAXNETNODES][MAXSPLITSCREENPLAYERS][32]; +extern uint8_t lastSentChallenge[MAXNETNODES][MAXSPLITSCREENPLAYERS][32]; #ifdef __cplusplus } // extern "C" diff --git a/src/d_main.cpp b/src/d_main.cpp index 38376fb99..99b7f1bda 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -183,8 +183,8 @@ INT32 eventhead, eventtail; boolean dedicated = false; // For identity negotiation with netgame servers -uint8_t public_key[32]; -uint8_t secret_key[64]; +uint8_t public_key[MAXSPLITSCREENPLAYERS][32]; +uint8_t secret_key[MAXSPLITSCREENPLAYERS][64]; boolean loaded_config = false; @@ -1878,32 +1878,36 @@ void D_SRB2Main(void) // TODO: This file should probably give a fuck about command line params, // or not be stored next to the EXE in a way that allows people to unknowingly send it to others. // I'm thinking ~/.config on nix and %appdata on windows since we don't have profiles. - Nep - static char keyfile[16] = "rrid.dat"; + static char keyfile[MAXSPLITSCREENPLAYERS][16] = {"rrid1.dat", "rrid2.dat", "rrid3.dat", "rrid4.dat"}; - static uint8_t seed[32]; - csprng(seed, 32); - crypto_eddsa_key_pair(secret_key, public_key, seed); - - int sk_size = sizeof(secret_key); - int pk_size = sizeof(public_key); - int totalsize = sk_size + pk_size; - - if (FIL_ReadFileOK(keyfile)) + for (INT32 snum = 0; snum < MAXSPLITSCREENPLAYERS; snum++) { - UINT8 *readbuffer = NULL; - UINT16 lengthRead = FIL_ReadFile(keyfile, &readbuffer); - if (readbuffer == NULL || lengthRead != totalsize) - I_Error("Malformed keyfile"); - memcpy(secret_key, readbuffer, sk_size); - memcpy(public_key, readbuffer + sk_size, pk_size); - } - else - { - uint8_t keybuffer[totalsize]; - memcpy(keybuffer, secret_key, sk_size); - memcpy(keybuffer + sk_size, public_key, pk_size); - if (!FIL_WriteFile(keyfile, keybuffer, totalsize)) - I_Error("Couldn't open keyfile"); + static uint8_t seed[32]; + csprng(seed, 32); + crypto_eddsa_key_pair(secret_key[snum], public_key[snum], seed); + + int sk_size = sizeof(secret_key[snum]); + int pk_size = sizeof(public_key[snum]); + int totalsize = sk_size + pk_size; + + if (FIL_ReadFileOK(keyfile[snum])) + { + UINT8 *readbuffer = NULL; + UINT16 lengthRead = FIL_ReadFile(keyfile[snum], &readbuffer); + if (readbuffer == NULL || lengthRead != totalsize) + I_Error("Malformed keyfile %d", snum); + memcpy(secret_key[snum], readbuffer, sk_size); + memcpy(public_key[snum], readbuffer + sk_size, pk_size); + } + else + { + uint8_t *keybuffer = (uint8_t *)malloc(totalsize); + memcpy(keybuffer, secret_key[snum], sk_size); + memcpy(keybuffer + sk_size, public_key[snum], pk_size); + if (!FIL_WriteFile(keyfile[snum], keybuffer, totalsize)) + I_Error("Couldn't open keyfile %d", snum); + free(keybuffer); + } } //------------------------------------------------ COMMAND LINE PARAMS diff --git a/src/d_main.h b/src/d_main.h index dc3c8dac4..80d28cb0a 100644 --- a/src/d_main.h +++ b/src/d_main.h @@ -64,8 +64,8 @@ extern char srb2path[256]; //Alam: SRB2's Home const char *D_GetFancyBranchName(void); -extern uint8_t public_key[32]; -extern uint8_t secret_key[64]; +extern uint8_t public_key[MAXSPLITSCREENPLAYERS][32]; +extern uint8_t secret_key[MAXSPLITSCREENPLAYERS][64]; // the infinite loop of D_SRB2Loop() called from win_main for windows version void D_SRB2Loop(void) FUNCNORETURN; diff --git a/src/d_net.c b/src/d_net.c index 6e4ce51cf..b8d005aac 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -879,9 +879,14 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen if (IsPacketSigned(netbuffer->packettype)) { - const void* message = &netbuffer->u; - //CONS_Printf("Signing packet type %d of length %d\n", netbuffer->packettype, packetlength); - crypto_eddsa_sign(netbuffer->signature, secret_key, message, packetlength); + int i; + + for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) + { + const void* message = &netbuffer->u; + //CONS_Printf("Signing packet type %d of length %d\n", netbuffer->packettype, packetlength); + crypto_eddsa_sign(netbuffer->signature[i], secret_key[i], message, packetlength); + } #ifdef DEVELOP if (cv_sigfail.value) diff --git a/src/d_netfil.c b/src/d_netfil.c index 69473e4df..2a1af0087 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -1348,7 +1348,7 @@ void PT_ClientKey(INT32 node) memcpy(lastReceivedKey[node], packet->key, sizeof(lastReceivedKey[node])); - CONS_Printf("Got keys from node %d, %s\n", node, GetPrettyRRID(lastReceivedKey[node], true)); + CONS_Printf("Got keys from node %d, %s / %s / %s / %s\n", node, GetPrettyRRID(lastReceivedKey[node][0], true), GetPrettyRRID(lastReceivedKey[node][1], true), GetPrettyRRID(lastReceivedKey[node][2], true), GetPrettyRRID(lastReceivedKey[node][3], true)); netbuffer->packettype = PT_SERVERCHALLENGE;