Reopen: Add a flag for rcon login via username (#800)

This uses an extended protocol message to signal that rcon
authentication might require a username, allowing the client to enable
the username prompt.

Add a forgotten logout on key update
This commit is contained in:
heinrich5991 2017-07-24 21:43:55 +02:00 committed by GitHub
parent cf08239e58
commit 1ebb4f89a6
11 changed files with 59 additions and 12 deletions

View file

@ -204,6 +204,7 @@ protected:
public:
virtual void OnConsoleInit() = 0;
virtual void OnRconType(bool UsernameReq) = 0;
virtual void OnRconLine(const char *pLine) = 0;
virtual void OnInit() = 0;
virtual void OnNewSnapshot() = 0;

View file

@ -1978,6 +1978,11 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket)
}
}
}
else if(Msg == NETMSG_RCONTYPE)
{
bool UsernameReq = Unpacker.GetInt() & 1;
GameClient()->OnRconType(UsernameReq);
}
}
else
{

View file

@ -182,3 +182,9 @@ bool CAuthManager::IsGenerated()
{
return m_Generated;
}
int CAuthManager::NumNonDefaultKeys()
{
int DefaultCount = (m_aDefault[0] >= 0) + (m_aDefault[1] >= 0) + (m_aDefault[2] >= 0);
return m_aKeys.size() - DefaultCount;
}

View file

@ -46,6 +46,7 @@ public:
void ListKeys(FListCallback pfnListCallbac, void *pUser);
void AddDefaultKey(int Level, const char *pPw);
bool IsGenerated();
int NumNonDefaultKeys();
};
#endif //ENGINE_SERVER_AUTH_MANAGER_H

View file

@ -864,6 +864,13 @@ int CServer::DelClientCallback(int ClientID, const char *pReason, void *pUser)
return 0;
}
void CServer::SendRconType(int ClientID, bool UsernameReq)
{
CMsgPacker Msg(NETMSG_RCONTYPE);
Msg.AddInt(UsernameReq);
SendMsgEx(&Msg, MSGFLAG_VITAL, ClientID, true);
}
void CServer::SendMap(int ClientID)
{
CMsgPacker Msg(NETMSG_MAP_CHANGE);
@ -1052,6 +1059,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
}
m_aClients[ClientID].m_State = CClient::STATE_CONNECTING;
SendRconType(ClientID, m_AuthManager.NumNonDefaultKeys() > 0);
SendMap(ClientID);
}
}
@ -2094,10 +2102,15 @@ void CServer::ConAuthAdd(IConsole::IResult *pResult, void *pUser)
return;
}
bool NeedUpdate = !pManager->NumNonDefaultKeys();
if(pManager->AddKey(pIdent, pPw, Level) < 0)
pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "auth", "ident already exists");
else
{
if(NeedUpdate)
pThis->SendRconType(-1, true);
pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "auth", "key added");
}
}
void CServer::ConAuthAddHashed(IConsole::IResult *pResult, void *pUser)
@ -2131,10 +2144,16 @@ void CServer::ConAuthAddHashed(IConsole::IResult *pResult, void *pUser)
return;
}
bool NeedUpdate = !pManager->NumNonDefaultKeys();
if(pManager->AddKeyHash(pIdent, aHash, aSalt, Level) < 0)
pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "auth", "ident already exists");
else
{
if(NeedUpdate)
pThis->SendRconType(-1, true);
pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "auth", "key added");
}
}
void CServer::ConAuthUpdate(IConsole::IResult *pResult, void *pUser)
@ -2161,6 +2180,7 @@ void CServer::ConAuthUpdate(IConsole::IResult *pResult, void *pUser)
}
pManager->UpdateKey(KeySlot, pPw, Level);
pThis->LogoutKey(KeySlot, "key update");
pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "auth", "key updated");
}
@ -2224,6 +2244,10 @@ void CServer::ConAuthRemove(IConsole::IResult *pResult, void *pUser)
}
pThis->AuthRemoveKey(KeySlot);
if(!pManager->NumNonDefaultKeys())
pThis->SendRconType(-1, false);
pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "auth", "key removed, all users logged out");
}

View file

@ -252,6 +252,7 @@ public:
static int ClientRejoinCallback(int ClientID, void *pUser);
void SendRconType(int ClientID, bool UsernameReq);
void SendMap(int ClientID);
void SendMapData(int ClientID, int Chunk);
void SendConnectionReady(int ClientID);

View file

@ -20,3 +20,5 @@
UUID(NETMSG_WHATIS, "what-is@ddnet.tw")
UUID(NETMSG_ITIS, "it-is@ddnet.tw")
UUID(NETMSG_IDONTKNOW, "i-dont-know@ddnet.tw")
UUID(NETMSG_RCONTYPE, "rcon-type@ddnet.tw")

View file

