Improve certificate validation registration

Fixed: Certificate validation during startup
Fixed: Errors removing Windows service

Closes #3037
Closes #3038
pull/3072/head
Mark McDowall 6 years ago
parent 04850331ce
commit 0911abcfc0

@ -1168,7 +1168,7 @@
<Compile Include="RootFolders\UnmappedFolder.cs" /> <Compile Include="RootFolders\UnmappedFolder.cs" />
<Compile Include="Hashing.cs" /> <Compile Include="Hashing.cs" />
<Compile Include="Security\CertificateValidationType.cs" /> <Compile Include="Security\CertificateValidationType.cs" />
<Compile Include="Security\X509CertificateValidationPolicy.cs" /> <Compile Include="Security\X509CertificateValidationService.cs" />
<Compile Include="SeriesStats\SeasonStatistics.cs" /> <Compile Include="SeriesStats\SeasonStatistics.cs" />
<Compile Include="SeriesStats\SeriesStatistics.cs" /> <Compile Include="SeriesStats\SeriesStatistics.cs" />
<Compile Include="SeriesStats\SeriesStatisticsRepository.cs" /> <Compile Include="SeriesStats\SeriesStatisticsRepository.cs" />

@ -5,30 +5,22 @@ using System.Security.Cryptography.X509Certificates;
using NLog; using NLog;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging.Events;
namespace NzbDrone.Core.Security namespace NzbDrone.Core.Security
{ {
public interface IX509CertificateValidationPolicy public class X509CertificateValidationService : IHandle<ApplicationStartedEvent>
{
void Register();
}
public class X509CertificateValidationPolicy : IX509CertificateValidationPolicy
{ {
private readonly IConfigService _configService; private readonly IConfigService _configService;
private readonly Logger _logger; private readonly Logger _logger;
public X509CertificateValidationPolicy(IConfigService configService, Logger logger) public X509CertificateValidationService(IConfigService configService, Logger logger)
{ {
_configService = configService; _configService = configService;
_logger = logger; _logger = logger;
} }
public void Register()
{
ServicePointManager.ServerCertificateValidationCallback = ShouldByPassValidationError;
}
private bool ShouldByPassValidationError(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) private bool ShouldByPassValidationError(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{ {
var request = sender as HttpWebRequest; var request = sender as HttpWebRequest;
@ -38,11 +30,10 @@ namespace NzbDrone.Core.Security
return true; return true;
} }
var req = sender as HttpWebRequest;
var cert2 = certificate as X509Certificate2; var cert2 = certificate as X509Certificate2;
if (cert2 != null && req != null && cert2.SignatureAlgorithm.FriendlyName == "md5RSA") if (cert2 != null && request != null && 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.", req.RequestUri.Authority); _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.", request.RequestUri.Authority);
} }
if (sslPolicyErrors == SslPolicyErrors.None) if (sslPolicyErrors == SslPolicyErrors.None)
@ -50,7 +41,7 @@ namespace NzbDrone.Core.Security
return true; return true;
} }
var host = Dns.GetHostEntry(req.Host); var ipAddresses = GetIPAddresses(request.Host);
var certificateValidation = _configService.CertificateValidation; var certificateValidation = _configService.CertificateValidation;
if (certificateValidation == CertificateValidationType.Disabled) if (certificateValidation == CertificateValidationType.Disabled)
@ -59,7 +50,7 @@ namespace NzbDrone.Core.Security
} }
if (certificateValidation == CertificateValidationType.DisabledForLocalAddresses && if (certificateValidation == CertificateValidationType.DisabledForLocalAddresses &&
host.AddressList.All(i => i.IsIPv6LinkLocal || i.IsLocalAddress())) ipAddresses.All(i => i.IsIPv6LinkLocal || i.IsLocalAddress()))
{ {
return true; return true;
} }
@ -69,5 +60,20 @@ namespace NzbDrone.Core.Security
return false; return false;
} }
private IPAddress[] GetIPAddresses(string host)
{
if (IPAddress.TryParse(host, out var ipAddress))
{
return new []{ ipAddress };
}
return Dns.GetHostEntry(host).AddressList;
}
public void Handle(ApplicationStartedEvent message)
{
ServicePointManager.ServerCertificateValidationCallback = ShouldByPassValidationError;
}
} }
} }

@ -9,7 +9,6 @@ using NzbDrone.Common.Instrumentation;
using NzbDrone.Common.Processes; using NzbDrone.Common.Processes;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.Instrumentation; using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Security;
namespace NzbDrone.Host namespace NzbDrone.Host
{ {
@ -36,7 +35,6 @@ namespace NzbDrone.Host
var appMode = GetApplicationMode(startupContext); var appMode = GetApplicationMode(startupContext);
Start(appMode, startupContext); Start(appMode, startupContext);
_container.Resolve<IX509CertificateValidationPolicy>().Register();
if (startCallback != null) if (startCallback != null)
{ {

Loading…
Cancel
Save