dynamic-forward.sh revision 1.14
1#	$OpenBSD: dynamic-forward.sh,v 1.14 2023/01/02 07:03:57 djm Exp $
2#	Placed in the Public Domain.
3
4tid="dynamic forwarding"
5
6FWDPORT=`expr $PORT + 1`
7
8cp $OBJ/ssh_config $OBJ/ssh_config.orig
9
10if [ -x "`which nc`" ] && nc -h 2>&1 | grep "proxy address" >/dev/null; then
11	proxycmd="nc -x 127.0.0.1:$FWDPORT -X"
12elif [ -x "`which connect`" ]; then
13	proxycmd="connect -S 127.0.0.1:$FWDPORT -"
14else
15	echo "skipped (no suitable ProxyCommand found)"
16	exit 0
17fi
18trace "will use ProxyCommand $proxycmd"
19
20start_ssh() {
21	direction="$1"
22	arg="$2"
23	n=0
24	error="1"
25	trace "start dynamic -$direction forwarding, fork to background"
26	(cat $OBJ/ssh_config.orig ; echo "$arg") > $OBJ/ssh_config
27	while [ "$error" -ne 0 -a "$n" -lt 3 ]; do
28		n=`expr $n + 1`
29		${SSH} -F $OBJ/ssh_config -f -$direction $FWDPORT -q \
30		    -oExitOnForwardFailure=yes somehost exec sh -c \
31			\'"echo \$\$ > $OBJ/remote_pid; exec sleep 444"\'
32		error=$?
33		if [ "$error" -ne 0 ]; then
34			trace "forward failed attempt $n err $error"
35			sleep $n
36		fi
37	done
38	if [ "$error" -ne 0 ]; then
39		fatal "failed to start dynamic forwarding"
40	fi
41}
42
43stop_ssh() {
44	if [ -f $OBJ/remote_pid ]; then
45		remote=`cat $OBJ/remote_pid`
46		trace "terminate remote shell, pid $remote"
47		if [ $remote -gt 1 ]; then
48			kill -HUP $remote
49		fi
50	else
51		fail "no pid file: $OBJ/remote_pid"
52	fi
53}
54
55check_socks() {
56	direction=$1
57	expect_success=$2
58	for s in 4 5; do
59	    for h in 127.0.0.1 localhost; do
60		trace "testing ssh socks version $s host $h (-$direction)"
61		${SSH} -F $OBJ/ssh_config \
62			-o "ProxyCommand ${proxycmd}${s} $h $PORT 2>/dev/null" \
63			somehost cat ${DATA} > ${COPY}
64		r=$?
65		if [ "x$expect_success" = "xY" ] ; then
66			if [ $r -ne 0 ] ; then
67				fail "ssh failed with exit status $r"
68			fi
69			test -f ${COPY}	 || fail "failed copy ${DATA}"
70			cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}"
71		elif [ $r -eq 0 ] ; then
72			fail "ssh unexpectedly succeeded"
73		fi
74	    done
75	done
76}
77
78start_sshd
79
80for d in D R; do
81	verbose "test -$d forwarding"
82	start_ssh $d
83	check_socks $d Y
84	stop_ssh
85	test "x$d" = "xR" || continue
86	
87	# Test PermitRemoteOpen
88	verbose "PermitRemoteOpen=any"
89	start_ssh $d PermitRemoteOpen=any
90	check_socks $d Y
91	stop_ssh
92
93	verbose "PermitRemoteOpen=none"
94	start_ssh $d PermitRemoteOpen=none
95	check_socks $d N
96	stop_ssh
97
98	verbose "PermitRemoteOpen=explicit"
99	start_ssh $d \
100	    PermitRemoteOpen="127.0.0.1:$PORT [::1]:$PORT localhost:$PORT"
101	check_socks $d Y
102	stop_ssh
103
104	verbose "PermitRemoteOpen=disallowed"
105	start_ssh $d \
106	    PermitRemoteOpen="127.0.0.1:1 [::1]:1 localhost:1"
107	check_socks $d N
108	stop_ssh
109done
110