Allow access to unvalidated authstrings (bug 5587, r=psychonic).

This commit is contained in:
Asher Baker 2013-03-07 00:58:17 +00:00
parent 462b5213d7
commit 0e865c0618
8 changed files with 59 additions and 38 deletions

View File

@ -116,7 +116,7 @@ PlayerManager::PlayerManager()
m_SourceTVUserId = -1;
m_ReplayUserId = -1;
m_bUseSteamAdminAuth = true; // use steam auth by default
m_bAuthstringValidation = true; // use steam auth by default
m_UserIdLookUp = new int[USHRT_MAX+1];
memset(m_UserIdLookUp, 0, sizeof(int) * (USHRT_MAX+1));
@ -234,9 +234,9 @@ ConfigResult PlayerManager::OnSourceModConfigChanged(const char *key,
} else if (strcmp( key, "SteamAuthstringValidation" ) == 0) {
if (strcasecmp(value, "yes") == 0)
{
m_bUseSteamAdminAuth = true;
m_bAuthstringValidation = true;
} else if ( strcasecmp(value, "no") == 0) {
m_bUseSteamAdminAuth = false;
m_bAuthstringValidation = false;
} else {
UTIL_Format(error, maxlength, "Invalid value: must be \"yes\" or \"no\"");
return ConfigResult_Reject;
@ -367,23 +367,18 @@ void PlayerManager::RunAuthChecks()
{
pPlayer = &m_Players[m_AuthQueue[i]];
authstr = engine->GetPlayerNetworkIDString(pPlayer->m_pEdict);
pPlayer->SetAuthString(authstr);
#if SOURCE_ENGINE >= SE_ORANGEBOX
// we can only easily check if the client is fully authed if we're on a recent engine
if (m_bUseSteamAdminAuth && !g_HL2.IsLANServer())
if (!pPlayer->IsAuthStringValidated())
{
if (!pPlayer->IsAuthedBySteam())
{
continue; // we're using steam auth, and steam doesn't know about this player yet so we can't do anything about them for now
}
continue; // we're using steam auth, and steam doesn't know about this player yet so we can't do anything about them for now
}
#endif
if (authstr && authstr[0] != '\0'
&& (strcmp(authstr, "STEAM_ID_PENDING") != 0))
{
/* Set authorization */
pPlayer->Authorize(authstr);
pPlayer->Authorize();
/* Mark as removed from queue */
unsigned int client = m_AuthQueue[i];
@ -558,7 +553,8 @@ void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername
/* Run manual connection routines */
char error[255];
const char *authid = engine->GetPlayerNetworkIDString(pEntity);
pPlayer->Authorize(authid);
pPlayer->SetAuthString(authid);
pPlayer->Authorize();
pPlayer->m_bFakeClient = true;
/*
@ -1272,11 +1268,12 @@ void PlayerManager::ProcessCommandTarget(cmd_target_info_t *info)
{
continue;
}
if (!pTarget->IsConnected() || !pTarget->IsAuthorized())
if (!pTarget->IsConnected())
{
continue;
}
if (strcmp(pTarget->GetAuthString(), new_pattern) == 0)
const char *authstr = pTarget->GetAuthString(false); // We want to make it easy for people to be kicked/banned, so don't require validation for command targets.
if (authstr && strcmp(authstr, new_pattern) == 0)
{
if ((info->reason = FilterCommandTarget(pAdmin, pTarget, info->flags))
== COMMAND_TARGET_VALID)
@ -1634,17 +1631,22 @@ void CPlayer::Connect()
}
}
void CPlayer::Authorize(const char *steamid)
void CPlayer::SetAuthString(const char *steamid)
{
if (m_IsAuthorized)
{
return;
}
m_IsAuthorized = true;
m_AuthID.assign(steamid);
}
// Ensure a valid AuthString is set before calling.
void CPlayer::Authorize()
{
m_IsAuthorized = true;
}
void CPlayer::Disconnect()
{
DumpAdmin(false);
@ -1685,8 +1687,13 @@ const char *CPlayer::GetIPAddress()
return m_Ip.c_str();
}
const char *CPlayer::GetAuthString()
const char *CPlayer::GetAuthString(bool validated)
{
if (validated && !IsAuthStringValidated())
{
return NULL;
}
return m_AuthID.c_str();
}
@ -1715,12 +1722,17 @@ bool CPlayer::IsAuthorized()
return m_IsAuthorized;
}
bool CPlayer::IsAuthStringValidated()
{
#if SOURCE_ENGINE >= SE_ORANGEBOX
bool CPlayer::IsAuthedBySteam()
{
return engine->IsClientFullyAuthenticated( m_pEdict );
if (g_Players.m_bAuthstringValidation && !g_HL2.IsLANServer())
{
return engine->IsClientFullyAuthenticated(m_pEdict);
}
#endif
return true;
}
#endif
IPlayerInfo *CPlayer::GetPlayerInfo()
{

View File

@ -69,15 +69,12 @@ public:
public:
const char *GetName();
const char *GetIPAddress();
const char *GetAuthString();
const char *GetAuthString(bool validated = true);
edict_t *GetEdict();
bool IsInGame();
bool WasCountedAsInGame();
bool IsConnected();
bool IsAuthorized();
#if SOURCE_ENGINE >= SE_ORANGEBOX
bool IsAuthedBySteam();
#endif
bool IsFakeClient();
bool IsSourceTV() const;
bool IsReplay() const;
@ -102,9 +99,11 @@ private:
void Disconnect();
void SetName(const char *name);
void DumpAdmin(bool deleting);
void Authorize(const char *auth);
void SetAuthString(const char *auth);
void Authorize();
void Authorize_Post();
void DoPostConnectAuthorization();
bool IsAuthStringValidated();
private:
bool m_IsConnected;
bool m_IsInGame;
@ -220,7 +219,7 @@ private:
unsigned int *m_AuthQueue;
String m_PassInfoVar;
bool m_QueryLang;
bool m_bUseSteamAdminAuth; // are we validating admins with steam before authorizing?
bool m_bAuthstringValidation; // are we validating admins with steam before authorizing?
bool m_bIsListenServer;
int m_ListenClient;
bool m_bIsSourceTVActive;

View File

@ -156,12 +156,20 @@ static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params)
return pCtx->ThrowNativeError("Client %d is not connected", index);
}
if (!pPlayer->IsAuthorized())
bool validate = true;
if (params[0] > 3)
{
validate = !!params[4];
}
const char *authstr = pPlayer->GetAuthString(validate);
if (!authstr || authstr[0] == '\0')
{
return 0;
}
pCtx->StringToLocal(params[2], static_cast<size_t>(params[3]), pPlayer->GetAuthString());
pCtx->StringToLocal(params[2], static_cast<size_t>(params[3]), authstr);
return 1;
}

View File

@ -534,8 +534,8 @@ public ParamCheck(client)
}
case SteamId:
{
GetClientAuthString(i, infoBuffer, sizeof(infoBuffer));
AddMenuItem(itemMenu, infoBuffer, nameBuffer);
if (GetClientAuthString(i, infoBuffer, sizeof(infoBuffer)))
AddMenuItem(itemMenu, infoBuffer, nameBuffer);
}
case IpAddress:
{

View File

@ -49,8 +49,7 @@ PrepareBan(client, target, time, const String:reason[])
return;
}
decl String:authid[64], String:name[32];
GetClientAuthString(target, authid, sizeof(authid));
new String:name[32];
GetClientName(target, name, sizeof(name));
if (!time)

View File

@ -37,7 +37,6 @@ DisplayVoteBanMenu(client, target)
g_voteClient[VOTE_USERID] = GetClientUserId(target);
GetClientName(target, g_voteInfo[VOTE_NAME], sizeof(g_voteInfo[]));
GetClientAuthString(target, g_voteInfo[VOTE_AUTHID], sizeof(g_voteInfo[]));
GetClientIP(target, g_voteInfo[VOTE_IP], sizeof(g_voteInfo[]));
LogAction(client, target, "\"%L\" initiated a ban vote against \"%L\"", client, target);

View File

@ -261,10 +261,13 @@ native bool:GetClientIP(client, String:ip[], maxlen, bool:remport=true);
* @param client Player index.
* @param auth Buffer to store the client's auth string.
* @param maxlen Maximum length of string buffer (includes NULL terminator).
* @param validate Check backend validation status.
* DO NOT PASS FALSE UNLESS YOU UNDERSTAND THE CONSEQUENCES,
* You WILL KNOW if you need to use this, MOST WILL NOT.
* @return True on success, false otherwise.
* @error If the client is not connected or the index is invalid.
*/
native bool:GetClientAuthString(client, String:auth[], maxlen);
native bool:GetClientAuthString(client, String:auth[], maxlen, bool:validate=true);
/**
* Retrieves a client's user id, which is an index incremented for every client

View File

@ -41,7 +41,7 @@
#include <IAdminSystem.h>
#define SMINTERFACE_PLAYERMANAGER_NAME "IPlayerManager"
#define SMINTERFACE_PLAYERMANAGER_VERSION 15
#define SMINTERFACE_PLAYERMANAGER_VERSION 16
struct edict_t;
class IPlayerInfo;
@ -76,10 +76,11 @@ namespace SourceMod
/**
* @brief Returns the player's authentication string.
*
* @param validated Check backend validation status.
* @return String containing the player's auth string.
* May be NULL if unavailable.
*/
virtual const char *GetAuthString() =0;
virtual const char *GetAuthString(bool validated = true) =0;
/**
* @brief Returns the player's edict_t structure.