public static PacketProcessResult HandleAuthSession(PacketProcessor p) { CMSG_AUTH_SESSION auth = new CMSG_AUTH_SESSION(); UInt32 unk, unk2, unk3, unk4, unk5; UInt64 unk6; auth.Build = p.CurrentPacket.ReadUInt32(); unk = p.CurrentPacket.ReadUInt32(); auth.Account = p.CurrentPacket.ReadCString(); unk2 = p.CurrentPacket.ReadUInt32(); auth.Seed = p.CurrentPacket.ReadUInt32(); unk3 = p.CurrentPacket.ReadUInt32(); unk4 = p.CurrentPacket.ReadUInt32(); unk5 = p.CurrentPacket.ReadUInt32(); unk6 = p.CurrentPacket.ReadUInt64(); auth.Digest = p.CurrentPacket.ReadBigInteger(20); var decompressedDataSize = p.CurrentPacket.ReadInt32(); var compressedData = p.CurrentPacket.ReadBytes((int)(p.CurrentPacket.Length - p.CurrentPacket.Position)); //read remaining array auth.AddonData = Shared.ZLib.Decompress(compressedData); var realmprocessor = p as RealmPacketProcessor; //get the encryption keys first because errors are encrypted too p.ClientConnection.CurrentSession.GetSessionKeyFromAuthAccount(auth.Account).Wait(); realmprocessor.SetupCrypto(p.ClientConnection.CurrentSession.GetSessionKey().Result); p.ClientConnection.CurrentSession.HandleAuthSession(auth, realmprocessor.Seed); return(PacketProcessResult.Processed); }
public static async Task OnClientAuthenticationSession(WorldClient client, byte[] data) { var request = new CMSG_AUTH_SESSION(data); if (!DataStore.Users.TryGetValue(request.AccountName, out var user)) { // return [SMSG_AUTH_RESPONSE, 21] throw new ArgumentException($"No user with name {request.AccountName} found in db."); } ////: if server is full and NOT GM return [SMSG_AUTH_RESPONSE, 21] ////: if player is already connected return [SMSG_AUTH_RESPONSE, 13] using (var sha = new SHA1CryptoServiceProvider()) { var calculatedDigest = sha.ComputeHash( Encoding.ASCII.GetBytes(request.AccountName) .Concat(new byte[] { 0, 0, 0, 0 }) .Concat(BitConverter.GetBytes(request.Seed)) .Concat(SMSG_AUTH_CHALLENGE.AuthSeed) .Concat(user.SessionKey) .ToArray()); if (!calculatedDigest.SequenceEqual(request.Digest)) { //return [SMSG_AUTH_RESPONSE, 21] throw new InvalidOperationException("Wrong digest SMSG_AUTH_RESPONSE"); } } client.Crypt.SetKey(user.SessionKey); await client.SendPacket(new SMSG_AUTH_RESPONSE()); client.User = user; }
public static void Handler(RealmServerSession session, CMSG_AUTH_SESSION handler) { // Search Account and set to session.Users session.Users = MainProgram.RealmServerDatabase.GetAccount(handler.ClientAccount); // Initializing Crypt for user session session.PacketCrypto = new VanillaCrypt(); session.PacketCrypto.Init(session.Users.sessionkey); // Check basic addons instaleds CheckAddons(handler); // Send AuthOK session.SendPacket(new SMSG_AUTH_RESPONSE(LoginErrorCode.AUTH_OK)); session.SendPacket(new SMSG_ADDON_INFO(AddOnsNames)); // TODO Alternatice to handle errors /* * RESPONSE_VERSION_MISMATCH * AUTH_FAILED * AUTH_UNAVAILABLE * AUTH_SYSTEM_ERROR * AUTH_ALREADY_LOGGING_IN * AUTH_SUSPENDED * * session.SendPacket(new SMSG_CHAR_CREATE(LoginErrorCode.AUTH_FAILED)); */ }
public async Task HandleAuthSession(CMSG_AUTH_SESSION auth, UInt32 ServerSeed) { if (SessionKey == 0) { await GetSessionKeyFromAuthAccount(auth.Account); } if (SessionKey == 0) { await SendAuthResponse(LoginErrorCode.AUTH_UNKNOWN_ACCOUNT); return; } byte[] t = new byte[4]; var accountbytes = Encoding.UTF8.GetBytes(Account.GetPrimaryKeyString()); var clientseed = BitConverter.GetBytes(auth.Seed); var serverseed = BitConverter.GetBytes(ServerSeed); var sess_key = SessionKey; var sesskeybytes = sess_key.GetBytes(); BigInteger ServerProof = BigInt.Hash(accountbytes, t, clientseed, serverseed, sesskeybytes); BigInteger ClientProof = new BigInteger(auth.Digest); if (ClientProof != ServerProof) { await SendAuthResponse(LoginErrorCode.AUTH_UNKNOWN_ACCOUNT); return; } Authed = true; await Account.AddSession(this); //set realm session (and disconnect any others) //TODO: add queues PacketOut p = new PacketOut(RealmOp.SMSG_AUTH_RESPONSE); p.Write((byte)LoginErrorCode.AUTH_OK); p.Write((int)0); p.Write((byte)0); p.Write(0); p.Write((byte)0); //expansionLevel await SendPacket(p); }
public static async Task OnClientAuthenticationSession(PacketHandlerContext c) { var request = CMSG_AUTH_SESSION.Read(c.Packet); var build = (int)request.Build; if (c.Client.Build != build) { c.Client.Log($"Expected build {c.Client.Build} but is {build}.", LogLevel.Warning); c.Client.Build = build; } var session = c.AccountService.GetSession(request.Identifier); if (session is null) { // return [SMSG_AUTH_RESPONSE, 21] throw new ArgumentException($"No user with name {request.Identifier} found in db."); } ////: if server is full and NOT GM return [SMSG_AUTH_RESPONSE, 21] ////: if player is already connected return [SMSG_AUTH_RESPONSE, 13] using var sha = new SHA1CryptoServiceProvider(); var calculatedDigest = sha.ComputeHash( Encoding.ASCII.GetBytes(request.Identifier) .Concat(new byte[] { 0, 0, 0, 0 }) .Concat(BitConverter.GetBytes(request.Seed)) .Concat(SMSG_AUTH_CHALLENGE.AuthSeed) .Concat(session.SessionKey) .ToArray()); if (!calculatedDigest.SequenceEqual(request.Digest)) { //return [SMSG_AUTH_RESPONSE, 21] throw new InvalidOperationException("Wrong digest SMSG_AUTH_RESPONSE"); } c.Client.HeaderCrypt = HeaderCryptFactory.Create(session.SessionKey, build); c.Client.Identifier = request.Identifier; await c.Client.SendPacket(new SMSG_AUTH_RESPONSE(build)); }