export public key to environment

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

 



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

Description: Put client's public key in environment for pubkey authentication
Author: David Newall <davidn@xxxxxxxxxxxxxxx>

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 *);
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@xxxxxxxxxxx
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux