]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - crypto/openssh/regress/test-exec.sh
Upgrade to OpenSSH 7.4p1.
[FreeBSD/FreeBSD.git] / crypto / openssh / regress / test-exec.sh
1 #       $OpenBSD: test-exec.sh,v 1.58 2016/12/16 01:06:27 dtucker 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=2
134 #SSH_PROTOCOLS=`$SSH -Q protocol-version`
135 if [ "x$TEST_SSH_PROTOCOLS" != "x" ]; then
136         SSH_PROTOCOLS="${TEST_SSH_PROTOCOLS}"
137 fi
138
139 # Path to sshd must be absolute for rexec
140 case "$SSHD" in
141 /*) ;;
142 *) SSHD=`which $SSHD` ;;
143 esac
144
145 case "$SSHAGENT" in
146 /*) ;;
147 *) SSHAGENT=`which $SSHAGENT` ;;
148 esac
149
150 # Record the actual binaries used.
151 SSH_BIN=${SSH}
152 SSHD_BIN=${SSHD}
153 SSHAGENT_BIN=${SSHAGENT}
154 SSHADD_BIN=${SSHADD}
155 SSHKEYGEN_BIN=${SSHKEYGEN}
156 SSHKEYSCAN_BIN=${SSHKEYSCAN}
157 SFTP_BIN=${SFTP}
158 SFTPSERVER_BIN=${SFTPSERVER}
159 SCP_BIN=${SCP}
160
161 if [ "x$USE_VALGRIND" != "x" ]; then
162         mkdir -p $OBJ/valgrind-out
163         VG_TEST=`basename $SCRIPT .sh`
164
165         # Some tests are difficult to fix.
166         case "$VG_TEST" in
167         connect-privsep|reexec)
168                 VG_SKIP=1 ;;
169         esac
170
171         if [ x"$VG_SKIP" = "x" ]; then
172                 VG_IGNORE="/bin/*,/sbin/*,/usr/*,/var/*"
173                 VG_LOG="$OBJ/valgrind-out/${VG_TEST}."
174                 VG_OPTS="--track-origins=yes --leak-check=full"
175                 VG_OPTS="$VG_OPTS --trace-children=yes"
176                 VG_OPTS="$VG_OPTS --trace-children-skip=${VG_IGNORE}"
177                 VG_PATH="valgrind"
178                 if [ "x$VALGRIND_PATH" != "x" ]; then
179                         VG_PATH="$VALGRIND_PATH"
180                 fi
181                 VG="$VG_PATH $VG_OPTS"
182                 SSH="$VG --log-file=${VG_LOG}ssh.%p $SSH"
183                 SSHD="$VG --log-file=${VG_LOG}sshd.%p $SSHD"
184                 SSHAGENT="$VG --log-file=${VG_LOG}ssh-agent.%p $SSHAGENT"
185                 SSHADD="$VG --log-file=${VG_LOG}ssh-add.%p $SSHADD"
186                 SSHKEYGEN="$VG --log-file=${VG_LOG}ssh-keygen.%p $SSHKEYGEN"
187                 SSHKEYSCAN="$VG --log-file=${VG_LOG}ssh-keyscan.%p $SSHKEYSCAN"
188                 SFTP="$VG --log-file=${VG_LOG}sftp.%p ${SFTP}"
189                 SCP="$VG --log-file=${VG_LOG}scp.%p $SCP"
190                 cat > $OBJ/valgrind-sftp-server.sh << EOF
191 #!/bin/sh
192 exec $VG --log-file=${VG_LOG}sftp-server.%p $SFTPSERVER "\$@"
193 EOF
194                 chmod a+rx $OBJ/valgrind-sftp-server.sh
195                 SFTPSERVER="$OBJ/valgrind-sftp-server.sh"
196         fi
197 fi
198
199 # Logfiles.
200 # SSH_LOGFILE should be the debug output of ssh(1) only
201 # SSHD_LOGFILE should be the debug output of sshd(8) only
202 # REGRESS_LOGFILE is the output of the test itself stdout and stderr
203 if [ "x$TEST_SSH_LOGFILE" = "x" ]; then
204         TEST_SSH_LOGFILE=$OBJ/ssh.log
205 fi
206 if [ "x$TEST_SSHD_LOGFILE" = "x" ]; then
207         TEST_SSHD_LOGFILE=$OBJ/sshd.log
208 fi
209 if [ "x$TEST_REGRESS_LOGFILE" = "x" ]; then
210         TEST_REGRESS_LOGFILE=$OBJ/regress.log
211 fi
212
213 # truncate logfiles
214 >$TEST_SSH_LOGFILE
215 >$TEST_SSHD_LOGFILE
216 >$TEST_REGRESS_LOGFILE
217
218 # Create wrapper ssh with logging.  We can't just specify "SSH=ssh -E..."
219 # because sftp and scp don't handle spaces in arguments.
220 SSHLOGWRAP=$OBJ/ssh-log-wrapper.sh
221 echo "#!/bin/sh" > $SSHLOGWRAP
222 echo "exec ${SSH} -E${TEST_SSH_LOGFILE} "'"$@"' >>$SSHLOGWRAP
223
224 chmod a+rx $OBJ/ssh-log-wrapper.sh
225 REAL_SSH="$SSH"
226 SSH="$SSHLOGWRAP"
227
228 # Some test data.  We make a copy because some tests will overwrite it.
229 # The tests may assume that $DATA exists and is writable and $COPY does
230 # not exist.  Tests requiring larger data files can call increase_datafile_size
231 # [kbytes] to ensure the file is at least that large.
232 DATANAME=data
233 DATA=$OBJ/${DATANAME}
234 cat ${SSHAGENT_BIN} >${DATA}
235 chmod u+w ${DATA}
236 COPY=$OBJ/copy
237 rm -f ${COPY}
238
239 increase_datafile_size()
240 {
241         while [ `du -k ${DATA} | cut -f1` -lt $1 ]; do
242                 cat ${SSHAGENT_BIN} >>${DATA}
243         done
244 }
245
246 # these should be used in tests
247 export SSH SSHD SSHAGENT SSHADD SSHKEYGEN SSHKEYSCAN SFTP SFTPSERVER SCP
248 #echo $SSH $SSHD $SSHAGENT $SSHADD $SSHKEYGEN $SSHKEYSCAN $SFTP $SFTPSERVER $SCP
249
250 # Portable specific functions
251 have_prog()
252 {
253         saved_IFS="$IFS"
254         IFS=":"
255         for i in $PATH
256         do
257                 if [ -x $i/$1 ]; then
258                         IFS="$saved_IFS"
259                         return 0
260                 fi
261         done
262         IFS="$saved_IFS"
263         return 1
264 }
265
266 jot() {
267         awk "BEGIN { for (i = $2; i < $2 + $1; i++) { printf \"%d\n\", i } exit }"
268 }
269
270 # Check whether preprocessor symbols are defined in config.h.
271 config_defined ()
272 {
273         str=$1
274         while test "x$2" != "x" ; do
275                 str="$str|$2"
276                 shift
277         done
278         egrep "^#define.*($str)" ${BUILDDIR}/config.h >/dev/null 2>&1
279 }
280
281 md5 () {
282         if have_prog md5sum; then
283                 md5sum
284         elif have_prog openssl; then
285                 openssl md5
286         elif have_prog cksum; then
287                 cksum
288         elif have_prog sum; then
289                 sum
290         else
291                 wc -c
292         fi
293 }
294 # End of portable specific functions
295
296 stop_sshd ()
297 {
298         if [ -f $PIDFILE ]; then
299                 pid=`$SUDO cat $PIDFILE`
300                 if [ "X$pid" = "X" ]; then
301                         echo no sshd running
302                 else
303                         if [ $pid -lt 2 ]; then
304                                 echo bad pid for sshd: $pid
305                         else
306                                 $SUDO kill $pid
307                                 trace "wait for sshd to exit"
308                                 i=0;
309                                 while [ -f $PIDFILE -a $i -lt 5 ]; do
310                                         i=`expr $i + 1`
311                                         sleep $i
312                                 done
313                                 test -f $PIDFILE && \
314                                     fatal "sshd didn't exit port $PORT pid $pid"
315                         fi
316                 fi
317         fi
318 }
319
320 # helper
321 cleanup ()
322 {
323         if [ "x$SSH_PID" != "x" ]; then
324                 if [ $SSH_PID -lt 2 ]; then
325                         echo bad pid for ssh: $SSH_PID
326                 else
327                         kill $SSH_PID
328                 fi
329         fi
330         stop_sshd
331 }
332
333 start_debug_log ()
334 {
335         echo "trace: $@" >$TEST_REGRESS_LOGFILE
336         echo "trace: $@" >$TEST_SSH_LOGFILE
337         echo "trace: $@" >$TEST_SSHD_LOGFILE
338 }
339
340 save_debug_log ()
341 {
342         echo $@ >>$TEST_REGRESS_LOGFILE
343         echo $@ >>$TEST_SSH_LOGFILE
344         echo $@ >>$TEST_SSHD_LOGFILE
345         (cat $TEST_REGRESS_LOGFILE; echo) >>$OBJ/failed-regress.log
346         (cat $TEST_SSH_LOGFILE; echo) >>$OBJ/failed-ssh.log
347         (cat $TEST_SSHD_LOGFILE; echo) >>$OBJ/failed-sshd.log
348 }
349
350 trace ()
351 {
352         start_debug_log $@
353         if [ "X$TEST_SSH_TRACE" = "Xyes" ]; then
354                 echo "$@"
355         fi
356 }
357
358 verbose ()
359 {
360         start_debug_log $@
361         if [ "X$TEST_SSH_QUIET" != "Xyes" ]; then
362                 echo "$@"
363         fi
364 }
365
366 warn ()
367 {
368         echo "WARNING: $@" >>$TEST_SSH_LOGFILE
369         echo "WARNING: $@"
370 }
371
372 fail ()
373 {
374         save_debug_log "FAIL: $@"
375         RESULT=1
376         echo "$@"
377
378 }
379
380 fatal ()
381 {
382         save_debug_log "FATAL: $@"
383         printf "FATAL: "
384         fail "$@"
385         cleanup
386         exit $RESULT
387 }
388
389 ssh_version ()
390 {
391         echo ${SSH_PROTOCOLS} | grep "$1" >/dev/null
392 }
393
394 RESULT=0
395 PIDFILE=$OBJ/pidfile
396
397 trap fatal 3 2
398
399 if ssh_version 1; then
400         PROTO="2,1"
401 else
402         PROTO="2"
403 fi
404
405 # create server config
406 cat << EOF > $OBJ/sshd_config
407         StrictModes             no
408         Port                    $PORT
409         AddressFamily           inet
410         ListenAddress           127.0.0.1
411         #ListenAddress          ::1
412         PidFile                 $PIDFILE
413         AuthorizedKeysFile      $OBJ/authorized_keys_%u
414         LogLevel                DEBUG3
415         AcceptEnv               _XXX_TEST_*
416         AcceptEnv               _XXX_TEST
417         Subsystem       sftp    $SFTPSERVER
418 EOF
419
420 # This may be necessary if /usr/src and/or /usr/obj are group-writable,
421 # but if you aren't careful with permissions then the unit tests could
422 # be abused to locally escalate privileges.
423 if [ ! -z "$TEST_SSH_UNSAFE_PERMISSIONS" ]; then
424         echo "StrictModes no" >> $OBJ/sshd_config
425 fi
426
427 if [ ! -z "$TEST_SSH_SSHD_CONFOPTS" ]; then
428         trace "adding sshd_config option $TEST_SSH_SSHD_CONFOPTS"
429         echo "$TEST_SSH_SSHD_CONFOPTS" >> $OBJ/sshd_config
430 fi
431
432 # server config for proxy connects
433 cp $OBJ/sshd_config $OBJ/sshd_proxy
434
435 # allow group-writable directories in proxy-mode
436 echo 'StrictModes no' >> $OBJ/sshd_proxy
437
438 # create client config
439 cat << EOF > $OBJ/ssh_config
440 Host *
441         Hostname                127.0.0.1
442         HostKeyAlias            localhost-with-alias
443         Port                    $PORT
444         User                    $USER
445         GlobalKnownHostsFile    $OBJ/known_hosts
446         UserKnownHostsFile      $OBJ/known_hosts
447         RSAAuthentication       yes
448         PubkeyAuthentication    yes
449         ChallengeResponseAuthentication no
450         HostbasedAuthentication no
451         PasswordAuthentication  no
452         RhostsRSAAuthentication no
453         BatchMode               yes
454         StrictHostKeyChecking   yes
455         LogLevel                DEBUG3
456 EOF
457
458 if [ ! -z "$TEST_SSH_SSH_CONFOPTS" ]; then
459         trace "adding ssh_config option $TEST_SSH_SSH_CONFOPTS"
460         echo "$TEST_SSH_SSH_CONFOPTS" >> $OBJ/ssh_config
461 fi
462
463 rm -f $OBJ/known_hosts $OBJ/authorized_keys_$USER
464
465 if ssh_version 1; then
466         SSH_KEYTYPES="rsa rsa1"
467 else
468         SSH_KEYTYPES="rsa ed25519"
469 fi
470 trace "generate keys"
471 for t in ${SSH_KEYTYPES}; do
472         # generate user key
473         if [ ! -f $OBJ/$t ] || [ ${SSHKEYGEN_BIN} -nt $OBJ/$t ]; then
474                 rm -f $OBJ/$t
475                 ${SSHKEYGEN} -q -N '' -t $t  -f $OBJ/$t ||\
476                         fail "ssh-keygen for $t failed"
477         fi
478
479         # known hosts file for client
480         (
481                 printf 'localhost-with-alias,127.0.0.1,::1 '
482                 cat $OBJ/$t.pub
483         ) >> $OBJ/known_hosts
484
485         # setup authorized keys
486         cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER
487         echo IdentityFile $OBJ/$t >> $OBJ/ssh_config
488
489         # use key as host key, too
490         $SUDO cp $OBJ/$t $OBJ/host.$t
491         echo HostKey $OBJ/host.$t >> $OBJ/sshd_config
492
493         # don't use SUDO for proxy connect
494         echo HostKey $OBJ/$t >> $OBJ/sshd_proxy
495 done
496 chmod 644 $OBJ/authorized_keys_$USER
497
498 # Activate Twisted Conch tests if the binary is present
499 REGRESS_INTEROP_CONCH=no
500 if test -x "$CONCH" ; then
501         REGRESS_INTEROP_CONCH=yes
502 fi
503
504 # If PuTTY is present and we are running a PuTTY test, prepare keys and
505 # configuration
506 REGRESS_INTEROP_PUTTY=no
507 if test -x "$PUTTYGEN" -a -x "$PLINK" ; then
508         REGRESS_INTEROP_PUTTY=yes
509 fi
510 case "$SCRIPT" in
511 *putty*)        ;;
512 *)              REGRESS_INTEROP_PUTTY=no ;;
513 esac
514
515 if test "$REGRESS_INTEROP_PUTTY" = "yes" ; then
516         mkdir -p ${OBJ}/.putty
517
518         # Add a PuTTY key to authorized_keys
519         rm -f ${OBJ}/putty.rsa2
520         if ! puttygen -t rsa -o ${OBJ}/putty.rsa2 \
521             --new-passphrase /dev/null < /dev/null > /dev/null; then
522                 echo "Your installed version of PuTTY is too old to support --new-passphrase; trying without (may require manual interaction) ..." >&2
523                 puttygen -t rsa -o ${OBJ}/putty.rsa2 < /dev/null > /dev/null
524         fi
525         puttygen -O public-openssh ${OBJ}/putty.rsa2 \
526             >> $OBJ/authorized_keys_$USER
527
528         # Convert rsa2 host key to PuTTY format
529         ${SRC}/ssh2putty.sh 127.0.0.1 $PORT $OBJ/rsa > \
530             ${OBJ}/.putty/sshhostkeys
531         ${SRC}/ssh2putty.sh 127.0.0.1 22 $OBJ/rsa >> \
532             ${OBJ}/.putty/sshhostkeys
533
534         # Setup proxied session
535         mkdir -p ${OBJ}/.putty/sessions
536         rm -f ${OBJ}/.putty/sessions/localhost_proxy
537         echo "Protocol=ssh" >> ${OBJ}/.putty/sessions/localhost_proxy
538         echo "HostName=127.0.0.1" >> ${OBJ}/.putty/sessions/localhost_proxy
539         echo "PortNumber=$PORT" >> ${OBJ}/.putty/sessions/localhost_proxy
540         echo "ProxyMethod=5" >> ${OBJ}/.putty/sessions/localhost_proxy
541         echo "ProxyTelnetCommand=sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy" >> ${OBJ}/.putty/sessions/localhost_proxy
542         echo "ProxyLocalhost=1" >> ${OBJ}/.putty/sessions/localhost_proxy
543
544         REGRESS_INTEROP_PUTTY=yes
545 fi
546
547 # create a proxy version of the client config
548 (
549         cat $OBJ/ssh_config
550         echo proxycommand ${SUDO} sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy
551 ) > $OBJ/ssh_proxy
552
553 # check proxy config
554 ${SSHD} -t -f $OBJ/sshd_proxy   || fatal "sshd_proxy broken"
555
556 start_sshd ()
557 {
558         # start sshd
559         $SUDO ${SSHD} -f $OBJ/sshd_config "$@" -t || fatal "sshd_config broken"
560         $SUDO ${SSHD} -f $OBJ/sshd_config "$@" -E$TEST_SSHD_LOGFILE
561
562         trace "wait for sshd"
563         i=0;
564         while [ ! -f $PIDFILE -a $i -lt 10 ]; do
565                 i=`expr $i + 1`
566                 sleep $i
567         done
568
569         test -f $PIDFILE || fatal "no sshd running on port $PORT"
570 }
571
572 # source test body
573 . $SCRIPT
574
575 # kill sshd
576 cleanup
577 if [ $RESULT -eq 0 ]; then
578         verbose ok $tid
579 else
580         echo failed $tid
581 fi
582 exit $RESULT