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