|
Packit |
b893dc |
#!/usr/bin/perl
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
use strict;
|
|
Packit |
b893dc |
use warnings;
|
|
Packit |
b893dc |
use Test::More;
|
|
Packit |
b893dc |
use Socket;
|
|
Packit |
b893dc |
use File::Spec;
|
|
Packit |
b893dc |
use Net::SSLeay;
|
|
Packit |
b893dc |
use Config;
|
|
Packit |
b893dc |
use IO::Socket::INET;
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
BEGIN {
|
|
Packit |
b893dc |
plan skip_all => "fork() not supported on $^O" unless $Config{d_fork};
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
plan tests => 2;
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
my $pid;
|
|
Packit |
b893dc |
alarm(30);
|
|
Packit |
b893dc |
END { kill 9,$pid if $pid }
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
my $server;
|
|
Packit |
b893dc |
Net::SSLeay::initialize();
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
{
|
|
Packit |
b893dc |
# SSL server - just handle single connect and shutdown connection
|
|
Packit |
b893dc |
my $cert_pem = File::Spec->catfile('t', 'data', 'testcert_wildcard.crt.pem');
|
|
Packit |
b893dc |
my $key_pem = File::Spec->catfile('t', 'data', 'testcert_key_2048.pem');
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
$server = IO::Socket::INET->new( LocalAddr => '127.0.0.1', Listen => 3)
|
|
Packit |
b893dc |
or BAIL_OUT("failed to create server socket: $!");
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
defined($pid = fork()) or BAIL_OUT("failed to fork: $!");
|
|
Packit |
b893dc |
if ($pid == 0) {
|
|
Packit |
b893dc |
for(qw(ctx ssl)) {
|
|
Packit |
b893dc |
my $cl = $server->accept or BAIL_OUT("accept failed: $!");
|
|
Packit |
b893dc |
my $ctx = Net::SSLeay::CTX_tlsv1_new();
|
|
Packit |
b893dc |
Net::SSLeay::set_cert_and_key($ctx, $cert_pem, $key_pem);
|
|
Packit |
b893dc |
my $ssl = Net::SSLeay::new($ctx);
|
|
Packit |
b893dc |
Net::SSLeay::set_fd($ssl, fileno($cl));
|
|
Packit |
b893dc |
Net::SSLeay::accept($ssl);
|
|
Packit |
b893dc |
for(1,2) {
|
|
Packit |
b893dc |
last if Net::SSLeay::shutdown($ssl)>0;
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
exit;
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
sub client {
|
|
Packit |
b893dc |
my ($where,$expect) = @_;
|
|
Packit |
b893dc |
# SSL client - connect and shutdown, all the while getting state updates
|
|
Packit |
b893dc |
# with info callback
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
my @states;
|
|
Packit |
b893dc |
my $infocb = sub {
|
|
Packit |
b893dc |
my ($ssl,$where,$ret) = @_;
|
|
Packit |
b893dc |
push @states,[$where,$ret];
|
|
Packit |
b893dc |
};
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
my $saddr = $server->sockhost.':'.$server->sockport;
|
|
Packit |
b893dc |
my $cl = IO::Socket::INET->new($saddr)
|
|
Packit |
b893dc |
or BAIL_OUT("failed to connect to server: $!");
|
|
Packit |
b893dc |
my $ctx = Net::SSLeay::CTX_tlsv1_new();
|
|
Packit |
b893dc |
Net::SSLeay::CTX_set_options($ctx, &Net::SSLeay::OP_ALL);
|
|
Packit |
b893dc |
Net::SSLeay::CTX_set_info_callback($ctx, $infocb) if $where eq 'ctx';
|
|
Packit |
b893dc |
my $ssl = Net::SSLeay::new($ctx);
|
|
Packit |
b893dc |
Net::SSLeay::set_fd($ssl, $cl);
|
|
Packit |
b893dc |
Net::SSLeay::set_info_callback($ssl, $infocb) if $where eq 'ssl';
|
|
Packit |
b893dc |
Net::SSLeay::connect($ssl);
|
|
Packit |
b893dc |
for(1,2) {
|
|
Packit |
b893dc |
last if Net::SSLeay::shutdown($ssl)>0;
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
for my $st (@states) {
|
|
Packit |
b893dc |
my @txt;
|
|
Packit |
b893dc |
for(qw(
|
|
Packit |
b893dc |
CB_READ_ALERT CB_WRITE_ALERT
|
|
Packit |
b893dc |
CB_ACCEPT_EXIT CB_ACCEPT_LOOP
|
|
Packit |
b893dc |
CB_CONNECT_EXIT CB_CONNECT_LOOP
|
|
Packit |
b893dc |
CB_HANDSHAKE_START CB_HANDSHAKE_DONE
|
|
Packit |
b893dc |
CB_READ CB_WRITE CB_ALERT
|
|
Packit |
b893dc |
CB_LOOP CB_EXIT
|
|
Packit |
b893dc |
)) {
|
|
Packit |
b893dc |
my $i = eval "Net::SSLeay::$_()"
|
|
Packit |
b893dc |
or BAIL_OUT("no state $_ known");
|
|
Packit |
b893dc |
if (($st->[0] & $i) == $i) {
|
|
Packit |
b893dc |
$st->[0] &= ~$i;
|
|
Packit |
b893dc |
push @txt,$_;
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
die "incomplete: @txt | $st->[0]" if $st->[0];
|
|
Packit |
b893dc |
$st = join("|",@txt);
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
if ("@states" =~ $expect) {
|
|
Packit |
b893dc |
pass("$where: @states");
|
|
Packit |
b893dc |
} else {
|
|
Packit |
b893dc |
fail("$where: @states");
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
}
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
my $expect = qr{^
|
|
Packit |
b893dc |
CB_HANDSHAKE_START\s
|
|
Packit |
b893dc |
(CB_CONNECT_LOOP\s)+
|
|
Packit |
b893dc |
CB_HANDSHAKE_DONE\s
|
|
Packit |
b893dc |
CB_CONNECT_EXIT\b
|
|
Packit |
b893dc |
}x;
|
|
Packit |
b893dc |
|
|
Packit |
b893dc |
client('ctx',$expect);
|
|
Packit |
b893dc |
client('ssl',$expect);
|
|
Packit |
b893dc |
waitpid $pid, 0;
|
|
Packit |
b893dc |
|