summaryrefslogtreecommitdiffstats
path: root/debian/patches/CVE-2023-51384.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/CVE-2023-51384.patch')
-rw-r--r--debian/patches/CVE-2023-51384.patch168
1 files changed, 168 insertions, 0 deletions
diff --git a/debian/patches/CVE-2023-51384.patch b/debian/patches/CVE-2023-51384.patch
new file mode 100644
index 0000000..1953197
--- /dev/null
+++ b/debian/patches/CVE-2023-51384.patch
@@ -0,0 +1,168 @@
+From d5be669c872a313a71d60babee64f3a80340dc51 Mon Sep 17 00:00:00 2001
+From: "djm@openbsd.org" <djm@openbsd.org>
+Date: Mon, 18 Dec 2023 14:46:12 +0000
+Subject: upstream: apply destination constraints to all p11 keys
+
+Previously applied only to the first key returned from each token.
+
+ok markus@
+
+OpenBSD-Commit-ID: 36df3afb8eb94eec6b2541f063d0d164ef8b488d
+
+Origin: backport, https://anongit.mindrot.org/openssh.git/commit/?id=881d9c6af9da4257c69c327c4e2f1508b2fa754b
+Last-Update: 2023-12-19
+
+Patch-Name: CVE-2023-51384.patch
+---
+ ssh-agent.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 99 insertions(+), 4 deletions(-)
+
+diff --git a/ssh-agent.c b/ssh-agent.c
+index dce2849d8..27bf9b5ad 100644
+--- a/ssh-agent.c
++++ b/ssh-agent.c
+@@ -248,6 +248,91 @@ free_dest_constraints(struct dest_constraint *dcs, size_t ndcs)
+ free(dcs);
+ }
+
++static void
++dup_dest_constraint_hop(const struct dest_constraint_hop *dch,
++ struct dest_constraint_hop *out)
++{
++ u_int i;
++ int r;
++
++ out->user = dch->user == NULL ? NULL : xstrdup(dch->user);
++ out->hostname = dch->hostname == NULL ? NULL : xstrdup(dch->hostname);
++ out->is_ca = dch->is_ca;
++ out->nkeys = dch->nkeys;
++ out->keys = out->nkeys == 0 ? NULL :
++ xcalloc(out->nkeys, sizeof(*out->keys));
++ out->key_is_ca = out->nkeys == 0 ? NULL :
++ xcalloc(out->nkeys, sizeof(*out->key_is_ca));
++ for (i = 0; i < dch->nkeys; i++) {
++ if (dch->keys[i] != NULL &&
++ (r = sshkey_from_private(dch->keys[i],
++ &(out->keys[i]))) != 0)
++ fatal_fr(r, "copy key");
++ out->key_is_ca[i] = dch->key_is_ca[i];
++ }
++}
++
++static struct dest_constraint *
++dup_dest_constraints(const struct dest_constraint *dcs, size_t ndcs)
++{
++ size_t i;
++ struct dest_constraint *ret;
++
++ if (ndcs == 0)
++ return NULL;
++ ret = xcalloc(ndcs, sizeof(*ret));
++ for (i = 0; i < ndcs; i++) {
++ dup_dest_constraint_hop(&dcs[i].from, &ret[i].from);
++ dup_dest_constraint_hop(&dcs[i].to, &ret[i].to);
++ }
++ return ret;
++}
++
++#ifdef DEBUG_CONSTRAINTS
++static void
++dump_dest_constraint_hop(const struct dest_constraint_hop *dch)
++{
++ u_int i;
++ char *fp;
++
++ debug_f("user %s hostname %s is_ca %d nkeys %u",
++ dch->user == NULL ? "(null)" : dch->user,
++ dch->hostname == NULL ? "(null)" : dch->hostname,
++ dch->is_ca, dch->nkeys);
++ for (i = 0; i < dch->nkeys; i++) {
++ fp = NULL;
++ if (dch->keys[i] != NULL &&
++ (fp = sshkey_fingerprint(dch->keys[i],
++ SSH_FP_HASH_DEFAULT, SSH_FP_DEFAULT)) == NULL)
++ fatal_f("fingerprint failed");
++ debug_f("key %u/%u: %s%s%s key_is_ca %d", i, dch->nkeys,
++ dch->keys[i] == NULL ? "" : sshkey_ssh_name(dch->keys[i]),
++ dch->keys[i] == NULL ? "" : " ",
++ dch->keys[i] == NULL ? "none" : fp,
++ dch->key_is_ca[i]);
++ free(fp);
++ }
++}
++#endif /* DEBUG_CONSTRAINTS */
++
++static void
++dump_dest_constraints(const char *context,
++ const struct dest_constraint *dcs, size_t ndcs)
++{
++#ifdef DEBUG_CONSTRAINTS
++ size_t i;
++
++ debug_f("%s: %zu constraints", context, ndcs);
++ for (i = 0; i < ndcs; i++) {
++ debug_f("constraint %zu / %zu: from: ", i, ndcs);
++ dump_dest_constraint_hop(&dcs[i].from);
++ debug_f("constraint %zu / %zu: to: ", i, ndcs);
++ dump_dest_constraint_hop(&dcs[i].to);
++ }
++ debug_f("done for %s", context);
++#endif /* DEBUG_CONSTRAINTS */
++}
++
+ static void
+ free_identity(Identity *id)
+ {
+@@ -519,13 +604,22 @@ process_request_identities(SocketEntry *e)
+ Identity *id;
+ struct sshbuf *msg, *keys;
+ int r;
+- u_int nentries = 0;
++ u_int i = 0, nentries = 0;
++ char *fp;
+
+ debug2_f("entering");
+
+ if ((msg = sshbuf_new()) == NULL || (keys = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
+ TAILQ_FOREACH(id, &idtab->idlist, next) {
++ if ((fp = sshkey_fingerprint(id->key, SSH_FP_HASH_DEFAULT,
++ SSH_FP_DEFAULT)) == NULL)
++ fatal_f("fingerprint failed");
++ debug_f("key %u / %u: %s %s", i++, idtab->nentries,
++ sshkey_ssh_name(id->key), fp);
++ dump_dest_constraints(__func__,
++ id->dest_constraints, id->ndest_constraints);
++ free(fp);
+ /* identity not visible, don't include in response */
+ if (identity_permitted(id, e, NULL, NULL, NULL) != 0)
+ continue;
+@@ -1225,6 +1319,7 @@ process_add_identity(SocketEntry *e)
+ sshbuf_reset(e->request);
+ goto out;
+ }
++ dump_dest_constraints(__func__, dest_constraints, ndest_constraints);
+
+ if (sk_provider != NULL) {
+ if (!sshkey_is_sk(k)) {
+@@ -1404,6 +1499,7 @@ process_add_smartcard_key(SocketEntry *e)
+ error_f("failed to parse constraints");
+ goto send;
+ }
++ dump_dest_constraints(__func__, dest_constraints, ndest_constraints);
+ if (e->nsession_ids != 0 && !remote_add_provider) {
+ verbose("failed PKCS#11 add of \"%.100s\": remote addition of "
+ "providers is disabled", provider);
+@@ -1439,10 +1535,9 @@ process_add_smartcard_key(SocketEntry *e)
+ }
+ id->death = death;
+ id->confirm = confirm;
+- id->dest_constraints = dest_constraints;
++ id->dest_constraints = dup_dest_constraints(
++ dest_constraints, ndest_constraints);
+ id->ndest_constraints = ndest_constraints;
+- dest_constraints = NULL; /* transferred */
+- ndest_constraints = 0;
+ TAILQ_INSERT_TAIL(&idtab->idlist, id, next);
+ idtab->nentries++;
+ success = 1;