6262# a server to connect to".
6363my $DERIVE_SIEVE_SERVER = 1;
6464
65+ # Command used for generating local-side listings.
6566my @cmd_localfs_ls = qw( ls -C ) ;
6667
68+ # Unset this to disable probing for SSL certs and just use whatever is
69+ # set above in %ssl_options.
6770my $SEARCH_FOR_CERTS_DIR_IF_NEEDED = 1;
6871
6972# You can override this to a particular path; is only used to find default
@@ -1806,6 +1809,42 @@ sub tilde_expand
18061809 return ($more and wantarray ) ? ($path , $tilded , $home ) : $path ;
18071810}
18081811
1812+ # Given a directory, the fact of its existence doesn't mean it's usable for
1813+ # OpenSSL certs; it could have been created by an installer but never used. If
1814+ # it's usable, then there will be hash symlinks therein. Each is 8 hex chars,
1815+ # a dot and then a sequence number starting at 0, to handle hash collisions.
1816+ # So, if there are no (symlinks to) files matching *.0 then although the dir
1817+ # exists, it's unitialised cruft. If none of the symlinks are resolvable, it's
1818+ # also cruft.
1819+ #
1820+ # Theoretically, a system might try to make the dir unreadable-but-executable
1821+ # so that it becomes an oracle that can be asked if a given cert should be
1822+ # trusted. That approach of self-mistrust is not supported: if you have such a
1823+ # system, report it and we can add an option to disable the contents probe.
1824+ sub confirm_valid_sslcerts_dir
1825+ {
1826+ my $dir = shift ;
1827+ die " internal error" unless defined $dir ;
1828+ return 0 unless -e $dir ;
1829+ unless (-d $dir ) {
1830+ debug(" setup: not a directory: $dir " );
1831+ return 0;
1832+ }
1833+ unless (opendir (DIR, $dir )) {
1834+ debug(" setup: unable to opendir($dir ): $! " );
1835+ return 0;
1836+ }
1837+ my @some_entries = grep /^[^.].+\.0\z/, readdir (DIR);
1838+ # while opendir failing is likely permissions, closedir
1839+ # failing is the system failing badly.
1840+ closedir (DIR) or die " closedir($dir ) failed: $! \n " ;
1841+ foreach my $entry (@some_entries ) {
1842+ return 1 if -f File::Spec-> catfile($dir , $entry );
1843+ }
1844+ debug(" setup: found no files named for cert-hashes, rejecting dir [$dir ]" );
1845+ return 0;
1846+ }
1847+
18091848sub fixup_ssl_configuration
18101849{
18111850 return unless $SEARCH_FOR_CERTS_DIR_IF_NEEDED ;
@@ -1816,25 +1855,37 @@ sub fixup_ssl_configuration
18161855
18171856 if (defined $OPENSSL_COMMAND ) {
18181857 debug " setup: Need to find SSL_ca_path, trying to ask openssl" ;
1819- my $found = 0 ;
1858+ my $found = undef ;
18201859 # protect against openssl command not existing
1821- open (my $olderr , " >&STDERR" );
1860+ open (my $olderr , " >&STDERR" ) or die " failed to dup(stderr): $! \n " ;
18221861 open (STDERR , File::Spec-> devnull());
1862+ my $oops = 0;
18231863 if (open (VERSION, ' -|' , $OPENSSL_COMMAND , ' version' , ' -d' )) {
1824- open (STDERR , " >&" , $olderr ); close ($olderr );
18251864 foreach (<VERSION>) {
18261865 next unless / ^OPENSSLDIR: "(.+)"\s *$ / ;
1827- $ssl_options {' SSL_ca_path' } = File::Spec-> catdir($1 , ' certs' );
1828- $found = 1;
1866+ $found = $1 ;
18291867 last ;
18301868 }
18311869 close (VERSION);
1832- debug(" setup: " . ($found
1833- ? " Have set SSL_ca_path to $ssl_options {'SSL_ca_path'}"
1834- : " Unable to get system SSL_ca_path" ));
1835- return ;
1870+ } else {
1871+ $oops = 1;
18361872 }
18371873 open (STDERR , " >&" , $olderr ); close ($olderr );
1874+ if ($oops ) {
1875+ debug(" setup: unable to run openssl" );
1876+ } elsif (defined $found ) {
1877+ my $attempt = File::Spec-> catdir($found , ' certs' );
1878+ if (confirm_valid_sslcerts_dir($attempt )) {
1879+ $ssl_options {' SSL_ca_path' } = $attempt ;
1880+ debug(" setup: Have set SSL_ca_path to $ssl_options {'SSL_ca_path'}" );
1881+ } else {
1882+ debug(" setup: found OPENSSLDIR but certs/ invalid" );
1883+ $found = undef ;
1884+ }
1885+ } else {
1886+ debug(" setup: openssl did not tell us OPENSSLDIR" );
1887+ }
1888+ return if defined $found ;
18381889 }
18391890
18401891 debug " setup: No OpenSSL, check some common locations" ;
@@ -1852,6 +1903,18 @@ sub fixup_ssl_configuration
18521903 debug(" setup: Have set SSL_ca_file to $ssl_options {'SSL_ca_file'}" );
18531904 return ;
18541905 }
1906+ my @alt_dir_locations = (
1907+ " /etc/ssl/certs" , # widespread
1908+ " /etc/x509/certs" ,
1909+ " /system/etc/security/cacerts" , # some Android
1910+ " /data/misc/keychain/cacerts-added" , # some Android
1911+ );
1912+ foreach my $loc (@alt_dir_locations ) {
1913+ confirm_valid_sslcerts_dir($loc ) or next ;
1914+ $ssl_options {' SSL_ca_path' } = $loc ;
1915+ debug(" setup: Have set SSL_ca_path to $ssl_options {'SSL_ca_path'}" );
1916+ return ;
1917+ }
18551918}
18561919
18571920# returns 1 "okay", 0 "definitely not available", undef "unknown"
0 commit comments