From 71548fc0d6fe83bb4a3d4979245f5b8d8b53889a Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Sun, 21 Jun 2015 19:46:55 +0200 Subject: [PATCH] If no rcon password is set, generate one After the generation (using the OS random number generator), the password is displayed to the user on stdout. --- src/base/system.c | 2 +- src/base/system.h | 2 +- src/engine/server/server.cpp | 45 ++++++++++++++++++++++++++++ src/engine/server/server.h | 4 +++ src/engine/shared/network_server.cpp | 6 ---- 5 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/base/system.c b/src/base/system.c index a4e161154..709dcea5f 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -2434,7 +2434,7 @@ int secure_random_init() #endif } -void secure_random_fill(unsigned char *bytes, size_t length) +void secure_random_fill(void *bytes, size_t length) { if(!secure_random_data.initialized) { diff --git a/src/base/system.h b/src/base/system.h index d52155b7c..a7ac63ec7 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -1367,7 +1367,7 @@ int secure_random_init(); buffer - Pointer to the start of the buffer. length - Length of the buffer. */ -void secure_random_fill(unsigned char *bytes, size_t length); +void secure_random_fill(void *bytes, size_t length); #ifdef __cplusplus } diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 233092de3..769d0b03c 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -314,6 +314,7 @@ CServer::CServer() m_RconAuthLevel = AUTHED_ADMIN; m_RconRestrict = -1; + m_GeneratedRconPassword = 0; Init(); } @@ -532,6 +533,36 @@ int CServer::MaxClients() const return m_NetServer.MaxClients(); } +void CServer::InitRconPasswordIfEmpty() +{ + if(g_Config.m_SvRconPassword[0]) + { + return; + } + + static const char VALUES[] = "ABCDEFGHKLMNPRSTUVWXYZabcdefghjkmnopqt23456789"; + static const size_t NUM_VALUES = sizeof(VALUES) - 1; // Disregard the '\0'. + static const size_t PASSWORD_LENGTH = 6; + dbg_assert(NUM_VALUES * NUM_VALUES >= 2048, "need at least 2048 possibilities for 2-character sequences"); + // With 6 characters, we get a password entropy of log(2048) * 6/2 = 33bit. + + dbg_assert(PASSWORD_LENGTH % 2 == 0, "need an even password length"); + unsigned short aRandom[PASSWORD_LENGTH / 2]; + char aRandomPassword[PASSWORD_LENGTH+1]; + aRandomPassword[PASSWORD_LENGTH] = 0; + + secure_random_fill(aRandom, sizeof(aRandom)); + for(size_t i = 0; i < PASSWORD_LENGTH / 2; i++) + { + unsigned short RandomNumber = aRandom[i] % 2048; + aRandomPassword[2 * i + 0] = VALUES[RandomNumber / NUM_VALUES]; + aRandomPassword[2 * i + 1] = VALUES[RandomNumber % NUM_VALUES]; + } + + str_copy(g_Config.m_SvRconPassword, aRandomPassword, sizeof(g_Config.m_SvRconPassword)); + m_GeneratedRconPassword = 1; +} + int CServer::SendMsg(CMsgPacker *pMsg, int Flags, int ClientID) { return SendMsgEx(pMsg, Flags, ClientID, false); @@ -1527,6 +1558,13 @@ int CServer::Run() // process pending commands m_pConsole->StoreCommands(false); + if(m_GeneratedRconPassword) + { + dbg_msg("server", "+-------------------------+"); + dbg_msg("server", "| rcon password: '%s' |", g_Config.m_SvRconPassword); + dbg_msg("server", "+-------------------------+"); + } + // start game { bool NonActive = false; @@ -2028,6 +2066,12 @@ int main(int argc, const char **argv) // ignore_convention } #endif + if(secure_random_init() != 0) + { + dbg_msg("secure", "could not initialize secure RNG"); + return -1; + } + CServer *pServer = CreateServer(); IKernel *pKernel = IKernel::Create(); @@ -2086,6 +2130,7 @@ int main(int argc, const char **argv) // ignore_convention #if defined(CONF_FAMILY_UNIX) FifoConsole *fifoConsole = new FifoConsole(pConsole, g_Config.m_SvInputFifo, CFGFLAG_SERVER); #endif + pServer->InitRconPasswordIfEmpty(); // run the server dbg_msg("server", "starting..."); diff --git a/src/engine/server/server.h b/src/engine/server/server.h index 8baa68509..f035ba146 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -174,6 +174,8 @@ public: unsigned char *m_pCurrentMapData; unsigned int m_CurrentMapSize; + int m_GeneratedRconPassword; + CDemoRecorder m_aDemoRecorder[MAX_CLIENTS+1]; CRegister m_Register; CMapChecker m_MapChecker; @@ -200,6 +202,8 @@ public: int Init(); + void InitRconPasswordIfEmpty(); + void SetRconCID(int ClientID); bool IsAuthed(int ClientID); int GetClientInfo(int ClientID, CClientInfo *pInfo); diff --git a/src/engine/shared/network_server.cpp b/src/engine/shared/network_server.cpp index 96b1efa20..fd1dc2210 100644 --- a/src/engine/shared/network_server.cpp +++ b/src/engine/shared/network_server.cpp @@ -30,12 +30,6 @@ bool CNetServer::Open(NETADDR BindAddr, CNetBan *pNetBan, int MaxClients, int Ma m_MaxClientsPerIP = MaxClientsPerIP; - if(secure_random_init() != 0) - { - dbg_msg("secure", "could not initialize secure RNG"); - return false; - } - secure_random_fill(m_SecurityTokenSeed, sizeof(m_SecurityTokenSeed)); for(int i = 0; i < NET_MAX_CLIENTS; i++)