Check ssl cert for remote hosts.

This commit is contained in:
Fabian
2023-07-16 19:03:33 +02:00
parent 4e6811cfaa
commit ca332be631
2 changed files with 54 additions and 6 deletions

View File

@@ -2,6 +2,10 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.CommandLine.Parsing;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using static Arctium.WoW.Launcher.Misc.Helpers;
namespace Arctium.WoW.Launcher;
@@ -87,14 +91,17 @@ static class Launcher
}
var configPath = $"{gameFolder}/WTF/{commandLineResult.GetValueForOption(LaunchOptions.GameConfig)}";
(string IPAddress, string HostName, int Port) portal = new();
if (!File.Exists(configPath))
LaunchOptions.IsDevModeAllowed = false;
else
{
var config = File.ReadAllText(configPath);
portal = ParsePortal(config);
LaunchOptions.IsDevModeAllowed = IsDevModeAllowed(ipFilter, config);
LaunchOptions.IsDevModeAllowed = IsDevModeAllowed(ipFilter, portal.IPAddress);
}
if (!LaunchOptions.IsDevModeAllowed)
@@ -106,6 +113,46 @@ static class Launcher
Console.WriteLine($"Developer mode: {(devModeEnabled ? "Enabled" : "Disabled")}");
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Gray;
// Check for valid certificate when dev mode is disabled.
if (!devModeEnabled)
{
try
{
var tcpClient = new TcpClient(portal.HostName, portal.Port);
var sslStream = new SslStream(tcpClient.GetStream(), false,
(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) =>
{
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
// Redirect to the trusted cert warning.
throw new AuthenticationException();
},
null
);
sslStream.AuthenticateAsClient("portal.HostName");
}
catch (SocketException)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"{portal.HostName}:{portal.Port} is offline.");
Console.ResetColor();
return string.Empty;
}
catch (AuthenticationException)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine($"Server with host name {portal.HostName} does not have a trusted certificate attached.");
Console.WriteLine("If you are the server owner be sure to generate one and replace the default bnet server certificate.");
Console.WriteLine("One way to generate one is through Let's Encrypt.");
Console.ResetColor();
return string.Empty;
}
}
return gameBinaryPath;
}
@@ -314,7 +361,7 @@ static class Launcher
return false;
}
static bool IsDevModeAllowed(IPFilter ipFilter, string config) => ipFilter.IsInRange(ParsePortal(config));
static bool IsDevModeAllowed(IPFilter ipFilter, string portalIP) => ipFilter.IsInRange(portalIP);
static long GenerateAuthSeedFunctionPatch(WinMemory memory, long modulusOffset)
{

View File

@@ -45,7 +45,7 @@ static class Helpers
Console.WriteLine($"Operating System: {RuntimeInformation.OSDescription}");
}
public static ReadOnlySpan<char> ParsePortal(string config)
public static (string IPAddress, string HostName, int Port) ParsePortal(string config)
{
const string portalKey = "SET portal";
@@ -68,25 +68,26 @@ static class Helpers
var portalSpan = config.AsSpan(startQuoteIndex + 1, portalLength);
var colonIndex = portalSpan.IndexOf(':');
var ipSpan = colonIndex != -1 ? portalSpan[..colonIndex] : portalSpan;
var port = colonIndex != -1 ? int.Parse(portalSpan[colonIndex..]) : 1119;
var portalString = ipSpan.ToString().Trim();
try
{
if (IPAddress.TryParse(portalString, out var ipAddress))
return ipAddress.ToString().AsSpan();
return (ipAddress.ToString(), portalString, port);
var ipv4Address = Dns.GetHostAddresses(portalString).FirstOrDefault(a => a.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork);
if (ipv4Address == null)
throw new Exception("No IPv4 address found for the provided hostname.");
return ipv4Address.ToString().AsSpan();
return (ipv4Address.ToString(), portalString, port);
}
catch (SocketException)
{
Console.WriteLine("No valid portal found. Dev (Local) mode disabled.");
return string.Empty.AsSpan();
return (string.Empty, string.Empty, port);
}
}
}