Beispiel #1
0
        public async Task RunAsync()
        {
            while (_run)
            {
                var cmd = (AuthCommand)await _reader.ReadUInt8Async();

                _currentCommand = cmd;
                _logger.LogTrace("Handling opcode {Opcode} from client", cmd);
                switch (cmd)
                {
                case AuthCommand.LogonChallenge:
                    await HandleLogonChallengeAsync();

                    break;

                case AuthCommand.LogonProof:
                    await HandleLogonProofAsync();

                    break;

                case AuthCommand.RealmList:
                    await HandleRealmListAsync();

                    break;

                default:
                    _logger.LogDebug("Unhandled opcode {Opcode}", cmd);
                    _run = false;
                    break;
                }
            }
        }
Beispiel #2
0
        public async Task RunAsync(TcpClient client)
        {
            Debug.WriteLine("New Connection");
            _client = client;
            _client.ReceiveTimeout = 1000;

            _clientStream = _client.GetStream();
            _reader       = new AsyncBinaryReader(_clientStream);

            while (_run && _clientStream.CanRead)
            {
                var cmd = (AuthCommand)await _reader.ReadUInt8Async();

                _currentCommand = cmd;
                Debug.WriteLine("OPCODE " + cmd + " received");
                switch (cmd)
                {
                case AuthCommand.LogonChallenge:
                    await HandleLogonChallengeAsync();

                    break;

                case AuthCommand.LogonProof:
                    await HandleLogonProofAsync();

                    break;

                case AuthCommand.RealmList:
                    await HandleRealmListAsync();

                    break;

                case AuthCommand.ReconnectChallenge:
                    await HandleReconnectChallengeAsync();

                    break;

                case AuthCommand.ReconnectProof:
                    await HandleReconnectProofAsync();

                    break;

                default:
                    Debug.WriteLine($"Unhandled opcode {cmd} (0x{cmd:X})");
                    await CloseAsync(AuthStatus.Unimplemented);

                    break;
                }
            }
        }
Beispiel #3
0
        private async Task HandleLogonChallengeAsync()
        {
            var error = await _reader.ReadUInt8Async(); // always 3

            var size = await _reader.ReadUInt16Async();

            if (_client.Available < size)
            {
                await CloseAsync(AuthStatus.ProtocolError);

                return;
            }

            var gameName = await _reader.ReadUInt32Async();

            if (gameName != GameName)
            {
                await CloseAsync(AuthStatus.ProtocolError);

                return;
            }

            var versionMajor = await _reader.ReadUInt8Async();

            var versionMinor = await _reader.ReadUInt8Async();

            var versionPatch = await _reader.ReadUInt8Async();

            _buildNumber = await _reader.ReadUInt16Async();

            var platform = (Architecture)await _reader.ReadUInt32Async();

            var os = (OperatingSystem)await _reader.ReadUInt32Async();

            var locale = (Locale)await _reader.ReadUInt32Async();

            var timezoneBias = await _reader.ReadUInt32Async();

            var ipAddress   = new IPAddress(await _reader.ReadUInt32Async());
            var realAddress = (_client.Client.RemoteEndPoint as IPEndPoint).Address;

            var accountNameLength = await _reader.ReadUInt8Async();

            var accountName = await _reader.ReadStringAsync(accountNameLength);

            accountName = accountName.ToUpperInvariant();

            _info = Program.authDatabase.Accounts.Single(a => a.username == accountName);

            _info.last_ip = realAddress.ToString();
            //_info.last_login = new DateTime().ToUniversalTime().ToString();
            _info.os = os.ToString();
            //_info.locale = (int)locale; <not the same>

            byte[]     passhash = MimicUtils.HexStringToByteArray(_info.pass_hash);
            BigInteger s, v;

            if (_info.s != "" && _info.v != "")
            {
                s = SrpHandler.BigIntFromHexString(_info.s);
                v = SrpHandler.BigIntFromHexString(_info.v);
            }
            else
            {
                s = BigInteger.Zero;
                v = BigInteger.Zero;
            }
            _authentication.ComputePrivateFields(accountName, passhash, s, v);

            List <byte> data = new List <byte>();

            data.Add((byte)_currentCommand);
            data.Add(0);

            data.Add((byte)AuthStatus.Success);

            data.AddRange(_authentication.PublicKey); // B

            data.Add((byte)_authentication.Generator.Length);
            data.AddRange(_authentication.Generator); // g

            data.Add((byte)_authentication.SafePrime.Length);
            data.AddRange(_authentication.SafePrime); // N

            data.AddRange(_authentication.Salt);      // s

            data.AddRange(Enumerable.Repeat((byte)0, 16));

            data.Add(0); // security flags;

            await _clientStream.WriteAsync(data.ToArray(), 0, data.Count);
        }