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>