diff options
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/bnetserver/Main.cpp | 1 | ||||
| -rw-r--r-- | src/server/bnetserver/REST/LoginRESTService.cpp | 106 | ||||
| -rw-r--r-- | src/server/bnetserver/REST/LoginRESTService.h | 6 | ||||
| -rw-r--r-- | src/server/database/Database/Implementation/LoginDatabase.cpp | 11 | ||||
| -rw-r--r-- | src/server/database/Database/Implementation/LoginDatabase.h | 7 | 
5 files changed, 101 insertions, 30 deletions
diff --git a/src/server/bnetserver/Main.cpp b/src/server/bnetserver/Main.cpp index b54249f9412..e05fa7c7166 100644 --- a/src/server/bnetserver/Main.cpp +++ b/src/server/bnetserver/Main.cpp @@ -282,6 +282,7 @@ void BanExpiryHandler(boost::system::error_code const& error)      {          LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS));          LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_UPD_EXPIRED_ACCOUNT_BANS)); +        LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_BNET_EXPERIED_ACCOUNT_BANNED));          _banExpiryCheckTimer->expires_from_now(boost::posix_time::seconds(_banExpiryCheckInterval));          _banExpiryCheckTimer->async_wait(BanExpiryHandler); diff --git a/src/server/bnetserver/REST/LoginRESTService.cpp b/src/server/bnetserver/REST/LoginRESTService.cpp index ab02e0b4254..af54f7e913d 100644 --- a/src/server/bnetserver/REST/LoginRESTService.cpp +++ b/src/server/bnetserver/REST/LoginRESTService.cpp @@ -247,46 +247,96 @@ int32 LoginRESTService::HandlePost(soap* soapClient)      PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_INFO);      stmt->setString(0, login); -    stmt->setString(1, CalculateShaPassHash(login, std::move(password))); +      if (PreparedQueryResult result = LoginDatabase.Query(stmt))      { +        std::string pass_hash = result->Fetch()[13].GetString(); +          std::unique_ptr<Battlenet::Session::AccountInfo> accountInfo = Trinity::make_unique<Battlenet::Session::AccountInfo>();          accountInfo->LoadResult(result); -        stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS_BY_BNET_ID); -        stmt->setUInt32(0, accountInfo->Id); -        if (PreparedQueryResult characterCountsResult = LoginDatabase.Query(stmt)) +        if (CalculateShaPassHash(login, std::move(password)) == pass_hash)          { -            do +            stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS_BY_BNET_ID); +            stmt->setUInt32(0, accountInfo->Id); +            if (PreparedQueryResult characterCountsResult = LoginDatabase.Query(stmt)) +            { +                do +                { +                    Field* fields = characterCountsResult->Fetch(); +                    accountInfo->GameAccounts[fields[0].GetUInt32()] +                        .CharacterCounts[Battlenet::RealmHandle{ fields[3].GetUInt8(), fields[4].GetUInt8(), fields[2].GetUInt32() }.GetAddress()] = fields[1].GetUInt8(); + +                } while (characterCountsResult->NextRow()); +            } + +            stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_LAST_PLAYER_CHARACTERS); +            stmt->setUInt32(0, accountInfo->Id); +            if (PreparedQueryResult lastPlayerCharactersResult = LoginDatabase.Query(stmt))              { -                Field* fields = characterCountsResult->Fetch(); -                accountInfo->GameAccounts[fields[0].GetUInt32()] -                    .CharacterCounts[Battlenet::RealmHandle{ fields[3].GetUInt8(), fields[4].GetUInt8(), fields[2].GetUInt32() }.GetAddress()] = fields[1].GetUInt8(); +                Field* fields = lastPlayerCharactersResult->Fetch(); +                Battlenet::RealmHandle realmId{ fields[1].GetUInt8(), fields[2].GetUInt8(), fields[3].GetUInt32() }; +                Battlenet::Session::LastPlayedCharacterInfo& lastPlayedCharacter = accountInfo->GameAccounts[fields[0].GetUInt32()] +                    .LastPlayedCharacters[realmId.GetSubRegionAddress()]; -            } while (characterCountsResult->NextRow()); -        } +                lastPlayedCharacter.RealmId = realmId; +                lastPlayedCharacter.CharacterName = fields[4].GetString(); +                lastPlayedCharacter.CharacterGUID = fields[5].GetUInt64(); +                lastPlayedCharacter.LastPlayedTime = fields[6].GetUInt32(); +            } -        stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_LAST_PLAYER_CHARACTERS); -        stmt->setUInt32(0, accountInfo->Id); -        if (PreparedQueryResult lastPlayerCharactersResult = LoginDatabase.Query(stmt)) -        { -            Field* fields = lastPlayerCharactersResult->Fetch(); -            Battlenet::RealmHandle realmId{ fields[1].GetUInt8(), fields[2].GetUInt8(), fields[3].GetUInt32() }; -            Battlenet::Session::LastPlayedCharacterInfo& lastPlayedCharacter = accountInfo->GameAccounts[fields[0].GetUInt32()] -                .LastPlayedCharacters[realmId.GetSubRegionAddress()]; - -            lastPlayedCharacter.RealmId = realmId; -            lastPlayedCharacter.CharacterName = fields[4].GetString(); -            lastPlayedCharacter.CharacterGUID = fields[5].GetUInt64(); -            lastPlayedCharacter.LastPlayedTime = fields[6].GetUInt32(); -        } +            BigNumber ticket; +            ticket.SetRand(20 * 8); -        BigNumber ticket; -        ticket.SetRand(20 * 8); +            loginResult.set_login_ticket("TC-" + ByteArrayToHexStr(ticket.AsByteArray(20).get(), 20)); -        loginResult.set_login_ticket("TC-" + ByteArrayToHexStr(ticket.AsByteArray(20).get(), 20)); +            AddLoginTicket(loginResult.login_ticket(), std::move(accountInfo)); +        } +        else if (!accountInfo->IsBanned) +        { +            uint32 maxWrongPassword = uint32(sConfigMgr->GetIntDefault("WrongPass.MaxCount", 0)); + +            if (sConfigMgr->GetBoolDefault("WrongPass.Logging", false)) +                TC_LOG_DEBUG("server.rest", "[%s, Account %s, Id %u] Attempted to connect with wrong password!", ip_address.c_str(), login.c_str(), accountInfo->Id); -        AddLoginTicket(loginResult.login_ticket(), std::move(accountInfo)); +            if (maxWrongPassword) +            { +                SQLTransaction trans = LoginDatabase.BeginTransaction(); +                stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_FAILED_LOGINS); +                stmt->setUInt32(0, accountInfo->Id); +                trans->Append(stmt); + +                ++accountInfo->FailedLogins; + +                TC_LOG_DEBUG("server.rest", "MaxWrongPass : %u, failed_login : %u", maxWrongPassword, accountInfo->Id); + +                if (accountInfo->FailedLogins >= maxWrongPassword) +                { +                    BanMode banType = BanMode(sConfigMgr->GetIntDefault("WrongPass.BanType", uint16(BanMode::BAN_IP))); +                    int32 banTime = sConfigMgr->GetIntDefault("WrongPass.BanTime", 600); + +                    if (banType == BanMode::BAN_ACCOUNT) +                    { +                        stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_ACCOUNT_AUTO_BANNED); +                        stmt->setUInt32(0, accountInfo->Id); +                    } +                    else +                    { +                        stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_IP_AUTO_BANNED); +                        stmt->setString(0, ip_address); +                    } + +                    stmt->setUInt32(1, banTime); +                    trans->Append(stmt); + +                    stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_RESET_FAILED_LOGINS); +                    stmt->setUInt32(0, accountInfo->Id); +                    trans->Append(stmt); +                } + +                LoginDatabase.CommitTransaction(trans); +            } +        }      }      loginResult.set_authentication_state(Battlenet::JSON::Login::DONE); diff --git a/src/server/bnetserver/REST/LoginRESTService.h b/src/server/bnetserver/REST/LoginRESTService.h index 881c656f15e..55d55a808e1 100644 --- a/src/server/bnetserver/REST/LoginRESTService.h +++ b/src/server/bnetserver/REST/LoginRESTService.h @@ -32,6 +32,12 @@  struct soap;  struct soap_plugin; +enum class BanMode +{ +    BAN_IP = 0, +    BAN_ACCOUNT = 1 +}; +  class LoginRESTService  {  public: diff --git a/src/server/database/Database/Implementation/LoginDatabase.cpp b/src/server/database/Database/Implementation/LoginDatabase.cpp index 19dca345143..5f5b617e6fa 100644 --- a/src/server/database/Database/Implementation/LoginDatabase.cpp +++ b/src/server/database/Database/Implementation/LoginDatabase.cpp @@ -118,9 +118,9 @@ void LoginDatabaseConnection::DoPrepareStatements()  #define BnetAccountInfo "ba.id, UPPER(ba.email), ba.locked, ba.lock_country, ba.last_ip, ba.failed_logins, bab.unbandate > UNIX_TIMESTAMP() OR bab.unbandate = bab.bandate, bab.unbandate = bab.bandate"  #define BnetGameAccountInfo "a.id, a.username, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, ab.unbandate = ab.bandate, aa.gmlevel" -    PrepareStatement(LOGIN_SEL_BNET_ACCOUNT_INFO, "SELECT " BnetAccountInfo ", " BnetGameAccountInfo +    PrepareStatement(LOGIN_SEL_BNET_ACCOUNT_INFO, "SELECT " BnetAccountInfo ", " BnetGameAccountInfo ", ba.sha_pass_hash"          " FROM battlenet_accounts ba LEFT JOIN battlenet_account_bans bab ON ba.id = bab.id LEFT JOIN account a ON ba.id = a.battlenet_account" -        " LEFT JOIN account_banned ab ON a.id = ab.id AND ab.active = 1 LEFT JOIN account_access aa ON a.id = aa.id AND aa.RealmID = -1 WHERE ba.email = ? AND ba.sha_pass_hash = ? ORDER BY a.id", CONNECTION_SYNCH); +        " LEFT JOIN account_banned ab ON a.id = ab.id AND ab.active = 1 LEFT JOIN account_access aa ON a.id = aa.id AND aa.RealmID = -1 WHERE ba.email = ? ORDER BY a.id", CONNECTION_SYNCH);      PrepareStatement(LOGIN_UPD_BNET_LAST_LOGIN_INFO, "UPDATE battlenet_accounts SET last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE id = ?", CONNECTION_ASYNC);      PrepareStatement(LOGIN_UPD_BNET_GAME_ACCOUNT_LOGIN_INFO, "UPDATE account SET sessionkey = ?, last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE username = ?", CONNECTION_SYNCH);      PrepareStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS_BY_ACCOUNT_ID, "SELECT rc.acctid, rc.numchars, r.id, r.Region, r.Battlegroup FROM realmcharacters rc INNER JOIN realmlist r ON rc.realmid = r.id WHERE rc.acctid = ?", CONNECTION_ASYNC); @@ -139,6 +139,13 @@ void LoginDatabaseConnection::DoPrepareStatements()      PrepareStatement(LOGIN_UPD_BNET_GAME_ACCOUNT_LINK, "UPDATE account SET battlenet_account = ?, battlenet_index = ? WHERE id = ?", CONNECTION_ASYNC);      PrepareStatement(LOGIN_SEL_BNET_MAX_ACCOUNT_INDEX, "SELECT MAX(battlenet_index) FROM account WHERE battlenet_account = ?", CONNECTION_SYNCH); +    PrepareStatement(LOGIN_UPD_BNET_FAILED_LOGINS, "UPDATE battlenet_accounts SET failed_logins = failed_logins + 1 WHERE id = ?", CONNECTION_ASYNC); +    PrepareStatement(LOGIN_SEL_BNET_FAILED_LOGINS, "SELECT failed_logins FROM battlenet_accounts WHERE id = ?", CONNECTION_SYNCH); +    PrepareStatement(LOGIN_INS_BNET_ACCOUNT_AUTO_BANNED, "INSERT INTO battlenet_account_bans(id, bandate, unbandate, bannedby, banreason) VALUES(?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, 'Trinity Auth', 'Failed login autoban')", CONNECTION_ASYNC); +    PrepareStatement(LOGIN_DEL_BNET_EXPERIED_ACCOUNT_BANNED, "DELETE FROM battlenet_account_bans WHERE unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_ASYNC); +    PrepareStatement(LOGIN_SEL_BNET_ACCOUNT_BANNED_BY_ID, "SELECT * FROM battlenet_account_bans WHERE id = ?", CONNECTION_SYNCH); +    PrepareStatement(LOGIN_UPD_BNET_RESET_FAILED_LOGINS, "UPDATE battlenet_accounts SET failed_logins = 0 WHERE id = ?", CONNECTION_ASYNC); +      PrepareStatement(LOGIN_SEL_LAST_CHAR_UNDELETE, "SELECT LastCharacterUndelete FROM battlenet_accounts WHERE Id = ?", CONNECTION_ASYNC);      PrepareStatement(LOGIN_UPD_LAST_CHAR_UNDELETE, "UPDATE battlenet_accounts SET LastCharacterUndelete = UNIX_TIMESTAMP() WHERE Id = ?", CONNECTION_ASYNC); diff --git a/src/server/database/Database/Implementation/LoginDatabase.h b/src/server/database/Database/Implementation/LoginDatabase.h index 75e37ca84ea..c78203215f4 100644 --- a/src/server/database/Database/Implementation/LoginDatabase.h +++ b/src/server/database/Database/Implementation/LoginDatabase.h @@ -130,6 +130,13 @@ enum LoginDatabaseStatements      LOGIN_UPD_BNET_GAME_ACCOUNT_LINK,      LOGIN_SEL_BNET_MAX_ACCOUNT_INDEX, +    LOGIN_UPD_BNET_FAILED_LOGINS, +    LOGIN_SEL_BNET_FAILED_LOGINS, +    LOGIN_INS_BNET_ACCOUNT_AUTO_BANNED, +    LOGIN_DEL_BNET_EXPERIED_ACCOUNT_BANNED, +    LOGIN_SEL_BNET_ACCOUNT_BANNED_BY_ID, +    LOGIN_UPD_BNET_RESET_FAILED_LOGINS, +      LOGIN_SEL_LAST_CHAR_UNDELETE,      LOGIN_UPD_LAST_CHAR_UNDELETE,  | 
