diff options
| author | Marius "Teelevision" Neugebauer <marius@teele.eu> | 2014-08-13 06:05:02 +0200 |
|---|---|---|
| committer | Marius "Teelevision" Neugebauer <marius@teele.eu> | 2014-08-13 06:05:02 +0200 |
| commit | 53d9302d597f2e6fc58ba83640caae6f8eb2f49e (patch) | |
| tree | a3f51814d6344d38f9445e529fff958bd8eea88a | |
| parent | 90a607d5c38c03183fe7c779bbe795755adccd8e (diff) | |
| download | zcatch-53d9302d597f2e6fc58ba83640caae6f8eb2f49e.tar.gz zcatch-53d9302d597f2e6fc58ba83640caae6f8eb2f49e.zip | |
added subadmin logins
| -rw-r--r-- | src/engine/console.h | 3 | ||||
| -rw-r--r-- | src/engine/server/server.cpp | 119 | ||||
| -rw-r--r-- | src/engine/server/server.h | 11 | ||||
| -rw-r--r-- | src/engine/shared/console.cpp | 4 | ||||
| -rw-r--r-- | src/engine/shared/console.h | 2 |
5 files changed, 130 insertions, 9 deletions
diff --git a/src/engine/console.h b/src/engine/console.h index 8951d2d1..44c40c16 100644 --- a/src/engine/console.h +++ b/src/engine/console.h @@ -18,6 +18,7 @@ public: OUTPUT_LEVEL_DEBUG, ACCESS_LEVEL_ADMIN=0, + ACCESS_LEVEL_SUBADMIN, ACCESS_LEVEL_MOD, TEMPCMD_NAME_LENGTH=32, @@ -69,7 +70,7 @@ public: virtual void PossibleCommands(const char *pStr, int FlagMask, bool Temp, FPossibleCallback pfnCallback, void *pUser) = 0; virtual void ParseArguments(int NumArgs, const char **ppArguments) = 0; - virtual void Register(const char *pName, const char *pParams, int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp) = 0; + virtual void Register(const char *pName, const char *pParams, int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp, int accessLevel = ACCESS_LEVEL_SUBADMIN) = 0; virtual void RegisterTemp(const char *pName, const char *pParams, int Flags, const char *pHelp) = 0; virtual void DeregisterTemp(const char *pName) = 0; virtual void DeregisterTempAll() = 0; diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 2ad7fbf0..0aa8fde4 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -31,6 +31,10 @@ #include "register.h" #include "server.h" +#include <string.h> +#include <string> +#include <map> + #if defined(CONF_FAMILY_WINDOWS) #define _WIN32_WINNT 0x0501 #define WIN32_LEAN_AND_MEAN @@ -869,7 +873,7 @@ void CServer::UpdateClientRconCommands() if(m_aClients[ClientID].m_State != CClient::STATE_EMPTY && m_aClients[ClientID].m_Authed) { - int ConsoleAccessLevel = m_aClients[ClientID].m_Authed == AUTHED_ADMIN ? IConsole::ACCESS_LEVEL_ADMIN : IConsole::ACCESS_LEVEL_MOD; + int ConsoleAccessLevel = m_aClients[ClientID].m_Authed == AUTHED_ADMIN ? IConsole::ACCESS_LEVEL_ADMIN : (AUTHED_SUBADMIN ? IConsole::ACCESS_LEVEL_SUBADMIN : IConsole::ACCESS_LEVEL_MOD); for(int i = 0; i < MAX_RCONCMD_SEND && m_aClients[ClientID].m_pRconCmdToSend; ++i) { SendRconCmdAdd(m_aClients[ClientID].m_pRconCmdToSend, ClientID); @@ -1050,7 +1054,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBuf); m_RconClientID = ClientID; m_RconAuthLevel = m_aClients[ClientID].m_Authed; - Console()->SetAccessLevel(m_aClients[ClientID].m_Authed == AUTHED_ADMIN ? IConsole::ACCESS_LEVEL_ADMIN : IConsole::ACCESS_LEVEL_MOD); + Console()->SetAccessLevel(m_aClients[ClientID].m_Authed == AUTHED_ADMIN ? IConsole::ACCESS_LEVEL_ADMIN : (m_aClients[ClientID].m_Authed == AUTHED_SUBADMIN ? IConsole::ACCESS_LEVEL_SUBADMIN : IConsole::ACCESS_LEVEL_MOD)); Console()->ExecuteLineFlag(pCmd, CFGFLAG_SERVER); Console()->SetAccessLevel(IConsole::ACCESS_LEVEL_ADMIN); m_RconClientID = IServer::RCON_CID_SERV; @@ -1062,12 +1066,23 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) const char *pPw; Unpacker.GetString(); // login name, not used pPw = Unpacker.GetString(CUnpacker::SANITIZE_CC); - + + // try matching username:password login + const char *delimiter = strchr(pPw, ':'); + std::string username, password; + loginiterator loginit; + bool loginWithUsername = (delimiter != NULL); + if(loginWithUsername) + { + username.assign(pPw, delimiter - pPw); + password.assign(delimiter + 1); + } + if(Unpacker.Error() == 0) { - if(g_Config.m_SvRconPassword[0] == 0 && g_Config.m_SvRconModPassword[0] == 0) + if(g_Config.m_SvRconPassword[0] == 0 && g_Config.m_SvRconModPassword[0] == 0 && logins.empty()) { - SendRconLine(ClientID, "No rcon password set on server. Set sv_rcon_password and/or sv_rcon_mod_password to enable the remote console."); + SendRconLine(ClientID, "No rcon password set on server. Set sv_rcon_password and/or sv_rcon_mod_password or add logins using add_login to enable the remote console."); } else if(g_Config.m_SvRconPassword[0] && str_comp(pPw, g_Config.m_SvRconPassword) == 0) { @@ -1075,7 +1090,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) Msg.AddInt(1); //authed Msg.AddInt(1); //cmdlist SendMsgEx(&Msg, MSGFLAG_VITAL, ClientID, true); - + m_aClients[ClientID].m_Authed = AUTHED_ADMIN; int SendRconCmds = Unpacker.GetInt(); if(Unpacker.Error() == 0 && SendRconCmds) @@ -1102,6 +1117,28 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket) str_format(aBuf, sizeof(aBuf), "ClientID=%d authed (moderator)", ClientID); Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf); } + else if(loginWithUsername + && !logins.empty() + && (loginit = logins.find(username)) != logins.end() + && loginit->second == password) + { + CMsgPacker Msg(NETMSG_RCON_AUTH_STATUS); + Msg.AddInt(1); //authed + Msg.AddInt(1); //cmdlist + SendMsgEx(&Msg, MSGFLAG_VITAL, ClientID, true); + + m_aClients[ClientID].m_Authed = AUTHED_SUBADMIN; + m_aClients[ClientID].m_SubAdminAuthName = loginit->first; + + int SendRconCmds = Unpacker.GetInt(); + if(Unpacker.Error() == 0 && SendRconCmds) + m_aClients[ClientID].m_pRconCmdToSend = Console()->FirstCommandInfo(IConsole::ACCESS_LEVEL_SUBADMIN, CFGFLAG_SERVER); + SendRconLine(ClientID, "Subadmin authentication successful. Limited remote console access granted."); + char aBuf[256]; + str_format(aBuf, sizeof(aBuf), "ClientID=%d authed (subadmin:%s)", ClientID, loginit->first.c_str()); + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf); + IncreaseLoggedInAdmins(); + } else if(g_Config.m_SvRconMaxTries) { m_aClients[ClientID].m_AuthTries++; @@ -1703,6 +1740,70 @@ void CServer::ConVotebans(IConsole::IResult *pResult, void *pUser) pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", aBuf); } +void CServer::ConAddLogin(IConsole::IResult *pResult, void *pUser) +{ + CServer* pThis = static_cast<CServer *>(pUser); + char aBuf[128]; + std::string username(pResult->GetString(0)), + password(pResult->GetString(1)); + + // insert if doesn't exist + if(pThis->logins.find(username) == pThis->logins.end()) + { + pThis->logins[username] = password; + + str_format(aBuf, sizeof(aBuf), "Added login for '%s'.", username.c_str()); + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", aBuf); + } + else + { + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", "Did not overwrite existing login."); + } +} + +void CServer::ConRemoveLogin(IConsole::IResult *pResult, void *pUser) +{ + CServer* pThis = static_cast<CServer *>(pUser); + char aBuf[128]; + loginiterator loginit; + std::string username(pResult->GetString(0)); + + // delete if exists + if((loginit = pThis->logins.find(username)) != pThis->logins.end()) + { + // check if someone is logged in with this login + for(int i = 0; i < MAX_CLIENTS; i++) + { + if(pThis->m_aClients[i].m_State != CClient::STATE_EMPTY && pThis->m_aClients[i].m_Authed == CServer::AUTHED_SUBADMIN && pThis->m_aClients[i].m_SubAdminAuthName == loginit->first) + { + CMsgPacker Msg(NETMSG_RCON_AUTH_STATUS); + Msg.AddInt(0); + Msg.AddInt(0); + pThis->SendMsgEx(&Msg, MSGFLAG_VITAL, i, true); + + pThis->m_aClients[i].m_Authed = AUTHED_NO; + pThis->m_aClients[i].m_AuthTries = 0; + pThis->m_aClients[i].m_pRconCmdToSend = 0; + pThis->SendRconLine(i, "You were logged out."); + char aBuf[32]; + str_format(aBuf, sizeof(aBuf), "ClientID=%d logged out", i); + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf); + pThis->DecreaseLoggedInAdmins(); + } + } + + // finally delete + pThis->logins.erase(loginit); + + str_format(aBuf, sizeof(aBuf), "Removed login '%s'.", username.c_str()); + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", aBuf); + } + else + { + pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", "No login with that username."); + } +} + void CServer::ConKick(IConsole::IResult *pResult, void *pUser) { if(pResult->NumArguments() > 1) @@ -1728,7 +1829,10 @@ void CServer::ConStatus(IConsole::IResult *pResult, void *pUser) net_addr_str(pThis->m_NetServer.ClientAddr(i), aAddrStr, sizeof(aAddrStr), true); if(pThis->m_aClients[i].m_State == CClient::STATE_INGAME) { + char bBuf[32]; + str_format(bBuf, sizeof(bBuf), "(Subadmin:%s)", pThis->m_aClients[i].m_SubAdminAuthName.c_str()); const char *pAuthStr = pThis->m_aClients[i].m_Authed == CServer::AUTHED_ADMIN ? "(Admin)" : + pThis->m_aClients[i].m_Authed == CServer::AUTHED_SUBADMIN ? bBuf : pThis->m_aClients[i].m_Authed == CServer::AUTHED_MOD ? "(Mod)" : ""; const char *pAimBotStr = pThis->GameServer()->IsClientAimBot(i) ? "[aimbot]" : ""; str_format(aBuf, sizeof(aBuf), "id=%d addr=%s name='%s' score=%d %s %s", i, aAddrStr, @@ -1907,6 +2011,9 @@ void CServer::RegisterCommands() Console()->Register("unvoteban", "i", CFGFLAG_SERVER, ConUnvoteban, this, "Remove voteban by index in list votebans"); Console()->Register("unvoteban_client", "i", CFGFLAG_SERVER, ConUnvotebanClient, this, "Remove voteban by player id"); Console()->Register("votebans", "", CFGFLAG_SERVER, ConVotebans, this, "Show all votebans"); + + Console()->Register("add_login", "ss", CFGFLAG_SERVER, ConAddLogin, this, "Add a subadmin login. The rcon password will be user:pass with no additional spaces.", IConsole::ACCESS_LEVEL_ADMIN); + Console()->Register("remove_login", "s", CFGFLAG_SERVER, ConRemoveLogin, this, "Remove a subadmin login", IConsole::ACCESS_LEVEL_ADMIN); // register console commands in sub parts m_ServerBan.InitServerBan(Console(), Storage(), this); diff --git a/src/engine/server/server.h b/src/engine/server/server.h index ebbcc82c..1958c4e6 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -6,6 +6,9 @@ #include <engine/server.h> +#include <string> +#include <map> + class CSnapIDPool { @@ -84,6 +87,7 @@ public: { AUTHED_NO=0, AUTHED_MOD, + AUTHED_SUBADMIN, AUTHED_ADMIN, MAX_RCONCMD_SEND=16, @@ -132,6 +136,7 @@ public: int m_Score; int m_Authed; int m_AuthTries; + std::string m_SubAdminAuthName; const IConsole::CCommandInfo *m_pRconCmdToSend; @@ -280,8 +285,14 @@ public: static void ConUnvoteban(IConsole::IResult *pResult, void *pUser); static void ConUnvotebanClient(IConsole::IResult *pResult, void *pUser); static void ConVotebans(IConsole::IResult *pResult, void *pUser); + static void ConAddLogin(IConsole::IResult *pResult, void *pUser); + static void ConRemoveLogin(IConsole::IResult *pResult, void *pUser); virtual int GetNumLoggedInAdmins() { return m_numLoggedInAdmins; } + + // logins + typedef std::map<std::string,std::string>::iterator loginiterator; + std::map<std::string,std::string> logins; }; #endif diff --git a/src/engine/shared/console.cpp b/src/engine/shared/console.cpp index 399f5323..dcace5b8 100644 --- a/src/engine/shared/console.cpp +++ b/src/engine/shared/console.cpp @@ -738,7 +738,7 @@ void CConsole::AddCommandSorted(CCommand *pCommand) } void CConsole::Register(const char *pName, const char *pParams, - int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp) + int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp, int accessLevel) { CCommand *pCommand = FindCommand(pName, Flags); bool DoAdd = false; @@ -756,6 +756,8 @@ void CConsole::Register(const char *pName, const char *pParams, pCommand->m_Flags = Flags; pCommand->m_Temp = false; + + pCommand->SetAccessLevel(accessLevel); if(DoAdd) AddCommandSorted(pCommand); diff --git a/src/engine/shared/console.h b/src/engine/shared/console.h index bbe267d4..a3d65eb3 100644 --- a/src/engine/shared/console.h +++ b/src/engine/shared/console.h @@ -163,7 +163,7 @@ public: virtual void PossibleCommands(const char *pStr, int FlagMask, bool Temp, FPossibleCallback pfnCallback, void *pUser); virtual void ParseArguments(int NumArgs, const char **ppArguments); - virtual void Register(const char *pName, const char *pParams, int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp); + virtual void Register(const char *pName, const char *pParams, int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp, int accessLevel = ACCESS_LEVEL_SUBADMIN); virtual void RegisterTemp(const char *pName, const char *pParams, int Flags, const char *pHelp); virtual void DeregisterTemp(const char *pName); virtual void DeregisterTempAll(); |