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
This commit is contained in:
parent
a7ed931cae
commit
881d9c6af9
105
ssh-agent.c
105
ssh-agent.c
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: ssh-agent.c,v 1.300 2023/07/19 13:56:33 djm Exp $ */
|
/* $OpenBSD: ssh-agent.c,v 1.301 2023/12/18 14:46:12 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* 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)
|
||||||
free(dcs);
|
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
|
static void
|
||||||
free_identity(Identity *id)
|
free_identity(Identity *id)
|
||||||
{
|
{
|
||||||
|
@ -518,13 +603,22 @@ process_request_identities(SocketEntry *e)
|
||||||
Identity *id;
|
Identity *id;
|
||||||
struct sshbuf *msg, *keys;
|
struct sshbuf *msg, *keys;
|
||||||
int r;
|
int r;
|
||||||
u_int nentries = 0;
|
u_int i = 0, nentries = 0;
|
||||||
|
char *fp;
|
||||||
|
|
||||||
debug2_f("entering");
|
debug2_f("entering");
|
||||||
|
|
||||||
if ((msg = sshbuf_new()) == NULL || (keys = sshbuf_new()) == NULL)
|
if ((msg = sshbuf_new()) == NULL || (keys = sshbuf_new()) == NULL)
|
||||||
fatal_f("sshbuf_new failed");
|
fatal_f("sshbuf_new failed");
|
||||||
TAILQ_FOREACH(id, &idtab->idlist, next) {
|
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 */
|
/* identity not visible, don't include in response */
|
||||||
if (identity_permitted(id, e, NULL, NULL, NULL) != 0)
|
if (identity_permitted(id, e, NULL, NULL, NULL) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
@ -1224,6 +1318,7 @@ process_add_identity(SocketEntry *e)
|
||||||
sshbuf_reset(e->request);
|
sshbuf_reset(e->request);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
dump_dest_constraints(__func__, dest_constraints, ndest_constraints);
|
||||||
|
|
||||||
if (sk_provider != NULL) {
|
if (sk_provider != NULL) {
|
||||||
if (!sshkey_is_sk(k)) {
|
if (!sshkey_is_sk(k)) {
|
||||||
|
@ -1403,6 +1498,7 @@ process_add_smartcard_key(SocketEntry *e)
|
||||||
error_f("failed to parse constraints");
|
error_f("failed to parse constraints");
|
||||||
goto send;
|
goto send;
|
||||||
}
|
}
|
||||||
|
dump_dest_constraints(__func__, dest_constraints, ndest_constraints);
|
||||||
if (e->nsession_ids != 0 && !remote_add_provider) {
|
if (e->nsession_ids != 0 && !remote_add_provider) {
|
||||||
verbose("failed PKCS#11 add of \"%.100s\": remote addition of "
|
verbose("failed PKCS#11 add of \"%.100s\": remote addition of "
|
||||||
"providers is disabled", provider);
|
"providers is disabled", provider);
|
||||||
|
@ -1438,10 +1534,9 @@ process_add_smartcard_key(SocketEntry *e)
|
||||||
}
|
}
|
||||||
id->death = death;
|
id->death = death;
|
||||||
id->confirm = confirm;
|
id->confirm = confirm;
|
||||||
id->dest_constraints = dest_constraints;
|
id->dest_constraints = dup_dest_constraints(
|
||||||
|
dest_constraints, ndest_constraints);
|
||||||
id->ndest_constraints = ndest_constraints;
|
id->ndest_constraints = ndest_constraints;
|
||||||
dest_constraints = NULL; /* transferred */
|
|
||||||
ndest_constraints = 0;
|
|
||||||
TAILQ_INSERT_TAIL(&idtab->idlist, id, next);
|
TAILQ_INSERT_TAIL(&idtab->idlist, id, next);
|
||||||
idtab->nentries++;
|
idtab->nentries++;
|
||||||
success = 1;
|
success = 1;
|
||||||
|
|
Loading…
Reference in New Issue