Lidarr/src/NzbDrone.Core/Security/X509CertificateValidationSe...

88 lines
2.7 KiB
C#

using System.Linq;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using NLog;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http.Dispatchers;
using NzbDrone.Core.Configuration;
namespace NzbDrone.Core.Security
{
public class X509CertificateValidationService : ICertificateValidationService
{
private readonly IConfigService _configService;
private readonly Logger _logger;
public X509CertificateValidationService(IConfigService configService, Logger logger)
{
_configService = configService;
_logger = logger;
}
public bool ShouldByPassValidationError(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
var targetHostName = string.Empty;
if (sender is not SslStream && sender is not string)
{
return true;
}
if (sender is SslStream request)
{
targetHostName = request.TargetHostName;
}
// Mailkit passes host in sender as string
if (sender is string stringHost)
{
targetHostName = stringHost;
}
if (certificate is X509Certificate2 cert2 && cert2.SignatureAlgorithm.FriendlyName == "md5RSA")
{
_logger.Error("https://{0} uses the obsolete md5 hash in it's https certificate, if that is your certificate, please (re)create certificate with better algorithm as soon as possible.", targetHostName);
}
if (sslPolicyErrors == SslPolicyErrors.None)
{
return true;
}
if (targetHostName == "localhost" || targetHostName == "127.0.0.1")
{
return true;
}
var ipAddresses = GetIPAddresses(targetHostName);
var certificateValidation = _configService.CertificateValidation;
if (certificateValidation == CertificateValidationType.Disabled)
{
return true;
}
if (certificateValidation == CertificateValidationType.DisabledForLocalAddresses &&
ipAddresses.All(i => i.IsLocalAddress()))
{
return true;
}
_logger.Error("Certificate validation for {0} failed. {1}", targetHostName, sslPolicyErrors);
return false;
}
private IPAddress[] GetIPAddresses(string host)
{
if (IPAddress.TryParse(host, out var ipAddress))
{
return new[] { ipAddress };
}
return Dns.GetHostEntry(host).AddressList;
}
}
}