Hello all,
Some while ago I developed a small patch for sshd, for internal
consumption, so that, when a client uses a private key, the
corresponding public key is exported in the environment.? I use it to
identify which of a multitude of devices is logged in to a shared
account, but I'm sure there are many uses to which it could be put.?
Now, I wonder whether there already was a way of achieving the same
result.? I need to be able to identify previously unseen devices, so I
cannot just store the public key (c.f. authorized_keys) before use.
If this patch does indeed provide a new function (could not otherwise
achieve the desired outcome), is it something which would be welcomed
for inclusion in the official source?? I've attached the patch so that
you can see what's involved.
Regards,
David
-------------- next part --------------
Description: Put client's public key in environment for pubkey
authentication
Author: David Newall <davidn at davidnewall.com>
diff -ru openssh-7.2p2/auth.h openssh-7.2p2.DN/auth.h
--- openssh-7.2p2/auth.h 2017-02-25 01:36:59.000000000 +1030
+++ openssh-7.2p2.DN/auth.h 2017-02-25 00:40:15.036779000 +1030
@@ -79,6 +79,7 @@
#endif
Buffer *loginmsg;
void *methoddata;
+ char *authkey; /* client's authentication key */
struct sshkey **prev_userkeys;
u_int nprev_userkeys;
diff -ru openssh-7.2p2/auth2-pubkey.c openssh-7.2p2.DN/auth2-pubkey.c
--- openssh-7.2p2/auth2-pubkey.c 2017-02-25 01:36:59.000000000 +1030
+++ openssh-7.2p2.DN/auth2-pubkey.c 2017-02-25 01:34:43.208779000 +1030
@@ -85,6 +85,11 @@
int have_sig, pktype;
int authenticated = 0;
+ if (authctxt->authkey) {
+debug("**********freeing key at %p in pid %d", authctxt->authkey,
getpid());
+ free(authctxt->authkey);
+ authctxt->authkey = NULL;
+ }
if (!authctxt->valid) {
debug2("%s: disabled because of invalid user", __func__);
return 0;
@@ -211,8 +216,19 @@
auth_clear_options();
done:
debug2("%s: authenticated %d pkalg %s", __func__, authenticated,
pkalg);
- if (key != NULL)
+ if (key != NULL) {
+ struct sshbuf *b = sshbuf_new();
+ if (b != NULL && sshkey_format_text(key, b) == 0) {
+ authctxt->authkey = malloc(sshbuf_len(b) + 1);
+ if (authctxt->authkey != NULL) {
+ memcpy(authctxt->authkey, sshbuf_ptr(b), sshbuf_len(b));
+ authctxt->authkey[sshbuf_len(b)] = '\0';
+debug("**********stored key at %p in pid %d", authctxt->authkey,
getpid());
+ }
+ }
+ sshbuf_free(b);
key_free(key);
+ }
free(pkalg);
free(pkblob);
free(fp);
diff -ru openssh-7.2p2/monitor.c openssh-7.2p2.DN/monitor.c
--- openssh-7.2p2/monitor.c 2017-02-25 01:36:59.000000000 +1030
+++ openssh-7.2p2.DN/monitor.c 2017-02-25 01:38:39.900779000 +1030
@@ -1231,6 +1231,12 @@
debug3("%s entering", __func__);
+ if (authctxt->authkey) {
+debug("**********freeing key at %p in pid %d", authctxt->authkey,
getpid());
+ free(authctxt->authkey);
+ authctxt->authkey = NULL;
+ }
+
type = buffer_get_int(m);
cuser = buffer_get_string(m, NULL);
chost = buffer_get_string(m, NULL);
@@ -1292,8 +1298,19 @@
break;
}
}
- if (key != NULL)
+ if (key != NULL) {
+ struct sshbuf *b = sshbuf_new();
+ if (b != NULL && sshkey_format_text(key, b) == 0) {
+ authctxt->authkey = malloc(sshbuf_len(b) + 1);
+ if (authctxt->authkey != NULL) {
+ memcpy(authctxt->authkey, sshbuf_ptr(b), sshbuf_len(b));
+ authctxt->authkey[sshbuf_len(b)] = '\0';
+debug("**********stored key at %p in pid %d", authctxt->authkey,
getpid());
+ }
+ }
+ sshbuf_free(b);
key_free(key);
+ }
/* clear temporarily storage (used by verify) */
monitor_reset_key_state();
diff -ru openssh-7.2p2/session.c openssh-7.2p2.DN/session.c
--- openssh-7.2p2/session.c 2017-02-25 01:36:59.000000000 +1030
+++ openssh-7.2p2.DN/session.c 2017-02-25 00:32:43.944779000 +1030
@@ -1334,6 +1334,10 @@
child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
auth_sock_name);
+ if (s->authctxt->authkey)
+ child_set_env(&env, &envsize, "SSH_AUTHKEY",
+ s->authctxt->authkey);
+
/* read $HOME/.ssh/environment. */
if (options.permit_user_env && !options.use_login) {
snprintf(buf, sizeof buf, "%.200s/.ssh/environment",
diff -ru openssh-7.2p2/sshkey.c openssh-7.2p2.DN/sshkey.c
--- openssh-7.2p2/sshkey.c 2017-02-25 01:36:59.000000000 +1030
+++ openssh-7.2p2.DN/sshkey.c 2017-02-25 01:22:35.072779000 +1030
@@ -1449,7 +1449,7 @@
return r;
}
-static int
+int
sshkey_format_text(const struct sshkey *key, struct sshbuf *b)
{
int r = SSH_ERR_INTERNAL_ERROR;
diff -ru openssh-7.2p2/sshkey.h openssh-7.2p2.DN/sshkey.h
--- openssh-7.2p2/sshkey.h 2017-02-25 01:36:59.000000000 +1030
+++ openssh-7.2p2.DN/sshkey.h 2017-02-25 01:25:11.900779000 +1030
@@ -126,6 +126,7 @@
int, u_char **retp, size_t *lenp);
const char *sshkey_type(const struct sshkey *);
const char *sshkey_cert_type(const struct sshkey *);
+int sshkey_format_text(const struct sshkey *key, struct sshbuf *b);
int sshkey_write(const struct sshkey *, FILE *);
int sshkey_read(struct sshkey *, char **);
u_int sshkey_size(const struct sshkey *);