]> git.deb.at Git - rhonda/impostor.git/commitdiff
Initial auth implementation
authorjs6pak <kubastaron@hotmail.com>
Fri, 2 Apr 2021 22:07:06 +0000 (00:07 +0200)
committerjs6pak <kubastaron@hotmail.com>
Fri, 2 Apr 2021 22:12:15 +0000 (00:12 +0200)
src/Impostor.Api/Net/Messages/Auth/Message01Complete.cs [new file with mode: 0644]
src/Impostor.Api/Net/Messages/Auth/MessageHandshake.cs [new file with mode: 0644]
src/Impostor.Server/Config/AuthServerConfig.cs [new file with mode: 0644]
src/Impostor.Server/Net/AuthService.cs [new file with mode: 0644]
src/Impostor.Server/Net/Matchmaker.cs
src/Impostor.Server/Program.cs

diff --git a/src/Impostor.Api/Net/Messages/Auth/Message01Complete.cs b/src/Impostor.Api/Net/Messages/Auth/Message01Complete.cs
new file mode 100644 (file)
index 0000000..2572f8c
--- /dev/null
@@ -0,0 +1,15 @@
+namespace Impostor.Api.Net.Messages.Auth
+{
+    public static class Message01Complete
+    {
+        public static void Serialize(IMessageWriter writer, uint nonce)
+        {
+            writer.WritePacked(nonce);
+        }
+
+        public static void Deserialize(IMessageReader reader, out uint nonce)
+        {
+            nonce = reader.ReadUInt32();
+        }
+    }
+}
diff --git a/src/Impostor.Api/Net/Messages/Auth/MessageHandshake.cs b/src/Impostor.Api/Net/Messages/Auth/MessageHandshake.cs
new file mode 100644 (file)
index 0000000..146d004
--- /dev/null
@@ -0,0 +1,14 @@
+using Impostor.Api.Innersloth;
+
+namespace Impostor.Api.Net.Messages.Auth
+{
+    public static class MessageHandshake
+    {
+        public static void Deserialize(IMessageReader reader, out int clientVersion, out Platforms platform, out string clientId)
+        {
+            clientVersion = reader.ReadInt32();
+            platform = (Platforms)reader.ReadByte();
+            clientId = reader.ReadString();
+        }
+    }
+}
diff --git a/src/Impostor.Server/Config/AuthServerConfig.cs b/src/Impostor.Server/Config/AuthServerConfig.cs
new file mode 100644 (file)
index 0000000..72c8efe
--- /dev/null
@@ -0,0 +1,27 @@
+using System.IO;
+using Impostor.Server.Utils;
+
+namespace Impostor.Server.Config
+{
+    internal class AuthServerConfig
+    {
+        public const string Section = "AuthServer";
+
+        private string? _resolvedListenIp;
+
+        public bool Enabled { get; set; } = false;
+
+        public string ListenIp { get; set; } = "0.0.0.0";
+
+        public ushort ListenPort { get; set; } = 22025;
+
+        public string Certificate { get; set; } = Path.Combine("dtls", "certificate.pem");
+
+        public string PrivateKey { get; set; } = Path.Combine("dtls", "key.pem");
+
+        public string ResolveListenIp()
+        {
+            return _resolvedListenIp ??= IpUtils.ResolveIp(ListenIp);
+        }
+    }
+}
diff --git a/src/Impostor.Server/Net/AuthService.cs b/src/Impostor.Server/Net/AuthService.cs
new file mode 100644 (file)
index 0000000..c8a95b2
--- /dev/null
@@ -0,0 +1,88 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Security.Cryptography;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading;
+using System.Threading.Tasks;
+using Impostor.Api.Events.Managers;
+using Impostor.Api.Net.Messages;
+using Impostor.Api.Net.Messages.Auth;
+using Impostor.Hazel;
+using Impostor.Hazel.Dtls;
+using Impostor.Server.Config;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.ObjectPool;
+using Microsoft.Extensions.Options;
+
+namespace Impostor.Server.Net
+{
+    internal class AuthService : IHostedService
+    {
+        private readonly ILogger<AuthService> _logger;
+        private readonly AuthServerConfig _config;
+        private readonly ObjectPool<MessageReader> _readerPool;
+        private readonly IEventManager _eventManager;
+        private DtlsConnectionListener? _connection;
+
+        public AuthService(ILogger<AuthService> logger, IOptions<AuthServerConfig> config, ObjectPool<MessageReader> readerPool, IEventManager eventManager)
+        {
+            _logger = logger;
+            _config = config.Value;
+            _readerPool = readerPool;
+            _eventManager = eventManager;
+        }
+
+        public async Task StartAsync(CancellationToken cancellationToken)
+        {
+            var endpoint = new IPEndPoint(IPAddress.Parse(_config.ResolveListenIp()), _config.ListenPort);
+
+            var mode = endpoint.AddressFamily switch
+            {
+                AddressFamily.InterNetwork => IPMode.IPv4,
+                AddressFamily.InterNetworkV6 => IPMode.IPv6,
+                _ => throw new InvalidOperationException(),
+            };
+
+            var rsa = RSA.Create();
+            rsa.ImportPkcs8PrivateKey(Convert.FromBase64String(string.Join(string.Empty, (await File.ReadAllLinesAsync(_config.PrivateKey, cancellationToken)).Where(x => !x.StartsWith("-----")))), out _);
+            var cert = new X509Certificate2(_config.Certificate).CopyWithPrivateKey(rsa);
+
+            _connection = new DtlsConnectionListener(endpoint, _readerPool, mode);
+            _connection.SetCertificate(cert);
+            _connection.NewConnection = ConnectionOnNewConnection;
+
+            await _connection.StartAsync();
+
+            _logger.LogInformation("Auth server is listening on {Address}:{Port}", endpoint.Address, endpoint.Port);
+        }
+
+        public async Task StopAsync(CancellationToken cancellationToken)
+        {
+            _logger.LogWarning("Auth server is shutting down!");
+
+            if (_connection != null)
+            {
+                await _connection.DisposeAsync();
+            }
+        }
+
+        private ValueTask ConnectionOnNewConnection(NewConnectionEventArgs e)
+        {
+            MessageHandshake.Deserialize(e.HandshakeData, out var clientVersion, out var platform, out var clientId);
+
+            _logger.LogTrace("New authentication request: {clientVersion}, {platform}, {clientId}", clientVersion, platform, clientId);
+
+            using var writer = MessageWriter.Get(MessageType.Reliable);
+
+            writer.StartMessage(1);
+            Message01Complete.Serialize(writer, (uint)RandomNumberGenerator.GetInt32(int.MinValue, int.MaxValue));
+            writer.EndMessage();
+
+            return e.Connection.SendAsync(writer);
+        }
+    }
+}
index e7ce3ace06c7893add9baa77c8fe4a3f2ab9e7f3..6af4f55993c5c10e2e86e13034b5f4aaee01a4ea 100644 (file)
@@ -61,7 +61,7 @@ namespace Impostor.Server.Net
         private async ValueTask OnNewConnection(NewConnectionEventArgs e)
         {
             // Handshake.
-            HandshakeC2S.Deserialize(e.HandshakeData, out var clientVersion, out var name);
+            HandshakeC2S.Deserialize(e.HandshakeData, out var clientVersion, out var name, out _);
 
             var connection = new HazelConnection(e.Connection, _connectionLogger);
 
index 03514d9020ab8611cab9370ac4587404d41fee88..d82a2362683d702054ebea884d56084b9e80f8a8 100644 (file)
@@ -117,6 +117,10 @@ namespace Impostor.Server
                         .GetSection(AnnouncementsServerConfig.Section)
                         .Get<AnnouncementsServerConfig>() ?? new AnnouncementsServerConfig();
 
+                    var authServer = host.Configuration
+                        .GetSection(AuthServerConfig.Section)
+                        .Get<AuthServerConfig>() ?? new AuthServerConfig();
+
                     services.AddSingleton<ServerEnvironment>();
                     services.AddSingleton<IDateTimeProvider, RealDateTimeProvider>();
 
@@ -124,6 +128,7 @@ namespace Impostor.Server
                     services.Configure<AntiCheatConfig>(host.Configuration.GetSection(AntiCheatConfig.Section));
                     services.Configure<ServerConfig>(host.Configuration.GetSection(ServerConfig.Section));
                     services.Configure<AnnouncementsServerConfig>(host.Configuration.GetSection(AnnouncementsServerConfig.Section));
+                    services.Configure<AuthServerConfig>(host.Configuration.GetSection(AuthServerConfig.Section));
                     services.Configure<ServerRedirectorConfig>(host.Configuration.GetSection(ServerRedirectorConfig.Section));
 
                     if (redirector.Enabled)
@@ -212,6 +217,11 @@ namespace Impostor.Server
                     {
                         services.AddHostedService<AnnouncementsService>();
                     }
+
+                    if (authServer.Enabled)
+                    {
+                        services.AddHostedService<AuthService>();
+                    }
                 })
                 .UseSerilog()
                 .UseConsoleLifetime()