[PATCH] Allow matching HostName against Host entries

Ryan Kavanagh rak at debian.org
Fri May 3 12:32:15 EST 2013


Hi all,

Sorry for the delay, I got caught up with work related things.

On Tue, Apr 16, 2013 at 11:52:48AM -0400, Ryan Kavanagh wrote:
> Seeing that this option had support in another subthread, I'll update
> my patch to use ExpandHost instead.
> 
> To those who objected to my initial patch, does this change address
> your concerns?

I've updated the patch, inlined below. I've added the following
additional extensions to the ExpandHost idea:

 * Add a "%h" flag to ExpandHost that does the same thing as "%h" in
   HostName: substitute in the host passed on the command line

 * Add a "%e" flag to HostName that expands to the value of ExpandHost.

These percent-expansions simplify cases like
       Host foo
            HostName foo.bar.baz
            ExpandHost foo.bar.baz
or 
       Host foo
            HostName %h.bar.baz
            ExpandHost foo.bar.baz
to the simpler
       Host foo
            HostName %h.bar.baz
            ExpandHost %h.bar.baz
or even simpler, to
       Host foo
            HostName %e
            ExpandHost %h.bar.baz

Note that the ordering of HostName and ExpandHost doesn't matter for the
percent-expansions: %e in HostName gets expanded from ssh.c after the
config file is processed, and nothing in ExpandHost depends on HostName.

Both of these percent-expansions are easy to remove should there be any
objections, but I think both are useful and I can easily think of
real-world use cases for each.

Please let me know if you have any questions/concerns/comments, and if
the patch below addresses the previously raised concerns.

Best wishes,
Ryan

-- 
|_)|_/	Ryan Kavanagh		| Debian Developer
| \| \	http://ryanak.ca/	| GPG Key 4A11C97A

Index: usr.bin/ssh/readconf.h
===================================================================
RCS file: /cvs/src/usr.bin/ssh/readconf.h,v
retrieving revision 1.93
diff -u -r1.93 readconf.h
--- usr.bin/ssh/readconf.h	22 Feb 2013 04:45:09 -0000	1.93
+++ usr.bin/ssh/readconf.h	3 May 2013 02:27:33 -0000
@@ -80,6 +80,7 @@
 	char   *kex_algorithms;	/* SSH2 kex methods in order of preference. */
 	int	protocol;	/* Protocol in order of preference. */
 	char   *hostname;	/* Real host to connect. */
+  	char   *expand_host;	/* Possible additional hostname to use in matching. */
 	char   *host_key_alias;	/* hostname alias for .ssh/known_hosts */
 	char   *proxy_command;	/* Proxy command for connecting the host. */
 	char   *user;		/* User to log in as. */
Index: usr.bin/ssh/readconf.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/readconf.c,v
retrieving revision 1.197
diff -u -r1.197 readconf.c
--- usr.bin/ssh/readconf.c	6 Mar 2013 23:36:53 -0000	1.197
+++ usr.bin/ssh/readconf.c	3 May 2013 02:27:36 -0000
@@ -128,7 +128,7 @@
 	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
 	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
 	oSendEnv, oControlPath, oControlMaster, oControlPersist,
-	oHashKnownHosts,
+	oHashKnownHosts, oExpandHost,
 	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
 	oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
 	oKexAlgorithms, oIPQoS, oRequestTTY,
@@ -177,6 +177,7 @@
 	{ "identityfile2", oIdentityFile },			/* obsolete */
 	{ "identitiesonly", oIdentitiesOnly },
 	{ "hostname", oHostName },
+	{ "expandhost", oExpandHost },
 	{ "hostkeyalias", oHostKeyAlias },
 	{ "proxycommand", oProxyCommand },
 	{ "port", oPort },
@@ -647,6 +648,16 @@
 		charptr = &options->hostname;
 		goto parse_string;
 
+	case oExpandHost:
+		charptr = &options->expand_host;
+		arg = strdelim(&s);
+		if (!arg || *arg == '\0')
+			fatal("%.200s line %d: Missing argument.",
+			    filename, linenum);
+		if (*activep && *charptr == NULL)
+			*charptr = percent_expand(arg, "h", host, (char *)NULL);
+		break;
+		
 	case oHostKeyAlias:
 		charptr = &options->host_key_alias;
 		goto parse_string;
