2021-11-13 21:10:42 +00:00
using System.Linq ;
2019-03-29 02:20:40 +00:00
using System.Net ;
using System.Net.Security ;
using System.Security.Cryptography.X509Certificates ;
using NLog ;
using NzbDrone.Common.Extensions ;
2021-11-13 21:10:42 +00:00
using NzbDrone.Common.Http.Dispatchers ;
2019-03-29 02:20:40 +00:00
using NzbDrone.Core.Configuration ;
namespace NzbDrone.Core.Security
{
2021-11-13 21:10:42 +00:00
public class X509CertificateValidationService : ICertificateValidationService
2019-03-29 02:20:40 +00:00
{
private readonly IConfigService _configService ;
private readonly Logger _logger ;
2019-04-11 02:34:21 +00:00
public X509CertificateValidationService ( IConfigService configService , Logger logger )
2019-03-29 02:20:40 +00:00
{
_configService = configService ;
_logger = logger ;
}
2021-11-13 21:10:42 +00:00
public bool ShouldByPassValidationError ( object sender , X509Certificate certificate , X509Chain chain , SslPolicyErrors sslPolicyErrors )
2019-03-29 02:20:40 +00:00
{
2021-11-13 21:10:42 +00:00
var targetHostName = string . Empty ;
2019-03-29 02:20:40 +00:00
2021-11-13 21:10:42 +00:00
if ( sender is not SslStream & & sender is not string )
2019-03-29 02:20:40 +00:00
{
return true ;
}
2021-11-13 21:10:42 +00:00
if ( sender is SslStream request )
2019-03-29 02:20:40 +00:00
{
2021-11-13 21:10:42 +00:00
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 ) ;
2019-03-29 02:20:40 +00:00
}
if ( sslPolicyErrors = = SslPolicyErrors . None )
{
return true ;
}
2021-11-13 21:10:42 +00:00
if ( targetHostName = = "localhost" | | targetHostName = = "127.0.0.1" )
2021-01-14 21:04:54 +00:00
{
return true ;
}
2021-11-13 21:10:42 +00:00
var ipAddresses = GetIPAddresses ( targetHostName ) ;
2019-03-29 02:20:40 +00:00
var certificateValidation = _configService . CertificateValidation ;
if ( certificateValidation = = CertificateValidationType . Disabled )
{
return true ;
}
2019-04-10 03:57:12 +00:00
if ( certificateValidation = = CertificateValidationType . DisabledForLocalAddresses & &
2020-04-27 21:58:35 +00:00
ipAddresses . All ( i = > i . IsLocalAddress ( ) ) )
2019-03-29 02:20:40 +00:00
{
return true ;
}
2021-11-13 21:10:42 +00:00
_logger . Error ( "Certificate validation for {0} failed. {1}" , targetHostName , sslPolicyErrors ) ;
2019-03-29 02:20:40 +00:00
return false ;
}
2019-04-11 02:34:21 +00:00
private IPAddress [ ] GetIPAddresses ( string host )
{
if ( IPAddress . TryParse ( host , out var ipAddress ) )
{
2021-08-03 04:43:28 +00:00
return new [ ] { ipAddress } ;
2019-04-11 02:34:21 +00:00
}
return Dns . GetHostEntry ( host ) . AddressList ;
}
2019-03-29 02:20:40 +00:00
}
}