private static void SendReconnectChallengeSuccess(IClient client, BigInteger rand) { Contract.Requires(client != null); Contract.Requires(rand != null); Contract.Requires(rand.ByteLength == 16); using (var packet = new OutgoingAuthPacket(GruntOpCodes.AuthenticationReconnectChallenge, 34)) { packet.Write((byte)AuthResult.Success); packet.Write(rand, 16); // this should be a byte[] but there's no point in initializing it as we always send 0s packet.Write((ulong)0); packet.Write((ulong)0); } }
private static void SendReconnectProofSuccess(IClient client) { using (var packet = new OutgoingAuthPacket(GruntOpCodes.AuthenticationReconnectProof, 3)) { packet.Write((byte)AuthResult.Success); packet.Write((short)0); // two unknown bytes } }
public static void SendAuthenticationLogonProofSuccess(IClient client, BigInteger serverResult) { Contract.Requires(client != null); Contract.Requires(serverResult != null); using (var packet = new OutgoingAuthPacket(GruntOpCodes.AuthenticationLogonProof, 31)) { packet.Write((byte)AuthResult.Success); packet.Write(serverResult, 20); // Flags. Only These are checked // 0x1 = ? // 0x8 = Trial Account // 0x800000 = ? packet.Write(0x00800000); // If 1, the client will do a hardware survey packet.Write(0x00); // If 1, client will fire EVENT_ACCOUNT_MESSAGES_AVAILABLE packet.Write((short)0x00); client.Send(packet); } }
public static void SendAuthenticationLogonProofFailure(IClient client, AuthResult result) { Contract.Requires(client != null); using (var packet = new OutgoingAuthPacket(GruntOpCodes.AuthenticationLogonProof, 3)) { packet.Write((byte)result); if (result == AuthResult.FailUnknownAccount) { // This is only read if the result == 4, and even then its not used. But it does need this to be here, as it does a length check before reading packet.Write((short) 0); } client.Send(packet); } }
public static void SendAuthenticationChallengeSuccess(IClient client, BigInteger publicEphemeral, BigInteger generator, BigInteger modulus, BigInteger salt, BigInteger rand) { Contract.Requires(client != null); Contract.Requires(publicEphemeral != null); Contract.Requires(publicEphemeral.ByteLength == 32); Contract.Requires(modulus != null); Contract.Requires(modulus.ByteLength == 32); Contract.Requires(salt != null); Contract.Requires(salt.ByteLength == 32); Contract.Requires(rand != null); Contract.Requires(rand.ByteLength == 16); Contract.Requires(generator != null); Contract.Requires(generator.ByteLength == 1); using (var packet = new OutgoingAuthPacket(GruntOpCodes.AuthenticationLogonChallenge, 118)) { packet.Write((byte)0x00); // If this is > 0, the client fails immediately packet.Write((byte)AuthResult.Success); packet.Write(publicEphemeral, 32); packet.Write(generator, 1, true); packet.Write(modulus, 32, true); packet.Write(salt, 32); packet.Write(rand, 16); var extraSecurityFlags = ExtraSecurityFlags.None; packet.Write((byte)extraSecurityFlags); if (extraSecurityFlags.HasFlag(ExtraSecurityFlags.PIN)) { packet.Write(0); // Used as the factor for determining PIN order // this is supposed to be an array of 16 bytes but there's no purpose in initializing it now packet.Write((long)0); packet.Write((long)0); } if (extraSecurityFlags.HasFlag(ExtraSecurityFlags.Matrix)) { packet.Write((byte) 0); // height packet.Write((byte) 0); // width packet.Write((byte) 0); // minDigits packet.Write((byte) 0); // maxDigits packet.Write((long) 0); // seed for md5 // Client MD5's the seed + sessionkey, and uses it as the seed to an HMAC-SHA1 // Client then uses the MD5 as a seed to an RC4 context // On every keypress, the client processes the entered value with the RC4, then updates the HMAC with that value // The HMAC result is sent in the auth proof } if (extraSecurityFlags.HasFlag(ExtraSecurityFlags.SecurityToken)) packet.Write((byte) 0); client.Send(packet); } }
public static void SendAuthenticationChallengeFailure(IClient client, AuthResult result) { Contract.Requires(client != null); Contract.Requires(result != AuthResult.Success); using (var packet = new OutgoingAuthPacket(GruntOpCodes.AuthenticationLogonChallenge, 2)) { packet.Write((byte)0x00); packet.Write((byte)result); client.Send(packet); } }
public static void HandleRealmlist(IClient client, IncomingAuthPacket packet) { Contract.Requires(client != null); Contract.Requires(packet != null); var unk = packet.ReadInt32(); // ignored List<string> realmNames = RealmList.GetRealmNames(); var realmsSize = 0; foreach (string realmName in realmNames) { Realm realm = RealmList.GetRealm(realmName); realmsSize += 3; // +1 for the null character at the end realmsSize += realm.Name.Length + 1; realmsSize += realm.Address.Length + 1; realmsSize += 6; if ((realm.Color & 4) != 0) realmsSize += 5; } using (var outPacket = new OutgoingAuthPacket(GruntOpCodes.RealmList, 10 + realmsSize)) { outPacket.Write((short)(6 + realmsSize + 2)); outPacket.Write(0); outPacket.Write((short)realmNames.Count); foreach (string realmName in realmNames) { Realm realm = RealmList.GetRealm(realmName); var numChars = realm.GetNumChars(client.UserData.SRP.Username); outPacket.Write(realm.Icon); outPacket.Write(realm.Lock); outPacket.Write(realm.Color); outPacket.WriteCString(realm.Name); outPacket.WriteCString(realm.Address); outPacket.Write(realm.PopulationLevel); outPacket.Write(numChars); outPacket.Write(realm.TimeZone); outPacket.Write((byte)0x2C); if ((realm.Color & 0x04) != 0) { outPacket.Write((byte)0); outPacket.Write((byte)0); outPacket.Write((byte)0); outPacket.Write((short)0); } } outPacket.Write((byte)0x10); outPacket.Write((byte)0x00); client.Send(outPacket); } }