From: js6pak Date: Fri, 2 Apr 2021 22:07:06 +0000 (+0200) Subject: Initial auth implementation X-Git-Tag: v1.4.0~14^2~15 X-Git-Url: https://git.deb.at/?a=commitdiff_plain;h=a39fae332551b3ebf1112d90d064dcbe2be2c626;p=rhonda%2Fimpostor.git Initial auth implementation --- diff --git a/src/Impostor.Api/Net/Messages/Auth/Message01Complete.cs b/src/Impostor.Api/Net/Messages/Auth/Message01Complete.cs new file mode 100644 index 0000000..2572f8c --- /dev/null +++ b/src/Impostor.Api/Net/Messages/Auth/Message01Complete.cs @@ -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 index 0000000..146d004 --- /dev/null +++ b/src/Impostor.Api/Net/Messages/Auth/MessageHandshake.cs @@ -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 index 0000000..72c8efe --- /dev/null +++ b/src/Impostor.Server/Config/AuthServerConfig.cs @@ -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 index 0000000..c8a95b2 --- /dev/null +++ b/src/Impostor.Server/Net/AuthService.cs @@ -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 _logger; + private readonly AuthServerConfig _config; + private readonly ObjectPool _readerPool; + private readonly IEventManager _eventManager; + private DtlsConnectionListener? _connection; + + public AuthService(ILogger logger, IOptions config, ObjectPool 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); + } + } +} diff --git a/src/Impostor.Server/Net/Matchmaker.cs b/src/Impostor.Server/Net/Matchmaker.cs index e7ce3ac..6af4f55 100644 --- a/src/Impostor.Server/Net/Matchmaker.cs +++ b/src/Impostor.Server/Net/Matchmaker.cs @@ -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); diff --git a/src/Impostor.Server/Program.cs b/src/Impostor.Server/Program.cs index 03514d9..d82a236 100644 --- a/src/Impostor.Server/Program.cs +++ b/src/Impostor.Server/Program.cs @@ -117,6 +117,10 @@ namespace Impostor.Server .GetSection(AnnouncementsServerConfig.Section) .Get() ?? new AnnouncementsServerConfig(); + var authServer = host.Configuration + .GetSection(AuthServerConfig.Section) + .Get() ?? new AuthServerConfig(); + services.AddSingleton(); services.AddSingleton(); @@ -124,6 +128,7 @@ namespace Impostor.Server services.Configure(host.Configuration.GetSection(AntiCheatConfig.Section)); services.Configure(host.Configuration.GetSection(ServerConfig.Section)); services.Configure(host.Configuration.GetSection(AnnouncementsServerConfig.Section)); + services.Configure(host.Configuration.GetSection(AuthServerConfig.Section)); services.Configure(host.Configuration.GetSection(ServerRedirectorConfig.Section)); if (redirector.Enabled) @@ -212,6 +217,11 @@ namespace Impostor.Server { services.AddHostedService(); } + + if (authServer.Enabled) + { + services.AddHostedService(); + } }) .UseSerilog() .UseConsoleLifetime()