1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
|
#!/usr/bin/perl
use v5.14;
use warnings;
use Getopt::Long;
use IO::Async::Loop;
use IO::Async::Stream 0.54; # ->new_close_future
use IO::Async::SSL;
my $DUMPCERT;
my $NO_VERIFY;
my $FAMILY;
GetOptions(
'd|dumpcert' => \$DUMPCERT,
'nv|no-verify' => \$NO_VERIFY,
'4|ipv4' => sub { $FAMILY = "inet" },
'6|ipv6' => sub { $FAMILY = "inet6" },
) or exit 1;
my $HOST = shift @ARGV or die "Need HOST";
my $PORT = shift @ARGV or die "Need PORT";
my $loop = IO::Async::Loop->new;
my ( $socketstream, $stdiostream );
my $peeraddr;
$socketstream = IO::Async::Stream->new(
on_read => sub {
my ( undef, $buffref, $closed ) = @_;
# Turn CRLFs into plain \n by stripping \r
$$buffref =~ s/\r//g;
$stdiostream->write( $$buffref );
$$buffref = "";
return 0;
},
on_closed => sub {
print STDERR "Closed connection to $peeraddr\n";
$stdiostream->close_when_empty;
},
);
$loop->add( $socketstream );
$stdiostream = IO::Async::Stream->new(
read_handle => \*STDIN,
write_handle => \*STDOUT,
on_read => sub {
my ( undef, $buffref, $closed ) = @_;
# Turn plain \n into CRLFs
$$buffref =~ s/\n/\x0d\x0a/g;
$socketstream->write( $$buffref );
$$buffref = "";
return 0;
},
on_closed => sub {
$socketstream->close_when_empty;
},
);
$loop->add( $stdiostream );
$loop->SSL_connect(
host => $HOST,
service => $PORT,
family => $FAMILY,
handle => $socketstream,
( $NO_VERIFY ? ( SSL_verify_mode => 0 ) : () ),
)->get;
my $socket = $socketstream->read_handle;
$peeraddr = $socket->peerhost . ":" . $socket->peerport;
print STDERR "Connected to $peeraddr\n";
if( $DUMPCERT ) {
print STDERR Net::SSLeay::PEM_get_string_X509($socket->peer_certificate) . "\n";
}
$loop->await( $socketstream->new_close_future, $stdiostream->new_close_future );
|