From 1a340de0e5f378e58130dd86955e6bcee47b6f19 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 8 Feb 2008 13:54:02 +0000 Subject: [PATCH] To verify that the sftp server is actually running, responsive and that all curl's tests generated configuration and key files are fine, a real connection is established to the test harness sftp server authenticating and running a simple sftp remote pwd command. The verification is done using OpenSSH's or SunSSH's sftp client tool with a configuration file with the same options as the test harness socks server with the exception that dynamic forwarding is not used for sftp. --- CHANGES | 5 ++++ tests/.cvsignore | 6 ++-- tests/runtests.pl | 69 ++++++++++++++++++++++++++++++++++++++++++---- tests/sshhelp.pm | 41 ++++++++++++++++++++++++++- tests/sshserver.pl | 67 ++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 176 insertions(+), 12 deletions(-) diff --git a/CHANGES b/CHANGES index feef3cfac..fc9932c84 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,11 @@ Changelog +Yang Tse (8 Feb 2008) +- Improved test harness SCP/SFTP start up server verification, doing a real + connection to the sftp server, authenticating and running a simple sftp + pwd command using the test harness generated configuration and key files. + Daniel S (8 Feb 2008) - Günter Knauf added lib/mk-ca-bundle.pl which gets the Firefox ca bundle and creates a suitable ca-bundle.crt file in PEM format for use with curl. The diff --git a/tests/.cvsignore b/tests/.cvsignore index 217b75782..e6d5aa18b 100644 --- a/tests/.cvsignore +++ b/tests/.cvsignore @@ -5,11 +5,13 @@ log *.pid *.pdf *.html -curl_client_knownhosts curl_client_key curl_client_key.pub +curl_client_knownhosts curl_host_dsa_key curl_host_dsa_key.pub -curl_sshd_config +curl_sftp_cmds +curl_sftp_config curl_ssh_config +curl_sshd_config stunnel.conf diff --git a/tests/runtests.pl b/tests/runtests.pl index 77b57b1dc..b0520dbff 100755 --- a/tests/runtests.pl +++ b/tests/runtests.pl @@ -69,14 +69,21 @@ use Cwd; use sshhelp qw( $sshdexe $sshexe + $sftpexe $sshconfig + $sftpconfig $sshlog + $sftplog + $sftpcmds display_sshdconfig display_sshconfig + display_sftpconfig display_sshdlog display_sshlog + display_sftplog find_sshd find_ssh + find_sftp sshversioninfo ); @@ -658,7 +665,9 @@ sub verifyftp { } ####################################################################### -# STUB for verifying scp/sftp +# Verify that the ssh server has written out its pidfile, recovering +# the pid from the file and returning it if a process with that pid is +# actually alive. sub verifyssh { my ($proto, $ip, $port) = @_; @@ -680,6 +689,37 @@ sub verifyssh { return $pid; } +####################################################################### +# Verify that we can connect to the sftp server, properly authenticate +# with generated config and key files and run a simple remote pwd. + +sub verifysftp { + my ($proto, $ip, $port) = @_; + my $verified = 0; + # Find out sftp client canonical file name + my $sftp = find_sftp(); + if(!$sftp) { + logmsg "RUN: SFTP server cannot find $sftpexe\n"; + return -1; + } + # Connect to sftp server, authenticate and run a remote pwd + # command using our generated configuration and key files + my $cmd = "$sftp -b $sftpcmds -F $sftpconfig $ip > $sftplog 2>&1"; + my $res = runclient($cmd); + # Search for pwd command response in log file + if(open(SFTPLOGFILE, "<$sftplog")) { + while() { + if(/^Remote working directory: /) { + $verified = 1; + last; + } + } + close(SFTPLOGFILE); + } + return $verified; +} + + ####################################################################### # STUB for verifying socks @@ -716,6 +756,7 @@ my %protofunc = ('http' => \&verifyhttp, 'ftps' => \&verifyftp, 'tftp' => \&verifyftp, 'ssh' => \&verifyssh, + 'sftp' => \&verifysftp, 'socks' => \&verifysocks); sub verifyserver { @@ -1122,19 +1163,35 @@ sub runsshserver { return (0,0); } - # server verification allows some extra time for the server to start up - # and gives us the opportunity of recovering the pid from the pidfile, - # which will be assigned to pid2 ONLY if pid2 was not already positive. + # 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("ssh",$ip,$port); if(!$pid3) { logmsg "RUN: SSH server failed verification\n"; - # failed to talk to it properly. Kill the server and return failure + # failed to fetch server pid. Kill the server and return failure + stopserver("$sshpid $pid2"); + $doesntrun{$pidfile} = 1; + return (0,0); + } + $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. + + if(!verifyserver("sftp",$ip,$port)) { + 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("$sshpid $pid2"); $doesntrun{$pidfile} = 1; return (0,0); } - $pid2 = $pid3 if($pid2 <= 0); if($verbose) { logmsg "RUN: SSH server is now running PID $pid2\n"; diff --git a/tests/sshhelp.pm b/tests/sshhelp.pm index b76c42dcf..7cd4b5c55 100644 --- a/tests/sshhelp.pm +++ b/tests/sshhelp.pm @@ -37,13 +37,17 @@ use vars qw( @EXPORT_OK $sshdexe $sshexe + $sftpsrvexe $sftpexe $sshkeygenexe $sshdconfig $sshconfig + $sftpconfig $knownhosts $sshdlog $sshlog + $sftplog + $sftpcmds $hstprvkeyf $hstpubkeyf $cliprvkeyf @@ -64,24 +68,31 @@ use vars qw( @EXPORT_OK = qw( $sshdexe $sshexe + $sftpsrvexe $sftpexe $sshkeygenexe $sshdconfig $sshconfig + $sftpconfig $knownhosts $sshdlog $sshlog + $sftplog + $sftpcmds $hstprvkeyf $hstpubkeyf $cliprvkeyf $clipubkeyf display_sshdconfig display_sshconfig + display_sftpconfig display_sshdlog display_sshlog + display_sftplog dump_array find_sshd find_ssh + find_sftpsrv find_sftp find_sshkeygen logmsg @@ -94,12 +105,16 @@ use vars qw( # $sshdexe = 'sshd' .exe_ext(); # base name and ext of ssh daemon $sshexe = 'ssh' .exe_ext(); # base name and ext of ssh client -$sftpexe = 'sftp-server' .exe_ext(); # base name and ext of sftp-server +$sftpsrvexe = 'sftp-server' .exe_ext(); # base name and ext of sftp-server +$sftpexe = 'sftp' .exe_ext(); # base name and ext of sftp client $sshkeygenexe = 'ssh-keygen' .exe_ext(); # base name and ext of ssh-keygen $sshdconfig = 'curl_sshd_config'; # ssh daemon config file $sshconfig = 'curl_ssh_config'; # ssh client config file +$sftpconfig = 'curl_sftp_config'; # sftp client config file $sshdlog = 'log/sshd.log'; # ssh daemon log file $sshlog = 'log/ssh.log'; # ssh client log file +$sftplog = 'log/sftp.log'; # sftp client log file +$sftpcmds = 'curl_sftp_cmds'; # sftp client commands batch file $knownhosts = 'curl_client_knownhosts'; # ssh knownhosts file $hstprvkeyf = 'curl_host_dsa_key'; # host private key file $hstpubkeyf = 'curl_host_dsa_key.pub'; # host public key file @@ -213,6 +228,14 @@ sub display_sshconfig { } +#*************************************************************************** +# Display contents of the sftp client config file +# +sub display_sftpconfig { + display_file($sftpconfig); +} + + #*************************************************************************** # Display contents of the ssh daemon log file # @@ -229,6 +252,14 @@ sub display_sshlog { } +#*************************************************************************** +# Display contents of the sftp client log file +# +sub display_sftplog { + display_file($sftplog); +} + + #*************************************************************************** # Find a file somewhere in the given path # @@ -276,6 +307,14 @@ sub find_ssh { #*************************************************************************** # Find sftp-server plugin and return canonical filename # +sub find_sftpsrv { + return find_sfile($sftpsrvexe); +} + + +#*************************************************************************** +# Find sftp client and return canonical filename +# sub find_sftp { return find_sfile($sftpexe); } diff --git a/tests/sshserver.pl b/tests/sshserver.pl index e94125343..3eb57a643 100644 --- a/tests/sshserver.pl +++ b/tests/sshserver.pl @@ -44,24 +44,31 @@ use Cwd; use sshhelp qw( $sshdexe $sshexe + $sftpsrvexe $sftpexe $sshkeygenexe $sshdconfig $sshconfig + $sftpconfig $knownhosts $sshdlog $sshlog + $sftplog + $sftpcmds $hstprvkeyf $hstpubkeyf $cliprvkeyf $clipubkeyf display_sshdconfig display_sshconfig + display_sftpconfig display_sshdlog display_sshlog + display_sftplog dump_array find_sshd find_ssh + find_sftpsrv find_sftp find_sshkeygen logmsg @@ -193,12 +200,23 @@ if((($sshdid =~ /OpenSSH/) && ($sshdvernum < 299)) || #*************************************************************************** # Find out sftp server plugin canonical file name # +my $sftpsrv = find_sftpsrv(); +if(!$sftpsrv) { + logmsg "cannot find $sftpsrvexe"; + exit 1; +} +logmsg "sftp server plugin found $sftpsrv" if($verbose); + + +#*************************************************************************** +# Find out sftp client canonical file name +# my $sftp = find_sftp(); if(!$sftp) { logmsg "cannot find $sftpexe"; exit 1; } -logmsg "sftp server plugin found $sftp" if($verbose); +logmsg "sftp client found $sftp" if($verbose); #*************************************************************************** @@ -428,7 +446,7 @@ push @cfgarr, 'RhostsRSAAuthentication no'; push @cfgarr, 'RSAAuthentication no'; push @cfgarr, 'ServerKeyBits 768'; push @cfgarr, 'StrictModes no'; -push @cfgarr, "Subsystem sftp $sftp"; +push @cfgarr, "Subsystem sftp $sftpsrv -f AUTH -l $loglevel"; push @cfgarr, 'SyslogFacility AUTH'; push @cfgarr, 'UseLogin no'; push @cfgarr, 'X11Forwarding no'; @@ -861,12 +879,55 @@ if($error) { logmsg $error; exit 1; } + + +#*************************************************************************** +# Initialize client sftp config with options actually supported. +# +logmsg 'generating sftp client config file...' if($verbose); +splice @cfgarr, 1, 1, "# $sshverstr sftp client configuration file for curl testing"; +# +for(my $i = scalar(@cfgarr) - 1; $i > 0; $i--) { + if($cfgarr[$i] =~ /^DynamicForward/) { + splice @cfgarr, $i, 1; + next; + } + if($cfgarr[$i] =~ /^ClearAllForwardings/) { + splice @cfgarr, $i, 1, "ClearAllForwardings yes"; + next; + } +} + + +#*************************************************************************** +# Write out resulting sftp client configuration file for curl's tests +# +$error = dump_array($sftpconfig, @cfgarr); +if($error) { + logmsg $error; + exit 1; +} +@cfgarr = (); + + +#*************************************************************************** +# Generate client sftp commands batch file for sftp server verification +# +logmsg 'generating sftp client commands file...' if($verbose); +push @cfgarr, 'pwd'; +push @cfgarr, 'quit'; +$error = dump_array($sftpcmds, @cfgarr); +if($error) { + logmsg $error; + exit 1; +} @cfgarr = (); #*************************************************************************** # Start the ssh server daemon without forking it # +logmsg "SCP/SFTP server listening on port $port" if($verbose); my $rc = system "$sshd -e -D -f $sshdconfig > $sshdlog 2>&1"; if($rc == -1) { logmsg "$sshd failed with: $!"; @@ -884,7 +945,7 @@ elsif($verbose && ($rc >> 8)) { # Clean up once the server has stopped # unlink($hstprvkeyf, $hstpubkeyf, $cliprvkeyf, $clipubkeyf, $knownhosts); -unlink($sshdconfig, $sshconfig); +unlink($sshdconfig, $sshconfig, $sftpconfig); exit 0;