Annotation of embedaddon/curl/tests/secureserver.pl, revision 1.1

1.1     ! misho       1: #!/usr/bin/env perl
        !             2: #***************************************************************************
        !             3: #                                  _   _ ____  _
        !             4: #  Project                     ___| | | |  _ \| |
        !             5: #                             / __| | | | |_) | |
        !             6: #                            | (__| |_| |  _ <| |___
        !             7: #                             \___|\___/|_| \_\_____|
        !             8: #
        !             9: # Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
        !            10: #
        !            11: # This software is licensed as described in the file COPYING, which
        !            12: # you should have received as part of this distribution. The terms
        !            13: # are also available at https://curl.haxx.se/docs/copyright.html.
        !            14: #
        !            15: # You may opt to use, copy, modify, merge, publish, distribute and/or sell
        !            16: # copies of the Software, and permit persons to whom the Software is
        !            17: # furnished to do so, under the terms of the COPYING file.
        !            18: #
        !            19: # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
        !            20: # KIND, either express or implied.
        !            21: #
        !            22: #***************************************************************************
        !            23: 
        !            24: # This is the HTTPS, FTPS, POP3S, IMAPS, SMTPS, server used for curl test
        !            25: # harness. Actually just a layer that runs stunnel properly using the
        !            26: # non-secure test harness servers.
        !            27: 
        !            28: BEGIN {
        !            29:     push(@INC, $ENV{'srcdir'}) if(defined $ENV{'srcdir'});
        !            30:     push(@INC, ".");
        !            31: }
        !            32: 
        !            33: use strict;
        !            34: use warnings;
        !            35: use Cwd;
        !            36: use Cwd 'abs_path';
        !            37: 
        !            38: use serverhelp qw(
        !            39:     server_pidfilename
        !            40:     server_logfilename
        !            41:     );
        !            42: 
        !            43: use pathhelp;
        !            44: 
        !            45: my $stunnel = "stunnel";
        !            46: 
        !            47: my $verbose=0; # set to 1 for debugging
        !            48: 
        !            49: my $accept_port = 8991; # just our default, weird enough
        !            50: my $target_port = 8999; # default test http-server port
        !            51: 
        !            52: my $stuncert;
        !            53: 
        !            54: my $ver_major;
        !            55: my $ver_minor;
        !            56: my $fips_support;
        !            57: my $stunnel_version;
        !            58: my $tstunnel_windows;
        !            59: my $socketopt;
        !            60: my $cmd;
        !            61: 
        !            62: my $pidfile;          # stunnel pid file
        !            63: my $logfile;          # stunnel log file
        !            64: my $loglevel = 5;     # stunnel log level
        !            65: my $ipvnum = 4;       # default IP version of stunneled server
        !            66: my $idnum = 1;        # default stunneled server instance number
        !            67: my $proto = 'https';  # default secure server protocol
        !            68: my $conffile;         # stunnel configuration file
        !            69: my $capath;           # certificate chain PEM folder
        !            70: my $certfile;         # certificate chain PEM file
        !            71: 
        !            72: #***************************************************************************
        !            73: # stunnel requires full path specification for several files.
        !            74: #
        !            75: my $path   = getcwd();
        !            76: my $srcdir = $path;
        !            77: my $logdir = $path .'/log';
        !            78: 
        !            79: #***************************************************************************
        !            80: # Signal handler to remove our stunnel 4.00 and newer configuration file.
        !            81: #
        !            82: sub exit_signal_handler {
        !            83:     my $signame = shift;
        !            84:     local $!; # preserve errno
        !            85:     local $?; # preserve exit status
        !            86:     unlink($conffile) if($conffile && (-f $conffile));
        !            87:     exit;
        !            88: }
        !            89: 
        !            90: #***************************************************************************
        !            91: # Process command line options
        !            92: #
        !            93: while(@ARGV) {
        !            94:     if($ARGV[0] eq '--verbose') {
        !            95:         $verbose = 1;
        !            96:     }
        !            97:     elsif($ARGV[0] eq '--proto') {
        !            98:         if($ARGV[1]) {
        !            99:             $proto = $ARGV[1];
        !           100:             shift @ARGV;
        !           101:         }
        !           102:     }
        !           103:     elsif($ARGV[0] eq '--accept') {
        !           104:         if($ARGV[1]) {
        !           105:             if($ARGV[1] =~ /^(\d+)$/) {
        !           106:                 $accept_port = $1;
        !           107:                 shift @ARGV;
        !           108:             }
        !           109:         }
        !           110:     }
        !           111:     elsif($ARGV[0] eq '--connect') {
        !           112:         if($ARGV[1]) {
        !           113:             if($ARGV[1] =~ /^(\d+)$/) {
        !           114:                 $target_port = $1;
        !           115:                 shift @ARGV;
        !           116:             }
        !           117:         }
        !           118:     }
        !           119:     elsif($ARGV[0] eq '--stunnel') {
        !           120:         if($ARGV[1]) {
        !           121:             if($ARGV[1] =~ /^([\w\/]+)$/) {
        !           122:                 $stunnel = $ARGV[1];
        !           123:             }
        !           124:             else {
        !           125:                 $stunnel = "\"". $ARGV[1] ."\"";
        !           126:             }
        !           127:             shift @ARGV;
        !           128:         }
        !           129:     }
        !           130:     elsif($ARGV[0] eq '--srcdir') {
        !           131:         if($ARGV[1]) {
        !           132:             $srcdir = $ARGV[1];
        !           133:             shift @ARGV;
        !           134:         }
        !           135:     }
        !           136:     elsif($ARGV[0] eq '--certfile') {
        !           137:         if($ARGV[1]) {
        !           138:             $stuncert = $ARGV[1];
        !           139:             shift @ARGV;
        !           140:         }
        !           141:     }
        !           142:     elsif($ARGV[0] eq '--id') {
        !           143:         if($ARGV[1]) {
        !           144:             if($ARGV[1] =~ /^(\d+)$/) {
        !           145:                 $idnum = $1 if($1 > 0);
        !           146:                 shift @ARGV;
        !           147:             }
        !           148:         }
        !           149:     }
        !           150:     elsif($ARGV[0] eq '--ipv4') {
        !           151:         $ipvnum = 4;
        !           152:     }
        !           153:     elsif($ARGV[0] eq '--ipv6') {
        !           154:         $ipvnum = 6;
        !           155:     }
        !           156:     elsif($ARGV[0] eq '--pidfile') {
        !           157:         if($ARGV[1]) {
        !           158:             $pidfile = "$path/". $ARGV[1];
        !           159:             shift @ARGV;
        !           160:         }
        !           161:     }
        !           162:     elsif($ARGV[0] eq '--logfile') {
        !           163:         if($ARGV[1]) {
        !           164:             $logfile = "$path/". $ARGV[1];
        !           165:             shift @ARGV;
        !           166:         }
        !           167:     }
        !           168:     else {
        !           169:         print STDERR "\nWarning: secureserver.pl unknown parameter: $ARGV[0]\n";
        !           170:     }
        !           171:     shift @ARGV;
        !           172: }
        !           173: 
        !           174: #***************************************************************************
        !           175: # Initialize command line option dependent variables
        !           176: #
        !           177: if(!$pidfile) {
        !           178:     $pidfile = "$path/". server_pidfilename($proto, $ipvnum, $idnum);
        !           179: }
        !           180: if(!$logfile) {
        !           181:     $logfile = server_logfilename($logdir, $proto, $ipvnum, $idnum);
        !           182: }
        !           183: 
        !           184: $conffile = "$path/${proto}_stunnel.conf";
        !           185: 
        !           186: $capath = abs_path($path);
        !           187: $certfile = "$srcdir/". ($stuncert?"certs/$stuncert":"stunnel.pem");
        !           188: $certfile = abs_path($certfile);
        !           189: 
        !           190: my $ssltext = uc($proto) ." SSL/TLS:";
        !           191: 
        !           192: #***************************************************************************
        !           193: # Find out version info for the given stunnel binary
        !           194: #
        !           195: foreach my $veropt (('-version', '-V')) {
        !           196:     foreach my $verstr (qx($stunnel $veropt 2>&1)) {
        !           197:         if($verstr =~ /^stunnel (\d+)\.(\d+) on /) {
        !           198:             $ver_major = $1;
        !           199:             $ver_minor = $2;
        !           200:         }
        !           201:         elsif($verstr =~ /^sslVersion.*fips *= *yes/) {
        !           202:             # the fips option causes an error if stunnel doesn't support it
        !           203:             $fips_support = 1;
        !           204:             last
        !           205:         }
        !           206:     }
        !           207:     last if($ver_major);
        !           208: }
        !           209: if((!$ver_major) || (!$ver_minor)) {
        !           210:     if(-x "$stunnel" && ! -d "$stunnel") {
        !           211:         print "$ssltext Unknown stunnel version\n";
        !           212:     }
        !           213:     else {
        !           214:         print "$ssltext No stunnel\n";
        !           215:     }
        !           216:     exit 1;
        !           217: }
        !           218: $stunnel_version = (100*$ver_major) + $ver_minor;
        !           219: 
        !           220: #***************************************************************************
        !           221: # Verify minimum stunnel required version
        !           222: #
        !           223: if($stunnel_version < 310) {
        !           224:     print "$ssltext Unsupported stunnel version $ver_major.$ver_minor\n";
        !           225:     exit 1;
        !           226: }
        !           227: 
        !           228: #***************************************************************************
        !           229: # Find out if we are running on Windows using the tstunnel binary
        !           230: #
        !           231: if($stunnel =~ /tstunnel(\.exe)?"?$/) {
        !           232:     $tstunnel_windows = 1;
        !           233: 
        !           234:     # convert Cygwin/MinGW paths to Win32 format
        !           235:     $capath = pathhelp::sys_native_abs_path($capath);
        !           236:     $certfile = pathhelp::sys_native_abs_path($certfile);
        !           237: }
        !           238: 
        !           239: #***************************************************************************
        !           240: # Build command to execute for stunnel 3.X versions
        !           241: #
        !           242: if($stunnel_version < 400) {
        !           243:     if($stunnel_version >= 319) {
        !           244:         $socketopt = "-O a:SO_REUSEADDR=1";
        !           245:     }
        !           246:     $cmd  = "$stunnel -p $certfile -P $pidfile ";
        !           247:     $cmd .= "-d $accept_port -r $target_port -f -D $loglevel ";
        !           248:     $cmd .= ($socketopt) ? "$socketopt " : "";
        !           249:     $cmd .= ">$logfile 2>&1";
        !           250:     if($verbose) {
        !           251:         print uc($proto) ." server (stunnel $ver_major.$ver_minor)\n";
        !           252:         print "cmd: $cmd\n";
        !           253:         print "pem cert file: $certfile\n";
        !           254:         print "pid file: $pidfile\n";
        !           255:         print "log file: $logfile\n";
        !           256:         print "log level: $loglevel\n";
        !           257:         print "listen on port: $accept_port\n";
        !           258:         print "connect to port: $target_port\n";
        !           259:     }
        !           260: }
        !           261: 
        !           262: #***************************************************************************
        !           263: # Build command to execute for stunnel 4.00 and newer
        !           264: #
        !           265: if($stunnel_version >= 400) {
        !           266:     $socketopt = "a:SO_REUSEADDR=1";
        !           267:     if(($stunnel_version >= 534) && $tstunnel_windows) {
        !           268:         # SO_EXCLUSIVEADDRUSE is on by default on Vista or newer,
        !           269:         # but does not work together with SO_REUSEADDR being on.
        !           270:         $socketopt .= "\nsocket = a:SO_EXCLUSIVEADDRUSE=0";
        !           271:     }
        !           272:     $cmd  = "$stunnel $conffile ";
        !           273:     $cmd .= ">$logfile 2>&1";
        !           274:     # setup signal handler
        !           275:     $SIG{INT} = \&exit_signal_handler;
        !           276:     $SIG{TERM} = \&exit_signal_handler;
        !           277:     # stunnel configuration file
        !           278:     if(open(STUNCONF, ">$conffile")) {
        !           279:         print STUNCONF "CApath = $capath\n";
        !           280:         print STUNCONF "cert = $certfile\n";
        !           281:         print STUNCONF "debug = $loglevel\n";
        !           282:         print STUNCONF "socket = $socketopt\n";
        !           283:         if($fips_support) {
        !           284:             # disable fips in case OpenSSL doesn't support it
        !           285:             print STUNCONF "fips = no\n";
        !           286:         }
        !           287:         if(!$tstunnel_windows) {
        !           288:             # do not use Linux-specific options on Windows
        !           289:             print STUNCONF "output = $logfile\n";
        !           290:             print STUNCONF "pid = $pidfile\n";
        !           291:             print STUNCONF "foreground = yes\n";
        !           292:         }
        !           293:         print STUNCONF "\n";
        !           294:         print STUNCONF "[curltest]\n";
        !           295:         print STUNCONF "accept = $accept_port\n";
        !           296:         print STUNCONF "connect = $target_port\n";
        !           297:         if(!close(STUNCONF)) {
        !           298:             print "$ssltext Error closing file $conffile\n";
        !           299:             exit 1;
        !           300:         }
        !           301:     }
        !           302:     else {
        !           303:         print "$ssltext Error writing file $conffile\n";
        !           304:         exit 1;
        !           305:     }
        !           306:     if($verbose) {
        !           307:         print uc($proto) ." server (stunnel $ver_major.$ver_minor)\n";
        !           308:         print "cmd: $cmd\n";
        !           309:         print "CApath = $capath\n";
        !           310:         print "cert = $certfile\n";
        !           311:         print "debug = $loglevel\n";
        !           312:         print "socket = $socketopt\n";
        !           313:         if($fips_support) {
        !           314:             print "fips = no\n";
        !           315:         }
        !           316:         if(!$tstunnel_windows) {
        !           317:             print "pid = $pidfile\n";
        !           318:             print "output = $logfile\n";
        !           319:             print "foreground = yes\n";
        !           320:         }
        !           321:         print "\n";
        !           322:         print "[curltest]\n";
        !           323:         print "accept = $accept_port\n";
        !           324:         print "connect = $target_port\n";
        !           325:     }
        !           326: }
        !           327: 
        !           328: #***************************************************************************
        !           329: # Set file permissions on certificate pem file.
        !           330: #
        !           331: chmod(0600, $certfile) if(-f $certfile);
        !           332: print STDERR "RUN: $cmd\n" if($verbose);
        !           333: 
        !           334: #***************************************************************************
        !           335: # Run tstunnel on Windows.
        !           336: #
        !           337: if($tstunnel_windows) {
        !           338:     # Fake pidfile for tstunnel on Windows.
        !           339:     if(open(OUT, ">$pidfile")) {
        !           340:         print OUT $$ . "\n";
        !           341:         close(OUT);
        !           342:     }
        !           343: 
        !           344:     # Put an "exec" in front of the command so that the child process
        !           345:     # keeps this child's process ID by being tied to the spawned shell.
        !           346:     exec("exec $cmd") || die "Can't exec() $cmd: $!";
        !           347:     # exec() will create a new process, but ties the existance of the
        !           348:     # new process to the parent waiting perl.exe and sh.exe processes.
        !           349: 
        !           350:     # exec() should never return back here to this process. We protect
        !           351:     # ourselves by calling die() just in case something goes really bad.
        !           352:     die "error: exec() has returned";
        !           353: }
        !           354: 
        !           355: #***************************************************************************
        !           356: # Run stunnel.
        !           357: #
        !           358: my $rc = system($cmd);
        !           359: 
        !           360: $rc >>= 8;
        !           361: 
        !           362: unlink($conffile) if($conffile && -f $conffile);
        !           363: 
        !           364: exit $rc;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>