Codebase list libnet-sslglue-perl / b4eea3f
Merge tag 'upstream/1.054' into upstream Upstream version 1.054 gregor herrmann 8 years ago
12 changed file(s) with 629 addition(s) and 495 deletion(s). Raw diff Collapse all Expand all
0 1.054 2015/04/28
1 - if a version of libnet is detected which already supports TLS (i.e.
2 libnet 3.0+) warn and use this instead.
3
4 1.053 2014/05/28
5 - if current LWP is detected is use this mostly unpatched
6 - fix Net::SSLGlue::FTP to use the same hostname when verifying the
7 certificate of the data connection
8
09 1.052 2014/01/16
110 - FTPS: reuse same SSL session for control and data channnel to work
211 with default configuration of proftpd.
2121 t/external/03_lwp.t
2222 t/external/04_pop3.t
2323 t/external/05_ftp.t
24 META.yml Module meta-data (added by MakeMaker)
24 META.yml Module YAML meta-data (added by MakeMaker)
25 META.json Module JSON meta-data (added by MakeMaker)
0 {
1 "abstract" : "unknown",
2 "author" : [
3 "unknown"
4 ],
5 "dynamic_config" : 1,
6 "generated_by" : "ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.120921",
7 "license" : [
8 "unknown"
9 ],
10 "meta-spec" : {
11 "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
12 "version" : "2"
13 },
14 "name" : "Net-SSLGlue",
15 "no_index" : {
16 "directory" : [
17 "t",
18 "inc"
19 ]
20 },
21 "prereqs" : {
22 "build" : {
23 "requires" : {
24 "ExtUtils::MakeMaker" : "0"
25 }
26 },
27 "configure" : {
28 "requires" : {
29 "ExtUtils::MakeMaker" : "0"
30 }
31 },
32 "runtime" : {
33 "requires" : {
34 "IO::Socket::SSL" : "1.19"
35 }
36 }
37 },
38 "release_status" : "stable",
39 "resources" : {
40 "repository" : {
41 "url" : "https://github.com/noxxi/p5-net-sslglue"
42 }
43 },
44 "version" : "1.054"
45 }
0 --- #YAML:1.0
1 name: Net-SSLGlue
2 version: 1.052
3 abstract: ~
4 author: []
5 license: unknown
6 distribution_type: module
0 ---
1 abstract: unknown
2 author:
3 - unknown
4 build_requires:
5 ExtUtils::MakeMaker: 0
76 configure_requires:
8 ExtUtils::MakeMaker: 0
9 build_requires:
10 ExtUtils::MakeMaker: 0
7 ExtUtils::MakeMaker: 0
8 dynamic_config: 1
9 generated_by: 'ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.120921'
10 license: unknown
11 meta-spec:
12 url: http://module-build.sourceforge.net/META-spec-v1.4.html
13 version: 1.4
14 name: Net-SSLGlue
15 no_index:
16 directory:
17 - t
18 - inc
1119 requires:
12 IO::Socket::SSL: 1.19
20 IO::Socket::SSL: 1.19
1321 resources:
14 repository: https://github.com/noxxi/p5-net-sslglue
15 no_index:
16 directory:
17 - t
18 - inc
19 generated_by: ExtUtils::MakeMaker version 6.57_05
20 meta-spec:
21 url: http://module-build.sourceforge.net/META-spec-v1.4.html
22 version: 1.4
22 repository: https://github.com/noxxi/p5-net-sslglue
23 version: 1.054
77 use Net::SSLGlue::Socket;
88 use Socket 'AF_INET';
99
10 our $VERSION = 1.001;
10 our $VERSION = 1.002;
1111
1212 BEGIN {
13 require Net::FTP;
14 if (defined &Net::FTP::starttls) {
15 warn "using SSL support of Net::FTP $Net::FTP::VERSION instead of SSLGlue";
16 goto DONE;
17 }
18
19 $Net::FTP::VERSION eq '2.77'
20 or warn "Not tested with Net::FTP version $Net::FTP::VERSION";
21
22 require Net::FTP::dataconn;
1323 for my $class (qw(Net::FTP Net::FTP::dataconn)) {
14 eval "require $class" or die "failed to load $class";
1524 no strict 'refs';
1625 my $fixed;
1726 for( @{ "${class}::ISA" } ) {
2332 die "cannot replace IO::Socket::INET with Net::SSLGlue::Socket in ${class}::ISA"
2433 if ! $fixed;
2534 }
26 $Net::FTP::VERSION eq '2.77'
27 or warn "Not tested with Net::FTP version $Net::FTP::VERSION";
28 }
29
30 # redefine Net::FTP::new so that it understands SSL => 1 and connects directly
31 # with SSL to the server
32 {
35
36 # redefine Net::FTP::new so that it understands SSL => 1 and connects directly
37 # with SSL to the server
3338 no warnings 'redefine';
3439 my $onew = Net::FTP->can('new');
3540 *Net::FTP::new = sub {
5257 ${*$self}{net_ftp_tlsargs} = \%sslargs;
5358 return $self;
5459 };
55 }
56
57 # add starttls method to upgrade connection to SSL: AUTH TLS
58 sub Net::FTP::starttls {
59 my $self = shift;
60 $self->is_ssl and croak("called starttls within SSL session");
61 $self->_AUTH('TLS') == Net::FTP::CMD_OK or return;
62
63 my $host = $self->host;
64 # for name verification strip port from domain:port, ipv4:port, [ipv6]:port
65 $host =~s{(?<!:):\d+$}{};
66
67 my %args = (
68 SSL_verify_mode => 1,
69 SSL_verifycn_scheme => 'ftp',
70 SSL_verifycn_name => $host,
71 # reuse SSL session of control connection in data connections
72 SSL_session_cache => Net::SSLGlue::FTP::SingleSessionCache->new,
73 %{ ${*$self}{net_ftp_tlsargs}},
74 @_
75 );
76
77 $self->start_SSL(%args) or return;
78 ${*$self}{net_ftp_tlsargs} = \%args;
79 $self->prot('P');
80 return 1;
81 }
82
83 # add prot method to set protection level (PROT C|P)
84 sub Net::FTP::prot {
85 my ($self,$type) = @_;
86 $type eq 'C' or $type eq 'P' or croak("type must by C or P");
87 $self->_PBSZ(0) or return;
88 $self->_PROT($type) or return;
89 ${*$self}{net_ftp_tlstype} = $type;
90 return 1;
91 }
92
93 # add stoptls method to downgrade connection from SSL: CCC
94 sub Net::FTP::stoptls {
95 my $self = shift;
96 $self->is_ssl or croak("called stoptls outside SSL session");
97 $self->_CCC() or return;
98 $self->stop_SSL();
99 return 1;
100 }
101
102 # add EPSV for new style passive mode (incl. IPv6)
103 sub Net::FTP::epsv {
104 my $self = shift;
105 @_ and croak 'usage: $ftp->epsv()';
106 delete ${*$self}{net_ftp_intern_port};
107
108 $self->_EPSV && $self->message =~ m{\(([\x33-\x7e])\1\1(\d+)\1\)}
109 ? ${*$self}{'net_ftp_pasv'} = [ $self->peerhost, $2 ]
110 : undef;
111 }
112
113 # redefine PASV so that it uses EPSV on IPv6
114 # also net_ftp_pasv contains now the parsed [ip,port]
115 {
116 no warnings 'redefine';
60
61 # add starttls method to upgrade connection to SSL: AUTH TLS
62 *Net::FTP::starttls = sub {
63 my $self = shift;
64 $self->is_ssl and croak("called starttls within SSL session");
65 $self->_AUTH('TLS') == &Net::FTP::CMD_OK or return;
66
67 my $host = $self->host;
68 # for name verification strip port from domain:port, ipv4:port, [ipv6]:port
69 $host =~s{(?<!:):\d+$}{};
70
71 my %args = (
72 SSL_verify_mode => 1,
73 SSL_verifycn_scheme => 'ftp',
74 SSL_verifycn_name => $host,
75 # reuse SSL session of control connection in data connections
76 SSL_session_cache => Net::SSLGlue::FTP::SingleSessionCache->new,
77 %{ ${*$self}{net_ftp_tlsargs}},
78 @_
79 );
80
81 $self->start_SSL(%args) or return;
82 ${*$self}{net_ftp_tlsargs} = \%args;
83 $self->prot('P');
84 return 1;
85 };
86
87 # add prot method to set protection level (PROT C|P)
88 *Net::FTP::prot = sub {
89 my ($self,$type) = @_;
90 $type eq 'C' or $type eq 'P' or croak("type must by C or P");
91 $self->_PBSZ(0) or return;
92 $self->_PROT($type) or return;
93 ${*$self}{net_ftp_tlstype} = $type;
94 return 1;
95 };
96
97 # add stoptls method to downgrade connection from SSL: CCC
98 *Net::FTP::stoptls = sub {
99 my $self = shift;
100 $self->is_ssl or croak("called stoptls outside SSL session");
101 $self->_CCC() or return;
102 $self->stop_SSL();
103 return 1;
104 };
105
106 # add EPSV for new style passive mode (incl. IPv6)
107 *Net::FTP::epsv = sub {
108 my $self = shift;
109 @_ and croak 'usage: $ftp->epsv()';
110 delete ${*$self}{net_ftp_intern_port};
111
112 $self->_EPSV && $self->message =~ m{\(([\x33-\x7e])\1\1(\d+)\1\)}
113 ? ${*$self}{'net_ftp_pasv'} = [ $self->peerhost, $2 ]
114 : undef;
115 };
116
117 # redefine PASV so that it uses EPSV on IPv6
118 # also net_ftp_pasv contains now the parsed [ip,port]
117119 *Net::FTP::pasv = sub {
118120 my $self = shift;
119121 @_ and croak 'usage: $ftp->port()';
128130 }
129131 return;
130132 };
131 }
132
133 # add EPRT for new style passive mode (incl. IPv6)
134 sub Net::FTP::eprt {
135 @_ == 1 || @_ == 2 or croak 'usage: $self->eprt([PORT])';
136 return _eprt('EPRT',@_);
137 }
138
139 # redefine PORT to use EPRT for IPv6
140 {
141 no warnings 'redefine';
133
134 # add EPRT for new style passive mode (incl. IPv6)
135 *Net::FTP::eprt = sub {
136 @_ == 1 || @_ == 2 or croak 'usage: $self->eprt([PORT])';
137 return _eprt('EPRT',@_);
138 };
139
140 # redefine PORT to use EPRT for IPv6
142141 *Net::FTP::port = sub {
143142 @_ == 1 || @_ == 2 or croak 'usage: $self->port([PORT])';
144143 return _eprt('PORT',@_);
145144 };
146 }
147
148 sub _eprt {
149 my ($cmd,$self,$port) = @_;
150 delete ${*$self}{net_ftp_intern_port};
151 unless ($port) {
152 my $listen = ${*$self}{net_ftp_listen} ||= Net::SSLGlue::Socket->new(
153 Listen => 1,
154 Timeout => $self->timeout,
155 LocalAddr => $self->sockhost,
156 );
157 ${*$self}{net_ftp_intern_port} = 1;
158 my $fam = ($listen->sockdomain == AF_INET) ? 1:2;
159 if ( $cmd eq 'EPRT' || $fam == 2 ) {
160 $port = "|$fam|".$listen->sockhost."|".$listen->sockport."|";
161 $cmd = 'EPRT';
162 } else {
163 my $p = $listen->sockport;
164 $port = join(',',split(m{\.},$listen->sockhost),$p >> 8,$p & 0xff);
165 }
166 }
167 my $ok = $cmd eq 'EPRT' ? $self->_EPRT($port) : $self->_PORT($port);
168 ${*$self}{net_ftp_port} = $port if $ok;
169 return $ok;
170 }
171
172
173
174 for my $cmd (qw(PBSZ PROT CCC EPRT EPSV)) {
175 no strict 'refs';
176 *{"Net::FTP::_$cmd"} = sub {
177 shift->command("$cmd @_")->response() == Net::FTP::CMD_OK
178 }
179 }
180
181 # redefine _dataconn to
182 # - support IPv6
183 # - upgrade data connection to SSL if PROT P
184 {
185
186 no warnings 'redefine';
145
146 sub _eprt {
147 my ($cmd,$self,$port) = @_;
148 delete ${*$self}{net_ftp_intern_port};
149 unless ($port) {
150 my $listen = ${*$self}{net_ftp_listen} ||= Net::SSLGlue::Socket->new(
151 Listen => 1,
152 Timeout => $self->timeout,
153 LocalAddr => $self->sockhost,
154 );
155 ${*$self}{net_ftp_intern_port} = 1;
156 my $fam = ($listen->sockdomain == AF_INET) ? 1:2;
157 if ( $cmd eq 'EPRT' || $fam == 2 ) {
158 $port = "|$fam|".$listen->sockhost."|".$listen->sockport."|";
159 $cmd = 'EPRT';
160 } else {
161 my $p = $listen->sockport;
162 $port = join(',',split(m{\.},$listen->sockhost),$p >> 8,$p & 0xff);
163 }
164 }
165 my $ok = $cmd eq 'EPRT' ? $self->_EPRT($port) : $self->_PORT($port);
166 ${*$self}{net_ftp_port} = $port if $ok;
167 return $ok;
168 }
169
170
171
172 for my $cmd (qw(PBSZ PROT CCC EPRT EPSV)) {
173 no strict 'refs';
174 *{"Net::FTP::_$cmd"} = sub {
175 shift->command("$cmd @_")->response() == &Net::FTP::CMD_OK
176 }
177 }
178
179
180 # redefine _dataconn to
181 # - support IPv6
182 # - upgrade data connection to SSL if PROT P
187183 *Net::FTP::_dataconn = sub {
188184 my $self = shift;
189185 my $pkg = "Net::FTP::" . $self->type;
204200 }
205201
206202 if (( ${*$self}{net_ftp_tlstype} || '') eq 'P'
207 && ! $conn->start_SSL( $self->is_ssl
208 ? ( SSL_reuse_ctx => $self )
209 : ( %{${*$self}{net_ftp_tlsargs}} )
210 ) ) {
203 && ! $conn->start_SSL( $self->is_ssl ? (
204 SSL_reuse_ctx => $self,
205 SSL_verifycn_name => ${*$self}{net_ftp_tlsargs}->{SSL_verifycn_name}
206 ):(
207 %{${*$self}{net_ftp_tlsargs}}
208 )
209 )) {
211210 croak("failed to ssl upgrade dataconn: $SSL_ERROR");
212211 return;
213212 }
219218 ${*$conn}{net_ftp_blksize} = ${*$self}{net_ftp_blksize};
220219 return $conn;
221220 };
221
222 DONE:
223 1;
222224 }
223225
224226 {
287289 =item starttls
288290
289291 If the connection is not yet SSLified it will issue the "AUTH TLS" command and
290 change the object, so that SSL will now be used. The usual C<SSL_*> parameter of
291 L<IO::Socket::SSL> will be given.
292 change the object, so that SSL will now be used.
292293
293294 =item peer_certificate ...
294295
1111 # Net::LDAP::_SSL_context_init_args
1212
1313 my $old = defined &Net::LDAP::_SSL_context_init_args
14 && \&Net::LDAP::_SSL_context_init_args
15 || die "cannot find Net::LDAP::_SSL_context_init_args";
14 && \&Net::LDAP::_SSL_context_init_args
15 || die "cannot find Net::LDAP::_SSL_context_init_args";
1616 no warnings 'redefine';
1717 *Net::LDAP::_SSL_context_init_args = sub {
18 my %arg = $old->(@_);
19 $arg{SSL_verifycn_scheme} ||= 'ldap' if $arg{SSL_verify_mode};
20 while ( my ($k,$v) = each %SSLopts ) {
21 $arg{$k} = $v;
22 }
23 return %arg;
18 my %arg = $old->(@_);
19 $arg{SSL_verifycn_scheme} ||= 'ldap' if $arg{SSL_verify_mode};
20 while ( my ($k,$v) = each %SSLopts ) {
21 $arg{$k} = $v;
22 }
23 return %arg;
2424 };
2525
2626 1;
3131
3232 =head1 SYNOPSIS
3333
34 use Net::SSLGlue::LDAP;
35 local %Net::SSLGlue::LDAP = ( SSL_verifycn_name => $hostname_in_cert );
36 my $ldap = Net::LDAP->new( $hostname, capath => ... );
37 $ldap->start_tls;
34 use Net::SSLGlue::LDAP;
35 local %Net::SSLGlue::LDAP = ( SSL_verifycn_name => $hostname_in_cert );
36 my $ldap = Net::LDAP->new( $hostname, capath => ... );
37 $ldap->start_tls;
3838
3939
4040 =head1 DESCRIPTION
00 use strict;
11 use warnings;
22 package Net::SSLGlue::LWP;
3 our $VERSION = 0.4;
3 our $VERSION = 0.5;
44 use LWP::UserAgent '5.822';
55 use IO::Socket::SSL 1.19;
66 use URI;
77
88 # force Net::SSLGlue::LWP::Socket as superclass of Net::HTTPS, because
99 # only it can verify certificates
10 my $use_existent;
1011 BEGIN {
12 require LWP::Protocol::https;
13 $use_existent = $LWP::Protocol::https::VERSION >= 6.06
14 && $LWP::UserAgent::VERSION >= 6.06;
15 if ($use_existent) {
16 my $oc = $Net::HTTPS::SSL_SOCKET_CLASS ||
17 $ENV{PERL_NET_HTTPS_SSL_SOCKET_CLASS};
18 $use_existent = 0 if $oc && $oc ne 'IO::Socket::SSL';
19 }
20 if ($use_existent) {
21 warn "Your LWP::UserAgent/LWP::Protocol::https looks fine.\n".
22 "Will use it instead of Net::SSLGLue::LWP\n";
23 } else {
1124 my $oc = $Net::HTTPS::SSL_SOCKET_CLASS;
1225 $Net::HTTPS::SSL_SOCKET_CLASS = my $need = 'Net::SSLGlue::LWP::Socket';
1326 require Net::HTTPS;
14 require LWP::Protocol::https;
27
1528 if ( ( my $oc = $Net::HTTPS::SSL_SOCKET_CLASS ) ne $need ) {
16 # was probably loaded before, change ISA
17 grep { s{^\Q$oc\E$}{$need} } @Net::HTTPS::ISA
29 # was probably loaded before, change ISA
30 grep { s{^\Q$oc\E$}{$need} } @Net::HTTPS::ISA
1831 }
1932 die "cannot force $need into Net::HTTPS"
20 if $Net::HTTPS::SSL_SOCKET_CLASS ne $need;
21 }
33 if $Net::HTTPS::SSL_SOCKET_CLASS ne $need;
34 }
35 }
36
2237
2338 our %SSLopts; # set by local and import
2439 sub import {
25 shift;
26 %SSLopts = @_;
40 shift;
41 %SSLopts = @_;
42 }
43
44 if (!$use_existent) {
45 # add SSL options
46 my $old_eso = UNIVERSAL::can( 'LWP::Protocol::https','_extra_sock_opts' );
47 no warnings 'redefine';
48 *LWP::Protocol::https::_extra_sock_opts = sub {
49 return (
50 $old_eso ? ( $old_eso->(@_) ):(),
51 SSL_verify_mode => 1,
52 SSL_verifycn_scheme => 'http',
53 HTTPS_proxy => $_[0]->{ua}{https_proxy},
54 %SSLopts,
55 );
56 };
57
58 # fix https_proxy handling - forward it to a variable handled by me
59 my $old_proxy = defined &LWP::UserAgent::proxy && \&LWP::UserAgent::proxy
60 or die "cannot find LWP::UserAgent::proxy";
61 *LWP::UserAgent::proxy = sub {
62 my ($self,$key,$val) = @_;
63 goto &$old_proxy if ref($key) || $key ne 'https';
64 if (@_>2) {
65 my $rv = &$old_proxy;
66 $self->{https_proxy} = delete $self->{proxy}{https}
67 || die "https proxy not set?";
68 }
69 return $self->{https_proxy};
70 };
71
72 } else {
73 # wrapper around LWP::Protocol::https::_extra_sock_opts to support %SSLopts
74 my $old_eso = UNIVERSAL::can( 'LWP::Protocol::https','_extra_sock_opts' )
75 or die "no LWP::Protocol::https::_extra_sock_opts found";
76 no warnings 'redefine';
77 *LWP::Protocol::https::_extra_sock_opts = sub {
78 return (
79 $old_eso->(@_),
80 %SSLopts,
81 );
82 };
2783 }
2884
2985 {
30 # add SSL options
31 my $old_eso = UNIVERSAL::can( 'LWP::Protocol::https','_extra_sock_opts' );
32 no warnings 'redefine';
33 *LWP::Protocol::https::_extra_sock_opts = sub {
34 return (
35 $old_eso ? ( $old_eso->(@_) ):(),
36 SSL_verify_mode => 1,
37 SSL_verifycn_scheme => 'http',
38 HTTPS_proxy => $_[0]->{ua}{https_proxy},
39 %SSLopts,
40 );
86
87 package Net::SSLGlue::LWP::Socket;
88 use IO::Socket::SSL;
89 use base 'IO::Socket::SSL';
90 my $sockclass = 'IO::Socket::INET';
91 use URI::Escape 'uri_unescape';
92 use MIME::Base64 'encode_base64';
93 $sockclass .= '6' if eval "require IO::Socket::INET6";
94
95 sub configure {
96 my ($self,$args) = @_;
97 my $phost = delete $args->{HTTPS_proxy}
98 or return $self->SUPER::configure($args);
99 $phost = URI->new($phost) if ! ref $phost;
100
101 my $port = $args->{PeerPort};
102 my $host = $args->{PeerHost} || $args->{PeerAddr};
103 if ( ! $port ) {
104 $host =~s{:(\w+)$}{};
105 $port = $args->{PeerPort} = $1;
106 $args->{PeerHost} = $host;
107 }
108 if ( $phost->scheme ne 'http' ) {
109 $@ = "scheme ".$phost->scheme." not supported for https_proxy";
110 return;
111 }
112 my $auth = '';
113 if ( my ($user,$pass) = split( ':', $phost->userinfo || '' ) ) {
114 $auth = "Proxy-authorization: Basic ".
115 encode_base64( uri_unescape($user).':'.uri_unescape($pass),'' ).
116 "\r\n";
117 }
118
119 my $pport = $phost->port;
120 $phost = $phost->host;
121
122 # temporally downgrade $self so that the right connect chain
123 # gets called w/o doing SSL stuff. If we don't do it it will
124 # try to call IO::Socket::SSL::connect
125 my $ssl_class = ref($self);
126 bless $self,$sockclass;
127 $self->configure({ %$args, PeerAddr => $phost, PeerPort => $pport }) or do {
128 $@ = "connect to proxy $phost port $pport failed";
129 return;
41130 };
42 }
43
44 {
45 # fix https_proxy handling - forward it to a variable handled by me
46 my $old_proxy = defined &LWP::UserAgent::proxy && \&LWP::UserAgent::proxy
47 or die "cannot find LWP::UserAgent::proxy";
48 no warnings 'redefine';
49 *LWP::UserAgent::proxy = sub {
50 my ($self,$key,$val) = @_;
51 goto &$old_proxy if ref($key) || $key ne 'https';
52 if (@_>2) {
53 my $rv = &$old_proxy;
54 $self->{https_proxy} = delete $self->{proxy}{https}
55 || die "https proxy not set?";
56 }
57 return $self->{https_proxy};
58 }
59 }
60
61 {
62
63 package Net::SSLGlue::LWP::Socket;
64 use IO::Socket::SSL;
65 use base 'IO::Socket::SSL';
66 my $sockclass = 'IO::Socket::INET';
67 use URI::Escape 'uri_unescape';
68 use MIME::Base64 'encode_base64';
69 $sockclass .= '6' if eval "require IO::Socket::INET6";
70
71 sub configure {
72 my ($self,$args) = @_;
73 my $phost = delete $args->{HTTPS_proxy}
74 or return $self->SUPER::configure($args);
75 $phost = URI->new($phost) if ! ref $phost;
76
77 my $port = $args->{PeerPort};
78 my $host = $args->{PeerHost} || $args->{PeerAddr};
79 if ( ! $port ) {
80 $host =~s{:(\w+)$}{};
81 $port = $args->{PeerPort} = $1;
82 $args->{PeerHost} = $host;
83 }
84 if ( $phost->scheme ne 'http' ) {
85 $@ = "scheme ".$phost->scheme." not supported for https_proxy";
86 return;
87 }
88 my $auth = '';
89 if ( my ($user,$pass) = split( ':', $phost->userinfo || '' ) ) {
90 $auth = "Proxy-authorization: Basic ".
91 encode_base64( uri_unescape($user).':'.uri_unescape($pass),'' ).
92 "\r\n";
93 }
94
95 my $pport = $phost->port;
96 $phost = $phost->host;
97
98 # temporally downgrade $self so that the right connect chain
99 # gets called w/o doing SSL stuff. If we don't do it it will
100 # try to call IO::Socket::SSL::connect
101 my $ssl_class = ref($self);
102 bless $self,$sockclass;
103 $self->configure({ %$args, PeerAddr => $phost, PeerPort => $pport }) or do {
104 $@ = "connect to proxy $phost port $pport failed";
105 return;
106 };
107 print $self "CONNECT $host:$port HTTP/1.0\r\n$auth\r\n";
108 my $hdr = '';
109 while (<$self>) {
110 $hdr .= $_;
111 last if $_ eq "\n" or $_ eq "\r\n";
112 }
113 if ( $hdr !~m{\AHTTP/1.\d 2\d\d} ) {
114 # error
115 $@ = "non 2xx response to CONNECT: $hdr";
116 return;
117 }
118
119 # and upgrade self by calling start_SSL
120 $ssl_class->start_SSL( $self,
121 SSL_verifycn_name => $host,
122 %$args
123 ) or do {
124 $@ = "start SSL failed: $SSL_ERROR";
125 return;
126 };
127 return $self;
131 print $self "CONNECT $host:$port HTTP/1.0\r\n$auth\r\n";
132 my $hdr = '';
133 while (<$self>) {
134 $hdr .= $_;
135 last if $_ eq "\n" or $_ eq "\r\n";
136 }
137 if ( $hdr !~m{\AHTTP/1.\d 2\d\d} ) {
138 # error
139 $@ = "non 2xx response to CONNECT: $hdr";
140 return;
141 }
142
143 # and upgrade self by calling start_SSL
144 $ssl_class->start_SSL( $self,
145 SSL_verifycn_name => $host,
146 %$args
147 ) or do {
148 $@ = "start SSL failed: $SSL_ERROR";
149 return;
128150 };
151 return $self;
152 };
129153 }
130154
131155 1;
135159 Net::SSLGlue::LWP - proper certificate checking for https in LWP
136160
137161 =head1 SYNOPSIS
138
139 use Net::SSLGlue::LWP SSL_ca_path => ...;
140 use LWP::Simple;
141 get( 'https://www....' );
142
143 {
144 local %Net::SSLGlue::LWP::SSLopts = %Net::SSLGlue::LWP::SSLopts;
145
146 # switch off verification
147 $Net::SSLGlue::LWP::SSLopts{SSL_verify_mode} = 0;
148
149 # or: set different verification policy, because cert does
150 # not conform to RFC (wildcards in CN are not allowed for https,
151 # but some servers do it anyway)
152 $Net::SSLGlue::LWP::SSLopts{SSL_verifycn_scheme} = {
153 wildcards_in_cn => 'anywhere',
154 check_cn => 'always',
155 };
156 }
162 u
163 use Net::SSLGlue::LWP SSL_ca_path => ...;
164 use LWP::Simple;
165 get( 'https://www....' );
166
167 {
168 local %Net::SSLGlue::LWP::SSLopts = %Net::SSLGlue::LWP::SSLopts;
169
170 # switch off verification
171 $Net::SSLGlue::LWP::SSLopts{SSL_verify_mode} = 0;
172
173 # or: set different verification policy, because cert does
174 # not conform to RFC (wildcards in CN are not allowed for https,
175 # but some servers do it anyway)
176 $Net::SSLGlue::LWP::SSLopts{SSL_verifycn_scheme} = {
177 wildcards_in_cn => 'anywhere',
178 check_cn => 'always',
179 };
180 }
157181
158182
159183 =head1 DESCRIPTION
163187 and that L<LWP::Protocol::https> does proper certificate checking using the
164188 C<http> SSL_verify_scheme from L<IO::Socket::SSL>.
165189
190 This module should only be used for older LWP version, see B<Supported LWP
191 versions> below.
192
166193 Because L<LWP> does not have a mechanism to forward arbitrary parameters for
167194 the construction of the underlying socket these parameters can be set globally
168195 when including the package, or with local settings of the
191218
192219 =back
193220
221 =head1 Supported LWP versions
222
223 This module should be used for older LWP version only. Starting with version
224 6.06 it is recommended to use LWP directly. If a recent version is found
225 Net::SSLGlue::LWP will print out a warning and not monkey patch too much into
226 LWP (only as much as necessary to still support C<%Net::SSLGlue::LWP::SSLopts>).
227
194228 =head1 SEE ALSO
195229
196230 IO::Socket::SSL, LWP, Net::HTTPS, LWP::Protocol::https
197231
198232 =head1 COPYRIGHT
199233
200 This module is copyright (c) 2008, Steffen Ullrich.
234 This module is copyright (c) 2008..2015, Steffen Ullrich.
201235 All Rights Reserved.
202236 This module is free software. It may be used, redistributed and/or modified
203237 under the same terms as Perl itself.
33 package Net::SSLGlue::POP3;
44 use IO::Socket::SSL 1.19;
55 use Net::POP3;
6 our $VERSION = 0.91;
7
8 ##############################################################################
9 # mix starttls method into Net::POP3 which on SSL handshake success
10 # upgrades the class to Net::POP3::_SSLified
11 ##############################################################################
12 sub Net::POP3::starttls {
6 our $VERSION = 0.911;
7
8 my $DONT;
9 BEGIN {
10 if (defined &Net::POP3::starttls) {
11 warn "using SSL support of Net::POP3 $Net::POP3::VERSION instead of SSLGlue";
12 $DONT = 1;
13 goto DONE;
14 }
15
16 ##############################################################################
17 # mix starttls method into Net::POP3 which on SSL handshake success
18 # upgrades the class to Net::SSLGlue::POP3::_SSLified
19 ##############################################################################
20 *Net::POP3::starttls = sub {
1321 my $self = shift;
1422 $self->_STLS or return;
1523 my $host = $self->host;
1624 # for name verification strip port from domain:port, ipv4:port, [ipv6]:port
1725 $host =~s{(?<!:):\d+$}{};
1826
19 Net::POP3::_SSLified->start_SSL( $self,
20 SSL_verify_mode => 1,
21 SSL_verifycn_scheme => 'pop3',
22 SSL_verifycn_name => $host,
23 @_
27 Net::SSLGlue::POP3::_SSLified->start_SSL( $self,
28 SSL_verify_mode => 1,
29 SSL_verifycn_scheme => 'pop3',
30 SSL_verifycn_name => $host,
31 @_
2432 ) or return;
25 }
26 sub Net::POP3::_STLS {
33 };
34
35 *Net::POP3::_STLS = sub {
2736 shift->command("STLS")->response() == Net::POP3::CMD_OK
28 }
29
30 no warnings 'redefine';
31 my $old_new = \&Net::POP3::new;
32 *Net::POP3::new = sub {
37 };
38
39 no warnings 'redefine';
40 my $old_new = \&Net::POP3::new;
41 *Net::POP3::new = sub {
3342 my $class = shift;
3443 my %arg = @_ % 2 == 0 ? @_ : ( Host => shift,@_ );
3544 if ( delete $arg{SSL} ) {
36 $arg{Port} ||= 995;
37 return Net::POP3::_SSLified->new(%arg);
45 $arg{Port} ||= 995;
46 return Net::SSLGlue::POP3::_SSLified->new(%arg);
3847 } else {
39 return $old_new->($class,%arg);
48 return $old_new->($class,%arg);
4049 }
41 };
50 };
51
52 DONE:
53 1;
54 }
4255
4356 ##############################################################################
4457 # Socket class derived from IO::Socket::SSL
4659 ##############################################################################
4760 our %SSLopts;
4861 {
49 package Net::POP3::_SSL_Socket;
50 our @ISA = 'IO::Socket::SSL';
51 sub configure_SSL {
52 my ($self,$arg_hash) = @_;
53
54 # set per default strict certificate verification
55 $arg_hash->{SSL_verify_mode} = 1
56 if ! exists $arg_hash->{SSL_verify_mode};
57 $arg_hash->{SSL_verifycn_scheme} = 'pop3'
58 if ! exists $arg_hash->{SSL_verifycn_scheme};
59 $arg_hash->{SSL_verifycn_name} = $self->host
60 if ! exists $arg_hash->{SSL_verifycn_name};
61
62 # force keys from %SSLopts
63 while ( my ($k,$v) = each %SSLopts ) {
64 $arg_hash->{$k} = $v;
65 }
66 return $self->SUPER::configure_SSL($arg_hash)
62 package Net::SSLGlue::POP3::_SSL_Socket;
63 goto DONE if $DONT;
64 our @ISA = 'IO::Socket::SSL';
65 *configure_SSL = sub {
66 my ($self,$arg_hash) = @_;
67
68 # set per default strict certificate verification
69 $arg_hash->{SSL_verify_mode} = 1
70 if ! exists $arg_hash->{SSL_verify_mode};
71 $arg_hash->{SSL_verifycn_scheme} = 'pop3'
72 if ! exists $arg_hash->{SSL_verifycn_scheme};
73 $arg_hash->{SSL_verifycn_name} = $self->host
74 if ! exists $arg_hash->{SSL_verifycn_name};
75
76 # force keys from %SSLopts
77 while ( my ($k,$v) = each %SSLopts ) {
78 $arg_hash->{$k} = $v;
6779 }
80 return $self->SUPER::configure_SSL($arg_hash)
81 };
82
83 DONE:
84 1;
6885 }
6986
7087
7390 # this talks SSL to the peer
7491 ##############################################################################
7592 {
76 package Net::POP3::_SSLified;
77 use Carp 'croak';
78
79 # deriving does not work because we need to replace a superclass
80 # from Net::POP3, so just copy the class into the new one and then
81 # change it
82
83 # copy subs
84 for ( keys %{Net::POP3::} ) {
85 no strict 'refs';
86 eval { *{$Net::POP3::{$_}} && *{$Net::POP3::{$_}}{CODE} } or next;
87 *{$_} = \&{ "Net::POP3::$_" };
88 }
89
90 # copy + fix @ISA
91 our @ISA = @Net::POP3::ISA;
92 grep { s{^IO::Socket::INET$}{Net::POP3::_SSL_Socket} } @ISA
93 or die "cannot find and replace IO::Socket::INET superclass";
94
95 # we are already sslified
96 no warnings 'redefine';
97 sub starttls { croak "have already TLS\n" }
98
99 my $old_new = \&new;
100 *Net::POP3::_SSLified::new = sub {
101 my $class = shift;
102 my %arg = @_ % 2 == 0 ? @_ : ( Host => shift,@_ );
103 local %SSLopts;
104 $SSLopts{$_} = delete $arg{$_} for ( grep { /^SSL_/ } keys %arg );
105 return $old_new->($class,%arg);
106 };
107
108 # Net::Cmd getline uses select, but this is not sufficient with SSL
109 # note that this does no EBCDIC etc conversions
110 *Net::POP3::_SSLified::getline = sub {
111 my $self = shift;
112 # skip Net::POP3 getline and go directly to IO::Socket::SSL
113 return $self->IO::Socket::SSL::getline(@_);
114 };
93 package Net::SSLGlue::POP3::_SSLified;
94 use Carp 'croak';
95 goto DONE if $DONT;
96
97 # deriving does not work because we need to replace a superclass
98 # from Net::POP3, so just copy the class into the new one and then
99 # change it
100
101 # copy subs
102 for ( keys %{Net::POP3::} ) {
103 no strict 'refs';
104 *{$_} = \&{ "Net::POP3::$_" } if defined &{ "Net::POP3::$_" };
105 }
106
107 # copy + fix @ISA
108 our @ISA = @Net::POP3::ISA;
109 grep { s{^IO::Socket::INET$}{Net::SSLGlue::POP3::_SSL_Socket} } @ISA
110 or die "cannot find and replace IO::Socket::INET superclass";
111
112 # we are already sslified
113 no warnings 'redefine';
114 *starttls = sub { croak "have already TLS\n" };
115
116 my $old_new = \&new;
117 *new = sub {
118 my $class = shift;
119 my %arg = @_ % 2 == 0 ? @_ : ( Host => shift,@_ );
120 local %SSLopts;
121 $SSLopts{$_} = delete $arg{$_} for ( grep { /^SSL_/ } keys %arg );
122 return $old_new->($class,%arg);
123 };
124
125 # Net::Cmd getline uses select, but this is not sufficient with SSL
126 # note that this does no EBCDIC etc conversions
127 *getline = sub {
128 my $self = shift;
129 # skip Net::POP3 getline and go directly to IO::Socket::SSL
130 return $self->IO::Socket::SSL::getline(@_);
131 };
132
133 DONE:
134 1;
115135 }
116136
117137 1;
122142
123143 =head1 SYNOPSIS
124144
125 use Net::SSLGlue::POP3;
126 my $pop3s = Net::POP3->new( $host,
127 SSL => 1,
128 SSL_ca_path => ...
129 );
130
131 my $pop3 = Net::POP3->new( $host );
132 $pop3->starttls( SSL_ca_path => ... );
145 use Net::SSLGlue::POP3;
146 my $pop3s = Net::POP3->new( $host,
147 SSL => 1,
148 SSL_ca_path => ...
149 );
150
151 my $pop3 = Net::POP3->new( $host );
152 $pop3->starttls( SSL_ca_path => ... );
133153
134154 =head1 DESCRIPTION
135155
33 package Net::SSLGlue::SMTP;
44 use IO::Socket::SSL 1.19;
55 use Net::SMTP;
6 our $VERSION = 1.0;
7
8 ##############################################################################
9 # mix starttls method into Net::SMTP which on SSL handshake success
10 # upgrades the class to Net::SMTP::_SSLified
11 ##############################################################################
12 sub Net::SMTP::starttls {
6 our $VERSION = 1.001;
7
8 my $DONT;
9 BEGIN {
10 if (defined &Net::SMTP::starttls) {
11 warn "using SSL support of Net::SMTP $Net::SMTP::VERSION instead of SSLGlue";
12 $DONT = 1;
13 goto DONE;
14 }
15
16 ##############################################################################
17 # mix starttls method into Net::SMTP which on SSL handshake success
18 # upgrades the class to Net::SSLGlue::SMTP::_SSLified
19 ##############################################################################
20 *Net::SMTP::starttls = sub {
1321 my $self = shift;
1422 $self->_STARTTLS or return;
1523 my $host = $self->host;
1624 # for name verification strip port from domain:port, ipv4:port, [ipv6]:port
1725 $host =~s{(?<!:):\d+$}{};
1826
19 Net::SMTP::_SSLified->start_SSL( $self,
20 SSL_verify_mode => 1,
21 SSL_verifycn_scheme => 'smtp',
22 SSL_verifycn_name => $host,
23 @_
27 Net::SSLGlue::SMTP::_SSLified->start_SSL( $self,
28 SSL_verify_mode => 1,
29 SSL_verifycn_scheme => 'smtp',
30 SSL_verifycn_name => $host,
31 @_
2432 ) or return;
2533
2634 # another hello after starttls to read new ESMTP capabilities
2735 return $self->hello(${*$self}{net_smtp_hello_domain});
28 }
29 sub Net::SMTP::_STARTTLS {
36 };
37
38 *Net::SMTP::_STARTTLS = sub {
3039 shift->command("STARTTLS")->response() == Net::SMTP::CMD_OK
31 }
32
33 no warnings 'redefine';
34 my $old_new = \&Net::SMTP::new;
35 *Net::SMTP::new = sub {
40 };
41
42 no warnings 'redefine';
43 my $old_new = \&Net::SMTP::new;
44 *Net::SMTP::new = sub {
3645 my $class = shift;
3746 my %arg = @_ % 2 == 0 ? @_ : ( Host => shift,@_ );
3847 if ( delete $arg{SSL} ) {
39 $arg{Port} ||= 465;
40 return Net::SMTP::_SSLified->new(%arg);
48 $arg{Port} ||= 465;
49 return Net::SSLGlue::SMTP::_SSLified->new(%arg);
4150 } else {
42 return $old_new->($class,%arg);
51 return $old_new->($class,%arg);
4352 }
44 };
45
46 my $old_hello = \&Net::SMTP::hello;
47 *Net::SMTP::hello = sub {
53 };
54
55 my $old_hello = \&Net::SMTP::hello;
56 *Net::SMTP::hello = sub {
4857 my ($self,$domain) = @_;
4958 ${*$self}{net_smtp_hello_domain} = $domain if $domain;
5059 goto &$old_hello;
51 };
60 };
61
62 DONE:
63 1;
64 }
5265
5366 ##############################################################################
5467 # Socket class derived from IO::Socket::SSL
5669 ##############################################################################
5770 our %SSLopts;
5871 {
59 package Net::SMTP::_SSL_Socket;
60 our @ISA = 'IO::Socket::SSL';
61 sub configure_SSL {
62 my ($self,$arg_hash) = @_;
63
64 # set per default strict certificate verification
65 $arg_hash->{SSL_verify_mode} = 1
66 if ! exists $arg_hash->{SSL_verify_mode};
67 $arg_hash->{SSL_verifycn_scheme} = 'smtp'
68 if ! exists $arg_hash->{SSL_verifycn_scheme};
69 $arg_hash->{SSL_verifycn_name} = $self->host
70 if ! exists $arg_hash->{SSL_verifycn_name};
71
72 # force keys from %SSLopts
73 while ( my ($k,$v) = each %SSLopts ) {
74 $arg_hash->{$k} = $v;
75 }
76 return $self->SUPER::configure_SSL($arg_hash)
72 package Net::SSLGlue::SMTP::_SSL_Socket;
73 goto DONE if $DONT;
74 our @ISA = 'IO::Socket::SSL';
75 *configure_SSL = sub {
76 my ($self,$arg_hash) = @_;
77
78 # set per default strict certificate verification
79 $arg_hash->{SSL_verify_mode} = 1
80 if ! exists $arg_hash->{SSL_verify_mode};
81 $arg_hash->{SSL_verifycn_scheme} = 'smtp'
82 if ! exists $arg_hash->{SSL_verifycn_scheme};
83 $arg_hash->{SSL_verifycn_name} = $self->host
84 if ! exists $arg_hash->{SSL_verifycn_name};
85
86 # force keys from %SSLopts
87 while ( my ($k,$v) = each %SSLopts ) {
88 $arg_hash->{$k} = $v;
7789 }
90 return $self->SUPER::configure_SSL($arg_hash)
91 };
92
93 DONE:
94 1;
7895 }
7996
8097
8198 ##############################################################################
82 # Net::SMTP derived from Net::SMTP::_SSL_Socket instead of IO::Socket::INET
99 # Net::SMTP derived from Net::SSLGlue::SMTP::_SSL_Socket instead of IO::Socket::INET
83100 # this talks SSL to the peer
84101 ##############################################################################
85102 {
86 package Net::SMTP::_SSLified;
87 use Carp 'croak';
88
89 # deriving does not work because we need to replace a superclass
90 # from Net::SMTP, so just copy the class into the new one and then
91 # change it
92
93 # copy subs
94 for ( keys %{Net::SMTP::} ) {
95 no strict 'refs';
96 *{$_} = \&{ "Net::SMTP::$_" } if *{$Net::SMTP::{$_}}{CODE};
97 }
98
99 # copy + fix @ISA
100 our @ISA = @Net::SMTP::ISA;
101 grep { s{^IO::Socket::INET$}{Net::SMTP::_SSL_Socket} } @ISA
102 or die "cannot find and replace IO::Socket::INET superclass";
103
104 # we are already sslified
105 no warnings 'redefine';
106 sub starttls { croak "have already TLS\n" }
107
108 my $old_new = \&new;
109 *Net::SMTP::_SSLified::new = sub {
110 my $class = shift;
111 my %arg = @_ % 2 == 0 ? @_ : ( Host => shift,@_ );
112 local %SSLopts;
113 $SSLopts{$_} = delete $arg{$_} for ( grep { /^SSL_/ } keys %arg );
114 return $old_new->($class,%arg);
115 };
103 package Net::SSLGlue::SMTP::_SSLified;
104 use Carp 'croak';
105 goto DONE if $DONT;
106
107 # deriving does not work because we need to replace a superclass
108 # from Net::SMTP, so just copy the class into the new one and then
109 # change it
110
111 # copy subs
112 for ( keys %{Net::SMTP::} ) {
113 no strict 'refs';
114 *{$_} = \&{ "Net::SMTP::$_" } if defined &{ "Net::SMTP::$_" };
115 }
116
117 # copy + fix @ISA
118 our @ISA = @Net::SMTP::ISA;
119 grep { s{^IO::Socket::INET$}{Net::SSLGlue::SMTP::_SSL_Socket} } @ISA
120 or die "cannot find and replace IO::Socket::INET superclass";
121
122 # we are already sslified
123 no warnings 'redefine';
124 *starttls = sub { croak "have already TLS\n" };
125
126 my $old_new = \&new;
127 *new = sub {
128 my $class = shift;
129 my %arg = @_ % 2 == 0 ? @_ : ( Host => shift,@_ );
130 local %SSLopts;
131 $SSLopts{$_} = delete $arg{$_} for ( grep { /^SSL_/ } keys %arg );
132 return $old_new->($class,%arg);
133 };
134
135 DONE:
136 1;
116137 }
117138
118139 1;
123144
124145 =head1 SYNOPSIS
125146
126 use Net::SSLGlue::SMTP;
127 my $smtp_ssl = Net::SMTP->new( $host,
128 SSL => 1,
129 SSL_ca_path => ...
130 );
131
132 my $smtp_plain = Net::SMTP->new( $host );
133 $smtp_plain->starttls( SSL_ca_path => ... );
147 use Net::SSLGlue::SMTP;
148 my $smtp_ssl = Net::SMTP->new( $host,
149 SSL => 1,
150 SSL_ca_path => ...
151 );
152
153 my $smtp_plain = Net::SMTP->new( $host );
154 $smtp_plain->starttls( SSL_ca_path => ... );
134155
135156 =head1 DESCRIPTION
136157
00 package Net::SSLGlue;
1 our $VERSION = '1.052';
1 our $VERSION = '1.054';
22
33 =head1 NAME
44
2424
2525 =item Net::LDAP - add proper certificate checking
2626
27 =item LWP - add proper certificate checking
27 =item LWP - add proper certificate checking for older LWP versions
2828
2929 =back
3030
1414 use LWP::Simple;
1515
1616 my $goodhost = 'google.de';
17 # this does not work any longer - will be skipped in test
18 my $badhost = 'www.fedora.org';
17 my $badhost = 'badcert.maulwuff.de';
1918
2019 my $capath = '/etc/ssl/certs/'; # unix?
2120 -d $capath or do {
6059 if ( IO::Socket::SSL->start_SSL( $sock,
6160 SSL_ca_path => $capath,
6261 SSL_verify_mode => 1,
62 SSL_verifycn_scheme => 'http',
63 SSL_verifycn_name => $badhost,
6364 )) {
6465 diag("certificate for $badhost unexpectly correct");
6566 $badhost = undef;
8384 if ( $badhost ) {
8485 # $badhost -> should fail
8586 diag("connecting to $badhost:443 with LWP");
86 $content = get( 'https://$badhost' );
87 $content = get( "https://$badhost" );
8788 print $content ? "not ok # lwp ssl connect $badhost should fail\n": "ok\n";
8889
8990 # $badhost -> should succeed if verify mode is 0
9091 {
9192 local %Net::SSLGlue::LWP::SSLopts = %Net::SSLGlue::LWP::SSLopts;
9293 $Net::SSLGlue::LWP::SSLopts{SSL_verify_mode} = 0;
93 $content = get( 'https://$badhost' );
94 $content = get( "https://$badhost" );
9495 print $content ? "ok\n": "not ok # lwp ssl $badhost w/o ssl verify\n";
9596 }
9697 }
22 use warnings;
33 use Test::More;
44
5 my $server = 'ftp.rebex.net';
5 my $server = 'test.rebex.net';
66 my $debug = 0;
77
88 BEGIN {
2727 # ssl to the right host
2828 diag( "connect inet to $server:990" );
2929 my $sock = IO::Socket::INET->new( "$server:990") or do {
30 plan skip_all => "$server:999 not reachable";
30 plan skip_all => "$server:990 not reachable";
3131 };
3232
3333 # now we need CAs
3838
3939 diag( "upgrade to ssl $server:990" );
4040 IO::Socket::SSL->start_SSL($sock,
41 %sslargs,
4241 SSL_verify_mode => 1,
4342 SSL_verifycn_name => $server,
44 SSL_verifycn_scheme => 'ftp'
43 SSL_verifycn_scheme => 'ftp',
44 %sslargs,
4545 ) or do {
46 plan skip_all => "$server:999 not upgradable to SSL: $SSL_ERROR";
46 plan skip_all => "$server:990 not upgradable to SSL: $SSL_ERROR";
4747 };
4848
4949 plan tests => 9;
6666 ok(~~$ftp->ls,"directory listing clear");
6767
6868 # then TLS upgrade inside plain connection
69 $ftp = Net::FTP->new($server, Passive => 1, Debug => $debug);
69 $ftp = Net::FTP->new($server, Passive => 1, Debug => $debug, %sslargs);
7070 ok($ftp,"ftp plain connect $server");
71 my $ok = $ftp->starttls(%sslargs);
71 my $ok = $ftp->starttls();
7272 ok($ok,"ssl upgrade");
7373 $ftp->login("anonymous",'net-sslglue-ftp@test.perl')
7474 or die "login to $server failed";
8383
8484
8585 __DATA__
86 # Subject: C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Class 1 Primary Intermediate Server CA
86 # Subject: C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Class 2 Primary Intermediate Server CA
8787 # Issuer: C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Certification Authority
8888 -----BEGIN CERTIFICATE-----
89 MIIGNDCCBBygAwIBAgIBGDANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
89 MIIGNDCCBBygAwIBAgIBGjANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
9090 MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
9191 Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
92 dGlvbiBBdXRob3JpdHkwHhcNMDcxMDI0MjA1NDE3WhcNMTcxMDI0MjA1NDE3WjCB
92 dGlvbiBBdXRob3JpdHkwHhcNMDcxMDI0MjA1NzA5WhcNMTcxMDI0MjA1NzA5WjCB
9393 jDELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsT
9494 IlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcxODA2BgNVBAMTL1N0
95 YXJ0Q29tIENsYXNzIDEgUHJpbWFyeSBJbnRlcm1lZGlhdGUgU2VydmVyIENBMIIB
96 IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtonGrO8JUngHrJJj0PREGBiE
97 gFYfka7hh/oyULTTRwbw5gdfcA4Q9x3AzhA2NIVaD5Ksg8asWFI/ujjo/OenJOJA
98 pgh2wJJuniptTT9uYSAK21ne0n1jsz5G/vohURjXzTCm7QduO3CHtPn66+6CPAVv
99 kvek3AowHpNz/gfK11+AnSJYUq4G2ouHI2mw5CrY6oPSvfNx23BaKA+vWjhwRRI/
100 ME3NO68X5Q/LoKldSKqxYVDLNM08XMML6BDAjJvwAwNi/rJsPnIO7hxDKslIDlc5
101 xDEhyBDBLIf+VJVSH1I8MRKbf+fAoKVZ1eKPPvDVqOHXcDGpxLPPr21TLwb0pwID
95 YXJ0Q29tIENsYXNzIDIgUHJpbWFyeSBJbnRlcm1lZGlhdGUgU2VydmVyIENBMIIB
96 IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4k85L6GMmoWtCA4IPlfyiAEh
97 G5SpbOK426oZGEY6UqH1D/RujOqWjJaHeRNAUS8i8gyLhw9l33F0NENVsTUJm9m8
98 H/rrQtCXQHK3Q5Y9upadXVACHJuRjZzArNe7LxfXyz6CnXPrB0KSss1ks3RVG7RL
99 hiEs93iHMuAW5Nq9TJXqpAp+tgoNLorPVavD5d1Bik7mb2VsskDPF125w2oLJxGE
100 d2H2wnztwI14FBiZgZl1Y7foU9O6YekO+qIw80aiuckfbIBaQKwn7UhHM7BUxkYa
101 8zVhwQIpkFR+ZE3EMFICgtffziFuGJHXuKuMJxe18KMBL47SLoc6PbQpZ4rEAwID
102102 AQABo4IBrTCCAakwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
103 VR0OBBYEFOtCNNCYsKuf9BtrCPfMZC7vDixFMB8GA1UdIwQYMBaAFE4L7xqkQFul
103 VR0OBBYEFBHbI0X9VMxqcW+EigPXvvcBLyaGMB8GA1UdIwQYMBaAFE4L7xqkQFul
104104 F2mHMMo0aEPQQa7yMGYGCCsGAQUFBwEBBFowWDAnBggrBgEFBQcwAYYbaHR0cDov
105105 L29jc3Auc3RhcnRzc2wuY29tL2NhMC0GCCsGAQUFBzAChiFodHRwOi8vd3d3LnN0
106106 YXJ0c3NsLmNvbS9zZnNjYS5jcnQwWwYDVR0fBFQwUjAnoCWgI4YhaHR0cDovL3d3
108108 c3NsLmNvbS9zZnNjYS5jcmwwgYAGA1UdIAR5MHcwdQYLKwYBBAGBtTcBAgEwZjAu
109109 BggrBgEFBQcCARYiaHR0cDovL3d3dy5zdGFydHNzbC5jb20vcG9saWN5LnBkZjA0
110110 BggrBgEFBQcCARYoaHR0cDovL3d3dy5zdGFydHNzbC5jb20vaW50ZXJtZWRpYXRl
111 LnBkZjANBgkqhkiG9w0BAQUFAAOCAgEAIQlJPqWIbuALi0jaMU2P91ZXouHTYlfp
112 tVbzhUV1O+VQHwSL5qBaPucAroXQ+/8gA2TLrQLhxpFy+KNN1t7ozD+hiqLjfDen
113 xk+PNdb01m4Ge90h2c9W/8swIkn+iQTzheWq8ecf6HWQTd35RvdCNPdFWAwRDYSw
114 xtpdPvkBnufh2lWVvnQce/xNFE+sflVHfXv0pQ1JHpXo9xLBzP92piVH0PN1Nb6X
115 t1gW66pceG/sUzCv6gRNzKkC4/C2BBL2MLERPZBOVmTX3DxDX3M570uvh+v2/miI
116 RHLq0gfGabDBoYvvF0nXYbFFSF87ICHpW7LM9NfpMfULFWE7epTj69m8f5SuauNi
117 YpaoZHy4h/OZMn6SolK+u/hlz8nyMPyLwcKmltdfieFcNID1j0cHL7SRv7Gifl9L
118 WtBbnySGBVFaaQNlQ0lxxeBvlDRr9hvYqbBMflPrj0jfyjO1SPo2ShpTpjMM0InN
119 SRXNiTE8kMBy12VLUjWKRhFEuT2OKGWmPnmeXAhEKa2wNREuIU640ucQPl2Eg7PD
120 wuTSxv0JS3QJ3fGz0xk+gA2iCxnwOOfFwq/iI9th4p1cbiCJSS4jarJiwUW0n6+L
121 p/EiO/h94pDQehn7Skzj0n1fSoMD7SfWI55rjbRZotnvbIIp3XUZPD9MEI3vu3Un
122 0q6Dp6jOW6c=
111 LnBkZjANBgkqhkiG9w0BAQUFAAOCAgEAnQfh7pB2MWcWRXCMy4SLS1doRKWJwfJ+
112 yyiL9edwd9W29AshYKWhdHMkIoDW2LqNomJdCTVCKfs5Y0ULpLA4Gmj0lRPM4EOU
113 7Os5GuxXKdmZbfWEzY5zrsncavqenRZkkwjHHMKJVJ53gJD2uSl26xNnSFn4Ljox
114 uMnTiOVfTtIZPUOO15L/zzi24VuKUx3OrLR2L9j3QGPV7mnzRX2gYsFhw3XtsntN
115 rCEnME5ZRmqTF8rIOS0Bc2Vb6UGbERecyMhK76F2YC2uk/8M1TMTn08Tzt2G8fz4
116 NVQVqFvnhX76Nwn/i7gxSZ4Nbt600hItuO3Iw/G2QqBMl3nf/sOjn6H0bSyEd6Si
117 BeEX/zHdmvO4esNSwhERt1Axin/M51qJzPeGmmGSTy+UtpjHeOBiS0N9PN7WmrQQ
118 oUCcSyrcuNDUnv3xhHgbDlePaVRCaHvqoO91DweijHOZq1X1BwnSrzgDapADDC+P
119 4uhDwjHpb62H5Y29TiyJS1HmnExUdsASgVOb7KD8LJzaGJVuHjgmQid4YAjff20y
120 6NjAbx/rJnWfk/x7G/41kNxTowemP4NVCitOYoIlzmYwXSzg+RkbdbmdmFamgyd6
121 0Y+NWZP8P3PXLrQsldiL98l+x/ydrHIEH9LMF/TtNGCbnkqXBP7dcg5XVFEGcE3v
122 qhykguAzx/Q=
123123 -----END CERTIFICATE-----
124124 # Subject: C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Certification Authority
125125 # Issuer: C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Certification Authority