Add support for proquake's password stuff.

This commit is contained in:
Shpoike 2023-07-25 11:07:50 +01:00
parent 2d76417807
commit 7ea16154f9
4 changed files with 53 additions and 22 deletions

View file

@ -30,8 +30,8 @@ unsigned short CRC_Value(unsigned short crcvalue);
unsigned short CRC_Block (const byte *start, size_t count); //johnfitz -- texture crc unsigned short CRC_Block (const byte *start, size_t count); //johnfitz -- texture crc
//additional hash functions... //additional hash functions...
unsigned Com_BlockChecksum (void *buffer, size_t length); unsigned Com_BlockChecksum (const void *buffer, size_t length);
void Com_BlockFullChecksum (void *buffer, size_t len, unsigned char *outbuf); void Com_BlockFullChecksum (const void *buffer, size_t len, unsigned char *outbuf);
#endif /* _QUAKE_CRC_H */ #endif /* _QUAKE_CRC_H */

View file

@ -53,9 +53,9 @@ struct mdfour {
}; };
static void mdfour_begin(struct mdfour *md); // old: MD4Init 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_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 #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; 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; 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]; unsigned char buf[128];
uint32 M[16]; 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]; 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; struct mdfour md;
mdfour_begin(&md); mdfour_begin(&md);
@ -234,12 +234,12 @@ static void mdfour(unsigned char *out, unsigned char *in, size_t n)
// Author: Jeff Teunissen <d2deek@pmail.net> // Author: Jeff Teunissen <d2deek@pmail.net>
// Date: 01 Jan 2000 // Date: 01 Jan 2000
unsigned Com_BlockChecksum (void *buffer, size_t length) unsigned Com_BlockChecksum (const void *buffer, size_t length)
{ {
int digest[4]; int digest[4];
unsigned val; 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]; val = digest[0] ^ digest[1] ^ digest[2] ^ digest[3];

View file

@ -54,6 +54,7 @@ static int droppedDatagrams;
cvar_t sv_reportheartbeats = {"sv_reportheartbeats", "0"}; cvar_t sv_reportheartbeats = {"sv_reportheartbeats", "0"};
cvar_t sv_public = {"sv_public", NULL}; cvar_t sv_public = {"sv_public", NULL};
cvar_t com_protocolname = {"com_protocolname", "FTE-Quake DarkPlaces-Quake"}; 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[] = cvar_t net_masters[] =
{ {
{"net_master1", ""}, {"net_master1", ""},
@ -1207,7 +1208,7 @@ static void _Datagram_ServerControlPacket (sys_socket_t acceptsock, struct qsock
int control; int control;
int ret; int ret;
int plnum; 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)); control = BigLong(*((int *)data));
if (control == -1) if (control == -1)
@ -1455,17 +1456,35 @@ static void _Datagram_ServerControlPacket (sys_socket_t acceptsock, struct qsock
//read proquake extensions //read proquake extensions
mod = MSG_ReadByte(); mod = MSG_ReadByte();
if (msg_badread) mod = 0; if (msg_badread) mod = 0;
#if 0 /*mod_ver = */MSG_ReadByte();
mod_ver = MSG_ReadByte(); /*if (msg_badread) mod_ver = 0;
if (msg_badread) mod_ver = 0; mod_flags = */MSG_ReadByte();
mod_flags = MSG_ReadByte(); /*if (msg_badread) mod_flags = 0;*/
if (msg_badread) mod_flags = 0;
mod_passwd = MSG_ReadLong(); mod_passwd = MSG_ReadLong();
if (msg_badread) mod_passwd = 0; if (msg_badread) mod_passwd = 0;
(void)mod_ver;
(void)mod_flags; if (*password.string && strcmp(password.string, "none"))
(void)mod_passwd; { //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)
#endif 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 #ifdef BAN_TEST
// check for a ban // check for a ban
@ -2085,11 +2104,22 @@ static qsocket_t *_Datagram_Connect (struct qsockaddr *serveraddr)
MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION); MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
if (sock->proquake_angle_hack) 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*/ { /*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"); Con_DWarning("Attempting to use ProQuake angle hack\n");
MSG_WriteByte(&net_message, 1); /*'mod', 1=proquake*/ MSG_WriteByte(&net_message, 1); /*'mod', 1=proquake*/
MSG_WriteByte(&net_message, 34); /*'mod' version*/ MSG_WriteByte(&net_message, 34); /*'mod' version*/
MSG_WriteByte(&net_message, 0); /*flags*/ 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)); *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
dfunc.Write (newsock, net_message.data, net_message.cursize, serveraddr); dfunc.Write (newsock, net_message.data, net_message.cursize, serveraddr);

View file

@ -1543,7 +1543,7 @@ void SV_Init (void)
extern cvar_t sv_reportheartbeats; //spike extern cvar_t sv_reportheartbeats; //spike
extern cvar_t com_protocolname; //spike extern cvar_t com_protocolname; //spike
extern cvar_t net_masters[]; //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_watersplash; //spike - making these changable is handy...
extern cvar_t sv_sound_land; //spike - and also mutable... 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_public);
Cvar_RegisterVariable (&sv_reportheartbeats); Cvar_RegisterVariable (&sv_reportheartbeats);
Cvar_RegisterVariable (&com_protocolname); Cvar_RegisterVariable (&com_protocolname);
Cvar_RegisterVariable (&password);
for (i = 0; net_masters[i].name; i++) for (i = 0; net_masters[i].name; i++)
Cvar_RegisterVariable (&net_masters[i]); Cvar_RegisterVariable (&net_masters[i]);
Cvar_RegisterVariable (&rcon_password); Cvar_RegisterVariable (&rcon_password);