File Coverage

blib/lib/LWP/Protocol/https.pm
Criterion Covered Total %
statement 42 49 85.7
branch 10 24 41.6
condition 3 14 21.4
subroutine 8 8 100.0
pod 0 1 0.0
total 63 96 65.6


line stmt bran cond sub pod time code
1             package LWP::Protocol::https;
2              
3 3     3   346272 use strict;
  3         21  
  3         88  
4 3     3   18 use warnings;
  3         6  
  3         154  
5              
6             our $VERSION = '6.11';
7              
8 3     3   31 use base qw(LWP::Protocol::http);
  3         7  
  3         1640  
9             require Net::HTTPS;
10              
11             sub socket_type
12             {
13 12     12 0 293476 return "https";
14             }
15              
16             sub _extra_sock_opts
17             {
18 10     10   22087 my $self = shift;
19 10 50       25 my %ssl_opts = %{$self->{ua}{ssl_opts} || {}};
  10         121  
20 10 100       46 if (delete $ssl_opts{verify_hostname}) {
21 6   50     65 $ssl_opts{SSL_verify_mode} ||= 1;
22 6         17 $ssl_opts{SSL_verifycn_scheme} = 'www';
23             }
24             else {
25 4 50       46 if ( $Net::HTTPS::SSL_SOCKET_CLASS eq 'Net::SSL' ) {
26 0         0 $ssl_opts{SSL_verifycn_scheme} = '';
27             } else {
28 4         23 $ssl_opts{SSL_verifycn_scheme} = 'none';
29             }
30             }
31 10 100       34 if ($ssl_opts{SSL_verify_mode}) {
32 6 0 33     27 unless (exists $ssl_opts{SSL_ca_file} || exists $ssl_opts{SSL_ca_path}) {
33 0 0 0     0 if ($Net::HTTPS::SSL_SOCKET_CLASS eq 'IO::Socket::SSL'
    0 0        
34             && defined &IO::Socket::SSL::default_ca
35             && IO::Socket::SSL::default_ca() ) {
36             # IO::Socket::SSL has a usable default CA
37             } elsif ( my $cafile = eval {
38 0         0 require Mozilla::CA;
39 0         0 Mozilla::CA::SSL_ca_file()
40             }) {
41             # use Mozilla::CA
42 0         0 $ssl_opts{SSL_ca_file} = $cafile;
43             } else {
44 0         0 die <<'EOT';
45             Can't verify SSL peers without knowing which Certificate Authorities to trust.
46              
47             This problem can be fixed by either setting the PERL_LWP_SSL_CA_FILE
48             environment variable to the file where your trusted CA are, or by installing
49             the Mozilla::CA module for set of commonly trusted CAs.
50              
51             To completly disable the verification that you talk to the correct SSL peer you
52             can set SSL_verify_mode to 0 within ssl_opts. But, if you do this you can't be
53             sure that you communicate with the expected peer.
54             EOT
55             }
56             }
57             }
58 10         35 $self->{ssl_opts} = \%ssl_opts;
59 10         73 return (%ssl_opts, $self->SUPER::_extra_sock_opts);
60             }
61              
62             # This is a subclass of LWP::Protocol::http.
63             # That parent class calls ->_check_sock() during the
64             # request method. This allows us to hook in and run checks
65             # sub _check_sock
66             # {
67             # my($self, $req, $sock) = @_;
68             # }
69              
70             sub _get_sock_info
71             {
72 8     8   718401 my $self = shift;
73 8         69 $self->SUPER::_get_sock_info(@_);
74 8         2126 my($res, $sock) = @_;
75 8 50 33     164 if ($sock->can('get_sslversion') and my $sslversion = $sock->get_sslversion) {
76 8         304 $res->header("Client-SSL-Version" => $sslversion);
77             }
78 8         695 $res->header("Client-SSL-Cipher" => $sock->get_cipher);
79 8         760 my $cert = $sock->get_peer_certificate;
80 8 50       64 if ($cert) {
81 8         51 $res->header("Client-SSL-Cert-Subject" => $cert->subject_name);
82 8         1182 $res->header("Client-SSL-Cert-Issuer" => $cert->issuer_name);
83             }
84 8 50       1026 if (!$self->{ssl_opts}{SSL_verify_mode}) {
    0          
85 8         61 $res->push_header("Client-SSL-Warning" => "Peer certificate not verified");
86             }
87             elsif (!$self->{ssl_opts}{SSL_verifycn_scheme}) {
88 0         0 $res->push_header("Client-SSL-Warning" => "Peer hostname match with certificate not verified");
89             }
90 8         442 $res->header("Client-SSL-Socket-Class" => $Net::HTTPS::SSL_SOCKET_CLASS);
91             }
92              
93             # upgrade plain socket to SSL, used for CONNECT tunnel when proxying https
94             # will only work if the underlying socket class of Net::HTTPS is
95             # IO::Socket::SSL, but code will only be called in this case
96             if ( $Net::HTTPS::SSL_SOCKET_CLASS->can('start_SSL')) {
97             *_upgrade_sock = sub {
98 6     6   98174 my ($self,$sock,$url) = @_;
99 6         29 $sock = LWP::Protocol::https::Socket->start_SSL( $sock,
100             SSL_verifycn_name => $url->host,
101             SSL_hostname => $url->host,
102             $self->_extra_sock_opts,
103             );
104 6 50       84195 $@ = LWP::Protocol::https::Socket->errstr if ! $sock;
105 6         33 return $sock;
106             }
107             }
108              
109             #-----------------------------------------------------------
110             package LWP::Protocol::https::Socket;
111              
112 3     3   94243 use base qw(Net::HTTPS LWP::Protocol::http::SocketMethods);
  3         9  
  3         1648  
113              
114             1;
115              
116             __END__