Annotation of embedaddon/curl/tests/sshserver.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: # Starts sshd for use in the SCP and SFTP curl test harness tests.
        !            25: # Also creates the ssh configuration files needed for these tests.
        !            26: 
        !            27: use strict;
        !            28: use warnings;
        !            29: use Cwd;
        !            30: use Cwd 'abs_path';
        !            31: use Digest::MD5;
        !            32: use Digest::MD5 'md5_hex';
        !            33: use MIME::Base64;
        !            34: 
        !            35: #***************************************************************************
        !            36: # Variables and subs imported from sshhelp module
        !            37: #
        !            38: use sshhelp qw(
        !            39:     $sshdexe
        !            40:     $sshexe
        !            41:     $sftpsrvexe
        !            42:     $sftpexe
        !            43:     $sshkeygenexe
        !            44:     $sshdconfig
        !            45:     $sshconfig
        !            46:     $sftpconfig
        !            47:     $knownhosts
        !            48:     $sshdlog
        !            49:     $sshlog
        !            50:     $sftplog
        !            51:     $sftpcmds
        !            52:     $hstprvkeyf
        !            53:     $hstpubkeyf
        !            54:     $hstpubmd5f
        !            55:     $cliprvkeyf
        !            56:     $clipubkeyf
        !            57:     display_sshdconfig
        !            58:     display_sshconfig
        !            59:     display_sftpconfig
        !            60:     display_sshdlog
        !            61:     display_sshlog
        !            62:     display_sftplog
        !            63:     dump_array
        !            64:     find_sshd
        !            65:     find_ssh
        !            66:     find_sftpsrv
        !            67:     find_sftp
        !            68:     find_sshkeygen
        !            69:     logmsg
        !            70:     sshversioninfo
        !            71:     );
        !            72: 
        !            73: #***************************************************************************
        !            74: # Subs imported from serverhelp module
        !            75: #
        !            76: use serverhelp qw(
        !            77:     server_pidfilename
        !            78:     server_logfilename
        !            79:     );
        !            80: 
        !            81: use pathhelp;
        !            82: 
        !            83: #***************************************************************************
        !            84: 
        !            85: my $verbose = 0;              # set to 1 for debugging
        !            86: my $debugprotocol = 0;        # set to 1 for protocol debugging
        !            87: my $port = 8999;              # our default SCP/SFTP server port
        !            88: my $listenaddr = '127.0.0.1'; # default address on which to listen
        !            89: my $ipvnum = 4;               # default IP version of listener address
        !            90: my $idnum = 1;                # default ssh daemon instance number
        !            91: my $proto = 'ssh';            # protocol the ssh daemon speaks
        !            92: my $path = getcwd();          # current working directory
        !            93: my $logdir = $path .'/log';   # directory for log files
        !            94: my $username = $ENV{USER};    # default user
        !            95: my $pidfile;                  # ssh daemon pid file
        !            96: my $identity = 'curl_client_key'; # default identity file
        !            97: 
        !            98: my $error;
        !            99: my @cfgarr;
        !           100: 
        !           101: 
        !           102: #***************************************************************************
        !           103: # Parse command line options
        !           104: #
        !           105: while(@ARGV) {
        !           106:     if($ARGV[0] eq '--verbose') {
        !           107:         $verbose = 1;
        !           108:     }
        !           109:     elsif($ARGV[0] eq '--debugprotocol') {
        !           110:         $verbose = 1;
        !           111:         $debugprotocol = 1;
        !           112:     }
        !           113:     elsif($ARGV[0] eq '--user') {
        !           114:         if($ARGV[1]) {
        !           115:             $username = $ARGV[1];
        !           116:             shift @ARGV;
        !           117:         }
        !           118:     }
        !           119:     elsif($ARGV[0] eq '--id') {
        !           120:         if($ARGV[1]) {
        !           121:             if($ARGV[1] =~ /^(\d+)$/) {
        !           122:                 $idnum = $1 if($1 > 0);
        !           123:                 shift @ARGV;
        !           124:             }
        !           125:         }
        !           126:     }
        !           127:     elsif($ARGV[0] eq '--ipv4') {
        !           128:         $ipvnum = 4;
        !           129:         $listenaddr = '127.0.0.1' if($listenaddr eq '::1');
        !           130:     }
        !           131:     elsif($ARGV[0] eq '--ipv6') {
        !           132:         $ipvnum = 6;
        !           133:         $listenaddr = '::1' if($listenaddr eq '127.0.0.1');
        !           134:     }
        !           135:     elsif($ARGV[0] eq '--addr') {
        !           136:         if($ARGV[1]) {
        !           137:             my $tmpstr = $ARGV[1];
        !           138:             if($tmpstr =~ /^(\d\d?\d?)\.(\d\d?\d?)\.(\d\d?\d?)\.(\d\d?\d?)$/) {
        !           139:                 $listenaddr = "$1.$2.$3.$4" if($ipvnum == 4);
        !           140:                 shift @ARGV;
        !           141:             }
        !           142:             elsif($ipvnum == 6) {
        !           143:                 $listenaddr = $tmpstr;
        !           144:                 $listenaddr =~ s/^\[(.*)\]$/$1/;
        !           145:                 shift @ARGV;
        !           146:             }
        !           147:         }
        !           148:     }
        !           149:     elsif($ARGV[0] eq '--pidfile') {
        !           150:         if($ARGV[1]) {
        !           151:             $pidfile = "$path/". $ARGV[1];
        !           152:             shift @ARGV;
        !           153:         }
        !           154:     }
        !           155:     elsif($ARGV[0] eq '--sshport') {
        !           156:         if($ARGV[1]) {
        !           157:             if($ARGV[1] =~ /^(\d+)$/) {
        !           158:                 $port = $1;
        !           159:                 shift @ARGV;
        !           160:             }
        !           161:         }
        !           162:     }
        !           163:     else {
        !           164:         print STDERR "\nWarning: sshserver.pl unknown parameter: $ARGV[0]\n";
        !           165:     }
        !           166:     shift @ARGV;
        !           167: }
        !           168: 
        !           169: 
        !           170: #***************************************************************************
        !           171: # Default ssh daemon pid file name
        !           172: #
        !           173: if(!$pidfile) {
        !           174:     $pidfile = "$path/". server_pidfilename($proto, $ipvnum, $idnum);
        !           175: }
        !           176: 
        !           177: 
        !           178: #***************************************************************************
        !           179: # ssh and sftp server log file names
        !           180: #
        !           181: $sshdlog = server_logfilename($logdir, 'ssh', $ipvnum, $idnum);
        !           182: $sftplog = server_logfilename($logdir, 'sftp', $ipvnum, $idnum);
        !           183: 
        !           184: 
        !           185: #***************************************************************************
        !           186: # Logging level for ssh server and client
        !           187: #
        !           188: my $loglevel = $debugprotocol?'DEBUG3':'DEBUG2';
        !           189: 
        !           190: 
        !           191: #***************************************************************************
        !           192: # Validate username
        !           193: #
        !           194: if(!$username) {
        !           195:     $error = 'Will not run ssh server without a user name';
        !           196: }
        !           197: elsif($username eq 'root') {
        !           198:     $error = 'Will not run ssh server as root to mitigate security risks';
        !           199: }
        !           200: if($error) {
        !           201:     logmsg $error;
        !           202:     exit 1;
        !           203: }
        !           204: 
        !           205: 
        !           206: #***************************************************************************
        !           207: # Find out ssh daemon canonical file name
        !           208: #
        !           209: my $sshd = find_sshd();
        !           210: if(!$sshd) {
        !           211:     logmsg "cannot find $sshdexe";
        !           212:     exit 1;
        !           213: }
        !           214: 
        !           215: 
        !           216: #***************************************************************************
        !           217: # Find out ssh daemon version info
        !           218: #
        !           219: my ($sshdid, $sshdvernum, $sshdverstr, $sshderror) = sshversioninfo($sshd);
        !           220: if(!$sshdid) {
        !           221:     # Not an OpenSSH or SunSSH ssh daemon
        !           222:     logmsg $sshderror if($verbose);
        !           223:     logmsg 'SCP and SFTP tests require OpenSSH 2.9.9 or later';
        !           224:     exit 1;
        !           225: }
        !           226: logmsg "ssh server found $sshd is $sshdverstr" if($verbose);
        !           227: 
        !           228: 
        !           229: #***************************************************************************
        !           230: #  ssh daemon command line options we might use and version support
        !           231: #
        !           232: #  -e:  log stderr           : OpenSSH 2.9.0 and later
        !           233: #  -f:  sshd config file     : OpenSSH 1.2.1 and later
        !           234: #  -D:  no daemon forking    : OpenSSH 2.5.0 and later
        !           235: #  -o:  command-line option  : OpenSSH 3.1.0 and later
        !           236: #  -t:  test config file     : OpenSSH 2.9.9 and later
        !           237: #  -?:  sshd version info    : OpenSSH 1.2.1 and later
        !           238: #
        !           239: #  -e:  log stderr           : SunSSH 1.0.0 and later
        !           240: #  -f:  sshd config file     : SunSSH 1.0.0 and later
        !           241: #  -D:  no daemon forking    : SunSSH 1.0.0 and later
        !           242: #  -o:  command-line option  : SunSSH 1.0.0 and later
        !           243: #  -t:  test config file     : SunSSH 1.0.0 and later
        !           244: #  -?:  sshd version info    : SunSSH 1.0.0 and later
        !           245: 
        !           246: 
        !           247: #***************************************************************************
        !           248: # Verify minimum ssh daemon version
        !           249: #
        !           250: if((($sshdid =~ /OpenSSH/) && ($sshdvernum < 299)) ||
        !           251:    (($sshdid =~ /SunSSH/)  && ($sshdvernum < 100))) {
        !           252:     logmsg 'SCP and SFTP tests require OpenSSH 2.9.9 or later';
        !           253:     exit 1;
        !           254: }
        !           255: 
        !           256: 
        !           257: #***************************************************************************
        !           258: # Find out sftp server plugin canonical file name
        !           259: #
        !           260: my $sftpsrv = find_sftpsrv();
        !           261: if(!$sftpsrv) {
        !           262:     logmsg "cannot find $sftpsrvexe";
        !           263:     exit 1;
        !           264: }
        !           265: logmsg "sftp server plugin found $sftpsrv" if($verbose);
        !           266: 
        !           267: 
        !           268: #***************************************************************************
        !           269: # Find out sftp client canonical file name
        !           270: #
        !           271: my $sftp = find_sftp();
        !           272: if(!$sftp) {
        !           273:     logmsg "cannot find $sftpexe";
        !           274:     exit 1;
        !           275: }
        !           276: logmsg "sftp client found $sftp" if($verbose);
        !           277: 
        !           278: 
        !           279: #***************************************************************************
        !           280: # Find out ssh keygen canonical file name
        !           281: #
        !           282: my $sshkeygen = find_sshkeygen();
        !           283: if(!$sshkeygen) {
        !           284:     logmsg "cannot find $sshkeygenexe";
        !           285:     exit 1;
        !           286: }
        !           287: logmsg "ssh keygen found $sshkeygen" if($verbose);
        !           288: 
        !           289: 
        !           290: #***************************************************************************
        !           291: # Find out ssh client canonical file name
        !           292: #
        !           293: my $ssh = find_ssh();
        !           294: if(!$ssh) {
        !           295:     logmsg "cannot find $sshexe";
        !           296:     exit 1;
        !           297: }
        !           298: 
        !           299: 
        !           300: #***************************************************************************
        !           301: # Find out ssh client version info
        !           302: #
        !           303: my ($sshid, $sshvernum, $sshverstr, $ssherror) = sshversioninfo($ssh);
        !           304: if(!$sshid) {
        !           305:     # Not an OpenSSH or SunSSH ssh client
        !           306:     logmsg $ssherror if($verbose);
        !           307:     logmsg 'SCP and SFTP tests require OpenSSH 2.9.9 or later';
        !           308:     exit 1;
        !           309: }
        !           310: logmsg "ssh client found $ssh is $sshverstr" if($verbose);
        !           311: 
        !           312: 
        !           313: #***************************************************************************
        !           314: #  ssh client command line options we might use and version support
        !           315: #
        !           316: #  -D:  dynamic app port forwarding  : OpenSSH 2.9.9 and later
        !           317: #  -F:  ssh config file              : OpenSSH 2.9.9 and later
        !           318: #  -N:  no shell/command             : OpenSSH 2.1.0 and later
        !           319: #  -p:  connection port              : OpenSSH 1.2.1 and later
        !           320: #  -v:  verbose messages             : OpenSSH 1.2.1 and later
        !           321: # -vv:  increase verbosity           : OpenSSH 2.3.0 and later
        !           322: #  -V:  ssh version info             : OpenSSH 1.2.1 and later
        !           323: #
        !           324: #  -D:  dynamic app port forwarding  : SunSSH 1.0.0 and later
        !           325: #  -F:  ssh config file              : SunSSH 1.0.0 and later
        !           326: #  -N:  no shell/command             : SunSSH 1.0.0 and later
        !           327: #  -p:  connection port              : SunSSH 1.0.0 and later
        !           328: #  -v:  verbose messages             : SunSSH 1.0.0 and later
        !           329: # -vv:  increase verbosity           : SunSSH 1.0.0 and later
        !           330: #  -V:  ssh version info             : SunSSH 1.0.0 and later
        !           331: 
        !           332: 
        !           333: #***************************************************************************
        !           334: # Verify minimum ssh client version
        !           335: #
        !           336: if((($sshid =~ /OpenSSH/) && ($sshvernum < 299)) ||
        !           337:    (($sshid =~ /SunSSH/)  && ($sshvernum < 100))) {
        !           338:     logmsg 'SCP and SFTP tests require OpenSSH 2.9.9 or later';
        !           339:     exit 1;
        !           340: }
        !           341: 
        !           342: 
        !           343: #***************************************************************************
        !           344: #  ssh keygen command line options we actually use and version support
        !           345: #
        !           346: #  -C:  identity comment : OpenSSH 1.2.1 and later
        !           347: #  -f:  key filename     : OpenSSH 1.2.1 and later
        !           348: #  -N:  new passphrase   : OpenSSH 1.2.1 and later
        !           349: #  -q:  quiet keygen     : OpenSSH 1.2.1 and later
        !           350: #  -t:  key type         : OpenSSH 2.5.0 and later
        !           351: #
        !           352: #  -C:  identity comment : SunSSH 1.0.0 and later
        !           353: #  -f:  key filename     : SunSSH 1.0.0 and later
        !           354: #  -N:  new passphrase   : SunSSH 1.0.0 and later
        !           355: #  -q:  quiet keygen     : SunSSH 1.0.0 and later
        !           356: #  -t:  key type         : SunSSH 1.0.0 and later
        !           357: 
        !           358: 
        !           359: #***************************************************************************
        !           360: # Generate host and client key files for curl's tests
        !           361: #
        !           362: if((! -e $hstprvkeyf) || (! -s $hstprvkeyf) ||
        !           363:    (! -e $hstpubkeyf) || (! -s $hstpubkeyf) ||
        !           364:    (! -e $hstpubmd5f) || (! -s $hstpubmd5f) ||
        !           365:    (! -e $cliprvkeyf) || (! -s $cliprvkeyf) ||
        !           366:    (! -e $clipubkeyf) || (! -s $clipubkeyf)) {
        !           367:     # Make sure all files are gone so ssh-keygen doesn't complain
        !           368:     unlink($hstprvkeyf, $hstpubkeyf, $hstpubmd5f, $cliprvkeyf, $clipubkeyf);
        !           369:     logmsg 'generating host keys...' if($verbose);
        !           370:     if(system "\"$sshkeygen\" -q -t rsa -f $hstprvkeyf -C 'curl test server' -N ''") {
        !           371:         logmsg 'Could not generate host key';
        !           372:         exit 1;
        !           373:     }
        !           374:     logmsg 'generating client keys...' if($verbose);
        !           375:     if(system "\"$sshkeygen\" -q -t rsa -f $cliprvkeyf -C 'curl test client' -N ''") {
        !           376:         logmsg 'Could not generate client key';
        !           377:         exit 1;
        !           378:     }
        !           379:     # Make sure that permissions are restricted so openssh doesn't complain
        !           380:     system "chmod 600 $hstprvkeyf";
        !           381:     system "chmod 600 $cliprvkeyf";
        !           382:     # Save md5 hash of public host key
        !           383:     open(RSAKEYFILE, "<$hstpubkeyf");
        !           384:     my @rsahostkey = do { local $/ = ' '; <RSAKEYFILE> };
        !           385:     close(RSAKEYFILE);
        !           386:     if(!$rsahostkey[1]) {
        !           387:         logmsg 'Failed parsing base64 encoded RSA host key';
        !           388:         exit 1;
        !           389:     }
        !           390:     open(PUBMD5FILE, ">$hstpubmd5f");
        !           391:     print PUBMD5FILE md5_hex(decode_base64($rsahostkey[1]));
        !           392:     close(PUBMD5FILE);
        !           393:     if((! -e $hstpubmd5f) || (! -s $hstpubmd5f)) {
        !           394:         logmsg 'Failed writing md5 hash of RSA host key';
        !           395:         exit 1;
        !           396:     }
        !           397: }
        !           398: 
        !           399: 
        !           400: #***************************************************************************
        !           401: # Convert paths for curl's tests running on Windows with Cygwin/Msys OpenSSH
        !           402: #
        !           403: my $clipubkeyf_config = abs_path("$path/$clipubkeyf");
        !           404: my $hstprvkeyf_config = abs_path("$path/$hstprvkeyf");
        !           405: my $pidfile_config = $pidfile;
        !           406: my $sftpsrv_config = $sftpsrv;
        !           407: 
        !           408: if (pathhelp::os_is_win()) {
        !           409:     # Ensure to use MinGW/Cygwin paths
        !           410:     $clipubkeyf_config = pathhelp::build_sys_abs_path($clipubkeyf_config);
        !           411:     $hstprvkeyf_config = pathhelp::build_sys_abs_path($hstprvkeyf_config);
        !           412:     $pidfile_config = pathhelp::build_sys_abs_path($pidfile_config);
        !           413:     $sftpsrv_config = "internal-sftp";
        !           414: }
        !           415: if ($sshdid =~ /OpenSSH-Windows/) {
        !           416:     # Ensure to use native Windows paths with OpenSSH for Windows
        !           417:     $clipubkeyf_config = pathhelp::sys_native_abs_path($clipubkeyf);
        !           418:     $hstprvkeyf_config = pathhelp::sys_native_abs_path($hstprvkeyf);
        !           419:     $pidfile_config = pathhelp::sys_native_abs_path($pidfile);
        !           420:     $sftpsrv_config = pathhelp::sys_native_abs_path($sftpsrv);
        !           421: 
        !           422:     $sshdconfig = pathhelp::sys_native_abs_path($sshdconfig);
        !           423:     $sshconfig = pathhelp::sys_native_abs_path($sshconfig);
        !           424:     $sftpconfig = pathhelp::sys_native_abs_path($sftpconfig);
        !           425: }
        !           426: 
        !           427: #***************************************************************************
        !           428: #  ssh daemon configuration file options we might use and version support
        !           429: #
        !           430: #  AFSTokenPassing                  : OpenSSH 1.2.1 and later [1]
        !           431: #  AcceptEnv                        : OpenSSH 3.9.0 and later
        !           432: #  AddressFamily                    : OpenSSH 4.0.0 and later
        !           433: #  AllowGroups                      : OpenSSH 1.2.1 and later
        !           434: #  AllowTcpForwarding               : OpenSSH 2.3.0 and later
        !           435: #  AllowUsers                       : OpenSSH 1.2.1 and later
        !           436: #  AuthorizedKeysFile               : OpenSSH 2.9.9 and later
        !           437: #  AuthorizedKeysFile2              : OpenSSH 2.9.9 and later
        !           438: #  Banner                           : OpenSSH 2.5.0 and later
        !           439: #  ChallengeResponseAuthentication  : OpenSSH 2.5.0 and later
        !           440: #  Ciphers                          : OpenSSH 2.1.0 and later [3]
        !           441: #  ClientAliveCountMax              : OpenSSH 2.9.0 and later
        !           442: #  ClientAliveInterval              : OpenSSH 2.9.0 and later
        !           443: #  Compression                      : OpenSSH 3.3.0 and later
        !           444: #  DenyGroups                       : OpenSSH 1.2.1 and later
        !           445: #  DenyUsers                        : OpenSSH 1.2.1 and later
        !           446: #  ForceCommand                     : OpenSSH 4.4.0 and later [3]
        !           447: #  GatewayPorts                     : OpenSSH 2.1.0 and later
        !           448: #  GSSAPIAuthentication             : OpenSSH 3.7.0 and later [1]
        !           449: #  GSSAPICleanupCredentials         : OpenSSH 3.8.0 and later [1]
        !           450: #  GSSAPIKeyExchange                :  SunSSH 1.0.0 and later [1]
        !           451: #  GSSAPIStoreDelegatedCredentials  :  SunSSH 1.0.0 and later [1]
        !           452: #  GSSCleanupCreds                  :  SunSSH 1.0.0 and later [1]
        !           453: #  GSSUseSessionCredCache           :  SunSSH 1.0.0 and later [1]
        !           454: #  HostbasedAuthentication          : OpenSSH 2.9.0 and later
        !           455: #  HostbasedUsesNameFromPacketOnly  : OpenSSH 2.9.0 and later
        !           456: #  HostKey                          : OpenSSH 1.2.1 and later
        !           457: #  IgnoreRhosts                     : OpenSSH 1.2.1 and later
        !           458: #  IgnoreUserKnownHosts             : OpenSSH 1.2.1 and later
        !           459: #  KbdInteractiveAuthentication     : OpenSSH 2.3.0 and later
        !           460: #  KeepAlive                        : OpenSSH 1.2.1 and later
        !           461: #  KerberosAuthentication           : OpenSSH 1.2.1 and later [1]
        !           462: #  KerberosGetAFSToken              : OpenSSH 3.8.0 and later [1]
        !           463: #  KerberosOrLocalPasswd            : OpenSSH 1.2.1 and later [1]
        !           464: #  KerberosTgtPassing               : OpenSSH 1.2.1 and later [1]
        !           465: #  KerberosTicketCleanup            : OpenSSH 1.2.1 and later [1]
        !           466: #  KeyRegenerationInterval          : OpenSSH 1.2.1 and later
        !           467: #  ListenAddress                    : OpenSSH 1.2.1 and later
        !           468: #  LoginGraceTime                   : OpenSSH 1.2.1 and later
        !           469: #  LogLevel                         : OpenSSH 1.2.1 and later
        !           470: #  LookupClientHostnames            :  SunSSH 1.0.0 and later
        !           471: #  MACs                             : OpenSSH 2.5.0 and later [3]
        !           472: #  Match                            : OpenSSH 4.4.0 and later [3]
        !           473: #  MaxAuthTries                     : OpenSSH 3.9.0 and later
        !           474: #  MaxStartups                      : OpenSSH 2.2.0 and later
        !           475: #  PAMAuthenticationViaKbdInt       : OpenSSH 2.9.0 and later [2]
        !           476: #  PasswordAuthentication           : OpenSSH 1.2.1 and later
        !           477: #  PermitEmptyPasswords             : OpenSSH 1.2.1 and later
        !           478: #  PermitOpen                       : OpenSSH 4.4.0 and later [3]
        !           479: #  PermitRootLogin                  : OpenSSH 1.2.1 and later
        !           480: #  PermitTunnel                     : OpenSSH 4.3.0 and later
        !           481: #  PermitUserEnvironment            : OpenSSH 3.5.0 and later
        !           482: #  PidFile                          : OpenSSH 2.1.0 and later
        !           483: #  Port                             : OpenSSH 1.2.1 and later
        !           484: #  PrintLastLog                     : OpenSSH 2.9.0 and later
        !           485: #  PrintMotd                        : OpenSSH 1.2.1 and later
        !           486: #  Protocol                         : OpenSSH 2.1.0 and later
        !           487: #  PubkeyAuthentication             : OpenSSH 2.5.0 and later
        !           488: #  RhostsAuthentication             : OpenSSH 1.2.1 and later
        !           489: #  RhostsRSAAuthentication          : OpenSSH 1.2.1 and later
        !           490: #  RSAAuthentication                : OpenSSH 1.2.1 and later
        !           491: #  ServerKeyBits                    : OpenSSH 1.2.1 and later
        !           492: #  SkeyAuthentication               : OpenSSH 1.2.1 and later [1]
        !           493: #  StrictModes                      : OpenSSH 1.2.1 and later
        !           494: #  Subsystem                        : OpenSSH 2.2.0 and later
        !           495: #  SyslogFacility                   : OpenSSH 1.2.1 and later
        !           496: #  TCPKeepAlive                     : OpenSSH 3.8.0 and later
        !           497: #  UseDNS                           : OpenSSH 3.7.0 and later
        !           498: #  UseLogin                         : OpenSSH 1.2.1 and later
        !           499: #  UsePAM                           : OpenSSH 3.7.0 and later [1][2]
        !           500: #  UsePrivilegeSeparation           : OpenSSH 3.2.2 and later
        !           501: #  VerifyReverseMapping             : OpenSSH 3.1.0 and later
        !           502: #  X11DisplayOffset                 : OpenSSH 1.2.1 and later [3]
        !           503: #  X11Forwarding                    : OpenSSH 1.2.1 and later
        !           504: #  X11UseLocalhost                  : OpenSSH 3.1.0 and later
        !           505: #  XAuthLocation                    : OpenSSH 2.1.1 and later [3]
        !           506: #
        !           507: #  [1] Option only available if activated at compile time
        !           508: #  [2] Option specific for portable versions
        !           509: #  [3] Option not used in our ssh server config file
        !           510: 
        !           511: 
        !           512: #***************************************************************************
        !           513: # Initialize sshd config with options actually supported in OpenSSH 2.9.9
        !           514: #
        !           515: logmsg 'generating ssh server config file...' if($verbose);
        !           516: @cfgarr = ();
        !           517: push @cfgarr, '# This is a generated file.  Do not edit.';
        !           518: push @cfgarr, "# $sshdverstr sshd configuration file for curl testing";
        !           519: push @cfgarr, '#';
        !           520: 
        !           521: # AllowUsers and DenyUsers options should use lowercase on Windows
        !           522: # and do not support quotes around values for some unknown reason.
        !           523: if ($sshdid =~ /OpenSSH-Windows/) {
        !           524:     my $username_lc = lc $username;
        !           525:     push @cfgarr, "DenyUsers !$username_lc";
        !           526:     push @cfgarr, "AllowUsers $username_lc";
        !           527: } else {
        !           528:     push @cfgarr, "DenyUsers !$username";
        !           529:     push @cfgarr, "AllowUsers $username";
        !           530: }
        !           531: 
        !           532: push @cfgarr, 'DenyGroups';
        !           533: push @cfgarr, 'AllowGroups';
        !           534: push @cfgarr, '#';
        !           535: push @cfgarr, "AuthorizedKeysFile $clipubkeyf_config";
        !           536: push @cfgarr, "AuthorizedKeysFile2 $clipubkeyf_config";
        !           537: push @cfgarr, "HostKey $hstprvkeyf_config";
        !           538: if ($sshdid !~ /OpenSSH-Windows/) {
        !           539:     push @cfgarr, "PidFile $pidfile_config";
        !           540: }
        !           541: push @cfgarr, '#';
        !           542: push @cfgarr, "Port $port";
        !           543: push @cfgarr, "ListenAddress $listenaddr";
        !           544: push @cfgarr, 'Protocol 2';
        !           545: push @cfgarr, '#';
        !           546: push @cfgarr, 'AllowTcpForwarding yes';
        !           547: push @cfgarr, 'Banner none';
        !           548: push @cfgarr, 'ChallengeResponseAuthentication no';
        !           549: push @cfgarr, 'ClientAliveCountMax 3';
        !           550: push @cfgarr, 'ClientAliveInterval 0';
        !           551: push @cfgarr, 'GatewayPorts no';
        !           552: push @cfgarr, 'HostbasedAuthentication no';
        !           553: push @cfgarr, 'HostbasedUsesNameFromPacketOnly no';
        !           554: push @cfgarr, 'IgnoreRhosts yes';
        !           555: push @cfgarr, 'IgnoreUserKnownHosts yes';
        !           556: push @cfgarr, 'KeyRegenerationInterval 0';
        !           557: push @cfgarr, 'LoginGraceTime 30';
        !           558: push @cfgarr, "LogLevel $loglevel";
        !           559: push @cfgarr, 'MaxStartups 5';
        !           560: push @cfgarr, 'PasswordAuthentication no';
        !           561: push @cfgarr, 'PermitEmptyPasswords no';
        !           562: push @cfgarr, 'PermitRootLogin no';
        !           563: push @cfgarr, 'PrintLastLog no';
        !           564: push @cfgarr, 'PrintMotd no';
        !           565: push @cfgarr, 'PubkeyAuthentication yes';
        !           566: push @cfgarr, 'RhostsRSAAuthentication no';
        !           567: push @cfgarr, 'RSAAuthentication no';
        !           568: push @cfgarr, 'ServerKeyBits 768';
        !           569: push @cfgarr, 'StrictModes no';
        !           570: push @cfgarr, "Subsystem sftp \"$sftpsrv_config\"";
        !           571: push @cfgarr, 'SyslogFacility AUTH';
        !           572: push @cfgarr, 'UseLogin no';
        !           573: push @cfgarr, 'X11Forwarding no';
        !           574: push @cfgarr, '#';
        !           575: 
        !           576: 
        !           577: #***************************************************************************
        !           578: # Write out initial sshd configuration file for curl's tests
        !           579: #
        !           580: $error = dump_array($sshdconfig, @cfgarr);
        !           581: if($error) {
        !           582:     logmsg $error;
        !           583:     exit 1;
        !           584: }
        !           585: 
        !           586: 
        !           587: #***************************************************************************
        !           588: # Verifies at run time if sshd supports a given configuration file option
        !           589: #
        !           590: sub sshd_supports_opt {
        !           591:     my ($option, $value) = @_;
        !           592:     my $err;
        !           593:     #
        !           594:     if((($sshdid =~ /OpenSSH/) && ($sshdvernum >= 310)) ||
        !           595:         ($sshdid =~ /SunSSH/)) {
        !           596:         # ssh daemon supports command line options -t -f and -o
        !           597:         $err = grep /((Unsupported)|(Bad configuration)|(Deprecated)) option.*$option/,
        !           598:                     qx("$sshd" -t -f $sshdconfig -o "$option=$value" 2>&1);
        !           599:         return !$err;
        !           600:     }
        !           601:     if(($sshdid =~ /OpenSSH/) && ($sshdvernum >= 299)) {
        !           602:         # ssh daemon supports command line options -t and -f
        !           603:         $err = dump_array($sshdconfig, (@cfgarr, "$option $value"));
        !           604:         if($err) {
        !           605:             logmsg $err;
        !           606:             return 0;
        !           607:         }
        !           608:         $err = grep /((Unsupported)|(Bad configuration)|(Deprecated)) option.*$option/,
        !           609:                     qx("$sshd" -t -f $sshdconfig 2>&1);
        !           610:         unlink $sshdconfig;
        !           611:         return !$err;
        !           612:     }
        !           613:     return 0;
        !           614: }
        !           615: 
        !           616: 
        !           617: #***************************************************************************
        !           618: # Kerberos Authentication support may have not been built into sshd
        !           619: #
        !           620: if(sshd_supports_opt('KerberosAuthentication','no')) {
        !           621:     push @cfgarr, 'KerberosAuthentication no';
        !           622: }
        !           623: if(sshd_supports_opt('KerberosGetAFSToken','no')) {
        !           624:     push @cfgarr, 'KerberosGetAFSToken no';
        !           625: }
        !           626: if(sshd_supports_opt('KerberosOrLocalPasswd','no')) {
        !           627:     push @cfgarr, 'KerberosOrLocalPasswd no';
        !           628: }
        !           629: if(sshd_supports_opt('KerberosTgtPassing','no')) {
        !           630:     push @cfgarr, 'KerberosTgtPassing no';
        !           631: }
        !           632: if(sshd_supports_opt('KerberosTicketCleanup','yes')) {
        !           633:     push @cfgarr, 'KerberosTicketCleanup yes';
        !           634: }
        !           635: 
        !           636: 
        !           637: #***************************************************************************
        !           638: # Andrew File System support may have not been built into sshd
        !           639: #
        !           640: if(sshd_supports_opt('AFSTokenPassing','no')) {
        !           641:     push @cfgarr, 'AFSTokenPassing no';
        !           642: }
        !           643: 
        !           644: 
        !           645: #***************************************************************************
        !           646: # S/Key authentication support may have not been built into sshd
        !           647: #
        !           648: if(sshd_supports_opt('SkeyAuthentication','no')) {
        !           649:     push @cfgarr, 'SkeyAuthentication no';
        !           650: }
        !           651: 
        !           652: 
        !           653: #***************************************************************************
        !           654: # GSSAPI Authentication support may have not been built into sshd
        !           655: #
        !           656: my $sshd_builtwith_GSSAPI;
        !           657: if(sshd_supports_opt('GSSAPIAuthentication','no')) {
        !           658:     push @cfgarr, 'GSSAPIAuthentication no';
        !           659:     $sshd_builtwith_GSSAPI = 1;
        !           660: }
        !           661: if(sshd_supports_opt('GSSAPICleanupCredentials','yes')) {
        !           662:     push @cfgarr, 'GSSAPICleanupCredentials yes';
        !           663: }
        !           664: if(sshd_supports_opt('GSSAPIKeyExchange','no')) {
        !           665:     push @cfgarr, 'GSSAPIKeyExchange no';
        !           666: }
        !           667: if(sshd_supports_opt('GSSAPIStoreDelegatedCredentials','no')) {
        !           668:     push @cfgarr, 'GSSAPIStoreDelegatedCredentials no';
        !           669: }
        !           670: if(sshd_supports_opt('GSSCleanupCreds','yes')) {
        !           671:     push @cfgarr, 'GSSCleanupCreds yes';
        !           672: }
        !           673: if(sshd_supports_opt('GSSUseSessionCredCache','no')) {
        !           674:     push @cfgarr, 'GSSUseSessionCredCache no';
        !           675: }
        !           676: push @cfgarr, '#';
        !           677: 
        !           678: 
        !           679: #***************************************************************************
        !           680: # Options that might be supported or not in sshd OpenSSH 2.9.9 and later
        !           681: #
        !           682: if(sshd_supports_opt('AcceptEnv','')) {
        !           683:     push @cfgarr, 'AcceptEnv';
        !           684: }
        !           685: if(sshd_supports_opt('AddressFamily','any')) {
        !           686:     # Address family must be specified before ListenAddress
        !           687:     splice @cfgarr, 14, 0, 'AddressFamily any';
        !           688: }
        !           689: if(sshd_supports_opt('Compression','no')) {
        !           690:     push @cfgarr, 'Compression no';
        !           691: }
        !           692: if(sshd_supports_opt('KbdInteractiveAuthentication','no')) {
        !           693:     push @cfgarr, 'KbdInteractiveAuthentication no';
        !           694: }
        !           695: if(sshd_supports_opt('KeepAlive','no')) {
        !           696:     push @cfgarr, 'KeepAlive no';
        !           697: }
        !           698: if(sshd_supports_opt('LookupClientHostnames','no')) {
        !           699:     push @cfgarr, 'LookupClientHostnames no';
        !           700: }
        !           701: if(sshd_supports_opt('MaxAuthTries','10')) {
        !           702:     push @cfgarr, 'MaxAuthTries 10';
        !           703: }
        !           704: if(sshd_supports_opt('PAMAuthenticationViaKbdInt','no')) {
        !           705:     push @cfgarr, 'PAMAuthenticationViaKbdInt no';
        !           706: }
        !           707: if(sshd_supports_opt('PermitTunnel','no')) {
        !           708:     push @cfgarr, 'PermitTunnel no';
        !           709: }
        !           710: if(sshd_supports_opt('PermitUserEnvironment','no')) {
        !           711:     push @cfgarr, 'PermitUserEnvironment no';
        !           712: }
        !           713: if(sshd_supports_opt('RhostsAuthentication','no')) {
        !           714:     push @cfgarr, 'RhostsAuthentication no';
        !           715: }
        !           716: if(sshd_supports_opt('TCPKeepAlive','no')) {
        !           717:     push @cfgarr, 'TCPKeepAlive no';
        !           718: }
        !           719: if(sshd_supports_opt('UseDNS','no')) {
        !           720:     push @cfgarr, 'UseDNS no';
        !           721: }
        !           722: if(sshd_supports_opt('UsePAM','no')) {
        !           723:     push @cfgarr, 'UsePAM no';
        !           724: }
        !           725: 
        !           726: if($sshdid =~ /OpenSSH/) {
        !           727:     # http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=6492415
        !           728:     if(sshd_supports_opt('UsePrivilegeSeparation','no')) {
        !           729:         push @cfgarr, 'UsePrivilegeSeparation no';
        !           730:     }
        !           731: }
        !           732: 
        !           733: if(sshd_supports_opt('VerifyReverseMapping','no')) {
        !           734:     push @cfgarr, 'VerifyReverseMapping no';
        !           735: }
        !           736: if(sshd_supports_opt('X11UseLocalhost','yes')) {
        !           737:     push @cfgarr, 'X11UseLocalhost yes';
        !           738: }
        !           739: push @cfgarr, '#';
        !           740: 
        !           741: 
        !           742: #***************************************************************************
        !           743: # Write out resulting sshd configuration file for curl's tests
        !           744: #
        !           745: $error = dump_array($sshdconfig, @cfgarr);
        !           746: if($error) {
        !           747:     logmsg $error;
        !           748:     exit 1;
        !           749: }
        !           750: 
        !           751: 
        !           752: #***************************************************************************
        !           753: # Verify that sshd actually supports our generated configuration file
        !           754: #
        !           755: if(system "\"$sshd\" -t -f $sshdconfig > $sshdlog 2>&1") {
        !           756:     logmsg "sshd configuration file $sshdconfig failed verification";
        !           757:     display_sshdlog();
        !           758:     display_sshdconfig();
        !           759:     exit 1;
        !           760: }
        !           761: 
        !           762: 
        !           763: #***************************************************************************
        !           764: # Generate ssh client host key database file for curl's tests
        !           765: #
        !           766: if((! -e $knownhosts) || (! -s $knownhosts)) {
        !           767:     logmsg 'generating ssh client known hosts file...' if($verbose);
        !           768:     unlink($knownhosts);
        !           769:     if(open(RSAKEYFILE, "<$hstpubkeyf")) {
        !           770:         my @rsahostkey = do { local $/ = ' '; <RSAKEYFILE> };
        !           771:         if(close(RSAKEYFILE)) {
        !           772:             if(open(KNOWNHOSTS, ">$knownhosts")) {
        !           773:                 print KNOWNHOSTS "$listenaddr ssh-rsa $rsahostkey[1]\n";
        !           774:                 if(!close(KNOWNHOSTS)) {
        !           775:                     $error = "Error: cannot close file $knownhosts";
        !           776:                 }
        !           777:             }
        !           778:             else {
        !           779:                 $error = "Error: cannot write file $knownhosts";
        !           780:             }
        !           781:         }
        !           782:         else {
        !           783:             $error = "Error: cannot close file $hstpubkeyf";
        !           784:         }
        !           785:     }
        !           786:     else {
        !           787:         $error = "Error: cannot read file $hstpubkeyf";
        !           788:     }
        !           789:     if($error) {
        !           790:         logmsg $error;
        !           791:         exit 1;
        !           792:     }
        !           793: }
        !           794: 
        !           795: 
        !           796: #***************************************************************************
        !           797: # Convert paths for curl's tests running on Windows using Cygwin OpenSSH
        !           798: #
        !           799: my $identity_config = abs_path("$path/$identity");
        !           800: my $knownhosts_config = abs_path("$path/$knownhosts");
        !           801: 
        !           802: if (pathhelp::os_is_win()) {
        !           803:     # Ensure to use MinGW/Cygwin paths
        !           804:     $identity_config = pathhelp::build_sys_abs_path($identity_config);
        !           805:     $knownhosts_config = pathhelp::build_sys_abs_path($knownhosts_config);
        !           806: }
        !           807: if ($sshdid =~ /OpenSSH-Windows/) {
        !           808:     # Ensure to use native Windows paths with OpenSSH for Windows
        !           809:     $identity_config = pathhelp::sys_native_abs_path($identity);
        !           810:     $knownhosts_config = pathhelp::sys_native_abs_path($knownhosts);
        !           811: }
        !           812: 
        !           813: #***************************************************************************
        !           814: #  ssh client configuration file options we might use and version support
        !           815: #
        !           816: #  AddressFamily                     : OpenSSH 3.7.0 and later
        !           817: #  BatchMode                         : OpenSSH 1.2.1 and later
        !           818: #  BindAddress                       : OpenSSH 2.9.9 and later
        !           819: #  ChallengeResponseAuthentication   : OpenSSH 2.5.0 and later
        !           820: #  CheckHostIP                       : OpenSSH 1.2.1 and later
        !           821: #  Cipher                            : OpenSSH 1.2.1 and later [3]
        !           822: #  Ciphers                           : OpenSSH 2.1.0 and later [3]
        !           823: #  ClearAllForwardings               : OpenSSH 2.9.9 and later
        !           824: #  Compression                       : OpenSSH 1.2.1 and later
        !           825: #  CompressionLevel                  : OpenSSH 1.2.1 and later [3]
        !           826: #  ConnectionAttempts                : OpenSSH 1.2.1 and later
        !           827: #  ConnectTimeout                    : OpenSSH 3.7.0 and later
        !           828: #  ControlMaster                     : OpenSSH 3.9.0 and later
        !           829: #  ControlPath                       : OpenSSH 3.9.0 and later
        !           830: #  DisableBanner                     :  SunSSH 1.2.0 and later
        !           831: #  DynamicForward                    : OpenSSH 2.9.0 and later
        !           832: #  EnableSSHKeysign                  : OpenSSH 3.6.0 and later
        !           833: #  EscapeChar                        : OpenSSH 1.2.1 and later [3]
        !           834: #  ExitOnForwardFailure              : OpenSSH 4.4.0 and later
        !           835: #  ForwardAgent                      : OpenSSH 1.2.1 and later
        !           836: #  ForwardX11                        : OpenSSH 1.2.1 and later
        !           837: #  ForwardX11Trusted                 : OpenSSH 3.8.0 and later
        !           838: #  GatewayPorts                      : OpenSSH 1.2.1 and later
        !           839: #  GlobalKnownHostsFile              : OpenSSH 1.2.1 and later
        !           840: #  GSSAPIAuthentication              : OpenSSH 3.7.0 and later [1]
        !           841: #  GSSAPIDelegateCredentials         : OpenSSH 3.7.0 and later [1]
        !           842: #  HashKnownHosts                    : OpenSSH 4.0.0 and later
        !           843: #  Host                              : OpenSSH 1.2.1 and later
        !           844: #  HostbasedAuthentication           : OpenSSH 2.9.0 and later
        !           845: #  HostKeyAlgorithms                 : OpenSSH 2.9.0 and later [3]
        !           846: #  HostKeyAlias                      : OpenSSH 2.5.0 and later [3]
        !           847: #  HostName                          : OpenSSH 1.2.1 and later
        !           848: #  IdentitiesOnly                    : OpenSSH 3.9.0 and later
        !           849: #  IdentityFile                      : OpenSSH 1.2.1 and later
        !           850: #  IgnoreIfUnknown                   :  SunSSH 1.2.0 and later
        !           851: #  KeepAlive                         : OpenSSH 1.2.1 and later
        !           852: #  KbdInteractiveAuthentication      : OpenSSH 2.3.0 and later
        !           853: #  KbdInteractiveDevices             : OpenSSH 2.3.0 and later [3]
        !           854: #  LocalCommand                      : OpenSSH 4.3.0 and later [3]
        !           855: #  LocalForward                      : OpenSSH 1.2.1 and later [3]
        !           856: #  LogLevel                          : OpenSSH 1.2.1 and later
        !           857: #  MACs                              : OpenSSH 2.5.0 and later [3]
        !           858: #  NoHostAuthenticationForLocalhost  : OpenSSH 3.0.0 and later
        !           859: #  NumberOfPasswordPrompts           : OpenSSH 1.2.1 and later
        !           860: #  PasswordAuthentication            : OpenSSH 1.2.1 and later
        !           861: #  PermitLocalCommand                : OpenSSH 4.3.0 and later
        !           862: #  Port                              : OpenSSH 1.2.1 and later
        !           863: #  PreferredAuthentications          : OpenSSH 2.5.2 and later
        !           864: #  Protocol                          : OpenSSH 2.1.0 and later
        !           865: #  ProxyCommand                      : OpenSSH 1.2.1 and later [3]
        !           866: #  PubkeyAuthentication              : OpenSSH 2.5.0 and later
        !           867: #  RekeyLimit                        : OpenSSH 3.7.0 and later
        !           868: #  RemoteForward                     : OpenSSH 1.2.1 and later [3]
        !           869: #  RhostsRSAAuthentication           : OpenSSH 1.2.1 and later
        !           870: #  RSAAuthentication                 : OpenSSH 1.2.1 and later
        !           871: #  SendEnv                           : OpenSSH 3.9.0 and later
        !           872: #  ServerAliveCountMax               : OpenSSH 3.8.0 and later
        !           873: #  ServerAliveInterval               : OpenSSH 3.8.0 and later
        !           874: #  SmartcardDevice                   : OpenSSH 2.9.9 and later [1][3]
        !           875: #  StrictHostKeyChecking             : OpenSSH 1.2.1 and later
        !           876: #  TCPKeepAlive                      : OpenSSH 3.8.0 and later
        !           877: #  Tunnel                            : OpenSSH 4.3.0 and later
        !           878: #  TunnelDevice                      : OpenSSH 4.3.0 and later [3]
        !           879: #  UsePAM                            : OpenSSH 3.7.0 and later [1][2][3]
        !           880: #  UsePrivilegedPort                 : OpenSSH 1.2.1 and later
        !           881: #  User                              : OpenSSH 1.2.1 and later
        !           882: #  UserKnownHostsFile                : OpenSSH 1.2.1 and later
        !           883: #  VerifyHostKeyDNS                  : OpenSSH 3.8.0 and later
        !           884: #  XAuthLocation                     : OpenSSH 2.1.1 and later [3]
        !           885: #
        !           886: #  [1] Option only available if activated at compile time
        !           887: #  [2] Option specific for portable versions
        !           888: #  [3] Option not used in our ssh client config file
        !           889: 
        !           890: 
        !           891: #***************************************************************************
        !           892: # Initialize ssh config with options actually supported in OpenSSH 2.9.9
        !           893: #
        !           894: logmsg 'generating ssh client config file...' if($verbose);
        !           895: @cfgarr = ();
        !           896: push @cfgarr, '# This is a generated file.  Do not edit.';
        !           897: push @cfgarr, "# $sshverstr ssh client configuration file for curl testing";
        !           898: push @cfgarr, '#';
        !           899: push @cfgarr, 'Host *';
        !           900: push @cfgarr, '#';
        !           901: push @cfgarr, "Port $port";
        !           902: push @cfgarr, "HostName $listenaddr";
        !           903: push @cfgarr, "User $username";
        !           904: push @cfgarr, 'Protocol 2';
        !           905: push @cfgarr, '#';
        !           906: 
        !           907: # BindAddress option is not supported by OpenSSH for Windows
        !           908: if (!($sshdid =~ /OpenSSH-Windows/)) {
        !           909:     push @cfgarr, "BindAddress $listenaddr";
        !           910: }
        !           911: 
        !           912: push @cfgarr, '#';
        !           913: push @cfgarr, "IdentityFile $identity_config";
        !           914: push @cfgarr, "UserKnownHostsFile $knownhosts_config";
        !           915: push @cfgarr, '#';
        !           916: push @cfgarr, 'BatchMode yes';
        !           917: push @cfgarr, 'ChallengeResponseAuthentication no';
        !           918: push @cfgarr, 'CheckHostIP no';
        !           919: push @cfgarr, 'ClearAllForwardings no';
        !           920: push @cfgarr, 'Compression no';
        !           921: push @cfgarr, 'ConnectionAttempts 3';
        !           922: push @cfgarr, 'ForwardAgent no';
        !           923: push @cfgarr, 'ForwardX11 no';
        !           924: push @cfgarr, 'GatewayPorts no';
        !           925: push @cfgarr, 'GlobalKnownHostsFile /dev/null';
        !           926: push @cfgarr, 'HostbasedAuthentication no';
        !           927: push @cfgarr, 'KbdInteractiveAuthentication no';
        !           928: push @cfgarr, "LogLevel $loglevel";
        !           929: push @cfgarr, 'NumberOfPasswordPrompts 0';
        !           930: push @cfgarr, 'PasswordAuthentication no';
        !           931: push @cfgarr, 'PreferredAuthentications publickey';
        !           932: push @cfgarr, 'PubkeyAuthentication yes';
        !           933: 
        !           934: # RSA authentication options are not supported by OpenSSH for Windows
        !           935: if (!($sshdid =~ /OpenSSH-Windows/)) {
        !           936:     push @cfgarr, 'RhostsRSAAuthentication no';
        !           937:     push @cfgarr, 'RSAAuthentication no';
        !           938: }
        !           939: 
        !           940: # Disabled StrictHostKeyChecking since it makes the tests fail on my
        !           941: # OpenSSH_6.0p1 on Debian Linux / Daniel
        !           942: push @cfgarr, 'StrictHostKeyChecking no';
        !           943: push @cfgarr, 'UsePrivilegedPort no';
        !           944: push @cfgarr, '#';
        !           945: 
        !           946: 
        !           947: #***************************************************************************
        !           948: # Options supported in ssh client newer than OpenSSH 2.9.9
        !           949: #
        !           950: 
        !           951: if(($sshid =~ /OpenSSH/) && ($sshvernum >= 370)) {
        !           952:     push @cfgarr, 'AddressFamily any';
        !           953: }
        !           954: 
        !           955: if((($sshid =~ /OpenSSH/) && ($sshvernum >= 370)) ||
        !           956:    (($sshid =~ /SunSSH/) && ($sshvernum >= 120))) {
        !           957:     push @cfgarr, 'ConnectTimeout 30';
        !           958: }
        !           959: 
        !           960: if(($sshid =~ /OpenSSH/) && ($sshvernum >= 390)) {
        !           961:     push @cfgarr, 'ControlMaster no';
        !           962: }
        !           963: 
        !           964: if(($sshid =~ /OpenSSH/) && ($sshvernum >= 420)) {
        !           965:     push @cfgarr, 'ControlPath none';
        !           966: }
        !           967: 
        !           968: if(($sshid =~ /SunSSH/) && ($sshvernum >= 120)) {
        !           969:     push @cfgarr, 'DisableBanner yes';
        !           970: }
        !           971: 
        !           972: if(($sshid =~ /OpenSSH/) && ($sshvernum >= 360)) {
        !           973:     push @cfgarr, 'EnableSSHKeysign no';
        !           974: }
        !           975: 
        !           976: if(($sshid =~ /OpenSSH/) && ($sshvernum >= 440)) {
        !           977:     push @cfgarr, 'ExitOnForwardFailure yes';
        !           978: }
        !           979: 
        !           980: if((($sshid =~ /OpenSSH/) && ($sshvernum >= 380)) ||
        !           981:    (($sshid =~ /SunSSH/) && ($sshvernum >= 120))) {
        !           982:     push @cfgarr, 'ForwardX11Trusted no';
        !           983: }
        !           984: 
        !           985: if(($sshd_builtwith_GSSAPI) && ($sshdid eq $sshid) &&
        !           986:    ($sshdvernum == $sshvernum)) {
        !           987:     push @cfgarr, 'GSSAPIAuthentication no';
        !           988:     push @cfgarr, 'GSSAPIDelegateCredentials no';
        !           989:     if($sshid =~ /SunSSH/) {
        !           990:         push @cfgarr, 'GSSAPIKeyExchange no';
        !           991:     }
        !           992: }
        !           993: 
        !           994: if((($sshid =~ /OpenSSH/) && ($sshvernum >= 400)) ||
        !           995:    (($sshid =~ /SunSSH/) && ($sshvernum >= 120))) {
        !           996:     push @cfgarr, 'HashKnownHosts no';
        !           997: }
        !           998: 
        !           999: if(($sshid =~ /OpenSSH/) && ($sshvernum >= 390)) {
        !          1000:     push @cfgarr, 'IdentitiesOnly yes';
        !          1001: }
        !          1002: 
        !          1003: if(($sshid =~ /SunSSH/) && ($sshvernum >= 120)) {
        !          1004:     push @cfgarr, 'IgnoreIfUnknown no';
        !          1005: }
        !          1006: 
        !          1007: if((($sshid =~ /OpenSSH/) && ($sshvernum < 380)) ||
        !          1008:     ($sshid =~ /SunSSH/)) {
        !          1009:     push @cfgarr, 'KeepAlive no';
        !          1010: }
        !          1011: 
        !          1012: if((($sshid =~ /OpenSSH/) && ($sshvernum >= 300)) ||
        !          1013:     ($sshid =~ /SunSSH/)) {
        !          1014:     push @cfgarr, 'NoHostAuthenticationForLocalhost no';
        !          1015: }
        !          1016: 
        !          1017: if(($sshid =~ /OpenSSH/) && ($sshvernum >= 430)) {
        !          1018:     push @cfgarr, 'PermitLocalCommand no';
        !          1019: }
        !          1020: 
        !          1021: if((($sshid =~ /OpenSSH/) && ($sshvernum >= 370)) ||
        !          1022:    (($sshid =~ /SunSSH/) && ($sshvernum >= 120))) {
        !          1023:     push @cfgarr, 'RekeyLimit 1G';
        !          1024: }
        !          1025: 
        !          1026: if(($sshid =~ /OpenSSH/) && ($sshvernum >= 390)) {
        !          1027:     push @cfgarr, 'SendEnv';
        !          1028: }
        !          1029: 
        !          1030: if((($sshid =~ /OpenSSH/) && ($sshvernum >= 380)) ||
        !          1031:    (($sshid =~ /SunSSH/) && ($sshvernum >= 120))) {
        !          1032:     push @cfgarr, 'ServerAliveCountMax 3';
        !          1033:     push @cfgarr, 'ServerAliveInterval 0';
        !          1034: }
        !          1035: 
        !          1036: if(($sshid =~ /OpenSSH/) && ($sshvernum >= 380)) {
        !          1037:     push @cfgarr, 'TCPKeepAlive no';
        !          1038: }
        !          1039: 
        !          1040: if(($sshid =~ /OpenSSH/) && ($sshvernum >= 430)) {
        !          1041:     push @cfgarr, 'Tunnel no';
        !          1042: }
        !          1043: 
        !          1044: if(($sshid =~ /OpenSSH/) && ($sshvernum >= 380)) {
        !          1045:     push @cfgarr, 'VerifyHostKeyDNS no';
        !          1046: }
        !          1047: 
        !          1048: push @cfgarr, '#';
        !          1049: 
        !          1050: 
        !          1051: #***************************************************************************
        !          1052: # Write out resulting ssh client configuration file for curl's tests
        !          1053: #
        !          1054: $error = dump_array($sshconfig, @cfgarr);
        !          1055: if($error) {
        !          1056:     logmsg $error;
        !          1057:     exit 1;
        !          1058: }
        !          1059: 
        !          1060: 
        !          1061: #***************************************************************************
        !          1062: # Initialize client sftp config with options actually supported.
        !          1063: #
        !          1064: logmsg 'generating sftp client config file...' if($verbose);
        !          1065: splice @cfgarr, 1, 1, "# $sshverstr sftp client configuration file for curl testing";
        !          1066: #
        !          1067: for(my $i = scalar(@cfgarr) - 1; $i > 0; $i--) {
        !          1068:     if($cfgarr[$i] =~ /^DynamicForward/) {
        !          1069:         splice @cfgarr, $i, 1;
        !          1070:         next;
        !          1071:     }
        !          1072:     if($cfgarr[$i] =~ /^ClearAllForwardings/) {
        !          1073:         splice @cfgarr, $i, 1, "ClearAllForwardings yes";
        !          1074:         next;
        !          1075:     }
        !          1076: }
        !          1077: 
        !          1078: 
        !          1079: #***************************************************************************
        !          1080: # Write out resulting sftp client configuration file for curl's tests
        !          1081: #
        !          1082: $error = dump_array($sftpconfig, @cfgarr);
        !          1083: if($error) {
        !          1084:     logmsg $error;
        !          1085:     exit 1;
        !          1086: }
        !          1087: @cfgarr = ();
        !          1088: 
        !          1089: 
        !          1090: #***************************************************************************
        !          1091: # Generate client sftp commands batch file for sftp server verification
        !          1092: #
        !          1093: logmsg 'generating sftp client commands file...' if($verbose);
        !          1094: push @cfgarr, 'pwd';
        !          1095: push @cfgarr, 'quit';
        !          1096: $error = dump_array($sftpcmds, @cfgarr);
        !          1097: if($error) {
        !          1098:     logmsg $error;
        !          1099:     exit 1;
        !          1100: }
        !          1101: @cfgarr = ();
        !          1102: 
        !          1103: #***************************************************************************
        !          1104: # Prepare command line of ssh server daemon
        !          1105: #
        !          1106: my $cmd = "\"$sshd\" -e -D -f $sshdconfig > $sshdlog 2>&1";
        !          1107: logmsg "SCP/SFTP server listening on port $port" if($verbose);
        !          1108: logmsg "RUN: $cmd" if($verbose);
        !          1109: 
        !          1110: #***************************************************************************
        !          1111: # Start the ssh server daemon on Windows without forking it
        !          1112: #
        !          1113: if ($sshdid =~ /OpenSSH-Windows/) {
        !          1114:     # Fake pidfile for ssh server on Windows.
        !          1115:     if(open(OUT, ">$pidfile")) {
        !          1116:         print OUT $$ . "\n";
        !          1117:         close(OUT);
        !          1118:     }
        !          1119: 
        !          1120:     # Put an "exec" in front of the command so that the child process
        !          1121:     # keeps this child's process ID by being tied to the spawned shell.
        !          1122:     exec("exec $cmd") || die "Can't exec() $cmd: $!";
        !          1123:     # exec() will create a new process, but ties the existance of the
        !          1124:     # new process to the parent waiting perl.exe and sh.exe processes.
        !          1125: 
        !          1126:     # exec() should never return back here to this process. We protect
        !          1127:     # ourselves by calling die() just in case something goes really bad.
        !          1128:     die "error: exec() has returned";
        !          1129: }
        !          1130: 
        !          1131: #***************************************************************************
        !          1132: # Start the ssh server daemon without forking it
        !          1133: #
        !          1134: my $rc = system($cmd);
        !          1135: if($rc == -1) {
        !          1136:     logmsg "\"$sshd\" failed with: $!";
        !          1137: }
        !          1138: elsif($rc & 127) {
        !          1139:     logmsg sprintf("\"$sshd\" died with signal %d, and %s coredump",
        !          1140:                    ($rc & 127), ($rc & 128)?'a':'no');
        !          1141: }
        !          1142: elsif($verbose && ($rc >> 8)) {
        !          1143:     logmsg sprintf("\"$sshd\" exited with %d", $rc >> 8);
        !          1144: }
        !          1145: 
        !          1146: 
        !          1147: #***************************************************************************
        !          1148: # Clean up once the server has stopped
        !          1149: #
        !          1150: unlink($hstprvkeyf, $hstpubkeyf, $hstpubmd5f,
        !          1151:        $cliprvkeyf, $clipubkeyf, $knownhosts,
        !          1152:        $sshdconfig, $sshconfig, $sftpconfig);
        !          1153: 
        !          1154: exit 0;

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