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