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