Skip to content

Commit 881d9c6

Browse files
committed
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
1 parent a7ed931 commit 881d9c6

File tree

1 file changed

+100
-5
lines changed

1 file changed

+100
-5
lines changed

ssh-agent.c

+100-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: ssh-agent.c,v 1.300 2023/07/19 13:56:33 djm Exp $ */
1+
/* $OpenBSD: ssh-agent.c,v 1.301 2023/12/18 14:46:12 djm Exp $ */
22
/*
33
* Author: Tatu Ylonen <ylo@cs.hut.fi>
44
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -247,6 +247,91 @@ free_dest_constraints(struct dest_constraint *dcs, size_t ndcs)
247247
free(dcs);
248248
}
249249

250+
static void
251+
dup_dest_constraint_hop(const struct dest_constraint_hop *dch,
252+
struct dest_constraint_hop *out)
253+
{
254+
u_int i;
255+
int r;
256+
257+
out->user = dch->user == NULL ? NULL : xstrdup(dch->user);
258+
out->hostname = dch->hostname == NULL ? NULL : xstrdup(dch->hostname);
259+
out->is_ca = dch->is_ca;
260+
out->nkeys = dch->nkeys;
261+
out->keys = out->nkeys == 0 ? NULL :
262+
xcalloc(out->nkeys, sizeof(*out->keys));
263+
out->key_is_ca = out->nkeys == 0 ? NULL :
264+
xcalloc(out->nkeys, sizeof(*out->key_is_ca));
265+
for (i = 0; i < dch->nkeys; i++) {
266+
if (dch->keys[i] != NULL &&
267+
(r = sshkey_from_private(dch->keys[i],
268+
&(out->keys[i]))) != 0)
269+
fatal_fr(r, "copy key");
270+
out->key_is_ca[i] = dch->key_is_ca[i];
271+
}
272+
}
273+
274+
static struct dest_constraint *
275+
dup_dest_constraints(const struct dest_constraint *dcs, size_t ndcs)
276+
{
277+
size_t i;
278+
struct dest_constraint *ret;
279+
280+
if (ndcs == 0)
281+
return NULL;
282+
ret = xcalloc(ndcs, sizeof(*ret));
283+
for (i = 0; i < ndcs; i++) {
284+
dup_dest_constraint_hop(&dcs[i].from, &ret[i].from);
285+
dup_dest_constraint_hop(&dcs[i].to, &ret[i].to);
286+
}
287+
return ret;
288+
}
289+
290+
#ifdef DEBUG_CONSTRAINTS
291+
static void
292+
dump_dest_constraint_hop(const struct dest_constraint_hop *dch)
293+
{
294+
u_int i;
295+
char *fp;
296+
297+
debug_f("user %s hostname %s is_ca %d nkeys %u",
298+
dch->user == NULL ? "(null)" : dch->user,
299+
dch->hostname == NULL ? "(null)" : dch->hostname,
300+
dch->is_ca, dch->nkeys);
301+
for (i = 0; i < dch->nkeys; i++) {
302+
fp = NULL;
303+
if (dch->keys[i] != NULL &&
304+
(fp = sshkey_fingerprint(dch->keys[i],
305+
SSH_FP_HASH_DEFAULT, SSH_FP_DEFAULT)) == NULL)
306+
fatal_f("fingerprint failed");
307+
debug_f("key %u/%u: %s%s%s key_is_ca %d", i, dch->nkeys,
308+
dch->keys[i] == NULL ? "" : sshkey_ssh_name(dch->keys[i]),
309+
dch->keys[i] == NULL ? "" : " ",
310+
dch->keys[i] == NULL ? "none" : fp,
311+
dch->key_is_ca[i]);
312+
free(fp);
313+
}
314+
}
315+
#endif /* DEBUG_CONSTRAINTS */
316+
317+
static void
318+
dump_dest_constraints(const char *context,
319+
const struct dest_constraint *dcs, size_t ndcs)
320+
{
321+
#ifdef DEBUG_CONSTRAINTS
322+
size_t i;
323+
324+
debug_f("%s: %zu constraints", context, ndcs);
325+
for (i = 0; i < ndcs; i++) {
326+
debug_f("constraint %zu / %zu: from: ", i, ndcs);
327+
dump_dest_constraint_hop(&dcs[i].from);
328+
debug_f("constraint %zu / %zu: to: ", i, ndcs);
329+
dump_dest_constraint_hop(&dcs[i].to);
330+
}
331+
debug_f("done for %s", context);
332+
#endif /* DEBUG_CONSTRAINTS */
333+
}
334+
250335
static void
251336
free_identity(Identity *id)
252337
{
@@ -518,13 +603,22 @@ process_request_identities(SocketEntry *e)
518603
Identity *id;
519604
struct sshbuf *msg, *keys;
520605
int r;
521-
u_int nentries = 0;
606+
u_int i = 0, nentries = 0;
607+
char *fp;
522608

523609
debug2_f("entering");
524610

525611
if ((msg = sshbuf_new()) == NULL || (keys = sshbuf_new()) == NULL)
526612
fatal_f("sshbuf_new failed");
527613
TAILQ_FOREACH(id, &idtab->idlist, next) {
614+
if ((fp = sshkey_fingerprint(id->key, SSH_FP_HASH_DEFAULT,
615+
SSH_FP_DEFAULT)) == NULL)
616+
fatal_f("fingerprint failed");
617+
debug_f("key %u / %u: %s %s", i++, idtab->nentries,
618+
sshkey_ssh_name(id->key), fp);
619+
dump_dest_constraints(__func__,
620+
id->dest_constraints, id->ndest_constraints);
621+
free(fp);
528622
/* identity not visible, don't include in response */
529623
if (identity_permitted(id, e, NULL, NULL, NULL) != 0)
530624
continue;
@@ -1224,6 +1318,7 @@ process_add_identity(SocketEntry *e)
12241318
sshbuf_reset(e->request);
12251319
goto out;
12261320
}
1321+
dump_dest_constraints(__func__, dest_constraints, ndest_constraints);
12271322

12281323
if (sk_provider != NULL) {
12291324
if (!sshkey_is_sk(k)) {
@@ -1403,6 +1498,7 @@ process_add_smartcard_key(SocketEntry *e)
14031498
error_f("failed to parse constraints");
14041499
goto send;
14051500
}
1501+
dump_dest_constraints(__func__, dest_constraints, ndest_constraints);
14061502
if (e->nsession_ids != 0 && !remote_add_provider) {
14071503
verbose("failed PKCS#11 add of \"%.100s\": remote addition of "
14081504
"providers is disabled", provider);
@@ -1438,10 +1534,9 @@ process_add_smartcard_key(SocketEntry *e)
14381534
}
14391535
id->death = death;
14401536
id->confirm = confirm;
1441-
id->dest_constraints = dest_constraints;
1537+
id->dest_constraints = dup_dest_constraints(
1538+
dest_constraints, ndest_constraints);
14421539
id->ndest_constraints = ndest_constraints;
1443-
dest_constraints = NULL; /* transferred */
1444-
ndest_constraints = 0;
14451540
TAILQ_INSERT_TAIL(&idtab->idlist, id, next);
14461541
idtab->nentries++;
14471542
success = 1;

0 commit comments

Comments
 (0)