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