1# $OpenBSD: agent-pkcs11-restrict.sh,v 1.1 2023/12/18 14:49:39 djm Exp $ 2# Placed in the Public Domain. 3 4tid="pkcs11 agent constraint test" 5 6p11_setup || skip "No PKCS#11 library found" 7 8rm -f $SSH_AUTH_SOCK $OBJ/agent.log $OBJ/host_[abcx]* $OBJ/user_[abcx]* 9rm -f $OBJ/sshd_proxy_host* $OBJ/ssh_output* $OBJ/expect_* 10rm -f $OBJ/ssh_proxy[._]* $OBJ/command $OBJ/authorized_keys_* 11 12trace "generate host keys" 13for h in a b x ca ; do 14 $SSHKEYGEN -q -t ed25519 -C host_$h -N '' -f $OBJ/host_$h || \ 15 fatal "ssh-keygen hostkey failed" 16done 17 18# XXX test CA hostcerts too. 19 20key_for() { 21 case $h in 22 a) K="${SSH_SOFTHSM_DIR}/RSA.pub" ;; 23 b) K="${SSH_SOFTHSM_DIR}/EC.pub" ;; 24 *) K="" ;; 25 esac 26 export K 27} 28 29SSH_AUTH_SOCK="$OBJ/agent.sock" 30export SSH_AUTH_SOCK 31rm -f $SSH_AUTH_SOCK 32trace "start agent" 33${SSHAGENT} ${EXTRA_AGENT_ARGS} -d -a $SSH_AUTH_SOCK > $OBJ/agent.log 2>&1 & 34AGENT_PID=$! 35trap "kill $AGENT_PID" EXIT 36for x in 0 1 2 3 4 ; do 37 # Give it a chance to start 38 ${SSHADD} -l > /dev/null 2>&1 39 r=$? 40 test $r -eq 1 && break 41 sleep 1 42done 43if [ $r -ne 1 ]; then 44 fatal "ssh-add -l did not fail with exit code 1 (got $r)" 45fi 46 47# XXX a lot of this is a copy of agent-restrict.sh, but I couldn't see a nice 48# way to factor it out -djm 49 50trace "prepare client config" 51egrep -vi '(identityfile|hostname|hostkeyalias|proxycommand)' \ 52 $OBJ/ssh_proxy > $OBJ/ssh_proxy.bak 53cat << _EOF > $OBJ/ssh_proxy 54IdentitiesOnly yes 55ForwardAgent yes 56ExitOnForwardFailure yes 57_EOF 58cp $OBJ/ssh_proxy $OBJ/ssh_proxy_noid 59for h in a b ; do 60 key_for $h 61 cat << _EOF >> $OBJ/ssh_proxy 62Host host_$h 63 Hostname host_$h 64 HostkeyAlias host_$h 65 IdentityFile $K 66 ProxyCommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy_host_$h 67_EOF 68 # Variant with no specified keys. 69 cat << _EOF >> $OBJ/ssh_proxy_noid 70Host host_$h 71 Hostname host_$h 72 HostkeyAlias host_$h 73 ProxyCommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy_host_$h 74_EOF 75done 76cat $OBJ/ssh_proxy.bak >> $OBJ/ssh_proxy 77cat $OBJ/ssh_proxy.bak >> $OBJ/ssh_proxy_noid 78 79LC_ALL=C 80export LC_ALL 81echo "SetEnv LC_ALL=${LC_ALL}" >> sshd_proxy 82 83trace "prepare known_hosts" 84rm -f $OBJ/known_hosts 85for h in a b x ; do 86 (printf "host_$h " ; cat $OBJ/host_${h}.pub) >> $OBJ/known_hosts 87done 88 89trace "prepare server configs" 90egrep -vi '(hostkey|pidfile)' $OBJ/sshd_proxy \ 91 > $OBJ/sshd_proxy.bak 92for h in a b ; do 93 cp $OBJ/sshd_proxy.bak $OBJ/sshd_proxy_host_$h 94 cat << _EOF >> $OBJ/sshd_proxy_host_$h 95ExposeAuthInfo yes 96Hostkey $OBJ/host_$h 97_EOF 98 cp $OBJ/sshd_proxy_host_$h $OBJ/sshd_proxy_host_${h}.bak 99done 100 101trace "prepare authorized_keys" 102cat >> $OBJ/command << EOF 103#!/bin/sh 104echo USERAUTH 105cat \$SSH_USER_AUTH 106echo AGENT 107if $SSHADD -ql >/dev/null 2>&1 ; then 108 $SSHADD -L | cut -d' ' -f1-2 | sort 109else 110 echo NONE 111fi 112EOF 113chmod a+x $OBJ/command 114>$OBJ/authorized_keys_$USER 115for h in a b ; do 116 key_for $h 117 (printf "%s" "restrict,agent-forwarding,command=\"$OBJ/command\" "; 118 cat $K) >> $OBJ/authorized_keys_$USER 119done 120 121trace "unrestricted keys" 122$SSHADD -qD >/dev/null || fatal "clear agent failed" 123p11_ssh_add -qs ${TEST_SSH_PKCS11} || 124 fatal "failed to add keys" 125for h in a b ; do 126 key_for $h 127 echo USERAUTH > $OBJ/expect_$h 128 printf "publickey " >> $OBJ/expect_$h 129 cat $K >> $OBJ/expect_$h 130 echo AGENT >> $OBJ/expect_$h 131 $SSHADD -L | cut -d' ' -f1-2 | sort >> $OBJ/expect_$h 132 ${SSH} -F $OBJ/ssh_proxy -oIdentityFile=$K \ 133 host_$h true > $OBJ/ssh_output || fatal "test ssh $h failed" 134 cmp $OBJ/expect_$h $OBJ/ssh_output || fatal "unexpected output" 135done 136 137trace "restricted to different host" 138$SSHADD -qD >/dev/null || fatal "clear agent failed" 139p11_ssh_add -q -h host_x -s ${TEST_SSH_PKCS11} -H $OBJ/known_hosts || 140 fatal "failed to add keys" 141for h in a b ; do 142 key_for $h 143 ${SSH} -F $OBJ/ssh_proxy -oIdentityFile=$K \ 144 host_$h true > $OBJ/ssh_output && fatal "test ssh $h succeeded" 145done 146 147trace "restricted to destination host" 148$SSHADD -qD >/dev/null || fatal "clear agent failed" 149p11_ssh_add -q -h host_a -h host_b -s ${TEST_SSH_PKCS11} -H $OBJ/known_hosts || 150 fatal "failed to add keys" 151for h in a b ; do 152 key_for $h 153 echo USERAUTH > $OBJ/expect_$h 154 printf "publickey " >> $OBJ/expect_$h 155 cat $K >> $OBJ/expect_$h 156 echo AGENT >> $OBJ/expect_$h 157 echo NONE >> $OBJ/expect_$h 158 ${SSH} -F $OBJ/ssh_proxy -oIdentityFile=$K \ 159 host_$h true > $OBJ/ssh_output || fatal "test ssh $h failed" 160 cmp $OBJ/expect_$h $OBJ/ssh_output || fatal "unexpected output" 161done 162 163trace "restricted multihop" 164$SSHADD -qD >/dev/null || fatal "clear agent failed" 165p11_ssh_add -q -h host_a -h "host_a>host_b" \ 166 -s ${TEST_SSH_PKCS11} -H $OBJ/known_hosts || fatal "failed to add keys" 167key_for a 168AK=$K 169key_for b 170BK=$K 171# Prepare authorized_keys file to additionally ssh to host_b 172_command="echo LOCAL ; ${OBJ}/command ; echo REMOTE; ${SSH} -AF $OBJ/ssh_proxy -oIdentityFile=$BK host_b" 173(printf "%s" "restrict,agent-forwarding,command=\"$_command\" "; 174 cat $BK) > $OBJ/authorized_keys_a 175grep -vi AuthorizedKeysFile $OBJ/sshd_proxy_host_a.bak > $OBJ/sshd_proxy_host_a 176echo "AuthorizedKeysFile $OBJ/authorized_keys_a" >> $OBJ/sshd_proxy_host_a 177# Prepare expected output from both hosts. 178echo LOCAL > $OBJ/expect_a 179echo USERAUTH >> $OBJ/expect_a 180printf "publickey " >> $OBJ/expect_a 181cat $AK >> $OBJ/expect_a 182echo AGENT >> $OBJ/expect_a 183$SSHADD -L | cut -d' ' -f1-2 | sort >> $OBJ/expect_a 184echo REMOTE >> $OBJ/expect_a 185echo USERAUTH >> $OBJ/expect_a 186printf "publickey " >> $OBJ/expect_a 187cat $BK >> $OBJ/expect_a 188echo AGENT >> $OBJ/expect_a 189echo NONE >> $OBJ/expect_a 190${SSH} -AF $OBJ/ssh_proxy -oIdentityFile=$AK \ 191 host_a whatever > $OBJ/ssh_output || fatal "test ssh $h failed" 192cmp $OBJ/expect_a $OBJ/ssh_output || fatal "unexpected output" 193 194