public static void HandleAuthLogonChallenge(IClient client, IncomingAuthPacket packet) { Contract.Requires(client != null); Contract.Requires(packet != null); var unk = packet.ReadByte(); var size = packet.ReadInt16(); // we can't read it in directly as a string or char array as in C# chars are 16 bits var gameName = packet.ReadFourCC(); var version1 = packet.ReadByte(); var version2 = packet.ReadByte(); var version3 = packet.ReadByte(); var build = packet.ReadInt16(); var platform = packet.ReadFourCC(); var os = packet.ReadFourCC(); var country = packet.ReadFourCC(); var timezoneBias = packet.ReadInt32(); var ip = packet.ReadInt32(); var usernameLength = packet.ReadByte(); var usernameBytes = packet.ReadBytes(usernameLength); var username = Encoding.ASCII.GetString(usernameBytes); SRPServer srpData = GetSRPDataForUsername(username); if (srpData == null) { SendAuthenticationChallengeFailure(client, AuthResult.FailUnknownAccount); } else { client.UserData.SRP = srpData; // make sure the result is at least 32 bytes long var peData = srpData.PublicEphemeralValueB.GetBytes(32); var publicEphemeral = new BigInteger(peData); var rand = new BigInteger(new FastRandom(), 16 * 8); SendAuthenticationChallengeSuccess(client, publicEphemeral, srpData.Parameters.Generator, srpData.Parameters.Modulus, srpData.Salt, rand); } }
public static void HandleReconnectChallenge(IClient client, IncomingAuthPacket packet) { // structure is the same as AuthenticationLogonChallenge Contract.Requires(client != null); Contract.Requires(packet != null); var unk = packet.ReadByte(); var size = packet.ReadInt16(); var gameName = packet.ReadFourCC(); var version1 = packet.ReadByte(); var version2 = packet.ReadByte(); var version3 = packet.ReadByte(); var build = packet.ReadInt16(); var platform = packet.ReadFourCC(); var os = packet.ReadFourCC(); var country = packet.ReadFourCC(); var timezoneBias = packet.ReadInt32(); var ip = packet.ReadInt32(); var usernameLength = packet.ReadByte(); var usernameBytes = packet.ReadBytes(usernameLength); var username = Encoding.ASCII.GetString(usernameBytes); // TODO fetch this from the database (or some other persistent storage) BigInteger sessionKey = null; if (sessionKey == null) { client.Disconnect(); return; } BigInteger rand = new BigInteger(new FastRandom(), 16 * 8); SendReconnectChallengeSuccess(client, rand); client.UserData.ReconnectRand = rand; client.UserData.Username = username; }