feat(gateway): detect HTTPS endpoints missing a certificate
This commit is contained in:
@@ -0,0 +1,37 @@
|
|||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
|
||||||
|
namespace ZB.MOM.WW.MxGateway.Server.Security.Tls;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Inspects the Kestrel configuration to decide whether the gateway must supply
|
||||||
|
/// a generated default certificate (an HTTPS endpoint exists with no certificate
|
||||||
|
/// of its own).
|
||||||
|
/// </summary>
|
||||||
|
public static class KestrelTlsInspector
|
||||||
|
{
|
||||||
|
public static bool RequiresGeneratedCertificate(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
IConfigurationSection endpoints = configuration.GetSection("Kestrel:Endpoints");
|
||||||
|
foreach (IConfigurationSection endpoint in endpoints.GetChildren())
|
||||||
|
{
|
||||||
|
string? url = endpoint["Url"];
|
||||||
|
if (string.IsNullOrWhiteSpace(url) ||
|
||||||
|
!url.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
IConfigurationSection certificate = endpoint.GetSection("Certificate");
|
||||||
|
bool hasOwnCertificate =
|
||||||
|
!string.IsNullOrWhiteSpace(certificate["Path"]) ||
|
||||||
|
!string.IsNullOrWhiteSpace(certificate["Subject"]);
|
||||||
|
|
||||||
|
if (!hasOwnCertificate)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using ZB.MOM.WW.MxGateway.Server.Security.Tls;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace ZB.MOM.WW.MxGateway.Tests.Security.Tls;
|
||||||
|
|
||||||
|
public sealed class KestrelTlsInspectorTests
|
||||||
|
{
|
||||||
|
private static IConfiguration Config(params (string Key, string Value)[] entries)
|
||||||
|
=> new ConfigurationBuilder()
|
||||||
|
.AddInMemoryCollection(entries.ToDictionary(e => e.Key, e => (string?)e.Value))
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void RequiresGeneratedCertificate_True_WhenHttpsEndpointHasNoCertificate()
|
||||||
|
=> Assert.True(KestrelTlsInspector.RequiresGeneratedCertificate(
|
||||||
|
Config(("Kestrel:Endpoints:Http:Url", "https://0.0.0.0:5120"))));
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void RequiresGeneratedCertificate_False_WhenAllEndpointsPlaintext()
|
||||||
|
=> Assert.False(KestrelTlsInspector.RequiresGeneratedCertificate(
|
||||||
|
Config(("Kestrel:Endpoints:Http:Url", "http://0.0.0.0:5120"))));
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void RequiresGeneratedCertificate_False_WhenHttpsEndpointHasOwnCertificate()
|
||||||
|
=> Assert.False(KestrelTlsInspector.RequiresGeneratedCertificate(
|
||||||
|
Config(
|
||||||
|
("Kestrel:Endpoints:Http:Url", "https://0.0.0.0:5120"),
|
||||||
|
("Kestrel:Endpoints:Http:Certificate:Path", @"C:\certs\real.pfx"))));
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void RequiresGeneratedCertificate_False_WhenNoEndpointsConfigured()
|
||||||
|
=> Assert.False(KestrelTlsInspector.RequiresGeneratedCertificate(Config()));
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user