diff --git a/src/d_clisrv.c b/src/d_clisrv.c index f8a60004c..1ac529422 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -143,8 +143,8 @@ UINT8 hu_redownloadinggamestate = 0; // kart, true when a player is connecting or disconnecting so that the gameplay has stopped in its tracks boolean hu_stopped = false; -UINT8 adminpassmd5[16]; -boolean adminpasswordset = false; +UINT8 (*adminpassmd5)[16]; +UINT32 adminpasscount = 0; // Client specific static ticcmd_t localcmds[MAXSPLITSCREENPLAYERS][MAXGENTLEMENDELAY]; @@ -4629,6 +4629,7 @@ static void HandlePacketFromPlayer(SINT8 node) INT32 netconsole; tic_t realend, realstart; UINT8 *pak, *txtpak, numtxtpak; + UINT32 i; #ifndef NOMD5 UINT8 finalmd5[16];/* Well, it's the cool thing to do? */ #endif @@ -4874,22 +4875,26 @@ static void HandlePacketFromPlayer(SINT8 node) if (doomcom->datalength < 16)/* ignore partial sends */ break; - if (!adminpasswordset) + if (adminpasscount == 0) { CONS_Printf(M_GetText("Password from %s failed (no password set).\n"), player_names[netconsole]); break; } - // Do the final pass to compare with the sent md5 - D_MD5PasswordPass(adminpassmd5, 16, va("PNUM%02d", netconsole), &finalmd5); - - if (!memcmp(netbuffer->u.md5sum, finalmd5, 16)) + for (i = 0; i < adminpasscount; i++) { - CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[netconsole]); - COM_BufInsertText(va("promote %d\n", netconsole)); // do this immediately + // Do the final pass to compare with the sent md5 + D_MD5PasswordPass(adminpassmd5[i], 16, va("PNUM%02d", netconsole), &finalmd5); + + if (!memcmp(netbuffer->u.md5sum, finalmd5, 16)) + { + CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[netconsole]); + COM_BufInsertText(va("promote %d\n", netconsole)); // do this immediately + continue; + } } - else - CONS_Printf(M_GetText("Password from %s failed.\n"), player_names[netconsole]); + + CONS_Printf(M_GetText("Password from %s failed.\n"), player_names[netconsole]); #endif break; case PT_NODETIMEOUT: diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 36e273074..26b233d53 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -588,8 +588,8 @@ void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void * extern UINT8 hu_redownloadinggamestate; -extern UINT8 adminpassmd5[16]; -extern boolean adminpasswordset; +extern UINT8 (*adminpassmd5)[16]; +extern UINT32 adminpasscount; extern boolean hu_stopped; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 3dc402cb1..a2ec45c42 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -216,6 +216,7 @@ static void Command_Clearscores_f(void); // Remote Administration static void Command_Changepassword_f(void); +static void Command_Clearpassword_f(void); static void Command_Login_f(void); static void Got_Verification(UINT8 **cp, INT32 playernum); static void Got_Removal(UINT8 **cp, INT32 playernum); @@ -806,6 +807,7 @@ void D_RegisterServerCommands(void) // Remote Administration COM_AddCommand("password", Command_Changepassword_f); + COM_AddCommand("clearpassword", Command_Clearpassword_f); COM_AddCommand("login", Command_Login_f); // useful in dedicated to kick off remote admin COM_AddCommand("promote", Command_Verify_f); RegisterNetXCmd(XD_VERIFIED, Got_Verification); @@ -4065,8 +4067,15 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) void D_SetPassword(const char *pw) { - D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &adminpassmd5); - adminpasswordset = true; + adminpassmd5 = Z_Realloc(adminpassmd5, sizeof(*adminpassmd5) * ++adminpasscount, PU_STATIC, NULL); + D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &adminpassmd5[adminpasscount-1]); +} + +void D_ClearPassword(void) +{ + Z_Free(adminpassmd5); + adminpassmd5 = NULL; + adminpasscount = 0; } // Remote Administration @@ -4084,12 +4093,31 @@ static void Command_Changepassword_f(void) if (COM_Argc() != 2) { - CONS_Printf(M_GetText("password : change remote admin password\n")); + CONS_Printf(M_GetText("password : add remote admin password\n")); return; } D_SetPassword(COM_Argv(1)); - CONS_Printf(M_GetText("Password set.\n")); + CONS_Printf(M_GetText("Password added.\n")); +#endif +} + + +// Remote Administration +static void Command_Clearpassword_f(void) +{ +#ifdef NOMD5 + // If we have no MD5 support then completely disable XD_LOGIN responses for security. + CONS_Alert(CONS_NOTICE, "Remote administration commands are not supported in this build.\n"); +#else + if (client) // cannot change remotely + { + CONS_Printf(M_GetText("Only the server can use this.\n")); + return; + } + + D_ClearPassword(); + CONS_Printf(M_GetText("Passwords cleared.\n")); #endif } diff --git a/src/d_netcmd.h b/src/d_netcmd.h index f68586a1a..f960b0c8e 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -348,6 +348,7 @@ void ClearAdminPlayers(void); void RemoveAdminPlayer(INT32 playernum); void ItemFinder_OnChange(void); void D_SetPassword(const char *pw); +void D_ClearPassword(void); void P_SetPlayerSpectator(INT32 playernum);