public static void HandleAuthContinuedSession(AuthContinuedSession authContinuedSession, WorldSession session) { var gameAccount = Manager.Redirect.GetGameAccountFromRedirect(authContinuedSession.Key); // Delete redirect key Manager.Redirect.DeleteGameAccountRedirect(authContinuedSession.Key); if (gameAccount != null) { var sha1 = new SHA1Managed(); var emailBytes = Encoding.UTF8.GetBytes(gameAccount.Account.Id + "#" + gameAccount.Index); var sessionKeyBytes = gameAccount.SessionKey.ToByteArray(); var challengeBytes = BitConverter.GetBytes(session.Challenge); sha1.TransformBlock(emailBytes, 0, emailBytes.Length, emailBytes, 0); sha1.TransformBlock(sessionKeyBytes, 0, 40, sessionKeyBytes, 0); sha1.TransformFinalBlock(challengeBytes, 0, 4); if (sha1.Hash.Compare(authContinuedSession.Digest)) { session.Crypt = new Framework.Cryptography.WoW.WoWCrypt(); session.Crypt.Initialize(gameAccount.SessionKey.ToByteArray(), session.ClientSeed, session.ServerSeed); // Resume on the new connection session.Send(new ResumeComms()); return; } } session.Dispose(); }
void HandleAuthContinuedSessionCallback(AuthContinuedSession authSession, SQLResult result) { if (result.IsEmpty()) { SendAuthResponseError(BattlenetRpcErrorCode.Denied); CloseSocket(); return; } ConnectToKey key = new ConnectToKey(); _key = key.Raw = authSession.Key; uint accountId = key.AccountId; string login = result.Read <string>(0); _sessionKey = result.Read <string>(1).ToByteArray(); HmacSha256 hmac = new HmacSha256(_sessionKey); hmac.Process(BitConverter.GetBytes(authSession.Key), 8); hmac.Process(authSession.LocalChallenge, authSession.LocalChallenge.Length); hmac.Process(_serverChallenge, 16); hmac.Finish(ContinuedSessionSeed, 16); if (!hmac.Digest.Compare(authSession.Digest)) { Log.outError(LogFilter.Network, "WorldSocket.HandleAuthContinuedSession: Authentication failed for account: {0} ('{1}') address: {2}", accountId, login, GetRemoteIpAddress()); CloseSocket(); return; } SendPacket(new EnableEncryption()); }
void HandleAuthContinuedSessionCallback(AuthContinuedSession authSession, SQLResult result) { if (result.IsEmpty()) { SendAuthResponseError(BattlenetRpcErrorCode.Denied); CloseSocket(); return; } ConnectToKey key = new ConnectToKey(); _key = key.Raw = authSession.Key; uint accountId = key.AccountId; string login = result.Read <string>(0); _sessionKey = result.Read <byte[]>(1); HmacSha256 hmac = new HmacSha256(_sessionKey); hmac.Process(BitConverter.GetBytes(authSession.Key), 8); hmac.Process(authSession.LocalChallenge, authSession.LocalChallenge.Length); hmac.Process(_serverChallenge, 16); hmac.Finish(ContinuedSessionSeed, 16); if (!hmac.Digest.Compare(authSession.Digest)) { Log.outError(LogFilter.Network, "WorldSocket.HandleAuthContinuedSession: Authentication failed for account: {0} ('{1}') address: {2}", accountId, login, GetRemoteIpAddress()); CloseSocket(); return; } HmacSha256 encryptKeyGen = new HmacSha256(_sessionKey); encryptKeyGen.Process(authSession.LocalChallenge, authSession.LocalChallenge.Length); encryptKeyGen.Process(_serverChallenge, 16); encryptKeyGen.Finish(EncryptionKeySeed, 16); // only first 16 bytes of the hmac are used Buffer.BlockCopy(encryptKeyGen.Digest, 0, _encryptKey, 0, 16); SendPacket(new EnterEncryptedMode(_encryptKey, true)); AsyncRead(); }
void HandleAuthContinuedSession(AuthContinuedSession authSession) { ConnectToKey key = new ConnectToKey(); _key = key.Raw = authSession.Key; _connectType = key.connectionType; if (_connectType != ConnectionType.Instance) { SendAuthResponseError(BattlenetRpcErrorCode.Denied); CloseSocket(); return; } uint accountId = key.AccountId; PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_ACCOUNT_INFO_CONTINUED_SESSION); stmt.AddValue(0, accountId); _queryProcessor.AddQuery(DB.Login.AsyncQuery(stmt).WithCallback(HandleAuthContinuedSessionCallback, authSession)); }
public static async void HandleAuthContinuedSession(AuthContinuedSession authContinuedSession, NodeSession session) { var accountInfo = Manager.Redirect.GetAccountInfo(authContinuedSession.Key); // Delete redirect key Manager.Redirect.DeleteCharacterRedirect(authContinuedSession.Key); if (accountInfo != null) { var sha1 = new SHA1Managed(); var emailBytes = Encoding.UTF8.GetBytes(accountInfo.Item1.AccountId + "#" + accountInfo.Item1.Index); var sessionKeyBytes = accountInfo.Item1.SessionKey.ToByteArray(); var challengeBytes = BitConverter.GetBytes(session.Challenge); sha1.TransformBlock(emailBytes, 0, emailBytes.Length, emailBytes, 0); sha1.TransformBlock(sessionKeyBytes, 0, 40, sessionKeyBytes, 0); sha1.TransformFinalBlock(challengeBytes, 0, 4); if (sha1.Hash.Compare(authContinuedSession.Digest)) { session.State = SessionState.Authenticated; session.Account = DB.Auth.Single <Account>(a => a.Id == accountInfo.Item1.AccountId); session.GameAccount = accountInfo.Item1; session.Crypt = new Framework.Cryptography.WoW.WoWCrypt(); session.Crypt.Initialize(accountInfo.Item1.SessionKey.ToByteArray(), session.ClientSeed, session.ServerSeed); // Resume on the new connection await session.Send(new ResumeComms()); return; } } session.Dispose(); }
bool ProcessPacket(WorldPacket packet) { ClientOpcodes opcode = (ClientOpcodes)packet.GetOpcode(); PacketLog.Write(packet.GetData(), opcode, GetRemoteIpAddress(), GetRemotePort(), _connectType); try { switch (opcode) { case ClientOpcodes.Ping: Ping ping = new Ping(packet); ping.Read(); return(HandlePing(ping)); case ClientOpcodes.AuthSession: if (_worldSession != null) { Log.outError(LogFilter.Network, "WorldSocket.ProcessPacket: received duplicate CMSG_AUTH_SESSION from {0}", _worldSession.GetPlayerInfo()); return(false); } AuthSession authSession = new AuthSession(packet); authSession.Read(); HandleAuthSession(authSession); break; case ClientOpcodes.AuthContinuedSession: if (_worldSession != null) { Log.outError(LogFilter.Network, "WorldSocket.ProcessPacket: received duplicate CMSG_AUTH_CONTINUED_SESSION from {0}", _worldSession.GetPlayerInfo()); return(false); } AuthContinuedSession authContinuedSession = new AuthContinuedSession(packet); authContinuedSession.Read(); HandleAuthContinuedSession(authContinuedSession); break; case ClientOpcodes.LogDisconnect: break; case ClientOpcodes.EnableNagle: Log.outDebug(LogFilter.Network, "Client {0} requested enabling nagle algorithm", GetRemoteIpAddress().ToString()); SetNoDelay(false); break; case ClientOpcodes.ConnectToFailed: ConnectToFailed connectToFailed = new ConnectToFailed(packet); connectToFailed.Read(); HandleConnectToFailed(connectToFailed); break; case ClientOpcodes.EnableEncryptionAck: HandleEnableEncryptionAck(); break; default: if (_worldSession == null) { Log.outError(LogFilter.Network, "ProcessIncoming: Client not authed opcode = {0}", opcode); return(false); } if (!PacketManager.ContainsHandler(opcode)) { Log.outError(LogFilter.Network, "No defined handler for opcode {0} sent by {1}", opcode, _worldSession.GetPlayerInfo()); break; } // Our Idle timer will reset on any non PING opcodes. // Catches people idling on the login screen and any lingering ingame connections. _worldSession.ResetTimeOutTime(); _worldSession.QueuePacket(packet); break; } } catch (IOException) { Log.outError(LogFilter.Network, "WorldSocket.ProcessPacket(): client {0} sent malformed {1}", GetRemoteIpAddress().ToString(), opcode); return(false); } return(true); }
ReadDataHandlerResult ReadData() { PacketHeader header = new PacketHeader(); header.Read(_headerBuffer.GetData()); if (!_worldCrypt.Decrypt(_packetBuffer.GetData(), header.Tag)) { Log.outError(LogFilter.Network, $"WorldSocket.ReadData(): client {GetRemoteIpAddress()} failed to decrypt packet (size: {header.Size})"); return(ReadDataHandlerResult.Error); } WorldPacket packet = new WorldPacket(_packetBuffer.GetData()); _packetBuffer.Reset(); if (packet.GetOpcode() >= (int)ClientOpcodes.Max) { Log.outError(LogFilter.Network, $"WorldSocket.ReadData(): client {GetRemoteIpAddress()} sent wrong opcode (opcode: {packet.GetOpcode()})"); return(ReadDataHandlerResult.Error); } PacketLog.Write(packet.GetData(), packet.GetOpcode(), GetRemoteIpAddress(), _connectType, true); ClientOpcodes opcode = (ClientOpcodes)packet.GetOpcode(); switch (opcode) { case ClientOpcodes.Ping: Ping ping = new Ping(packet); ping.Read(); if (!HandlePing(ping)) { return(ReadDataHandlerResult.Error); } break; case ClientOpcodes.AuthSession: if (_worldSession != null) { Log.outError(LogFilter.Network, $"WorldSocket.ReadData(): received duplicate CMSG_AUTH_SESSION from {_worldSession.GetPlayerInfo()}"); return(ReadDataHandlerResult.Error); } AuthSession authSession = new AuthSession(packet); authSession.Read(); HandleAuthSession(authSession); return(ReadDataHandlerResult.WaitingForQuery); case ClientOpcodes.AuthContinuedSession: if (_worldSession != null) { Log.outError(LogFilter.Network, $"WorldSocket.ReadData(): received duplicate CMSG_AUTH_CONTINUED_SESSION from {_worldSession.GetPlayerInfo()}"); return(ReadDataHandlerResult.Error); } AuthContinuedSession authContinuedSession = new AuthContinuedSession(packet); authContinuedSession.Read(); HandleAuthContinuedSession(authContinuedSession); return(ReadDataHandlerResult.WaitingForQuery); case ClientOpcodes.KeepAlive: if (_worldSession != null) { _worldSession.ResetTimeOutTime(true); } break; case ClientOpcodes.LogDisconnect: break; case ClientOpcodes.EnableNagle: SetNoDelay(false); break; case ClientOpcodes.ConnectToFailed: ConnectToFailed connectToFailed = new ConnectToFailed(packet); connectToFailed.Read(); HandleConnectToFailed(connectToFailed); break; case ClientOpcodes.EnterEncryptedModeAck: HandleEnterEncryptedModeAck(); break; default: if (_worldSession == null) { Log.outError(LogFilter.Network, $"ProcessIncoming: Client not authed opcode = {opcode}"); return(ReadDataHandlerResult.Error); } if (!PacketManager.ContainsHandler(opcode)) { Log.outError(LogFilter.Network, $"No defined handler for opcode {opcode} sent by {_worldSession.GetPlayerInfo()}"); break; } // Our Idle timer will reset on any non PING opcodes on login screen, allowing us to catch people idling. _worldSession.ResetTimeOutTime(false); // Copy the packet to the heap before enqueuing _worldSession.QueuePacket(packet); break; } return(ReadDataHandlerResult.Ok); }