Hello community,

here is the log from the commit of package perl-IO-Socket-SSL for 
openSUSE:Factory checked in at 2014-03-27 06:08:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-IO-Socket-SSL (Old)
 and      /work/SRC/openSUSE:Factory/.perl-IO-Socket-SSL.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "perl-IO-Socket-SSL"

Changes:
--------
--- /work/SRC/openSUSE:Factory/perl-IO-Socket-SSL/perl-IO-Socket-SSL.changes    
2014-02-12 17:32:13.000000000 +0100
+++ 
/work/SRC/openSUSE:Factory/.perl-IO-Socket-SSL.new/perl-IO-Socket-SSL.changes   
    2014-03-27 06:08:53.000000000 +0100
@@ -1,0 +2,27 @@
+Sat Mar 22 19:05:20 UTC 2014 - [email protected]
+
+- updated to 1.970
+ - fix rt#93987 by making sure sub default_ca does use a local $_ and not a
+   version of an outer scope which might be read-only.  Thanks to gshank
+ 1.969 2014/03/13
+ - fix set_defaults to match documentation regarding short names
+ - new function set_args_filter_hack to make it possible to override bad SSL
+   settings from other code at the last moment.
+ - determine default_ca on module load (and not on first use in each thread)
+ - don't try default hostname verification if verify_mode 0
+ - fix hostname verification when reusing context
+ 1.968 2014/03/13
+ - BEHAVIOR CHANGE: removed implicit defaults of certs/server-{cert,key}.pem
+   for SSL_{cert,key}_file and ca/,certs/my-ca.pem for SSL_ca_file.
+   These defaults were depreceated since 1.951 (2013/7/3).
+ - Usable CA verification path on Windows etc:
+   Do not use Net::SSLeay::CTX_set_default_verify_paths any longer to set
+   system/build dependended default verification path, because there was no
+   way to retrieve these default values and check if they contained usable
+   CA. Instead re-implement the same algorithm and export the results with
+   public function default_ca() and make it possible to overwrite it.
+   Also check for usable verification path during build.
+   If no usable path are detected require Mozilla::CA at build and try to
+   use it at runtime.
+
+-------------------------------------------------------------------

Old:
----
  IO-Socket-SSL-1.967.tar.gz

New:
----
  IO-Socket-SSL-1.970.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ perl-IO-Socket-SSL.spec ++++++
--- /var/tmp/diff_new_pack.rJkw6c/_old  2014-03-27 06:08:54.000000000 +0100
+++ /var/tmp/diff_new_pack.rJkw6c/_new  2014-03-27 06:08:54.000000000 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           perl-IO-Socket-SSL
-Version:        1.967
+Version:        1.970
 Release:        0
 %define cpan_name IO-Socket-SSL
 Summary:        Nearly transparent SSL encapsulation for IO::Socket::INET.

++++++ IO-Socket-SSL-1.967.tar.gz -> IO-Socket-SSL-1.970.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/IO-Socket-SSL-1.967/Changes 
new/IO-Socket-SSL-1.970/Changes
--- old/IO-Socket-SSL-1.967/Changes     2014-02-06 22:22:04.000000000 +0100
+++ new/IO-Socket-SSL-1.970/Changes     2014-03-19 06:01:41.000000000 +0100
@@ -1,3 +1,26 @@
+1.970 2014/03/19
+- fix rt#93987 by making sure sub default_ca does use a local $_ and not a
+  version of an outer scope which might be read-only.  Thanks to gshank
+1.969 2014/03/13
+- fix set_defaults to match documentation regarding short names
+- new function set_args_filter_hack to make it possible to override bad SSL
+  settings from other code at the last moment.
+- determine default_ca on module load (and not on first use in each thread)
+- don't try default hostname verification if verify_mode 0
+- fix hostname verification when reusing context
+1.968 2014/03/13
+- BEHAVIOR CHANGE: removed implicit defaults of certs/server-{cert,key}.pem
+  for SSL_{cert,key}_file and ca/,certs/my-ca.pem for SSL_ca_file.
+  These defaults were depreceated since 1.951 (2013/7/3).
+- Usable CA verification path on Windows etc:
+  Do not use Net::SSLeay::CTX_set_default_verify_paths any longer to set
+  system/build dependended default verification path, because there was no
+  way to retrieve these default values and check if they contained usable
+  CA. Instead re-implement the same algorithm and export the results with
+  public function default_ca() and make it possible to overwrite it.
+  Also check for usable verification path during build.
+  If no usable path are detected require Mozilla::CA at build and try to
+  use it at runtime.
 1.967 2014/02/06
 - verify the hostname inside a certificate by default with a superset of
   common verification schemes instead of not verifying identity at all.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/IO-Socket-SSL-1.967/MANIFEST 
new/IO-Socket-SSL-1.970/MANIFEST
--- old/IO-Socket-SSL-1.967/MANIFEST    2014-02-06 23:00:55.000000000 +0100
+++ new/IO-Socket-SSL-1.970/MANIFEST    2014-03-19 06:02:43.000000000 +0100
@@ -51,6 +51,7 @@
 t/mitm.t
 t/ecdhe.t
 t/verify_fingerprint.t
+t/external/usable_ca.t
 util/export_certs.pl
 META.yml                                 Module YAML meta-data (added by 
MakeMaker)
 META.json                                Module JSON meta-data (added by 
MakeMaker)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/IO-Socket-SSL-1.967/META.json 
new/IO-Socket-SSL-1.970/META.json
--- old/IO-Socket-SSL-1.967/META.json   2014-02-06 23:00:55.000000000 +0100
+++ new/IO-Socket-SSL-1.970/META.json   2014-03-19 06:02:43.000000000 +0100
@@ -1,7 +1,7 @@
 {
    "abstract" : "Nearly transparent SSL encapsulation for IO::Socket::INET.",
    "author" : [
-      "Steffen Ullrich <sullr.org>, Peter Behroozi, Marko Asplund"
+      "Steffen Ullrich <[email protected]>, Peter Behroozi, Marko Asplund"
    ],
    "dynamic_config" : 1,
    "generated_by" : "ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter 
version 2.120921",
@@ -50,5 +50,5 @@
          "url" : "https://github.com/noxxi/p5-io-socket-ssl";
       }
    },
