xref: /freebsd/crypto/openssh/regress/percent.sh (revision d9cc3d558d00ee7f62dbef2032f099033c91d2a1)
1#	$OpenBSD: percent.sh,v 1.21 2025/04/08 23:10:46 djm Exp $
2#	Placed in the Public Domain.
3
4tid="percent expansions"
5
6USER=`id -u -n`
7USERID=`id -u`
8HOST=`hostname | cut -f1 -d.`
9HOSTNAME=`hostname`
10HASH=""
11
12# Localcommand is evaluated after connection because %T is not available
13# until then.  Because of this we use a different method of exercising it,
14# and we can't override the remote user otherwise authentication will fail.
15# We also have to explicitly enable it.
16echo "permitlocalcommand yes" >> $OBJ/ssh_proxy
17
18trial()
19{
20	opt="$1"; arg="$2"
21	expect=`echo "$3" | sed 's|^//|/|'` # approximate realpath
22
23	trace "test $opt=$arg $expect"
24	rm -f $OBJ/actual
25	got=""
26	case "$opt" in
27	localcommand)
28		${SSH} -F $OBJ/ssh_proxy -o $opt="echo '$arg' >$OBJ/actual" \
29		    somehost true
30		got=`cat $OBJ/actual`
31		;;
32	user|user-l|user-at)
33		if [ "$arg" = '%r' ] || [ "$arg" = '%C' ]; then
34			# User does not support %r, ie itself or %C.  Skip test.
35			got="$expect"
36		elif [ "$i" = "user" ]; then
37			got=`${SSH} -F $OBJ/ssh_proxy -o $opt="$arg" -G \
38			    remuser@somehost | awk '$1=="'$opt'"{print $2}'`
39		elif [ "$i" = "user-l" ]; then
40			# Also test ssh -l
41			got=`${SSH} -F $OBJ/ssh_proxy -l "$arg" -G \
42			    somehost | awk '$1=="'user'"{print $2}'`
43		elif [ "$i" = "user-at" ]; then
44			# Also test user@host
45			got=`${SSH} -F $OBJ/ssh_proxy -G "$arg@somehost" | \
46			    awk '$1=="'user'"{print $2}'`
47		fi
48		;;
49	userknownhostsfile)
50		# Move the userknownhosts file to what the expansion says,
51		# make sure ssh works then put it back.
52		mv "$OBJ/known_hosts" "$OBJ/$expect"
53		${SSH} -F $OBJ/ssh_proxy -o $opt="$OBJ/$arg" somehost true && \
54			got="$expect"
55		mv "$OBJ/$expect" "$OBJ/known_hosts"
56		;;
57	matchexec)
58		(cat $OBJ/ssh_proxy && \
59		 echo "Match Exec \"echo '$arg' >$OBJ/actual\"") \
60		    >$OBJ/ssh_proxy_match
61		${SSH} -F $OBJ/ssh_proxy_match remuser@somehost true || true
62		got=`cat $OBJ/actual`
63		;;
64	*forward)
65		# LocalForward and RemoteForward take two args and only
66		# operate on Unix domain socket paths
67		got=`${SSH} -F $OBJ/ssh_proxy -o $opt="/$arg /$arg" -G \
68		    remuser@somehost | awk '$1=="'$opt'"{print $2" "$3}'`
69		expect="/$expect /$expect"
70		;;
71	setenv)
72		# First make sure we don't expand variable names.
73		got=`${SSH} -F $OBJ/ssh_proxy -o $opt="$arg=TESTVAL" -G \
74		    remuser@somehost | awk '$1=="'$opt'"{print $2}'`
75		if [ "$got" != "$arg=TESTVAL" ]; then
76			fatal "incorrectly expanded setenv variable name"
77		fi
78		# Now check that the value expands as expected.
79		got=`${SSH} -F $OBJ/ssh_proxy -o $opt=TESTVAL="$arg" -G \
80		    remuser@somehost | awk '$1=="'$opt'"{print $2}'`
81		got=`echo "$got" | sed 's/^TESTVAL=//'`
82		;;
83	*)
84		got=`${SSH} -F $OBJ/ssh_proxy -o $opt="$arg" -G \
85		    remuser@somehost | awk '$1=="'$opt'"{print $2}'`
86	esac
87	if [ "$got" != "$expect" ]; then
88		fail "$opt=$arg expect $expect got $got"
89	fi
90}
91
92for i in matchexec localcommand remotecommand controlpath identityagent \
93    forwardagent localforward remoteforward revokedhostkeys \
94    user user-l user-at setenv userknownhostsfile; do
95	verbose $tid $i percent
96	case "$i" in
97	localcommand|userknownhostsfile)
98		# Any test that's going to actually make a connection needs
99		# to use the real username.
100		REMUSER=$USER ;;
101	*)
102		REMUSER=remuser ;;
103	esac
104	if [ "$i" = "$localcommand" ]; then
105		trial $i '%T' NONE
106	fi
107	# Matches implementation in readconf.c:ssh_connection_hash()
108	if [ ! -z "${OPENSSL_BIN}" ]; then
109		HASH=`printf "${HOSTNAME}127.0.0.1${PORT}${REMUSER}" |
110		    $OPENSSL_BIN sha1 | cut -f2 -d' '`
111		trial $i '%C' $HASH
112	fi
113	trial $i '%%' '%'
114	trial $i '%i' $USERID
115	trial $i '%h' 127.0.0.1
116	trial $i '%L' $HOST
117	trial $i '%l' $HOSTNAME
118	trial $i '%n' somehost
119	trial $i '%k' localhost-with-alias
120	trial $i '%p' $PORT
121	trial $i '%r' $REMUSER
122	trial $i '%u' $USER
123	# We can't specify a full path outside the regress dir, so skip tests
124	# containing %d for UserKnownHostsFile, and %r can't refer to itself.
125	if [ "$i" != "userknownhostsfile" ] && [ "$i" != "user" ] && \
126	     [ "$i" != "user-l" ] && [ "$i" != "user-at" ]; then
127		trial $i '%d' $HOME
128		in='%%/%i/%h/%d/%L/%l/%n/%p/%r/%u'
129		out="%/$USERID/127.0.0.1/$HOME/$HOST/$HOSTNAME/somehost/$PORT/$REMUSER/$USER"
130		if [ ! -z "${HASH}" ]; then
131			in="$in/%C"
132			out="$out/$HASH"
133		fi
134		trial $i "$in" "$out"
135	fi
136done
137
138# Subset of above since we don't expand shell-style variables on anything that
139# runs a command because the shell will expand those.
140for i in controlpath identityagent forwardagent localforward remoteforward \
141    user user-l user-at setenv userknownhostsfile; do
142	verbose $tid $i dollar
143	FOO=bar
144	export FOO
145	trial $i '${FOO}' $FOO
146done
147
148
149# A subset of options support tilde expansion
150for i in controlpath identityagent forwardagent; do
151	verbose $tid $i tilde
152	trial $i '~' $HOME/
153	trial $i '~/.ssh' $HOME/.ssh
154done
155