Promote RCON command execution authority

Allow RCON to execute any commands and set any cvar, regardless of their flags.
This commit is contained in:
Kawe Mazidjatari 2023-08-04 11:53:46 +02:00
parent f6d2628937
commit ce4b7b84a8
2 changed files with 27 additions and 10 deletions

View File

@ -909,7 +909,9 @@ RCON_CmdQuery_f
*/ */
void RCON_CmdQuery_f(const CCommand& args) void RCON_CmdQuery_f(const CCommand& args)
{ {
if (args.ArgC() < 2) const int64_t argCount = args.ArgC();
if (argCount < 2)
{ {
const char* pszAddress = rcon_address->GetString(); const char* pszAddress = rcon_address->GetString();
@ -935,7 +937,7 @@ void RCON_CmdQuery_f(const CCommand& args)
if (strcmp(args.Arg(1), "PASS") == 0) // Auth with RCON server using rcon_password ConVar value. if (strcmp(args.Arg(1), "PASS") == 0) // Auth with RCON server using rcon_password ConVar value.
{ {
if (args.ArgC() > 2) if (argCount > 2)
{ {
bSuccess = RCONClient()->Serialize(vecMsg, args.Arg(2), "", cl_rcon::request_t::SERVERDATA_REQUEST_AUTH); bSuccess = RCONClient()->Serialize(vecMsg, args.Arg(2), "", cl_rcon::request_t::SERVERDATA_REQUEST_AUTH);
} }
@ -957,7 +959,7 @@ void RCON_CmdQuery_f(const CCommand& args)
return; return;
} }
bSuccess = RCONClient()->Serialize(vecMsg, args.ArgS(), "", cl_rcon::request_t::SERVERDATA_REQUEST_EXECCOMMAND); bSuccess = RCONClient()->Serialize(vecMsg, args.Arg(1), args.ArgS(), cl_rcon::request_t::SERVERDATA_REQUEST_EXECCOMMAND);
if (bSuccess) if (bSuccess)
{ {
RCONClient()->Send(hSocket, vecMsg.data(), int(vecMsg.size())); RCONClient()->Send(hSocket, vecMsg.data(), int(vecMsg.size()));

View File

@ -439,19 +439,34 @@ bool CRConServer::ProcessMessage(const char* pMsgBuf, const int nMsgLen)
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: execute commands issued from netconsole // Purpose: execute commands issued from netconsole (ignores all protection flags)
// Input : *request - // Input : &request -
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CRConServer::Execute(const cl_rcon::request& request) const void CRConServer::Execute(const cl_rcon::request& request) const
{ {
ConVar* pConVar = g_pCVar->FindVar(request.requestmsg().c_str()); const char* pCommandString = request.requestmsg().c_str();
if (pConVar) // Only run if this is a ConVar. ConCommandBase* pCommandBase = g_pCVar->FindCommandBase(pCommandString);
if (!pCommandBase)
{ {
pConVar->SetValue(request.requestval().c_str()); // Found nothing.
return;
} }
else // Execute command with "<val>".
const bool isCommand = pCommandBase->IsCommand();
const char* pValueString = request.requestval().c_str();
if (!isCommand)
{ {
Cbuf_AddText(Cbuf_GetCurrentPlayer(), request.requestmsg().c_str(), cmd_source_t::kCommandSrcCode); ConVar* pConVar = reinterpret_cast<ConVar*>(pCommandBase);
pConVar->SetValue(pValueString);
}
else // Invoke command callback directly.
{
CCommand cmd;
cmd.Tokenize(pValueString, cmd_source_t::kCommandSrcCode);
v_Cmd_Dispatch(ECommandTarget_t::CBUF_SERVER, pCommandBase, &cmd, false);
} }
} }