djm@openbsd.org | dd36932 | 2017-04-30 23:34:55 +0000 | [diff] [blame] | 1 | # $OpenBSD: forward-control.sh,v 1.4 2017/04/30 23:34:55 djm Exp $ |
Damien Miller | 999bd2d | 2012-12-03 10:13:39 +1100 | [diff] [blame] | 2 | # Placed in the Public Domain. |
| 3 | |
| 4 | tid="sshd control of local and remote forwarding" |
| 5 | |
| 6 | LFWD_PORT=3320 |
| 7 | RFWD_PORT=3321 |
| 8 | CTL=$OBJ/ctl-sock |
| 9 | READY=$OBJ/ready |
| 10 | |
| 11 | wait_for_file_to_appear() { |
| 12 | _path=$1 |
| 13 | _n=0 |
Tim Rice | 0ec7423 | 2013-02-20 21:37:55 -0800 | [diff] [blame] | 14 | while test ! -f $_path ; do |
Damien Miller | 999bd2d | 2012-12-03 10:13:39 +1100 | [diff] [blame] | 15 | test $_n -eq 1 && trace "waiting for $_path to appear" |
| 16 | _n=`expr $_n + 1` |
Darren Tucker | 834a0d6 | 2013-03-06 14:06:48 +1100 | [diff] [blame] | 17 | test $_n -ge 20 && return 1 |
Damien Miller | 999bd2d | 2012-12-03 10:13:39 +1100 | [diff] [blame] | 18 | sleep 1 |
| 19 | done |
| 20 | return 0 |
| 21 | } |
| 22 | |
| 23 | wait_for_process_to_exit() { |
| 24 | _pid=$1 |
| 25 | _n=0 |
| 26 | while kill -0 $_pid 2>/dev/null ; do |
| 27 | test $_n -eq 1 && trace "waiting for $_pid to exit" |
| 28 | _n=`expr $_n + 1` |
Darren Tucker | 834a0d6 | 2013-03-06 14:06:48 +1100 | [diff] [blame] | 29 | test $_n -ge 20 && return 1 |
Damien Miller | 999bd2d | 2012-12-03 10:13:39 +1100 | [diff] [blame] | 30 | sleep 1 |
| 31 | done |
| 32 | return 0 |
| 33 | } |
| 34 | |
djm@openbsd.org | dd36932 | 2017-04-30 23:34:55 +0000 | [diff] [blame] | 35 | # usage: check_lfwd Y|N message |
Damien Miller | 999bd2d | 2012-12-03 10:13:39 +1100 | [diff] [blame] | 36 | check_lfwd() { |
djm@openbsd.org | dd36932 | 2017-04-30 23:34:55 +0000 | [diff] [blame] | 37 | _expected=$1 |
| 38 | _message=$2 |
Damien Miller | 999bd2d | 2012-12-03 10:13:39 +1100 | [diff] [blame] | 39 | rm -f $READY |
djm@openbsd.org | dd36932 | 2017-04-30 23:34:55 +0000 | [diff] [blame] | 40 | ${SSH} -F $OBJ/ssh_proxy \ |
Damien Miller | 999bd2d | 2012-12-03 10:13:39 +1100 | [diff] [blame] | 41 | -L$LFWD_PORT:127.0.0.1:$PORT \ |
| 42 | -o ExitOnForwardFailure=yes \ |
Tim Rice | a514bc0 | 2013-02-26 19:35:26 -0800 | [diff] [blame] | 43 | -n host exec sh -c \'"sleep 60 & echo \$! > $READY ; wait "\' \ |
Damien Miller | 999bd2d | 2012-12-03 10:13:39 +1100 | [diff] [blame] | 44 | >/dev/null 2>&1 & |
| 45 | _sshpid=$! |
| 46 | wait_for_file_to_appear $READY || \ |
| 47 | fatal "check_lfwd ssh fail: $_message" |
| 48 | ${SSH} -F $OBJ/ssh_config -p $LFWD_PORT \ |
| 49 | -oConnectionAttempts=4 host true >/dev/null 2>&1 |
| 50 | _result=$? |
| 51 | kill $_sshpid `cat $READY` 2>/dev/null |
| 52 | wait_for_process_to_exit $_sshpid |
| 53 | if test "x$_expected" = "xY" -a $_result -ne 0 ; then |
| 54 | fail "check_lfwd failed (expecting success): $_message" |
| 55 | elif test "x$_expected" = "xN" -a $_result -eq 0 ; then |
| 56 | fail "check_lfwd succeeded (expecting failure): $_message" |
| 57 | elif test "x$_expected" != "xY" -a "x$_expected" != "xN" ; then |
| 58 | fatal "check_lfwd invalid argument \"$_expected\"" |
| 59 | else |
| 60 | verbose "check_lfwd done (expecting $_expected): $_message" |
| 61 | fi |
| 62 | } |
| 63 | |
djm@openbsd.org | dd36932 | 2017-04-30 23:34:55 +0000 | [diff] [blame] | 64 | # usage: check_rfwd Y|N message |
Damien Miller | 999bd2d | 2012-12-03 10:13:39 +1100 | [diff] [blame] | 65 | check_rfwd() { |
djm@openbsd.org | dd36932 | 2017-04-30 23:34:55 +0000 | [diff] [blame] | 66 | _expected=$1 |
| 67 | _message=$2 |
Damien Miller | 999bd2d | 2012-12-03 10:13:39 +1100 | [diff] [blame] | 68 | rm -f $READY |
djm@openbsd.org | dd36932 | 2017-04-30 23:34:55 +0000 | [diff] [blame] | 69 | ${SSH} -F $OBJ/ssh_proxy \ |
Damien Miller | 999bd2d | 2012-12-03 10:13:39 +1100 | [diff] [blame] | 70 | -R$RFWD_PORT:127.0.0.1:$PORT \ |
| 71 | -o ExitOnForwardFailure=yes \ |
Tim Rice | a514bc0 | 2013-02-26 19:35:26 -0800 | [diff] [blame] | 72 | -n host exec sh -c \'"sleep 60 & echo \$! > $READY ; wait "\' \ |
Damien Miller | 999bd2d | 2012-12-03 10:13:39 +1100 | [diff] [blame] | 73 | >/dev/null 2>&1 & |
| 74 | _sshpid=$! |
| 75 | wait_for_file_to_appear $READY |
| 76 | _result=$? |
| 77 | if test $_result -eq 0 ; then |
| 78 | ${SSH} -F $OBJ/ssh_config -p $RFWD_PORT \ |
| 79 | -oConnectionAttempts=4 host true >/dev/null 2>&1 |
| 80 | _result=$? |
| 81 | kill $_sshpid `cat $READY` 2>/dev/null |
| 82 | wait_for_process_to_exit $_sshpid |
| 83 | fi |
| 84 | if test "x$_expected" = "xY" -a $_result -ne 0 ; then |
| 85 | fail "check_rfwd failed (expecting success): $_message" |
| 86 | elif test "x$_expected" = "xN" -a $_result -eq 0 ; then |
| 87 | fail "check_rfwd succeeded (expecting failure): $_message" |
| 88 | elif test "x$_expected" != "xY" -a "x$_expected" != "xN" ; then |
| 89 | fatal "check_rfwd invalid argument \"$_expected\"" |
| 90 | else |
| 91 | verbose "check_rfwd done (expecting $_expected): $_message" |
| 92 | fi |
| 93 | } |
| 94 | |
| 95 | start_sshd |
| 96 | cp ${OBJ}/sshd_proxy ${OBJ}/sshd_proxy.bak |
| 97 | cp ${OBJ}/authorized_keys_${USER} ${OBJ}/authorized_keys_${USER}.bak |
| 98 | |
| 99 | # Sanity check: ensure the default config allows forwarding |
djm@openbsd.org | dd36932 | 2017-04-30 23:34:55 +0000 | [diff] [blame] | 100 | check_lfwd Y "default configuration" |
| 101 | check_rfwd Y "default configuration" |
Damien Miller | 999bd2d | 2012-12-03 10:13:39 +1100 | [diff] [blame] | 102 | |
| 103 | # Usage: all_tests yes|local|remote|no Y|N Y|N Y|N Y|N Y|N Y|N |
| 104 | all_tests() { |
| 105 | _tcpfwd=$1 |
| 106 | _plain_lfwd=$2 |
| 107 | _plain_rfwd=$3 |
| 108 | _nopermit_lfwd=$4 |
| 109 | _nopermit_rfwd=$5 |
| 110 | _permit_lfwd=$6 |
| 111 | _permit_rfwd=$7 |
| 112 | _badfwd=127.0.0.1:22 |
| 113 | _goodfwd=127.0.0.1:${PORT} |
djm@openbsd.org | dd36932 | 2017-04-30 23:34:55 +0000 | [diff] [blame] | 114 | cp ${OBJ}/authorized_keys_${USER}.bak ${OBJ}/authorized_keys_${USER} |
| 115 | _prefix="AllowTcpForwarding=$_tcpfwd" |
| 116 | # No PermitOpen |
| 117 | ( cat ${OBJ}/sshd_proxy.bak ; |
| 118 | echo "AllowTcpForwarding $_tcpfwd" ) \ |
| 119 | > ${OBJ}/sshd_proxy |
| 120 | check_lfwd $_plain_lfwd "$_prefix" |
| 121 | check_rfwd $_plain_rfwd "$_prefix" |
| 122 | # PermitOpen via sshd_config that doesn't match |
| 123 | ( cat ${OBJ}/sshd_proxy.bak ; |
| 124 | echo "AllowTcpForwarding $_tcpfwd" ; |
| 125 | echo "PermitOpen $_badfwd" ) \ |
| 126 | > ${OBJ}/sshd_proxy |
| 127 | check_lfwd $_nopermit_lfwd "$_prefix, !PermitOpen" |
| 128 | check_rfwd $_nopermit_rfwd "$_prefix, !PermitOpen" |
| 129 | # PermitOpen via sshd_config that does match |
| 130 | ( cat ${OBJ}/sshd_proxy.bak ; |
| 131 | echo "AllowTcpForwarding $_tcpfwd" ; |
| 132 | echo "PermitOpen $_badfwd $_goodfwd" ) \ |
| 133 | > ${OBJ}/sshd_proxy |
| 134 | # NB. permitopen via authorized_keys should have same |
| 135 | # success/fail as via sshd_config |
| 136 | # permitopen via authorized_keys that doesn't match |
| 137 | sed "s/^/permitopen=\"$_badfwd\" /" \ |
| 138 | < ${OBJ}/authorized_keys_${USER}.bak \ |
| 139 | > ${OBJ}/authorized_keys_${USER} || fatal "sed 1 fail" |
| 140 | ( cat ${OBJ}/sshd_proxy.bak ; |
| 141 | echo "AllowTcpForwarding $_tcpfwd" ) \ |
| 142 | > ${OBJ}/sshd_proxy |
| 143 | check_lfwd $_nopermit_lfwd "$_prefix, !permitopen" |
| 144 | check_rfwd $_nopermit_rfwd "$_prefix, !permitopen" |
| 145 | # permitopen via authorized_keys that does match |
| 146 | sed "s/^/permitopen=\"$_badfwd\",permitopen=\"$_goodfwd\" /" \ |
| 147 | < ${OBJ}/authorized_keys_${USER}.bak \ |
| 148 | > ${OBJ}/authorized_keys_${USER} || fatal "sed 2 fail" |
| 149 | ( cat ${OBJ}/sshd_proxy.bak ; |
| 150 | echo "AllowTcpForwarding $_tcpfwd" ) \ |
| 151 | > ${OBJ}/sshd_proxy |
| 152 | check_lfwd $_permit_lfwd "$_prefix, permitopen" |
| 153 | check_rfwd $_permit_rfwd "$_prefix, permitopen" |
Damien Miller | 999bd2d | 2012-12-03 10:13:39 +1100 | [diff] [blame] | 154 | } |
| 155 | |
| 156 | # no-permitopen mismatch-permitopen match-permitopen |
| 157 | # AllowTcpForwarding local remote local remote local remote |
| 158 | all_tests yes Y Y N Y Y Y |
| 159 | all_tests local Y N N N Y N |
| 160 | all_tests remote N Y N Y N Y |
| 161 | all_tests no N N N N N N |