public static void HandleKeyData(StsSession session, ClientKeyDataMessage keyData)
        {
            session.KeyExchange.CalculateSecret(keyData.A);

            byte[] key = session.KeyExchange.CalculateSessionKey();
            if (!session.KeyExchange.VerifyClientEvidenceMessage(keyData.M1))
            {
                session.EnqueueMessageError(new ServerErrorMessage((int)ErrorCode.InvalidAccountNameOrPassword));
                return;
            }

            byte[] M2 = session.KeyExchange.CalculateServerEvidenceMessage();

            using (MemoryStream stream = new MemoryStream())
                using (BinaryWriter writer = new BinaryWriter(stream))
                {
                    writer.Write(M2.Length);
                    writer.Write(M2, 0, M2.Length);

                    session.EnqueueMessageOk(new ServerKeyDataMessage
                    {
                        KeyData = Convert.ToBase64String(stream.ToArray())
                    });
                }

            // enqueue new key to be set after next packet flush
            session.InitialiseEncryption(key);
        }
        public static void HandleKeyData(StsSession session, ClientKeyDataMessage keyData)
        {
            session.KeyExchange.CalculateSecret(keyData.A);

            byte[] key = session.KeyExchange.CalculateSessionKey();
            if (!session.KeyExchange.VerifyClientEvidenceMessage(keyData.M1))
            {
                // TODO: send error
                return;
            }

            byte[] M2 = session.KeyExchange.CalculateServerEvidenceMessage();

            using (MemoryStream stream = new MemoryStream())
                using (BinaryWriter writer = new BinaryWriter(stream))
                {
                    writer.Write(M2.Length);
                    writer.Write(M2, 0, M2.Length);

                    session.EnqueueMessageOk(new ServerKeyDataMessage
                    {
                        KeyData = Convert.ToBase64String(stream.ToArray())
                    });
                }

            // must be set after sending response
            session.InitialiseEncryption(key);
        }
        public static void HandleLoginStart(StsSession session, ClientLoginStartMessage loginStart)
        {
            session.EnqueueEvent(new TaskGenericEvent <Account>(AuthDatabase.GetAccountAsync(loginStart.LoginName),
                                                                account =>
            {
                if (account == null)
                {
                    session.EnqueueMessageError(new ServerErrorMessage((int)ErrorCode.InvalidAccountNameOrPassword));
                    return;
                }

                session.Account = account;

                byte[] s            = account.S.ToByteArray();
                byte[] v            = account.V.ToByteArray();
                session.KeyExchange = new Srp6Provider(account.Email, s, v);

                byte[] B = session.KeyExchange.GenerateServerCredentials();
                using (MemoryStream stream = new MemoryStream())
                    using (BinaryWriter writer = new BinaryWriter(stream))
                    {
                        writer.Write(s.Length);
                        writer.Write(s, 0, s.Length);
                        writer.Write(B.Length);
                        writer.Write(B, 0, B.Length);

                        session.EnqueueMessageOk(new ServerLoginStartMessage
                        {
                            KeyData = Convert.ToBase64String(stream.ToArray())
                        });
                    }

                session.State = SessionState.LoginStart;
            }));
        }
 public static void HandleLoginFinish(StsSession session, ClientLoginFinishMessage loginFinish)
 {
     session.EnqueueMessageOk(new ServerLoginFinishMessage
     {
         LocationId = "",
         UserId     = "",
         UserCenter = 0,
         UserName   = "",
         AccessMask = 1L
     });
 }
        public static void HandleRequestGameToken(StsSession session, RequestGameTokenMessage requestGameToken)
        {
            Guid guid = RandomProvider.GetGuid();

            session.EnqueueEvent(new TaskEvent(AuthDatabase.UpdateAccountGameToken(session.Account, guid),
                                               () =>
            {
                session.EnqueueMessageOk(new RequestGameTokenResponse
                {
                    Token = guid.ToString()
                });
            }));
        }
        public static bool Invoke(StsPacket reader, StsSession session)
        {
            var message = ((StsHeader)reader.Header).Message;

            Console.WriteLine($"Received Auth packet: {message} (0x{message:X}), Length: {reader.Data.Length}");

            HandleAuthPacket packet;

            if (AuthMessageHandlers.TryGetValue(message, out packet))
            {
                packet.Invoke(reader, session);

                return true;
            }

            return false;
        }
        public static void HandleAuthKeyData(StsPacket packet, StsSession session)
        {
            var keyData = new BinaryReader(new MemoryStream(Convert.FromBase64String(packet["KeyData"].ToString())));
            var a = keyData.ReadBytes(keyData.ReadInt32());
            var m = keyData.ReadBytes(keyData.ReadInt32());

            session.SecureRemotePassword.CalculateU(a);
            session.SecureRemotePassword.CalculateClientM(a);

            if (session.SecureRemotePassword.ClientM.Compare(m))
            {
                session.SecureRemotePassword.CalculateServerM(m, a);

                session.ClientCrypt = new SARC4();
                session.ClientCrypt.PrepareKey(session.SecureRemotePassword.SessionKey);

                session.State = 1;

                var SKeyData = new BinaryWriter(new MemoryStream());

                SKeyData.Write(session.SecureRemotePassword.ServerM.Length);
                SKeyData.Write(session.SecureRemotePassword.ServerM);

                var reply = new StsPacket(StsReason.OK, packet.Header.Sequence);
                var xmlData = new XmlData();

                xmlData.WriteElementRoot("Reply");
                xmlData.WriteElement("KeyData", Convert.ToBase64String(SKeyData.ToArray()));

                reply.WriteXmlData(xmlData);

                session.Send(reply);
            }
            else
            {
                session.Account = null;

                var reply = new StsPacket(StsReason.ErrBadPasswd, packet.Header.Sequence);

                reply.WriteString("<Error code=\"11\" server=\"0\" module=\"0\" line=\"0\"/>\n");

                session.Send(reply);
            }
        }
        public static void HandleGameAccountListMyAccounts(StsPacket packet, StsSession session)
        {
            var userId = uint.Parse(packet["UserId"].ToString());

            if (userId == session.Account.Id)
            {
                var reply = new StsPacket(StsReason.OK, packet.Header.Sequence);
                var xmlData = new XmlData();

                // Only 1 GameAccount supported for now.
                xmlData.WriteElementRoot("Reply");
                xmlData.WriteCustom("<GameAccount>\n");
                xmlData.WriteElement("Alias", $"{session.Account.GameAccounts[0].Alias}");
                xmlData.WriteElement("Created", "");
                xmlData.WriteCustom("</GameAccount>\n");

                reply.WriteXmlData(xmlData);

                session.Send(reply);
            }
        }
        public static void HandleAuthLoginFinish(StsPacket packet, StsSession session)
        {
            // Server packets are encrypted now.
            session.ServerCrypt = new SARC4();
            session.ServerCrypt.PrepareKey(session.SecureRemotePassword.SessionKey);

            var reply = new StsPacket(StsReason.OK, packet.Header.Sequence);
            var xmlData = new XmlData();

            xmlData.WriteElementRoot("Reply");

            xmlData.WriteElement("LocationId", "");
            xmlData.WriteElement("UserId", session.Account.Id.ToString());
            xmlData.WriteElement("UserCenter", "");
            xmlData.WriteElement("UserName", session.Account.LoginName);
            xmlData.WriteElement("AccessMask", "");
            xmlData.WriteElement("Roles", "");
            xmlData.WriteElement("Status", "");

            reply.WriteXmlData(xmlData);

            session.Send(reply);
        }
 public static void HandleListMyAccounts(StsSession session, ListMyAccountsMessage listMyAccounts)
 {
     session.EnqueueMessageOk(new ListMyAccountsResponse
     {
     });
 }
