1263970Sdes# $OpenBSD: forward-control.sh,v 1.2 2013/11/18 05:09:32 naddy Exp $ 2248613Sdes# Placed in the Public Domain. 3248613Sdes 4248613Sdestid="sshd control of local and remote forwarding" 5248613Sdes 6248613SdesLFWD_PORT=3320 7248613SdesRFWD_PORT=3321 8248613SdesCTL=$OBJ/ctl-sock 9248613SdesREADY=$OBJ/ready 10248613Sdes 11248613Sdeswait_for_file_to_appear() { 12248613Sdes _path=$1 13248613Sdes _n=0 14248613Sdes while test ! -f $_path ; do 15248613Sdes test $_n -eq 1 && trace "waiting for $_path to appear" 16248613Sdes _n=`expr $_n + 1` 17248613Sdes test $_n -ge 20 && return 1 18248613Sdes sleep 1 19248613Sdes done 20248613Sdes return 0 21248613Sdes} 22248613Sdes 23248613Sdeswait_for_process_to_exit() { 24248613Sdes _pid=$1 25248613Sdes _n=0 26248613Sdes while kill -0 $_pid 2>/dev/null ; do 27248613Sdes test $_n -eq 1 && trace "waiting for $_pid to exit" 28248613Sdes _n=`expr $_n + 1` 29248613Sdes test $_n -ge 20 && return 1 30248613Sdes sleep 1 31248613Sdes done 32248613Sdes return 0 33248613Sdes} 34248613Sdes 35248613Sdes# usage: check_lfwd protocol Y|N message 36248613Sdescheck_lfwd() { 37248613Sdes _proto=$1 38248613Sdes _expected=$2 39248613Sdes _message=$3 40248613Sdes rm -f $READY 41248613Sdes ${SSH} -oProtocol=$_proto -F $OBJ/ssh_proxy \ 42248613Sdes -L$LFWD_PORT:127.0.0.1:$PORT \ 43248613Sdes -o ExitOnForwardFailure=yes \ 44248613Sdes -n host exec sh -c \'"sleep 60 & echo \$! > $READY ; wait "\' \ 45248613Sdes >/dev/null 2>&1 & 46248613Sdes _sshpid=$! 47248613Sdes wait_for_file_to_appear $READY || \ 48248613Sdes fatal "check_lfwd ssh fail: $_message" 49248613Sdes ${SSH} -F $OBJ/ssh_config -p $LFWD_PORT \ 50248613Sdes -oConnectionAttempts=4 host true >/dev/null 2>&1 51248613Sdes _result=$? 52248613Sdes kill $_sshpid `cat $READY` 2>/dev/null 53248613Sdes wait_for_process_to_exit $_sshpid 54248613Sdes if test "x$_expected" = "xY" -a $_result -ne 0 ; then 55248613Sdes fail "check_lfwd failed (expecting success): $_message" 56248613Sdes elif test "x$_expected" = "xN" -a $_result -eq 0 ; then 57248613Sdes fail "check_lfwd succeeded (expecting failure): $_message" 58248613Sdes elif test "x$_expected" != "xY" -a "x$_expected" != "xN" ; then 59248613Sdes fatal "check_lfwd invalid argument \"$_expected\"" 60248613Sdes else 61248613Sdes verbose "check_lfwd done (expecting $_expected): $_message" 62248613Sdes fi 63248613Sdes} 64248613Sdes 65248613Sdes# usage: check_rfwd protocol Y|N message 66248613Sdescheck_rfwd() { 67248613Sdes _proto=$1 68248613Sdes _expected=$2 69248613Sdes _message=$3 70248613Sdes rm -f $READY 71248613Sdes ${SSH} -oProtocol=$_proto -F $OBJ/ssh_proxy \ 72248613Sdes -R$RFWD_PORT:127.0.0.1:$PORT \ 73248613Sdes -o ExitOnForwardFailure=yes \ 74248613Sdes -n host exec sh -c \'"sleep 60 & echo \$! > $READY ; wait "\' \ 75248613Sdes >/dev/null 2>&1 & 76248613Sdes _sshpid=$! 77248613Sdes wait_for_file_to_appear $READY 78248613Sdes _result=$? 79248613Sdes if test $_result -eq 0 ; then 80248613Sdes ${SSH} -F $OBJ/ssh_config -p $RFWD_PORT \ 81248613Sdes -oConnectionAttempts=4 host true >/dev/null 2>&1 82248613Sdes _result=$? 83248613Sdes kill $_sshpid `cat $READY` 2>/dev/null 84248613Sdes wait_for_process_to_exit $_sshpid 85248613Sdes fi 86248613Sdes if test "x$_expected" = "xY" -a $_result -ne 0 ; then 87248613Sdes fail "check_rfwd failed (expecting success): $_message" 88248613Sdes elif test "x$_expected" = "xN" -a $_result -eq 0 ; then 89248613Sdes fail "check_rfwd succeeded (expecting failure): $_message" 90248613Sdes elif test "x$_expected" != "xY" -a "x$_expected" != "xN" ; then 91248613Sdes fatal "check_rfwd invalid argument \"$_expected\"" 92248613Sdes else 93248613Sdes verbose "check_rfwd done (expecting $_expected): $_message" 94248613Sdes fi 95248613Sdes} 96248613Sdes 97248613Sdesstart_sshd 98248613Sdescp ${OBJ}/sshd_proxy ${OBJ}/sshd_proxy.bak 99248613Sdescp ${OBJ}/authorized_keys_${USER} ${OBJ}/authorized_keys_${USER}.bak 100248613Sdes 101248613Sdes# Sanity check: ensure the default config allows forwarding 102248613Sdesfor p in 1 2 ; do 103248613Sdes check_lfwd $p Y "proto $p, default configuration" 104248613Sdes check_rfwd $p Y "proto $p, default configuration" 105248613Sdesdone 106248613Sdes 107248613Sdes# Usage: all_tests yes|local|remote|no Y|N Y|N Y|N Y|N Y|N Y|N 108248613Sdesall_tests() { 109248613Sdes _tcpfwd=$1 110248613Sdes _plain_lfwd=$2 111248613Sdes _plain_rfwd=$3 112248613Sdes _nopermit_lfwd=$4 113248613Sdes _nopermit_rfwd=$5 114248613Sdes _permit_lfwd=$6 115248613Sdes _permit_rfwd=$7 116248613Sdes _badfwd=127.0.0.1:22 117248613Sdes _goodfwd=127.0.0.1:${PORT} 118248613Sdes for _proto in 1 2 ; do 119248613Sdes cp ${OBJ}/authorized_keys_${USER}.bak \ 120248613Sdes ${OBJ}/authorized_keys_${USER} 121248613Sdes _prefix="proto $_proto, AllowTcpForwarding=$_tcpfwd" 122248613Sdes # No PermitOpen 123248613Sdes ( cat ${OBJ}/sshd_proxy.bak ; 124248613Sdes echo "AllowTcpForwarding $_tcpfwd" ) \ 125248613Sdes > ${OBJ}/sshd_proxy 126248613Sdes check_lfwd $_proto $_plain_lfwd "$_prefix" 127248613Sdes check_rfwd $_proto $_plain_rfwd "$_prefix" 128248613Sdes # PermitOpen via sshd_config that doesn't match 129248613Sdes ( cat ${OBJ}/sshd_proxy.bak ; 130248613Sdes echo "AllowTcpForwarding $_tcpfwd" ; 131248613Sdes echo "PermitOpen $_badfwd" ) \ 132248613Sdes > ${OBJ}/sshd_proxy 133248613Sdes check_lfwd $_proto $_nopermit_lfwd "$_prefix, !PermitOpen" 134248613Sdes check_rfwd $_proto $_nopermit_rfwd "$_prefix, !PermitOpen" 135248613Sdes # PermitOpen via sshd_config that does match 136248613Sdes ( cat ${OBJ}/sshd_proxy.bak ; 137248613Sdes echo "AllowTcpForwarding $_tcpfwd" ; 138248613Sdes echo "PermitOpen $_badfwd $_goodfwd" ) \ 139248613Sdes > ${OBJ}/sshd_proxy 140248613Sdes # NB. permitopen via authorized_keys should have same 141248613Sdes # success/fail as via sshd_config 142248613Sdes # permitopen via authorized_keys that doesn't match 143248613Sdes sed "s/^/permitopen=\"$_badfwd\" /" \ 144248613Sdes < ${OBJ}/authorized_keys_${USER}.bak \ 145248613Sdes > ${OBJ}/authorized_keys_${USER} || fatal "sed 1 fail" 146248613Sdes ( cat ${OBJ}/sshd_proxy.bak ; 147248613Sdes echo "AllowTcpForwarding $_tcpfwd" ) \ 148248613Sdes > ${OBJ}/sshd_proxy 149248613Sdes check_lfwd $_proto $_nopermit_lfwd "$_prefix, !permitopen" 150248613Sdes check_rfwd $_proto $_nopermit_rfwd "$_prefix, !permitopen" 151248613Sdes # permitopen via authorized_keys that does match 152248613Sdes sed "s/^/permitopen=\"$_badfwd\",permitopen=\"$_goodfwd\" /" \ 153248613Sdes < ${OBJ}/authorized_keys_${USER}.bak \ 154248613Sdes > ${OBJ}/authorized_keys_${USER} || fatal "sed 2 fail" 155248613Sdes ( cat ${OBJ}/sshd_proxy.bak ; 156248613Sdes echo "AllowTcpForwarding $_tcpfwd" ) \ 157248613Sdes > ${OBJ}/sshd_proxy 158248613Sdes check_lfwd $_proto $_permit_lfwd "$_prefix, permitopen" 159248613Sdes check_rfwd $_proto $_permit_rfwd "$_prefix, permitopen" 160248613Sdes done 161248613Sdes} 162248613Sdes 163248613Sdes# no-permitopen mismatch-permitopen match-permitopen 164248613Sdes# AllowTcpForwarding local remote local remote local remote 165248613Sdesall_tests yes Y Y N Y Y Y 166248613Sdesall_tests local Y N N N Y N 167248613Sdesall_tests remote N Y N Y N Y 168248613Sdesall_tests no N N N N N N 169