22 | 22 |
use TLSProxy::ServerKeyExchange;
|
23 | 23 |
use TLSProxy::NewSessionTicket;
|
24 | 24 |
|
25 | |
my $have_IPv6 = 0;
|
|
25 |
my $have_IPv6;
|
26 | 26 |
my $IP_factory;
|
27 | 27 |
|
28 | |
my $is_tls13 = 0;
|
29 | |
my $ciphersuite = undef;
|
30 | |
|
31 | |
sub new
|
32 | |
{
|
33 | |
my $class = shift;
|
34 | |
my ($filter,
|
35 | |
$execute,
|
36 | |
$cert,
|
37 | |
$debug) = @_;
|
38 | |
|
39 | |
my $self = {
|
40 | |
#Public read/write
|
41 | |
proxy_addr => "localhost",
|
42 | |
server_addr => "localhost",
|
43 | |
filter => $filter,
|
44 | |
serverflags => "",
|
45 | |
clientflags => "",
|
46 | |
serverconnects => 1,
|
47 | |
reneg => 0,
|
48 | |
sessionfile => undef,
|
49 | |
|
50 | |
#Public read
|
51 | |
proxy_port => 0,
|
52 | |
server_port => 0,
|
53 | |
serverpid => 0,
|
54 | |
clientpid => 0,
|
55 | |
execute => $execute,
|
56 | |
cert => $cert,
|
57 | |
debug => $debug,
|
58 | |
cipherc => "",
|
59 | |
ciphersuitesc => "",
|
60 | |
ciphers => "AES128-SHA",
|
61 | |
ciphersuitess => "TLS_AES_128_GCM_SHA256",
|
62 | |
flight => -1,
|
63 | |
direction => -1,
|
64 | |
partial => ["", ""],
|
65 | |
record_list => [],
|
66 | |
message_list => [],
|
67 | |
};
|
68 | |
|
|
28 |
BEGIN
|
|
29 |
{
|
69 | 30 |
# IO::Socket::IP is on the core module list, IO::Socket::INET6 isn't.
|
70 | 31 |
# However, IO::Socket::INET6 is older and is said to be more widely
|
71 | 32 |
# deployed for the moment, and may have less bugs, so we try the latter
|
72 | |
# first, then fall back on the code modules. Worst case scenario, we
|
|
33 |
# first, then fall back on the core modules. Worst case scenario, we
|
73 | 34 |
# fall back to IO::Socket::INET, only supports IPv4.
|
74 | 35 |
eval {
|
75 | 36 |
require IO::Socket::INET6;
|
|
100 | 61 |
$have_IPv6 = 1;
|
101 | 62 |
} else {
|
102 | 63 |
$IP_factory = sub { IO::Socket::INET->new(@_); };
|
103 | |
}
|
104 | |
}
|
|
64 |
$have_IPv6 = 0;
|
|
65 |
}
|
|
66 |
}
|
|
67 |
}
|
|
68 |
|
|
69 |
my $is_tls13 = 0;
|
|
70 |
my $ciphersuite = undef;
|
|
71 |
|
|
72 |
sub new
|
|
73 |
{
|
|
74 |
my $class = shift;
|
|
75 |
my ($filter,
|
|
76 |
$execute,
|
|
77 |
$cert,
|
|
78 |
$debug) = @_;
|
|
79 |
|
|
80 |
my $self = {
|
|
81 |
#Public read/write
|
|
82 |
proxy_addr => $have_IPv6 ? "[::1]" : "127.0.0.1",
|
|
83 |
filter => $filter,
|
|
84 |
serverflags => "",
|
|
85 |
clientflags => "",
|
|
86 |
serverconnects => 1,
|
|
87 |
reneg => 0,
|
|
88 |
sessionfile => undef,
|
|
89 |
|
|
90 |
#Public read
|
|
91 |
proxy_port => 0,
|
|
92 |
server_port => 0,
|
|
93 |
serverpid => 0,
|
|
94 |
clientpid => 0,
|
|
95 |
execute => $execute,
|
|
96 |
cert => $cert,
|
|
97 |
debug => $debug,
|
|
98 |
cipherc => "",
|
|
99 |
ciphersuitesc => "",
|
|
100 |
ciphers => "AES128-SHA",
|
|
101 |
ciphersuitess => "TLS_AES_128_GCM_SHA256",
|
|
102 |
flight => -1,
|
|
103 |
direction => -1,
|
|
104 |
partial => ["", ""],
|
|
105 |
record_list => [],
|
|
106 |
message_list => [],
|
|
107 |
};
|
105 | 108 |
|
106 | 109 |
# Create the Proxy socket
|
107 | 110 |
my $proxaddr = $self->{proxy_addr};
|
|
112 | 115 |
Proto => "tcp",
|
113 | 116 |
Listen => SOMAXCONN,
|
114 | 117 |
);
|
115 | |
$self->{proxy_sock} = $IP_factory->(@proxyargs);
|
116 | |
|
117 | |
if ($self->{proxy_sock}) {
|
118 | |
$self->{proxy_port} = $self->{proxy_sock}->sockport();
|
119 | |
print "Proxy started on port ".$self->{proxy_port}."\n";
|
|
118 |
|
|
119 |
if (my $sock = $IP_factory->(@proxyargs)) {
|
|
120 |
$self->{proxy_sock} = $sock;
|
|
121 |
$self->{proxy_port} = $sock->sockport();
|
|
122 |
$self->{proxy_addr} = $sock->sockhost();
|
|
123 |
$self->{proxy_addr} =~ s/(.*:.*)/[$1]/;
|
|
124 |
print "Proxy started on port ",
|
|
125 |
"$self->{proxy_addr}:$self->{proxy_port}\n";
|
|
126 |
# use same address for s_server
|
|
127 |
$self->{server_addr} = $self->{proxy_addr};
|
120 | 128 |
} else {
|
121 | 129 |
warn "Failed creating proxy socket (".$proxaddr.",0): $!\n";
|
122 | 130 |
}
|
|
211 | 219 |
|
212 | 220 |
my $execcmd = $self->execute
|
213 | 221 |
." s_server -max_protocol TLSv1.3 -no_comp -rev -engine ossltest"
|
214 | |
." -accept 0 -cert ".$self->cert." -cert2 ".$self->cert
|
|
222 |
." -accept $self->{server_addr}:0"
|
|
223 |
." -cert ".$self->cert." -cert2 ".$self->cert
|
215 | 224 |
." -naccept ".$self->serverconnects;
|
216 | |
unless ($self->supports_IPv6) {
|
217 | |
$execcmd .= " -4";
|
218 | |
}
|
219 | 225 |
if ($self->ciphers ne "") {
|
220 | 226 |
$execcmd .= " -cipher ".$self->ciphers;
|
221 | 227 |
}
|
|
285 | 291 |
$self->{serverpid} = $pid;
|
286 | 292 |
|
287 | 293 |
print STDERR "Server responds on ",
|
288 | |
$self->{server_addr}, ":", $self->{server_port}, "\n";
|
|
294 |
"$self->{server_addr}:$self->{server_port}\n";
|
289 | 295 |
|
290 | 296 |
# Connect right away...
|
291 | 297 |
$self->connect_to_server();
|
|
300 | 306 |
if ($self->execute) {
|
301 | 307 |
my $pid;
|
302 | 308 |
my $execcmd = $self->execute
|
303 | |
." s_client -max_protocol TLSv1.3 -engine ossltest -connect "
|
304 | |
.($self->proxy_addr).":".($self->proxy_port);
|
305 | |
unless ($self->supports_IPv6) {
|
306 | |
$execcmd .= " -4";
|
307 | |
}
|
|
309 |
." s_client -max_protocol TLSv1.3 -engine ossltest"
|
|
310 |
." -connect $self->{proxy_addr}:$self->{proxy_port}";
|
308 | 311 |
if ($self->cipherc ne "") {
|
309 | 312 |
$execcmd .= " -cipher ".$self->cipherc;
|
310 | 313 |
}
|
|
313 | 316 |
}
|
314 | 317 |
if ($self->clientflags ne "") {
|
315 | 318 |
$execcmd .= " ".$self->clientflags;
|
|
319 |
}
|
|
320 |
if ($self->clientflags !~ m/-(no)?servername/) {
|
|
321 |
$execcmd .= " -servername localhost";
|
316 | 322 |
}
|
317 | 323 |
if (defined $self->sessionfile) {
|
318 | 324 |
$execcmd .= " -ign_eof";
|