1#!/usr/bin/perl 2 3use strict; 4use vars qw($opt_p $opt_n $opt_bench $opt_debug $opt_version 5 $opt_v $opt_help 6 $opt_cert $opt_key $opt_cafile $opt_cadir 7 ); 8use lib qw(lib); 9use Net::SSL; 10use File::Basename; 11use Benchmark; 12 13use Getopt::Long; 14&GetOptions ('p:s' => \$opt_p, 15 'proxy:s' => \$opt_p, 16 'bench:n' => \$opt_bench, 17 'd' => \$opt_debug, 18 'version:i' => \$opt_version, 19 'v:i' => \$opt_version, 20 'h' => \$opt_help, 21 'help' => \$opt_help, 22 'cert:s' => \$opt_cert, 23 'key:s' => \$opt_key, 24 'CAfile:s' => \$opt_cafile, 25 'CAdir:s' => \$opt_cadir, 26 ); 27 28my $basename = &File::Basename::basename($0); 29 30# define sub first, in case you are reading the source :) 31sub help { 32 33 print <<HELP; 34Usage: $basename [-d] [-b=NNN] [-h] [-p proxy_name:port] [-CAfile=FILE] [GET|HEAD] [ssl_server_name] [port] 35 36 -d Debug mode 37 -b Benchmark NNN times, good test for memory leaks 38 -h This help message 39 -p Proxy server, via CONNECT method, localhost:80 format 40 41 -cert client certificate file 42 -key private key file 43 44 -CAfile CA certificates file, use certs/ca-bundle.crt for primary root certs 45 46 method defaults to HEAD 47 ssl_server_name defaults to www.nodeworks.com 48 port defaults to 443 49 50These are equivalent: 51 52 ./net_ssl_test 53 ./net_ssl_test HEAD www.nodeworks.com 443 54 55This might be how you debug your proxy: 56 57 ./net_ssl_test -d -p http://proxy_name:80 www.nodeworks.com 58 59Note http:// on proxy hostname is stripped off, and is 60meaningless to Crypt::SSLeay. 61 62HELP 63; 64 exit; 65} 66 67if($opt_help) { 68 &help; 69}; 70 71if($opt_debug) { 72 eval "use LWP::Debug qw(+)"; 73} 74 75my $method = (@ARGV && $ARGV[0] =~ /^[A-Z]+$/) ? shift : "HEAD"; 76my($host, $port, $path); 77if($opt_bench) { 78 $host = shift || die("need host, run like ./$basename HEAD yourhost.com.foo"); 79} else { 80 $host = shift || "www.nodeworks.com"; 81} 82if($host =~ m|^(https://)?([^/:]+)(:(\d+))?(/.*)?$|) { 83 ($host, $port, $path) = ($2, $4, $5); 84} 85 86$port ||= shift || 443; 87$path ||= '/'; 88 89if($opt_n) { 90 $ENV{NO_PROXY} = $opt_n; 91} 92 93$ENV{HTTPS_PROXY} = $opt_p; 94$ENV{HTTPS_CERT_FILE} = $opt_cert; 95$ENV{HTTPS_KEY_FILE} = $opt_key; 96 97$opt_cafile && ( $ENV{HTTPS_CA_FILE} = $opt_cafile ); 98$opt_cadir && ( $ENV{HTTPS_CA_DIR} = $opt_cadir ); 99 100if($opt_version) { 101 grep($opt_version eq $_, '2', '3', '23') 102 || die("$opt_version must be one of 2, 3, or 23"); 103 $ENV{HTTPS_VERSION} = $opt_version; 104} 105 106unless(eval { &ssl_connect() }) { 107 print <<OUT; 108== FAILED TO CONNECT == 109Error: $@ 110 111If you need to use a proxy, please pass it in as an argument like 112 113 ./net_ssl_test -p 127.0.0.1:8080 114 115which sets \$ENV{HTTPS_PROXY} for you. 116 117OUT 118 ; 119} 120 121if($opt_bench) { 122 timethis($opt_bench, sub { &ssl_connect() }); 123} 124 125 126sub ssl_connect { 127 my $sock = Net::SSL->new( 128 PeerAddr => $host, 129 PeerPort => $port, 130 SSL_Debug => $opt_debug, 131 Timeout => 15, 132 ); 133 $sock || ($@ ||= "no Net::SSL connection established"); 134 my $error = $@; 135 $error && die("Can't connect to $host:$port; $error; $!"); 136 137 my $out; 138 $out .= "WEB SITE : $host:$port\n"; 139 $out .= "CIPHER : ".$sock->get_cipher."\n"; 140 my $cert = $sock->get_peer_certificate; 141 142 $out .= "CERT SUBJECT : ".$cert->subject_name."\n"; 143 $out .= "CERTIFIED BY : ".$cert->issuer_name."\n"; 144 $out .= "CERT NOT BEFORE: ".$cert->not_before."\n"; 145 $out .= "CERT NOT AFTER : ".$cert->not_after."\n"; 146 147 $out .= "\n"; 148 $sock->print("$method $path HTTP/1.0\n\n"); 149 print $out; 150 $out = ''; 151 152 my $buf = ''; 153 while ($sock->read($buf, 1024)) { 154 $out .= $buf; 155 } 156 157 unless($opt_bench) { 158 print $out; 159 } 160 161 1; 162} 163 164