diff --git a/src/server/authserver/Server/AuthSocket.cpp b/src/server/authserver/Server/AuthSocket.cpp index 655f71cc8..baf9cd26e 100644 --- a/src/server/authserver/Server/AuthSocket.cpp +++ b/src/server/authserver/Server/AuthSocket.cpp @@ -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(fields[8].GetUInt8()) > SEC_CONSOLE ? SEC_CONSOLE : static_cast(fields[8].GetUInt8()); + IsBanned = fields[6].GetBool() || fields[8].GetBool(); + IsPermanentlyBanned = fields[7].GetBool() || fields[9].GetBool(); + SecurityLevel = static_cast(fields[10].GetUInt8()) > SEC_CONSOLE ? SEC_CONSOLE : static_cast(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("EnableTOTP", false) && !fields[9].IsNull()) + if (sConfigMgr->GetOption("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(*_totpSecret, *secret); @@ -467,8 +472,8 @@ bool AuthSocket::_HandleLogonChallenge() _srp6.emplace( _accountInfo.Login, - fields[10].GetBinary(), - fields[11].GetBinary()); + fields[12].GetBinary(), + fields[13].GetBinary()); // 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(); + _sessionKey = fields[11].GetBinary(); Acore::Crypto::GetRandomBytes(_reconnectProof); ///- All good, await client's proof diff --git a/src/server/authserver/Server/AuthSocket.h b/src/server/authserver/Server/AuthSocket.h index 20ca60e53..5b8e91bbf 100644 --- a/src/server/authserver/Server/AuthSocket.h +++ b/src/server/authserver/Server/AuthSocket.h @@ -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; }; diff --git a/src/server/database/Database/Implementation/LoginDatabase.cpp b/src/server/database/Database/Implementation/LoginDatabase.cpp index 90989bde9..c369aaa79 100644 --- a/src/server/database/Database/Implementation/LoginDatabase.cpp +++ b/src/server/database/Database/Implementation/LoginDatabase.cpp @@ -11,12 +11,26 @@ void LoginDatabaseConnection::DoPrepareStatements() if (!m_reconnecting) m_stmts.resize(MAX_LOGINDATABASE_STATEMENTS); - PrepareStatement(LOGIN_SEL_LOGONCHALLENGE, "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, " - "ab.unbandate = ab.bandate, aa.gmlevel, a.totp_secret, a.salt, a.verifier " - "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 WHERE a.username = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_RECONNECTCHALLENGE, "SELECT a.id, UPPER(a.username), a.locked, a.lock_country, a.last_ip, a.failed_logins, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, " - "ab.unbandate = ab.bandate, aa.gmlevel, a.session_key " - "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 WHERE a.username = ? AND a.session_key IS NOT NULL", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_LOGONCHALLENGE, + "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, ab.unbandate = ab.bandate, " + "ipb.unbandate > UNIX_TIMESTAMP() OR ipb.unbandate = ipb.bandate, ipb.unbandate = ipb.bandate, " + "aa.gmlevel, a.totp_secret, a.salt, a.verifier " + "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 = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_RECONNECTCHALLENGE, + "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, ab.unbandate = ab.bandate, " + "ipb.unbandate > UNIX_TIMESTAMP() OR ipb.unbandate = ipb.bandate, ipb.unbandate = ipb.bandate, " + "aa.gmlevel, a.session_key " + "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 = ? AND a.session_key IS NOT NULL", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME, "SELECT a.id, a.session_key, a.last_ip, a.locked, a.lock_country, a.expansion, a.mutetime, a.locale, a.recruiter, a.os, a.totaltime, " "aa.gmlevel, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, r.id FROM account a LEFT JOIN account_access aa ON a.id = aa.id AND aa.RealmID IN (-1, ?) " "LEFT JOIN account_banned ab ON a.id = ab.id AND ab.active = 1 LEFT JOIN account r ON a.id = r.recruiter WHERE a.username = ? "