From 11c291c105cc108c4bf12b15a2914e6afdd2d857 Mon Sep 17 00:00:00 2001 From: "Robin C. Ladiges" Date: Thu, 23 Mar 2023 01:16:11 +0100 Subject: [PATCH] fix: actually working ban functionality Changes: - ignore new sockets from banned IP addresses way earlier. - ignore all packets by banned profiles. Intentionally keeping the connection open instead of d/c banned clients. This is to prevent endless server logs due to automatically reconnecting clients. Before: Reconnecting clients aren't entering `ClientJoined` and therefore the d/c is only working on first connections. Effectively banned clients got a d/c and then automatically reconnected again without getting a d/c again. Therefore allowing them to play normally. --- Server/BanLists.cs | 1 + Server/Client.cs | 1 + Server/Program.cs | 3 --- Server/Server.cs | 22 +++++++++++++++++++++- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/Server/BanLists.cs b/Server/BanLists.cs index 7458389..6ce8fba 100644 --- a/Server/BanLists.cs +++ b/Server/BanLists.cs @@ -128,6 +128,7 @@ public static class BanLists { public static void Crash(Client user, bool permanent = false) { + user.Ignored = true; Task.Run(async () => { await user.Send(new ChangeStagePacket { Id = (permanent ? "$agogus/ban4lyfe" : "$among$us/cr4sh%"), diff --git a/Server/Client.cs b/Server/Client.cs index 5f3336f..9b7aa05 100644 --- a/Server/Client.cs +++ b/Server/Client.cs @@ -12,6 +12,7 @@ namespace Server; public class Client : IDisposable { public readonly ConcurrentDictionary Metadata = new ConcurrentDictionary(); // can be used to store any information about a player public bool Connected = false; + public bool Ignored = false; public CostumePacket? CurrentCostume = null; // required for proper client sync public string Name { get => Logger.Name; diff --git a/Server/Program.cs b/Server/Program.cs index 1ae5933..8bb3c7d 100644 --- a/Server/Program.cs +++ b/Server/Program.cs @@ -62,9 +62,6 @@ async Task LoadShines() await LoadShines(); server.ClientJoined += (c, _) => { - if (BanLists.Enabled && BanLists.IsClientBanned(c)) { - throw new Exception($"Banned player attempted join: {c.Name}"); - } c.Metadata["shineSync"] = new ConcurrentBag(); c.Metadata["loadedSave"] = false; c.Metadata["scenario"] = (byte?) 0; diff --git a/Server/Server.cs b/Server/Server.cs index cfb7091..0c01067 100644 --- a/Server/Server.cs +++ b/Server/Server.cs @@ -29,6 +29,11 @@ public class Server { Socket socket = token.HasValue ? await serverSocket.AcceptAsync(token.Value) : await serverSocket.AcceptAsync(); socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); + if (BanLists.Enabled && BanLists.IsIPv4Banned(((IPEndPoint) socket.RemoteEndPoint!).Address!)) { + Logger.Warn($"Ignoring banned IPv4 address {socket.RemoteEndPoint}"); + continue; + } + Logger.Warn($"Accepted connection for client {socket.RemoteEndPoint}"); try { @@ -64,7 +69,7 @@ public class Server { public static void FillPacket(PacketHeader header, T packet, Memory memory) where T : struct, IPacket { Span data = memory.Span; - + header.Serialize(data[..Constants.HeaderSize]); packet.Serialize(data[Constants.HeaderSize..]); } @@ -167,6 +172,11 @@ public class Server { break; } + if (client.Ignored) { + memory.Dispose(); + continue; + } + // connection initialization if (first) { first = false; @@ -174,6 +184,16 @@ public class Server { ConnectPacket connect = new ConnectPacket(); connect.Deserialize(memory.Memory.Span[packetRange]); + + if (BanLists.Enabled && BanLists.IsProfileBanned(header.Id)) { + client.Id = header.Id; + client.Name = connect.ClientName; + client.Ignored = true; + client.Logger.Warn($"Ignoring banned profile ID {header.Id}"); + memory.Dispose(); + continue; + } + lock (Clients) { if (Clients.Count(x => x.Connected) == Settings.Instance.Server.MaxPlayers) { client.Logger.Error($"Turned away as server is at max clients");