Changed the test harness to attempt to gracefully shut down servers
before resorting to the kill -9 hammer. Added test harness infrastructure to support scp/sftp tests, using OpenSSH as the server.
This commit is contained in:
parent
3d528e1b15
commit
b7131009fb
6
CHANGES
6
CHANGES
@ -10,6 +10,12 @@ Dan F (23 March 2007)
|
||||
- Added --pubkey option to curl and made --key also work for SCP/SFTP,
|
||||
plus made --pass work on an SSH private key as well.
|
||||
|
||||
- Changed the test harness to attempt to gracefully shut down servers
|
||||
before resorting to the kill -9 hammer.
|
||||
|
||||
- Added test harness infrastructure to support scp/sftp tests, using
|
||||
OpenSSH as the server.
|
||||
|
||||
Yang Tse (20 March 2007)
|
||||
- Fixed: When a signal was caught awaiting for an event using Curl_select()
|
||||
or Curl_poll() with a non-zero timeout both functions would restart the
|
||||
|
@ -126,6 +126,8 @@ http
|
||||
http-ipv6
|
||||
https
|
||||
none
|
||||
scp
|
||||
sftp
|
||||
|
||||
Give only one per line. This subsection is mandatory.
|
||||
</server>
|
||||
@ -212,9 +214,11 @@ Available substitute variables include:
|
||||
%FTP2PORT - Port number of the FTP server 2
|
||||
%TFTPPORT - Port number of the TFTP server
|
||||
%TFTP6PORT - IPv6 port number of the TFTP server
|
||||
%SSHPORT - Port number of the SCP/SFTP server
|
||||
%SRCDIR - Full path to the source dir
|
||||
%PWD - Current directory
|
||||
%CURL - Path to the curl executable
|
||||
%USER - Login ID of the user running the test
|
||||
</command>
|
||||
|
||||
<file name="log/filename">
|
||||
|
@ -48,6 +48,7 @@ my $FTPSPORT; # FTPS server port
|
||||
my $FTP6PORT; # FTP IPv6 server port
|
||||
my $TFTPPORT; # TFTP
|
||||
my $TFTP6PORT; # TFTP
|
||||
my $SSHPORT; # SCP/SFTP
|
||||
|
||||
my $CURL="../src/curl"; # what curl executable to run on the tests
|
||||
my $DBGCURL=$CURL; #"../src/.libs/curl"; # alternative for debugging
|
||||
@ -79,6 +80,7 @@ my $FTP2PIDFILE=".ftp2.pid";
|
||||
my $FTPSPIDFILE=".ftps.pid";
|
||||
my $TFTPPIDFILE=".tftpd.pid";
|
||||
my $TFTP6PIDFILE=".tftp6.pid";
|
||||
my $SSHPIDFILE=".ssh.pid";
|
||||
|
||||
# invoke perl like this:
|
||||
my $perl="perl -I$srcdir";
|
||||
@ -197,6 +199,15 @@ sub logmsg {
|
||||
|
||||
chomp($pwd = `pwd`);
|
||||
|
||||
# get the name of the current user
|
||||
my $USER = $ENV{USER}; # Linux
|
||||
if (!$USER) {
|
||||
$USER = $ENV{USERNAME}; # Windows
|
||||
if (!$USER) {
|
||||
$USER = $ENV{LOGNAME}; # Some UNIX (I think)
|
||||
}
|
||||
}
|
||||
|
||||
# enable memory debugging if curl is compiled with it
|
||||
$ENV{'CURL_MEMDEBUG'} = $memdump;
|
||||
$ENV{'HOME'}=$pwd;
|
||||
@ -230,6 +241,16 @@ $ENV{'SSL_CERT_DIR'}=undef;
|
||||
$ENV{'SSL_CERT_PATH'}=undef;
|
||||
$ENV{'CURL_CA_BUNDLE'}=undef;
|
||||
|
||||
#######################################################################
|
||||
# Check if a given child process has just died. Reaps it if so.
|
||||
#
|
||||
sub checkdied {
|
||||
use POSIX ":sys_wait_h";
|
||||
my $pid = $_[0];
|
||||
my $rc = waitpid($pid, &WNOHANG);
|
||||
return $rc == $pid;
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
# Start a new thread/process and run the given command line in there.
|
||||
# Return the pids (yes plural) of the new child process to the parent.
|
||||
@ -277,6 +298,15 @@ sub startnew {
|
||||
last;
|
||||
}
|
||||
}
|
||||
if (checkdied($child)) {
|
||||
logmsg "startnew: Warning: child process has died\n" if($verbose);
|
||||
# We can't just abort waiting for the server with a
|
||||
# return (-1,-1);
|
||||
# because the server might have forked and could still start
|
||||
# up normally. Instead, just reduce the amount of time we remain
|
||||
# waiting.
|
||||
$count >>= 2;
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
@ -411,8 +441,10 @@ sub stopserver {
|
||||
return; # whad'da'ya wanna'da with no pid ?
|
||||
}
|
||||
|
||||
# it might be more than one pid
|
||||
# It might be more than one pid
|
||||
# Send each one a SIGTERM to gracefully kill it
|
||||
|
||||
my @killed;
|
||||
my @pids = split(/\s+/, $pid);
|
||||
for (@pids) {
|
||||
chomp($_);
|
||||
@ -421,10 +453,27 @@ sub stopserver {
|
||||
if($verbose) {
|
||||
logmsg "RUN: Test server pid $1 signalled to die\n";
|
||||
}
|
||||
kill(9, $1); # die!
|
||||
kill(15, $1); # die!
|
||||
push @killed, $1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Give each process killed up to a few seconds to die, then send
|
||||
# a SIGKILL to finish it off for good.
|
||||
for (@killed) {
|
||||
my $count = 5; # wait for this many seconds for server to die
|
||||
while($count--) {
|
||||
if (!kill(0, $_) || checkdied($_)) {
|
||||
last;
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
if ($count < 0) {
|
||||
logmsg "RUN: forcing pid $_ to die with SIGKILL\n";
|
||||
kill(9, $_); # die!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
@ -520,6 +569,17 @@ sub verifyftp {
|
||||
return $pid;
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
# STUB for verifying scp/sftp
|
||||
|
||||
sub verifyssh {
|
||||
my ($proto, $ip, $port) = @_;
|
||||
open(FILE, "<" . $SSHPIDFILE);
|
||||
my $pid=0+<FILE>;
|
||||
close(FILE);
|
||||
return $pid;
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
# Verify that the server that runs on $ip, $port is our server.
|
||||
# Retry during 5 seconds before giving up.
|
||||
@ -529,7 +589,8 @@ my %protofunc = ('http' => \&verifyhttp,
|
||||
'https' => \&verifyhttp,
|
||||
'ftp' => \&verifyftp,
|
||||
'ftps' => \&verifyftp,
|
||||
'tftp' => \&verifyftp);
|
||||
'tftp' => \&verifyftp,
|
||||
'ssh' => \&verifyssh);
|
||||
|
||||
sub verifyserver {
|
||||
my ($proto, $ip, $port) = @_;
|
||||
@ -852,6 +913,44 @@ sub runtftpserver {
|
||||
}
|
||||
|
||||
|
||||
#######################################################################
|
||||
# Start the scp/sftp server
|
||||
#
|
||||
sub runsshserver {
|
||||
my ($id, $verbose, $ipv6) = @_;
|
||||
my $ip=$HOSTIP;
|
||||
my $port = $SSHPORT;
|
||||
my $pidfile = $SSHPIDFILE;
|
||||
|
||||
my $pid = checkserver($pidfile);
|
||||
if($pid > 0) {
|
||||
stopserver($pid);
|
||||
}
|
||||
|
||||
my $flag=$debugprotocol?"-v ":"";
|
||||
my $cmd="$perl $srcdir/sshserver.pl $flag-u $USER -d $srcdir $port";
|
||||
my ($sshpid, $pid2) =
|
||||
startnew($cmd, $pidfile); # start the server in a new process
|
||||
|
||||
if(!$sshpid || !kill(0, $sshpid)) {
|
||||
# it is NOT alive
|
||||
logmsg "RUN: failed to start the SSH server!\n";
|
||||
# failed to talk to it properly. Kill the server and return failure
|
||||
stopserver("$sshpid $pid2");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!verifyserver('ssh',$ip,$port)) {
|
||||
logmsg "RUN: SSH server failed verification\n";
|
||||
return (0,0);
|
||||
}
|
||||
if($verbose) {
|
||||
logmsg "RUN: SSH server is now running PID $sshpid\n";
|
||||
}
|
||||
|
||||
return ($pid2, $sshpid);
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
# Remove all files in the specified directory
|
||||
#
|
||||
@ -1167,9 +1266,10 @@ sub checksystem {
|
||||
if($tftp_ipv6) {
|
||||
logmsg sprintf("* TFTP IPv6 port: %d\n", $TFTP6PORT);
|
||||
}
|
||||
logmsg sprintf("* SCP/SFTP port: %d\n", $SSHPORT);
|
||||
|
||||
if($ssl_version) {
|
||||
logmsg sprintf("* SSL library: %s\n", $ssllib?"yassl":"<unknown>");
|
||||
logmsg sprintf("* SSL library: %s\n", $ssllib);
|
||||
}
|
||||
|
||||
$has_textaware = ($^O eq 'MSWin32') || ($^O eq 'msys');
|
||||
@ -1197,7 +1297,9 @@ sub subVariables {
|
||||
$$thing =~ s/%PWD/$pwd/g;
|
||||
$$thing =~ s/%TFTPPORT/$TFTPPORT/g;
|
||||
$$thing =~ s/%TFTP6PORT/$TFTP6PORT/g;
|
||||
$$thing =~ s/%SSHPORT/$SSHPORT/g;
|
||||
$$thing =~ s/%CURL/$CURL/g;
|
||||
$$thing =~ s/%USER/$USER/g;
|
||||
|
||||
# The purpose of FTPTIME2 and FTPTIME3 is to provide times that can be
|
||||
# used for time-out tests and that whould work on most hosts as these
|
||||
@ -2058,6 +2160,16 @@ sub startservers {
|
||||
$run{'tftp-ipv6'}="$pid $pid2";
|
||||
}
|
||||
}
|
||||
elsif($what eq "sftp" || $what eq "scp") {
|
||||
if(!$run{'ssh'}) {
|
||||
($pid, $pid2) = runsshserver("", $verbose);
|
||||
if($pid <= 0) {
|
||||
return "failed starting SSH server";
|
||||
}
|
||||
printf ("* pid ssh => %d %d\n", $pid, $pid2) if($verbose);
|
||||
$run{'ssh'}="$pid $pid2";
|
||||
}
|
||||
}
|
||||
elsif($what eq "none") {
|
||||
logmsg "* starts no server\n" if ($verbose);
|
||||
}
|
||||
@ -2244,6 +2356,7 @@ $FTP2PORT = $base + 5; # FTP server 2 port
|
||||
$FTP6PORT = $base + 6; # FTP IPv6 port
|
||||
$TFTPPORT = $base + 7; # TFTP (UDP) port
|
||||
$TFTP6PORT = $base + 8; # TFTP IPv6 (UDP) port
|
||||
$SSHPORT = $base + 9; # SSH (SCP/SFTP) port
|
||||
|
||||
#######################################################################
|
||||
# clear and create logging directory:
|
||||
|
138
tests/sshserver.pl
Normal file
138
tests/sshserver.pl
Normal file
@ -0,0 +1,138 @@
|
||||
#/usr/bin/env perl
|
||||
# $Id$
|
||||
# Start sshd for use in the SCP and SFTP curl test harness tests
|
||||
|
||||
# Options:
|
||||
# -u user
|
||||
# -v
|
||||
# target_port
|
||||
|
||||
use strict;
|
||||
use File::Spec;
|
||||
|
||||
my $verbose=0; # set to 1 for debugging
|
||||
|
||||
my $port = 8999; # just our default, weird enough
|
||||
|
||||
my $path = `pwd`;
|
||||
chomp $path;
|
||||
|
||||
my $exeext;
|
||||
if ($^O eq 'MSWin32' || $^O eq 'cygwin' || $^O eq 'msys' || $^O eq 'dos' || $^O eq 'os2') {
|
||||
$exeext = '.exe';
|
||||
}
|
||||
|
||||
# Where to look for sftp-server
|
||||
my @sftppath=qw(/usr/lib/openssh /usr/libexec/openssh /usr/libexec /usr/local/libexec /opt/local/libexec /usr/lib/ssh /usr/libexec/ssh /usr/sbin /usr/lib /usr/lib/ssh/openssh /usr/lib64/ssh);
|
||||
|
||||
my $username = $ENV{USER};
|
||||
|
||||
# Find a file somewhere in the given path
|
||||
sub searchpath {
|
||||
my $fn = $_[0] . $exeext;
|
||||
shift;
|
||||
my @path = @_;
|
||||
foreach (@path) {
|
||||
my $file = File::Spec->catfile($_, $fn);
|
||||
if (-e $file) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Parse options
|
||||
do {
|
||||
if($ARGV[0] eq "-v") {
|
||||
$verbose=1;
|
||||
}
|
||||
elsif($ARGV[0] eq "-u") {
|
||||
$username=$ARGV[1];
|
||||
shift @ARGV;
|
||||
}
|
||||
elsif($ARGV[0] =~ /^(\d+)$/) {
|
||||
$port = $1;
|
||||
}
|
||||
} while(shift @ARGV);
|
||||
|
||||
my $conffile="curl_sshd_config"; # sshd configuration data
|
||||
|
||||
# Search the PATH for sshd. sshd insists on being called with an absolute
|
||||
# path for some reason.
|
||||
my $sshd = searchpath("sshd", File::Spec->path());
|
||||
if (!$sshd) {
|
||||
print "sshd is not available\n";
|
||||
exit 1;
|
||||
}
|
||||
if ($verbose) {
|
||||
print STDERR "SSH server found at $sshd\n";
|
||||
}
|
||||
|
||||
my $sftp = searchpath("sftp-server", @sftppath);
|
||||
if (!$sftp) {
|
||||
print "Could not find sftp-server plugin\n";
|
||||
exit 1;
|
||||
}
|
||||
if ($verbose) {
|
||||
print STDERR "SFTP server plugin found at $sftp\n";
|
||||
}
|
||||
|
||||
if (! -e "curl_client_key.pub") {
|
||||
if ($verbose) {
|
||||
print STDERR "Generating host and client keys...\n";
|
||||
}
|
||||
# Make sure all files are gone so ssh-keygen doesn't complain
|
||||
unlink("curl_host_dsa_key", "curl_client_key","curl_host_dsa_key.pub", "curl_client_key.pub");
|
||||
system "ssh-keygen -q -t dsa -f curl_host_dsa_key -C 'curl test server' -N ''" and die "Could not generate key";
|
||||
system "ssh-keygen -q -t dsa -f curl_client_key -C 'curl test client' -N ''" and die "Could not generate key";
|
||||
}
|
||||
|
||||
open(FILE, ">$conffile") || die "Could not write $conffile";
|
||||
print FILE <<EOF
|
||||
# This is a generated file! Do not edit!
|
||||
# OpenSSH sshd configuration file for curl testing
|
||||
AllowUsers $username
|
||||
AuthorizedKeysFile $path/curl_client_key.pub
|
||||
HostKey $path/curl_host_dsa_key
|
||||
PidFile $path/.ssh.pid
|
||||
Port $port
|
||||
ListenAddress localhost
|
||||
Protocol 2
|
||||
AllowTcpForwarding no
|
||||
HostbasedAuthentication no
|
||||
IgnoreRhosts yes
|
||||
IgnoreUserKnownHosts yes
|
||||
KeepAlive no
|
||||
PasswordAuthentication no
|
||||
PermitEmptyPasswords no
|
||||
PermitRootLogin no
|
||||
PrintLastLog no
|
||||
PrintMotd no
|
||||
StrictModes no
|
||||
Subsystem sftp $sftp
|
||||
UseLogin no
|
||||
X11Forwarding no
|
||||
# Newer OpenSSH options
|
||||
UsePam no
|
||||
UseDNS no
|
||||
ChallengeResponseAuthentication no
|
||||
EOF
|
||||
;
|
||||
close FILE;
|
||||
|
||||
if (system "$sshd -t -q -f $conffile") {
|
||||
# This is likely due to missing support for UsePam
|
||||
print "$sshd is too old and is not supported\n";
|
||||
unlink $conffile;
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# Start the server
|
||||
my $rc = system "$sshd -e -f $conffile > log/ssh.log 2>&1";
|
||||
$rc >>= 8;
|
||||
if($rc) {
|
||||
print STDERR "$sshd exited with $rc!\n";
|
||||
}
|
||||
|
||||
unlink $conffile;
|
||||
|
||||
exit $rc;
|
Loading…
Reference in New Issue
Block a user