fix(Core): fix ip bans (#6519)

This commit is contained in:
Axel Cocat
2021-06-28 18:02:19 +02:00
committed by GitHub
parent 091b072be1
commit f1727b79d2
3 changed files with 43 additions and 23 deletions

View File

@@ -185,11 +185,15 @@ const AuthHandler table[] =
void AccountInfo::LoadResult(Field* fields)
{
// 0 1 2 3 4 5 6
//SELECT a.id, a.username, a.locked, a.lock_country, a.last_ip, a.failed_logins, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate,
// 7 8
// ab.unbandate = ab.bandate, aa.gmlevel (, more query-specific fields)
//FROM account a LEFT JOIN account_access aa ON a.id = aa.AccountID LEFT JOIN account_banned ab ON ab.id = a.id AND ab.active = 1 WHERE a.username = ?
// 0 1 2 3 4 5
// SELECT a.id, a.username, a.locked, a.lock_country, a.last_ip, a.failed_logins,
// 6 7
// ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, ab.unbandate = ab.bandate,
// 8 9
// ipb.unbandate > UNIX_TIMESTAMP() OR ipb.unbandate = ipb.bandate, ipb.unbandate = ipb.bandate,
// 10
// aa.gmlevel (, more query-specific fields)
// FROM account a LEFT JOIN account_access aa ON a.id = aa.id LEFT JOIN account_banned ab ON ab.id = a.id AND ab.active = 1 LEFT JOIN ip_banned ipb ON ipb.ip = ? WHERE a.username = ?
Id = fields[0].GetUInt32();
Login = fields[1].GetString();
@@ -197,9 +201,9 @@ void AccountInfo::LoadResult(Field* fields)
LockCountry = fields[3].GetString();
LastIP = fields[4].GetString();
FailedLogins = fields[5].GetUInt32();
IsBanned = fields[6].GetUInt64() != 0;
IsPermanenetlyBanned = fields[7].GetUInt64() != 0;
SecurityLevel = static_cast<AccountTypes>(fields[8].GetUInt8()) > SEC_CONSOLE ? SEC_CONSOLE : static_cast<AccountTypes>(fields[8].GetUInt8());
IsBanned = fields[6].GetBool() || fields[8].GetBool();
IsPermanentlyBanned = fields[7].GetBool() || fields[9].GetBool();
SecurityLevel = static_cast<AccountTypes>(fields[10].GetUInt8()) > SEC_CONSOLE ? SEC_CONSOLE : static_cast<AccountTypes>(fields[10].GetUInt8());
// Use our own uppercasing of the account name instead of using UPPER() in mysql query
// This is how the account was created in the first place and changing it now would result in breaking
@@ -378,7 +382,8 @@ bool AuthSocket::_HandleLogonChallenge()
// Get the account details from the account table
// No SQL injection (prepared statement)
auto stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LOGONCHALLENGE);
stmt->setString(0, login);
stmt->setString(0, ipAddress);
stmt->setString(1, login);
PreparedQueryResult res2 = LoginDatabase.Query(stmt);
if (!res2) //no account
@@ -428,7 +433,7 @@ bool AuthSocket::_HandleLogonChallenge()
// If the account is banned, reject the logon attempt
if (_accountInfo.IsBanned)
{
if (_accountInfo.IsPermanenetlyBanned)
if (_accountInfo.IsPermanentlyBanned)
{
pkt << uint8(WOW_FAIL_BANNED);
LOG_DEBUG("server.authserver.banned", "'%s:%d' [AuthChallenge] Banned account %s tried to login!", ipAddress.c_str(), port, _accountInfo.Login.c_str());
@@ -446,12 +451,12 @@ bool AuthSocket::_HandleLogonChallenge()
uint8 securityFlags = 0;
// Check if a TOTP token is needed
if (sConfigMgr->GetOption<bool>("EnableTOTP", false) && !fields[9].IsNull())
if (sConfigMgr->GetOption<bool>("EnableTOTP", false) && !fields[11].IsNull())
{
LOG_DEBUG("server.authserver", "[AuthChallenge] Account '%s' using TOTP", _accountInfo.Login.c_str());
securityFlags = 4;
_totpSecret = fields[9].GetBinary();
_totpSecret = fields[11].GetBinary();
if (auto const& secret = sSecretMgr->GetSecret(SECRET_TOTP_MASTER_KEY))
{
bool success = Acore::Crypto::AEDecrypt<Acore::Crypto::AES>(*_totpSecret, *secret);
@@ -467,8 +472,8 @@ bool AuthSocket::_HandleLogonChallenge()
_srp6.emplace(
_accountInfo.Login,
fields[10].GetBinary<Acore::Crypto::SRP6::SALT_LENGTH>(),
fields[11].GetBinary<Acore::Crypto::SRP6::VERIFIER_LENGTH>());
fields[12].GetBinary<Acore::Crypto::SRP6::SALT_LENGTH>(),
fields[13].GetBinary<Acore::Crypto::SRP6::VERIFIER_LENGTH>());
// Fill the response packet with the result
if (!AuthHelper::IsAcceptedClientBuild(_build))
@@ -720,7 +725,8 @@ bool AuthSocket::_HandleReconnectChallenge()
return false;
auto* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RECONNECTCHALLENGE);
stmt->setString(0, login);
stmt->setString(0, socket().getRemoteAddress());
stmt->setString(1, login);
PreparedQueryResult result = LoginDatabase.Query(stmt);
// Stop if the account is not found
@@ -737,7 +743,7 @@ bool AuthSocket::_HandleReconnectChallenge()
// Restore string order as its byte order is reversed
std::reverse(_os.begin(), _os.end());
_sessionKey = fields[9].GetBinary<SESSION_KEY_LENGTH>();
_sessionKey = fields[11].GetBinary<SESSION_KEY_LENGTH>();
Acore::Crypto::GetRandomBytes(_reconnectProof);
///- All good, await client's proof

View File

@@ -39,7 +39,7 @@ struct AccountInfo
std::string LastIP;
uint32 FailedLogins = 0;
bool IsBanned = false;
bool IsPermanenetlyBanned = false;
bool IsPermanentlyBanned = false;
AccountTypes SecurityLevel = SEC_PLAYER;
};