IO-Socket-SSL
view release on metacpan or search on metacpan
lib/IO/Socket/SSL.pm view on Meta::CPAN
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 = $CHECK_SSL_PATH->($path);
$ca_detected = 0;
} else {
$ca_detected = undef;
}
}
return %default_ca if defined $ca_detected;
# SSLEAY_DIR was 5 up to OpenSSL 1.1, then switched to 4 and got
# renamed to OPENSSL_DIR. Unfortunately it is not exported as constant
# by Net::SSLeay so we use the fixed number.
$openssldir ||=
Net::SSLeay::SSLeay_version(5) =~m{^OPENSSLDIR: "(.+)"$} ? $1 :
Net::SSLeay::SSLeay_version(4) =~m{^OPENSSLDIR: "(.+)"$} ? $1 :
'cannot-determine-openssldir-from-ssleay-version';
# (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;
while (my $line = <$fh>) {
$line =~m{^-+BEGIN (X509 |TRUSTED |)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)) {
while (my $line = <$fh>) {
$line =~m{^-+BEGIN (X509 |TRUSTED |)CERTIFICATE-} or next;
$default_ca{SSL_ca_file} = $file;
last;
}
}
$default_ca{SSL_ca_file} = Mozilla::CA::SSL_ca_file() if ! %default_ca && do {
local $SIG{__DIE__};
eval { require Mozilla::CA; 1 };
};
$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
sub import {
my $class = shift;
my @export;
foreach (@_) {
if ( /^inet4$/i ) {
# explicitly fall back to inet4
@ISA = 'IO::Socket::INET';
@caller_force_inet4 = caller(); # save for warnings for 'inet6' case
} elsif ( /^inet6$/i ) {
# check if we have already ipv6 as base
if ( ! UNIVERSAL::isa( $class, 'IO::Socket::INET6')
and ! UNIVERSAL::isa( $class, 'IO::Socket::IP' )) {
# either we don't support it or we disabled it by explicitly
# loading it with 'inet4'. In this case re-enable but warn
# because this is probably an error
if ( CAN_IPV6 ) {
@ISA = ( CAN_IPV6 );
warn "IPv6 support re-enabled in __PACKAGE__, got disabled in file $caller_force_inet4[1] line $caller_force_inet4[2]";
} else {
die "INET6 is not supported, install IO::Socket::IP";
}
}
} elsif ( /^:?debug(\d+)/ ) {
$DEBUG=$1;
} else {
push @export,$_
}
}
@_ = ( $class,@export );
goto &Exporter::import;
}
my %SSL_OBJECT;
my %CREATED_IN_THIS_THREAD;
sub CLONE { %CREATED_IN_THIS_THREAD = (); }
# all keys specific for the current state of the socket
# these should be removed on close
my %all_my_conn_keys = map { $_ => 1 } qw(
_SSL_fileno
_SSL_object
_SSL_opened
_SSL_opening
_SSL_read_closed
_SSL_write_closed
_SSL_rawfd
_SSL_bio_socket
_SSL_bio_sub
);
my %all_my_conn_and_cert_keys = (
%all_my_conn_keys,
_SSL_certificate => 1,
);
# all keys used internally, these should be cleaned up at end
# but not already on close
my %all_my_keys = (
%all_my_conn_and_cert_keys,
map { $_ => 1 } qw(
_SSL_arguments
_SSL_ctx
_SSL_ioclass_upgraded
_SSL_last_err
_SSL_ocsp_verify
_SSL_servername
_SSL_msg_callback
)
( run in 2.424 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )