1#	$OpenBSD: percent.sh,v 1.17 2023/03/27 03:56:50 dtucker 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	userknownhostsfile)
33		# Move the userknownhosts file to what the expansion says,
34		# make sure ssh works then put it back.
35		mv "$OBJ/known_hosts" "$OBJ/$expect"
36		${SSH} -F $OBJ/ssh_proxy -o $opt="$OBJ/$arg" somehost true && \
37			got="$expect"
38		mv "$OBJ/$expect" "$OBJ/known_hosts"
39		;;
40	matchexec)
41		(cat $OBJ/ssh_proxy && \
42		 echo "Match Exec \"echo '$arg' >$OBJ/actual\"") \
43		    >$OBJ/ssh_proxy_match
44		${SSH} -F $OBJ/ssh_proxy_match remuser@somehost true || true
45		got=`cat $OBJ/actual`
46		;;
47	*forward)
48		# LocalForward and RemoteForward take two args and only
49		# operate on Unix domain socket paths
50		got=`${SSH} -F $OBJ/ssh_proxy -o $opt="/$arg /$arg" -G \
51		    remuser@somehost | awk '$1=="'$opt'"{print $2" "$3}'`
52		expect="/$expect /$expect"
53		;;
54	*)
55		got=`${SSH} -F $OBJ/ssh_proxy -o $opt="$arg" -G \
56		    remuser@somehost | awk '$1=="'$opt'"{print $2}'`
57	esac
58	if [ "$got" != "$expect" ]; then
59		fail "$opt=$arg expect $expect got $got"
60	fi
61}
62
63for i in matchexec localcommand remotecommand controlpath identityagent \
64    forwardagent localforward remoteforward revokedhostkeys \
65    userknownhostsfile; do
66	verbose $tid $i percent
67	case "$i" in
68	localcommand|userknownhostsfile)
69		# Any test that's going to actually make a connection needs
70		# to use the real username.
71		REMUSER=$USER ;;
72	*)
73		REMUSER=remuser ;;
74	esac
75	if [ "$i" = "$localcommand" ]; then
76		trial $i '%T' NONE
77	fi
78	# Matches implementation in readconf.c:ssh_connection_hash()
79	if [ ! -z "${OPENSSL_BIN}" ]; then
80		HASH=`printf "${HOSTNAME}127.0.0.1${PORT}$REMUSER" |
81		    $OPENSSL_BIN sha1 | cut -f2 -d' '`
82		trial $i '%C' $HASH
83	fi
84	trial $i '%%' '%'
85	trial $i '%i' $USERID
86	trial $i '%h' 127.0.0.1
87	trial $i '%L' $HOST
88	trial $i '%l' $HOSTNAME
89	trial $i '%n' somehost
90	trial $i '%k' localhost-with-alias
91	trial $i '%p' $PORT
92	trial $i '%r' $REMUSER
93	trial $i '%u' $USER
94	# We can't specify a full path outside the regress dir, so skip tests
95	# containing %d for UserKnownHostsFile
96	if [ "$i" != "userknownhostsfile" ]; then
97		trial $i '%d' $HOME
98		in='%%/%i/%h/%d/%L/%l/%n/%p/%r/%u'
99		out="%/$USERID/127.0.0.1/$HOME/$HOST/$HOSTNAME/somehost/$PORT/$REMUSER/$USER"
100		if [ ! -z "${HASH}" ]; then
101			in="$in/%C"
102			out="$out/$HASH"
103		fi
104		trial $i "$in" "$out"
105	fi
106done
107
108# Subset of above since we don't expand shell-style variables on anything that
109# runs a command because the shell will expand those.
110for i in controlpath identityagent forwardagent localforward remoteforward \
111    userknownhostsfile; do
112	verbose $tid $i dollar
113	FOO=bar
114	export FOO
115	trial $i '${FOO}' $FOO
116done
117
118
119# A subset of options support tilde expansion
120for i in controlpath identityagent forwardagent; do
121	verbose $tid $i tilde
122	trial $i '~' $HOME/
123	trial $i '~/.ssh' $HOME/.ssh
124done
125