72 lines
2.7 KiB
C#
72 lines
2.7 KiB
C#
using System.Text.Json;
|
|
|
|
namespace SGU.CredentialProvider;
|
|
|
|
internal sealed class ProviderSettings
|
|
{
|
|
private const int MaximumSettingsBytes = 16 * 1024;
|
|
|
|
public Uri BrokerEndpoint { get; init; } = new("https://sgu-auth.lci.lasalle.mx:8443/v1/authenticate");
|
|
|
|
public string DomainNetbios { get; init; } = "LCI";
|
|
|
|
public int TimeoutSeconds { get; init; } = 35;
|
|
|
|
public string ClientCertificateThumbprint { get; init; } = string.Empty;
|
|
|
|
public string ServerCertificateThumbprint { get; init; } = string.Empty;
|
|
|
|
public static string DefaultPath => Path.Combine(
|
|
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
|
|
"SGU",
|
|
"CredentialProvider",
|
|
"settings.json");
|
|
|
|
public static ProviderSettings Load(string? path = null)
|
|
{
|
|
path ??= Environment.GetEnvironmentVariable("SGU_CREDENTIAL_PROVIDER_CONFIG") ?? DefaultPath;
|
|
FileInfo file = new(path);
|
|
if (!file.Exists || file.Length is <= 0 or > MaximumSettingsBytes)
|
|
{
|
|
throw new InvalidOperationException("Credential Provider settings are missing or invalid.");
|
|
}
|
|
|
|
using FileStream stream = new(path, FileMode.Open, FileAccess.Read, FileShare.Read);
|
|
ProviderSettings settings = JsonSerializer.Deserialize<ProviderSettings>(stream, new JsonSerializerOptions
|
|
{
|
|
PropertyNameCaseInsensitive = true
|
|
}) ?? throw new InvalidOperationException("Credential Provider settings could not be read.");
|
|
settings.Validate();
|
|
return settings;
|
|
}
|
|
|
|
public void Validate()
|
|
{
|
|
if (!BrokerEndpoint.IsAbsoluteUri ||
|
|
BrokerEndpoint.Scheme != Uri.UriSchemeHttps ||
|
|
!string.IsNullOrEmpty(BrokerEndpoint.UserInfo))
|
|
{
|
|
throw new InvalidOperationException("BrokerEndpoint must be an absolute HTTPS URL without user information.");
|
|
}
|
|
|
|
if (!string.Equals(BrokerEndpoint.AbsolutePath.TrimEnd('/'), "/v1/authenticate", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
throw new InvalidOperationException("BrokerEndpoint must target /v1/authenticate.");
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(DomainNetbios) || TimeoutSeconds is < 2 or > 60)
|
|
{
|
|
throw new InvalidOperationException("DomainNetbios or TimeoutSeconds is invalid.");
|
|
}
|
|
|
|
if (NormalizeThumbprint(ClientCertificateThumbprint).Length != 40 ||
|
|
NormalizeThumbprint(ServerCertificateThumbprint).Length != 40)
|
|
{
|
|
throw new InvalidOperationException("Client and server SHA-1 certificate thumbprints are required.");
|
|
}
|
|
}
|
|
|
|
public static string NormalizeThumbprint(string value) =>
|
|
value.Replace(" ", string.Empty, StringComparison.Ordinal).ToUpperInvariant();
|
|
}
|