xref: /freebsd/crypto/openssh/regress/agent-restrict.sh (revision 4d3fc8b0570b29fb0d6ee9525f104d52176ff0d4)
1*4d3fc8b0SEd Maste#	$OpenBSD: agent-restrict.sh,v 1.6 2023/03/01 09:29:32 dtucker Exp $
21323ec57SEd Maste#	Placed in the Public Domain.
31323ec57SEd Maste
41323ec57SEd Mastetid="agent restrictions"
51323ec57SEd Maste
61323ec57SEd MasteSSH_AUTH_SOCK="$OBJ/agent.sock"
71323ec57SEd Masteexport SSH_AUTH_SOCK
81323ec57SEd Masterm -f $SSH_AUTH_SOCK $OBJ/agent.log $OBJ/host_[abcdex]* $OBJ/user_[abcdex]*
91323ec57SEd Masterm -f $OBJ/sshd_proxy_host* $OBJ/ssh_output* $OBJ/expect_*
101323ec57SEd Masterm -f $OBJ/ssh_proxy[._]* $OBJ/command
111323ec57SEd Maste
121323ec57SEd Masteverbose "generate keys"
131323ec57SEd Mastefor h in a b c d e x ca ; do
141323ec57SEd Maste	$SSHKEYGEN -q -t ed25519 -C host_$h -N '' -f $OBJ/host_$h || \
151323ec57SEd Maste		fatal "ssh-keygen hostkey failed"
161323ec57SEd Maste	$SSHKEYGEN -q -t ed25519 -C user_$h -N '' -f $OBJ/user_$h || \
171323ec57SEd Maste		fatal "ssh-keygen userkey failed"
181323ec57SEd Mastedone
191323ec57SEd Maste
201323ec57SEd Maste# Make some hostcerts
211323ec57SEd Mastefor h in d e ; do
221323ec57SEd Maste	id="host_$h"
231323ec57SEd Maste	$SSHKEYGEN -q -s $OBJ/host_ca -I $id -n $id -h $OBJ/host_${h}.pub || \
241323ec57SEd Maste		fatal "ssh-keygen certify failed"
251323ec57SEd Mastedone
261323ec57SEd Maste
271323ec57SEd Masteverbose "prepare client config"
281323ec57SEd Masteegrep -vi '(identityfile|hostname|hostkeyalias|proxycommand)' \
291323ec57SEd Maste	$OBJ/ssh_proxy > $OBJ/ssh_proxy.bak
301323ec57SEd Mastecat << _EOF > $OBJ/ssh_proxy
311323ec57SEd MasteIdentitiesOnly yes
321323ec57SEd MasteForwardAgent yes
331323ec57SEd MasteExitOnForwardFailure yes
341323ec57SEd Maste_EOF
351323ec57SEd Mastecp $OBJ/ssh_proxy $OBJ/ssh_proxy_noid
361323ec57SEd Mastefor h in a b c d e ; do
371323ec57SEd Maste	cat << _EOF >> $OBJ/ssh_proxy
381323ec57SEd MasteHost host_$h
391323ec57SEd Maste	Hostname host_$h
401323ec57SEd Maste	HostkeyAlias host_$h
411323ec57SEd Maste	IdentityFile $OBJ/user_$h
42*4d3fc8b0SEd Maste	ProxyCommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy_host_$h
431323ec57SEd Maste_EOF
441323ec57SEd Maste	# Variant with no specified keys.
451323ec57SEd Maste	cat << _EOF >> $OBJ/ssh_proxy_noid
461323ec57SEd MasteHost host_$h
471323ec57SEd Maste	Hostname host_$h
481323ec57SEd Maste	HostkeyAlias host_$h
49*4d3fc8b0SEd Maste	ProxyCommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy_host_$h
501323ec57SEd Maste_EOF
511323ec57SEd Mastedone
521323ec57SEd Mastecat $OBJ/ssh_proxy.bak >> $OBJ/ssh_proxy
531323ec57SEd Mastecat $OBJ/ssh_proxy.bak >> $OBJ/ssh_proxy_noid
541323ec57SEd Maste
551323ec57SEd MasteLC_ALL=C
561323ec57SEd Masteexport LC_ALL
571323ec57SEd Masteecho "SetEnv LC_ALL=${LC_ALL}" >> sshd_proxy
581323ec57SEd Maste
591323ec57SEd Masteverbose "prepare known_hosts"
601323ec57SEd Masterm -f $OBJ/known_hosts
611323ec57SEd Mastefor h in a b c x ; do
621323ec57SEd Maste	(printf "host_$h " ; cat $OBJ/host_${h}.pub) >> $OBJ/known_hosts
631323ec57SEd Mastedone
641323ec57SEd Maste(printf "@cert-authority host_* " ; cat $OBJ/host_ca.pub) >> $OBJ/known_hosts
651323ec57SEd Maste
661323ec57SEd Masteverbose "prepare server configs"
671323ec57SEd Masteegrep -vi '(hostkey|pidfile)' $OBJ/sshd_proxy \
681323ec57SEd Maste	> $OBJ/sshd_proxy.bak
691323ec57SEd Mastefor h in a b c d e; do
701323ec57SEd Maste	cp $OBJ/sshd_proxy.bak $OBJ/sshd_proxy_host_$h
711323ec57SEd Maste	cat << _EOF >> $OBJ/sshd_proxy_host_$h
721323ec57SEd MasteExposeAuthInfo yes
731323ec57SEd MastePidFile none
741323ec57SEd MasteHostkey $OBJ/host_$h
751323ec57SEd Maste_EOF
761323ec57SEd Mastedone
771323ec57SEd Mastefor h in d e ; do
781323ec57SEd Maste	echo "HostCertificate $OBJ/host_${h}-cert.pub" \
791323ec57SEd Maste		>> $OBJ/sshd_proxy_host_$h
801323ec57SEd Mastedone
811323ec57SEd Maste# Create authorized_keys with canned command.
821323ec57SEd Mastereset_keys() {
831323ec57SEd Maste	_whichcmd="$1"
841323ec57SEd Maste	_command=""
851323ec57SEd Maste	case "$_whichcmd" in
861323ec57SEd Maste	authinfo)	_command="cat \$SSH_USER_AUTH" ;;
871323ec57SEd Maste	keylist)		_command="$SSHADD -L | cut -d' ' -f-2 | sort" ;;
881323ec57SEd Maste	*)		fatal "unsupported command $_whichcmd" ;;
891323ec57SEd Maste	esac
901323ec57SEd Maste	trace "reset keys"
911323ec57SEd Maste	>$OBJ/authorized_keys_$USER
921323ec57SEd Maste	for h in e d c b a; do
931323ec57SEd Maste		(printf "%s" "restrict,agent-forwarding,command=\"$_command\" ";
941323ec57SEd Maste		 cat $OBJ/user_$h.pub) >> $OBJ/authorized_keys_$USER
951323ec57SEd Maste	done
961323ec57SEd Maste}
971323ec57SEd Maste# Prepare a key for comparison with ExposeAuthInfo/$SSH_USER_AUTH.
981323ec57SEd Masteexpect_key() {
991323ec57SEd Maste	_key="$OBJ/${1}.pub"
1001323ec57SEd Maste	_file="$OBJ/$2"
1011323ec57SEd Maste	(printf "publickey " ; cut -d' ' -f-2 $_key) > $_file
1021323ec57SEd Maste}
1031323ec57SEd Maste# Prepare expect_* files to compare against authinfo forced command to ensure
1041323ec57SEd Maste# keys used for authentication match.
1051323ec57SEd Mastereset_expect_keys() {
1061323ec57SEd Maste	for u in a b c d e; do
1071323ec57SEd Maste		expect_key user_$u expect_$u
1081323ec57SEd Maste	done
1091323ec57SEd Maste}
1101323ec57SEd Maste# ssh to host, expecting success and that output matched expectation for
1111323ec57SEd Maste# that host (expect_$h file).
1121323ec57SEd Masteexpect_succeed() {
1131323ec57SEd Maste	_id="$1"
1141323ec57SEd Maste	_case="$2"
1151323ec57SEd Maste	shift; shift; _extra="$@"
1161323ec57SEd Maste	_host="host_$_id"
1171323ec57SEd Maste	trace "connect $_host expect success"
1181323ec57SEd Maste	rm -f $OBJ/ssh_output
1191323ec57SEd Maste	${SSH} $_extra -F $OBJ/ssh_proxy $_host true > $OBJ/ssh_output
1201323ec57SEd Maste	_s=$?
1211323ec57SEd Maste	test $_s -eq 0 || fail "host $_host $_case fail, exit status $_s"
1221323ec57SEd Maste	diff $OBJ/ssh_output $OBJ/expect_${_id} ||
1231323ec57SEd Maste		fail "unexpected ssh output"
1241323ec57SEd Maste}
1251323ec57SEd Maste# ssh to host using explicit key, expecting success and that the key was
1261323ec57SEd Maste# actually used for authentication.
1271323ec57SEd Masteexpect_succeed_key() {
1281323ec57SEd Maste	_id="$1"
1291323ec57SEd Maste	_key="$2"
1301323ec57SEd Maste	_case="$3"
1311323ec57SEd Maste	shift; shift; shift; _extra="$@"
1321323ec57SEd Maste	_host="host_$_id"
1331323ec57SEd Maste	trace "connect $_host expect success, with key $_key"
1341323ec57SEd Maste	_keyfile="$OBJ/$_key"
1351323ec57SEd Maste	rm -f $OBJ/ssh_output
1361323ec57SEd Maste	${SSH} $_extra -F $OBJ/ssh_proxy_noid \
1371323ec57SEd Maste	    -oIdentityFile=$_keyfile $_host true > $OBJ/ssh_output
1381323ec57SEd Maste	_s=$?
1391323ec57SEd Maste	test $_s -eq 0 || fail "host $_host $_key $_case fail, exit status $_s"
1401323ec57SEd Maste	expect_key $_key expect_key
1411323ec57SEd Maste	diff $OBJ/ssh_output $OBJ/expect_key ||
1421323ec57SEd Maste		fail "incorrect key used for authentication"
1431323ec57SEd Maste}
1441323ec57SEd Maste# ssh to a host, expecting it to fail.
1451323ec57SEd Masteexpect_fail() {
1461323ec57SEd Maste	_host="$1"
1471323ec57SEd Maste	_case="$2"
1481323ec57SEd Maste	shift; shift; _extra="$@"
1491323ec57SEd Maste	trace "connect $_host expect failure"
1501323ec57SEd Maste	${SSH} $_extra -F $OBJ/ssh_proxy $_host true >/dev/null && \
1511323ec57SEd Maste		fail "host $_host $_case succeeded unexpectedly"
1521323ec57SEd Maste}
1531323ec57SEd Maste# ssh to a host using an explicit key, expecting it to fail.
1541323ec57SEd Masteexpect_fail_key() {
1551323ec57SEd Maste	_id="$1"
1561323ec57SEd Maste	_key="$2"
1571323ec57SEd Maste	_case="$3"
1581323ec57SEd Maste	shift; shift; shift; _extra="$@"
1591323ec57SEd Maste	_host="host_$_id"
1601323ec57SEd Maste	trace "connect $_host expect failure, with key $_key"
1611323ec57SEd Maste	_keyfile="$OBJ/$_key"
1621323ec57SEd Maste	${SSH} $_extra -F $OBJ/ssh_proxy_noid -oIdentityFile=$_keyfile \
1631323ec57SEd Maste	    $_host true > $OBJ/ssh_output && \
1641323ec57SEd Maste		fail "host $_host $_key $_case succeeded unexpectedly"
1651323ec57SEd Maste}
1661323ec57SEd Maste# Move the private key files out of the way to force use of agent-hosted keys.
1671323ec57SEd Mastehide_privatekeys() {
1681323ec57SEd Maste	trace "hide private keys"
1691323ec57SEd Maste	for u in a b c d e x; do
1701323ec57SEd Maste		mv $OBJ/user_$u $OBJ/user_x$u || fatal "hide privkey $u"
1711323ec57SEd Maste	done
1721323ec57SEd Maste}
1731323ec57SEd Maste# Put the private key files back.
1741323ec57SEd Masterestore_privatekeys() {
1751323ec57SEd Maste	trace "restore private keys"
1761323ec57SEd Maste	for u in a b c d e x; do
1771323ec57SEd Maste		mv $OBJ/user_x$u $OBJ/user_$u || fatal "restore privkey $u"
1781323ec57SEd Maste	done
1791323ec57SEd Maste}
1801323ec57SEd Masteclear_agent() {
1811323ec57SEd Maste	${SSHADD} -D > /dev/null 2>&1 || fatal "clear agent failed"
1821323ec57SEd Maste}
1831323ec57SEd Maste
1841323ec57SEd Mastereset_keys authinfo
1851323ec57SEd Mastereset_expect_keys
1861323ec57SEd Maste
1871323ec57SEd Masteverbose "authentication w/o agent"
1881323ec57SEd Mastefor h in a b c d e ; do
1891323ec57SEd Maste	expect_succeed $h "w/o agent"
1901323ec57SEd Maste	wrongkey=user_e
1911323ec57SEd Maste	test "$h" = "e" && wrongkey=user_a
1921323ec57SEd Maste	expect_succeed_key $h $wrongkey "\"wrong\" key w/o agent"
1931323ec57SEd Mastedone
1941323ec57SEd Mastehide_privatekeys
1951323ec57SEd Mastefor h in a b c d e ; do
1961323ec57SEd Maste	expect_fail $h "w/o agent"
1971323ec57SEd Mastedone
1981323ec57SEd Masterestore_privatekeys
1991323ec57SEd Maste
2001323ec57SEd Masteverbose "start agent"
2011323ec57SEd Maste${SSHAGENT} ${EXTRA_AGENT_ARGS} -d -a $SSH_AUTH_SOCK > $OBJ/agent.log 2>&1 &
2021323ec57SEd MasteAGENT_PID=$!
2031323ec57SEd Mastetrap "kill $AGENT_PID" EXIT
2041323ec57SEd Mastesleep 4 # Give it a chance to start
2051323ec57SEd Maste# Check that it's running.
2061323ec57SEd Maste${SSHADD} -l > /dev/null 2>&1
2071323ec57SEd Masteif [ $? -ne 1 ]; then
2081323ec57SEd Maste	fail "ssh-add -l did not fail with exit code 1"
2091323ec57SEd Mastefi
2101323ec57SEd Maste
2111323ec57SEd Masteverbose "authentication with agent (no restrict)"
2121323ec57SEd Mastefor u in a b c d e x; do
2131323ec57SEd Maste	$SSHADD -q $OBJ/user_$u || fatal "add key $u unrestricted"
2141323ec57SEd Mastedone
2151323ec57SEd Mastehide_privatekeys
2161323ec57SEd Mastefor h in a b c d e ; do
2171323ec57SEd Maste	expect_succeed $h "with agent"
2181323ec57SEd Maste	wrongkey=user_e
2191323ec57SEd Maste	test "$h" = "e" && wrongkey=user_a
2201323ec57SEd Maste	expect_succeed_key $h $wrongkey "\"wrong\" key with agent"
2211323ec57SEd Mastedone
2221323ec57SEd Maste
2231323ec57SEd Masteverbose "unrestricted keylist"
2241323ec57SEd Mastereset_keys keylist
2251323ec57SEd Masterm -f $OBJ/expect_list.pre
2261323ec57SEd Maste# List of keys from agent should contain everything.
2271323ec57SEd Mastefor u in a b c d e x; do
2281323ec57SEd Maste	cut -d " " -f-2 $OBJ/user_${u}.pub >> $OBJ/expect_list.pre
2291323ec57SEd Mastedone
2301323ec57SEd Mastesort $OBJ/expect_list.pre > $OBJ/expect_list
2311323ec57SEd Mastefor h in a b c d e; do
2321323ec57SEd Maste	cp $OBJ/expect_list $OBJ/expect_$h
2331323ec57SEd Maste	expect_succeed $h "unrestricted keylist"
2341323ec57SEd Mastedone
2351323ec57SEd Masterestore_privatekeys
2361323ec57SEd Maste
2371323ec57SEd Masteverbose "authentication with agent (basic restrict)"
2381323ec57SEd Mastereset_keys authinfo
2391323ec57SEd Mastereset_expect_keys
2401323ec57SEd Mastefor h in a b c d e; do
2411323ec57SEd Maste	$SSHADD -h host_$h -H $OBJ/known_hosts -q $OBJ/user_$h \
2421323ec57SEd Maste		|| fatal "add key $u basic restrict"
2431323ec57SEd Mastedone
2441323ec57SEd Maste# One more, unrestricted
2451323ec57SEd Maste$SSHADD -q $OBJ/user_x || fatal "add unrestricted key"
2461323ec57SEd Mastehide_privatekeys
2471323ec57SEd Maste# Authentication to host with expected key should work.
2481323ec57SEd Mastefor h in a b c d e ; do
2491323ec57SEd Maste	expect_succeed $h "with agent"
2501323ec57SEd Mastedone
2511323ec57SEd Maste# Authentication to host with incorrect key should fail.
2521323ec57SEd Masteverbose "authentication with agent incorrect key (basic restrict)"
2531323ec57SEd Mastefor h in a b c d e ; do
2541323ec57SEd Maste	wrongkey=user_e
2551323ec57SEd Maste	test "$h" = "e" && wrongkey=user_a
2561323ec57SEd Maste	expect_fail_key $h $wrongkey "wrong key with agent (basic restrict)"
2571323ec57SEd Mastedone
2581323ec57SEd Maste
2591323ec57SEd Masteverbose "keylist (basic restrict)"
2601323ec57SEd Mastereset_keys keylist
2611323ec57SEd Maste# List from forwarded agent should contain only user_x - the unrestricted key.
2621323ec57SEd Mastecut -d " " -f-2 $OBJ/user_x.pub > $OBJ/expect_list
2631323ec57SEd Mastefor h in a b c d e; do
2641323ec57SEd Maste	cp $OBJ/expect_list $OBJ/expect_$h
2651323ec57SEd Maste	expect_succeed $h "keylist (basic restrict)"
2661323ec57SEd Mastedone
2671323ec57SEd Masterestore_privatekeys
2681323ec57SEd Maste
2691323ec57SEd Masteverbose "username"
2701323ec57SEd Mastereset_keys authinfo
2711323ec57SEd Mastereset_expect_keys
2721323ec57SEd Mastefor h in a b c d e; do
2731323ec57SEd Maste	$SSHADD -h "${USER}@host_$h" -H $OBJ/known_hosts -q $OBJ/user_$h \
2741323ec57SEd Maste		|| fatal "add key $u basic restrict"
2751323ec57SEd Mastedone
2761323ec57SEd Mastehide_privatekeys
2771323ec57SEd Mastefor h in a b c d e ; do
2781323ec57SEd Maste	expect_succeed $h "wildcard user"
2791323ec57SEd Mastedone
2801323ec57SEd Masterestore_privatekeys
2811323ec57SEd Maste
2821323ec57SEd Masteverbose "username wildcard"
2831323ec57SEd Mastereset_keys authinfo
2841323ec57SEd Mastereset_expect_keys
2851323ec57SEd Mastefor h in a b c d e; do
2861323ec57SEd Maste	$SSHADD -h "*@host_$h" -H $OBJ/known_hosts -q $OBJ/user_$h \
2871323ec57SEd Maste		|| fatal "add key $u basic restrict"
2881323ec57SEd Mastedone
2891323ec57SEd Mastehide_privatekeys
2901323ec57SEd Mastefor h in a b c d e ; do
2911323ec57SEd Maste	expect_succeed $h "wildcard user"
2921323ec57SEd Mastedone
2931323ec57SEd Masterestore_privatekeys
2941323ec57SEd Maste
2951323ec57SEd Masteverbose "username incorrect"
2961323ec57SEd Mastereset_keys authinfo
2971323ec57SEd Mastereset_expect_keys
2981323ec57SEd Mastefor h in a b c d e; do
2991323ec57SEd Maste	$SSHADD -h "--BADUSER@host_$h" -H $OBJ/known_hosts -q $OBJ/user_$h \
3001323ec57SEd Maste		|| fatal "add key $u basic restrict"
3011323ec57SEd Mastedone
3021323ec57SEd Mastehide_privatekeys
3031323ec57SEd Mastefor h in a b c d e ; do
3041323ec57SEd Maste	expect_fail $h "incorrect user"
3051323ec57SEd Mastedone
3061323ec57SEd Masterestore_privatekeys
3071323ec57SEd Maste
3081323ec57SEd Maste
3091323ec57SEd Masteverbose "agent restriction honours certificate principal"
3101323ec57SEd Mastereset_keys authinfo
3111323ec57SEd Mastereset_expect_keys
3121323ec57SEd Masteclear_agent
3131323ec57SEd Maste$SSHADD -h host_e -H $OBJ/known_hosts -q $OBJ/user_d || fatal "add key"
3141323ec57SEd Mastehide_privatekeys
3151323ec57SEd Masteexpect_fail d "restricted agent w/ incorrect cert principal"
3161323ec57SEd Masterestore_privatekeys
3171323ec57SEd Maste
3181323ec57SEd Maste# Prepares the script used to drive chained ssh connections for the
3191323ec57SEd Maste# multihop tests. Believe me, this is easier than getting the escaping
3201323ec57SEd Maste# right for 5 hops on the command-line...
3211323ec57SEd Masteprepare_multihop_script() {
3221323ec57SEd Maste	MULTIHOP_RUN=$OBJ/command
3231323ec57SEd Maste	cat << _EOF > $MULTIHOP_RUN
3241323ec57SEd Maste#!/bin/sh
3251323ec57SEd Maste#set -x
3261323ec57SEd Masteme="\$1" ; shift
3271323ec57SEd Mastenext="\$1"
3281323ec57SEd Masteif test ! -z "\$me" ; then 
3291323ec57SEd Maste	rm -f $OBJ/done
3301323ec57SEd Maste	echo "HOSTNAME host_\$me"
3311323ec57SEd Maste	echo "AUTHINFO"
3321323ec57SEd Maste	cat \$SSH_USER_AUTH
3331323ec57SEd Mastefi
3341323ec57SEd Masteecho AGENT
3351323ec57SEd Maste$SSHADD -L | egrep "^ssh" | cut -d" " -f-2 | sort
3361323ec57SEd Masteif test -z "\$next" ; then 
3371323ec57SEd Maste	touch $OBJ/done
3381323ec57SEd Maste	echo "FINISH"
3391323ec57SEd Maste	e=0
3401323ec57SEd Masteelse
3411323ec57SEd Maste	echo NEXT
3421323ec57SEd Maste	${SSH} -F $OBJ/ssh_proxy_noid -oIdentityFile=$OBJ/user_a \
3431323ec57SEd Maste		host_\$next $MULTIHOP_RUN "\$@"
3441323ec57SEd Maste	e=\$?
3451323ec57SEd Mastefi
3461323ec57SEd Masteecho "COMPLETE \"\$me\""
3471323ec57SEd Masteif test ! -z "\$me" ; then 
3481323ec57SEd Maste	if test ! -f $OBJ/done ; then
3491323ec57SEd Maste		echo "DONE MARKER MISSING"
3501323ec57SEd Maste		test \$e -eq 0 && e=63
3511323ec57SEd Maste	fi
3521323ec57SEd Mastefi
3531323ec57SEd Masteexit \$e
3541323ec57SEd Maste_EOF
3551323ec57SEd Maste	chmod u+x $MULTIHOP_RUN
3561323ec57SEd Maste}
3571323ec57SEd Maste
3581323ec57SEd Maste# Prepare expected output for multihop tests at expect_a
3591323ec57SEd Masteprepare_multihop_expected() {
3601323ec57SEd Maste	_keys="$1"
3611323ec57SEd Maste	_hops="a b c d e"
3621323ec57SEd Maste	test -z "$2" || _hops="$2"
3631323ec57SEd Maste	_revhops=$(echo "$_hops" | rev)
3641323ec57SEd Maste	_lasthop=$(echo "$_hops" | sed 's/.* //')
3651323ec57SEd Maste
3661323ec57SEd Maste	rm -f $OBJ/expect_keys
3671323ec57SEd Maste	for h in a b c d e; do
3681323ec57SEd Maste		cut -d" " -f-2 $OBJ/user_${h}.pub >> $OBJ/expect_keys
3691323ec57SEd Maste	done
3701323ec57SEd Maste	rm -f $OBJ/expect_a
3711323ec57SEd Maste	echo "AGENT" >> $OBJ/expect_a
3721323ec57SEd Maste	test "x$_keys" = "xnone" || sort $OBJ/expect_keys >> $OBJ/expect_a
3731323ec57SEd Maste	echo "NEXT" >> $OBJ/expect_a
3741323ec57SEd Maste	for h in $_hops ; do
3751323ec57SEd Maste		echo "HOSTNAME host_$h" >> $OBJ/expect_a
3761323ec57SEd Maste		echo "AUTHINFO" >> $OBJ/expect_a
3771323ec57SEd Maste		(printf "publickey " ; cut -d" " -f-2 $OBJ/user_a.pub) >> $OBJ/expect_a
3781323ec57SEd Maste		echo "AGENT" >> $OBJ/expect_a
3791323ec57SEd Maste		if test "x$_keys" = "xall" ; then
3801323ec57SEd Maste			sort $OBJ/expect_keys >> $OBJ/expect_a
3811323ec57SEd Maste		fi
3821323ec57SEd Maste		if test "x$h" != "x$_lasthop" ; then
3831323ec57SEd Maste			if test "x$_keys" = "xfiltered" ; then
3841323ec57SEd Maste				cut -d" " -f-2 $OBJ/user_a.pub >> $OBJ/expect_a
3851323ec57SEd Maste			fi
3861323ec57SEd Maste			echo "NEXT" >> $OBJ/expect_a
3871323ec57SEd Maste		fi
3881323ec57SEd Maste	done
3891323ec57SEd Maste	echo "FINISH" >> $OBJ/expect_a
3901323ec57SEd Maste	for h in $_revhops "" ; do
3911323ec57SEd Maste		echo "COMPLETE \"$h\"" >> $OBJ/expect_a
3921323ec57SEd Maste	done
3931323ec57SEd Maste}
3941323ec57SEd Maste
3951323ec57SEd Masteprepare_multihop_script
3961323ec57SEd Mastecp $OBJ/user_a.pub $OBJ/authorized_keys_$USER # only one key used.
3971323ec57SEd Maste
3981323ec57SEd Masteverbose "multihop without agent"
3991323ec57SEd Masteclear_agent
4001323ec57SEd Masteprepare_multihop_expected none
4011323ec57SEd Maste$MULTIHOP_RUN "" a b c d e > $OBJ/ssh_output || fail "multihop no agent ssh failed"
4021323ec57SEd Mastediff $OBJ/ssh_output $OBJ/expect_a || fail "unexpected ssh output"
4031323ec57SEd Maste
4041323ec57SEd Masteverbose "multihop agent unrestricted"
4051323ec57SEd Masteclear_agent
4061323ec57SEd Maste$SSHADD -q $OBJ/user_[abcde]
4071323ec57SEd Masteprepare_multihop_expected all
4081323ec57SEd Maste$MULTIHOP_RUN "" a b c d e > $OBJ/ssh_output || fail "multihop no agent ssh failed"
4091323ec57SEd Mastediff $OBJ/ssh_output $OBJ/expect_a || fail "unexpected ssh output"
4101323ec57SEd Maste
4111323ec57SEd Masteverbose "multihop restricted"
4121323ec57SEd Masteclear_agent
4131323ec57SEd Masteprepare_multihop_expected filtered
4141323ec57SEd Maste# Add user_a, with permission to connect through the whole chain.
4151323ec57SEd Maste$SSHADD -h host_a -h "host_a>host_b" -h "host_b>host_c" \
4161323ec57SEd Maste	-h "host_c>host_d" -h "host_d>host_e" \
4171323ec57SEd Maste	-H $OBJ/known_hosts -q $OBJ/user_a \
4181323ec57SEd Maste	|| fatal "add key user_a multihop"
4191323ec57SEd Maste# Add the other keys, bound to a unused host.
4201323ec57SEd Maste$SSHADD -q -h host_x -H $OBJ/known_hosts $OBJ/user_[bcde] || fail "add keys"
4211323ec57SEd Mastehide_privatekeys
4221323ec57SEd Maste$MULTIHOP_RUN "" a b c d e > $OBJ/ssh_output || fail "multihop ssh failed"
4231323ec57SEd Mastediff $OBJ/ssh_output $OBJ/expect_a || fail "unexpected ssh output"
4241323ec57SEd Masterestore_privatekeys
4251323ec57SEd Maste
4261323ec57SEd Masteverbose "multihop username"
4271323ec57SEd Maste$SSHADD -h host_a -h "host_a>${USER}@host_b" -h "host_b>${USER}@host_c" \
4281323ec57SEd Maste	-h "host_c>${USER}@host_d"  -h "host_d>${USER}@host_e" \
4291323ec57SEd Maste	-H $OBJ/known_hosts -q $OBJ/user_a || fatal "add key user_a multihop"
4301323ec57SEd Mastehide_privatekeys
4311323ec57SEd Maste$MULTIHOP_RUN "" a b c d e > $OBJ/ssh_output || fail "multihop w/ user ssh failed"
4321323ec57SEd Mastediff $OBJ/ssh_output $OBJ/expect_a || fail "unexpected ssh output"
4331323ec57SEd Masterestore_privatekeys
4341323ec57SEd Maste
4351323ec57SEd Masteverbose "multihop wildcard username"
4361323ec57SEd Maste$SSHADD -h host_a -h "host_a>*@host_b" -h "host_b>*@host_c" \
4371323ec57SEd Maste	-h "host_c>*@host_d"  -h "host_d>*@host_e" \
4381323ec57SEd Maste	-H $OBJ/known_hosts -q $OBJ/user_a || fatal "add key user_a multihop"
4391323ec57SEd Mastehide_privatekeys
4401323ec57SEd Maste$MULTIHOP_RUN "" a b c d e > $OBJ/ssh_output || fail "multihop w/ user ssh failed"
4411323ec57SEd Mastediff $OBJ/ssh_output $OBJ/expect_a || fail "unexpected ssh output"
4421323ec57SEd Masterestore_privatekeys
4431323ec57SEd Maste
4441323ec57SEd Masteverbose "multihop wrong username"
4451323ec57SEd Maste$SSHADD -h host_a -h "host_a>*@host_b" -h "host_b>*@host_c" \
4461323ec57SEd Maste	-h "host_c>--BADUSER@host_d"  -h "host_d>*@host_e" \
4471323ec57SEd Maste	-H $OBJ/known_hosts -q $OBJ/user_a || fatal "add key user_a multihop"
4481323ec57SEd Mastehide_privatekeys
4491323ec57SEd Maste$MULTIHOP_RUN "" a b c d e > $OBJ/ssh_output && \
4501323ec57SEd Maste	fail "multihop with wrong user succeeded unexpectedly"
4511323ec57SEd Masterestore_privatekeys
4521323ec57SEd Maste
4531323ec57SEd Masteverbose "multihop cycle no agent"
4541323ec57SEd Masteclear_agent
4551323ec57SEd Masteprepare_multihop_expected none "a b a a c d e"
4561323ec57SEd Maste$MULTIHOP_RUN "" a b a a c d e > $OBJ/ssh_output || \
4571323ec57SEd Maste	fail "multihop cycle no-agent fail"
4581323ec57SEd Mastediff $OBJ/ssh_output $OBJ/expect_a || fail "unexpected ssh output"
4591323ec57SEd Maste
4601323ec57SEd Masteverbose "multihop cycle agent unrestricted"
4611323ec57SEd Masteclear_agent
4621323ec57SEd Maste$SSHADD -q $OBJ/user_[abcde] || fail "add keys"
4631323ec57SEd Masteprepare_multihop_expected all "a b a a c d e"
4641323ec57SEd Maste$MULTIHOP_RUN "" a b a a c d e > $OBJ/ssh_output || \
4651323ec57SEd Maste	fail "multihop cycle agent ssh failed"
4661323ec57SEd Mastediff $OBJ/ssh_output $OBJ/expect_a || fail "unexpected ssh output"
4671323ec57SEd Maste
4681323ec57SEd Masteverbose "multihop cycle restricted deny"
4691323ec57SEd Masteclear_agent
4701323ec57SEd Maste$SSHADD -q -h host_x -H $OBJ/known_hosts $OBJ/user_[bcde] || fail "add keys"
4711323ec57SEd Maste$SSHADD -h host_a -h "host_a>host_b" -h "host_b>host_c" \
4721323ec57SEd Maste	-h "host_c>host_d" -h "host_d>host_e" \
4731323ec57SEd Maste	-H $OBJ/known_hosts -q $OBJ/user_a \
4741323ec57SEd Maste	|| fatal "add key user_a multihop"
4751323ec57SEd Masteprepare_multihop_expected filtered "a b a a c d e"
4761323ec57SEd Mastehide_privatekeys
4771323ec57SEd Maste$MULTIHOP_RUN "" a b a a c d e > $OBJ/ssh_output && \
4781323ec57SEd Maste	fail "multihop cycle restricted deny succeded unexpectedly"
4791323ec57SEd Masterestore_privatekeys
4801323ec57SEd Maste
4811323ec57SEd Masteverbose "multihop cycle restricted allow"
4821323ec57SEd Masteclear_agent
4831323ec57SEd Maste$SSHADD -q -h host_x -H $OBJ/known_hosts $OBJ/user_[bcde] || fail "add keys"
4841323ec57SEd Maste$SSHADD -h host_a -h "host_a>host_b" -h "host_b>host_c" \
4851323ec57SEd Maste	-h "host_c>host_d" -h "host_d>host_e" \
4861323ec57SEd Maste	-h "host_b>host_a" -h "host_a>host_a" -h "host_a>host_c" \
4871323ec57SEd Maste	-H $OBJ/known_hosts -q $OBJ/user_a \
4881323ec57SEd Maste	|| fatal "add key user_a multihop"
4891323ec57SEd Masteprepare_multihop_expected filtered "a b a a c d e"
4901323ec57SEd Mastehide_privatekeys
4911323ec57SEd Maste$MULTIHOP_RUN "" a b a a c d e > $OBJ/ssh_output || \
4921323ec57SEd Maste	fail "multihop cycle restricted allow failed"
4931323ec57SEd Mastediff $OBJ/ssh_output $OBJ/expect_a || fail "unexpected ssh output"
4941323ec57SEd Masterestore_privatekeys
4951323ec57SEd Maste
496