From 7ea16154f9f74f80dea9d9ec728f38f792ad5ee6 Mon Sep 17 00:00:00 2001 From: Shpoike Date: Tue, 25 Jul 2023 11:07:50 +0100 Subject: [PATCH] Add support for proquake's password stuff. --- Quake/crc.h | 4 ++-- Quake/mdfour.c | 16 +++++++-------- Quake/net_dgrm.c | 52 ++++++++++++++++++++++++++++++++++++++---------- Quake/sv_main.c | 3 ++- 4 files changed, 53 insertions(+), 22 deletions(-) diff --git a/Quake/crc.h b/Quake/crc.h index 98905ed9..d0acb32f 100644 --- a/Quake/crc.h +++ b/Quake/crc.h @@ -30,8 +30,8 @@ unsigned short CRC_Value(unsigned short crcvalue); unsigned short CRC_Block (const byte *start, size_t count); //johnfitz -- texture crc //additional hash functions... -unsigned Com_BlockChecksum (void *buffer, size_t length); -void Com_BlockFullChecksum (void *buffer, size_t len, unsigned char *outbuf); +unsigned Com_BlockChecksum (const void *buffer, size_t length); +void Com_BlockFullChecksum (const void *buffer, size_t len, unsigned char *outbuf); #endif /* _QUAKE_CRC_H */ diff --git a/Quake/mdfour.c b/Quake/mdfour.c index 685d5883..58f98785 100644 --- a/Quake/mdfour.c +++ b/Quake/mdfour.c @@ -53,9 +53,9 @@ struct mdfour { }; static void mdfour_begin(struct mdfour *md); // old: MD4Init -static void mdfour_update(struct mdfour *md, unsigned char *in, size_t n); //old: MD4Update +static void mdfour_update(struct mdfour *md, const unsigned char *in, size_t n); //old: MD4Update static void mdfour_result(struct mdfour *md, unsigned char *out); // old: MD4Final -static void mdfour(unsigned char *out, unsigned char *in, size_t n); +static void mdfour(unsigned char *out, const unsigned char *in, size_t n); #endif // _MDFOUR_H @@ -133,7 +133,7 @@ static void mdfour64(struct mdfour *m, uint32 *M) m->A = A; m->B = B; m->C = C; m->D = D; } -static void copy64(uint32 *M, unsigned char *in) +static void copy64(uint32 *M, const unsigned char *in) { int i; @@ -160,7 +160,7 @@ static void mdfour_begin(struct mdfour *md) } -static void mdfour_tail(struct mdfour *m, unsigned char *in, size_t n) +static void mdfour_tail(struct mdfour *m, const unsigned char *in, size_t n) { unsigned char buf[128]; uint32 M[16]; @@ -190,7 +190,7 @@ static void mdfour_tail(struct mdfour *m, unsigned char *in, size_t n) } } -static void mdfour_update(struct mdfour *m, unsigned char *in, size_t n) +static void mdfour_update(struct mdfour *m, const unsigned char *in, size_t n) { uint32 M[16]; @@ -218,7 +218,7 @@ static void mdfour_result(struct mdfour *m, unsigned char *out) } -static void mdfour(unsigned char *out, unsigned char *in, size_t n) +static void mdfour(unsigned char *out, const unsigned char *in, size_t n) { struct mdfour md; mdfour_begin(&md); @@ -234,12 +234,12 @@ static void mdfour(unsigned char *out, unsigned char *in, size_t n) // Author: Jeff Teunissen // Date: 01 Jan 2000 -unsigned Com_BlockChecksum (void *buffer, size_t length) +unsigned Com_BlockChecksum (const void *buffer, size_t length) { int digest[4]; unsigned val; - mdfour ( (unsigned char *) digest, (unsigned char *) buffer, length ); + mdfour ( (unsigned char *) digest, (const unsigned char *) buffer, length ); val = digest[0] ^ digest[1] ^ digest[2] ^ digest[3]; diff --git a/Quake/net_dgrm.c b/Quake/net_dgrm.c index cab1c1e7..60968dc9 100644 --- a/Quake/net_dgrm.c +++ b/Quake/net_dgrm.c @@ -54,6 +54,7 @@ static int droppedDatagrams; cvar_t sv_reportheartbeats = {"sv_reportheartbeats", "0"}; cvar_t sv_public = {"sv_public", NULL}; cvar_t com_protocolname = {"com_protocolname", "FTE-Quake DarkPlaces-Quake"}; +cvar_t password = {"password", ""}; //this is super-lame and limited to numbers, so when not numeric we hash it and use that instead. there's no nonces though. cvar_t net_masters[] = { {"net_master1", ""}, @@ -1207,7 +1208,7 @@ static void _Datagram_ServerControlPacket (sys_socket_t acceptsock, struct qsock int control; int ret; int plnum; - int mod;//, mod_ver, mod_flags, mod_passwd; //proquake extensions + int mod, /*mod_ver, mod_flags,*/ mod_passwd; //proquake extensions control = BigLong(*((int *)data)); if (control == -1) @@ -1455,17 +1456,35 @@ static void _Datagram_ServerControlPacket (sys_socket_t acceptsock, struct qsock //read proquake extensions mod = MSG_ReadByte(); if (msg_badread) mod = 0; -#if 0 - mod_ver = MSG_ReadByte(); - if (msg_badread) mod_ver = 0; - mod_flags = MSG_ReadByte(); - if (msg_badread) mod_flags = 0; + /*mod_ver = */MSG_ReadByte(); + /*if (msg_badread) mod_ver = 0; + mod_flags = */MSG_ReadByte(); + /*if (msg_badread) mod_flags = 0;*/ mod_passwd = MSG_ReadLong(); if (msg_badread) mod_passwd = 0; - (void)mod_ver; - (void)mod_flags; - (void)mod_passwd; -#endif + + if (*password.string && strcmp(password.string, "none")) + { //FIXME: if this protocol is ever updated, this needs a nonce (eg based on client's IP+time, but requires round-trips to find that out, and confines of proquake's protocol makes it awkward) + char *e; + int pwd = strtol(password.string, &e, 0); + if (*e) + pwd = Com_BlockChecksum(password.string, strlen(password.string)); + if (mod_passwd != pwd) + { + //FIXME: add a short ban so they can't just keep trying + //FIXME: CCREP_REJECT really needs to be a helper... + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREP_REJECT); + MSG_WriteString(&net_message, "bad/missing password.\n"); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (acceptsock, net_message.data, net_message.cursize, clientaddr); + SZ_Clear(&net_message); + return; + } + } + //else if (mod_passwd) thank you for telling me your password for some other server. I'm sure I'll put it to good use... #ifdef BAN_TEST // check for a ban @@ -2085,11 +2104,22 @@ static qsocket_t *_Datagram_Connect (struct qsockaddr *serveraddr) MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION); if (sock->proquake_angle_hack) { /*Spike -- proquake compat. if both engines claim to be using mod==1 then 16bit client->server angles can be used. server->client angles remain 16bit*/ + char *e; + int pwd; + if (!*password.string || !strcmp(password.string, "none")) + pwd = 0; //no password specified, assume none. + else + { + pwd = strtol(password.string, &e, 0); + if (*e) //something trailing = not a numer = hash it and send that. + pwd = Com_BlockChecksum(password.string, strlen(password.string)); + } + Con_DWarning("Attempting to use ProQuake angle hack\n"); MSG_WriteByte(&net_message, 1); /*'mod', 1=proquake*/ MSG_WriteByte(&net_message, 34); /*'mod' version*/ MSG_WriteByte(&net_message, 0); /*flags*/ - MSG_WriteLong(&net_message, 0);//strtoul(password.string, NULL, 0)); /*password*/ + MSG_WriteLong(&net_message, pwd); /*password*/ } *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); dfunc.Write (newsock, net_message.data, net_message.cursize, serveraddr); diff --git a/Quake/sv_main.c b/Quake/sv_main.c index a058c800..724851c1 100644 --- a/Quake/sv_main.c +++ b/Quake/sv_main.c @@ -1543,7 +1543,7 @@ void SV_Init (void) extern cvar_t sv_reportheartbeats; //spike extern cvar_t com_protocolname; //spike extern cvar_t net_masters[]; //spike - extern cvar_t rcon_password; //spike, proquake-compatible rcon + extern cvar_t rcon_password, password; //spike, proquake-compatible rcon extern cvar_t sv_sound_watersplash; //spike - making these changable is handy... extern cvar_t sv_sound_land; //spike - and also mutable... @@ -1578,6 +1578,7 @@ void SV_Init (void) Cvar_RegisterVariable (&sv_public); Cvar_RegisterVariable (&sv_reportheartbeats); Cvar_RegisterVariable (&com_protocolname); + Cvar_RegisterVariable (&password); for (i = 0; net_masters[i].name; i++) Cvar_RegisterVariable (&net_masters[i]); Cvar_RegisterVariable (&rcon_password);