@ -51,6 +51,7 @@ CGameConsole::CInstance::CInstance(int Type)
m_aUser[0] = '\0';
m_UserGot = false;
m_UsernameReq = false;
m_IsCommand = false;
}
@ -82,10 +83,7 @@ void CGameConsole::CInstance::ExecuteLine(const char *pLine)
m_pGameConsole->Client()->Rcon(pLine);
else
{
CServerInfo pServerInfo;
m_pGameConsole->Client()->GetServerInfo(&pServerInfo);
if(!m_UserGot && IsDDNet(&pServerInfo))
if(!m_UserGot && m_UsernameReq)
{
m_UserGot = true;
str_copy(m_aUser, pLine, sizeof m_aUser);
@ -149,9 +147,7 @@ void CGameConsole::CInstance::OnInput(IInput::CEvent Event)
{
if(Event.m_Key == KEY_RETURN || Event.m_Key == KEY_KP_ENTER)
{
CServerInfo pServerInfo;
m_pGameConsole->Client()->GetServerInfo(&pServerInfo);
if(m_Input.GetString()[0] || (IsDDNet(&pServerInfo) && !m_pGameConsole->Client()->RconAuthed() && !m_UserGot))
if(m_Input.GetString()[0] || (m_UsernameReq && !m_pGameConsole->Client()->RconAuthed() && !m_UserGot))
{
if(m_Type == CONSOLETYPE_LOCAL || m_pGameConsole->Client()->RconAuthed())
{
@ -488,9 +484,6 @@ void CGameConsole::OnRender()
Info.m_pCurrentCmd = pConsole->m_aCompletionBuffer;
TextRender()->SetCursor(&Info.m_Cursor, x+Info.m_Offset, y+RowHeight+2.0f, FontSize, TEXTFLAG_RENDER);
CServerInfo pServerInfo;
Client()->GetServerInfo(&pServerInfo);
// render prompt
CTextCursor Cursor;
TextRender()->SetCursor(&Cursor, x, y, FontSize, TEXTFLAG_RENDER);
@ -503,7 +496,7 @@ void CGameConsole::OnRender()
pPrompt = "rcon> ";
else
{
if(IsDDNet(&pServerInfo))
if(pConsole->m_UsernameReq)
{
if(!pConsole->m_UserGot)
pPrompt = "Enter Username> ";
@ -537,7 +530,7 @@ void CGameConsole::OnRender()
//hide rcon password
char aInputString[512];
str_copy(aInputString, pConsole->m_Input.GetString(Editing), sizeof(aInputString));
if(m_ConsoleType == CONSOLETYPE_REMOTE && Client()->State() == IClient::STATE_ONLINE && !Client()->RconAuthed() && (pConsole->m_UserGot || !IsDDNet(&pServerInfo)))
if(m_ConsoleType == CONSOLETYPE_REMOTE && Client()->State() == IClient::STATE_ONLINE && !Client()->RconAuthed() && (pConsole->m_UserGot || !pConsole->m_UsernameReq))
{
for(int i = 0; i < pConsole->m_Input.GetLength(Editing); ++i)
aInputString[i] = '*';
@ -788,6 +781,11 @@ void CGameConsole::ConchainConsoleOutputLevelUpdate(IConsole::IResult *pResult,
}
}
void CGameConsole::RequireUsername(bool UsernameReq)
{
m_RemoteConsole.m_UsernameReq = UsernameReq;
}
void CGameConsole::PrintLine(int Type, const char *pLine)
{
if(Type == CONSOLETYPE_LOCAL)
@ -823,5 +821,6 @@ void CGameConsole::OnStateChange(int NewState, int OldState)
{
m_RemoteConsole.m_UserGot = false;
m_RemoteConsole.m_Input.Clear();
m_RemoteConsole.m_UsernameReq = false;
}
}

View file

@ -45,6 +45,7 @@ class CGameConsole : public CComponent
char m_aUser[32];
bool m_UserGot;
bool m_UsernameReq;
bool m_IsCommand;
char m_aCommandName[IConsole::TEMPCMD_NAME_LENGTH];
@ -103,6 +104,7 @@ public:
CGameConsole();
void PrintLine(int Type, const char *pLine);
void RequireUsername(bool UsernameReq);
virtual void OnStateChange(int NewState, int OldState);
virtual void OnConsoleInit();

View file

@ -884,6 +884,11 @@ void CGameClient::OnFlagGrab(int TeamID)
m_aStats[m_Snap.m_pGameDataObj->m_FlagCarrierBlue].m_FlagGrabs++;
}
void CGameClient::OnRconType(bool UsernameReq)
{
m_pGameConsole->RequireUsername(UsernameReq);
}
void CGameClient::OnRconLine(const char *pLine)
{
m_pGameConsole->PrintLine(CGameConsole::CONSOLETYPE_REMOTE, pLine);

View file

@ -311,6 +311,7 @@ public:
virtual int OnSnapInput(int *pData, bool Dummy, bool Force);
virtual void OnShutdown();
virtual void OnEnterGame();
virtual void OnRconType(bool UsernameReq);
virtual void OnRconLine(const char *pLine);
virtual void OnGameOver();
virtual void OnStartGame();