[libnet-sslglue-perl] 32/39: Imported Upstream version 1.052
dom at earth.li
dom at earth.li
Thu Aug 27 18:38:44 UTC 2015
This is an automated email from the git hooks/post-receive script.
dom pushed a commit to branch master
in repository libnet-sslglue-perl.
commit b1cb840a574c8d8bc3e7894adf196e1dc9ab6c3c
Author: Dominic Hargreaves <dom at earth.li>
Date: Sun Feb 9 15:01:25 2014 +0000
Imported Upstream version 1.052
---
Changes | 14 ++
MANIFEST | 23 ++--
META.yml | 4 +-
Makefile.PL | 21 +--
TODO | 1 -
examples/ftps-direct.pl | 12 ++
examples/ftps-starttls.pl | 21 +++
examples/ftps-tests.pl | 124 +++++++++++++++++
lib/Net/SSLGlue.pm | 8 +-
lib/Net/SSLGlue/FTP.pm | 334 ++++++++++++++++++++++++++++++++++++++++++++++
lib/Net/SSLGlue/Socket.pm | 204 ++++++++++++++++++++++++++++
t/external/02_smtp.t | 28 +---
t/external/03_lwp.t | 104 +++++++++------
t/external/04_pop3.t | 29 +---
t/external/05_ftp.t | 169 +++++++++++++++++++++++
15 files changed, 981 insertions(+), 115 deletions(-)
diff --git a/Changes b/Changes
index 7741a5c..e853530 100644
--- a/Changes
+++ b/Changes
@@ -1,3 +1,17 @@
+1.052 2014/01/16
+- FTPS: reuse same SSL session for control and data channnel to work
+ with default configuration of proftpd.
+
+1.051 2014/01/10
+- fixes to Net::FTP SSL support
+- examples/ftps-tests.pl has lots of tests for FTP against live server
+
+1.05 2014/01/09
+- added support for SSL+IPv6 in Net::FTP
+- new package Net::SSLGlue::Socket for a socket which combines plain,ssl,ipv6
+- fixed some tests - some checks for bad certificates do not work anymore
+ because these certs were fixed
+
1.04 2013/08/01
replace Net::Cmd::getline via Net::SSLGlue::POP3 because it assumed, that it
just needs to wait for read events on the sockets - which is not the case for
diff --git a/MANIFEST b/MANIFEST
index dde4968..2c2acbf 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,20 +1,25 @@
+Changes
+COPYRIGHT
+examples/ftps-direct.pl
+examples/ftps-starttls.pl
+examples/ftps-tests.pl
+examples/lwp.pl
+examples/lwp_post.pl
+examples/send-ssl-mail.pl
+examples/send-starttls-mail.pl
lib/Net/SSLGlue.pm
+lib/Net/SSLGlue/FTP.pm
lib/Net/SSLGlue/LDAP.pm
lib/Net/SSLGlue/LWP.pm
-lib/Net/SSLGlue/SMTP.pm
lib/Net/SSLGlue/POP3.pm
+lib/Net/SSLGlue/SMTP.pm
+lib/Net/SSLGlue/Socket.pm
Makefile.PL
MANIFEST This list of files
+README
t/01_load.t
t/external/02_smtp.t
t/external/03_lwp.t
t/external/04_pop3.t
-TODO
-COPYRIGHT
-examples/lwp.pl
-examples/lwp_post.pl
-examples/send-ssl-mail.pl
-examples/send-starttls-mail.pl
-Changes
-README
+t/external/05_ftp.t
META.yml Module meta-data (added by MakeMaker)
diff --git a/META.yml b/META.yml
index 38dff5f..8007d08 100644
--- a/META.yml
+++ b/META.yml
@@ -1,6 +1,6 @@
--- #YAML:1.0
name: Net-SSLGlue
-version: 1.04
+version: 1.052
abstract: ~
author: []
license: unknown
@@ -11,6 +11,8 @@ build_requires:
ExtUtils::MakeMaker: 0
requires:
IO::Socket::SSL: 1.19
+resources:
+ repository: https://github.com/noxxi/p5-net-sslglue
no_index:
directory:
- t
diff --git a/Makefile.PL b/Makefile.PL
index f260435..2ab35fc 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -1,14 +1,19 @@
use ExtUtils::MakeMaker;
require 5.008;
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.\n".
- "[y/N]", 'n' );
+ "These tests will fail if there is no internet connection or if a firewall\n".
+ "blocks some traffic.\n".
+ "[y/N]", 'n' );
WriteMakefile(
- NAME => 'Net::SSLGlue',
- VERSION_FROM => 'lib/Net/SSLGlue.pm',
- PREREQ_PM => {
- 'IO::Socket::SSL' => 1.19,
+ NAME => 'Net::SSLGlue',
+ VERSION_FROM => 'lib/Net/SSLGlue.pm',
+ PREREQ_PM => {
+ 'IO::Socket::SSL' => 1.19,
+ },
+ $xt =~m{^y}i ? ( test => { TESTS => 't/*.t t/external/*.t' }):(),
+ META_MERGE => {
+ resources => {
+ repository => 'https://github.com/noxxi/p5-net-sslglue',
},
- $xt =~m{^y}i ? ( test => { TESTS => 't/*.t t/external/*.t' }):(),
+ },
);
diff --git a/TODO b/TODO
deleted file mode 100644
index 011330a..0000000
--- a/TODO
+++ /dev/null
@@ -1 +0,0 @@
-ldap tests
diff --git a/examples/ftps-direct.pl b/examples/ftps-direct.pl
new file mode 100644
index 0000000..32c410a
--- /dev/null
+++ b/examples/ftps-direct.pl
@@ -0,0 +1,12 @@
+use strict;
+use warnings;
+use Net::SSLGlue::FTP;
+
+my $ftp = Net::FTP->new( 'ftp.example.com',
+ SSL => 1,
+ SSL_ca_path => '/etc/ssl/certs',
+ Passive => 1,
+ Debug => 1,
+);
+$ftp->login('foo','bar');
+print $ftp->ls;
diff --git a/examples/ftps-starttls.pl b/examples/ftps-starttls.pl
new file mode 100644
index 0000000..6d23876
--- /dev/null
+++ b/examples/ftps-starttls.pl
@@ -0,0 +1,21 @@
+use strict;
+use warnings;
+use Net::SSLGlue::FTP;
+
+my $ftp = Net::FTP->new( 'ftp.example.com',
+ Passive => 1,
+ Debug => 1,
+);
+$ftp->starttls( SSL_ca_path => '/etc/ssl/certs' )
+ or die "tls upgrade failed";
+$ftp->login('foo','bar');
+print $ftp->ls;
+
+# change protection to clear
+$ftp->prot('C');
+$ftp->ls;
+
+# stop TLS on control channel
+$ftp->stoptls;
+$ftp->ls;
+
diff --git a/examples/ftps-tests.pl b/examples/ftps-tests.pl
new file mode 100644
index 0000000..c860fbb
--- /dev/null
+++ b/examples/ftps-tests.pl
@@ -0,0 +1,124 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+# This runs lots of tests with SSL against a test server
+# - plain
+# - with SSL upgrade and plain data connections
+# - with SSL upgrade and SSL data connections
+# - with SSL upgrade and downgrade after auth
+# - with direct SSL connection
+
+# setup stuff here
+# you need a server where you can write and read and create directories
+# SSL support is optional, but preferred
+# IPv6 support should be possible
+
+my $testhost = '127.0.0.1'; # where your test server is, IPv6 should be ok
+my $plain_port = 2021; # port where server listens for plain ftp
+my $user = 'foo'; # login as user
+my $pass = 'bar'; # with pass
+my $can_auth = 1; # does server support AUTH TLS
+my $ssl_port = 2090; # does server support direct SSL
+my %sslargs = (
+ # should be enabled if you want to verify certificates
+ SSL_verify_mode => 1,
+ # for CAs known to the system this might be maybe ommitted
+ # otherwise set this or SSL_ca_path
+ SSL_ca_file => 'ca.pem',
+ # if the certificate has a different name then $testhost set it here
+ SSL_verifycn_name => 'server.local',
+);
+
+
+use Net::SSLGlue::FTP;
+use IO::Socket::SSL;
+use Carp 'croak';
+
+my @test = (
+ # basic FTP server stuff
+ { Passive => 0 },
+ { Passive => 1 },
+ $can_auth ? (
+ # SSL upgrade with data connections unprotected
+ { Passive => 0, _starttls => 1, _prot => 'C' },
+ { Passive => 1, _starttls => 1, _prot => 'C' },
+ # SSL upgrade with data connections protected
+ { Passive => 0, _starttls => 1 },
+ { Passive => 1, _starttls => 1 },
+ # SSL upgrade with SSL downgrade after auth
+ { Passive => 0, _starttls => 1, _stoptls => 1 },
+ { Passive => 1, _starttls => 1, _stoptls => 1 },
+ ):(),
+ # direct SSL on separate port
+ $ssl_port ? (
+ { Passive => 0, SSL => 1, Port => $ssl_port },
+ { Passive => 1, SSL => 1, Port => $ssl_port },
+ ):(),
+);
+
+my $testbase = sprintf("test-%04x%04x-",rand(2**16),rand(2**16));
+for( my $i=0;$i<@test;$i++ ) {
+
+ my %conf = %{$test[$i]};
+ my $starttls = delete $conf{_starttls};
+ my $stoptls = delete $conf{_stoptls};
+ my $prot = delete $conf{_prot};
+ my $dir = "$testbase$i";
+
+ print STDERR "------------ $dir\n";
+ my $ftp = Net::FTP->new( $testhost,
+ Port => $plain_port,
+ Debug => 1,
+ %sslargs,
+ %conf,
+ ) or die "ftp connect failed";
+
+ my $ftperr = sub {
+ my $msg = shift;
+ croak "$msg failed (@_): ".$ftp->message;
+ };
+
+ # upgrade to SSL
+ $ftp->starttls or $ftperr->('auth tls', $SSL_ERROR)
+ if $starttls;
+
+ # login
+ $ftp->login($user,$pass) or $ftperr->('login');
+
+ # downgrade from SSL
+ $ftp->stoptls or $ftperr->('ccc') if $stoptls;
+
+ # change protection level
+ $ftp->prot($prot) or $ftperr->("PROT $prot")
+ if $prot;
+
+ # create directory for test and change into it
+ $ftp->mkdir($dir) or $ftperr->('mkd');
+ $ftp->cwd($dir) or $ftperr->('cwd');
+
+ # check that dir is empty
+ my @files = $ftp->ls;
+ $ftp->ok or $ftperr->('nlst');
+ @files and die "directory should be empty";
+
+ # create a file in dir
+ $ftp->put( _s2f( my $foo = 'foo' ,'<' ), 'foo.txt' )
+ or $ftperr->('stor');
+ # append some bytes to it
+ $ftp->append( _s2f('bar'),'foo.txt' ) or $ftperr->('appe');
+ # check that it is there
+ @files = $ftp->ls;
+ "@files" eq 'foo.txt' or die "wrong ls: @files";
+
+ # retrieve file and verify content
+ $ftp->get( 'foo.txt', _s2f( $foo = '','>' ));
+ $foo eq 'foobar' or die "wrong data: 'foobar' != '$foo'";
+
+ $ftp->quit;
+}
+
+sub _s2f {
+ open( my $fh,$_[1] || '<',\$_[0] );
+ return $fh
+}
diff --git a/lib/Net/SSLGlue.pm b/lib/Net/SSLGlue.pm
index a1c38b9..8e7ce83 100644
--- a/lib/Net/SSLGlue.pm
+++ b/lib/Net/SSLGlue.pm
@@ -1,5 +1,5 @@
package Net::SSLGlue;
-our $VERSION = '1.04';
+our $VERSION = '1.052';
=head1 NAME
@@ -21,12 +21,18 @@ available:
=item Net::POP3 - add SSL from beginning or using STLS
+=item Net::FTP - add SSL and IPv6 support to Net::FTP
+
=item Net::LDAP - add proper certificate checking
=item LWP - add proper certificate checking
=back
+There is also a Net::SSLGlue::Socket package which combines ssl and non-ssl
+and ipv6 capabilities to make it easier to enhance modules based on
+IO::Socket::INET.
+
=head1 COPYRIGHT
This module and the modules in the Net::SSLGlue Hierarchy distributed together
diff --git a/lib/Net/SSLGlue/FTP.pm b/lib/Net/SSLGlue/FTP.pm
new file mode 100644
index 0000000..70d020a
--- /dev/null
+++ b/lib/Net/SSLGlue/FTP.pm
@@ -0,0 +1,334 @@
+
+package Net::SSLGlue::FTP;
+
+use strict;
+use warnings;
+use Carp 'croak';
+use IO::Socket::SSL '$SSL_ERROR';
+use Net::SSLGlue::Socket;
+use Socket 'AF_INET';
+
+our $VERSION = 1.001;
+
+BEGIN {
+ for my $class (qw(Net::FTP Net::FTP::dataconn)) {
+ eval "require $class" or die "failed to load $class";
+ no strict 'refs';
+ my $fixed;
+ for( @{ "${class}::ISA" } ) {
+ $_ eq 'IO::Socket::INET' or next;
+ $_ = 'Net::SSLGlue::Socket';
+ $fixed = 1;
+ last;
+ }
+ die "cannot replace IO::Socket::INET with Net::SSLGlue::Socket in ${class}::ISA"
+ if ! $fixed;
+ }
+ $Net::FTP::VERSION eq '2.77'
+ or warn "Not tested with Net::FTP version $Net::FTP::VERSION";
+}
+
+# redefine Net::FTP::new so that it understands SSL => 1 and connects directly
+# with SSL to the server
+{
+ no warnings 'redefine';
+ my $onew = Net::FTP->can('new');
+ *Net::FTP::new = sub {
+ my $class = shift;
+ my %args = @_%2 ? ( Host => shift(), @_ ): @_;
+ my %sslargs = map { $_ => delete $args{$_} }
+ grep { m{^SSL_} } keys %args;
+
+ my $self;
+ if ( $args{SSL} ) {
+ # go immediatly to SSL
+ # Net::FTP::new gives only specific args to socket class
+ $args{Port} ||= 990;
+ local %Net::SSLGlue::Socket::ARGS = ( SSL => 1, %sslargs );
+ $self = $onew->($class,%args) or return;
+ ${*$self}{net_ftp_tlstype} = 'P';
+ } else {
+ $self = $onew->($class,%args) or return;
+ }
+ ${*$self}{net_ftp_tlsargs} = \%sslargs;
+ return $self;
+ };
+}
+
+# add starttls method to upgrade connection to SSL: AUTH TLS
+sub Net::FTP::starttls {
+ my $self = shift;
+ $self->is_ssl and croak("called starttls within SSL session");
+ $self->_AUTH('TLS') == Net::FTP::CMD_OK or return;
+
+ my $host = $self->host;
+ # for name verification strip port from domain:port, ipv4:port, [ipv6]:port
+ $host =~s{(?<!:):\d+$}{};
+
+ my %args = (
+ SSL_verify_mode => 1,
+ SSL_verifycn_scheme => 'ftp',
+ SSL_verifycn_name => $host,
+ # reuse SSL session of control connection in data connections
+ SSL_session_cache => Net::SSLGlue::FTP::SingleSessionCache->new,
+ %{ ${*$self}{net_ftp_tlsargs}},
+ @_
+ );
+
+ $self->start_SSL(%args) or return;
+ ${*$self}{net_ftp_tlsargs} = \%args;
+ $self->prot('P');
+ return 1;
+}
+
+# add prot method to set protection level (PROT C|P)
+sub Net::FTP::prot {
+ my ($self,$type) = @_;
+ $type eq 'C' or $type eq 'P' or croak("type must by C or P");
+ $self->_PBSZ(0) or return;
+ $self->_PROT($type) or return;
+ ${*$self}{net_ftp_tlstype} = $type;
+ return 1;
+}
+
+# add stoptls method to downgrade connection from SSL: CCC
+sub Net::FTP::stoptls {
+ my $self = shift;
+ $self->is_ssl or croak("called stoptls outside SSL session");
+ $self->_CCC() or return;
+ $self->stop_SSL();
+ return 1;
+}
+
+# add EPSV for new style passive mode (incl. IPv6)
+sub Net::FTP::epsv {
+ my $self = shift;
+ @_ and croak 'usage: $ftp->epsv()';
+ delete ${*$self}{net_ftp_intern_port};
+
+ $self->_EPSV && $self->message =~ m{\(([\x33-\x7e])\1\1(\d+)\1\)}
+ ? ${*$self}{'net_ftp_pasv'} = [ $self->peerhost, $2 ]
+ : undef;
+}
+
+# redefine PASV so that it uses EPSV on IPv6
+# also net_ftp_pasv contains now the parsed [ip,port]
+{
+ no warnings 'redefine';
+ *Net::FTP::pasv = sub {
+ my $self = shift;
+ @_ and croak 'usage: $ftp->port()';
+ return $self->epsv if $self->sockdomain != AF_INET;
+ delete ${*$self}{net_ftp_intern_port};
+
+ if ( $self->_PASV &&
+ $self->message =~ m{(\d+,\d+,\d+,\d+),(\d+),(\d+)} ) {
+ my $port = 256 * $2 + $3;
+ ( my $ip = $1 ) =~s{,}{.}g;
+ return ${*$self}{'net_ftp_pasv'} = [ $ip,$port ];
+ }
+ return;
+ };
+}
+
+# add EPRT for new style passive mode (incl. IPv6)
+sub Net::FTP::eprt {
+ @_ == 1 || @_ == 2 or croak 'usage: $self->eprt([PORT])';
+ return _eprt('EPRT', at _);
+}
+
+# redefine PORT to use EPRT for IPv6
+{
+ no warnings 'redefine';
+ *Net::FTP::port = sub {
+ @_ == 1 || @_ == 2 or croak 'usage: $self->port([PORT])';
+ return _eprt('PORT', at _);
+ };
+}
+
+sub _eprt {
+ my ($cmd,$self,$port) = @_;
+ delete ${*$self}{net_ftp_intern_port};
+ unless ($port) {
+ my $listen = ${*$self}{net_ftp_listen} ||= Net::SSLGlue::Socket->new(
+ Listen => 1,
+ Timeout => $self->timeout,
+ LocalAddr => $self->sockhost,
+ );
+ ${*$self}{net_ftp_intern_port} = 1;
+ my $fam = ($listen->sockdomain == AF_INET) ? 1:2;
+ if ( $cmd eq 'EPRT' || $fam == 2 ) {
+ $port = "|$fam|".$listen->sockhost."|".$listen->sockport."|";
+ $cmd = 'EPRT';
+ } else {
+ my $p = $listen->sockport;
+ $port = join(',',split(m{\.},$listen->sockhost),$p >> 8,$p & 0xff);
+ }
+ }
+ my $ok = $cmd eq 'EPRT' ? $self->_EPRT($port) : $self->_PORT($port);
+ ${*$self}{net_ftp_port} = $port if $ok;
+ return $ok;
+}
+
+
+
+for my $cmd (qw(PBSZ PROT CCC EPRT EPSV)) {
+ no strict 'refs';
+ *{"Net::FTP::_$cmd"} = sub {
+ shift->command("$cmd @_")->response() == Net::FTP::CMD_OK
+ }
+}
+
+# redefine _dataconn to
+# - support IPv6
+# - upgrade data connection to SSL if PROT P
+{
+
+ no warnings 'redefine';
+ *Net::FTP::_dataconn = sub {
+ my $self = shift;
+ my $pkg = "Net::FTP::" . $self->type;
+ eval "require $pkg";
+ $pkg =~ s/ /_/g;
+ delete ${*$self}{net_ftp_dataconn};
+
+ my $conn;
+ if ( my $pasv = ${*$self}{net_ftp_pasv} ) {
+ $conn = $pkg->new(
+ PeerAddr => $pasv->[0],
+ PeerPort => $pasv->[1],
+ LocalAddr => ${*$self}{net_ftp_localaddr},
+ ) or return;
+ } elsif (my $listen = delete ${*$self}{net_ftp_listen}) {
+ $conn = $listen->accept($pkg) or return;
+ close($listen);
+ }
+
+ if (( ${*$self}{net_ftp_tlstype} || '') eq 'P'
+ && ! $conn->start_SSL( $self->is_ssl
+ ? ( SSL_reuse_ctx => $self )
+ : ( %{${*$self}{net_ftp_tlsargs}} )
+ ) ) {
+ croak("failed to ssl upgrade dataconn: $SSL_ERROR");
+ return;
+ }
+
+ $conn->timeout($self->timeout);
+ ${*$self}{net_ftp_dataconn} = $conn;
+ ${*$conn} = "";
+ ${*$conn}{net_ftp_cmd} = $self;
+ ${*$conn}{net_ftp_blksize} = ${*$self}{net_ftp_blksize};
+ return $conn;
+ };
+}
+
+{
+ # Session Cache with single entry
+ # used to make sure that we reuse same session for control channel and data
+ package Net::SSLGlue::FTP::SingleSessionCache;
+ sub new { my $x; return bless \$x,shift }
+ sub add_session {
+ my ($self,$key,$session) = @_;
+ Net::SSLeay::SESSION_free($$self) if $$self;
+ $$self = $session;
+ }
+ sub get_session {
+ my $self = shift;
+ return $$self
+ }
+ sub DESTROY {
+ my $self = shift;
+ Net::SSLeay::SESSION_free($$self) if $$self;
+ }
+}
+
+1;
+
+=head1 NAME
+
+Net::SSLGlue::FTP - extend Net::FTP for FTPS (SSL) and IPv6
+
+=head1 SYNOPSIS
+
+ use Net::SSLGlue::FTP;
+ # SSL right from start
+ my $ftps = Net::FTP->new( $host,
+ SSL => 1,
+ SSL_ca_path => ...
+ );
+
+ # SSL through upgrade of plain connection
+ my $ftp = Net::FTP->new( $host );
+ $ftp->starttls( SSL_ca_path => ... );
+
+ # change protection mode to unencrypted|encrypted
+ $ftp->prot('C'); # clear
+ $ftp->prot('P'); # protected
+
+=head1 DESCRIPTION
+
+L<Net::SSLGlue::FTP> extends L<Net::FTP> so one can either start directly with
+SSL or switch later to SSL using starttls method (AUTH TLS command).
+If IO::Socket::IP or IO::Socket::INET6 are installed it will also transparently
+use IPv6.
+
+By default it will take care to verify the certificate according to the rules
+for FTP implemented in L<IO::Socket::SSL>.
+
+=head1 METHODS
+
+=over 4
+
+=item new
+
+The method C<new> of L<Net::FTP> is now able to start directly with SSL when
+the argument C<<SSL => 1>> is given. One can give the usual C<SSL_*> parameter
+of L<IO::Socket::SSL> to C<Net::FTP::new>.
+
+=item starttls
+
+If the connection is not yet SSLified it will issue the "AUTH TLS" command and
+change the object, so that SSL will now be used. The usual C<SSL_*> parameter of
+L<IO::Socket::SSL> will be given.
+
+=item peer_certificate ...
+
+Once the SSL connection is established you can use this method to get
+information about the certificate. See the L<IO::Socket::SSL> documentation.
+
+=back
+
+All of these methods can take the C<SSL_*> parameter from L<IO::Socket::SSL> to
+change the behavior of the SSL connection. The following parameters are
+especially useful:
+
+=over 4
+
+=item SSL_ca_path, SSL_ca_file
+
+Specifies the path or a file where the CAs used for checking the certificates
+are located. This is typically L</etc/ssl/certs> on UNIX systems.
+
+=item SSL_verify_mode
+
+If set to 0, verification of the certificate will be disabled. By default
+it is set to 1 which means that the peer certificate is checked.
+
+=item SSL_verifycn_name
+
+Usually the name given as the hostname in the constructor is used to verify the
+identity of the certificate. If you want to check the certificate against
+another name you can specify it with this parameter.
+
+=back
+
+=head1 SEE ALSO
+
+IO::Socket::SSL, Net::FTP, Net::SSLGlue::Socket
+
+=head1 COPYRIGHT
+
+This module is copyright (c) 2013, Steffen Ullrich.
+All Rights Reserved.
+This module is free software. It may be used, redistributed and/or modified
+under the same terms as Perl itself.
diff --git a/lib/Net/SSLGlue/Socket.pm b/lib/Net/SSLGlue/Socket.pm
new file mode 100644
index 0000000..a8e8842
--- /dev/null
+++ b/lib/Net/SSLGlue/Socket.pm
@@ -0,0 +1,204 @@
+
+package Net::SSLGlue::Socket;
+our $VERSION = 1.001;
+
+use strict;
+use warnings;
+use Carp 'croak';
+use Symbol 'gensym';
+use IO::Socket::SSL;
+my $IPCLASS;
+BEGIN {
+ for(qw(IO::Socket::IP IO::Socket::INET6 IO::Socket::INET)) {
+ $IPCLASS = $_,last if eval "require $_";
+ }
+}
+
+# this can be overwritten (with local) to get arguments passed around
+# to strict calls of the socket class new
+our %ARGS;
+
+sub new {
+ my $class = shift;
+ my %args = @_>1 ? @_ : ( PeerAddr => shift() );
+ %args = ( %args, %ARGS );
+
+ my %sslargs;
+ for(keys %args) {
+ $sslargs{$_} = delete $args{$_} if m{^SSL_};
+ }
+
+ my $ssl = delete $args{SSL};
+ my $sock = $ssl
+ ? IO::Socket::SSL->new(%args,%sslargs)
+ : $IPCLASS->new(%args)
+ or return;
+
+ my $self = gensym();
+ *$self = *$sock; # clone handle
+ bless $self,$class;
+ ${*$self}{sock} = $sock;
+ ${*$self}{ssl} = $ssl;
+ ${*$self}{sslargs} = \%sslargs;
+
+ return $self;
+}
+
+for my $sub (qw(
+ fileno sysread syswrite close connect fcntl
+ read write readline print printf getc say eof getline getlines
+ blocking autoflush timeout
+ sockhost sockport peerhost peerport sockdomain
+ truncate stat setbuf setvbuf fdopen ungetc send recv
+)) {
+ no strict 'refs';
+ *$sub = sub {
+ my $self = shift;
+ my $sock = ${*$self}{sock} or return;
+ my $sock_sub = $sock->can($sub) or croak("$sock does not support $sub");
+ unshift @_,$sock;
+ # warn "*** $sub called";
+ goto &$sock_sub;
+ };
+}
+
+sub accept {
+ my ($self,$class) = @_;
+ my $sock = ${*$self}{sock} or return;
+ my $conn = $sock->accept();
+
+ return bless $conn,$class
+ if $class && ! $class->isa('Net::SSLGlue::Socket');
+
+ $class ||= ref($self);
+ my $wrap = gensym;
+ *$wrap = *$conn; # clone original handle
+ bless $wrap, $class;
+ ${*$wrap}{sock} = $conn;
+ ${*$wrap}{ssl} = ${*$self}{ssl};
+ ${*$wrap}{sslargs} = ${*$self}{sslargs};
+ return $wrap;
+};
+
+sub start_SSL {
+ my $self = shift;
+ croak("start_SSL called on SSL socket") if ${*$self}{ssl};
+ IO::Socket::SSL->start_SSL(${*$self}{sock},%{${*$self}{sslargs}}, at _)
+ or return;
+ ${*$self}{ssl} = 1;
+ return $self;
+}
+
+sub stop_SSL {
+ my $self = shift;
+ croak("stop_SSL called on plain socket") if ! ${*$self}{ssl};
+ ${*$self}{sock}->stop_SSL(@_) or return;
+ ${*$self}{ssl} = 0;
+ return $self;
+}
+
+sub can_read {
+ my ($self,$timeout) = @_;
+ return 1 if ${*$self}{ssl} && ${*$self}{sock}->pending;
+ vec( my $vec,fileno(${*$self}{sock}),1) = 1;
+ return select($vec,undef,undef,$timeout);
+}
+
+sub peer_certificate {
+ my $self = shift;
+ return ${*$self}{ssl} && ${*$self}{sock}->peer_certificate(@_);
+}
+
+sub is_ssl {
+ my $self = shift;
+ return ${*$self}{ssl} && ${*$self}{sock};
+}
+
+1;
+
+=head1 NAME
+
+Net::SSLGlue::Socket - socket which can be either SSL or plain IP (IPv4/IPv6)
+
+=head1 SYNOPSIS
+
+ use Net::SSLGlue::Socket;
+ # SSL right from start
+ my $ssl = Net::SSLGlue::Socket->new(
+ PeerHost => ..., # IPv4|IPv6 address
+ PeerPort => ...,
+ SSL => 1,
+ SSL_ca_path => ...
+ );
+
+ # SSL through upgrade of plain connection
+ my $plain = Net::SSLGlue::Socket->new(...);
+ $plain->start_SSL( SSL_ca_path => ... );
+ ...
+ $plain->stop_SSL
+
+
+=head1 DESCRIPTION
+
+L<Net::SSLGlue::Socket> implements a socket which can be either plain or SSL.
+If IO::Socket::IP or IO::Socket::INET6 are installed it will also transparently
+handle IPv6 connections.
+
+A socket can be either start directly with SSL or it can be start plain and
+later be upgraded to SSL (because of a STARTTLS commando or similar) and also
+downgraded again.
+
+It is possible but not recommended to use the socket in non-blocking
+mode, because in this case special care must be taken with SSL (see
+documentation of L<IO::Socket::SSL>).
+
+Additionally to the usual socket methods the following methods are defined or
+extended:
+
+=head1 METHODS
+
+=over 4
+
+=item new
+
+The method C<new> of L<Net::SSLGlue::Socket> can have the argument SSL. If this
+is true the SSL upgrade will be done immediatly. If not set any SSL_* args will
+still be saved and used at a later start_SSL call.
+
+=item start_SSL
+
+This will upgrade the plain socket to SSL. See L<IO::Socket::SSL> for
+arguments to C<start_SSL>. Any SSL_* arguments given to new will be applied
+here too.
+
+=item stop_SSL
+
+This will downgrade the socket from SSL to plain.
+
+=item peer_certificate ...
+
+Once the SSL connection is established you can use this method to get
+information about the certificate. See the L<IO::Socket::SSL> documentation.
+
+=item can_read(timeout)
+
+This will check for available data. For a plain socket this will only use
+C<select> to check the socket, but for SSL it will check if there are any
+pending data before trying a select.
+Because SSL needs to read the whole frame before decryption can be done, a
+successful return of can_read is no guarantee that data can be read
+immediatly, only that new data are either available or in the process of
+arriving.
+
+=back
+
+=head1 SEE ALSO
+
+IO::Socket::SSL
+
+=head1 COPYRIGHT
+
+This module is copyright (c) 2013, Steffen Ullrich.
+All Rights Reserved.
+This module is free software. It may be used, redistributed and/or modified
+under the same terms as Perl itself.
diff --git a/t/external/02_smtp.t b/t/external/02_smtp.t
index 4edad8d..abc16ed 100644
--- a/t/external/02_smtp.t
+++ b/t/external/02_smtp.t
@@ -38,20 +38,8 @@ IO::Socket::SSL->new(
exit
};
-# ssl to the wrong host
-# the certificate mail.gmx.de returns is for mail.gmx.net
-diag( "connect ssl to mail.gmx.de:465" );
-IO::Socket::SSL->new(
- PeerAddr => 'mail.gmx.de:465',
- SSL_ca_path => $capath,
- SSL_verify_mode => 1,
- SSL_verifycn_scheme => 'smtp'
-) and do {
- print "1..0 # mail.gmx.de:465 reachable with SSL\n";
- exit
-};
-print "1..6\n";
+print "1..3\n";
# first direct SSL
my $smtp = Net::SMTP->new( 'mail.gmx.net',
@@ -67,20 +55,6 @@ print $ok ? "ok\n" : "not ok # smtp starttls mail.gmx.net\n";
# check that we can talk on connection
print $smtp->quit ? "ok\n": "not ok # quit failed\n";
-# against wrong host should fail
-$smtp = Net::SMTP->new( 'mail.gmx.de' ); # should succeed
-$ok = $smtp->starttls( SSL_ca_path => $capath );
-print $ok ? "not ok # smtp starttls mail.gmx.de did not fail\n": "ok\n";
-
-# but not if we specify the right SSL_verifycn_name
-$smtp = Net::SMTP->new( 'mail.gmx.de' ); # should succeed
-$ok = $smtp->starttls( SSL_ca_path => $capath, SSL_verifycn_name => 'mail.gmx.net' );
-print $ok ? "ok\n" : "not ok # smtp starttls mail.gmx.de/net\n";
-
-# or disable verification
-$smtp = Net::SMTP->new( 'mail.gmx.de' ); # should succeed
-$ok = $smtp->starttls( SSL_verify_mode => 0 );
-print $ok ? "ok\n" : "not ok # smtp starttls mail.gmx.de\n";
sub diag {
#print STDERR "@_\n"
diff --git a/t/external/03_lwp.t b/t/external/03_lwp.t
index cd167a2..a6f5853 100644
--- a/t/external/03_lwp.t
+++ b/t/external/03_lwp.t
@@ -3,73 +3,97 @@ use strict;
use warnings;
BEGIN {
- eval "use LWP";
- if ( $@ ) {
- print "1..0 # no LWP\n";
- exit
- }
+ eval "use LWP";
+ if ( $@ ) {
+ print "1..0 # no LWP\n";
+ exit
+ }
}
use Net::SSLGlue::LWP;
+use IO::Socket::SSL;
use LWP::Simple;
+my $goodhost = 'google.de';
+# this does not work any longer - will be skipped in test
+my $badhost = 'www.fedora.org';
+
my $capath = '/etc/ssl/certs/'; # unix?
-d $capath or do {
- print "1..0 # cannot find system CA-path\n";
- exit
+ print "1..0 # cannot find system CA-path\n";
+ exit
};
-Net::SSLGlue::LWP->import( SSL_ca_path => $capath );
+Net::SSLGlue::LWP->import(
+ SSL_ca_path => $capath,
+ # LWP might define SSL_ca_file - remove it to avoid conflict
+ SSL_ca_file => undef
+);
#
# first check everything directly with IO::Socket::SSL
#
-# signin.ebay.de has a certificate, which is for signin.ebay.com
-# but where signin.ebay.de is a subjectAltName
-IO::Socket::SSL->new(
- PeerAddr => 'signin.ebay.de:443',
- SSL_ca_path => $capath,
- SSL_verify_mode => 1,
- SSL_verifycn_scheme => 'http'
+diag("connecting to $goodhost:443 with IO::Socket::INET");
+my $sock = IO::Socket::INET->new(
+ PeerAddr => "$goodhost:443",
+ Timeout => 10
) or do {
- print "1..0 # ssl connect signin.ebay.de failed\n";
- exit
-};
-
-# www.fedora.org has a certificate which has nothing in common
-# with the hostname
-my $sock = IO::Socket::INET->new( 'www.fedora.org:443' ) or do {
- print "1..0 # connect to www.fedora.org failed\n";
- exit
+ print "1..0 # connect $goodhost failed: $!\n";
+ exit
};
+diag("ssl upgrade $goodhost");
IO::Socket::SSL->start_SSL( $sock,
+ SSL_ca_path => $capath,
+ SSL_verifycn_name => "$goodhost",
+ SSL_verify_mode => 1,
+ SSL_verifycn_scheme => 'http',
+) or do {
+ print "1..0 # ssl upgrade $goodhost failed: $SSL_ERROR\n";
+ exit
+};
+
+diag("connecting to $badhost:443 with IO::Socket::INET");
+if ( $sock = IO::Socket::INET->new(
+ PeerAddr => "$badhost:443",
+ Timeout => 10,
+)) {
+ diag("upgrading to https - should fail because of bad certificate");
+ if ( IO::Socket::SSL->start_SSL( $sock,
SSL_ca_path => $capath,
SSL_verify_mode => 1,
- SSL_verifycn_scheme => 'http'
-) and do {
- print "1..0 # certificate for www.fedora.org unexpectly correct\n";
- exit
-};
+ )) {
+ diag("certificate for $badhost unexpectly correct");
+ $badhost = undef;
+ };
+} else {
+ diag("connect to $badhost failed: $!");
+ $badhost = undef;
+}
#
# and than check, that LWP uses the same checks
#
-print "1..3\n";
+print "1..".( $badhost ? 3:1 )."\n";
-# signin.ebay.de -> should succeed
-my $content = get( 'https://signin.ebay.de' );
-print $content ? "ok\n": "not ok # lwp connect signin.ebay.de: $@\n";
+# $goodhost -> should succeed
+diag("connecting to $goodhost:443 with LWP");
+my $content = get( "https://$goodhost" );
+print $content ? "ok\n": "not ok # lwp connect $goodhost: $@\n";
-# www.fedora.org -> should fail
-$content = get( 'https://www.fedora.org' );
-print $content ? "not ok # lwp ssl connect www.fedora.org should fail\n": "ok\n";
+if ( $badhost ) {
+ # $badhost -> should fail
+ diag("connecting to $badhost:443 with LWP");
+ $content = get( 'https://$badhost' );
+ print $content ? "not ok # lwp ssl connect $badhost should fail\n": "ok\n";
-# www.fedora.org -> should succeed if verify mode is 0
-{
+ # $badhost -> should succeed if verify mode is 0
+ {
local %Net::SSLGlue::LWP::SSLopts = %Net::SSLGlue::LWP::SSLopts;
$Net::SSLGlue::LWP::SSLopts{SSL_verify_mode} = 0;
- $content = get( 'https://www.fedora.org' );
- print $content ? "ok\n": "not ok # lwp ssl www.fedora.org w/o ssl verify\n";
+ $content = get( 'https://$badhost' );
+ print $content ? "ok\n": "not ok # lwp ssl $badhost w/o ssl verify\n";
+ }
}
+sub diag { print "# @_\n" }
diff --git a/t/external/04_pop3.t b/t/external/04_pop3.t
index 4fc3b7e..917a167 100644
--- a/t/external/04_pop3.t
+++ b/t/external/04_pop3.t
@@ -38,20 +38,8 @@ IO::Socket::SSL->new(
exit
};
-# ssl to the wrong host
-# the certificate pop.gmx.de returns is for pop.gmx.net
-diag( "connect ssl to pop.gmx.de:995" );
-IO::Socket::SSL->new(
- PeerAddr => 'pop.gmx.de:995',
- SSL_ca_path => $capath,
- SSL_verify_mode => 1,
- SSL_verifycn_scheme => 'smtp'
-) and do {
- print "1..0 # pop.gmx.de:995 reachable with SSL\n";
- exit
-};
-print "1..6\n";
+print "1..3\n";
# first direct SSL
my $smtp = Net::POP3->new( 'pop.gmx.net',
@@ -67,21 +55,6 @@ print $ok ? "ok\n" : "not ok # smtp starttls pop.gmx.net\n";
# check that we can talk on connection
print $smtp->quit ? "ok\n": "not ok # quit failed\n";
-# against wrong host should fail
-$smtp = Net::POP3->new( 'pop.gmx.de' ); # should succeed
-$ok = $smtp->starttls( SSL_ca_path => $capath );
-print $ok ? "not ok # smtp starttls pop.gmx.de did not fail\n": "ok\n";
-
-# but not if we specify the right SSL_verifycn_name
-$smtp = Net::POP3->new( 'pop.gmx.de' ); # should succeed
-$ok = $smtp->starttls( SSL_ca_path => $capath, SSL_verifycn_name => 'pop.gmx.net' );
-print $ok ? "ok\n" : "not ok # smtp starttls pop.gmx.de/net\n";
-
-# or disable verification
-$smtp = Net::POP3->new( 'pop.gmx.de' ); # should succeed
-$ok = $smtp->starttls( SSL_verify_mode => 0 );
-print $ok ? "ok\n" : "not ok # smtp starttls pop.gmx.de\n";
-
sub diag {
#print STDERR "@_\n"
}
diff --git a/t/external/05_ftp.t b/t/external/05_ftp.t
new file mode 100644
index 0000000..7a8cbbf
--- /dev/null
+++ b/t/external/05_ftp.t
@@ -0,0 +1,169 @@
+
+use strict;
+use warnings;
+use Test::More;
+
+my $server = 'ftp.rebex.net';
+my $debug = 0;
+
+BEGIN {
+ eval "use Net::FTP";
+ if ( $@ ) {
+ print "1..0 # no Net::FTP\n";
+ exit
+ }
+}
+
+use Net::SSLGlue::FTP;
+use IO::Socket::SSL;
+use File::Temp;
+
+# first try to connect w/o ftp
+# plain
+diag( "connect inet to $server:21" );
+IO::Socket::INET->new( "$server:21" ) or do {
+ plan skip_all => "$server:21 not reachable";
+};
+
+# ssl to the right host
+diag( "connect inet to $server:990" );
+my $sock = IO::Socket::INET->new( "$server:990") or do {
+ plan skip_all => "$server:999 not reachable";
+};
+
+# now we need CAs
+my $cafh = File::Temp->new( UNLINK => 0, SUFFIX => '.crt' );
+my %sslargs = ( SSL_ca_file => $cafh->filename );
+print $cafh <DATA>;
+close($cafh);
+
+diag( "upgrade to ssl $server:990" );
+IO::Socket::SSL->start_SSL($sock,
+ %sslargs,
+ SSL_verify_mode => 1,
+ SSL_verifycn_name => $server,
+ SSL_verifycn_scheme => 'ftp'
+) or do {
+ plan skip_all => "$server:999 not upgradable to SSL: $SSL_ERROR";
+};
+
+plan tests => 9;
+
+# first direct SSL
+diag( "connect ftp over ssl to $server" );
+my $ftp = Net::FTP->new($server,
+ SSL => 1,
+ %sslargs,
+ Debug => $debug,
+ Passive => 1,
+);
+ok($ftp,"ftp ssl connect $server");
+$ftp->login("anonymous",'net-sslglue-ftp at test.perl')
+ or die "login to $server failed";
+diag("logged in");
+# check that we can talk on connection
+ok(~~$ftp->ls,"directory listing protected");
+$ftp->prot('C');
+ok(~~$ftp->ls,"directory listing clear");
+
+# then TLS upgrade inside plain connection
+$ftp = Net::FTP->new($server, Passive => 1, Debug => $debug);
+ok($ftp,"ftp plain connect $server");
+my $ok = $ftp->starttls(%sslargs);
+ok($ok,"ssl upgrade");
+$ftp->login("anonymous",'net-sslglue-ftp at test.perl')
+ or die "login to $server failed";
+diag("logged in");
+# check that we can talk on connection
+ok(~~$ftp->ls,"directory listing protected");
+$ftp->prot('C');
+ok(~~$ftp->ls,"directory listing clear");
+$ok = $ftp->stoptls;
+ok($ok,"ssl downgrade");
+ok(~~$ftp->ls,"directory listing after downgrade");
+
+
+__DATA__
+# Subject: C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Class 1 Primary Intermediate Server CA
+# Issuer: C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Certification Authority
+-----BEGIN CERTIFICATE-----
+MIIGNDCCBBygAwIBAgIBGDANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
+MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
+Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkwHhcNMDcxMDI0MjA1NDE3WhcNMTcxMDI0MjA1NDE3WjCB
+jDELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsT
+IlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcxODA2BgNVBAMTL1N0
+YXJ0Q29tIENsYXNzIDEgUHJpbWFyeSBJbnRlcm1lZGlhdGUgU2VydmVyIENBMIIB
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtonGrO8JUngHrJJj0PREGBiE
+gFYfka7hh/oyULTTRwbw5gdfcA4Q9x3AzhA2NIVaD5Ksg8asWFI/ujjo/OenJOJA
+pgh2wJJuniptTT9uYSAK21ne0n1jsz5G/vohURjXzTCm7QduO3CHtPn66+6CPAVv
+kvek3AowHpNz/gfK11+AnSJYUq4G2ouHI2mw5CrY6oPSvfNx23BaKA+vWjhwRRI/
+ME3NO68X5Q/LoKldSKqxYVDLNM08XMML6BDAjJvwAwNi/rJsPnIO7hxDKslIDlc5
+xDEhyBDBLIf+VJVSH1I8MRKbf+fAoKVZ1eKPPvDVqOHXcDGpxLPPr21TLwb0pwID
+AQABo4IBrTCCAakwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
+VR0OBBYEFOtCNNCYsKuf9BtrCPfMZC7vDixFMB8GA1UdIwQYMBaAFE4L7xqkQFul
+F2mHMMo0aEPQQa7yMGYGCCsGAQUFBwEBBFowWDAnBggrBgEFBQcwAYYbaHR0cDov
+L29jc3Auc3RhcnRzc2wuY29tL2NhMC0GCCsGAQUFBzAChiFodHRwOi8vd3d3LnN0
+YXJ0c3NsLmNvbS9zZnNjYS5jcnQwWwYDVR0fBFQwUjAnoCWgI4YhaHR0cDovL3d3
+dy5zdGFydHNzbC5jb20vc2ZzY2EuY3JsMCegJaAjhiFodHRwOi8vY3JsLnN0YXJ0
+c3NsLmNvbS9zZnNjYS5jcmwwgYAGA1UdIAR5MHcwdQYLKwYBBAGBtTcBAgEwZjAu
+BggrBgEFBQcCARYiaHR0cDovL3d3dy5zdGFydHNzbC5jb20vcG9saWN5LnBkZjA0
+BggrBgEFBQcCARYoaHR0cDovL3d3dy5zdGFydHNzbC5jb20vaW50ZXJtZWRpYXRl
+LnBkZjANBgkqhkiG9w0BAQUFAAOCAgEAIQlJPqWIbuALi0jaMU2P91ZXouHTYlfp
+tVbzhUV1O+VQHwSL5qBaPucAroXQ+/8gA2TLrQLhxpFy+KNN1t7ozD+hiqLjfDen
+xk+PNdb01m4Ge90h2c9W/8swIkn+iQTzheWq8ecf6HWQTd35RvdCNPdFWAwRDYSw
+xtpdPvkBnufh2lWVvnQce/xNFE+sflVHfXv0pQ1JHpXo9xLBzP92piVH0PN1Nb6X
+t1gW66pceG/sUzCv6gRNzKkC4/C2BBL2MLERPZBOVmTX3DxDX3M570uvh+v2/miI
+RHLq0gfGabDBoYvvF0nXYbFFSF87ICHpW7LM9NfpMfULFWE7epTj69m8f5SuauNi
+YpaoZHy4h/OZMn6SolK+u/hlz8nyMPyLwcKmltdfieFcNID1j0cHL7SRv7Gifl9L
+WtBbnySGBVFaaQNlQ0lxxeBvlDRr9hvYqbBMflPrj0jfyjO1SPo2ShpTpjMM0InN
+SRXNiTE8kMBy12VLUjWKRhFEuT2OKGWmPnmeXAhEKa2wNREuIU640ucQPl2Eg7PD
+wuTSxv0JS3QJ3fGz0xk+gA2iCxnwOOfFwq/iI9th4p1cbiCJSS4jarJiwUW0n6+L
+p/EiO/h94pDQehn7Skzj0n1fSoMD7SfWI55rjbRZotnvbIIp3XUZPD9MEI3vu3Un
+0q6Dp6jOW6c=
+-----END CERTIFICATE-----
+# Subject: C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Certification Authority
+# Issuer: C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Certification Authority
+-----BEGIN CERTIFICATE-----
+MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEW
+MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
+Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM3WhcNMzYwOTE3MTk0NjM2WjB9
+MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
+U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
+cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA
+A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk
+pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf
+OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C
+Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT
+Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi
+HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM
+Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w
++2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+
+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3
+Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B
+26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID
+AQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
+VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFul
+F2mHMMo0aEPQQa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCC
+ATgwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w
+ZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVybWVk
+aWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENvbW1lcmNpYWwgKFN0
+YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0aGUg
+c2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0
+aWZpY2F0aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93
+d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgG
+CWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1
+dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5fPGFf59Jb2vKXfuM/gTF
+wWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWmN3PH/UvS
+Ta0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst
+0OcNOrg+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNc
+pRJvkrKTlMeIFw6Ttn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKl
+CcWw0bdT82AUuoVpaiF8H3VhFyAXe2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVF
+P0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA2MFrLH9ZXF2RsXAiV+uKa0hK
+1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBsHvUwyKMQ5bLm
+KhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE
+JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ
+8dCAWZvLMdibD4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnm
+fyWl8kgAwKQB2j8=
+-----END CERTIFICATE-----
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libnet-sslglue-perl.git
More information about the Pkg-perl-cvs-commits
mailing list