private void SendChallengeResponse(long cSalt, long sSalt) { ChallengeResponsePacket responsePacket = new ChallengeResponsePacket(); responsePacket.payload.result = cSalt ^ sSalt; SendToServer(responsePacket); }
public void OnReceivePacket(IPEndPoint ipEndpoint, PacketType packetType, Stream stream) { switch (packetType) { case PacketType.ConnectionRequest: ConnectionRequestPacket connectionRequestPacket = new ConnectionRequestPacket(); connectionRequestPacket.Deserialize(stream); CheckAndSendChallengeRequest(ipEndpoint, connectionRequestPacket.payload); break; case PacketType.ChallengeRequest: ChallengeRequestPacket challengeRequestPacket = new ChallengeRequestPacket(); challengeRequestPacket.Deserialize(stream); CheckAndSendChallengeResponse(ipEndpoint, challengeRequestPacket.payload); break; case PacketType.ChallengeResponse: ChallengeResponsePacket challengeResponsePacket = new ChallengeResponsePacket(); challengeResponsePacket.Deserialize(stream); CheckResult(ipEndpoint, challengeResponsePacket.payload); break; case PacketType.Connected: if (!isServer && currentState == State.RespondingChallenge) { currentState = State.Connected; } break; } }
void SendChallengeResponse(long clientSalt, long serverSalt) { ChallengeResponsePacket packet = new ChallengeResponsePacket(); packet.payload.result = clientSalt ^ serverSalt; // Example: 110011 ^ 000011 = 110000 PacketManager.Instance.SendPacketToServer(packet); }
private void SendChallengeResponse(ulong clientSalt, ulong serverSalt) { ChallengeResponsePacket request = new ChallengeResponsePacket(); request.payload.result = clientSalt ^ serverSalt; SendToServer(request); }
public static async Task HandleProofAsync(LogonRemoteClient client, LogonPacket logonPacket) { var proofPacket = new ProofPacket(logonPacket); var proofValid = client.AuthData.Srp6.IsClientProofValid(proofPacket.A, proofPacket.M1); Console.WriteLine($"Authentication {(proofValid ? "successful" : "failed")}"); if (!proofValid) { var response = new ChallengeResponsePacket { Error = ChallengeResponsePacket.ChallengeResponseError.NoSuchAccount }; await client.SendDataAsync(new LogonMetaPacket(response.FinalizePacket())); return; } var successPacket = new Packet(); successPacket.WriteByte(0x1); successPacket.WriteByte(0x0); successPacket.WriteBytes(client.AuthData.Srp6.ServerSessionKeyProof.GetBytes(20)); successPacket.WriteInt32(0); successPacket.WriteInt32(0); successPacket.WriteInt16(0); await client.SendDataAsync(new LogonMetaPacket(successPacket.FinalizePacket())); }
public void OnReceivePacket(IPEndPoint ipEndpoint, PacketType packetType, Stream stream) { switch (packetType) { case PacketType.ConnectionRequest: { ConnectionRequestPacket connectionRequestPacket = new ConnectionRequestPacket(); connectionRequestPacket.Deserialize(stream); CheckAndSendChallengeRequest(ipEndpoint, connectionRequestPacket.payload); } break; case PacketType.ChallengeRequest: { ChallengeRequestPacket challengeRequestPacket = new ChallengeRequestPacket(); challengeRequestPacket.Deserialize(stream); CheckAndSendChallengeResponse(ipEndpoint, challengeRequestPacket.payload); } break; case PacketType.ChallengeResponse: { ChallengeResponsePacket challengeResponsePacket = new ChallengeResponsePacket(); challengeResponsePacket.Deserialize(stream); CheckResult(ipEndpoint, challengeResponsePacket.payload); } break; case PacketType.Connected: { FinishHandShake(); } break; } }
private void OnChallengeResponse(IPEndPoint iPEndPoint, Stream stream) { Debug.Log("OnChallengeResponse"); ChallengeResponsePacket challengeResponsePacket = new ChallengeResponsePacket(); challengeResponsePacket.Deserialize(stream); CheckResultForConnection(iPEndPoint, challengeResponsePacket.payload); }
void SendChallengeResponse() { Debug.Log("Enviando Challenge Response"); ChallengeResponsePacket packet = new ChallengeResponsePacket(); packet.payload = challengeResolved; PacketsManager.Instance.SendPacket(packet, objectId); }
private void SendChallengeResponse(ulong clientSalt, ulong serverSalt) { Debug.Log("Sending challenge response"); ChallengeResponsePacket challengeResponsePacket = new ChallengeResponsePacket(); challengeResponsePacket.payload.result = clientSalt ^ serverSalt; SendToServer(challengeResponsePacket); }
void SendChallengeResponse() { ChallengeResponsePacket challengeResponsePacket = new ChallengeResponsePacket(); ChallengeResponseData challengeResponseData; challengeResponseData.result = challengeResultGeneratedByClient; challengeResponsePacket.Payload = challengeResponseData; PacketsManager.Instance.SendPacket(challengeResponsePacket); }
public void ReceivingChallengeResponse(Stream stream, IPEndPoint iPEnd) { if (NetworkManager.Instance.isServer) { ChallengeResponsePacket responsePacket = new ChallengeResponsePacket(); responsePacket.Deserialize(stream); if (NetworkManager.Instance.ipToId.ContainsKey(iPEnd)) { Client client = NetworkManager.Instance.clients[NetworkManager.Instance.ipToId[iPEnd]]; challengeResult = client._clientSalt ^ client._serverSalt; if (responsePacket.payload.result == challengeResult) { client.state = Client.ClientConnection.Connected; SendConnected(client._id, iPEnd); } } } }
public void TestChallengeResponsePacket() { Random rnd = new Random(0); ulong clientRandom = (ulong)rnd.Next(int.MaxValue); ulong serverRandom = (ulong)rnd.Next(int.MaxValue); ulong challengeResponse = (ulong)rnd.Next(int.MaxValue); ChallengeResponsePacket packet1 = new ChallengeResponsePacket(clientRandom, serverRandom, challengeResponse); byte[] output = new byte[1024]; int written = packet1.Write(output, null); ChallengeResponsePacket packet2 = new ChallengeResponsePacket(); packet2.Read(output, written); Assert.AreEqual(packet1.ClientRandom, packet2.ClientRandom); Assert.AreEqual(packet1.ServerRandom, packet2.ServerRandom); Assert.AreEqual(packet1.ChallengeResponse, packet2.ChallengeResponse); }
void OnChallengeResponse(Stream stream, IPEndPoint iPEndPoint) { if (NetworkManager.Instance.isServer) { ChallengeResponsePacket packet = new ChallengeResponsePacket(); packet.Deserialize(stream); if (ipToId.ContainsKey(iPEndPoint)) { Client client = clients[ipToId[iPEndPoint]]; long result = client.clientSalt ^ client.serverSalt; if (result == packet.payload.result) { client.state = Client.ClientState.Connected; SendConnected(client.id, iPEndPoint); } } } }
void OnRecieve(ushort type, Stream stream, IPEndPoint ip) { switch (type) { case (ushort)PacketType.ConnectionRequest: { ConnectionRequestPacket packet = new ConnectionRequestPacket(); packet.Deserialize(stream); AddNewClient(ip, packet.payload); break; } case (ushort)PacketType.ChallengeRequest: { onConectionRequest = false; ChallengeRequestPacket packet = new ChallengeRequestPacket(); packet.Deserialize(stream); serverDirt = packet.payload; DoChallenge(); break; } case (ushort)PacketType.ChallengeResponse: { ChallengeResponsePacket packet = new ChallengeResponsePacket(); packet.Deserialize(stream); CheckChallengeRecieved(ip, packet.payload); break; } case (ushort)PacketType.Conected: OnConected(); break; } }
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); } } }; }
void ReceiveConnectionData(ushort packetTypeIndex, IPEndPoint ipEndPoint, Stream stream) { switch ((PacketType)packetTypeIndex) { case PacketType.ChallengeRequest: if (!UdpNetworkManager.Instance.IsServer && clientConnectionState == ClientConnectionState.RequestingConnection) { ChallengeRequestPacket challengeRequestPacket = new ChallengeRequestPacket(); challengeRequestPacket.Deserialize(stream); challengeResultGeneratedByClient = saltGeneratedByClient ^ challengeRequestPacket.Payload.serverSalt; clientConnectionState = ClientConnectionState.SendingChallengeResponse; } break; case PacketType.ConnectionAccepted: if (!UdpNetworkManager.Instance.IsServer && clientConnectionState == ClientConnectionState.SendingChallengeResponse) { ConnectionAcceptedPacket connectionAcceptedPacket = new ConnectionAcceptedPacket(); connectionAcceptedPacket.Deserialize(stream); UdpNetworkManager.Instance.SetClientID(connectionAcceptedPacket.Payload.clientID); onClientConnectedCallback?.Invoke(connectionAcceptedPacket.Payload.clientsInSession); onClientConnectedCallback = null; clientConnectionState = ClientConnectionState.Connected; } break; case PacketType.ClientJoined: if (!UdpNetworkManager.Instance.IsServer && clientConnectionState == ClientConnectionState.Connected) { ClientJoinedPacket clientJoinedPacket = new ClientJoinedPacket(); clientJoinedPacket.Deserialize(stream); OnOtherClientJoined.Invoke(clientJoinedPacket.Payload.clientID); } break; case PacketType.ConnectionRequest: if (UdpNetworkManager.Instance.IsServer && !udpClientsIDs.ContainsKey(ipEndPoint)) { if (!udpPendingClientsData.ContainsKey(ipEndPoint)) { ConnectionRequestPacket connectionRequestPacket = new ConnectionRequestPacket(); connectionRequestPacket.Deserialize(stream); AddPendingClient(ipEndPoint, connectionRequestPacket.Payload.clientSalt); } UdpPendingClientData udpPendingClientData = udpPendingClientsData[ipEndPoint]; SendChallengeRequest(udpPendingClientData); } break; case PacketType.ChallengeResponse: if (UdpNetworkManager.Instance.IsServer) { if (udpPendingClientsData.ContainsKey(ipEndPoint)) { ChallengeResponsePacket challengeResponsePacket = new ChallengeResponsePacket(); UdpPendingClientData udpPendingClientData = udpPendingClientsData[ipEndPoint]; challengeResponsePacket.Deserialize(stream); long serverResult = udpPendingClientData.clientSalt ^ udpPendingClientData.serverSalt; if (challengeResponsePacket.Payload.result == serverResult) { ClientJoinedPacket clientJoinedPacket = new ClientJoinedPacket(); ClientJoinedData clientJoinedData; clientJoinedData.clientID = ClientID; clientJoinedPacket.Payload = clientJoinedData; PacketsManager.Instance.SendPacket(clientJoinedPacket, null, 0, 0, reliable: true); AddClient(ipEndPoint); RemovePendingClient(ipEndPoint); OnClientAddedByServer?.Invoke(udpClientsIDs[ipEndPoint]); } } if (udpClientsIDs.ContainsKey(ipEndPoint)) { SendConnectionAccepted(udpClientsData[udpClientsIDs[ipEndPoint]]); } } break; } }
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; } }