
Some checks failed
CIFuzz / Fuzzing (push) Waiting to run
C/C++ CI self-hosted / win10 cygwin-release (push) Waiting to run
C/C++ CI self-hosted / ARM default (push) Waiting to run
C/C++ CI self-hosted / ARM64 default (push) Waiting to run
C/C++ CI self-hosted / alpine default (push) Waiting to run
C/C++ CI self-hosted / centos7 default (push) Waiting to run
C/C++ CI self-hosted / debian-i386 default (push) Waiting to run
C/C++ CI self-hosted / dfly30 default (push) Waiting to run
C/C++ CI self-hosted / dfly48 default (push) Waiting to run
C/C++ CI self-hosted / dfly60 default (push) Waiting to run
C/C++ CI self-hosted / dfly62 default (push) Waiting to run
C/C++ CI self-hosted / dfly64 default (push) Waiting to run
C/C++ CI self-hosted / fbsd10 default (push) Waiting to run
C/C++ CI self-hosted / fbsd12 default (push) Waiting to run
C/C++ CI self-hosted / fbsd13 default (push) Waiting to run
C/C++ CI self-hosted / fbsd14 default (push) Waiting to run
C/C++ CI self-hosted / nbsd10 default (push) Waiting to run
C/C++ CI self-hosted / nbsd3 default (push) Waiting to run
C/C++ CI self-hosted / nbsd4 default (push) Waiting to run
C/C++ CI self-hosted / nbsd8 default (push) Waiting to run
C/C++ CI self-hosted / nbsd9 default (push) Waiting to run
C/C++ CI self-hosted / obsd51 default (push) Waiting to run
C/C++ CI self-hosted / obsd67 default (push) Waiting to run
C/C++ CI self-hosted / obsd72 default (push) Waiting to run
C/C++ CI self-hosted / obsd73 default (push) Waiting to run
C/C++ CI self-hosted / obsd74 default (push) Waiting to run
C/C++ CI self-hosted / obsdsnap default (push) Waiting to run
C/C++ CI self-hosted / obsdsnap-i386 default (push) Waiting to run
C/C++ CI self-hosted / omnios default (push) Waiting to run
C/C++ CI self-hosted / openindiana default (push) Waiting to run
C/C++ CI self-hosted / ubuntu-2204 default (push) Waiting to run
C/C++ CI self-hosted / obsd-arm64 default (push) Waiting to run
C/C++ CI self-hosted / aix51 default (push) Waiting to run
C/C++ CI self-hosted / fbsd14-ppc64 default (push) Waiting to run
C/C++ CI self-hosted / sol10 default (push) Waiting to run
C/C++ CI self-hosted / sol11 default (push) Waiting to run
C/C++ CI self-hosted / win10 default (push) Waiting to run
C/C++ CI self-hosted / debian-riscv64 default (push) Waiting to run
C/C++ CI self-hosted / openwrt-mips default (push) Waiting to run
C/C++ CI self-hosted / openwrt-mipsel default (push) Waiting to run
C/C++ CI self-hosted / ARM64 pam (push) Waiting to run
C/C++ CI self-hosted / centos7 pam (push) Waiting to run
C/C++ CI self-hosted / debian-i386 pam (push) Waiting to run
C/C++ CI self-hosted / dfly48 pam (push) Waiting to run
C/C++ CI self-hosted / dfly58 pam (push) Waiting to run
C/C++ CI self-hosted / dfly60 pam (push) Waiting to run
C/C++ CI self-hosted / dfly62 pam (push) Waiting to run
C/C++ CI self-hosted / dfly64 pam (push) Waiting to run
C/C++ CI self-hosted / fbsd10 pam (push) Waiting to run
C/C++ CI self-hosted / fbsd12 pam (push) Waiting to run
C/C++ CI self-hosted / fbsd13 pam (push) Waiting to run
C/C++ CI self-hosted / fbsd14 pam (push) Waiting to run
C/C++ CI self-hosted / nbsd10 pam (push) Waiting to run
C/C++ CI self-hosted / nbsd8 pam (push) Waiting to run
C/C++ CI self-hosted / nbsd9 pam (push) Waiting to run
C/C++ CI self-hosted / omnios pam (push) Waiting to run
C/C++ CI self-hosted / openindiana pam (push) Waiting to run
C/C++ CI self-hosted / sol10 pam (push) Waiting to run
C/C++ CI self-hosted / sol11 pam-krb5 (push) Waiting to run
C/C++ CI self-hosted / sol11 sol64 (push) Waiting to run
C/C++ CI self-hosted / dfly30 without-openssl (push) Waiting to run
C/C++ CI / ubuntu-latest aws-lc (push) Failing after 31s
C/C++ CI / ubuntu-latest boringssl (push) Failing after 31s
C/C++ CI / ubuntu-latest clang-15 (push) Failing after 31s
C/C++ CI / ubuntu-latest clang-19 (push) Failing after 19s
C/C++ CI / ubuntu-latest default (push) Failing after 3s
C/C++ CI / ubuntu-latest gcc-14 (push) Failing after 4s
C/C++ CI / ubuntu-latest libressl-3.2.6 (push) Failing after 4s
C/C++ CI / ubuntu-latest libressl-3.3.6 (push) Failing after 3s
C/C++ CI / ubuntu-latest libressl-3.4.3 (push) Failing after 3s
C/C++ CI / ubuntu-latest libressl-3.5.3 (push) Failing after 4s
C/C++ CI / ubuntu-latest libressl-3.6.1 (push) Failing after 4s
C/C++ CI / ubuntu-latest libressl-3.7.2 (push) Failing after 4s
C/C++ CI / ubuntu-latest libressl-3.8.4 (push) Failing after 3s
C/C++ CI / ubuntu-latest libressl-3.9.2 (push) Failing after 3s
C/C++ CI / ubuntu-latest libressl-4.0.0 (push) Failing after 4s
C/C++ CI / ubuntu-latest libressl-master (push) Failing after 4s
C/C++ CI / ubuntu-latest musl (push) Failing after 3s
C/C++ CI / ubuntu-latest openssl-1.1.1 (push) Failing after 4s
C/C++ CI / ubuntu-latest openssl-1.1.1_stable (push) Failing after 4s
C/C++ CI / ubuntu-latest openssl-1.1.1t (push) Failing after 3s
C/C++ CI / ubuntu-latest openssl-1.1.1w (push) Failing after 4s
C/C++ CI / ubuntu-latest openssl-3.0 (push) Failing after 3s
C/C++ CI / ubuntu-latest openssl-3.0.0 (push) Failing after 3s
C/C++ CI / ubuntu-latest openssl-3.0.15 (push) Failing after 4s
C/C++ CI / ubuntu-latest openssl-3.1 (push) Failing after 3s
C/C++ CI / ubuntu-latest openssl-3.1.0 (push) Failing after 3s
C/C++ CI / ubuntu-latest openssl-3.1.7 (push) Failing after 4s
C/C++ CI / ubuntu-latest openssl-3.2 (push) Failing after 4s
C/C++ CI / ubuntu-latest openssl-3.2.3 (push) Failing after 3s
C/C++ CI / ubuntu-latest openssl-3.3 (push) Failing after 3s
C/C++ CI / ubuntu-latest openssl-3.3.2 (push) Failing after 4s
C/C++ CI / ubuntu-latest openssl-3.4.0 (push) Failing after 3s
C/C++ CI / ubuntu-latest openssl-master (push) Failing after 3s
C/C++ CI / ubuntu-latest openssl-noec (push) Failing after 4s
C/C++ CI / ubuntu-latest putty-0.71 (push) Failing after 4s
C/C++ CI / ubuntu-latest putty-0.72 (push) Failing after 3s
C/C++ CI / ubuntu-latest putty-0.73 (push) Failing after 4s
C/C++ CI / ubuntu-latest putty-0.74 (push) Failing after 4s
C/C++ CI / ubuntu-latest putty-0.75 (push) Failing after 3s
C/C++ CI / ubuntu-latest putty-0.76 (push) Failing after 4s
C/C++ CI / ubuntu-latest putty-0.77 (push) Failing after 4s
C/C++ CI / ubuntu-latest putty-0.78 (push) Failing after 3s
C/C++ CI / ubuntu-latest putty-0.79 (push) Failing after 3s
C/C++ CI / ubuntu-latest putty-0.80 (push) Failing after 4s
C/C++ CI / ubuntu-latest putty-0.81 (push) Failing after 4s
C/C++ CI / ubuntu-latest putty-0.82 (push) Failing after 3s
C/C++ CI / ubuntu-latest putty-0.83 (push) Failing after 4s
C/C++ CI / ubuntu-latest putty-snapshot (push) Failing after 4s
C/C++ CI / ubuntu-latest tcmalloc (push) Failing after 3s
C/C++ CI / ubuntu-latest zlib-develop (push) Failing after 3s
C/C++ CI / ubuntu-22.04 c89 (push) Has been cancelled
C/C++ CI / ubuntu-22.04 clang-11 (push) Has been cancelled
C/C++ CI / ubuntu-22.04 clang-12-Werror (push) Has been cancelled
C/C++ CI / ubuntu-22.04 clang-14 (push) Has been cancelled
C/C++ CI / ubuntu-22.04 clang-sanitize-address (push) Has been cancelled
C/C++ CI / ubuntu-22.04 clang-sanitize-undefined (push) Has been cancelled
C/C++ CI / windows-2019 cygwin-release (push) Has been cancelled
C/C++ CI / windows-2022 cygwin-release (push) Has been cancelled
C/C++ CI / macos-13 default (push) Has been cancelled
C/C++ CI / macos-14 default (push) Has been cancelled
C/C++ CI / macos-15 default (push) Has been cancelled
C/C++ CI / ubuntu-22.04 default (push) Has been cancelled
C/C++ CI / ubuntu-22.04-arm default (push) Has been cancelled
C/C++ CI / ubuntu-24.04-arm default (push) Has been cancelled
C/C++ CI / windows-2019 default (push) Has been cancelled
C/C++ CI / windows-2022 default (push) Has been cancelled
C/C++ CI / ubuntu-22.04 gcc-11-Werror (push) Has been cancelled
C/C++ CI / ubuntu-22.04 gcc-12-Werror (push) Has been cancelled
C/C++ CI / ubuntu-22.04 gcc-9 (push) Has been cancelled
C/C++ CI / ubuntu-22.04 gcc-sanitize-address (push) Has been cancelled
C/C++ CI / ubuntu-22.04 gcc-sanitize-undefined (push) Has been cancelled
C/C++ CI / ubuntu-22.04 hardenedmalloc (push) Has been cancelled
C/C++ CI / ubuntu-22.04 heimdal (push) Has been cancelled
C/C++ CI / ubuntu-22.04 kitchensink (push) Has been cancelled
C/C++ CI / ubuntu-22.04-arm kitchensink (push) Has been cancelled
C/C++ CI / ubuntu-24.04-arm kitchensink (push) Has been cancelled
C/C++ CI / ubuntu-22.04 krb5 (push) Has been cancelled
C/C++ CI / ubuntu-22.04 libedit (push) Has been cancelled
C/C++ CI / macos-13 pam (push) Has been cancelled
C/C++ CI / macos-14 pam (push) Has been cancelled
C/C++ CI / macos-15 pam (push) Has been cancelled
C/C++ CI / ubuntu-22.04 pam (push) Has been cancelled
C/C++ CI / ubuntu-22.04 selinux (push) Has been cancelled
C/C++ CI / ubuntu-22.04 sk (push) Has been cancelled
C/C++ CI / ubuntu-22.04 valgrind-1 (push) Has been cancelled
C/C++ CI / ubuntu-22.04 valgrind-2 (push) Has been cancelled
C/C++ CI / ubuntu-22.04 valgrind-3 (push) Has been cancelled
C/C++ CI / ubuntu-22.04 valgrind-4 (push) Has been cancelled
C/C++ CI / ubuntu-22.04 valgrind-unit (push) Has been cancelled
C/C++ CI / ubuntu-22.04 without-openssl (push) Has been cancelled
496 lines
15 KiB
Bash
496 lines
15 KiB
Bash
# $OpenBSD: agent-restrict.sh,v 1.7 2025/03/28 21:45:55 dtucker Exp $
|
|
# Placed in the Public Domain.
|
|
|
|
tid="agent restrictions"
|
|
|
|
SSH_AUTH_SOCK="$OBJ/agent.sock"
|
|
export SSH_AUTH_SOCK
|
|
rm -f $SSH_AUTH_SOCK $OBJ/agent.log $OBJ/host_[abcdex]* $OBJ/user_[abcdex]*
|
|
rm -f $OBJ/sshd_proxy_host* $OBJ/ssh_output* $OBJ/expect_*
|
|
rm -f $OBJ/ssh_proxy[._]* $OBJ/command
|
|
|
|
verbose "generate keys"
|
|
for h in a b c d e x ca ; do
|
|
$SSHKEYGEN -q -t ed25519 -C host_$h -N '' -f $OBJ/host_$h || \
|
|
fatal "ssh-keygen hostkey failed"
|
|
$SSHKEYGEN -q -t ed25519 -C user_$h -N '' -f $OBJ/user_$h || \
|
|
fatal "ssh-keygen userkey failed"
|
|
done
|
|
|
|
# Make some hostcerts
|
|
for h in d e ; do
|
|
id="host_$h"
|
|
$SSHKEYGEN -q -s $OBJ/host_ca -I $id -n $id -h $OBJ/host_${h}.pub || \
|
|
fatal "ssh-keygen certify failed"
|
|
done
|
|
|
|
verbose "prepare client config"
|
|
egrep -vi '(identityfile|hostname|hostkeyalias|proxycommand)' \
|
|
$OBJ/ssh_proxy > $OBJ/ssh_proxy.bak
|
|
cat << _EOF > $OBJ/ssh_proxy
|
|
IdentitiesOnly yes
|
|
ForwardAgent yes
|
|
ExitOnForwardFailure yes
|
|
_EOF
|
|
cp $OBJ/ssh_proxy $OBJ/ssh_proxy_noid
|
|
for h in a b c d e ; do
|
|
cat << _EOF >> $OBJ/ssh_proxy
|
|
Host host_$h
|
|
Hostname host_$h
|
|
HostkeyAlias host_$h
|
|
IdentityFile $OBJ/user_$h
|
|
ProxyCommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${TEST_SSH_SSHD_ENV} ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy_host_$h
|
|
_EOF
|
|
# Variant with no specified keys.
|
|
cat << _EOF >> $OBJ/ssh_proxy_noid
|
|
Host host_$h
|
|
Hostname host_$h
|
|
HostkeyAlias host_$h
|
|
ProxyCommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${TEST_SSH_SSHD_ENV} ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy_host_$h
|
|
_EOF
|
|
done
|
|
cat $OBJ/ssh_proxy.bak >> $OBJ/ssh_proxy
|
|
cat $OBJ/ssh_proxy.bak >> $OBJ/ssh_proxy_noid
|
|
|
|
LC_ALL=C
|
|
export LC_ALL
|
|
echo "SetEnv LC_ALL=${LC_ALL}" >> sshd_proxy
|
|
|
|
verbose "prepare known_hosts"
|
|
rm -f $OBJ/known_hosts
|
|
for h in a b c x ; do
|
|
(printf "host_$h " ; cat $OBJ/host_${h}.pub) >> $OBJ/known_hosts
|
|
done
|
|
(printf "@cert-authority host_* " ; cat $OBJ/host_ca.pub) >> $OBJ/known_hosts
|
|
|
|
verbose "prepare server configs"
|
|
egrep -vi '(hostkey|pidfile)' $OBJ/sshd_proxy \
|
|
> $OBJ/sshd_proxy.bak
|
|
for h in a b c d e; do
|
|
cp $OBJ/sshd_proxy.bak $OBJ/sshd_proxy_host_$h
|
|
cat << _EOF >> $OBJ/sshd_proxy_host_$h
|
|
ExposeAuthInfo yes
|
|
PidFile none
|
|
Hostkey $OBJ/host_$h
|
|
_EOF
|
|
done
|
|
for h in d e ; do
|
|
echo "HostCertificate $OBJ/host_${h}-cert.pub" \
|
|
>> $OBJ/sshd_proxy_host_$h
|
|
done
|
|
# Create authorized_keys with canned command.
|
|
reset_keys() {
|
|
_whichcmd="$1"
|
|
_command=""
|
|
case "$_whichcmd" in
|
|
authinfo) _command="cat \$SSH_USER_AUTH" ;;
|
|
keylist) _command="$SSHADD -L | cut -d' ' -f-2 | sort" ;;
|
|
*) fatal "unsupported command $_whichcmd" ;;
|
|
esac
|
|
trace "reset keys"
|
|
>$OBJ/authorized_keys_$USER
|
|
for h in e d c b a; do
|
|
(printf "%s" "restrict,agent-forwarding,command=\"$_command\" ";
|
|
cat $OBJ/user_$h.pub) >> $OBJ/authorized_keys_$USER
|
|
done
|
|
}
|
|
# Prepare a key for comparison with ExposeAuthInfo/$SSH_USER_AUTH.
|
|
expect_key() {
|
|
_key="$OBJ/${1}.pub"
|
|
_file="$OBJ/$2"
|
|
(printf "publickey " ; cut -d' ' -f-2 $_key) > $_file
|
|
}
|
|
# Prepare expect_* files to compare against authinfo forced command to ensure
|
|
# keys used for authentication match.
|
|
reset_expect_keys() {
|
|
for u in a b c d e; do
|
|
expect_key user_$u expect_$u
|
|
done
|
|
}
|
|
# ssh to host, expecting success and that output matched expectation for
|
|
# that host (expect_$h file).
|
|
expect_succeed() {
|
|
_id="$1"
|
|
_case="$2"
|
|
shift; shift; _extra="$@"
|
|
_host="host_$_id"
|
|
trace "connect $_host expect success"
|
|
rm -f $OBJ/ssh_output
|
|
${SSH} $_extra -F $OBJ/ssh_proxy $_host true > $OBJ/ssh_output
|
|
_s=$?
|
|
test $_s -eq 0 || fail "host $_host $_case fail, exit status $_s"
|
|
diff $OBJ/ssh_output $OBJ/expect_${_id} ||
|
|
fail "unexpected ssh output"
|
|
}
|
|
# ssh to host using explicit key, expecting success and that the key was
|
|
# actually used for authentication.
|
|
expect_succeed_key() {
|
|
_id="$1"
|
|
_key="$2"
|
|
_case="$3"
|
|
shift; shift; shift; _extra="$@"
|
|
_host="host_$_id"
|
|
trace "connect $_host expect success, with key $_key"
|
|
_keyfile="$OBJ/$_key"
|
|
rm -f $OBJ/ssh_output
|
|
${SSH} $_extra -F $OBJ/ssh_proxy_noid \
|
|
-oIdentityFile=$_keyfile $_host true > $OBJ/ssh_output
|
|
_s=$?
|
|
test $_s -eq 0 || fail "host $_host $_key $_case fail, exit status $_s"
|
|
expect_key $_key expect_key
|
|
diff $OBJ/ssh_output $OBJ/expect_key ||
|
|
fail "incorrect key used for authentication"
|
|
}
|
|
# ssh to a host, expecting it to fail.
|
|
expect_fail() {
|
|
_host="$1"
|
|
_case="$2"
|
|
shift; shift; _extra="$@"
|
|
trace "connect $_host expect failure"
|
|
${SSH} $_extra -F $OBJ/ssh_proxy $_host true >/dev/null && \
|
|
fail "host $_host $_case succeeded unexpectedly"
|
|
}
|
|
# ssh to a host using an explicit key, expecting it to fail.
|
|
expect_fail_key() {
|
|
_id="$1"
|
|
_key="$2"
|
|
_case="$3"
|
|
shift; shift; shift; _extra="$@"
|
|
_host="host_$_id"
|
|
trace "connect $_host expect failure, with key $_key"
|
|
_keyfile="$OBJ/$_key"
|
|
${SSH} $_extra -F $OBJ/ssh_proxy_noid -oIdentityFile=$_keyfile \
|
|
$_host true > $OBJ/ssh_output && \
|
|
fail "host $_host $_key $_case succeeded unexpectedly"
|
|
}
|
|
# Move the private key files out of the way to force use of agent-hosted keys.
|
|
hide_privatekeys() {
|
|
trace "hide private keys"
|
|
for u in a b c d e x; do
|
|
mv $OBJ/user_$u $OBJ/user_x$u || fatal "hide privkey $u"
|
|
done
|
|
}
|
|
# Put the private key files back.
|
|
restore_privatekeys() {
|
|
trace "restore private keys"
|
|
for u in a b c d e x; do
|
|
mv $OBJ/user_x$u $OBJ/user_$u || fatal "restore privkey $u"
|
|
done
|
|
}
|
|
clear_agent() {
|
|
${SSHADD} -D > /dev/null 2>&1 || fatal "clear agent failed"
|
|
}
|
|
|
|
reset_keys authinfo
|
|
reset_expect_keys
|
|
|
|
verbose "authentication w/o agent"
|
|
for h in a b c d e ; do
|
|
expect_succeed $h "w/o agent"
|
|
wrongkey=user_e
|
|
test "$h" = "e" && wrongkey=user_a
|
|
expect_succeed_key $h $wrongkey "\"wrong\" key w/o agent"
|
|
done
|
|
hide_privatekeys
|
|
for h in a b c d e ; do
|
|
expect_fail $h "w/o agent"
|
|
done
|
|
restore_privatekeys
|
|
|
|
verbose "start agent"
|
|
${SSHAGENT} ${EXTRA_AGENT_ARGS} -d -a $SSH_AUTH_SOCK > $OBJ/agent.log 2>&1 &
|
|
AGENT_PID=$!
|
|
trap "kill $AGENT_PID" EXIT
|
|
sleep 4 # Give it a chance to start
|
|
# Check that it's running.
|
|
${SSHADD} -l > /dev/null 2>&1
|
|
if [ $? -ne 1 ]; then
|
|
fail "ssh-add -l did not fail with exit code 1"
|
|
fi
|
|
|
|
verbose "authentication with agent (no restrict)"
|
|
for u in a b c d e x; do
|
|
$SSHADD -q $OBJ/user_$u || fatal "add key $u unrestricted"
|
|
done
|
|
hide_privatekeys
|
|
for h in a b c d e ; do
|
|
expect_succeed $h "with agent"
|
|
wrongkey=user_e
|
|
test "$h" = "e" && wrongkey=user_a
|
|
expect_succeed_key $h $wrongkey "\"wrong\" key with agent"
|
|
done
|
|
|
|
verbose "unrestricted keylist"
|
|
reset_keys keylist
|
|
rm -f $OBJ/expect_list.pre
|
|
# List of keys from agent should contain everything.
|
|
for u in a b c d e x; do
|
|
cut -d " " -f-2 $OBJ/user_${u}.pub >> $OBJ/expect_list.pre
|
|
done
|
|
sort $OBJ/expect_list.pre > $OBJ/expect_list
|
|
for h in a b c d e; do
|
|
cp $OBJ/expect_list $OBJ/expect_$h
|
|
expect_succeed $h "unrestricted keylist"
|
|
done
|
|
restore_privatekeys
|
|
|
|
verbose "authentication with agent (basic restrict)"
|
|
reset_keys authinfo
|
|
reset_expect_keys
|
|
for h in a b c d e; do
|
|
$SSHADD -h host_$h -H $OBJ/known_hosts -q $OBJ/user_$h \
|
|
|| fatal "add key $u basic restrict"
|
|
done
|
|
# One more, unrestricted
|
|
$SSHADD -q $OBJ/user_x || fatal "add unrestricted key"
|
|
hide_privatekeys
|
|
# Authentication to host with expected key should work.
|
|
for h in a b c d e ; do
|
|
expect_succeed $h "with agent"
|
|
done
|
|
# Authentication to host with incorrect key should fail.
|
|
verbose "authentication with agent incorrect key (basic restrict)"
|
|
for h in a b c d e ; do
|
|
wrongkey=user_e
|
|
test "$h" = "e" && wrongkey=user_a
|
|
expect_fail_key $h $wrongkey "wrong key with agent (basic restrict)"
|
|
done
|
|
|
|
verbose "keylist (basic restrict)"
|
|
reset_keys keylist
|
|
# List from forwarded agent should contain only user_x - the unrestricted key.
|
|
cut -d " " -f-2 $OBJ/user_x.pub > $OBJ/expect_list
|
|
for h in a b c d e; do
|
|
cp $OBJ/expect_list $OBJ/expect_$h
|
|
expect_succeed $h "keylist (basic restrict)"
|
|
done
|
|
restore_privatekeys
|
|
|
|
verbose "username"
|
|
reset_keys authinfo
|
|
reset_expect_keys
|
|
for h in a b c d e; do
|
|
$SSHADD -h "${USER}@host_$h" -H $OBJ/known_hosts -q $OBJ/user_$h \
|
|
|| fatal "add key $u basic restrict"
|
|
done
|
|
hide_privatekeys
|
|
for h in a b c d e ; do
|
|
expect_succeed $h "wildcard user"
|
|
done
|
|
restore_privatekeys
|
|
|
|
verbose "username wildcard"
|
|
reset_keys authinfo
|
|
reset_expect_keys
|
|
for h in a b c d e; do
|
|
$SSHADD -h "*@host_$h" -H $OBJ/known_hosts -q $OBJ/user_$h \
|
|
|| fatal "add key $u basic restrict"
|
|
done
|
|
hide_privatekeys
|
|
for h in a b c d e ; do
|
|
expect_succeed $h "wildcard user"
|
|
done
|
|
restore_privatekeys
|
|
|
|
verbose "username incorrect"
|
|
reset_keys authinfo
|
|
reset_expect_keys
|
|
for h in a b c d e; do
|
|
$SSHADD -h "--BADUSER@host_$h" -H $OBJ/known_hosts -q $OBJ/user_$h \
|
|
|| fatal "add key $u basic restrict"
|
|
done
|
|
hide_privatekeys
|
|
for h in a b c d e ; do
|
|
expect_fail $h "incorrect user"
|
|
done
|
|
restore_privatekeys
|
|
|
|
|
|
verbose "agent restriction honours certificate principal"
|
|
reset_keys authinfo
|
|
reset_expect_keys
|
|
clear_agent
|
|
$SSHADD -h host_e -H $OBJ/known_hosts -q $OBJ/user_d || fatal "add key"
|
|
hide_privatekeys
|
|
expect_fail d "restricted agent w/ incorrect cert principal"
|
|
restore_privatekeys
|
|
|
|
# Prepares the script used to drive chained ssh connections for the
|
|
# multihop tests. Believe me, this is easier than getting the escaping
|
|
# right for 5 hops on the command-line...
|
|
prepare_multihop_script() {
|
|
MULTIHOP_RUN=$OBJ/command
|
|
cat << _EOF > $MULTIHOP_RUN
|
|
#!/bin/sh
|
|
#set -x
|
|
me="\$1" ; shift
|
|
next="\$1"
|
|
if test ! -z "\$me" ; then
|
|
rm -f $OBJ/done
|
|
echo "HOSTNAME host_\$me"
|
|
echo "AUTHINFO"
|
|
cat \$SSH_USER_AUTH
|
|
fi
|
|
echo AGENT
|
|
$SSHADD -L | egrep "^ssh" | cut -d" " -f-2 | sort
|
|
if test -z "\$next" ; then
|
|
touch $OBJ/done
|
|
echo "FINISH"
|
|
e=0
|
|
else
|
|
echo NEXT
|
|
${SSH} -F $OBJ/ssh_proxy_noid -oIdentityFile=$OBJ/user_a \
|
|
host_\$next $MULTIHOP_RUN "\$@"
|
|
e=\$?
|
|
fi
|
|
echo "COMPLETE \"\$me\""
|
|
if test ! -z "\$me" ; then
|
|
if test ! -f $OBJ/done ; then
|
|
echo "DONE MARKER MISSING"
|
|
test \$e -eq 0 && e=63
|
|
fi
|
|
fi
|
|
exit \$e
|
|
_EOF
|
|
chmod u+x $MULTIHOP_RUN
|
|
}
|
|
|
|
# Prepare expected output for multihop tests at expect_a
|
|
prepare_multihop_expected() {
|
|
_keys="$1"
|
|
_hops="a b c d e"
|
|
test -z "$2" || _hops="$2"
|
|
_revhops=$(echo "$_hops" | rev)
|
|
_lasthop=$(echo "$_hops" | sed 's/.* //')
|
|
|
|
rm -f $OBJ/expect_keys
|
|
for h in a b c d e; do
|
|
cut -d" " -f-2 $OBJ/user_${h}.pub >> $OBJ/expect_keys
|
|
done
|
|
rm -f $OBJ/expect_a
|
|
echo "AGENT" >> $OBJ/expect_a
|
|
test "x$_keys" = "xnone" || sort $OBJ/expect_keys >> $OBJ/expect_a
|
|
echo "NEXT" >> $OBJ/expect_a
|
|
for h in $_hops ; do
|
|
echo "HOSTNAME host_$h" >> $OBJ/expect_a
|
|
echo "AUTHINFO" >> $OBJ/expect_a
|
|
(printf "publickey " ; cut -d" " -f-2 $OBJ/user_a.pub) >> $OBJ/expect_a
|
|
echo "AGENT" >> $OBJ/expect_a
|
|
if test "x$_keys" = "xall" ; then
|
|
sort $OBJ/expect_keys >> $OBJ/expect_a
|
|
fi
|
|
if test "x$h" != "x$_lasthop" ; then
|
|
if test "x$_keys" = "xfiltered" ; then
|
|
cut -d" " -f-2 $OBJ/user_a.pub >> $OBJ/expect_a
|
|
fi
|
|
echo "NEXT" >> $OBJ/expect_a
|
|
fi
|
|
done
|
|
echo "FINISH" >> $OBJ/expect_a
|
|
for h in $_revhops "" ; do
|
|
echo "COMPLETE \"$h\"" >> $OBJ/expect_a
|
|
done
|
|
}
|
|
|
|
prepare_multihop_script
|
|
cp $OBJ/user_a.pub $OBJ/authorized_keys_$USER # only one key used.
|
|
|
|
verbose "multihop without agent"
|
|
clear_agent
|
|
prepare_multihop_expected none
|
|
$MULTIHOP_RUN "" a b c d e > $OBJ/ssh_output || fail "multihop no agent ssh failed"
|
|
diff $OBJ/ssh_output $OBJ/expect_a || fail "unexpected ssh output"
|
|
|
|
verbose "multihop agent unrestricted"
|
|
clear_agent
|
|
$SSHADD -q $OBJ/user_[abcde]
|
|
prepare_multihop_expected all
|
|
$MULTIHOP_RUN "" a b c d e > $OBJ/ssh_output || fail "multihop no agent ssh failed"
|
|
diff $OBJ/ssh_output $OBJ/expect_a || fail "unexpected ssh output"
|
|
|
|
verbose "multihop restricted"
|
|
clear_agent
|
|
prepare_multihop_expected filtered
|
|
# Add user_a, with permission to connect through the whole chain.
|
|
$SSHADD -h host_a -h "host_a>host_b" -h "host_b>host_c" \
|
|
-h "host_c>host_d" -h "host_d>host_e" \
|
|
-H $OBJ/known_hosts -q $OBJ/user_a \
|
|
|| fatal "add key user_a multihop"
|
|
# Add the other keys, bound to a unused host.
|
|
$SSHADD -q -h host_x -H $OBJ/known_hosts $OBJ/user_[bcde] || fail "add keys"
|
|
hide_privatekeys
|
|
$MULTIHOP_RUN "" a b c d e > $OBJ/ssh_output || fail "multihop ssh failed"
|
|
diff $OBJ/ssh_output $OBJ/expect_a || fail "unexpected ssh output"
|
|
restore_privatekeys
|
|
|
|
verbose "multihop username"
|
|
$SSHADD -h host_a -h "host_a>${USER}@host_b" -h "host_b>${USER}@host_c" \
|
|
-h "host_c>${USER}@host_d" -h "host_d>${USER}@host_e" \
|
|
-H $OBJ/known_hosts -q $OBJ/user_a || fatal "add key user_a multihop"
|
|
hide_privatekeys
|
|
$MULTIHOP_RUN "" a b c d e > $OBJ/ssh_output || fail "multihop w/ user ssh failed"
|
|
diff $OBJ/ssh_output $OBJ/expect_a || fail "unexpected ssh output"
|
|
restore_privatekeys
|
|
|
|
verbose "multihop wildcard username"
|
|
$SSHADD -h host_a -h "host_a>*@host_b" -h "host_b>*@host_c" \
|
|
-h "host_c>*@host_d" -h "host_d>*@host_e" \
|
|
-H $OBJ/known_hosts -q $OBJ/user_a || fatal "add key user_a multihop"
|
|
hide_privatekeys
|
|
$MULTIHOP_RUN "" a b c d e > $OBJ/ssh_output || fail "multihop w/ user ssh failed"
|
|
diff $OBJ/ssh_output $OBJ/expect_a || fail "unexpected ssh output"
|
|
restore_privatekeys
|
|
|
|
verbose "multihop wrong username"
|
|
$SSHADD -h host_a -h "host_a>*@host_b" -h "host_b>*@host_c" \
|
|
-h "host_c>--BADUSER@host_d" -h "host_d>*@host_e" \
|
|
-H $OBJ/known_hosts -q $OBJ/user_a || fatal "add key user_a multihop"
|
|
hide_privatekeys
|
|
$MULTIHOP_RUN "" a b c d e > $OBJ/ssh_output && \
|
|
fail "multihop with wrong user succeeded unexpectedly"
|
|
restore_privatekeys
|
|
|
|
verbose "multihop cycle no agent"
|
|
clear_agent
|
|
prepare_multihop_expected none "a b a a c d e"
|
|
$MULTIHOP_RUN "" a b a a c d e > $OBJ/ssh_output || \
|
|
fail "multihop cycle no-agent fail"
|
|
diff $OBJ/ssh_output $OBJ/expect_a || fail "unexpected ssh output"
|
|
|
|
verbose "multihop cycle agent unrestricted"
|
|
clear_agent
|
|
$SSHADD -q $OBJ/user_[abcde] || fail "add keys"
|
|
prepare_multihop_expected all "a b a a c d e"
|
|
$MULTIHOP_RUN "" a b a a c d e > $OBJ/ssh_output || \
|
|
fail "multihop cycle agent ssh failed"
|
|
diff $OBJ/ssh_output $OBJ/expect_a || fail "unexpected ssh output"
|
|
|
|
verbose "multihop cycle restricted deny"
|
|
clear_agent
|
|
$SSHADD -q -h host_x -H $OBJ/known_hosts $OBJ/user_[bcde] || fail "add keys"
|
|
$SSHADD -h host_a -h "host_a>host_b" -h "host_b>host_c" \
|
|
-h "host_c>host_d" -h "host_d>host_e" \
|
|
-H $OBJ/known_hosts -q $OBJ/user_a \
|
|
|| fatal "add key user_a multihop"
|
|
prepare_multihop_expected filtered "a b a a c d e"
|
|
hide_privatekeys
|
|
$MULTIHOP_RUN "" a b a a c d e > $OBJ/ssh_output && \
|
|
fail "multihop cycle restricted deny succeded unexpectedly"
|
|
restore_privatekeys
|
|
|
|
verbose "multihop cycle restricted allow"
|
|
clear_agent
|
|
$SSHADD -q -h host_x -H $OBJ/known_hosts $OBJ/user_[bcde] || fail "add keys"
|
|
$SSHADD -h host_a -h "host_a>host_b" -h "host_b>host_c" \
|
|
-h "host_c>host_d" -h "host_d>host_e" \
|
|
-h "host_b>host_a" -h "host_a>host_a" -h "host_a>host_c" \
|
|
-H $OBJ/known_hosts -q $OBJ/user_a \
|
|
|| fatal "add key user_a multihop"
|
|
prepare_multihop_expected filtered "a b a a c d e"
|
|
hide_privatekeys
|
|
$MULTIHOP_RUN "" a b a a c d e > $OBJ/ssh_output || \
|
|
fail "multihop cycle restricted allow failed"
|
|
diff $OBJ/ssh_output $OBJ/expect_a || fail "unexpected ssh output"
|
|
restore_privatekeys
|
|
|