public void HandleLoginRequest(HttpHeader request) { LogonData loginForm = Json.CreateObject <LogonData>(request.Content); LogonResult loginResult = new LogonResult(); if (loginForm == null) { loginResult.AuthenticationState = "LOGIN"; loginResult.ErrorCode = "UNABLE_TO_DECODE"; loginResult.ErrorMessage = "There was an internal error while connecting to Battle.net. Please try again later."; SendResponse(HttpCode.BadRequest, loginResult); return; } string login = ""; string password = ""; for (int i = 0; i < loginForm.Inputs.Count; ++i) { switch (loginForm.Inputs[i].Id) { case "account_name": login = loginForm.Inputs[i].Value; break; case "password": password = loginForm.Inputs[i].Value; break; } } PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_BNET_ACCOUNT_INFO); stmt.AddValue(0, login); SQLResult result = DB.Login.Query(stmt); if (result.IsEmpty()) { loginResult.AuthenticationState = "LOGIN"; loginResult.ErrorCode = "UNABLE_TO_DECODE"; loginResult.ErrorMessage = "There was an internal error while connecting to Battle.net. Please try again later."; SendResponse(HttpCode.BadRequest, loginResult); return; } string pass_hash = result.Read <string>(13); var accountInfo = new AccountInfo(); accountInfo.LoadResult(result); if (CalculateShaPassHash(login, password) == pass_hash) { stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_BNET_CHARACTER_COUNTS_BY_BNET_ID); stmt.AddValue(0, accountInfo.Id); SQLResult characterCountsResult = DB.Login.Query(stmt); if (!characterCountsResult.IsEmpty()) { do { accountInfo.GameAccounts[characterCountsResult.Read <uint>(0)] .CharacterCounts[new RealmHandle(characterCountsResult.Read <byte>(3), characterCountsResult.Read <byte>(4), characterCountsResult.Read <uint>(2)).GetAddress()] = characterCountsResult.Read <byte>(1); } while (characterCountsResult.NextRow()); } stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_BNET_LAST_PLAYER_CHARACTERS); stmt.AddValue(0, accountInfo.Id); SQLResult lastPlayerCharactersResult = DB.Login.Query(stmt); if (!lastPlayerCharactersResult.IsEmpty()) { RealmHandle realmId = new RealmHandle(lastPlayerCharactersResult.Read <byte>(1), lastPlayerCharactersResult.Read <byte>(2), lastPlayerCharactersResult.Read <uint>(3)); LastPlayedCharacterInfo lastPlayedCharacter = new LastPlayedCharacterInfo(); lastPlayedCharacter.RealmId = realmId; lastPlayedCharacter.CharacterName = lastPlayerCharactersResult.Read <string>(4); lastPlayedCharacter.CharacterGUID = lastPlayerCharactersResult.Read <ulong>(5); lastPlayedCharacter.LastPlayedTime = lastPlayerCharactersResult.Read <uint>(6); accountInfo.GameAccounts[lastPlayerCharactersResult.Read <uint>(0)].LastPlayedCharacters[realmId.GetSubRegionAddress()] = lastPlayedCharacter; } byte[] ticket = new byte[0].GenerateRandomKey(20); loginResult.LoginTicket = "TC-" + ticket.ToHexString(); Global.SessionMgr.AddLoginTicket(loginResult.LoginTicket, accountInfo); } else if (!accountInfo.IsBanned) { uint maxWrongPassword = ConfigMgr.GetDefaultValue("WrongPass.MaxCount", 0u); if (ConfigMgr.GetDefaultValue("WrongPass.Logging", false)) { Log.outDebug(LogFilter.Network, "[{0}, Account {1}, Id {2}] Attempted to connect with wrong password!", request.Host, login, accountInfo.Id); } if (maxWrongPassword != 0) { SQLTransaction trans = new SQLTransaction(); stmt = DB.Login.GetPreparedStatement(LoginStatements.UPD_BNET_FAILED_LOGINS); stmt.AddValue(0, accountInfo.Id); trans.Append(stmt); ++accountInfo.FailedLogins; Log.outDebug(LogFilter.Network, "MaxWrongPass : {0}, failed_login : {1}", maxWrongPassword, accountInfo.Id); if (accountInfo.FailedLogins >= maxWrongPassword) { BanMode banType = ConfigMgr.GetDefaultValue("WrongPass.BanType", BanMode.Ip); int banTime = ConfigMgr.GetDefaultValue("WrongPass.BanTime", 600); if (banType == BanMode.Account) { stmt = DB.Login.GetPreparedStatement(LoginStatements.INS_BNET_ACCOUNT_AUTO_BANNED); stmt.AddValue(0, accountInfo.Id); } else { stmt = DB.Login.GetPreparedStatement(LoginStatements.INS_IP_AUTO_BANNED); stmt.AddValue(0, request.Host); } stmt.AddValue(1, banTime); trans.Append(stmt); stmt = DB.Login.GetPreparedStatement(LoginStatements.UPD_BNET_RESET_FAILED_LOGINS); stmt.AddValue(0, accountInfo.Id); trans.Append(stmt); } DB.Login.CommitTransaction(trans); } } loginResult.AuthenticationState = "DONE"; SendResponse(HttpCode.Ok, loginResult); }
public BattlenetRpcErrorCode HandleVerifyWebCredentials(Bgs.Protocol.Authentication.V1.VerifyWebCredentialsRequest verifyWebCredentialsRequest) { PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_BNET_ACCOUNT_INFO); stmt.AddValue(0, verifyWebCredentialsRequest.WebCredentials.ToStringUtf8()); SQLResult result = DB.Login.Query(stmt); if (result.IsEmpty()) { return(BattlenetRpcErrorCode.Denied); } _accountInfo = new AccountInfo(); _accountInfo.LoadResult(result); if (_accountInfo.LoginTicketExpiry < Time.UnixTime) { return(BattlenetRpcErrorCode.TimedOut); } stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_BNET_CHARACTER_COUNTS_BY_BNET_ID); stmt.AddValue(0, _accountInfo.Id); SQLResult characterCountsResult = DB.Login.Query(stmt); if (!characterCountsResult.IsEmpty()) { do { RealmHandle realmId = new RealmHandle(characterCountsResult.Read <byte>(3), characterCountsResult.Read <byte>(4), characterCountsResult.Read <uint>(2)); _accountInfo.GameAccounts[characterCountsResult.Read <uint>(0)].CharacterCounts[realmId.GetAddress()] = characterCountsResult.Read <byte>(1); } while (characterCountsResult.NextRow()); } stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_BNET_LAST_PLAYER_CHARACTERS); stmt.AddValue(0, _accountInfo.Id); SQLResult lastPlayerCharactersResult = DB.Login.Query(stmt); if (!lastPlayerCharactersResult.IsEmpty()) { do { RealmHandle realmId = new RealmHandle(lastPlayerCharactersResult.Read <byte>(1), lastPlayerCharactersResult.Read <byte>(2), lastPlayerCharactersResult.Read <uint>(3)); LastPlayedCharacterInfo lastPlayedCharacter = new LastPlayedCharacterInfo(); lastPlayedCharacter.RealmId = realmId; lastPlayedCharacter.CharacterName = lastPlayerCharactersResult.Read <string>(4); lastPlayedCharacter.CharacterGUID = lastPlayerCharactersResult.Read <ulong>(5); lastPlayedCharacter.LastPlayedTime = lastPlayerCharactersResult.Read <uint>(6); _accountInfo.GameAccounts[lastPlayerCharactersResult.Read <uint>(0)].LastPlayedCharacters[realmId.GetSubRegionAddress()] = lastPlayedCharacter; } while (lastPlayerCharactersResult.NextRow()); } string ip_address = GetRemoteIpAddress().ToString(); // If the IP is 'locked', check that the player comes indeed from the correct IP address if (_accountInfo.IsLockedToIP) { Log.outDebug(LogFilter.Session, "Session.HandleVerifyWebCredentials: Account '{0}' is locked to IP - '{1}' is logging in from '{2}'", _accountInfo.Login, _accountInfo.LastIP, ip_address); if (_accountInfo.LastIP != ip_address) { return(BattlenetRpcErrorCode.RiskAccountLocked); } } else { Log.outDebug(LogFilter.Session, "Session.HandleVerifyWebCredentials: Account '{0}' is not locked to ip", _accountInfo.Login); if (_accountInfo.LockCountry.IsEmpty() || _accountInfo.LockCountry == "00") { Log.outDebug(LogFilter.Session, "Session.HandleVerifyWebCredentials: Account '{0}' is not locked to country", _accountInfo.Login); } else if (!_accountInfo.LockCountry.IsEmpty() && !_ipCountry.IsEmpty()) { Log.outDebug(LogFilter.Session, "Session.HandleVerifyWebCredentials: Account '{0}' is locked to country: '{1}' Player country is '{2}'", _accountInfo.Login, _accountInfo.LockCountry, _ipCountry); if (_ipCountry != _accountInfo.LockCountry) { return(BattlenetRpcErrorCode.RiskAccountLocked); } } } // If the account is banned, reject the logon attempt if (_accountInfo.IsBanned) { if (_accountInfo.IsPermanenetlyBanned) { Log.outDebug(LogFilter.Session, "{0} Session.HandleVerifyWebCredentials: Banned account {1} tried to login!", GetClientInfo(), _accountInfo.Login); return(BattlenetRpcErrorCode.GameAccountBanned); } else { Log.outDebug(LogFilter.Session, "{0} Session.HandleVerifyWebCredentials: Temporarily banned account {1} tried to login!", GetClientInfo(), _accountInfo.Login); return(BattlenetRpcErrorCode.GameAccountSuspended); } } Bgs.Protocol.Authentication.V1.LogonResult logonResult = new Bgs.Protocol.Authentication.V1.LogonResult(); logonResult.ErrorCode = 0; logonResult.AccountId = new EntityId(); logonResult.AccountId.Low = _accountInfo.Id; logonResult.AccountId.High = 0x100000000000000; foreach (var pair in _accountInfo.GameAccounts) { EntityId gameAccountId = new EntityId(); gameAccountId.Low = pair.Value.Id; gameAccountId.High = 0x200000200576F57; logonResult.GameAccountId.Add(gameAccountId); } if (!_ipCountry.IsEmpty()) { logonResult.GeoipCountry = _ipCountry; } logonResult.SessionKey = ByteString.CopyFrom(new byte[64].GenerateRandomKey(64)); _authed = true; SendRequest((uint)OriginalHash.AuthenticationListener, 5, logonResult); return(BattlenetRpcErrorCode.Ok); }
BattlenetRpcErrorCode HandleVerifyWebCredentials(VerifyWebCredentialsRequest verifyWebCredentialsRequest) { if (verifyWebCredentialsRequest.WebCredentials.IsEmpty) { return(BattlenetRpcErrorCode.Denied); } PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.SelBnetAccountInfo); stmt.AddValue(0, verifyWebCredentialsRequest.WebCredentials.ToStringUtf8()); SQLResult result = DB.Login.Query(stmt); if (result.IsEmpty()) { return(BattlenetRpcErrorCode.Denied); } accountInfo = new AccountInfo(result); if (accountInfo.LoginTicketExpiry < Time.UnixTime) { return(BattlenetRpcErrorCode.TimedOut); } stmt = DB.Login.GetPreparedStatement(LoginStatements.SelBnetCharacterCountsByAccountId); stmt.AddValue(0, accountInfo.Id); SQLResult characterCountsResult = DB.Login.Query(stmt); if (!characterCountsResult.IsEmpty()) { do { var realmId = new RealmId(characterCountsResult.Read <byte>(3), characterCountsResult.Read <byte>(4), characterCountsResult.Read <uint>(2)); accountInfo.GameAccounts[characterCountsResult.Read <uint>(0)].CharacterCounts[realmId.GetAddress()] = characterCountsResult.Read <byte>(1); } while (characterCountsResult.NextRow()); } stmt = DB.Login.GetPreparedStatement(LoginStatements.SelBnetLastPlayerCharacters); stmt.AddValue(0, accountInfo.Id); SQLResult lastPlayerCharactersResult = DB.Login.Query(stmt); if (!lastPlayerCharactersResult.IsEmpty()) { do { var realmId = new RealmId(lastPlayerCharactersResult.Read <byte>(1), lastPlayerCharactersResult.Read <byte>(2), lastPlayerCharactersResult.Read <uint>(3)); LastPlayedCharacterInfo lastPlayedCharacter = new LastPlayedCharacterInfo(); lastPlayedCharacter.RealmId = realmId; lastPlayedCharacter.CharacterName = lastPlayerCharactersResult.Read <string>(4); lastPlayedCharacter.CharacterGUID = lastPlayerCharactersResult.Read <ulong>(5); lastPlayedCharacter.LastPlayedTime = lastPlayerCharactersResult.Read <uint>(6); accountInfo.GameAccounts[lastPlayerCharactersResult.Read <uint>(0)].LastPlayedCharacters[realmId.GetSubRegionAddress()] = lastPlayedCharacter; } while (lastPlayerCharactersResult.NextRow()); } string ip_address = GetRemoteIpEndPoint().ToString(); // If the IP is 'locked', check that the player comes indeed from the correct IP address if (accountInfo.IsLockedToIP) { Log.outDebug(LogFilter.Session, $"Session.HandleVerifyWebCredentials: Account: {accountInfo.Login} is locked to IP: {accountInfo.LastIP} is logging in from IP: {ip_address}"); if (accountInfo.LastIP != ip_address) { return(BattlenetRpcErrorCode.RiskAccountLocked); } } else { Log.outDebug(LogFilter.Session, $"Session.HandleVerifyWebCredentials: Account: {accountInfo.Login} is not locked to ip"); if (accountInfo.LockCountry.IsEmpty() || accountInfo.LockCountry == "00") { Log.outDebug(LogFilter.Session, $"Session.HandleVerifyWebCredentials: Account: {accountInfo.Login} is not locked to country"); } else if (!accountInfo.LockCountry.IsEmpty() && !ipCountry.IsEmpty()) { Log.outDebug(LogFilter.Session, $"Session.HandleVerifyWebCredentials: Account: {accountInfo.Login} is locked to Country: {accountInfo.LockCountry} player Country: {ipCountry}"); if (ipCountry != accountInfo.LockCountry) { return(BattlenetRpcErrorCode.RiskAccountLocked); } } } // If the account is banned, reject the logon attempt if (accountInfo.IsBanned) { if (accountInfo.IsPermanenetlyBanned) { Log.outDebug(LogFilter.Session, $"{GetClientInfo()} Session.HandleVerifyWebCredentials: Banned account {accountInfo.Login} tried to login!"); return(BattlenetRpcErrorCode.GameAccountBanned); } else { Log.outDebug(LogFilter.Session, $"{GetClientInfo()} Session.HandleVerifyWebCredentials: Temporarily banned account {accountInfo.Login} tried to login!"); return(BattlenetRpcErrorCode.GameAccountSuspended); } } LogonResult logonResult = new LogonResult(); logonResult.ErrorCode = 0; logonResult.AccountId = new EntityId(); logonResult.AccountId.Low = accountInfo.Id; logonResult.AccountId.High = 0x100000000000000; foreach (var pair in accountInfo.GameAccounts) { EntityId gameAccountId = new EntityId(); gameAccountId.Low = pair.Value.Id; gameAccountId.High = 0x200000200576F57; logonResult.GameAccountId.Add(gameAccountId); } if (!ipCountry.IsEmpty()) { logonResult.GeoipCountry = ipCountry; } logonResult.SessionKey = ByteString.CopyFrom(new byte[64].GenerateRandomKey(64)); authed = true; SendRequest((uint)OriginalHash.AuthenticationListener, 5, logonResult); return(BattlenetRpcErrorCode.Ok); }