示例#11
0
 public static void HandleConnect(StsSession session, ClientConnectMessage connect)
 {
     session.State = SessionState.Connected;
 }
示例#12
0
 public static void HandlePing(StsSession session, PingMessage ping)
 {
     session.Heartbeat.OnHeartbeat();
 }
示例#13
0
        public static void HandleAuthLoginStart(StsPacket packet, StsSession session)
        {
            // Can be an email or user name.
            var loginName = packet["LoginName"].ToString();

            session.Account = DB.Auth.Single<Account>(a => a.Email == loginName);

            // Support for email only.
            if (loginName != null && session.Account != null)
            {
                session.SecureRemotePassword = new SRP6a(session.Account.Salt, loginName, session.Account.PasswordVerifier);
                session.SecureRemotePassword.CalculateB();

                var keyData = new BinaryWriter(new MemoryStream());

                keyData.Write(session.SecureRemotePassword.S.Length);
                keyData.Write(session.SecureRemotePassword.S);
                keyData.Write(session.SecureRemotePassword.B.Length);
                keyData.Write(session.SecureRemotePassword.B);

                var reply = new StsPacket(StsReason.OK, packet.Header.Sequence);
                var xmlData = new XmlData();

                xmlData.WriteElementRoot("Reply");
                xmlData.WriteElement("KeyData", Convert.ToBase64String(keyData.ToArray()));

                reply.WriteXmlData(xmlData);

                session.Send(reply);
            }
            else
            {
                // Let's use ErrBadPasswd instead of ErrAccountNotFound.
                var reply = new StsPacket(StsReason.ErrBadPasswd, packet.Header.Sequence);

                reply.WriteString("<Error code=\"11\" server=\"0\" module=\"0\" line=\"0\"/>\n");

                session.Send(reply);
            }
        }
示例#14
0
        public static void HandleAuthRequestGameToken(StsPacket packet, StsSession session)
        {
            if (DB.Auth.Update<Account>(a => a.Id == session.Account.Id, a => a.Online.Set(true)))
            {
                var reply = new StsPacket(StsReason.OK, packet.Header.Sequence);
                var xmlData = new XmlData();

                xmlData.WriteElementRoot("Reply");

                xmlData.WriteElement("Token", "");

                reply.WriteXmlData(xmlData);

                session.Send(reply);
            }
            else
                session.Dispose();
        }