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);
        }
Beispiel #2
0
        public BattlenetRpcErrorCode HandleVerifyWebCredentials(Bgs.Protocol.Authentication.V1.VerifyWebCredentialsRequest verifyWebCredentialsRequest)
        {
            if (verifyWebCredentialsRequest.WebCredentials.IsEmpty)
            {
                return(BattlenetRpcErrorCode.Denied);
            }

            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);
        }