From d1239b50bececdb84e748da9528223c516ad8308 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 20 Apr 2020 15:10:24 +0200 Subject: tests: pick a random port number for SSH Since sshd doesn't have such an option by itself, we iterate over a series of random ports until one works. Closes #5273 --- tests/runtests.pl | 132 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 76 insertions(+), 56 deletions(-) diff --git a/tests/runtests.pl b/tests/runtests.pl index fe794b3b7..b8d946a47 100755 --- a/tests/runtests.pl +++ b/tests/runtests.pl @@ -2117,7 +2117,6 @@ sub runrtspserver { sub runsshserver { my ($id, $verbose, $ipv6) = @_; my $ip=$HOSTIP; - my $port = $SSHPORT; my $proto = 'ssh'; my $ipvnum = 4; my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1; @@ -2125,7 +2124,7 @@ sub runsshserver { my $srvrname; my $pidfile; my $logfile; - my $flags = ""; + my $port = 20000; # no lower port $server = servername_id($proto, $ipvnum, $idnum); @@ -2135,7 +2134,6 @@ sub runsshserver { if ($doesntrun{$pidfile}) { return (0,0); } - my $pid = processexists($pidfile); if($pid > 0) { stopserver($server, "$pid"); @@ -2146,60 +2144,87 @@ sub runsshserver { $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum); + my $flags = ""; $flags .= "--verbose " if($verbose); $flags .= "--debugprotocol " if($debugprotocol); $flags .= "--pidfile \"$pidfile\" "; $flags .= "--id $idnum " if($idnum > 1); $flags .= "--ipv$ipvnum --addr \"$ip\" "; - $flags .= "--sshport $port "; $flags .= "--user \"$USER\""; - my $cmd = "$perl $srcdir/sshserver.pl $flags"; - my ($sshpid, $pid2) = startnew($cmd, $pidfile, 60, 0); - - # on loaded systems sshserver start up can take longer than the timeout - # passed to startnew, when this happens startnew completes without being - # able to read the pidfile and consequently returns a zero pid2 above. - - if($sshpid <= 0 || !pidexists($sshpid)) { - # it is NOT alive - logmsg "RUN: failed to start the $srvrname server\n"; - stopserver($server, "$pid2"); - $doesntrun{$pidfile} = 1; - return (0,0); - } + my $sshpid; + my $pid2; + + my $wport = 0, + my @tports; + for(1 .. 10) { + + # sshd doesn't have a way to pick an unused random port number, so + # instead we iterate over possible port numbers to use until we find + # one that works + $port += int(rand(500)); + push @tports, $port; + + my $options = "$flags --sshport $port"; + + my $cmd = "$perl $srcdir/sshserver.pl $options"; + ($sshpid, $pid2) = startnew($cmd, $pidfile, 60, 0); + + # on loaded systems sshserver start up can take longer than the + # timeout passed to startnew, when this happens startnew completes + # without being able to read the pidfile and consequently returns a + # zero pid2 above. + if($sshpid <= 0 || !pidexists($sshpid)) { + # it is NOT alive + logmsg "RUN: failed to start the $srvrname server on $port\n"; + stopserver($server, "$pid2"); + $doesntrun{$pidfile} = 1; + next; + } - # ssh server verification allows some extra time for the server to start up - # and gives us the opportunity of recovering the pid from the pidfile, when - # this verification succeeds the recovered pid is assigned to pid2. + # ssh server verification allows some extra time for the server to + # start up and gives us the opportunity of recovering the pid from the + # pidfile, when this verification succeeds the recovered pid is + # assigned to pid2. - my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port); - if(!$pid3) { - logmsg "RUN: $srvrname server failed verification\n"; - # failed to fetch server pid. Kill the server and return failure - stopserver($server, "$sshpid $pid2"); - $doesntrun{$pidfile} = 1; - return (0,0); + my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port); + if(!$pid3) { + logmsg "RUN: $srvrname server failed verification\n"; + # failed to fetch server pid. Kill the server and return failure + stopserver($server, "$sshpid $pid2"); + $doesntrun{$pidfile} = 1; + next; + } + $pid2 = $pid3; + + # once it is known that the ssh server is alive, sftp server + # verification is performed actually connecting to it, authenticating + # and performing a very simple remote command. This verification is + # tried only one time. + + $sshdlog = server_logfilename($LOGDIR, 'ssh', $ipvnum, $idnum); + $sftplog = server_logfilename($LOGDIR, 'sftp', $ipvnum, $idnum); + + if(verifysftp('sftp', $ipvnum, $idnum, $ip, $port) < 1) { + logmsg "RUN: SFTP server failed verification\n"; + # failed to talk to it properly. Kill the server and return failure + display_sftplog(); + display_sftpconfig(); + display_sshdlog(); + display_sshdconfig(); + stopserver($server, "$sshpid $pid2"); + $doesntrun{$pidfile} = 1; + next; + } + # we're happy, no need to loop anymore! + $wport = $port; + last; } - $pid2 = $pid3; - - # once it is known that the ssh server is alive, sftp server verification - # is performed actually connecting to it, authenticating and performing a - # very simple remote command. This verification is tried only one time. - $sshdlog = server_logfilename($LOGDIR, 'ssh', $ipvnum, $idnum); - $sftplog = server_logfilename($LOGDIR, 'sftp', $ipvnum, $idnum); - - if(verifysftp('sftp', $ipvnum, $idnum, $ip, $port) < 1) { - logmsg "RUN: SFTP server failed verification\n"; - # failed to talk to it properly. Kill the server and return failure - display_sftplog(); - display_sftpconfig(); - display_sshdlog(); - display_sshdconfig(); - stopserver($server, "$sshpid $pid2"); - $doesntrun{$pidfile} = 1; - return (0,0); + if(!$wport) { + logmsg "RUN: couldn't start $srvrname. Tried these ports:"; + logmsg "RUN: ".join(", ", @tports); + return (0,0,0); } my $hstpubmd5f = "curl_host_rsa_key.pub_md5"; @@ -2214,11 +2239,9 @@ sub runsshserver { die $msg; } - if($verbose) { - logmsg "RUN: $srvrname server is now running PID $pid2\n"; - } + logmsg "RUN: $srvrname on PID $pid2 port $wport\n"; - return ($pid2, $sshpid); + return ($pid2, $sshpid, $wport); } ####################################################################### @@ -3168,7 +3191,6 @@ sub checksystem { logmsg sprintf("FTPS/%d ", $FTPSPORT); logmsg sprintf("HTTPS/%d ", $HTTPSPORT); } - logmsg sprintf("\n* SSH/%d ", $SSHPORT); if($httptlssrv) { logmsg sprintf("HTTPTLS/%d ", $HTTPTLSPORT); if($has_ipv6) { @@ -3718,8 +3740,7 @@ sub singletest { return -1; } my $fileContent = join('', @inputfile); - subVariables \$fileContent; -# logmsg "DEBUG: writing file " . $filename . "\n"; + subVariables(\$fileContent); open(OUTFILE, ">$filename"); binmode OUTFILE; # for crapage systems, use binary print OUTFILE $fileContent; @@ -3987,7 +4008,7 @@ sub singletest { if(@postcheck) { $cmd = join("", @postcheck); chomp $cmd; - subVariables \$cmd; + subVariables(\$cmd); if($cmd) { logmsg "postcheck $cmd\n" if($verbose); my $rc = runclient("$cmd"); @@ -4828,7 +4849,7 @@ sub startservers { } elsif($what eq "sftp" || $what eq "scp") { if(!$run{'ssh'}) { - ($pid, $pid2) = runsshserver("", $verbose); + ($pid, $pid2, $SSHPORT) = runsshserver("", $verbose); if($pid <= 0) { return "failed starting SSH server"; } @@ -5396,7 +5417,6 @@ if ($gdbthis) { $minport = $base; # original base port number $HTTPSPORT = $base++; # HTTPS (stunnel) server port $FTPSPORT = $base++; # FTPS (stunnel) server port -$SSHPORT = $base++; # SSH (SCP/SFTP) port $HTTPTLSPORT = $base++; # HTTP TLS (non-stunnel) server port $HTTPTLS6PORT = $base++; # HTTP TLS (non-stunnel) IPv6 server port $HTTP2PORT = $base++; # HTTP/2 port -- cgit v1.2.3