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