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