-   "version" : "1.967"
+   "version" : "1.970"
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/IO-Socket-SSL-1.967/META.yml 
new/IO-Socket-SSL-1.970/META.yml
--- old/IO-Socket-SSL-1.967/META.yml    2014-02-06 23:00:55.000000000 +0100
+++ new/IO-Socket-SSL-1.970/META.yml    2014-03-19 06:02:43.000000000 +0100
@@ -1,7 +1,7 @@
 ---
 abstract: 'Nearly transparent SSL encapsulation for IO::Socket::INET.'
 author:
-  - 'Steffen Ullrich <sullr.org>, Peter Behroozi, Marko Asplund'
+  - 'Steffen Ullrich <[email protected]>, Peter Behroozi, Marko Asplund'
 build_requires:
   ExtUtils::MakeMaker: 0
 configure_requires:
@@ -25,4 +25,4 @@
   homepage: https://github.com/noxxi/p5-io-socket-ssl
   license: http://dev.perl.org/licenses/
   repository: https://github.com/noxxi/p5-io-socket-ssl
-version: 1.967
+version: 1.970
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/IO-Socket-SSL-1.967/Makefile.PL 
new/IO-Socket-SSL-1.970/Makefile.PL
--- old/IO-Socket-SSL-1.967/Makefile.PL 2014-02-05 20:30:16.000000000 +0100
+++ new/IO-Socket-SSL-1.970/Makefile.PL 2014-03-13 07:14:46.000000000 +0100
@@ -76,21 +76,60 @@
 EOM
 }
 
