[RFC] Add hash token to ControlPath

mancha mancha1 at zoho.com
Thu Apr 3 02:38:46 EST 2014


On Fri, Mar 07, 2014 at 04:11:17AM +0000, mancha wrote:
> Darren Tucker <dtucker at zip.com.au> writes:
> > 
> > On Fri, Mar 7, 2014 at 7:36 AM, mancha <mancha1 at hush.com> wrote:
> > [...]
> > > 1. Digest is based on lhost(%l) + rhost(%h) + rport(%p) +
> > > ruser(%r) 2. Macro is %D
> > 
> > Here's the currently implemented % expansions across all the tools
> > (the intention being to prevent any new conflicts or
> > inconsistencies).
> > 
> > http://www.dtucker.net/openssh/percent_expand_opts.html
> > 
> 
> That table was really helpful - thanks.
> 
> I've settled on %m (for "message digest") to avoid any confusion.
> 
> New patch is up:
> 
> http://sf.net/projects/mancha/files/misc/openssh-6.5p1-mux-hash.diff
> 
> --mancha
> 

Hello.

I've updated the mux-hash patch for OpenSSH 6.6p1 (attached & posted at
http://sf.net/projects/mancha/files/misc/openssh-6.6p1-mux-hash.diff).

--mancha
-------------- next part --------------
>From 6fdd69b3bfc8dcefccc2d7ca4220b72d2bb8b8d3 Mon Sep 17 00:00:00 2001
From: mancha <mancha1 AT zoho.com>
Date: Wed, 02 Apr 2014
Subject: Add digest of lhost+rhost+rport+ruser for use with ControlPath.

When combining %h, %r, and %p (recommended for uniqueness) in ControlPath,
long remote usernames and/or hostnames can cause the expansion to bump up
against UNIX_PATH_MAX.

This patch adds a new percent-token (%m) that expands to the sha1 digest
of the concatenation of the local host (%l) + remote host (%h) + remote
port (%p) + remote user (%r). This token's expanded length is a fixed 40
characters and, barring digest collision, provides uniqueness.

Sample usage:

  ControlPath ~/.ssh/control-master/%m

---
 ssh.c        |   19 +++++++++++++++++++
 ssh_config.5 |    8 +++++---
 2 files changed, 24 insertions(+), 3 deletions(-)

--- a/ssh.c
+++ b/ssh.c
@@ -83,6 +83,7 @@
 #include "canohost.h"
 #include "compat.h"
 #include "cipher.h"
+#include "digest.h"
 #include "packet.h"
 #include "buffer.h"
 #include "channels.h"
@@ -190,6 +191,9 @@ static int remote_forward_confirms_recei
 extern int muxserver_sock;
 extern u_int muxclient_command;
 
+/* Length of mux hash value (using sha1) */
+#define MUX_DIGEST_LENGTH 20
+
 /* Prints a help message to the user.  This function never returns. */
 
 static void
@@ -422,6 +426,9 @@ main(int ac, char **av)
 	extern char *optarg;
 	Forward fwd;
 	struct addrinfo *addrs = NULL;
+	struct ssh_digest_ctx *md;
+	unsigned char digest[MUX_DIGEST_LENGTH];
+	char mux_hash[MUX_DIGEST_LENGTH*2+1];
 
 	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
 	sanitise_stdfd();
@@ -982,6 +989,17 @@ main(int ac, char **av)
 	shorthost[strcspn(thishost, ".")] = '\0';
 	snprintf(portstr, sizeof(portstr), "%d", options.port);
 
+	if ((md = ssh_digest_start(SSH_DIGEST_SHA1)) == NULL ||
+	    ssh_digest_update(md, thishost, strlen(thishost)) < 0 ||
+	    ssh_digest_update(md, host, strlen(host)) < 0 ||
+	    ssh_digest_update(md, portstr, strlen(portstr)) < 0 ||
+	    ssh_digest_update(md, options.user, strlen(options.user)) < 0 ||
+	    ssh_digest_final(md, digest, sizeof(digest)) < 0)
+		fatal("%s: mux digest failed", __func__);
+	for(i = 0; i < MUX_DIGEST_LENGTH; i++)
+		sprintf(&mux_hash[i*2], "%02x", (unsigned int)digest[i]);
+	ssh_digest_free(md);
+
 	if (options.local_command != NULL) {
 		debug3("expanding LocalCommand: %s", options.local_command);
 		cp = options.local_command;
@@ -1000,6 +1018,7 @@ main(int ac, char **av)
 		options.control_path = percent_expand(cp, "h", host,
 		    "l", thishost, "n", host_arg, "r", options.user,
 		    "p", portstr, "u", pw->pw_name, "L", shorthost,
+		    "m", mux_hash,
 		    (char *)NULL);
 		free(cp);
 	}
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -482,14 +482,16 @@
 .Ql %p
 the destination port,
 .Ql %r
-by the remote login username, and
+by the remote login username,
 .Ql %u
 by the username of the user running
-.Xr ssh 1 .
+.Xr ssh 1 , and
+.Ql %m
+by the SHA1 digest of the concatenation: %l%h%p%r.
 It is recommended that any
 .Cm ControlPath
 used for opportunistic connection sharing include
-at least %h, %p, and %r.
+at least %h, %p, and %r (or alternatively %m).
 This ensures that shared connections are uniquely identified.
 .It Cm ControlPersist
 When used in conjunction with


More information about the openssh-unix-dev mailing list