@@ -823,7 +834,9 @@
 			negated = *arg == '!';
 			if (negated)
 				arg++;
-			if (match_pattern(host, arg)) {
+			if (match_pattern(host, arg) ||
+			    (options->expand_host &&
+			    match_pattern(options->expand_host, arg))) {
 				if (negated) {
 					debug("%.200s line %d: Skipping Host "
 					    "block because of negated match "
@@ -1179,6 +1192,7 @@
 	options->protocol = SSH_PROTO_UNKNOWN;
 	options->num_identity_files = 0;
 	options->hostname = NULL;
+	options->expand_host = NULL;
 	options->host_key_alias = NULL;
 	options->proxy_command = NULL;
 	options->user = NULL;
Index: usr.bin/ssh/ssh.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/ssh.c,v
retrieving revision 1.377
diff -u -r1.377 ssh.c
--- usr.bin/ssh/ssh.c	19 Apr 2013 11:10:18 -0000	1.377
+++ usr.bin/ssh/ssh.c	3 May 2013 02:27:37 -0000
@@ -729,8 +729,13 @@
 	/* preserve host name given on command line for %n expansion */
 	host_arg = host;
 	if (options.hostname != NULL) {
-		host = percent_expand(options.hostname,
-		    "h", host, (char *)NULL);
+		if (options.expand_host != NULL) {
+			host = percent_expand(options.hostname,
+			    "h", host, "e", options.expand_host, (char *)NULL);
+		} else {
+			host = percent_expand(options.hostname,
+			    "h", host, (char *)NULL);
+		}
 	}
 
 	if (gethostname(thishost, sizeof(thishost)) == -1)
Index: usr.bin/ssh/ssh_config.5
===================================================================
RCS file: /cvs/src/usr.bin/ssh/ssh_config.5,v
retrieving revision 1.161
diff -u -r1.161 ssh_config.5
--- usr.bin/ssh/ssh_config.5	8 Jan 2013 18:49:04 -0000	1.161
+++ usr.bin/ssh/ssh_config.5	3 May 2013 02:27:39 -0000
@@ -1,4 +1,4 @@
-.\"
+\"
 .\" Author: Tatu Ylonen <ylo at cs.hut.fi>
 .\" Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
 .\"                    All rights reserved
@@ -65,7 +65,10 @@
 .Dq Host
 specifications, and that section is only applied for hosts that
 match one of the patterns given in the specification.
-The matched host name is the one given on the command line.
+The matched host name is the one given on the command line,
+and additionally the value of the
+.Dq ExpandHost
+configuration option once set.
 .Pp
 Since the first obtained value for each parameter is used, more
 host-specific declarations should be given near the beginning of the
@@ -111,6 +114,9 @@
 .Ar hostname
 argument given on the command line (i.e. the name is not converted to
 a canonicalized host name before matching).
+If the
+.Cm ExpandHost
+option has been set, its value is also matched against the patterns.
 .Pp
 A pattern entry may be negated by prefixing it with an exclamation mark
 .Pq Sq !\& .
@@ -434,6 +440,13 @@
 .Dq no .
 The default is
 .Dq no .
+.It Cm ExpandHost
+Specifies an additional string to match against any subsequent
+.Cm Host
+stanza's patterns.
+If the specification contains the character sequence
+.Ql %h ,
+then this will be replaced with the host name specified on the command line.
 .It Cm ForwardAgent
 Specifies whether the connection to the authentication agent (if any)
 will be forwarded to the remote machine.
@@ -593,6 +606,11 @@
 .Ql %h ,
 then this will be replaced with the host name specified on the command line
 (this is useful for manipulating unqualified names).
+If it contains the character sequence
+.Ql %e ,
+then this will be replaced with the value of the
+.Cm ExpandHost
+specification, which must have been set.
 The default is the name given on the command line.
 Numeric IP addresses are also permitted (both on the command line and in
 .Cm HostName


More information about the openssh-unix-dev mailing list