+# check if we have usable CA store
+# on windows we might need to install Mozilla::CA
+# settings for default path from openssl crypto/cryptlib.h
+my %usable_ca;
+{
+    my $openssldir = eval { 
+       require Net::SSLeay;
+       Net::SSLeay::SSLeay_version(5) =~m{^OPENSSLDIR: "(.+)"$} && $1 || '';
+    };
+    my $dir = $ENV{SSL_CERT_DIR} 
+       || ( $^O =~m{vms}i ? "SSLCERTS:":"$openssldir/certs" );
+    if ( opendir(my $dh,$dir)) {
+       FILES: for my $f (  grep { m{^[a-f\d]{8}(\.\d+)?$} } readdir($dh) ) {
+           open( my $fh,'<',"$dir/$f") or next;
+           while (<$fh>) {
+               m{^-+BEGIN CERTIFICATE-} or next;
+               $usable_ca{SSL_ca_path} = $dir;
+               last FILES;
+           }
+       }
+    }
+    my $file = $ENV{SSL_CERT_FILE} 
+       || ( $^O =~m{vms}i ? "SSLCERTS:cert.pem":"$openssldir/cert.pem" );
+    if ( open(my $fh,'<',$file)) {
+       while (<$fh>) {
+           m{^-+BEGIN CERTIFICATE-} or next;
+           $usable_ca{SSL_ca_file} = $file;
+           last;
+       }
+    }
+}
+
+my $xt = prompt( "Should I do external tests?\n".
+    "These tests will fail if there is no internet connection or if a 
firewall\n".
+    "blocks some traffic, does SSL interception or if a HTTP proxy is 
needed.\n".
+    "[y/N]", 'n' );
+
 
 # See lib/ExtUtils/MakeMaker.pm for details of how to influence
 # the contents of the Makefile that is written.
 WriteMakefile(
     'NAME' => 'IO::Socket::SSL',
     'ABSTRACT' => 'Nearly transparent SSL encapsulation for IO::Socket::INET.',
-    'AUTHOR' => "Steffen Ullrich <[email protected]>, Peter Behroozi, Marko 
Asplund",
+    'AUTHOR' => 'Steffen Ullrich <[email protected]>, Peter Behroozi, Marko 
Asplund',
     'LICENSE' => 'perl',
     'DISTNAME' => 'IO-Socket-SSL',
     'VERSION_FROM' => 'lib/IO/Socket/SSL.pm',
     'PREREQ_PM' => {
        'Net::SSLeay' => 1.46,
        'Scalar::Util' => 0,
+       ! %usable_ca ? ( 'Mozilla::CA' => 0 ):(),
     },
     'dist' => { COMPRESS => 'gzip', SUFFIX => 'gz', },
+    $xt =~m{^y}i ? ( test => { TESTS => 't/*.t t/external/*.t' }):(),
     $ExtUtils::MakeMaker::VERSION >= 6.46 ? (
        'META_MERGE' => {
            resources => {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/IO-Socket-SSL-1.967/lib/IO/Socket/SSL.pm 
new/IO-Socket-SSL-1.970/lib/IO/Socket/SSL.pm
--- old/IO-Socket-SSL-1.967/lib/IO/Socket/SSL.pm        2014-02-06 
22:58:10.000000000 +0100
+++ new/IO-Socket-SSL-1.970/lib/IO/Socket/SSL.pm        2014-03-19 
06:01:55.000000000 +0100
@@ -20,7 +20,7 @@
 use Carp;
 use strict;
 
-our $VERSION = '1.967';
+our $VERSION = '1.970';
 
 use constant SSL_VERIFY_NONE => Net::SSLeay::VERIFY_NONE();
 use constant SSL_VERIFY_PEER => Net::SSLeay::VERIFY_PEER();
@@ -48,8 +48,8 @@
     SSL_check_crl => 0,
     SSL_version => 'SSLv23:!SSLv2',
     SSL_verify_callback => undef,
-    SSL_verifycn_scheme => undef,  # don't verify cn
-    SSL_verifycn_name => undef,    # use from PeerAddr/PeerHost
+    SSL_verifycn_scheme => undef,  # fallback cn verification
+    #SSL_verifycn_name => undef,   # use from PeerAddr/PeerHost - do not 
override in set_filter_args_hack 'use_defaults'
     SSL_npn_protocols => undef,    # meaning depends whether on server or 
client side
     SSL_cipher_list =>
        'EECDH+AESGCM+ECDSA EECDH+AESGCM EECDH+ECDSA +AES256 EECDH EDH+AESGCM '.
@@ -60,6 +60,10 @@
     %DEFAULT_SSL_ARGS,
     SSL_verify_mode => SSL_VERIFY_PEER,
 
+    SSL_ca_file => undef,
+    SSL_ca_path => undef,
+    default_ca(),
+
     # older versions of F5 BIG-IP hang when getting SSL client hello >255 bytes
     # http://support.f5.com/kb/en-us/solutions/public/13000/000/sol13037.html
     # http://guest:[email protected]/Ticket/Display.html?id=2771
@@ -70,7 +74,7 @@
     # RC4-SHA is already bad enough. Also, we have a different sort order
     # compared to IE11, because we put ciphers supporting forward secrecy on 
top
 
-    SSL_cipher_list => join(" ", 
+    SSL_cipher_list => join(" ",
        qw(
            ECDHE-ECDSA-AES128-GCM-SHA256
            ECDHE-ECDSA-AES128-SHA256
@@ -130,6 +134,9 @@
 my $GLOBAL_SSL_CLIENT_ARGS = {};
 my $GLOBAL_SSL_SERVER_ARGS = {};
 
+# hack which is used to filter bad settings from used modules
+my $FILTER_SSL_ARGS = undef;
+
 # non-XS Versions of Scalar::Util will fail
 BEGIN{
     local $SIG{__DIE__}; local $SIG{__WARN__}; # be silent
@@ -148,7 +155,7 @@
 }
 
 our $DEBUG;
-use vars qw(@ISA $SSL_ERROR @EXPORT );
+use vars qw(@ISA $SSL_ERROR @EXPORT);
 
 {
     # These constants will be used in $! at return from SSL_connect,
@@ -197,9 +204,8 @@
 
        # if we have IO::Socket::INET6 we will use this not IO::Socket::INET
        # because it can handle both IPv4 and IPv6
-       # require at least 2.55 because of
-       # https://rt.cpan.org/Ticket/Display.html?id=39550
-       } elsif( eval { require IO::Socket::INET6; 
IO::Socket::INET6->VERSION(2.55) } ) {
+       # require at least 2.62 because of several problems before that version
+       } elsif( eval { require IO::Socket::INET6; 
IO::Socket::INET6->VERSION(2.62) } ) {
            @ISA = qw(IO::Socket::INET6);
            constant->import( CAN_IPV6 => "IO::Socket::INET6" );
        } else {
@@ -266,6 +272,67 @@
     }
 }
 
+{
+    my %default_ca;
+    my $ca_detected; # 0: never detect, undef: need to (re)detect
+    my $openssldir;
+    sub default_ca {
+       if (@_) {
+           # user defined default CA or reset
+           if ( @_ > 1 ) {
+               %default_ca = @_;
+               $ca_detected  = 0;
+           } elsif ( my $path = shift ) {
+               %default_ca =
+                   -d $path ? ( SSL_ca_path => $path ) :
+                   -f $path ? ( SSL_ca_file => $path ) :
+                   die "no such file or directory $path";
+               $ca_detected  = 0;
+           } else {
+               $ca_detected = undef;
+           }
+       }
+       return %default_ca if defined $ca_detected;
+
+       $openssldir ||= eval {
+           require Net::SSLeay;
+           Net::SSLeay::SSLeay_version(5) =~m{^OPENSSLDIR: "(.+)"$} && $1 || 
'';
+       };
+
+       # (re)detect according to openssl crypto/cryptlib.h
+       my $dir = $ENV{SSL_CERT_DIR}
+           || ( $^O =~m{vms}i ? "SSLCERTS:":"$openssldir/certs" );
+       if ( opendir(my $dh,$dir)) {
+           FILES: for my $f (  grep { m{^[a-f\d]{8}(\.\d+)?$} } readdir($dh) ) 
{
+               open( my $fh,'<',"$dir/$f") or next;
+               local $_;
+               while (<$fh>) {
+                   m{^-+BEGIN CERTIFICATE-} or next;
+                   $default_ca{SSL_ca_path} = $dir;
+                   last FILES;
+               }
+           }
+       }
+       my $file = $ENV{SSL_CERT_FILE}
+           || ( $^O =~m{vms}i ? "SSLCERTS:cert.pem":"$openssldir/cert.pem" );
+       if ( open(my $fh,'<',$file)) {
+           local $_;
+           while (<$fh>) {
+               m{^-+BEGIN CERTIFICATE-} or next;
+               $default_ca{SSL_ca_file} = $file;
+               last;
+           }
+       }
+
+       $default_ca{SSL_ca_file} = Mozilla::CA::SSL_ca_file()
+           if ! %default_ca && eval { require Mozilla::CA };
+
+       $ca_detected = 1;
+       return %default_ca;
+    }
+}
+
+
 # Export some stuff
 # inet4|inet6|debug will be handled by myself, everything
 # else will be handled the Exporter way
@@ -346,12 +413,18 @@
        $is_server = $arg_hash->{SSL_server} = $arg_hash->{Listen} || 0;
     }
 
-    # add user defined defaults
-    %$arg_hash = (
+    # add user defined defaults, maybe after filtering
+    $FILTER_SSL_ARGS->($is_server,$arg_hash) if $FILTER_SSL_ARGS;
+    my %defaults = (
        %$GLOBAL_SSL_ARGS,
        $is_server ? %$GLOBAL_SSL_SERVER_ARGS : %$GLOBAL_SSL_CLIENT_ARGS,
-       %$arg_hash
     );
+    if ( $defaults{SSL_reuse_ctx} ) {
+       # ignore default context if there are args to override it
+       delete $defaults{SSL_reuse_ctx} 
+           if grep { m{^SSL_(?!verifycn_name)$} } keys %$arg_hash;
+    }
+    %$arg_hash = ( %defaults, %$arg_hash ) if %defaults;
 
     my $ctx = $arg_hash->{'SSL_reuse_ctx'};
     if ($ctx) {
@@ -462,6 +535,17 @@
        }
 
        $arg_hash->{PeerAddr} || $self->_update_peer;
+       if ( $ctx->{verify_name_ref} ) {
+           # need target name for update
+           my $host = $arg_hash->{SSL_verifycn_name};
+           if ( ! defined $host ) {
+               if ( $host = $arg_hash->{PeerHost} || $arg_hash->{PeerAddr} ) {
+                   $host =~s{:[a-zA-Z0-9_\-]+$}{};
+               }
+           }
+           ${$ctx->{verify_name_ref}} = $host;
+       }
+
        my $session = $ctx->session_cache( $arg_hash->{SSL_session_key} ?
            ( $arg_hash->{SSL_session_key},1 ) :
            ( $arg_hash->{PeerAddr}, $arg_hash->{PeerPort} )
@@ -958,7 +1042,7 @@
            while (1) {
                if ( $status & SSL_SENT_SHUTDOWN and
                    # don't care for received if fast shutdown
-                   $status & SSL_RECEIVED_SHUTDOWN 
+                   $status & SSL_RECEIVED_SHUTDOWN
                        || $stop_args->{SSL_fast_shutdown}) {
                    # shutdown complete
                    last;
@@ -1077,7 +1161,7 @@
            # upgrade to SSL failed, downgrade socket to original class
            if ( $original_class ) {
                bless($socket,$original_class);
-               $socket->blocking(0) if ! $was_blocking 
+               $socket->blocking(0) if ! $was_blocking
                    && $socket->can('blocking');
            }
            return;
@@ -1455,29 +1539,58 @@
     $GLOBAL_SSL_ARGS->{SSL_session_cache} = shift;
 }
 
-sub set_defaults {
-    my %args = @_;
-    while ( my ($k,$v) = each %args ) {
-       $k =~s{^(SSL_)?}{SSL_};
-       $GLOBAL_SSL_ARGS->{$k} = $v;
-    }
-}
-{ # deprecated API
-    no warnings;
-    *set_ctx_defaults = \&set_defaults;
-}
-sub set_client_defaults {
-    my %args = @_;
-    while ( my ($k,$v) = each %args ) {
-       $k =~s{^(SSL_)?}{SSL_};
-       $GLOBAL_SSL_CLIENT_ARGS->{$k} = $v;
-    }
-}
-sub set_server_defaults {
-    my %args = @_;
-    while ( my ($k,$v) = each %args ) {
-       $k =~s{^(SSL_)?}{SSL_};
-       $GLOBAL_SSL_SERVER_ARGS->{$k} = $v;
+
+{
+    my $set_defaults = sub {
+       my $args = shift;
+       for(my $i=0;$i<@$args;$i+=2 ) {
+           my ($k,$v) = @{$args}[$i,$i+1];
+           if ( $k =~m{^SSL_} ) {
+               $_->{$k} = $v for(@_);
+           } elsif ( $k =~m{^(name|scheme)$} ) {
+               $_->{"SSL_verifycn_$k"} = $v for (@_);
+           } elsif ( $k =~m{^(callback|mode)$} ) {
+               $_->{"SSL_verify_$k"} = $v for(@_);
+           } else {
+               $_->{"SSL_$k"} = $v for(@_);
+           }
+       }
+    };
+    sub set_defaults {
+       my %args = @_;
+       $set_defaults->(\@_,
+           $GLOBAL_SSL_ARGS,
+           $GLOBAL_SSL_CLIENT_ARGS,
+           $GLOBAL_SSL_SERVER_ARGS
+       );
+    }
+    { # deprecated API
+       no warnings;
+       *set_ctx_defaults = \&set_defaults;
+    }
+    sub set_client_defaults {
+       my %args = @_;
+       $set_defaults->(\@_, $GLOBAL_SSL_CLIENT_ARGS );
+    }
+    sub set_server_defaults {
+       my %args = @_;
+       $set_defaults->(\@_, $GLOBAL_SSL_SERVER_ARGS );
+    }
+}
+
+sub set_args_filter_hack {
+    my $sub = shift;
+    if ( ref $sub ) {
+       $FILTER_SSL_ARGS = shift;
+    } elsif ( $sub eq 'use_defaults' ) {
+       # override args with defaults
+       $FILTER_SSL_ARGS = sub {
+           my ($is_server,$args) = @_;
+           %$args = ( %$args, $is_server
+               ? ( %DEFAULT_SSL_SERVER_ARGS, %$GLOBAL_SSL_SERVER_ARGS )
+               : ( %DEFAULT_SSL_CLIENT_ARGS, %$GLOBAL_SSL_CLIENT_ARGS )
+           );
+       }
     }
 }
 
@@ -1592,6 +1705,14 @@
        $arg_hash->{SSL_use_cert} = 1
     }
 
+    # if any of SSL_ca_path or SSL_ca_file is set don't set the other SSL_ca_*
+    # from defaults
+    if ( $arg_hash->{SSL_ca_path} ) {
+       $arg_hash->{SSL_ca_file} ||= undef
+    } elsif ( $arg_hash->{SSL_ca_file} ) {
+       $arg_hash->{SSL_ca_path} ||= undef;
+    }
+
     # add library defaults
     %$arg_hash = (
        SSL_use_cert => $is_server,
@@ -1602,113 +1723,83 @@
     # Avoid passing undef arguments to Net::SSLeay
     defined($arg_hash->{$_}) or delete($arg_hash->{$_}) for(keys %$arg_hash);
 
-    # use default path to certs and ca unless another one was given
-    # don't mix default path with user specified path, either we use all
-    # or no defaults
-    {
-       my $use_default = 1;
-       for (qw( SSL_cert SSL_cert_file SSL_key SSL_key_file
-           SSL_ca_file SSL_ca_path
-           SSL_fingerprint )) {
-           next if ! defined $arg_hash->{$_};
-           # some apps set keys '' to signal that it is not set, replace with 
undef
-           if ( $arg_hash->{$_} eq '' ) {
-               $arg_hash->{$_} = undef;
-               next;
-           }
-           $use_default = 0;
+    # check SSL CA, cert etc arguments
+    # some apps set keys '' to signal that it is not set, replace with undef
+    for (qw( SSL_cert SSL_cert_file SSL_key SSL_key_file
+       SSL_ca_file SSL_ca_path
+       SSL_fingerprint )) {
+       $arg_hash->{$_} = undef if defined $arg_hash->{$_}
+           and $arg_hash->{$_} eq '';
+    }
+    for(qw(SSL_cert_file SSL_key_file)) {
+        defined( my $file = $arg_hash->{$_} ) or next;
+       for my $f (ref($file) eq 'HASH' ? values(%$file):$file ) {
+           die "$_ $f does not exist" if ! -f $f;
+           die "$_ $f is not accessible" if ! -r _;
        }
+    }
 
-       $use_default = 0 if $use_default
-           and ! $is_server
-           and ! $arg_hash->{SSL_verify_mode};
-
-       if ( $use_default ) {
-
-           my %ca =
-               -f 'certs/my-ca.pem' ? ( SSL_ca_file => 'certs/my-ca.pem' ) :
-               -d 'ca/' ? ( SSL_ca_path => 'ca/' ) :
-               ();
-           my %certs = $is_server ? (
-               SSL_key_file => 'certs/server-key.pem',
-               SSL_cert_file => 'certs/server-cert.pem',
-           ) : $arg_hash->{SSL_use_cert} ? (
-               SSL_key_file => 'certs/client-key.pem',
-               SSL_cert_file => 'certs/client-cert.pem',
-           ) :();
-           %$arg_hash = ( %$arg_hash, %ca, %certs );
-
-           carp(
-               
"*******************************************************************\n".
-               " The implicite use of IO::Socket::SSL specific default 
settings for \n".
-               " CA, cert and key is depreceated.\n".
-               " Please explicitly specify your own CA, cert and key using:\n".
-               "    - SSL_ca_file or SSL_ca_path for the CA\n".
-               "    - SSL_cert_file and SSL_key_file for cert and key\n".
-               " To specify your own system wide defaults you can use \n".
-               " set_defaults, set_client_defaults and set_server_defaults.\n".
-               
"*******************************************************************\n".
-               " "
-           ) if %ca or %certs;
-
-       } else {
-           for(qw(SSL_cert_file SSL_key_file)) {
-               defined( my $file = $arg_hash->{$_} ) or next;
-               for my $f (ref($file) eq 'HASH' ? values(%$file):$file ) {
-                   die "$_ $f does not exist" if ! -f $f;
-                   die "$_ $f is not accessible" if ! -r _;
-               }
-           }
-           if ( defined( my $f = $arg_hash->{SSL_ca_file} )) {
-               die "SSL_ca_file $f does not exist" if ! -f $f;
-               die "SSL_ca_file $f is not accessible" if ! -r _;
-           }
-           if ( defined( my $d = $arg_hash->{SSL_ca_path} )) {
-               die "only SSL_ca_path or SSL_ca_file should be given"
-                   if defined $arg_hash->{SSL_ca_file};
-               die "SSL_ca_path $d does not exist" if ! -d $d;
-               die "SSL_ca_path $d is not accessible" if ! -r _;
-           }
+    my $verify_mode = $arg_hash->{SSL_verify_mode};
+    if ( $verify_mode != Net::SSLeay::VERIFY_NONE()) {
+       if ( defined( my $f = $arg_hash->{SSL_ca_file} )) {
+           ref($f) and ! $$f and next; # explicitly ignore
+           die "SSL_ca_file $f does not exist" if ! -f $f;
+           die "SSL_ca_file $f is not accessible" if ! -r _;
+       }
+       if ( defined( my $d = $arg_hash->{SSL_ca_path} )) {
+           ref($d) and ! $$d and next; # explicitly ignore
+           die "only SSL_ca_path or SSL_ca_file should be given"
+               if defined $arg_hash->{SSL_ca_file};
+           die "SSL_ca_path $d does not exist" if ! -d $d;
+           die "SSL_ca_path $d is not accessible" if ! -r _;
        }
     }
 
+    my $self = bless {},$class;
+
     my $vcn_scheme = delete $arg_hash->{SSL_verifycn_scheme};
-    if ( ! $vcn_scheme or $vcn_scheme ne 'none' ) {
-       # don't access ${*self} inside callback - this seems to create
-       # circular references from the ssl object to the context and back
-
-       # use SSL_verifycn_name or determine from PeerAddr
-       my $host = $arg_hash->{SSL_verifycn_name};
-       if (not defined($host)) {
-           if ( $host = $arg_hash->{PeerAddr} || $arg_hash->{PeerHost} ) {
-               $host =~s{:[a-zA-Z0-9_\-]+$}{};
+    if ( ! $is_server and $verify_mode & 0x01 and
+       ! $vcn_scheme || $vcn_scheme ne 'none' ) {
+
+       # gets updated during configure_SSL
+       my $verify_name;
+       $self->{verify_name_ref} = \$verify_name;
+
+       my $vcb = $arg_hash->{SSL_verify_callback};
+       $arg_hash->{SSL_verify_callback} = sub {
+           my ($ok,$ctx_store,$certname,$error,$cert) = @_;
+           $ok = $vcb->($ok,$ctx_store,$certname,$error,$cert) if $vcb;
+           $ok or return 0;
+
+           return $ok if
+               Net::SSLeay::X509_STORE_CTX_get_error_depth($ctx_store) !=0;
+
+           my $host = $verify_name || ref($vcn_scheme) && 
$vcn_scheme->{callback} && 'unknown';
+           if ( ! $host ) {
+               if ( $vcn_scheme ) {
+                   IO::Socket::SSL->error(
+                       "Cannot determine peer hostname for verification" );
+                   return 0;
+               }
+               warn "Cannot determine hostname if peer for verification. ".
+                   "Disabling default hostname verification for now. ".
+                   "Please specify hostname with SSL_verifycn_name and better 
set SSL_verifycn_scheme too.\n";
+               return $ok;
+           } elsif ( ! $vcn_scheme && $host =~m{^[\d.]+$|:} ) {
+               # don't try to verify IP by default
+               return $ok;
            }
-       }
-       $host ||= ref($vcn_scheme) && $vcn_scheme->{callback} && 'unknown';
-       if ( ! $host ) {
-           return IO::Socket::SSL->error(
-               "Cannot determine peer hostname for verification" )
-               if $vcn_scheme;
-       } elsif ( ! $vcn_scheme && $host =~m{^[\d.]+$|:} ) {
-           # don't try to verify IP by default
-       } else {
-           my $vcb = $arg_hash->{SSL_verify_callback};
-           $arg_hash->{SSL_verify_callback} = sub {
-               my ($ok,$ctx_store,$certname,$error,$cert) = @_;
-               $ok = $vcb->($ok,$ctx_store,$certname,$error,$cert) if $vcb;
-               $ok or return 0;
-               return $ok if
-                   Net::SSLeay::X509_STORE_CTX_get_error_depth($ctx_store) !=0;
-
-               # verify name
-               my $rv = IO::Socket::SSL::verify_hostname_of_cert(
-                   $host,$cert,$vcn_scheme );
-               if ( ! $rv && ! $vcn_scheme ) {
-                   # For now we use the default hostname verification if none
-                   # was specified and complain loudly but return ok if it does
-                   # not match. In the future we will enforce checks and users
-                   # should better specify and explicite verification scheme.
-                   warn <<WARN;
+
+
+           # verify name
+           my $rv = IO::Socket::SSL::verify_hostname_of_cert(
+               $host,$cert,$vcn_scheme );
+           if ( ! $rv && ! $vcn_scheme ) {
+               # For now we use the default hostname verification if none
+               # was specified and complain loudly but return ok if it does
+               # not match. In the future we will enforce checks and users
+               # should better specify and explicite verification scheme.
+               warn <<WARN;
 
 The verification of cert '$certname'
 failed against the host '$host' with the default verification scheme.
@@ -1719,11 +1810,14 @@
 the name of the host you expect in the certificate.
 
 WARN
-                   return 1;
-               }
-               return $rv;
-           };
-       }
+               return $ok;
+           }
+           if ( ! $rv ) {
+               IO::Socket::SSL->error(
+                   "hostname verification failed" );
+           }
+           return $rv;
+       };
     }
 
     my $ssl_op = Net::SSLeay::OP_ALL();
@@ -1790,15 +1884,23 @@
        }
     }
 
-    my $verify_mode = $arg_hash->{SSL_verify_mode};
     if ( $verify_mode != Net::SSLeay::VERIFY_NONE()) {
        if ( defined $arg_hash->{SSL_ca_file} || defined 
$arg_hash->{SSL_ca_path} ) {
-           return IO::Socket::SSL->error("Invalid certificate authority 
locations")
-               if ! Net::SSLeay::CTX_load_verify_locations( $ctx,
-                   $arg_hash->{SSL_ca_file} || '',$arg_hash->{SSL_ca_path} || 
'');
-       } else {
+           my $file = $arg_hash->{SSL_ca_file};
+           $file = undef if ref($file) && ! $$file;
+           my $dir = $arg_hash->{SSL_ca_path};
+           $dir = undef if ref($dir) && ! $$dir;
+           if ( $file || $dir and ! Net::SSLeay::CTX_load_verify_locations(
+               $ctx, $file || '', $dir || '')) {
+               return IO::Socket::SSL->error(
+                   "Invalid certificate authority locations")
+           }
+       } elsif ( my %ca = IO::Socket::SSL::default_ca()) {
            # no CA path given, continue with system defaults
-           Net::SSLeay::CTX_set_default_verify_paths($ctx);
+           return IO::Socket::SSL->error(
+               "Invalid default certificate authority locations")
+               if ! Net::SSLeay::CTX_load_verify_locations( $ctx,
+                   $ca{SSL_ca_file} || '',$ca{SSL_ca_path} || '');
        }
     }
 
@@ -1952,7 +2054,7 @@
        if ( $cert && @accept_fp ) {
            my %fp;
            for(@accept_fp) {
-               my $fp = $fp{$_->[0]} ||= 
+               my $fp = $fp{$_->[0]} ||=
                    Net::SSLeay::X509_get_fingerprint($cert,$_->[0]);
                return 1 if $fp eq $_->[1];
            }
@@ -1972,7 +2074,7 @@
        $cb->($ctx);
     }
 
-    my $self = bless { context => $ctx },$class;
+    $self->{context} = $ctx;
     $self->{has_verifycb} = 1 if $verify_callback;
     $DEBUG>=3 && DEBUG( "new ctx $ctx" );
     $CTX_CREATED_IN_THIS_THREAD{$ctx} = 1;
@@ -2108,8 +2210,13 @@
 
        # certificate verification
        SSL_verify_mode => SSL_VERIFY_PEER,
+
+       # location of CA store
        SSL_ca_path => '/etc/ssl/certs', # typical CA path on Linux
-       # on OpenBSD instead: SSL_ca_file => '/etc/ssl/cert.pem'
+       SSL_ca_file => '/etc/ssl/cert.pem', # typical CA file on BSD
+       # or just use default path on system:
+       IO::Socket::SSL::default_ca(), # either explicitly
+       # or implicitly by not giving SSL_ca_*
 
        # easy hostname verification
        SSL_verifycn_name => 'foo.bar', # defaults to PeerHost
@@ -2236,7 +2343,7 @@
 Data are transmitted inside the SSL protocol using encrypted frames, which can
 only be decrypted once the full frame is received. So if you use C<read> or
 C<sysread> to receive less data than the SSL frame contains, it will read the
-whole frame, return part of it and buffer the rest for later reads. 
+whole frame, return part of it and buffer the rest for later reads.
 This does not make a difference for simple programs, but if you use
 select-loops or polling or non-blocking I/O please read the related sections.
 
@@ -2321,7 +2428,7 @@
 
 =item SSL_version
 
-Sets the version of the SSL protocol used to transmit data. 
+Sets the version of the SSL protocol used to transmit data.
 'SSLv23' auto-negotiates between SSLv2 and SSLv3, while 'SSLv2', 'SSLv3',
 'TLSv1', 'TLSv1_1' or 'TLSv1_2' restrict the protocol to the specified version.
 All values are case-insensitive.  Instead of 'TLSv1_1' and 'TLSv1_2' one can
@@ -2454,10 +2561,11 @@
 trusted certificate authority. In this case you should use this option to
 specify the file (SSL_ca_file) or directory (SSL_ca_path) containing the
 certificateZ<>(s) of the trusted certificate authorities.
-If both SSL_ca_file and SSL_ca_path are undefined and builtin defaults (see
-"Defaults for Cert, Key and CA".) can not be used, the system
-defaults built into the OpenSSL library will be tried.
-If you really don't want to set a CA set this key to C<''>.
+If both SSL_ca_file and SSL_ca_path are unset it will use C<default_ca()>
+to determine the user-set or system defaults.
+If you really don't want to set a CA set this key to C<\undef> (unfortunatly
+C<''> is used by some modules using IO::Socket::SSL when CA is not exlicitly
+given).
 
 =item SSL_fingerprint
 
@@ -2466,7 +2574,7 @@
 verification at all. In this case you can specify the fingerprint of the
 certificate as C<'algo$hex_fingerprint'>. C<algo> is a fingerprint algorithm
 supported by OpenSSL, e.g. 'sha1','sha256'... and C<hex_fingerprint> is the
-hexadecimal representation of the binary fingerprint. 
+hexadecimal representation of the binary fingerprint.
 To get the fingerprint of an established connection you can use
 C<get_fingerprint>.
 
@@ -2663,7 +2771,7 @@
 non-blocking socket, the SSL handshake on the new file object will be done in a
 blocking way. Please see the section about non-blocking I/O for details.
 If you don't like this behavior you should do accept on the TCP socket and then
-upgrade it with C<start_SSL> later. 
+upgrade it with C<start_SSL> later.
 
 =item B<connect(...)>
 
@@ -2713,7 +2821,7 @@
 =item B<sysread( BUF, LEN, [ OFFSET ] )>
 
 This function behaves from the outside the same as B<sysread> in other
-L<IO::Socket> objects, e.g. it returns at most LEN bytes of data. 
+L<IO::Socket> objects, e.g. it returns at most LEN bytes of data.
 But in reality it reads not only LEN bytes from the underlying socket, but at
 a single SSL frame. It then returns up to LEN bytes it decrypted from this SSL
 frame. If the frame contained more data than requested it will return only LEN
@@ -2738,12 +2846,12 @@
 This functions behaves from the outside the same as B<syswrite> in other
 L<IO::Socket> objects, e.g. it will write at most LEN bytes to the socket, but
 there is no guarantee, that all LEN bytes are written. It will return the 
number
-of bytes written. 
+of bytes written.
 syswrite will write all the data within a single SSL frame, which means, that
 no more than 16.384 bytes, which is the maximum size of an SSL frame, can be
 written at once.
 
-For non-blocking sockets SSL specific behavior applies. 
+For non-blocking sockets SSL specific behavior applies.
 Pease read the specific section in this documentation.
 
 =item B<peek( BUF, LEN, [ OFFSET ])>
@@ -2969,6 +3077,29 @@
 If C<$fd> is already an IO::Socket object you should better call C<start_SSL>
 directly.
 
+=item B<IO::Socket::SSL::default_ca([ path|dir| SSL_ca_file => ..., 
SSL_ca_path => ... ])>
+
+Determines or sets the default CA path.
+If existing path or dir or a hash is given it will set the default CA path to
+this value and never try to detect it automatically.
+If C<undef> is given it will forget any stored defaults and continue with
+detection of system defaults.
+If no arguments are given it will start detection of system defaults, unless it
+has already stored user-set or previously detected values.
+
+The detection of system defaults works similar to OpenSSL, e.g. it will check
+the directory specified in environment variable SSL_CERT_DIR or the path
+OPENSSLDIR/certs (SSLCERTS: on VMS) and the file specified in environment
+variable SSL_CERT_FILE or the path OPENSSLDIR/cert.pem (SSLCERTS:cert.pem on
+VMS). Contrary to OpenSSL it will check if the SSL_ca_path contains PEM files
+with the hash as file name and if the SSL_ca_file looks like PEM.
+If no usable system default can be found it will try to load and use
+L<Mozilla::CA> and if not available give up detection.
+The result of the detection will be saved to speed up future calls.
+
+The function returns the saved default CA as hash with SSL_ca_file and
+SSL_ca_path.
+
 =item B<IO::Socket::SSL::set_default_context(...)>
 
 You may use this to make IO::Socket::SSL automatically re-use a given context 
(unless
@@ -2989,19 +3120,18 @@
 =item B<IO::Socket::SSL::set_defaults(%args)>
 
 With this function one can set defaults for all SSL_* parameter used for 
creation of
-the context, like the SSL_verify* parameter.
+the context, like the SSL_verify* parameter. Any SSL_* parameter can be given
+or the following short versions:
 
 =over 8
 
-=item mode - set default SSL_verify_mode
-
-=item callback - set default SSL_verify_callback
+=item mode - SSL_verify_mode
 
-=item scheme - set default SSL_verifycn_scheme
+=item callback - SSL_verify_callback
 
-=item name - set default SSL_verifycn_name
+=item scheme - SSL_verifycn_scheme
 
-If not given and scheme is hash reference with key callback it will be set to 
'unknown'
+=item name - SSL_verifycn_name
 
 =back
 
@@ -3013,6 +3143,35 @@
 
 Similar to C<set_defaults>, but only sets the defaults for server mode.
 
+=item B<IO::Socket::SSL::set_args_filter_hack(\&code|'use_defaults')>
+
+Sometimes one has to use code which uses unwanted or invalid arguments for SSL,
+typically disabling SSL verification or setting wrong ciphers or SSL versions.
+With this hack it is possible to override these settings and restore sanity.
+Example:
+
+    IO::Socket::SSL::set_args_filter_hack( sub {
+       my ($is_server,$args) = @_;
+       if ( ! $is_server ) {
+           # client settings - enable verification with default CA
+           # and fallback hostname verification etc
+           delete @{$args}{qw(
+               SSL_verify_mode
+               SSL_ca_file
+               SSL_ca_path
+               SSL_verifycn_scheme
+               SSL_version
+           )};
+           # and add some fingerprints for known certs which are signed by
+           # unknown CAs or are self-signed
+           $args->{SSL_fingerprint} = ...
+       }
+    });
+
+With the short setting C<set_args_filter_hack('use_defaults')> it will prefer
+the default settings in all cases. These default settings can be modified with
+C<set_defaults>, C<set_client_defaults> and C<set_server_defaults>.
+
 =back
 
 The following methods are unsupported (not to mention futile!) and 
IO::Socket::SSL
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/IO-Socket-SSL-1.967/t/external/usable_ca.t 
new/IO-Socket-SSL-1.970/t/external/usable_ca.t
--- old/IO-Socket-SSL-1.967/t/external/usable_ca.t      1970-01-01 
01:00:00.000000000 +0100
+++ new/IO-Socket-SSL-1.970/t/external/usable_ca.t      2014-03-13 
07:24:47.000000000 +0100
@@ -0,0 +1,42 @@
+use strict;
+use warnings;
+use Test::More;
+use IO::Socket::SSL;
+
+my $ipclass = 'IO::Socket::INET';
+for( qw( IO::Socket::IP IO::Socket::INET6  )) {
+    eval { require $_ } or next;
+    $ipclass = $_;
+    last;
+}
+
+my @hosts = qw( www.google.com www.live.com );
+plan tests => 0+@hosts;
+
+for my $host (@hosts) {
+    SKIP: {
+       # first check if we can connect at all
+       my $cl = $ipclass->new( 
+           PeerAddr => $host,
+           PeerPort => 443,
+           Timeout => 15,
+       );
+
+       skip "cannot connect to $host:443 with $ipclass: $!",1
+           if ! $cl;
+       diag("connection to $host ok");
+
+       # then try to upgrade with SSL using default CA path
+       my $upgrade_ok = IO::Socket::SSL->start_SSL($cl,
+           SSL_verify_mode => 1,
+           SSL_verifycn_name => $host,
+           SSL_verifycn_scheme => 'http',
+       );
+       ok($upgrade_ok,"SSL upgrade with default CA");
+    }
+}
+
+
+    
+
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/IO-Socket-SSL-1.967/t/sessions.t 
new/IO-Socket-SSL-1.970/t/sessions.t
--- old/IO-Socket-SSL-1.967/t/sessions.t        2014-02-05 20:30:16.000000000 
+0100
+++ new/IO-Socket-SSL-1.970/t/sessions.t        2014-03-16 17:35:26.000000000 
+0100
@@ -51,7 +51,7 @@
         SSL_ca_path => '',
         SSL_version => 'TLSv1',
         SSL_cipher_list => 'HIGH',
-        SSL_session_cache_size => 4
+        SSL_session_cache_size => 4,
     );
 
 
@@ -104,19 +104,13 @@
 
     my $sock3 = IO::Socket::INET->new($saddr[2]);
     my @clients = (
-       IO::Socket::SSL->new(
-           PeerAddr => $saddr[0],
-           SSL_verify_mode => 0
-       ),
-       IO::Socket::SSL->new(
-           PeerAddr => $saddr[1],
-           SSL_verify_mode => 0
-       ),
-       IO::Socket::SSL->start_SSL( $sock3 , SSL_verify_mode => 0),
+       IO::Socket::SSL->new($saddr[0]),
+       IO::Socket::SSL->new($saddr[1]),
+       IO::Socket::SSL->start_SSL( $sock3 ),
     );
 
     if ( grep { !$_ } @clients >0 ) {
-       print "not ok \# Client init\n";
+       print "not ok \# Client init $SSL_ERROR\n";
        exit;
     }
     &ok("Client init");
@@ -153,10 +147,7 @@
     }
 
     @clients = map {
-       IO::Socket::SSL->new(
-           PeerAddr => $_,
-           SSL_verify_mode => 0,
-       )
+       IO::Socket::SSL->new($_)
     } @saddr;
 
     if (keys(%$cache) != 6) {

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to