From 9311e8673b5bc61fd22d4ce82be1f24dd734a9e7 Mon Sep 17 00:00:00 2001 From: George Clark Date: Sun, 4 Dec 2016 23:42:35 -0500 Subject: [PATCH] Item14205: More compatibility issues with IO::Socket::SSL Versions older than 1.973 don't support setting of both SSLCaPath and SSLCaFile. They are mutually exclusive. Newer versions support setting both. Ubuntu 14.04 ships with 1.965, so the autoconfig fails on that platform. Check the versions, and ensure that only one or the other are set with older versions of IO::Socket::SSL --- core/lib/Foswiki.spec | 2 + .../Configure/Checkers/Email/SSLCaPath.pm | 17 ++++++ .../Configure/Wizards/AutoConfigureEmail.pm | 12 ++-- .../Configure/Wizards/SSLCertificates.pm | 58 ++++++++++++++++--- 4 files changed, 75 insertions(+), 14 deletions(-) diff --git a/core/lib/Foswiki.spec b/core/lib/Foswiki.spec index b091b3ddd9..e56538d48f 100644 --- a/core/lib/Foswiki.spec +++ b/core/lib/Foswiki.spec @@ -1920,6 +1920,7 @@ $Foswiki::cfg{Email}{SSLVerifyServer} = $FALSE; # **PATH LABEL="Certificate Authorities Filename" \ # FEEDBACK="icon='ui-icon-shuffle';label='Guess certificate locations'; wizard='SSLCertificates'; method='guess_locations'"\ +# CHECK_ON_CHANGE="{Email}{SSLCaPath}" CHECK="also:{Email}{SSLCaPath}" \ # DISPLAY_IF="{EnableEmail} && /^Net::SMTP/.test({Email}{MailMethod}) && {Email}{SSLVerifyServer}"** # Specify the file used to verify the server certificate trust chain. # This is the list of root Certificate authorities that you trust to issue @@ -1931,6 +1932,7 @@ $Foswiki::cfg{Email}{SSLCaFile} = ''; # FEEDBACK='label="Validate Contents"; wizard="SSLCertificates"; method="validate";\ # title="Examines every file in the directory and verifies \ # that the contents look like certificates/and/or CRLs"' \ +# CHECK_ON_CHANGE="{Email}{SSLCaFile}" CHECK="also:{Email}{SSLCaFile}" \ # DISPLAY_IF="{EnableEmail} && /^Net::SMTP/.test({Email}{MailMethod}) && {Email}{SSLVerifyServer}"** # Specify the directory used to verify the server certificate trust chain. # This is the list of root Certificate authorities that you trust to issue diff --git a/core/lib/Foswiki/Configure/Checkers/Email/SSLCaPath.pm b/core/lib/Foswiki/Configure/Checkers/Email/SSLCaPath.pm index 4000e95268..424a5c7685 100644 --- a/core/lib/Foswiki/Configure/Checkers/Email/SSLCaPath.pm +++ b/core/lib/Foswiki/Configure/Checkers/Email/SSLCaPath.pm @@ -36,6 +36,23 @@ sub check_current_value { ); } + if ( $file && $path ) { + my @mods = ( + { + name => 'IO::Socket::SSL', + usage => +'Required if both ={Email}{SSLCaFile}= and ={Email}{SSLCaPath}= are set. Clear one or the other.', + minimumVersion => 1.973 + } + ); + Foswiki::Configure::Dependency::checkPerlModules(@mods); + foreach my $mod (@mods) { + if ( !$mod->{ok} ) { + $reporter->ERROR( $mod->{check_result} ); + } + } + } + my $cfile = $Foswiki::cfg{Email}{SSLCrlFile}; Foswiki::Configure::Load::expandValue($cfile); if ( $Foswiki::cfg{Email}{SSLCheckCRL} diff --git a/core/lib/Foswiki/Configure/Wizards/AutoConfigureEmail.pm b/core/lib/Foswiki/Configure/Wizards/AutoConfigureEmail.pm index b7ae6b937a..4f7903f8f5 100644 --- a/core/lib/Foswiki/Configure/Wizards/AutoConfigureEmail.pm +++ b/core/lib/Foswiki/Configure/Wizards/AutoConfigureEmail.pm @@ -115,11 +115,8 @@ sub _muteExec { { # Don't try to capture STDERR on FastCGI systems. it won't work. my $muter = Foswiki::Aux::MuteOut->new( - outFile => $outFile, - errFile => ( - defined $Foswiki::cfg{Engine} - && $Foswiki::cfg{Engine} =~ m/FastCGI$/ - ) ? undef : $errFile, + outFile => $outFile, + errFile => $errFile, reporter => $reporter, ); @@ -192,8 +189,11 @@ NOCERT $reporter->WARN( 'Debug log not captured in FCGI environments. Check web server error log for debugging information' ); + $ok = _autoconfigSMTP($reporter); + } + else { + ( $ok, $out, $err ) = _muteExec( \&_autoconfigSMTP, $reporter ); } - ( $ok, $out, $err ) = _muteExec( \&_autoconfigSMTP, $reporter ); $err =~ s/AUTH\s([^\s]+)\s.*$/AUTH $1 xxxxxxxxxxxxxxxx/mg if $err; unless ($ok) { diff --git a/core/lib/Foswiki/Configure/Wizards/SSLCertificates.pm b/core/lib/Foswiki/Configure/Wizards/SSLCertificates.pm index 9f851e9554..ba0fc6962a 100644 --- a/core/lib/Foswiki/Configure/Wizards/SSLCertificates.pm +++ b/core/lib/Foswiki/Configure/Wizards/SSLCertificates.pm @@ -28,6 +28,24 @@ Guess the locations of SSL Certificate files. sub guess_locations { my ( $this, $reporter ) = @_; + my $supportBoth = 1; # Support both CA File and CA Path. + +# SMELL: Versions of IO::Socket::SSL before 1.973 will croak if both CaFile and CaPath are set. + my @mods = ( + { + name => 'IO::Socket::SSL', + usage => +'Required if both ={Email}{SSLCaFile}= and ={Email}{SSLCaPath}= are set. Clear one or the other.', + minimumVersion => 1.973 + } + ); + Foswiki::Configure::Dependency::checkPerlModules(@mods); + foreach my $mod (@mods) { + if ( !$mod->{ok} ) { + $supportBoth = 0; + } + } + my @CERT_FILES = ( "/etc/pki/tls/certs/ca-bundle.crt", #Fedora/RHEL "/etc/ssl/certs/ca-certificates.crt", #Debian/Ubuntu/Gentoo etc. @@ -53,14 +71,14 @@ sub guess_locations { if ( $file || $path ) { $reporter->NOTE("Guessed from LWP settings"); $guessed = 1; - _setLocations( $reporter, $file, $path ); + _setLocations( $reporter, $file, $path, $supportBoth ); } else { ( $file, $path ) = @ENV{qw/HTTPS_CA_FILE HTTPS_CA_DIR/}; if ( $file || $path ) { $reporter->NOTE("Guessed from Crypt::SSLEay's settings"); $guessed = 1; - _setLocations( $reporter, $file, $path ); + _setLocations( $reporter, $file, $path, $supportBoth ); } else { if ( eval('require Mozilla::CA;') ) { @@ -68,7 +86,7 @@ sub guess_locations { if ($file) { $reporter->NOTE("Obtained from Mozilla::CA"); $guessed = 1; - _setLocations( $reporter, $file, $path ); + _setLocations( $reporter, $file, $path, $supportBoth ); } else { $reporter->WARN("Mozilla::CA is installed but has no file"); @@ -83,21 +101,19 @@ sub guess_locations { if ( -e $file && -r $file ) { $guessed = 1; $reporter->NOTE("Guessed $file as the CA certificate bundle."); - _setLocations( $reporter, $file, $path ); + _setLocations( $reporter, $file, $path, $supportBoth ); last; } } -# SMELL: I've seen some errors that suggest that only File or Path should be specified -# but IO::Socket::SSL docs clearly state both are acceptable. -#return undef if ($guessed); + return undef if ( $guessed && !$supportBoth ); # First see if the linux default path work foreach $path (@CERT_DIRS) { if ( -d $path && -r $path ) { $reporter->NOTE("Guessed $path as the certificate directory."); $guessed = 1; - _setLocations( $reporter, $file, $path ); + _setLocations( $reporter, $file, $path, $supportBoth ); } } @@ -114,10 +130,36 @@ sub _setLocations { # my ( $reporter, $file, $path ) = @_ #$_[0]->WARN(Foswiki::Configure::Checker::GUESSED_MESSAGE); + + if ( + !$_[3] + && ( $Foswiki::cfg{Email}{SSLCaFile} + || $Foswiki::cfg{Email}{SSLCaPath} ) + ) + { + $_[0]->WARN( +'Obsolete version of IO::Socket::SSL installed: ={Email}{SSLCaFile}= and ={Email}{SSLCaPath}= must not both be set.' + ); + return; + } + if ( $_[1] ) { $Foswiki::cfg{Email}{SSLCaFile} = $_[1]; $_[0]->CHANGED('{Email}{SSLCaFile}'); } + + if ( + !$_[3] + && ( $Foswiki::cfg{Email}{SSLCaFile} + || $Foswiki::cfg{Email}{SSLCaPath} ) + ) + { + $_[0]->WARN( +'Obsolete version of IO::Socket::SSL installed: ={Email}{SSLCaFile}= and ={Email}{SSLCaPath}= must not both be set.' + ); + return; + } + if ( $_[2] ) { $Foswiki::cfg{Email}{SSLCaPath} = $_[2]; $_[0]->CHANGED('{Email}{SSLCaPath}');