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 { }); }
public static void HandleConnect(StsSession session, ClientConnectMessage connect) { session.State = SessionState.Connected; }
public static void HandlePing(StsSession session, PingMessage ping) { session.Heartbeat.OnHeartbeat(); }
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); } }
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(); }