Exemple #1
0
        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;
        }
Exemple #3
0
        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));
             */
        }
Exemple #4
0
        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));
        }