Feature rqst/Patch: Attempted key's fp in env to AuthorizedKeysCommand

Micah Cowan micah at addictivecode.org
Fri Oct 10 05:38:06 EST 2014


Hello. My employer (Akamai Technologies) had a case where they wanted to
manage a large number (tens of thousands) of authorized keys for a
single user.

I'm sure there may be alternatives to that sort of use case, but at any
rate it was decided that the simplest way to proceed would be to use
OpenSSH's AuthorizedKeysCommand config option, with the extension that
the attempted key's fingerprint would be placed in the environment of
the command, so that it could use it as an index, and limit its output
to only the relevant key, so that OpenSSH wouldn't spin around,
linearly processing large number of keys to be thrown away in a moment.

It was thought that it might be worth providing the patch in case it was
thought to be useful to a wider audience.

NOTES:
  - The patch below is similar to, but not quite the same, as the patch
    that was actually created for Akamai's use. Our patch uses a
    different name for the env var, and was written against Ubuntu's
    openssh source package, with a variety of other custom in-house
    patches atop it.
  - It is thus UNTESTED. It didn't seem worthwhile to me to set up a
    proper testing environment, as I suspect there's a strong chance it
    won't be applied upstream unchanged, and that at any rate you folks
    probably test more thoroughly than I would know to. (And the patch is
    trivial in any case.)
  - Are the results from this command cached in any way, and then reused
    if the user is trying multiple keys (say, from ssh-agent)? That
    won't be the way we're using it, so probably doesn't matter for us;
    but it'd be reasonable for a general-audience implementation to take
    that into account. This patch assumes no, and expects subsequent
    key attempts would result in additional invocations of
    user_key_command_allowed2 for each attempted key, but I hadn't
    actually confirmed this to be the case.
  - We're just using the SHA256 fingerprint, but it doesn't seem like
    it'd be a bad idea just to get all three sum-types, and throw them
    all into the environment, so users could use whichever they
    preferred for the index lookup (or whatever use they're putting it
    to). I originally wrote the patch to use MD5, but was then asked to
    use a stronger hash instead. But when the purpose is indexing, and
    not verification or direct authentication, I don't see much harm in
    using "weak" hashes.

Patch follows. Thanks for your attention/feedback!
-mjc

diff -urNp openssh-6.7.orig/auth2-pubkey.c openssh-6.7/auth2-pubkey.c
--- openssh-6.7.orig/auth2-pubkey.c	2014-07-15 08:54:14.000000000 -0700
+++ openssh-6.7/auth2-pubkey.c	2014-10-09 11:07:02.620077981 -0700
@@ -507,6 +507,7 @@ user_key_command_allowed2(struct passwd
 	int status, devnull, p[2], i;
 	pid_t pid;
 	char *username, errmsg[512];
+	char *envsha256;
 
 	if (options.authorized_keys_command == NULL ||
 	    options.authorized_keys_command[0] != '/')
@@ -595,6 +596,20 @@ user_key_command_allowed2(struct passwd
 			_exit(1);
 		}
 
+		/*
+		 * Put attempted key's fingerprint in environment, so
+		 * users with many authorized keys can use indexing and
+		 * return only the single relevant key for processing.
+		 */
+		envsha256 = key_fingerprint(key, SSH_FP_SHA256,
+		    SSH_FP_HEX);
+		if (setenv(SSH_ATTEMPT_KEY_SHA256_ENV_NAME, envsha256, 1)
+		    == -1) {
+			error("%s: setenv: %s", __func__, strerror(errno));
+			_exit(1);
+		}
+		free(envsha256); /* Key has been copied into env. */
+
 		execl(options.authorized_keys_command,
 		    options.authorized_keys_command, user_pw->pw_name, NULL);
 
diff -urNp openssh-6.7.orig/ssh.h openssh-6.7/ssh.h
--- openssh-6.7.orig/ssh.h	2010-06-25 00:14:46.000000000 -0700
+++ openssh-6.7/ssh.h	2014-10-09 11:04:28.720082528 -0700
@@ -69,6 +69,12 @@
 #define SSH_ASKPASS_ENV		"SSH_ASKPASS"
 
 /*
+ * Name of the environment variable used to pass the key fingerprint to the
+ * command named by the AuthorizedKeyCommand configuration setting.
+ */
+#define SSH_ATTEMPT_KEY_SHA256_ENV_NAME		"SSH_ATTEMPT_KEY_SHA256"
+
+/*
  * Force host key length and server key length to differ by at least this
  * many bits.  This is to make double encryption with rsaref work.
  */

(End of message.)


More information about the openssh-unix-dev mailing list