]> CyberLeo.Net >> Repos - FreeBSD/releng/10.3.git/blob - crypto/openssh/regress/test-exec.sh
- Copy stable/10@296371 to releng/10.3 in preparation for 10.3-RC1
[FreeBSD/releng/10.3.git] / crypto / openssh / regress / test-exec.sh
1 #       $OpenBSD: test-exec.sh,v 1.51 2015/03/03 22:35:19 markus Exp $
2 #       Placed in the Public Domain.
3
4 #SUDO=sudo
5
6 # Unbreak GNU head(1)
7 _POSIX2_VERSION=199209
8 export _POSIX2_VERSION
9
10 case `uname -s 2>/dev/null` in
11 OSF1*)
12         BIN_SH=xpg4
13         export BIN_SH
14         ;;
15 CYGWIN_NT-5.0)
16         os=cygwin
17         TEST_SSH_IPV6=no
18         ;;
19 CYGWIN*)
20         os=cygwin
21         ;;
22 esac
23
24 if [ ! -z "$TEST_SSH_PORT" ]; then
25         PORT="$TEST_SSH_PORT"
26 else
27         PORT=4242
28 fi
29
30 if [ -x /usr/ucb/whoami ]; then
31         USER=`/usr/ucb/whoami`
32 elif whoami >/dev/null 2>&1; then
33         USER=`whoami`
34 elif logname >/dev/null 2>&1; then
35         USER=`logname`
36 else
37         USER=`id -un`
38 fi
39
40 OBJ=$1
41 if [ "x$OBJ" = "x" ]; then
42         echo '$OBJ not defined'
43         exit 2
44 fi
45 if [ ! -d $OBJ ]; then
46         echo "not a directory: $OBJ"
47         exit 2
48 fi
49 SCRIPT=$2
50 if [ "x$SCRIPT" = "x" ]; then
51         echo '$SCRIPT not defined'
52         exit 2
53 fi
54 if [ ! -f $SCRIPT ]; then
55         echo "not a file: $SCRIPT"
56         exit 2
57 fi
58 if $TEST_SHELL -n $SCRIPT; then
59         true
60 else
61         echo "syntax error in $SCRIPT"
62         exit 2
63 fi
64 unset SSH_AUTH_SOCK
65
66 SRC=`dirname ${SCRIPT}`
67
68 # defaults
69 SSH=ssh
70 SSHD=sshd
71 SSHAGENT=ssh-agent
72 SSHADD=ssh-add
73 SSHKEYGEN=ssh-keygen
74 SSHKEYSCAN=ssh-keyscan
75 SFTP=sftp
76 SFTPSERVER=/usr/libexec/openssh/sftp-server
77 SCP=scp
78
79 # Interop testing
80 PLINK=plink
81 PUTTYGEN=puttygen
82 CONCH=conch
83
84 if [ "x$TEST_SSH_SSH" != "x" ]; then
85         SSH="${TEST_SSH_SSH}"
86 fi
87 if [ "x$TEST_SSH_SSHD" != "x" ]; then
88         SSHD="${TEST_SSH_SSHD}"
89 fi
90 if [ "x$TEST_SSH_SSHAGENT" != "x" ]; then
91         SSHAGENT="${TEST_SSH_SSHAGENT}"
92 fi
93 if [ "x$TEST_SSH_SSHADD" != "x" ]; then
94         SSHADD="${TEST_SSH_SSHADD}"
95 fi
96 if [ "x$TEST_SSH_SSHKEYGEN" != "x" ]; then
97         SSHKEYGEN="${TEST_SSH_SSHKEYGEN}"
98 fi
99 if [ "x$TEST_SSH_SSHKEYSCAN" != "x" ]; then
100         SSHKEYSCAN="${TEST_SSH_SSHKEYSCAN}"
101 fi
102 if [ "x$TEST_SSH_SFTP" != "x" ]; then
103         SFTP="${TEST_SSH_SFTP}"
104 fi
105 if [ "x$TEST_SSH_SFTPSERVER" != "x" ]; then
106         SFTPSERVER="${TEST_SSH_SFTPSERVER}"
107 fi
108 if [ "x$TEST_SSH_SCP" != "x" ]; then
109         SCP="${TEST_SSH_SCP}"
110 fi
111 if [ "x$TEST_SSH_PLINK" != "x" ]; then
112         # Find real binary, if it exists
113         case "${TEST_SSH_PLINK}" in
114         /*) PLINK="${TEST_SSH_PLINK}" ;;
115         *) PLINK=`which ${TEST_SSH_PLINK} 2>/dev/null` ;;
116         esac
117 fi
118 if [ "x$TEST_SSH_PUTTYGEN" != "x" ]; then
119         # Find real binary, if it exists
120         case "${TEST_SSH_PUTTYGEN}" in
121         /*) PUTTYGEN="${TEST_SSH_PUTTYGEN}" ;;
122         *) PUTTYGEN=`which ${TEST_SSH_PUTTYGEN} 2>/dev/null` ;;
123         esac
124 fi
125 if [ "x$TEST_SSH_CONCH" != "x" ]; then
126         # Find real binary, if it exists
127         case "${TEST_SSH_CONCH}" in
128         /*) CONCH="${TEST_SSH_CONCH}" ;;
129         *) CONCH=`which ${TEST_SSH_CONCH} 2>/dev/null` ;;
130         esac
131 fi
132
133 SSH_PROTOCOLS=`$SSH -Q protocol-version`
134 if [ "x$TEST_SSH_PROTOCOLS" != "x" ]; then
135         SSH_PROTOCOLS="${TEST_SSH_PROTOCOLS}"
136 fi
137
138 # Path to sshd must be absolute for rexec
139 case "$SSHD" in
140 /*) ;;
141 *) SSHD=`which $SSHD` ;;
142 esac
143
144 case "$SSHAGENT" in
145 /*) ;;
146 *) SSHAGENT=`which $SSHAGENT` ;;
147 esac
148
149 # Record the actual binaries used.
150 SSH_BIN=${SSH}
151 SSHD_BIN=${SSHD}
152 SSHAGENT_BIN=${SSHAGENT}
153 SSHADD_BIN=${SSHADD}
154 SSHKEYGEN_BIN=${SSHKEYGEN}
155 SSHKEYSCAN_BIN=${SSHKEYSCAN}
156 SFTP_BIN=${SFTP}
157 SFTPSERVER_BIN=${SFTPSERVER}
158 SCP_BIN=${SCP}
159
160 if [ "x$USE_VALGRIND" != "x" ]; then
161         mkdir -p $OBJ/valgrind-out
162         VG_TEST=`basename $SCRIPT .sh`
163
164         # Some tests are difficult to fix.
165         case "$VG_TEST" in
166         connect-privsep|reexec)
167                 VG_SKIP=1 ;;
168         esac
169
170         if [ x"$VG_SKIP" = "x" ]; then
171                 VG_IGNORE="/bin/*,/sbin/*,/usr/*,/var/*"
172                 VG_LOG="$OBJ/valgrind-out/${VG_TEST}."
173                 VG_OPTS="--track-origins=yes --leak-check=full"
174                 VG_OPTS="$VG_OPTS --trace-children=yes"
175                 VG_OPTS="$VG_OPTS --trace-children-skip=${VG_IGNORE}"
176                 VG_PATH="valgrind"
177                 if [ "x$VALGRIND_PATH" != "x" ]; then
178                         VG_PATH="$VALGRIND_PATH"
179                 fi
180                 VG="$VG_PATH $VG_OPTS"
181                 SSH="$VG --log-file=${VG_LOG}ssh.%p $SSH"
182                 SSHD="$VG --log-file=${VG_LOG}sshd.%p $SSHD"
183                 SSHAGENT="$VG --log-file=${VG_LOG}ssh-agent.%p $SSHAGENT"
184                 SSHADD="$VG --log-file=${VG_LOG}ssh-add.%p $SSHADD"
185                 SSHKEYGEN="$VG --log-file=${VG_LOG}ssh-keygen.%p $SSHKEYGEN"
186                 SSHKEYSCAN="$VG --log-file=${VG_LOG}ssh-keyscan.%p $SSHKEYSCAN"
187                 SFTP="$VG --log-file=${VG_LOG}sftp.%p ${SFTP}"
188                 SCP="$VG --log-file=${VG_LOG}scp.%p $SCP"
189                 cat > $OBJ/valgrind-sftp-server.sh << EOF
190 #!/bin/sh
191 exec $VG --log-file=${VG_LOG}sftp-server.%p $SFTPSERVER "\$@"
192 EOF
193                 chmod a+rx $OBJ/valgrind-sftp-server.sh
194                 SFTPSERVER="$OBJ/valgrind-sftp-server.sh"
195         fi
196 fi
197
198 # Logfiles.
199 # SSH_LOGFILE should be the debug output of ssh(1) only
200 # SSHD_LOGFILE should be the debug output of sshd(8) only
201 # REGRESS_LOGFILE is the output of the test itself stdout and stderr
202 if [ "x$TEST_SSH_LOGFILE" = "x" ]; then
203         TEST_SSH_LOGFILE=$OBJ/ssh.log
204 fi
205 if [ "x$TEST_SSHD_LOGFILE" = "x" ]; then
206         TEST_SSHD_LOGFILE=$OBJ/sshd.log
207 fi
208 if [ "x$TEST_REGRESS_LOGFILE" = "x" ]; then
209         TEST_REGRESS_LOGFILE=$OBJ/regress.log
210 fi
211
212 # truncate logfiles
213 >$TEST_SSH_LOGFILE
214 >$TEST_SSHD_LOGFILE
215 >$TEST_REGRESS_LOGFILE
216
217 # Create wrapper ssh with logging.  We can't just specify "SSH=ssh -E..."
218 # because sftp and scp don't handle spaces in arguments.
219 SSHLOGWRAP=$OBJ/ssh-log-wrapper.sh
220 echo "#!/bin/sh" > $SSHLOGWRAP
221 echo "exec ${SSH} -E${TEST_SSH_LOGFILE} "'"$@"' >>$SSHLOGWRAP
222
223 chmod a+rx $OBJ/ssh-log-wrapper.sh
224 SSH="$SSHLOGWRAP"
225
226 # Some test data.  We make a copy because some tests will overwrite it.
227 # The tests may assume that $DATA exists and is writable and $COPY does
228 # not exist.  Tests requiring larger data files can call increase_datafile_size
229 # [kbytes] to ensure the file is at least that large.
230 DATANAME=data
231 DATA=$OBJ/${DATANAME}
232 cat ${SSHAGENT_BIN} >${DATA}
233 chmod u+w ${DATA}
234 COPY=$OBJ/copy
235 rm -f ${COPY}
236
237 increase_datafile_size()
238 {
239         while [ `du -k ${DATA} | cut -f1` -lt $1 ]; do
240                 cat ${SSHAGENT_BIN} >>${DATA}
241         done
242 }
243
244 # these should be used in tests
245 export SSH SSHD SSHAGENT SSHADD SSHKEYGEN SSHKEYSCAN SFTP SFTPSERVER SCP
246 #echo $SSH $SSHD $SSHAGENT $SSHADD $SSHKEYGEN $SSHKEYSCAN $SFTP $SFTPSERVER $SCP
247
248 # Portable specific functions
249 have_prog()
250 {
251         saved_IFS="$IFS"
252         IFS=":"
253         for i in $PATH
254         do
255                 if [ -x $i/$1 ]; then
256                         IFS="$saved_IFS"
257                         return 0
258                 fi
259         done
260         IFS="$saved_IFS"
261         return 1
262 }
263
264 jot() {
265         awk "BEGIN { for (i = $2; i < $2 + $1; i++) { printf \"%d\n\", i } exit }"
266 }
267
268 # Check whether preprocessor symbols are defined in config.h.
269 config_defined ()
270 {
271         str=$1
272         while test "x$2" != "x" ; do
273                 str="$str|$2"
274                 shift
275         done
276         egrep "^#define.*($str)" ${BUILDDIR}/config.h >/dev/null 2>&1
277 }
278
279 md5 () {
280         if have_prog md5sum; then
281                 md5sum
282         elif have_prog openssl; then
283                 openssl md5
284         elif have_prog cksum; then
285                 cksum
286         elif have_prog sum; then
287                 sum
288         else
289                 wc -c
290         fi
291 }
292 # End of portable specific functions
293
294 # helper
295 cleanup ()
296 {
297         if [ "x$SSH_PID" != "x" ]; then
298                 if [ $SSH_PID -lt 2 ]; then
299                         echo bad pid for ssh: $SSH_PID
300                 else
301                         kill $SSH_PID
302                 fi
303         fi
304         if [ -f $PIDFILE ]; then
305                 pid=`$SUDO cat $PIDFILE`
306                 if [ "X$pid" = "X" ]; then
307                         echo no sshd running
308                 else
309                         if [ $pid -lt 2 ]; then
310                                 echo bad pid for sshd: $pid
311                         else
312                                 $SUDO kill $pid
313                                 trace "wait for sshd to exit"
314                                 i=0;
315                                 while [ -f $PIDFILE -a $i -lt 5 ]; do
316                                         i=`expr $i + 1`
317                                         sleep $i
318                                 done
319                                 test -f $PIDFILE && \
320                                     fatal "sshd didn't exit port $PORT pid $pid"
321                         fi
322                 fi
323         fi
324 }
325
326 start_debug_log ()
327 {
328         echo "trace: $@" >$TEST_REGRESS_LOGFILE
329         echo "trace: $@" >$TEST_SSH_LOGFILE
330         echo "trace: $@" >$TEST_SSHD_LOGFILE
331 }
332
333 save_debug_log ()
334 {
335         echo $@ >>$TEST_REGRESS_LOGFILE
336         echo $@ >>$TEST_SSH_LOGFILE
337         echo $@ >>$TEST_SSHD_LOGFILE
338         (cat $TEST_REGRESS_LOGFILE; echo) >>$OBJ/failed-regress.log
339         (cat $TEST_SSH_LOGFILE; echo) >>$OBJ/failed-ssh.log
340         (cat $TEST_SSHD_LOGFILE; echo) >>$OBJ/failed-sshd.log
341 }
342
343 trace ()
344 {
345         start_debug_log $@
346         if [ "X$TEST_SSH_TRACE" = "Xyes" ]; then
347                 echo "$@"
348         fi
349 }
350
351 verbose ()
352 {
353         start_debug_log $@
354         if [ "X$TEST_SSH_QUIET" != "Xyes" ]; then
355                 echo "$@"
356         fi
357 }
358
359 warn ()
360 {
361         echo "WARNING: $@" >>$TEST_SSH_LOGFILE
362         echo "WARNING: $@"
363 }
364
365 fail ()
366 {
367         save_debug_log "FAIL: $@"
368         RESULT=1
369         echo "$@"
370
371 }
372
373 fatal ()
374 {
375         save_debug_log "FATAL: $@"
376         printf "FATAL: "
377         fail "$@"
378         cleanup
379         exit $RESULT
380 }
381
382 ssh_version ()
383 {
384         echo ${SSH_PROTOCOLS} | grep "$1" >/dev/null
385 }
386
387 RESULT=0
388 PIDFILE=$OBJ/pidfile
389
390 trap fatal 3 2
391
392 if ssh_version 1; then
393         PROTO="2,1"
394 else
395         PROTO="2"
396 fi
397
398 # create server config
399 cat << EOF > $OBJ/sshd_config
400         StrictModes             no
401         Port                    $PORT
402         Protocol                $PROTO
403         AddressFamily           inet
404         ListenAddress           127.0.0.1
405         #ListenAddress          ::1
406         PidFile                 $PIDFILE
407         AuthorizedKeysFile      $OBJ/authorized_keys_%u
408         LogLevel                DEBUG3
409         AcceptEnv               _XXX_TEST_*
410         AcceptEnv               _XXX_TEST
411         Subsystem       sftp    $SFTPSERVER
412 EOF
413
414 if [ ! -z "$TEST_SSH_SSHD_CONFOPTS" ]; then
415         trace "adding sshd_config option $TEST_SSH_SSHD_CONFOPTS"
416         echo "$TEST_SSH_SSHD_CONFOPTS" >> $OBJ/sshd_config
417 fi
418
419 # server config for proxy connects
420 cp $OBJ/sshd_config $OBJ/sshd_proxy
421
422 # allow group-writable directories in proxy-mode
423 echo 'StrictModes no' >> $OBJ/sshd_proxy
424
425 # create client config
426 cat << EOF > $OBJ/ssh_config
427 Host *
428         Protocol                $PROTO
429         Hostname                127.0.0.1
430         HostKeyAlias            localhost-with-alias
431         Port                    $PORT
432         User                    $USER
433         GlobalKnownHostsFile    $OBJ/known_hosts
434         UserKnownHostsFile      $OBJ/known_hosts
435         RSAAuthentication       yes
436         PubkeyAuthentication    yes
437         ChallengeResponseAuthentication no
438         HostbasedAuthentication no
439         PasswordAuthentication  no
440         RhostsRSAAuthentication no
441         BatchMode               yes
442         StrictHostKeyChecking   yes
443         LogLevel                DEBUG3
444 EOF
445
446 if [ ! -z "$TEST_SSH_SSH_CONFOPTS" ]; then
447         trace "adding ssh_config option $TEST_SSH_SSH_CONFOPTS"
448         echo "$TEST_SSH_SSH_CONFOPTS" >> $OBJ/ssh_config
449 fi
450
451 rm -f $OBJ/known_hosts $OBJ/authorized_keys_$USER
452
453 if ssh_version 1; then
454         SSH_KEYTYPES="rsa rsa1"
455 else
456         SSH_KEYTYPES="rsa ed25519"
457 fi
458 trace "generate keys"
459 for t in ${SSH_KEYTYPES}; do
460         # generate user key
461         if [ ! -f $OBJ/$t ] || [ ${SSHKEYGEN_BIN} -nt $OBJ/$t ]; then
462                 rm -f $OBJ/$t
463                 ${SSHKEYGEN} -q -N '' -t $t  -f $OBJ/$t ||\
464                         fail "ssh-keygen for $t failed"
465         fi
466
467         # known hosts file for client
468         (
469                 printf 'localhost-with-alias,127.0.0.1,::1 '
470                 cat $OBJ/$t.pub
471         ) >> $OBJ/known_hosts
472
473         # setup authorized keys
474         cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER
475         echo IdentityFile $OBJ/$t >> $OBJ/ssh_config
476
477         # use key as host key, too
478         $SUDO cp $OBJ/$t $OBJ/host.$t
479         echo HostKey $OBJ/host.$t >> $OBJ/sshd_config
480
481         # don't use SUDO for proxy connect
482         echo HostKey $OBJ/$t >> $OBJ/sshd_proxy
483 done
484 chmod 644 $OBJ/authorized_keys_$USER
485
486 # Activate Twisted Conch tests if the binary is present
487 REGRESS_INTEROP_CONCH=no
488 if test -x "$CONCH" ; then
489         REGRESS_INTEROP_CONCH=yes
490 fi
491
492 # If PuTTY is present and we are running a PuTTY test, prepare keys and
493 # configuration
494 REGRESS_INTEROP_PUTTY=no
495 if test -x "$PUTTYGEN" -a -x "$PLINK" ; then
496         REGRESS_INTEROP_PUTTY=yes
497 fi
498 case "$SCRIPT" in
499 *putty*)        ;;
500 *)              REGRESS_INTEROP_PUTTY=no ;;
501 esac
502
503 if test "$REGRESS_INTEROP_PUTTY" = "yes" ; then
504         mkdir -p ${OBJ}/.putty
505
506         # Add a PuTTY key to authorized_keys
507         rm -f ${OBJ}/putty.rsa2
508         puttygen -t rsa -o ${OBJ}/putty.rsa2 < /dev/null > /dev/null
509         puttygen -O public-openssh ${OBJ}/putty.rsa2 \
510             >> $OBJ/authorized_keys_$USER
511
512         # Convert rsa2 host key to PuTTY format
513         ${SRC}/ssh2putty.sh 127.0.0.1 $PORT $OBJ/rsa > \
514             ${OBJ}/.putty/sshhostkeys
515         ${SRC}/ssh2putty.sh 127.0.0.1 22 $OBJ/rsa >> \
516             ${OBJ}/.putty/sshhostkeys
517
518         # Setup proxied session
519         mkdir -p ${OBJ}/.putty/sessions
520         rm -f ${OBJ}/.putty/sessions/localhost_proxy
521         echo "Hostname=127.0.0.1" >> ${OBJ}/.putty/sessions/localhost_proxy
522         echo "PortNumber=$PORT" >> ${OBJ}/.putty/sessions/localhost_proxy
523         echo "ProxyMethod=5" >> ${OBJ}/.putty/sessions/localhost_proxy
524         echo "ProxyTelnetCommand=sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy" >> ${OBJ}/.putty/sessions/localhost_proxy
525
526         REGRESS_INTEROP_PUTTY=yes
527 fi
528
529 # create a proxy version of the client config
530 (
531         cat $OBJ/ssh_config
532         echo proxycommand ${SUDO} sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy
533 ) > $OBJ/ssh_proxy
534
535 # check proxy config
536 ${SSHD} -t -f $OBJ/sshd_proxy   || fatal "sshd_proxy broken"
537
538 start_sshd ()
539 {
540         # start sshd
541         $SUDO ${SSHD} -f $OBJ/sshd_config "$@" -t || fatal "sshd_config broken"
542         $SUDO ${SSHD} -f $OBJ/sshd_config "$@" -E$TEST_SSHD_LOGFILE
543
544         trace "wait for sshd"
545         i=0;
546         while [ ! -f $PIDFILE -a $i -lt 10 ]; do
547                 i=`expr $i + 1`
548                 sleep $i
549         done
550
551         test -f $PIDFILE || fatal "no sshd running on port $PORT"
552 }
553
554 # source test body
555 . $SCRIPT
556
557 # kill sshd
558 cleanup
559 if [ $RESULT -eq 0 ]; then
560         verbose ok $tid
561 else
562         echo failed $tid
563 fi
564 exit $RESULT