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: public:
virtual void OnConsoleInit() = 0; virtual void OnConsoleInit() = 0;
virtual void OnRconType(bool UsernameReq) = 0;
virtual void OnRconLine(const char *pLine) = 0; virtual void OnRconLine(const char *pLine) = 0;
virtual void OnInit() = 0; virtual void OnInit() = 0;
virtual void OnNewSnapshot() = 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 else
{ {

View file

@ -182,3 +182,9 @@ bool CAuthManager::IsGenerated()
{ {
return m_Generated; 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 ListKeys(FListCallback pfnListCallbac, void *pUser);
void AddDefaultKey(int Level, const char *pPw); void AddDefaultKey(int Level, const char *pPw);
bool IsGenerated(); bool IsGenerated();
int NumNonDefaultKeys();
}; };
#endif //ENGINE_SERVER_AUTH_MANAGER_H #endif //ENGINE_SERVER_AUTH_MANAGER_H

View file

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

View file

@ -20,3 +20,5 @@
UUID(NETMSG_WHATIS, "what-is@ddnet.tw") UUID(NETMSG_WHATIS, "what-is@ddnet.tw")
UUID(NETMSG_ITIS, "it-is@ddnet.tw") UUID(NETMSG_ITIS, "it-is@ddnet.tw")
UUID(NETMSG_IDONTKNOW, "i-dont-know@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_aUser[0] = '\0';
m_UserGot = false; m_UserGot = false;
m_UsernameReq = false;
m_IsCommand = false; m_IsCommand = false;
} }
@ -82,10 +83,7 @@ void CGameConsole::CInstance::ExecuteLine(const char *pLine)
m_pGameConsole->Client()->Rcon(pLine); m_pGameConsole->Client()->Rcon(pLine);
else else
{ {
CServerInfo pServerInfo; if(!m_UserGot && m_UsernameReq)
m_pGameConsole->Client()->GetServerInfo(&pServerInfo);
if(!m_UserGot && IsDDNet(&pServerInfo))
{ {
m_UserGot = true; m_UserGot = true;
str_copy(m_aUser, pLine, sizeof m_aUser); 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) if(Event.m_Key == KEY_RETURN || Event.m_Key == KEY_KP_ENTER)
{ {
CServerInfo pServerInfo; if(m_Input.GetString()[0] || (m_UsernameReq && !m_pGameConsole->Client()->RconAuthed() && !m_UserGot))
m_pGameConsole->Client()->GetServerInfo(&pServerInfo);
if(m_Input.GetString()[0] || (IsDDNet(&pServerInfo) && !m_pGameConsole->Client()->RconAuthed() && !m_UserGot))
{ {
if(m_Type == CONSOLETYPE_LOCAL || m_pGameConsole->Client()->RconAuthed()) if(m_Type == CONSOLETYPE_LOCAL || m_pGameConsole->Client()->RconAuthed())
{ {
@ -488,9 +484,6 @@ void CGameConsole::OnRender()
Info.m_pCurrentCmd = pConsole->m_aCompletionBuffer; Info.m_pCurrentCmd = pConsole->m_aCompletionBuffer;
TextRender()->SetCursor(&Info.m_Cursor, x+Info.m_Offset, y+RowHeight+2.0f, FontSize, TEXTFLAG_RENDER); TextRender()->SetCursor(&Info.m_Cursor, x+Info.m_Offset, y+RowHeight+2.0f, FontSize, TEXTFLAG_RENDER);
CServerInfo pServerInfo;
Client()->GetServerInfo(&pServerInfo);
// render prompt // render prompt
CTextCursor Cursor; CTextCursor Cursor;
TextRender()->SetCursor(&Cursor, x, y, FontSize, TEXTFLAG_RENDER); TextRender()->SetCursor(&Cursor, x, y, FontSize, TEXTFLAG_RENDER);
@ -503,7 +496,7 @@ void CGameConsole::OnRender()
pPrompt = "rcon> "; pPrompt = "rcon> ";
else else
{ {
if(IsDDNet(&pServerInfo)) if(pConsole->m_UsernameReq)
{ {
if(!pConsole->m_UserGot) if(!pConsole->m_UserGot)
pPrompt = "Enter Username> "; pPrompt = "Enter Username> ";
@ -537,7 +530,7 @@ void CGameConsole::OnRender()
//hide rcon password //hide rcon password
char aInputString[512]; char aInputString[512];
str_copy(aInputString, pConsole->m_Input.GetString(Editing), sizeof(aInputString)); 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) for(int i = 0; i < pConsole->m_Input.GetLength(Editing); ++i)
aInputString[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) void CGameConsole::PrintLine(int Type, const char *pLine)
{ {
if(Type == CONSOLETYPE_LOCAL) if(Type == CONSOLETYPE_LOCAL)
@ -823,5 +821,6 @@ void CGameConsole::OnStateChange(int NewState, int OldState)
{ {
m_RemoteConsole.m_UserGot = false; m_RemoteConsole.m_UserGot = false;
m_RemoteConsole.m_Input.Clear(); m_RemoteConsole.m_Input.Clear();
m_RemoteConsole.m_UsernameReq = false;
} }
} }

View file

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

View file

@ -884,6 +884,11 @@ void CGameClient::OnFlagGrab(int TeamID)
m_aStats[m_Snap.m_pGameDataObj->m_FlagCarrierBlue].m_FlagGrabs++; 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) void CGameClient::OnRconLine(const char *pLine)
{ {
m_pGameConsole->PrintLine(CGameConsole::CONSOLETYPE_REMOTE, 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 int OnSnapInput(int *pData, bool Dummy, bool Force);
virtual void OnShutdown(); virtual void OnShutdown();
virtual void OnEnterGame(); virtual void OnEnterGame();
virtual void OnRconType(bool UsernameReq);
virtual void OnRconLine(const char *pLine); virtual void OnRconLine(const char *pLine);
virtual void OnGameOver(); virtual void OnGameOver();
virtual void OnStartGame(); virtual void OnStartGame();