public void GetChallengeTest() { byte[] raw = new byte[] { 09, 04, 05, 06, 07, 0x2D, 49, 50, 51, 52, 53, 0 }; // ... -12345 ChallengePacket packet = new ChallengePacket(raw); CollectionAssert.AreEqual(new byte[] { 255, 255, 207, 199 }, packet.GetChallenge()); }
protected override void ConstructeResponse() { ChallengePacket packet = new ChallengePacket(); packet.Parse(_session.RemoteEndPoint, _recv); _sendingBuffer = packet.BuildResponse(); }
protected override void ConstructeResponse() { ChallengePacket packet = new ChallengePacket(); QRSession client = (QRSession)_session.GetInstance(); packet.Parse(client.RemoteEndPoint, _recv); _sendingBuffer = packet.GenerateResponse(); }
public void GetBytesTest() { byte[] expected = DataGenerator.GetChallengePacket(); byte[] data = DataGenerator.GetChallengePacket(); ChallengePacket packet = new ChallengePacket(data); CollectionAssert.AreEqual(expected, packet.GetBytes()); }
public void GetDataTest() { byte[] expected = DataGenerator.ExtractDataBytes( DataGenerator.GetChallengePacket(), DataStartPosition); byte[] data = DataGenerator.GetChallengePacket(); ChallengePacket packet = new ChallengePacket(data); CollectionAssert.AreEqual(expected, packet.GetData()); }
public void GetDataStringTest() { byte[] data = DataGenerator.ExtractDataBytes( DataGenerator.GetChallengePacket(), DataStartPosition); string expected = Encoding.ASCII.GetString(data); ChallengePacket packet = new ChallengePacket(DataGenerator.GetChallengePacket()); Assert.AreEqual <string>(expected, packet.GetDataString()); }
public void TestChallengePacket() { Random rnd = new Random(0); ulong clientRandom = (ulong)rnd.Next(int.MaxValue); ulong serverRandom = (ulong)rnd.Next(int.MaxValue); ChallengePacket packet1 = new ChallengePacket(clientRandom, serverRandom); byte[] output = new byte[1024]; int written = packet1.Write(output, null); ChallengePacket packet2 = new ChallengePacket(); packet2.Read(output, written); Assert.AreEqual(packet1.ClientRandom, packet2.ClientRandom); Assert.AreEqual(packet1.ServerRandom, packet2.ServerRandom); }
public static async Task HandleChallengeAsync(LogonRemoteClient client, LogonPacket logonPacket) { var packet = new ChallengePacket(logonPacket); Console.WriteLine("Received logon packet:"); Console.WriteLine($"\tError:\t\t\t{packet.Error}"); Console.WriteLine($"\tSize:\t\t\t{packet.Size}"); Console.WriteLine($"\tGame:\t\t\t{packet.Game}"); Console.WriteLine($"\tBuild:\t\t\t{packet.Build}"); Console.WriteLine($"\tPlatform:\t\t{packet.Platform}"); Console.WriteLine($"\tOS:\t\t\t{packet.OS}"); Console.WriteLine($"\tCountry:\t\t{packet.Country}"); Console.WriteLine($"\tTimezone Bias:\t\t{packet.TimezoneBias}"); Console.WriteLine($"\tIP:\t\t\t{packet.IP}"); Console.WriteLine($"\tAccount Name:\t\t{packet.AccountName}"); Console.Write($"Validating username... "); var account = LogonServices.Accounts.GetAccount(packet.AccountName); if (account == null) { Console.WriteLine($"failed. Account {packet.AccountName} does not exist."); var response = new ChallengeResponsePacket { Error = ChallengeResponsePacket.ChallengeResponseError.NoSuchAccount }; await client.SendDataAsync(new LogonMetaPacket(response.FinalizePacket())); } else { Console.WriteLine("success!"); if (account.Banned) { Console.WriteLine($"Account {account.Username} is currently banned."); var response = new ChallengeResponsePacket { Error = ChallengeResponsePacket.ChallengeResponseError.AccountClosed }; await client.SendDataAsync(new LogonMetaPacket(response.FinalizePacket())); client.Disconnect(); return; } client.AuthData.DbAccount = account; Console.WriteLine($"Validating username and password for account {account.Username}"); client.AuthData.InitSRP6(account.Username, account.PasswordHash.ByteRepresentationToByteArray()); var pack = new Packet(); pack.WriteByte(0); pack.WriteByte(0); pack.WriteByte(0); var b = client.AuthData.Srp6.PublicEphemeralValueB; pack.WriteBytes(b.GetBytes(32)); pack.WriteByte(1); pack.WriteBytes(client.AuthData.Srp6.Generator.GetBytes(1)); pack.WriteByte(32); pack.WriteBytes(client.AuthData.Srp6.Modulus.GetBytes(32)); pack.WriteBytes(client.AuthData.Srp6.Salt.GetBytes(32)); var rand = new Random(Environment.TickCount); var randBytes = new byte[16]; rand.NextBytes(randBytes); pack.WriteBytes(randBytes); pack.WriteByte(0); await client.SendDataAsync(new LogonMetaPacket(pack.FinalizePacket())); } }
/// <summary> /// Initializes serverobject with IP /// </summary> /// <param name="useLocalhost">Whether the server should use 127.0.0.1 ip or use its actual outgoing one</param> public Server(bool useLocalhost = false) { WorldManager.OnServer = true; isDisposed = false; isDoingCleanup = false; IPAddress ip; if (useLocalhost) { ip = IPAddress.Parse("127.0.0.1"); } else { ip = GetIP(); } IPEndPoint iep = new IPEndPoint(ip, PORT); listener = new CustomUdpClient(PORT); listener.PacketRecieved += PacketReceived; pending = new Connection[PENDING_SLOTS]; connected = new Connection[CONNECTED_SLOTS]; games = new Game[GAME_SLOTS]; packetCallbacks = new Dictionary <Type, Action <Packet> >() { { typeof(StringPacket), (Packet p) => { StringPacket sp = (StringPacket)p; Console.WriteLine(sp.Content); } }, { typeof(ConnectPacket), (Packet p) => { int connectionIndex = GetConnectionIndexFromIEP(pending, p.Sender); ChallengePacket challenge; ConnectPacket cp = (ConnectPacket)p; if (connectionIndex == -1) { int i = GetFirstFreeIndex(pending); if (i == -1) { listener.Send(new DeclineConnectPacket(), p.Sender); return; } challenge = new ChallengePacket(cp.ClientSalt); pending[i] = new Connection(cp.Sender, cp.ClientSalt, challenge.ServerSalt); pending[i].RefreshRecievedPacketTimestamp(); } else { Connection c = pending[connectionIndex]; c.ClientSalt = cp.ClientSalt; challenge = new ChallengePacket(c.ClientSalt, c.ServerSalt); c.RefreshRecievedPacketTimestamp(); } listener.Send(challenge, p.Sender); } }, { typeof(ChallengeResponsePacket), (Packet p) => { int connectionIndex = GetConnectionIndexFromIEP(pending, p.Sender); if (connectionIndex == -1) { return; } Connection c = pending[connectionIndex]; ChallengeResponsePacket crp = (ChallengeResponsePacket)p; if (crp.Xored == c.Xored) // response packet was correct { pending[connectionIndex] = null; connectionIndex = GetFirstFreeIndex(connected); if (connectionIndex == -1) { listener.Send(new DeclineConnectPacket(), p.Sender); return; } connected[connectionIndex] = c; c.RefreshRecievedPacketTimestamp(); KeepClientAlivePacket kcap = new KeepClientAlivePacket(); listener.Send(kcap, p.Sender); return; } listener.Send(new DeclineConnectPacket(), p.Sender); } } }; connectedPacketCallbacks = new Dictionary <Type, Action <SaltedPacket, Connection> >() { { typeof(KeepAlivePacket), (SaltedPacket p, Connection c) => { c.RefreshRecievedPacketTimestamp(); } }, { typeof(QueuePacket), (SaltedPacket p, Connection c) => { int gameIndex = GetGameIndexFromIep(p.Sender); int gameId = -1; if (gameIndex != -1) { gameId = games[gameIndex].Id; } else { lock (games) { foreach (Game g in games) { if (g != null && g.AddConnection(c)) { gameId = g.Id; break; } } if (gameId == -1) { int newGameIndex = GetFirstFreeIndex(games); if (newGameIndex != -1) { Game g = new Game(); games[newGameIndex] = g; g.AddConnection(c); gameId = g.Id; g.StartHandle(SendPacket); g.GameEnded += (object sender, EventArgs e) => { lock (games) games[newGameIndex] = null; }; } } } } QueueResponsePacket qrp = new QueueResponsePacket(gameId); listener.Send(qrp, p.Sender); c.RefreshSentPacketTimestamp(); } }, { typeof(GetGameInfoPacket), (SaltedPacket p, Connection c) => { int gameIndex = GetGameIndexFromIep(c.Client); if (gameIndex == -1) { return; } Game g = games[gameIndex]; GameInfoPacket ggip = new GameInfoPacket(g); listener.Send(ggip, p.Sender); c.RefreshSentPacketTimestamp(); } }, { typeof(InputPacket), (SaltedPacket p, Connection c) => { int gameIndex = GetGameIndexFromIep(c.Client); if (gameIndex == -1) { SendPacket(new QueueResponsePacket(-1), c.Client); return; } Game g = games[gameIndex]; InputPacket inpt = (InputPacket)p; g.HandleInputPacket(inpt, c); } } }; }
private void HandlePacket(byte[] data, int length, EndPoint fromEndpoint) { if (length < 1) { // TODO: Shit hit the fan } PacketType type = (PacketType)data[0]; switch (type) { case PacketType.ConnectionRequest: { ConnectionRequestPacket connectionRequest = new ConnectionRequestPacket(); if (connectionRequest.Read(data, length) && !PendingPeers.ContainsKey(new ConnectKey(fromEndpoint, connectionRequest.ClientRandom))) { ulong localSessionPart = RandomUtils.GetULong(Constants.USE_CRYPTO_RANDOM); RemotePeer peer = new RemotePeer() { ChallengeData = connectionRequest.ClientRandom, RemoteEndpoint = fromEndpoint, ConnectionState = ConnectState.WaitingForChallengeResponse, ChallengeSeed = localSessionPart, ChallengeResult = localSessionPart ^ connectionRequest.ClientRandom, LastIncomingMessageDate = DateTime.Now }; PendingPeers.Add(new ConnectKey(fromEndpoint, connectionRequest.ClientRandom), peer); ChallengePacket packet = new ChallengePacket(peer.ChallengeData, peer.ChallengeSeed); SendPacket(packet, peer); for (int i = 0; i < Constants.CONNECTION_SEGMENT_RETRIES - 1; i++) { _network.PacketScheduler.Add(DateTime.Now.Add(new TimeSpan(0, 0, 0, 0, Constants.CONNECTION_SEGMENT_RETRY_TIMEOUT * i)), new ScheduledPacket() { Packet = packet, LocalPeer = this, RemotePeer = peer }); } } } break; case PacketType.Challenge: { ChallengePacket challenge = new ChallengePacket(); if (challenge.Read(data, length) && PendingPeers.ContainsKey(new ConnectKey(fromEndpoint, challenge.ClientRandom))) { RemotePeer peer = PendingPeers[new ConnectKey(fromEndpoint, challenge.ClientRandom)]; if (peer.ConnectionState == ConnectState.WaitingForChallenge) { peer.CreateChannels(_network.ChannelTypes); peer.LastIncomingMessageDate = DateTime.Now; peer.ChallengeData = challenge.ServerRandom; peer.ChallengeResult = peer.ChallengeData ^ peer.ChallengeSeed; peer.ConnectionState = ConnectState.Connected; PendingPeers.Remove(new ConnectKey(fromEndpoint, challenge.ClientRandom)); Connected.Add(fromEndpoint, peer); incomingEvents.Enqueue(new NetworkEvent() { EventType = EventType.Connect, Packet = null, RemotePeer = peer, LocalPeer = this }); ChallengeResponsePacket packet = new ChallengeResponsePacket(peer.ChallengeSeed, peer.ChallengeData, peer.ChallengeResult); SendPacket(packet, peer); for (int i = 0; i < Constants.CONNECTION_SEGMENT_RETRIES - 1; i++) { _network.PacketScheduler.Add(DateTime.Now.Add(new TimeSpan(0, 0, 0, 0, Constants.CONNECTION_SEGMENT_RETRY_TIMEOUT * i)), new ScheduledPacket() { Packet = packet, LocalPeer = this, RemotePeer = peer }); } } } } break; case PacketType.ChallengeResponse: { ChallengeResponsePacket challengeResponse = new ChallengeResponsePacket(); if (challengeResponse.Read(data, length) && PendingPeers.ContainsKey(new ConnectKey(fromEndpoint, challengeResponse.ClientRandom))) { RemotePeer peer = PendingPeers[new ConnectKey(fromEndpoint, challengeResponse.ClientRandom)]; if (peer.ConnectionState == ConnectState.WaitingForChallengeResponse && peer.ChallengeResult == challengeResponse.ChallengeResponse) { peer.CreateChannels(_network.ChannelTypes); peer.LastIncomingMessageDate = DateTime.Now; peer.ConnectionState = ConnectState.Connected; PendingPeers.Remove(new ConnectKey(fromEndpoint, challengeResponse.ClientRandom)); Connected.Add(fromEndpoint, peer); incomingEvents.Enqueue(new NetworkEvent() { EventType = EventType.Connect, Packet = null, RemotePeer = peer, LocalPeer = this }); } } } break; case PacketType.Data: { ChanneledPacket channeledPacket = new ChanneledPacket(); if (channeledPacket.Read(data, length) && Connected.ContainsKey(fromEndpoint)) { RemotePeer peer = Connected[fromEndpoint]; if (peer.ConnectionState == ConnectState.Connected) { ChanneledPacket incomingPacket = peer.Channels[channeledPacket.Channel].HandleIncomingMessagePoll(data, length, out bool hasMore); while (incomingPacket != null) { peer.LastIncomingMessageDate = DateTime.Now; incomingEvents.Enqueue(new NetworkEvent() { EventType = EventType.Data, Packet = incomingPacket, RemotePeer = peer, LocalPeer = this }); if (!hasMore) { break; } incomingPacket = peer.Channels[channeledPacket.Channel].HandlePoll(); } } } } break; case PacketType.Disconnect: { DisconnectPacket disconnectPacket = new DisconnectPacket(); if (disconnectPacket.Read(data, length) && Connected.ContainsKey(fromEndpoint)) { RemotePeer peer = Connected[fromEndpoint]; peer.ConnectionState = ConnectState.Disconnected; Connected.Remove(fromEndpoint); incomingEvents.Enqueue(new NetworkEvent() { EventType = EventType.Disconnect, Packet = null, RemotePeer = peer, LocalPeer = this }); } } break; case PacketType.Ack: { AckPacket ackPacket = new AckPacket(); if (ackPacket.Read(data, length) && Connected.ContainsKey(fromEndpoint)) { RemotePeer peer = Connected[fromEndpoint]; if (peer.Channels[ackPacket.Channel].SupportsAck) { peer.Channels[ackPacket.Channel].HandleAck(ackPacket); } } } break; } }