public static PacketProcessResult HandleLogonAuthProof(PacketProcessor p) { p.dataNeeded = 75; //1 op, 32 A, 20 M1, 20 crc_hash, 1 number_of_keys, 1 unk if (p.currentPacket.Length < p.dataNeeded) return PacketProcessResult.RequiresData; AuthLogonProof proof = new AuthLogonProof(); proof.A = p.currentPacket.ReadBytes(32); proof.M1 = p.currentPacket.ReadBytes(20); proof.crchash = p.currentPacket.ReadBytes(20); proof.number_of_keys = p.currentPacket.ReadByte(); proof.unk = p.currentPacket.ReadByte(); if (p.sock != null && p.sock.session != null) p.sock.session.OnLogonProof(proof); return PacketProcessResult.Processed; }
public async Task OnLogonProof(AuthLogonProof proof) { BigInteger A = new BigInteger(proof.A); BigInteger M1 = new BigInteger(proof.M1); if (A == 0 || M1 == 0) //possible hack attempt { await SendAuthError(AuthError.NoAccount); return; } BigInteger u = BigInt.Hash(A, B); BigInteger tmp = v.ModPow(u, N); if (tmp < 0) tmp += N; BigInteger S = A * tmp; S = S.ModPow(b, N); if (S < 0) S += N; byte[] t = S.GetBytes(); //byte[] t = new byte[32]; byte[] t1 = new byte[16]; byte[] t2 = new byte[16]; byte[] vK = new byte[40]; for (int i = 0; i < 16; ++i) { t1[i] = t[i * 2]; t2[i] = t[(i * 2) + 1]; } var t1sha = BigInt.Hash(t1); var t2sha = BigInt.Hash(t2); var t1shabytes = t1sha.GetBytes(20); var t2shabytes = t2sha.GetBytes(20); for (int i = 0; i < 20; ++i) { vK[i * 2] = t1shabytes[i]; vK[(i * 2) + 1] = t2shabytes[i]; } var t3 = BigInt.Hash(N) ^ BigInt.Hash(g); var AccountName = Account.GetPrimaryKeyString().ToUpper(); var t4bytes = Encoding.UTF8.GetBytes(AccountName); var t4 = BigInt.Hash(t4bytes); t4bytes = t4.GetBytes(); SessionKey = new BigInteger(vK); var M = BigInt.Hash(t3, t4, s, A, B, SessionKey); //do we match the M sent by the client? if (M == M1) { Authed = true; // The account code will disconnect any other attached auth or realm sessions when we add an auth session to it await Account.AddSession(this); BigInteger M2 = BigInt.Hash(A, M, SessionKey); PacketOut p = new PacketOut(AuthOp.AUTH_LOGON_PROOF); p.Write((byte)AuthError.Success); p.WriteBigInt(M2, 20); p.Write((int)0); p.Write((int)0); p.Write((short)0); await SendPacket(p); } else { await SendAuthError(AuthError.NoAccount); } }