File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / tests / sshserver.pl
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 10:01:16 2020 UTC (5 years ago) by misho
Branches: curl, MAIN
CVS tags: v7_70_0p4, HEAD
curl

    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>