]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - crypto/openssh/regress/test-exec.sh
Upgrade OpenSSH to 7.3p1.
[FreeBSD/stable/10.git] / crypto / openssh / regress / test-exec.sh
1 #       $OpenBSD: test-exec.sh,v 1.53 2016/04/15 02:57:10 djm 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 REAL_SSH="$SSH"
225 SSH="$SSHLOGWRAP"
226
227 # Some test data.  We make a copy because some tests will overwrite it.
228 # The tests may assume that $DATA exists and is writable and $COPY does
229 # not exist.  Tests requiring larger data files can call increase_datafile_size
230 # [kbytes] to ensure the file is at least that large.
231 DATANAME=data
232 DATA=$OBJ/${DATANAME}
233 cat ${SSHAGENT_BIN} >${DATA}
234 chmod u+w ${DATA}
235 COPY=$OBJ/copy
236 rm -f ${COPY}
237
238 increase_datafile_size()
239 {
240         while [ `du -k ${DATA} | cut -f1` -lt $1 ]; do
241                 cat ${SSHAGENT_BIN} >>${DATA}
242         done
243 }
244
245 # these should be used in tests
246 export SSH SSHD SSHAGENT SSHADD SSHKEYGEN SSHKEYSCAN SFTP SFTPSERVER SCP
247 #echo $SSH $SSHD $SSHAGENT $SSHADD $SSHKEYGEN $SSHKEYSCAN $SFTP $SFTPSERVER $SCP
248
249 # Portable specific functions
250 have_prog()
251 {
252         saved_IFS="$IFS"
253         IFS=":"
254         for i in $PATH
255         do
256                 if [ -x $i/$1 ]; then
257                         IFS="$saved_IFS"
258                         return 0
259                 fi
260         done
261         IFS="$saved_IFS"
262         return 1
263 }
264
265 jot() {
266         awk "BEGIN { for (i = $2; i < $2 + $1; i++) { printf \"%d\n\", i } exit }"
267 }
268
269 # Check whether preprocessor symbols are defined in config.h.
270 config_defined ()
271 {
272         str=$1
273         while test "x$2" != "x" ; do
274                 str="$str|$2"
275                 shift
276         done
277         egrep "^#define.*($str)" ${BUILDDIR}/config.h >/dev/null 2>&1
278 }
279
280 md5 () {
281         if have_prog md5sum; then
282                 md5sum
283         elif have_prog openssl; then
284                 openssl md5
285         elif have_prog cksum; then
286                 cksum
287         elif have_prog sum; then
288                 sum
289         else
290                 wc -c
291         fi
292 }
293 # End of portable specific functions
294
295 # helper
296 cleanup ()
297 {
298         if [ "x$SSH_PID" != "x" ]; then
299                 if [ $SSH_PID -lt 2 ]; then
300                         echo bad pid for ssh: $SSH_PID
301                 else
302                         kill $SSH_PID
303                 fi
304         fi
305         if [ -f $PIDFILE ]; then
306                 pid=`$SUDO cat $PIDFILE`
307                 if [ "X$pid" = "X" ]; then
308                         echo no sshd running
309                 else
310                         if [ $pid -lt 2 ]; then
311                                 echo bad pid for sshd: $pid
312                         else
313                                 $SUDO kill $pid
314                                 trace "wait for sshd to exit"
315                                 i=0;
316                                 while [ -f $PIDFILE -a $i -lt 5 ]; do
317                                         i=`expr $i + 1`
318                                         sleep $i
319                                 done
320                                 test -f $PIDFILE && \
321                                     fatal "sshd didn't exit port $PORT pid $pid"
322                         fi
323                 fi
324         fi
325 }
326
327 start_debug_log ()
328 {
329         echo "trace: $@" >$TEST_REGRESS_LOGFILE
330         echo "trace: $@" >$TEST_SSH_LOGFILE
331         echo "trace: $@" >$TEST_SSHD_LOGFILE
332 }
333
334 save_debug_log ()
335 {
336         echo $@ >>$TEST_REGRESS_LOGFILE
337         echo $@ >>$TEST_SSH_LOGFILE
338         echo $@ >>$TEST_SSHD_LOGFILE
339         (cat $TEST_REGRESS_LOGFILE; echo) >>$OBJ/failed-regress.log
340         (cat $TEST_SSH_LOGFILE; echo) >>$OBJ/failed-ssh.log
341         (cat $TEST_SSHD_LOGFILE; echo) >>$OBJ/failed-sshd.log
342 }
343
344 trace ()
345 {
346         start_debug_log $@
347         if [ "X$TEST_SSH_TRACE" = "Xyes" ]; then
348                 echo "$@"
349         fi
350 }
351
352 verbose ()
353 {
354         start_debug_log $@
355         if [ "X$TEST_SSH_QUIET" != "Xyes" ]; then
356                 echo "$@"
357         fi
358 }
359
360 warn ()
361 {
362         echo "WARNING: $@" >>$TEST_SSH_LOGFILE
363         echo "WARNING: $@"
364 }
365
366 fail ()
367 {
368         save_debug_log "FAIL: $@"
369         RESULT=1
370         echo "$@"
371
372 }
373
374 fatal ()
375 {
376         save_debug_log "FATAL: $@"
377         printf "FATAL: "
378         fail "$@"
379         cleanup
380         exit $RESULT
381 }
382
383 ssh_version ()
384 {
385         echo ${SSH_PROTOCOLS} | grep "$1" >/dev/null
386 }
387
388 RESULT=0
389 PIDFILE=$OBJ/pidfile
390
391 trap fatal 3 2
392
393 if ssh_version 1; then
394         PROTO="2,1"
395 else
396         PROTO="2"
397 fi
398
399 # create server config
400 cat << EOF > $OBJ/sshd_config
401         StrictModes             no
402         Port                    $PORT
403         Protocol                $PROTO
404         AddressFamily           inet
405         ListenAddress           127.0.0.1
406         #ListenAddress          ::1
407         PidFile                 $PIDFILE
408         AuthorizedKeysFile      $OBJ/authorized_keys_%u
409         LogLevel                DEBUG3
410         AcceptEnv               _XXX_TEST_*
411         AcceptEnv               _XXX_TEST
412         Subsystem       sftp    $SFTPSERVER
413 EOF
414
415 # This may be necessary if /usr/src and/or /usr/obj are group-writable,
416 # but if you aren't careful with permissions then the unit tests could
417 # be abused to locally escalate privileges.
418 if [ ! -z "$TEST_SSH_UNSAFE_PERMISSIONS" ]; then
419         echo "StrictModes no" >> $OBJ/sshd_config
420 fi
421
422 if [ ! -z "$TEST_SSH_SSHD_CONFOPTS" ]; then
423         trace "adding sshd_config option $TEST_SSH_SSHD_CONFOPTS"
424         echo "$TEST_SSH_SSHD_CONFOPTS" >> $OBJ/sshd_config
425 fi
426
427 # server config for proxy connects
428 cp $OBJ/sshd_config $OBJ/sshd_proxy
429
430 # allow group-writable directories in proxy-mode
431 echo 'StrictModes no' >> $OBJ/sshd_proxy
432
433 # create client config
434 cat << EOF > $OBJ/ssh_config
435 Host *
436         Protocol                $PROTO
437         Hostname                127.0.0.1
438         HostKeyAlias            localhost-with-alias
439         Port                    $PORT
440         User                    $USER
441         GlobalKnownHostsFile    $OBJ/known_hosts
442         UserKnownHostsFile      $OBJ/known_hosts
443         RSAAuthentication       yes
444         PubkeyAuthentication    yes
445         ChallengeResponseAuthentication no
446         HostbasedAuthentication no
447         PasswordAuthentication  no
448         RhostsRSAAuthentication no
449         BatchMode               yes
450         StrictHostKeyChecking   yes
451         LogLevel                DEBUG3
452 EOF
453
454 if [ ! -z "$TEST_SSH_SSH_CONFOPTS" ]; then
455         trace "adding ssh_config option $TEST_SSH_SSH_CONFOPTS"
456         echo "$TEST_SSH_SSH_CONFOPTS" >> $OBJ/ssh_config
457 fi
458
459 rm -f $OBJ/known_hosts $OBJ/authorized_keys_$USER
460
461 if ssh_version 1; then
462         SSH_KEYTYPES="rsa rsa1"
463 else
464         SSH_KEYTYPES="rsa ed25519"
465 fi
466 trace "generate keys"
467 for t in ${SSH_KEYTYPES}; do
468         # generate user key
469         if [ ! -f $OBJ/$t ] || [ ${SSHKEYGEN_BIN} -nt $OBJ/$t ]; then
470                 rm -f $OBJ/$t
471                 ${SSHKEYGEN} -q -N '' -t $t  -f $OBJ/$t ||\
472                         fail "ssh-keygen for $t failed"
473         fi
474
475         # known hosts file for client
476         (
477                 printf 'localhost-with-alias,127.0.0.1,::1 '
478                 cat $OBJ/$t.pub
479         ) >> $OBJ/known_hosts
480
481         # setup authorized keys
482         cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER
483         echo IdentityFile $OBJ/$t >> $OBJ/ssh_config
484
485         # use key as host key, too
486         $SUDO cp $OBJ/$t $OBJ/host.$t
487         echo HostKey $OBJ/host.$t >> $OBJ/sshd_config
488
489         # don't use SUDO for proxy connect
490         echo HostKey $OBJ/$t >> $OBJ/sshd_proxy
491 done
492 chmod 644 $OBJ/authorized_keys_$USER
493
494 # Activate Twisted Conch tests if the binary is present
495 REGRESS_INTEROP_CONCH=no
496 if test -x "$CONCH" ; then
497         REGRESS_INTEROP_CONCH=yes
498 fi
499
500 # If PuTTY is present and we are running a PuTTY test, prepare keys and
501 # configuration
502 REGRESS_INTEROP_PUTTY=no
503 if test -x "$PUTTYGEN" -a -x "$PLINK" ; then
504         REGRESS_INTEROP_PUTTY=yes
505 fi
506 case "$SCRIPT" in
507 *putty*)        ;;
508 *)              REGRESS_INTEROP_PUTTY=no ;;
509 esac
510
511 if test "$REGRESS_INTEROP_PUTTY" = "yes" ; then
512         mkdir -p ${OBJ}/.putty
513
514         # Add a PuTTY key to authorized_keys
515         rm -f ${OBJ}/putty.rsa2
516         puttygen -t rsa -o ${OBJ}/putty.rsa2 < /dev/null > /dev/null
517         puttygen -O public-openssh ${OBJ}/putty.rsa2 \
518             >> $OBJ/authorized_keys_$USER
519
520         # Convert rsa2 host key to PuTTY format
521         ${SRC}/ssh2putty.sh 127.0.0.1 $PORT $OBJ/rsa > \
522             ${OBJ}/.putty/sshhostkeys
523         ${SRC}/ssh2putty.sh 127.0.0.1 22 $OBJ/rsa >> \
524             ${OBJ}/.putty/sshhostkeys
525
526         # Setup proxied session
527         mkdir -p ${OBJ}/.putty/sessions
528         rm -f ${OBJ}/.putty/sessions/localhost_proxy
529         echo "Hostname=127.0.0.1" >> ${OBJ}/.putty/sessions/localhost_proxy
530         echo "PortNumber=$PORT" >> ${OBJ}/.putty/sessions/localhost_proxy
531         echo "ProxyMethod=5" >> ${OBJ}/.putty/sessions/localhost_proxy
532         echo "ProxyTelnetCommand=sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy" >> ${OBJ}/.putty/sessions/localhost_proxy
533
534         REGRESS_INTEROP_PUTTY=yes
535 fi
536
537 # create a proxy version of the client config
538 (
539         cat $OBJ/ssh_config
540         echo proxycommand ${SUDO} sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy
541 ) > $OBJ/ssh_proxy
542
543 # check proxy config
544 ${SSHD} -t -f $OBJ/sshd_proxy   || fatal "sshd_proxy broken"
545
546 start_sshd ()
547 {
548         # start sshd
549         $SUDO ${SSHD} -f $OBJ/sshd_config "$@" -t || fatal "sshd_config broken"
550         $SUDO ${SSHD} -f $OBJ/sshd_config "$@" -E$TEST_SSHD_LOGFILE
551
552         trace "wait for sshd"
553         i=0;
554         while [ ! -f $PIDFILE -a $i -lt 10 ]; do
555                 i=`expr $i + 1`
556                 sleep $i
557         done
558
559         test -f $PIDFILE || fatal "no sshd running on port $PORT"
560 }
561
562 # source test body
563 . $SCRIPT
564
565 # kill sshd
566 cleanup
567 if [ $RESULT -eq 0 ]; then
568         verbose ok $tid
569 else
570         echo failed $tid
571 fi
572 exit $RESULT