Actually on second thought, I do want splitscreen

This commit is contained in:
NepDisk 2026-03-29 13:54:25 -04:00
parent d6eab04a7a
commit 163d4a0e72
6 changed files with 101 additions and 68 deletions

View file

@ -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;
}
}
}
}

View file

@ -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"

View file

@ -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

View file

@ -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;

View file

@ -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)

View file

@ -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;