2 #***************************************************************************
4 # Project ___| | | | _ \| |
6 # | (__| |_| | _ <| |___
7 # \___|\___/|_| \_\_____|
9 # Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
11 # This software is licensed as described in the file COPYING, which
12 # you should have received as part of this distribution. The terms
13 # are also available at http://curl.haxx.se/docs/copyright.html.
15 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
16 # copies of the Software, and permit persons to whom the Software is
17 # furnished to do so, under the terms of the COPYING file.
19 # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 # KIND, either express or implied.
22 # $Id: sshserver.pl,v 1.1.1.1 2008-09-23 16:32:06 hoffman Exp $
23 #***************************************************************************
25 # Starts sshd for use in the SCP, SFTP and SOCKS curl test harness tests.
26 # Also creates the ssh configuration files needed for these tests.
34 # -p SCP/SFTP server port
35 # -s SOCKS4/5 server port
41 #***************************************************************************
42 # Variables and subs imported from sshhelp module
79 #***************************************************************************
81 my $verbose = 0; # set to 1 for debugging
82 my $debugprotocol = 0; # set to 1 for protocol debugging
83 my $port = 8999; # our default SCP/SFTP server port
84 my $socksport = $port + 1; # our default SOCKS4/5 server port
85 my $listenaddr = '127.0.0.1'; # default address on which to listen
86 my $path = getcwd
(); # current working directory
87 my $username = $ENV{USER
}; # default user
93 #***************************************************************************
94 # Parse command line options
97 if($ARGV[0] eq '-v') {
100 elsif($ARGV[0] eq '-d') {
104 elsif($ARGV[0] eq '-u') {
105 $username = $ARGV[1];
108 elsif($ARGV[0] eq '-l') {
109 $listenaddr = $ARGV[1];
112 elsif($ARGV[0] eq '-p') {
113 if($ARGV[1] =~ /^(\d+)$/) {
118 elsif($ARGV[0] eq '-s') {
119 if($ARGV[1] =~ /^(\d+)$/) {
128 #***************************************************************************
129 # Logging level for ssh server and client
131 my $loglevel = $debugprotocol?
'DEBUG3':'DEBUG2';
134 #***************************************************************************
138 $error = 'Will not run ssh server without a user name';
140 elsif($username eq 'root') {
141 $error = 'Will not run ssh server as root to mitigate security risks';
149 #***************************************************************************
150 # Find out ssh daemon canonical file name
152 my $sshd = find_sshd
();
154 logmsg
"cannot find $sshdexe";
159 #***************************************************************************
160 # Find out ssh daemon version info
162 my ($sshdid, $sshdvernum, $sshdverstr, $sshderror) = sshversioninfo
($sshd);
164 # Not an OpenSSH or SunSSH ssh daemon
165 logmsg
$sshderror if($verbose);
166 logmsg
'SCP, SFTP and SOCKS tests require OpenSSH 2.9.9 or later';
169 logmsg
"ssh server found $sshd is $sshdverstr" if($verbose);
172 #***************************************************************************
173 # ssh daemon command line options we might use and version support
175 # -e: log stderr : OpenSSH 2.9.0 and later
176 # -f: sshd config file : OpenSSH 1.2.1 and later
177 # -D: no daemon forking : OpenSSH 2.5.0 and later
178 # -o: command-line option : OpenSSH 3.1.0 and later
179 # -t: test config file : OpenSSH 2.9.9 and later
180 # -?: sshd version info : OpenSSH 1.2.1 and later
182 # -e: log stderr : SunSSH 1.0.0 and later
183 # -f: sshd config file : SunSSH 1.0.0 and later
184 # -D: no daemon forking : SunSSH 1.0.0 and later
185 # -o: command-line option : SunSSH 1.0.0 and later
186 # -t: test config file : SunSSH 1.0.0 and later
187 # -?: sshd version info : SunSSH 1.0.0 and later
190 #***************************************************************************
191 # Verify minimum ssh daemon version
193 if((($sshdid =~ /OpenSSH/) && ($sshdvernum < 299)) ||
194 (($sshdid =~ /SunSSH/) && ($sshdvernum < 100))) {
195 logmsg
'SCP, SFTP and SOCKS tests require OpenSSH 2.9.9 or later';
200 #***************************************************************************
201 # Find out sftp server plugin canonical file name
203 my $sftpsrv = find_sftpsrv
();
205 logmsg
"cannot find $sftpsrvexe";
208 logmsg
"sftp server plugin found $sftpsrv" if($verbose);
211 #***************************************************************************
212 # Find out sftp client canonical file name
214 my $sftp = find_sftp
();
216 logmsg
"cannot find $sftpexe";
219 logmsg
"sftp client found $sftp" if($verbose);
222 #***************************************************************************
223 # Find out ssh keygen canonical file name
225 my $sshkeygen = find_sshkeygen
();
227 logmsg
"cannot find $sshkeygenexe";
230 logmsg
"ssh keygen found $sshkeygen" if($verbose);
233 #***************************************************************************
234 # Find out ssh client canonical file name
236 my $ssh = find_ssh
();
238 logmsg
"cannot find $sshexe";
243 #***************************************************************************
244 # Find out ssh client version info
246 my ($sshid, $sshvernum, $sshverstr, $ssherror) = sshversioninfo
($ssh);
248 # Not an OpenSSH or SunSSH ssh client
249 logmsg
$ssherror if($verbose);
250 logmsg
'SCP, SFTP and SOCKS tests require OpenSSH 2.9.9 or later';
253 logmsg
"ssh client found $ssh is $sshverstr" if($verbose);
256 #***************************************************************************
257 # ssh client command line options we might use and version support
259 # -D: dynamic app port forwarding : OpenSSH 2.9.9 and later
260 # -F: ssh config file : OpenSSH 2.9.9 and later
261 # -N: no shell/command : OpenSSH 2.1.0 and later
262 # -p: connection port : OpenSSH 1.2.1 and later
263 # -v: verbose messages : OpenSSH 1.2.1 and later
264 # -vv: increase verbosity : OpenSSH 2.3.0 and later
265 # -V: ssh version info : OpenSSH 1.2.1 and later
267 # -D: dynamic app port forwarding : SunSSH 1.0.0 and later
268 # -F: ssh config file : SunSSH 1.0.0 and later
269 # -N: no shell/command : SunSSH 1.0.0 and later
270 # -p: connection port : SunSSH 1.0.0 and later
271 # -v: verbose messages : SunSSH 1.0.0 and later
272 # -vv: increase verbosity : SunSSH 1.0.0 and later
273 # -V: ssh version info : SunSSH 1.0.0 and later
276 #***************************************************************************
277 # Verify minimum ssh client version
279 if((($sshid =~ /OpenSSH/) && ($sshvernum < 299)) ||
280 (($sshid =~ /SunSSH/) && ($sshvernum < 100))) {
281 logmsg
'SCP, SFTP and SOCKS tests require OpenSSH 2.9.9 or later';
286 #***************************************************************************
287 # ssh keygen command line options we actually use and version support
289 # -C: identity comment : OpenSSH 1.2.1 and later
290 # -f: key filename : OpenSSH 1.2.1 and later
291 # -N: new passphrase : OpenSSH 1.2.1 and later
292 # -q: quiet keygen : OpenSSH 1.2.1 and later
293 # -t: key type : OpenSSH 2.5.0 and later
295 # -C: identity comment : SunSSH 1.0.0 and later
296 # -f: key filename : SunSSH 1.0.0 and later
297 # -N: new passphrase : SunSSH 1.0.0 and later
298 # -q: quiet keygen : SunSSH 1.0.0 and later
299 # -t: key type : SunSSH 1.0.0 and later
302 #***************************************************************************
303 # Generate host and client key files for curl's tests
305 if((! -e
$hstprvkeyf) || (! -e
$hstpubkeyf) ||
306 (! -e
$cliprvkeyf) || (! -e
$clipubkeyf)) {
307 # Make sure all files are gone so ssh-keygen doesn't complain
308 unlink($hstprvkeyf, $hstpubkeyf, $cliprvkeyf, $clipubkeyf);
309 logmsg
'generating host keys...' if($verbose);
310 if(system "$sshkeygen -q -t dsa -f $hstprvkeyf -C 'curl test server' -N ''") {
311 logmsg
'Could not generate host key';
314 logmsg
'generating client keys...' if($verbose);
315 if(system "$sshkeygen -q -t dsa -f $cliprvkeyf -C 'curl test client' -N ''") {
316 logmsg
'Could not generate client key';
322 #***************************************************************************
323 # ssh daemon configuration file options we might use and version support
325 # AFSTokenPassing : OpenSSH 1.2.1 and later [1]
326 # AcceptEnv : OpenSSH 3.9.0 and later
327 # AddressFamily : OpenSSH 4.0.0 and later
328 # AllowGroups : OpenSSH 1.2.1 and later
329 # AllowTcpForwarding : OpenSSH 2.3.0 and later
330 # AllowUsers : OpenSSH 1.2.1 and later
331 # AuthorizedKeysFile : OpenSSH 2.9.9 and later
332 # AuthorizedKeysFile2 : OpenSSH 2.9.9 and later
333 # Banner : OpenSSH 2.5.0 and later
334 # ChallengeResponseAuthentication : OpenSSH 2.5.0 and later
335 # Ciphers : OpenSSH 2.1.0 and later [3]
336 # ClientAliveCountMax : OpenSSH 2.9.0 and later
337 # ClientAliveInterval : OpenSSH 2.9.0 and later
338 # Compression : OpenSSH 3.3.0 and later
339 # DenyGroups : OpenSSH 1.2.1 and later
340 # DenyUsers : OpenSSH 1.2.1 and later
341 # ForceCommand : OpenSSH 4.4.0 and later [3]
342 # GatewayPorts : OpenSSH 2.1.0 and later
343 # GSSAPIAuthentication : OpenSSH 3.7.0 and later [1]
344 # GSSAPICleanupCredentials : OpenSSH 3.8.0 and later [1]
345 # GSSAPIKeyExchange : SunSSH 1.0.0 and later [1]
346 # GSSAPIStoreDelegatedCredentials : SunSSH 1.0.0 and later [1]
347 # GSSCleanupCreds : SunSSH 1.0.0 and later [1]
348 # GSSUseSessionCredCache : SunSSH 1.0.0 and later [1]
349 # HostbasedAuthentication : OpenSSH 2.9.0 and later
350 # HostbasedUsesNameFromPacketOnly : OpenSSH 2.9.0 and later
351 # HostKey : OpenSSH 1.2.1 and later
352 # IgnoreRhosts : OpenSSH 1.2.1 and later
353 # IgnoreUserKnownHosts : OpenSSH 1.2.1 and later
354 # KbdInteractiveAuthentication : OpenSSH 2.3.0 and later
355 # KeepAlive : OpenSSH 1.2.1 and later
356 # KerberosAuthentication : OpenSSH 1.2.1 and later [1]
357 # KerberosGetAFSToken : OpenSSH 3.8.0 and later [1]
358 # KerberosOrLocalPasswd : OpenSSH 1.2.1 and later [1]
359 # KerberosTgtPassing : OpenSSH 1.2.1 and later [1]
360 # KerberosTicketCleanup : OpenSSH 1.2.1 and later [1]
361 # KeyRegenerationInterval : OpenSSH 1.2.1 and later
362 # ListenAddress : OpenSSH 1.2.1 and later
363 # LoginGraceTime : OpenSSH 1.2.1 and later
364 # LogLevel : OpenSSH 1.2.1 and later
365 # LookupClientHostnames : SunSSH 1.0.0 and later
366 # MACs : OpenSSH 2.5.0 and later [3]
367 # Match : OpenSSH 4.4.0 and later [3]
368 # MaxAuthTries : OpenSSH 3.9.0 and later
369 # MaxStartups : OpenSSH 2.2.0 and later
370 # PAMAuthenticationViaKbdInt : OpenSSH 2.9.0 and later [2]
371 # PasswordAuthentication : OpenSSH 1.2.1 and later
372 # PermitEmptyPasswords : OpenSSH 1.2.1 and later
373 # PermitOpen : OpenSSH 4.4.0 and later [3]
374 # PermitRootLogin : OpenSSH 1.2.1 and later
375 # PermitTunnel : OpenSSH 4.3.0 and later
376 # PermitUserEnvironment : OpenSSH 3.5.0 and later
377 # PidFile : OpenSSH 2.1.0 and later
378 # Port : OpenSSH 1.2.1 and later
379 # PrintLastLog : OpenSSH 2.9.0 and later
380 # PrintMotd : OpenSSH 1.2.1 and later
381 # Protocol : OpenSSH 2.1.0 and later
382 # PubkeyAuthentication : OpenSSH 2.5.0 and later
383 # RhostsAuthentication : OpenSSH 1.2.1 and later
384 # RhostsRSAAuthentication : OpenSSH 1.2.1 and later
385 # RSAAuthentication : OpenSSH 1.2.1 and later
386 # ServerKeyBits : OpenSSH 1.2.1 and later
387 # SkeyAuthentication : OpenSSH 1.2.1 and later [1]
388 # StrictModes : OpenSSH 1.2.1 and later
389 # Subsystem : OpenSSH 2.2.0 and later
390 # SyslogFacility : OpenSSH 1.2.1 and later
391 # TCPKeepAlive : OpenSSH 3.8.0 and later
392 # UseDNS : OpenSSH 3.7.0 and later
393 # UseLogin : OpenSSH 1.2.1 and later
394 # UsePAM : OpenSSH 3.7.0 and later [1][2]
395 # UsePrivilegeSeparation : OpenSSH 3.2.2 and later
396 # VerifyReverseMapping : OpenSSH 3.1.0 and later
397 # X11DisplayOffset : OpenSSH 1.2.1 and later [3]
398 # X11Forwarding : OpenSSH 1.2.1 and later
399 # X11UseLocalhost : OpenSSH 3.1.0 and later
400 # XAuthLocation : OpenSSH 2.1.1 and later [3]
402 # [1] Option only available if activated at compile time
403 # [2] Option specific for portable versions
404 # [3] Option not used in our ssh server config file
407 #***************************************************************************
408 # Initialize sshd config with options actually supported in OpenSSH 2.9.9
410 logmsg
'generating ssh server config file...' if($verbose);
412 push @cfgarr, '# This is a generated file. Do not edit.';
413 push @cfgarr, "# $sshdverstr sshd configuration file for curl testing";
415 push @cfgarr, "DenyUsers !$username";
416 push @cfgarr, "AllowUsers $username";
417 push @cfgarr, 'DenyGroups';
418 push @cfgarr, 'AllowGroups';
420 push @cfgarr, "AuthorizedKeysFile $path/$clipubkeyf";
421 push @cfgarr, "AuthorizedKeysFile2 $path/$clipubkeyf";
422 push @cfgarr, "HostKey $path/$hstprvkeyf";
423 push @cfgarr, "PidFile $path/.ssh.pid";
425 push @cfgarr, "Port $port";
426 push @cfgarr, "ListenAddress $listenaddr";
427 push @cfgarr, 'Protocol 2';
429 push @cfgarr, 'AllowTcpForwarding yes';
430 push @cfgarr, 'Banner none';
431 push @cfgarr, 'ChallengeResponseAuthentication no';
432 push @cfgarr, 'ClientAliveCountMax 3';
433 push @cfgarr, 'ClientAliveInterval 0';
434 push @cfgarr, 'GatewayPorts no';
435 push @cfgarr, 'HostbasedAuthentication no';
436 push @cfgarr, 'HostbasedUsesNameFromPacketOnly no';
437 push @cfgarr, 'IgnoreRhosts yes';
438 push @cfgarr, 'IgnoreUserKnownHosts yes';
439 push @cfgarr, 'KeyRegenerationInterval 0';
440 push @cfgarr, 'LoginGraceTime 30';
441 push @cfgarr, "LogLevel $loglevel";
442 push @cfgarr, 'MaxStartups 5';
443 push @cfgarr, 'PasswordAuthentication no';
444 push @cfgarr, 'PermitEmptyPasswords no';
445 push @cfgarr, 'PermitRootLogin no';
446 push @cfgarr, 'PrintLastLog no';
447 push @cfgarr, 'PrintMotd no';
448 push @cfgarr, 'PubkeyAuthentication yes';
449 push @cfgarr, 'RhostsRSAAuthentication no';
450 push @cfgarr, 'RSAAuthentication no';
451 push @cfgarr, 'ServerKeyBits 768';
452 push @cfgarr, 'StrictModes no';
453 push @cfgarr, "Subsystem sftp $sftpsrv";
454 push @cfgarr, 'SyslogFacility AUTH';
455 push @cfgarr, 'UseLogin no';
456 push @cfgarr, 'X11Forwarding no';
460 #***************************************************************************
461 # Write out initial sshd configuration file for curl's tests
463 $error = dump_array
($sshdconfig, @cfgarr);
470 #***************************************************************************
471 # Verifies at run time if sshd supports a given configuration file option
473 sub sshd_supports_opt
{
474 my ($option, $value) = @_;
477 if((($sshdid =~ /OpenSSH/) && ($sshdvernum >= 310)) ||
478 ($sshdid =~ /SunSSH/)) {
479 # ssh daemon supports command line options -t -f and -o
480 $err = grep /((Unsupported)|(Bad configuration)|(Deprecated)) option.*$option/,
481 qx($sshd -t
-f
$sshdconfig -o
$option=$value 2>&1);
484 if(($sshdid =~ /OpenSSH/) && ($sshdvernum >= 299)) {
485 # ssh daemon supports command line options -t and -f
486 $err = dump_array
($sshdconfig, (@cfgarr, "$option $value"));
491 $err = grep /((Unsupported)|(Bad configuration)|(Deprecated)) option.*$option/,
492 qx($sshd -t
-f
$sshdconfig 2>&1);
500 #***************************************************************************
501 # Kerberos Authentication support may have not been built into sshd
503 if(sshd_supports_opt
('KerberosAuthentication','no')) {
504 push @cfgarr, 'KerberosAuthentication no';
506 if(sshd_supports_opt
('KerberosGetAFSToken','no')) {
507 push @cfgarr, 'KerberosGetAFSToken no';
509 if(sshd_supports_opt
('KerberosOrLocalPasswd','no')) {
510 push @cfgarr, 'KerberosOrLocalPasswd no';
512 if(sshd_supports_opt
('KerberosTgtPassing','no')) {
513 push @cfgarr, 'KerberosTgtPassing no';
515 if(sshd_supports_opt
('KerberosTicketCleanup','yes')) {
516 push @cfgarr, 'KerberosTicketCleanup yes';
520 #***************************************************************************
521 # Andrew File System support may have not been built into sshd
523 if(sshd_supports_opt
('AFSTokenPassing','no')) {
524 push @cfgarr, 'AFSTokenPassing no';
528 #***************************************************************************
529 # S/Key authentication support may have not been built into sshd
531 if(sshd_supports_opt
('SkeyAuthentication','no')) {
532 push @cfgarr, 'SkeyAuthentication no';
536 #***************************************************************************
537 # GSSAPI Authentication support may have not been built into sshd
539 my $sshd_builtwith_GSSAPI;
540 if(sshd_supports_opt
('GSSAPIAuthentication','no')) {
541 push @cfgarr, 'GSSAPIAuthentication no';
542 $sshd_builtwith_GSSAPI = 1;
544 if(sshd_supports_opt
('GSSAPICleanupCredentials','yes')) {
545 push @cfgarr, 'GSSAPICleanupCredentials yes';
547 if(sshd_supports_opt
('GSSAPIKeyExchange','no')) {
548 push @cfgarr, 'GSSAPIKeyExchange no';
550 if(sshd_supports_opt
('GSSAPIStoreDelegatedCredentials','no')) {
551 push @cfgarr, 'GSSAPIStoreDelegatedCredentials no';
553 if(sshd_supports_opt
('GSSCleanupCreds','yes')) {
554 push @cfgarr, 'GSSCleanupCreds yes';
556 if(sshd_supports_opt
('GSSUseSessionCredCache','no')) {
557 push @cfgarr, 'GSSUseSessionCredCache no';
562 #***************************************************************************
563 # Options that might be supported or not in sshd OpenSSH 2.9.9 and later
565 if(sshd_supports_opt
('AcceptEnv','')) {
566 push @cfgarr, 'AcceptEnv';
568 if(sshd_supports_opt
('AddressFamily','any')) {
569 # Address family must be specified before ListenAddress
570 splice @cfgarr, 14, 0, 'AddressFamily any';
572 if(sshd_supports_opt
('Compression','no')) {
573 push @cfgarr, 'Compression no';
575 if(sshd_supports_opt
('KbdInteractiveAuthentication','no')) {
576 push @cfgarr, 'KbdInteractiveAuthentication no';
578 if(sshd_supports_opt
('KeepAlive','no')) {
579 push @cfgarr, 'KeepAlive no';
581 if(sshd_supports_opt
('LookupClientHostnames','no')) {
582 push @cfgarr, 'LookupClientHostnames no';
584 if(sshd_supports_opt
('MaxAuthTries','10')) {
585 push @cfgarr, 'MaxAuthTries 10';
587 if(sshd_supports_opt
('PAMAuthenticationViaKbdInt','no')) {
588 push @cfgarr, 'PAMAuthenticationViaKbdInt no';
590 if(sshd_supports_opt
('PermitTunnel','no')) {
591 push @cfgarr, 'PermitTunnel no';
593 if(sshd_supports_opt
('PermitUserEnvironment','no')) {
594 push @cfgarr, 'PermitUserEnvironment no';
596 if(sshd_supports_opt
('RhostsAuthentication','no')) {
597 push @cfgarr, 'RhostsAuthentication no';
599 if(sshd_supports_opt
('TCPKeepAlive','no')) {
600 push @cfgarr, 'TCPKeepAlive no';
602 if(sshd_supports_opt
('UseDNS','no')) {
603 push @cfgarr, 'UseDNS no';
605 if(sshd_supports_opt
('UsePAM','no')) {
606 push @cfgarr, 'UsePAM no';
609 if($sshdid =~ /OpenSSH/) {
610 # http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=6492415
611 if(sshd_supports_opt
('UsePrivilegeSeparation','no')) {
612 push @cfgarr, 'UsePrivilegeSeparation no';
616 if(sshd_supports_opt
('VerifyReverseMapping','no')) {
617 push @cfgarr, 'VerifyReverseMapping no';
619 if(sshd_supports_opt
('X11UseLocalhost','yes')) {
620 push @cfgarr, 'X11UseLocalhost yes';
625 #***************************************************************************
626 # Write out resulting sshd configuration file for curl's tests
628 $error = dump_array
($sshdconfig, @cfgarr);
635 #***************************************************************************
636 # Verify that sshd actually supports our generated configuration file
638 if(system "$sshd -t -f $sshdconfig > $sshdlog 2>&1") {
639 logmsg
"sshd configuration file $sshdconfig failed verification";
641 display_sshdconfig
();
646 #***************************************************************************
647 # Generate ssh client host key database file for curl's tests
649 if(! -e
$knownhosts) {
650 logmsg
'generating ssh client known hosts file...' if($verbose);
651 if(open(DSAKEYFILE
, "<$hstpubkeyf")) {
652 my @dsahostkey = do { local $/ = ' '; <DSAKEYFILE
> };
653 if(close(DSAKEYFILE
)) {
654 if(open(KNOWNHOSTS
, ">$knownhosts")) {
655 print KNOWNHOSTS
"$listenaddr ssh-dss $dsahostkey[1]\n";
656 if(!close(KNOWNHOSTS
)) {
657 $error = "Error: cannot close file $knownhosts";
661 $error = "Error: cannot write file $knownhosts";
665 $error = "Error: cannot close file $hstpubkeyf";
669 $error = "Error: cannot read file $hstpubkeyf";
678 #***************************************************************************
679 # ssh client configuration file options we might use and version support
681 # AddressFamily : OpenSSH 3.7.0 and later
682 # BatchMode : OpenSSH 1.2.1 and later
683 # BindAddress : OpenSSH 2.9.9 and later
684 # ChallengeResponseAuthentication : OpenSSH 2.5.0 and later
685 # CheckHostIP : OpenSSH 1.2.1 and later
686 # Cipher : OpenSSH 1.2.1 and later [3]
687 # Ciphers : OpenSSH 2.1.0 and later [3]
688 # ClearAllForwardings : OpenSSH 2.9.9 and later
689 # Compression : OpenSSH 1.2.1 and later
690 # CompressionLevel : OpenSSH 1.2.1 and later [3]
691 # ConnectionAttempts : OpenSSH 1.2.1 and later
692 # ConnectTimeout : OpenSSH 3.7.0 and later
693 # ControlMaster : OpenSSH 3.9.0 and later
694 # ControlPath : OpenSSH 3.9.0 and later
695 # DisableBanner : SunSSH 1.2.0 and later
696 # DynamicForward : OpenSSH 2.9.0 and later
697 # EnableSSHKeysign : OpenSSH 3.6.0 and later
698 # EscapeChar : OpenSSH 1.2.1 and later [3]
699 # ExitOnForwardFailure : OpenSSH 4.4.0 and later
700 # ForwardAgent : OpenSSH 1.2.1 and later
701 # ForwardX11 : OpenSSH 1.2.1 and later
702 # ForwardX11Trusted : OpenSSH 3.8.0 and later
703 # GatewayPorts : OpenSSH 1.2.1 and later
704 # GlobalKnownHostsFile : OpenSSH 1.2.1 and later
705 # GSSAPIAuthentication : OpenSSH 3.7.0 and later [1]
706 # GSSAPIDelegateCredentials : OpenSSH 3.7.0 and later [1]
707 # HashKnownHosts : OpenSSH 4.0.0 and later
708 # Host : OpenSSH 1.2.1 and later
709 # HostbasedAuthentication : OpenSSH 2.9.0 and later
710 # HostKeyAlgorithms : OpenSSH 2.9.0 and later [3]
711 # HostKeyAlias : OpenSSH 2.5.0 and later [3]
712 # HostName : OpenSSH 1.2.1 and later
713 # IdentitiesOnly : OpenSSH 3.9.0 and later
714 # IdentityFile : OpenSSH 1.2.1 and later
715 # IgnoreIfUnknown : SunSSH 1.2.0 and later
716 # KeepAlive : OpenSSH 1.2.1 and later
717 # KbdInteractiveAuthentication : OpenSSH 2.3.0 and later
718 # KbdInteractiveDevices : OpenSSH 2.3.0 and later [3]
719 # LocalCommand : OpenSSH 4.3.0 and later [3]
720 # LocalForward : OpenSSH 1.2.1 and later [3]
721 # LogLevel : OpenSSH 1.2.1 and later
722 # MACs : OpenSSH 2.5.0 and later [3]
723 # NoHostAuthenticationForLocalhost : OpenSSH 3.0.0 and later
724 # NumberOfPasswordPrompts : OpenSSH 1.2.1 and later
725 # PasswordAuthentication : OpenSSH 1.2.1 and later
726 # PermitLocalCommand : OpenSSH 4.3.0 and later
727 # Port : OpenSSH 1.2.1 and later
728 # PreferredAuthentications : OpenSSH 2.5.2 and later
729 # Protocol : OpenSSH 2.1.0 and later
730 # ProxyCommand : OpenSSH 1.2.1 and later [3]
731 # PubkeyAuthentication : OpenSSH 2.5.0 and later
732 # RekeyLimit : OpenSSH 3.7.0 and later
733 # RemoteForward : OpenSSH 1.2.1 and later [3]
734 # RhostsRSAAuthentication : OpenSSH 1.2.1 and later
735 # RSAAuthentication : OpenSSH 1.2.1 and later
736 # SendEnv : OpenSSH 3.9.0 and later
737 # ServerAliveCountMax : OpenSSH 3.8.0 and later
738 # ServerAliveInterval : OpenSSH 3.8.0 and later
739 # SmartcardDevice : OpenSSH 2.9.9 and later [1][3]
740 # StrictHostKeyChecking : OpenSSH 1.2.1 and later
741 # TCPKeepAlive : OpenSSH 3.8.0 and later
742 # Tunnel : OpenSSH 4.3.0 and later
743 # TunnelDevice : OpenSSH 4.3.0 and later [3]
744 # UsePAM : OpenSSH 3.7.0 and later [1][2][3]
745 # UsePrivilegedPort : OpenSSH 1.2.1 and later
746 # User : OpenSSH 1.2.1 and later
747 # UserKnownHostsFile : OpenSSH 1.2.1 and later
748 # VerifyHostKeyDNS : OpenSSH 3.8.0 and later
749 # XAuthLocation : OpenSSH 2.1.1 and later [3]
751 # [1] Option only available if activated at compile time
752 # [2] Option specific for portable versions
753 # [3] Option not used in our ssh client config file
756 #***************************************************************************
757 # Initialize ssh config with options actually supported in OpenSSH 2.9.9
759 logmsg
'generating ssh client config file...' if($verbose);
761 push @cfgarr, '# This is a generated file. Do not edit.';
762 push @cfgarr, "# $sshverstr ssh client configuration file for curl testing";
764 push @cfgarr, 'Host *';
766 push @cfgarr, "Port $port";
767 push @cfgarr, "HostName $listenaddr";
768 push @cfgarr, "User $username";
769 push @cfgarr, 'Protocol 2';
771 push @cfgarr, "BindAddress $listenaddr";
772 push @cfgarr, "DynamicForward $socksport";
774 push @cfgarr, "IdentityFile $path/curl_client_key";
775 push @cfgarr, "UserKnownHostsFile $path/$knownhosts";
777 push @cfgarr, 'BatchMode yes';
778 push @cfgarr, 'ChallengeResponseAuthentication no';
779 push @cfgarr, 'CheckHostIP no';
780 push @cfgarr, 'ClearAllForwardings no';
781 push @cfgarr, 'Compression no';
782 push @cfgarr, 'ConnectionAttempts 3';
783 push @cfgarr, 'ForwardAgent no';
784 push @cfgarr, 'ForwardX11 no';
785 push @cfgarr, 'GatewayPorts no';
786 push @cfgarr, 'GlobalKnownHostsFile /dev/null';
787 push @cfgarr, 'HostbasedAuthentication no';
788 push @cfgarr, 'KbdInteractiveAuthentication no';
789 push @cfgarr, "LogLevel $loglevel";
790 push @cfgarr, 'NumberOfPasswordPrompts 0';
791 push @cfgarr, 'PasswordAuthentication no';
792 push @cfgarr, 'PreferredAuthentications publickey';
793 push @cfgarr, 'PubkeyAuthentication yes';
794 push @cfgarr, 'RhostsRSAAuthentication no';
795 push @cfgarr, 'RSAAuthentication no';
796 push @cfgarr, 'StrictHostKeyChecking yes';
797 push @cfgarr, 'UsePrivilegedPort no';
801 #***************************************************************************
802 # Options supported in ssh client newer than OpenSSH 2.9.9
805 if(($sshid =~ /OpenSSH/) && ($sshvernum >= 370)) {
806 push @cfgarr, 'AddressFamily any';
809 if((($sshid =~ /OpenSSH/) && ($sshvernum >= 370)) ||
810 (($sshid =~ /SunSSH/) && ($sshvernum >= 120))) {
811 push @cfgarr, 'ConnectTimeout 30';
814 if(($sshid =~ /OpenSSH/) && ($sshvernum >= 390)) {
815 push @cfgarr, 'ControlMaster no';
818 if(($sshid =~ /OpenSSH/) && ($sshvernum >= 420)) {
819 push @cfgarr, 'ControlPath none';
822 if(($sshid =~ /SunSSH/) && ($sshvernum >= 120)) {
823 push @cfgarr, 'DisableBanner yes';
826 if(($sshid =~ /OpenSSH/) && ($sshvernum >= 360)) {
827 push @cfgarr, 'EnableSSHKeysign no';
830 if(($sshid =~ /OpenSSH/) && ($sshvernum >= 440)) {
831 push @cfgarr, 'ExitOnForwardFailure yes';
834 if((($sshid =~ /OpenSSH/) && ($sshvernum >= 380)) ||
835 (($sshid =~ /SunSSH/) && ($sshvernum >= 120))) {
836 push @cfgarr, 'ForwardX11Trusted no';
839 if(($sshd_builtwith_GSSAPI) && ($sshdid eq $sshid) &&
840 ($sshdvernum == $sshvernum)) {
841 push @cfgarr, 'GSSAPIAuthentication no';
842 push @cfgarr, 'GSSAPIDelegateCredentials no';
843 if($sshid =~ /SunSSH/) {
844 push @cfgarr, 'GSSAPIKeyExchange no';
848 if((($sshid =~ /OpenSSH/) && ($sshvernum >= 400)) ||
849 (($sshid =~ /SunSSH/) && ($sshvernum >= 120))) {
850 push @cfgarr, 'HashKnownHosts no';
853 if(($sshid =~ /OpenSSH/) && ($sshvernum >= 390)) {
854 push @cfgarr, 'IdentitiesOnly yes';
857 if(($sshid =~ /SunSSH/) && ($sshvernum >= 120)) {
858 push @cfgarr, 'IgnoreIfUnknown no';
861 if((($sshid =~ /OpenSSH/) && ($sshvernum < 380)) ||
862 ($sshid =~ /SunSSH/)) {
863 push @cfgarr, 'KeepAlive no';
866 if((($sshid =~ /OpenSSH/) && ($sshvernum >= 300)) ||
867 ($sshid =~ /SunSSH/)) {
868 push @cfgarr, 'NoHostAuthenticationForLocalhost no';
871 if(($sshid =~ /OpenSSH/) && ($sshvernum >= 430)) {
872 push @cfgarr, 'PermitLocalCommand no';
875 if((($sshid =~ /OpenSSH/) && ($sshvernum >= 370)) ||
876 (($sshid =~ /SunSSH/) && ($sshvernum >= 120))) {
877 push @cfgarr, 'RekeyLimit 1G';
880 if(($sshid =~ /OpenSSH/) && ($sshvernum >= 390)) {
881 push @cfgarr, 'SendEnv';
884 if((($sshid =~ /OpenSSH/) && ($sshvernum >= 380)) ||
885 (($sshid =~ /SunSSH/) && ($sshvernum >= 120))) {
886 push @cfgarr, 'ServerAliveCountMax 3';
887 push @cfgarr, 'ServerAliveInterval 0';
890 if(($sshid =~ /OpenSSH/) && ($sshvernum >= 380)) {
891 push @cfgarr, 'TCPKeepAlive no';
894 if(($sshid =~ /OpenSSH/) && ($sshvernum >= 430)) {
895 push @cfgarr, 'Tunnel no';
898 if(($sshid =~ /OpenSSH/) && ($sshvernum >= 380)) {
899 push @cfgarr, 'VerifyHostKeyDNS no';
905 #***************************************************************************
906 # Write out resulting ssh client configuration file for curl's tests
908 $error = dump_array
($sshconfig, @cfgarr);
915 #***************************************************************************
916 # Initialize client sftp config with options actually supported.
918 logmsg
'generating sftp client config file...' if($verbose);
919 splice @cfgarr, 1, 1, "# $sshverstr sftp client configuration file for curl testing";
921 for(my $i = scalar(@cfgarr) - 1; $i > 0; $i--) {
922 if($cfgarr[$i] =~ /^DynamicForward/) {
923 splice @cfgarr, $i, 1;
926 if($cfgarr[$i] =~ /^ClearAllForwardings/) {
927 splice @cfgarr, $i, 1, "ClearAllForwardings yes";
933 #***************************************************************************
934 # Write out resulting sftp client configuration file for curl's tests
936 $error = dump_array
($sftpconfig, @cfgarr);
944 #***************************************************************************
945 # Generate client sftp commands batch file for sftp server verification
947 logmsg
'generating sftp client commands file...' if($verbose);
949 push @cfgarr, 'quit';
950 $error = dump_array
($sftpcmds, @cfgarr);
958 #***************************************************************************
959 # Start the ssh server daemon without forking it
961 logmsg
"SCP/SFTP server listening on port $port" if($verbose);
962 my $rc = system "$sshd -e -D -f $sshdconfig > $sshdlog 2>&1";
964 logmsg
"$sshd failed with: $!";
967 logmsg
sprintf("$sshd died with signal %d, and %s coredump",
968 ($rc & 127), ($rc & 128)?
'a':'no');
970 elsif($verbose && ($rc >> 8)) {
971 logmsg
sprintf("$sshd exited with %d", $rc >> 8);
975 #***************************************************************************
976 # Clean up once the server has stopped
978 unlink($hstprvkeyf, $hstpubkeyf, $cliprvkeyf, $clipubkeyf, $knownhosts);
979 unlink($sshdconfig, $sshconfig, $sftpconfig);