Loading CHANGES +6 −0 Original line number Diff line number Diff line Loading @@ -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 Loading tests/FILEFORMAT +4 −0 Original line number Diff line number Diff line Loading @@ -126,6 +126,8 @@ http http-ipv6 https none scp sftp Give only one per line. This subsection is mandatory. </server> Loading Loading @@ -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"> Loading tests/runtests.pl +117 −4 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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"; Loading Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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); } Loading Loading @@ -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($_); Loading @@ -421,8 +453,25 @@ 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! } } } Loading Loading @@ -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. Loading @@ -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) = @_; Loading Loading @@ -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 # Loading Loading @@ -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'); Loading Loading @@ -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 Loading Loading @@ -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); } Loading Loading @@ -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: Loading tests/sshserver.pl 0 → 100644 +138 −0 Original line number Diff line number Diff line #/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
CHANGES +6 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
tests/FILEFORMAT +4 −0 Original line number Diff line number Diff line Loading @@ -126,6 +126,8 @@ http http-ipv6 https none scp sftp Give only one per line. This subsection is mandatory. </server> Loading Loading @@ -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"> Loading
tests/runtests.pl +117 −4 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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"; Loading Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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); } Loading Loading @@ -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($_); Loading @@ -421,8 +453,25 @@ 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! } } } Loading Loading @@ -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. Loading @@ -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) = @_; Loading Loading @@ -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 # Loading Loading @@ -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'); Loading Loading @@ -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 Loading Loading @@ -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); } Loading Loading @@ -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: Loading
tests/sshserver.pl 0 → 100644 +138 −0 Original line number Diff line number Diff line #/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;