Consolidate the locations where we have our internal perl modules
[openssl.git] / util / TLSProxy / Proxy.pm
diff --git a/util/TLSProxy/Proxy.pm b/util/TLSProxy/Proxy.pm
deleted file mode 100644 (file)
index c92652e..0000000
+++ /dev/null
@@ -1,603 +0,0 @@
-# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
-#
-# Licensed under the OpenSSL license (the "License").  You may not use
-# this file except in compliance with the License.  You can obtain a copy
-# in the file LICENSE in the source distribution or at
-# https://www.openssl.org/source/license.html
-
-use strict;
-use POSIX ":sys_wait_h";
-
-package TLSProxy::Proxy;
-
-use File::Spec;
-use IO::Socket;
-use IO::Select;
-use TLSProxy::Record;
-use TLSProxy::Message;
-use TLSProxy::ClientHello;
-use TLSProxy::HelloRetryRequest;
-use TLSProxy::ServerHello;
-use TLSProxy::EncryptedExtensions;
-use TLSProxy::Certificate;
-use TLSProxy::CertificateVerify;
-use TLSProxy::ServerKeyExchange;
-use TLSProxy::NewSessionTicket;
-
-my $have_IPv6 = 0;
-my $IP_factory;
-
-my $is_tls13 = 0;
-my $ciphersuite = undef;
-
-sub new
-{
-    my $class = shift;
-    my ($filter,
-        $execute,
-        $cert,
-        $debug) = @_;
-
-    my $self = {
-        #Public read/write
-        proxy_addr => "localhost",
-        proxy_port => 4453,
-        server_addr => "localhost",
-        server_port => 4443,
-        filter => $filter,
-        serverflags => "",
-        clientflags => "",
-        serverconnects => 1,
-        serverpid => 0,
-        clientpid => 0,
-        reneg => 0,
-        sessionfile => undef,
-
-        #Public read
-        execute => $execute,
-        cert => $cert,
-        debug => $debug,
-        cipherc => "",
-        ciphers => "AES128-SHA:TLS13-AES-128-GCM-SHA256",
-        flight => 0,
-        record_list => [],
-        message_list => [],
-    };
-
-    # IO::Socket::IP is on the core module list, IO::Socket::INET6 isn't.
-    # However, IO::Socket::INET6 is older and is said to be more widely
-    # deployed for the moment, and may have less bugs, so we try the latter
-    # first, then fall back on the code modules.  Worst case scenario, we
-    # fall back to IO::Socket::INET, only supports IPv4.
-    eval {
-        require IO::Socket::INET6;
-        my $s = IO::Socket::INET6->new(
-            LocalAddr => "::1",
-            LocalPort => 0,
-            Listen=>1,
-            );
-        $s or die "\n";
-        $s->close();
-    };
-    if ($@ eq "") {
-        $IP_factory = sub { IO::Socket::INET6->new(@_); };
-        $have_IPv6 = 1;
-    } else {
-        eval {
-            require IO::Socket::IP;
-            my $s = IO::Socket::IP->new(
-                LocalAddr => "::1",
-                LocalPort => 0,
-                Listen=>1,
-                );
-            $s or die "\n";
-            $s->close();
-        };
-        if ($@ eq "") {
-            $IP_factory = sub { IO::Socket::IP->new(@_); };
-            $have_IPv6 = 1;
-        } else {
-            $IP_factory = sub { IO::Socket::INET->new(@_); };
-        }
-    }
-
-    return bless $self, $class;
-}
-
-sub clearClient
-{
-    my $self = shift;
-
-    $self->{cipherc} = "";
-    $self->{flight} = 0;
-    $self->{record_list} = [];
-    $self->{message_list} = [];
-    $self->{clientflags} = "";
-    $self->{sessionfile} = undef;
-    $self->{clientpid} = 0;
-    $is_tls13 = 0;
-    $ciphersuite = undef;
-
-    TLSProxy::Message->clear();
-    TLSProxy::Record->clear();
-}
-
-sub clear
-{
-    my $self = shift;
-
-    $self->clearClient;
-    $self->{ciphers} = "AES128-SHA:TLS13-AES-128-GCM-SHA256";
-    $self->{serverflags} = "";
-    $self->{serverconnects} = 1;
-    $self->{serverpid} = 0;
-    $self->{reneg} = 0;
-}
-
-sub restart
-{
-    my $self = shift;
-
-    $self->clear;
-    $self->start;
-}
-
-sub clientrestart
-{
-    my $self = shift;
-
-    $self->clear;
-    $self->clientstart;
-}
-
-sub start
-{
-    my ($self) = shift;
-    my $pid;
-
-    $pid = fork();
-    if ($pid == 0) {
-        if (!$self->debug) {
-            open(STDOUT, ">", File::Spec->devnull())
-                or die "Failed to redirect stdout: $!";
-            open(STDERR, ">&STDOUT");
-        }
-        my $execcmd = $self->execute
-            ." s_server -no_comp -rev -engine ossltest -accept "
-            .($self->server_port)
-            ." -cert ".$self->cert." -cert2 ".$self->cert
-            ." -naccept ".$self->serverconnects;
-        if ($self->ciphers ne "") {
-            $execcmd .= " -cipher ".$self->ciphers;
-        }
-        if ($self->serverflags ne "") {
-            $execcmd .= " ".$self->serverflags;
-        }
-        if ($self->debug) {
-            print STDERR "Server command: $execcmd\n";
-        }
-        exec($execcmd);
-    }
-    $self->serverpid($pid);
-
-    return $self->clientstart;
-}
-
-sub clientstart
-{
-    my ($self) = shift;
-    my $oldstdout;
-
-    if(!$self->debug) {
-        open DEVNULL, ">", File::Spec->devnull();
-        $oldstdout = select(DEVNULL);
-    }
-
-    # Create the Proxy socket
-    my $proxaddr = $self->proxy_addr;
-    $proxaddr =~ s/[\[\]]//g; # Remove [ and ]
-    my $proxy_sock = $IP_factory->(
-        LocalHost   => $proxaddr,
-        LocalPort   => $self->proxy_port,
-        Proto       => "tcp",
-        Listen      => SOMAXCONN,
-        ReuseAddr   => 1
-    );
-
-    if ($proxy_sock) {
-        print "Proxy started on port ".$self->proxy_port."\n";
-    } else {
-        warn "Failed creating proxy socket (".$proxaddr.",".$self->proxy_port."): $!\n";
-        return 0;
-    }
-
-    if ($self->execute) {
-        my $pid = fork();
-        if ($pid == 0) {
-            if (!$self->debug) {
-                open(STDOUT, ">", File::Spec->devnull())
-                    or die "Failed to redirect stdout: $!";
-                open(STDERR, ">&STDOUT");
-            }
-            my $echostr;
-            if ($self->reneg()) {
-                $echostr = "R";
-            } else {
-                $echostr = "test";
-            }
-            my $execcmd = "echo ".$echostr." | ".$self->execute
-                 ." s_client -engine ossltest -connect "
-                 .($self->proxy_addr).":".($self->proxy_port);
-            if ($self->cipherc ne "") {
-                $execcmd .= " -cipher ".$self->cipherc;
-            }
-            if ($self->clientflags ne "") {
-                $execcmd .= " ".$self->clientflags;
-            }
-            if (defined $self->sessionfile) {
-                $execcmd .= " -ign_eof";
-            }
-            if ($self->debug) {
-                print STDERR "Client command: $execcmd\n";
-            }
-            exec($execcmd);
-        }
-        $self->clientpid($pid);
-    }
-
-    # Wait for incoming connection from client
-    my $client_sock;
-    if(!($client_sock = $proxy_sock->accept())) {
-        warn "Failed accepting incoming connection: $!\n";
-        return 0;
-    }
-
-    print "Connection opened\n";
-
-    # Now connect to the server
-    my $retry = 10;
-    my $server_sock;
-    #We loop over this a few times because sometimes s_server can take a while
-    #to start up
-    do {
-        my $servaddr = $self->server_addr;
-        $servaddr =~ s/[\[\]]//g; # Remove [ and ]
-        eval {
-            $server_sock = $IP_factory->(
-                PeerAddr => $servaddr,
-                PeerPort => $self->server_port,
-                MultiHomed => 1,
-                Proto => 'tcp'
-            );
-        };
-
-        $retry--;
-        #Some buggy IP factories can return a defined server_sock that hasn't
-        #actually connected, so we check peerport too
-        if ($@ || !defined($server_sock) || !defined($server_sock->peerport)) {
-            $server_sock->close() if defined($server_sock);
-            undef $server_sock;
-            if ($retry) {
-                #Sleep for a short while
-                select(undef, undef, undef, 0.1);
-            } else {
-                warn "Failed to start up server (".$servaddr.",".$self->server_port."): $!\n";
-                return 0;
-            }
-        }
-    } while (!$server_sock);
-
-    my $sel = IO::Select->new($server_sock, $client_sock);
-    my $indata;
-    my @handles = ($server_sock, $client_sock);
-
-    #Wait for either the server socket or the client socket to become readable
-    my @ready;
-    my $ctr = 0;
-    while(     (!(TLSProxy::Message->end)
-                || (defined $self->sessionfile()
-                    && (-s $self->sessionfile()) == 0))
-            && $ctr < 10
-            && (@ready = $sel->can_read(1))) {
-        foreach my $hand (@ready) {
-            if ($hand == $server_sock) {
-                $server_sock->sysread($indata, 16384) or goto END;
-                $indata = $self->process_packet(1, $indata);
-                $client_sock->syswrite($indata);
-                $ctr = 0;
-            } elsif ($hand == $client_sock) {
-                $client_sock->sysread($indata, 16384) or goto END;
-                $indata = $self->process_packet(0, $indata);
-                $server_sock->syswrite($indata);
-                $ctr = 0;
-            } else {
-                $ctr++
-            }
-        }
-    }
-
-    die "No progress made" if $ctr >= 10;
-
-    END:
-    print "Connection closed\n";
-    if($server_sock) {
-        $server_sock->close();
-    }
-    if($client_sock) {
-        #Closing this also kills the child process
-        $client_sock->close();
-    }
-    if($proxy_sock) {
-        $proxy_sock->close();
-    }
-    if(!$self->debug) {
-        select($oldstdout);
-    }
-    $self->serverconnects($self->serverconnects - 1);
-    if ($self->serverconnects == 0) {
-        die "serverpid is zero\n" if $self->serverpid == 0;
-        print "Waiting for server process to close: "
-              .$self->serverpid."\n";
-        waitpid( $self->serverpid, 0);
-        die "exit code $? from server process\n" if $? != 0;
-    }
-    die "clientpid is zero\n" if $self->clientpid == 0;
-    print "Waiting for client process to close: ".$self->clientpid."\n";
-    waitpid($self->clientpid, 0);
-
-    return 1;
-}
-
-sub process_packet
-{
-    my ($self, $server, $packet) = @_;
-    my $len_real;
-    my $decrypt_len;
-    my $data;
-    my $recnum;
-
-    if ($server) {
-        print "Received server packet\n";
-    } else {
-        print "Received client packet\n";
-    }
-
-    print "Packet length = ".length($packet)."\n";
-    print "Processing flight ".$self->flight."\n";
-
-    #Return contains the list of record found in the packet followed by the
-    #list of messages in those records
-    my @ret = TLSProxy::Record->get_records($server, $self->flight, $packet);
-    push @{$self->record_list}, @{$ret[0]};
-    push @{$self->{message_list}}, @{$ret[1]};
-
-    print "\n";
-
-    #Finished parsing. Call user provided filter here
-    if(defined $self->filter) {
-        $self->filter->($self);
-    }
-
-    #Reconstruct the packet
-    $packet = "";
-    foreach my $record (@{$self->record_list}) {
-        #We only replay the records for the current flight
-        if ($record->flight != $self->flight) {
-            next;
-        }
-        $packet .= $record->reconstruct_record($server);
-    }
-
-    $self->{flight} = $self->{flight} + 1;
-
-    print "Forwarded packet length = ".length($packet)."\n\n";
-
-    return $packet;
-}
-
-#Read accessors
-sub execute
-{
-    my $self = shift;
-    return $self->{execute};
-}
-sub cert
-{
-    my $self = shift;
-    return $self->{cert};
-}
-sub debug
-{
-    my $self = shift;
-    return $self->{debug};
-}
-sub flight
-{
-    my $self = shift;
-    return $self->{flight};
-}
-sub record_list
-{
-    my $self = shift;
-    return $self->{record_list};
-}
-sub success
-{
-    my $self = shift;
-    return $self->{success};
-}
-sub end
-{
-    my $self = shift;
-    return $self->{end};
-}
-sub supports_IPv6
-{
-    my $self = shift;
-    return $have_IPv6;
-}
-
-#Read/write accessors
-sub proxy_addr
-{
-    my $self = shift;
-    if (@_) {
-        $self->{proxy_addr} = shift;
-    }
-    return $self->{proxy_addr};
-}
-sub proxy_port
-{
-    my $self = shift;
-    if (@_) {
-        $self->{proxy_port} = shift;
-    }
-    return $self->{proxy_port};
-}
-sub server_addr
-{
-    my $self = shift;
-    if (@_) {
-        $self->{server_addr} = shift;
-    }
-    return $self->{server_addr};
-}
-sub server_port
-{
-    my $self = shift;
-    if (@_) {
-        $self->{server_port} = shift;
-    }
-    return $self->{server_port};
-}
-sub filter
-{
-    my $self = shift;
-    if (@_) {
-        $self->{filter} = shift;
-    }
-    return $self->{filter};
-}
-sub cipherc
-{
-    my $self = shift;
-    if (@_) {
-        $self->{cipherc} = shift;
-    }
-    return $self->{cipherc};
-}
-sub ciphers
-{
-    my $self = shift;
-    if (@_) {
-        $self->{ciphers} = shift;
-    }
-    return $self->{ciphers};
-}
-sub serverflags
-{
-    my $self = shift;
-    if (@_) {
-        $self->{serverflags} = shift;
-    }
-    return $self->{serverflags};
-}
-sub clientflags
-{
-    my $self = shift;
-    if (@_) {
-        $self->{clientflags} = shift;
-    }
-    return $self->{clientflags};
-}
-sub serverconnects
-{
-    my $self = shift;
-    if (@_) {
-        $self->{serverconnects} = shift;
-    }
-    return $self->{serverconnects};
-}
-# This is a bit ugly because the caller is responsible for keeping the records
-# in sync with the updated message list; simply updating the message list isn't
-# sufficient to get the proxy to forward the new message.
-# But it does the trick for the one test (test_sslsessiontick) that needs it.
-sub message_list
-{
-    my $self = shift;
-    if (@_) {
-        $self->{message_list} = shift;
-    }
-    return $self->{message_list};
-}
-sub serverpid
-{
-    my $self = shift;
-    if (@_) {
-        $self->{serverpid} = shift;
-    }
-    return $self->{serverpid};
-}
-sub clientpid
-{
-    my $self = shift;
-    if (@_) {
-        $self->{clientpid} = shift;
-    }
-    return $self->{clientpid};
-}
-
-sub fill_known_data
-{
-    my $length = shift;
-    my $ret = "";
-    for (my $i = 0; $i < $length; $i++) {
-        $ret .= chr($i);
-    }
-    return $ret;
-}
-
-sub is_tls13
-{
-    my $class = shift;
-    if (@_) {
-        $is_tls13 = shift;
-    }
-    return $is_tls13;
-}
-
-sub reneg
-{
-    my $self = shift;
-    if (@_) {
-        $self->{reneg} = shift;
-    }
-    return $self->{reneg};
-}
-
-#Setting a sessionfile means that the client will not close until the given
-#file exists. This is useful in TLSv1.3 where otherwise s_client will close
-#immediately at the end of the handshake, but before the session has been
-#received from the server. A side effect of this is that s_client never sends
-#a close_notify, so instead we consider success to be when it sends application
-#data over the connection.
-sub sessionfile
-{
-    my $self = shift;
-    if (@_) {
-        $self->{sessionfile} = shift;
-        TLSProxy::Message->successondata(1);
-    }
-    return $self->{sessionfile};
-}
-
-sub ciphersuite
-{
-    my $class = shift;
-    if (@_) {
-        $ciphersuite = shift;
-    }
-    return $ciphersuite;
-}
-
-1;