Renamed the sshd log file to sshd.log.
[platform/upstream/curl.git] / tests / sshserver.pl
1 #/usr/bin/env perl
2 # $Id$
3 # Starts sshd for use in the SCP, SFTP and SOCKS curl test harness tests.
4 # Also creates the ssh configuration files (this could be moved to a
5 # separate script).
6
7 # Options:
8 # -u user
9 # -v
10 # target_port
11
12 use strict;
13 use File::Spec;
14
15 my $verbose=0; # set to 1 for debugging
16
17 my $port = 8999;        # just our default, weird enough
18
19 my $path = `pwd`;
20 chomp $path;
21
22 my $exeext;
23 if ($^O eq 'MSWin32' || $^O eq 'cygwin' || $^O eq 'msys' || $^O eq 'dos' || $^O eq 'os2') {
24     $exeext = '.exe';
25 }
26
27 # Where to look for sftp-server
28 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 /usr/lib64/misc);
29
30 my $username = $ENV{USER};
31
32 # Find a file somewhere in the given path
33 sub searchpath {
34   my $fn = $_[0] . $exeext;
35   shift;
36   my @path = @_;
37   foreach (@path) {
38       my $file = File::Spec->catfile($_, $fn);
39       if (-e $file) {
40           return $file;
41       }
42   }
43 }
44
45 # Parse options
46 do {
47     if($ARGV[0] eq "-v") {
48         $verbose=1;
49     }
50     elsif($ARGV[0] eq "-u") {
51         $username=$ARGV[1];
52         shift @ARGV;
53     }
54     elsif($ARGV[0] =~ /^(\d+)$/) {
55         $port = $1;
56     }
57 } while(shift @ARGV);
58
59 my $conffile="curl_sshd_config";    # sshd configuration data
60 my $conffile_ssh="curl_ssh_config";    # ssh configuration data
61 my $knownhostsfile="curl_client_knownhosts";    # ssh knownhosts file
62
63 # Searching for sshd and sftp-server will be done first
64 # in the PATH and afterwards in other common locations.
65 my @spath;
66 push(@spath, File::Spec->path()); 
67 push(@spath, @sftppath); 
68
69 # sshd insists on being called with an absolute path.
70 my $sshd = searchpath("sshd", @spath);
71 if (!$sshd) {
72     print "sshd$exeext not found\n";
73     exit 1;
74 }
75 if ($verbose) {
76     print STDERR "SSH server found at $sshd\n";
77 }
78
79 my $sftp = searchpath("sftp-server", @spath);
80 if (!$sftp) {
81     print "Could not find sftp-server$exeext plugin\n";
82     exit 1;
83 }
84 if ($verbose) {
85     print STDERR "SFTP server plugin found at $sftp\n";
86 }
87
88 if ($username eq "root") {
89     print "Will not run ssh daemon as root to mitigate security risks\n";
90     exit 1;
91 }
92
93 # Find out sshd version.
94 my $tmpstr;
95 my $ssh_daemon;
96 my $ssh_ver_major;
97 my $ssh_ver_minor;
98 my $ssh_ver_patch;
99 chomp($tmpstr = qx($sshd -V 2>&1 | grep OpenSSH));
100 if ($tmpstr =~ /OpenSSH[_-](\d+)\.(\d+)(\.(\d+))*/) {
101     ($ssh_ver_major, $ssh_ver_minor, $ssh_ver_patch) = ($1, $2, $4);
102     $ssh_daemon = 'OpenSSH';
103 }
104 if ($verbose) {
105     print STDERR "ssh_daemon: $ssh_daemon\n";
106     print STDERR "ssh_ver_major: $ssh_ver_major\n";
107     print STDERR "ssh_ver_minor: $ssh_ver_minor\n";
108     print STDERR "ssh_ver_patch: $ssh_ver_patch\n";
109 }
110
111 # Verify minimum OpenSSH version.
112 if (($ssh_daemon !~ /OpenSSH/) || (10 * $ssh_ver_major + $ssh_ver_minor < 37)) {
113     print "SCP, SFTP and SOCKS tests require OpenSSH 3.7 or later\n";
114     exit 1;
115 }
116
117 # Initialize sshd configuration file for curl's tests.
118 open(CONF, ">$conffile") || die "Could not write $conffile";
119 print CONF "# This is a generated file!  Do not edit!\n";
120 print CONF "# OpenSSH sshd configuration file for curl testing\n";
121 close CONF;
122
123 # Support for some options might have not been built into sshd.  On some
124 # platforms specifying an unsupported option prevents sshd from starting.
125 # Check here for possible unsupported options, avoiding its use in sshd.
126 sub sshd_supports_opt($) {
127     my ($option) = @_;
128     my $err = grep /Unsupported .* $option/, qx($sshd -t -f $conffile -o $option=no 2>&1);
129     return !$err;
130 }
131
132 my $supports_UsePAM = sshd_supports_opt('UsePAM');
133 my $supports_UseDNS = sshd_supports_opt('UseDNS');
134 my $supports_ChReAu = sshd_supports_opt('ChallengeResponseAuthentication');
135 if ($verbose) {
136     print STDERR "sshd supports UsePAM: ";
137     print STDERR $supports_UsePAM ? "yes\n" : "no\n";
138     print STDERR "sshd supports UseDNS: ";
139     print STDERR $supports_UseDNS ? "yes\n" : "no\n";
140     print STDERR "sshd supports ChallengeResponseAuthentication: ";
141     print STDERR $supports_ChReAu ? "yes\n" : "no\n";
142 }
143
144 if (! -e "curl_client_key.pub") {
145     if ($verbose) {
146         print STDERR "Generating host and client keys...\n";
147     }
148     # Make sure all files are gone so ssh-keygen doesn't complain
149     unlink("curl_host_dsa_key", "curl_client_key","curl_host_dsa_key.pub", "curl_client_key.pub"); 
150     system "ssh-keygen -q -t dsa -f curl_host_dsa_key -C 'curl test server' -N ''" and die "Could not generate key";
151     system "ssh-keygen -q -t dsa -f curl_client_key -C 'curl test client' -N ''" and die "Could not generate key";
152 }
153
154 open(FILE, ">>", $conffile) || die "Could not write $conffile";
155 print FILE <<EOFSSHD
156 AllowUsers $username
157 DenyUsers
158 DenyGroups
159 AuthorizedKeysFile $path/curl_client_key.pub
160 HostKey $path/curl_host_dsa_key
161 PidFile $path/.ssh.pid
162 Port $port
163 ListenAddress localhost
164 Protocol 2
165 AllowTcpForwarding yes
166 GatewayPorts no
167 HostbasedAuthentication no
168 IgnoreRhosts yes
169 IgnoreUserKnownHosts yes
170 KeepAlive no
171 PasswordAuthentication no
172 PermitEmptyPasswords no
173 PermitUserEnvironment no
174 PermitRootLogin no
175 PrintLastLog no
176 PrintMotd no
177 StrictModes no
178 Subsystem sftp $sftp
179 UseLogin no
180 PrintLastLog no
181 X11Forwarding no
182 UsePrivilegeSeparation no
183 # Newer OpenSSH options
184 EOFSSHD
185 ;
186 close FILE ||  die "Could not close $conffile";
187
188 sub set_sshd_option {
189     my ($string) = @_;
190     if (open(FILE, ">>$conffile")) {
191         print FILE "$string\n";
192         close FILE;
193     }
194 }
195
196 if ($supports_UsePAM) {
197     set_sshd_option('UsePAM no');
198 }
199 if ($supports_UseDNS) {
200     set_sshd_option('UseDNS no');
201 }
202 if ($supports_ChReAu) {
203     set_sshd_option('ChallengeResponseAuthentication no');
204 }
205
206
207 # Now, set up some configuration files for the ssh client
208 open(DSAKEYFILE, "<", "curl_host_dsa_key.pub") || die 'Could not read curl_host_dsa_key.pub';
209 my @dsahostkey = do { local $/ = ' '; <DSAKEYFILE> };
210 close DSAKEYFILE || die "Could not close RSAKEYFILE";
211
212 open(RSAKEYFILE, "<", "curl_host_dsa_key.pub") || die 'Could not read curl_host_dsa_key.pub';
213 my @rsahostkey = do { local $/ = ' '; <RSAKEYFILE> };
214 close RSAKEYFILE || die "Could not close RSAKEYFILE";
215
216 open(KNOWNHOSTS, ">", $knownhostsfile) || die "Could not write $knownhostsfile";
217 print KNOWNHOSTS "[127.0.0.1]:$port ssh-dss $dsahostkey[1]\n" || die 'Could not write to KNOWNHOSTS';
218 print KNOWNHOSTS "[127.0.0.1]:$port ssh-rsa $rsahostkey[1]\n" || die 'Could not write to KNOWNHOSTS';
219 close KNOWNHOSTS || die "Could not close KNOWNHOSTS";
220
221 open(SSHFILE, ">", $conffile_ssh) || die "Could not write $conffile_ssh";
222 print SSHFILE <<EOFSSH
223 IdentityFile $path/curl_client_key
224 UserKnownHostsFile $path/$knownhostsfile
225 StrictHostKeyChecking no
226 Protocol 2
227 BatchMode yes
228 CheckHostIP no
229 Compression no
230 ConnectTimeout 20
231 ForwardX11 no
232 HostbasedAuthentication yes
233 NoHostAuthenticationForLocalhost no
234 # Newer OpenSSH options
235 #SetupTimeOut 20
236 EOFSSH
237 ;
238 close SSHFILE ||  die "Could not close $conffile_ssh";
239
240
241 if (system "$sshd -t -q -f $conffile") {
242     # This is likely due to missing support for UsePam
243     print "$sshd is too old and is not supported\n";
244     unlink $conffile;
245     exit 1;
246 }
247
248 # Start the server
249 my $rc = system "$sshd -e -D -f $conffile > log/sshd.log 2>&1";
250 $rc >>= 8;
251 if($rc && $verbose) {
252     print STDERR "$sshd exited with $rc!\n";
253 }
254
255 unlink $conffile;
256
257 exit $rc;