diff options
-rw-r--r-- | sbin/iked/iked.h | 4 | ||||
-rw-r--r-- | sbin/iked/ikev2.c | 10 | ||||
-rw-r--r-- | sbin/iked/policy.c | 25 |
3 files changed, 26 insertions, 13 deletions
diff --git a/sbin/iked/iked.h b/sbin/iked/iked.h index 02d23634ec1..b8abfcf1c6c 100644 --- a/sbin/iked/iked.h +++ b/sbin/iked/iked.h @@ -1,4 +1,4 @@ -/* $OpenBSD: iked.h,v 1.193 2021/09/01 15:30:06 tobhe Exp $ */ +/* $OpenBSD: iked.h,v 1.194 2021/10/12 10:01:59 tobhe Exp $ */ /* * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de> @@ -916,7 +916,7 @@ struct iked_sa * sa_dstid_insert(struct iked *, struct iked_sa *); void sa_dstid_remove(struct iked *, struct iked_sa *); int proposals_negotiate(struct iked_proposals *, struct iked_proposals *, - struct iked_proposals *, int); + struct iked_proposals *, int, int); RB_PROTOTYPE(iked_sas, iked_sa, sa_entry, sa_cmp); RB_PROTOTYPE(iked_dstid_sas, iked_sa, sa_dstid_entry, sa_dstid_cmp); RB_PROTOTYPE(iked_addrpool, iked_sa, sa_addrpool_entry, sa_addrpool_cmp); diff --git a/sbin/iked/ikev2.c b/sbin/iked/ikev2.c index f319919168d..52ce7e616b9 100644 --- a/sbin/iked/ikev2.c +++ b/sbin/iked/ikev2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ikev2.c,v 1.328 2021/10/12 09:27:21 tobhe Exp $ */ +/* $OpenBSD: ikev2.c,v 1.329 2021/10/12 10:01:59 tobhe Exp $ */ /* * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de> @@ -972,7 +972,7 @@ ikev2_ike_auth_recv(struct iked *env, struct iked_sa *sa, if (!TAILQ_EMPTY(&msg->msg_proposals)) { if (proposals_negotiate(&sa->sa_proposals, &sa->sa_policy->pol_proposals, &msg->msg_proposals, - 0) != 0) { + 0, -1) != 0) { log_info("%s: no proposal chosen", __func__); msg->msg_error = IKEV2_N_NO_PROPOSAL_CHOSEN; return (-1); @@ -4212,7 +4212,7 @@ ikev2_init_create_child_sa(struct iked *env, struct iked_message *msg) } if (proposals_negotiate(&sa->sa_proposals, &sa->sa_proposals, - &msg->msg_proposals, 1) != 0) { + &msg->msg_proposals, 1, -1) != 0) { log_info("%s: no proposal chosen", SPI_SA(sa, __func__)); return (-1); } @@ -4715,7 +4715,7 @@ ikev2_resp_create_child_sa(struct iked *env, struct iked_message *msg) if (proposals_negotiate(&proposals, &sa->sa_policy->pol_proposals, &msg->msg_proposals, - 1) != 0) { + 1, msg->msg_dhgroup) != 0) { log_info("%s: no proposal chosen", __func__); msg->msg_error = IKEV2_N_NO_PROPOSAL_CHOSEN; goto fail; @@ -5228,7 +5228,7 @@ ikev2_sa_negotiate_common(struct iked *env, struct iked_sa *sa, struct iked_mess /* XXX we need a better way to get this */ if (proposals_negotiate(&sa->sa_proposals, - &msg->msg_policy->pol_proposals, &msg->msg_proposals, 0) != 0) { + &msg->msg_policy->pol_proposals, &msg->msg_proposals, 0, -1) != 0) { log_info("%s: proposals_negotiate", __func__); return (-1); } diff --git a/sbin/iked/policy.c b/sbin/iked/policy.c index 51763014923..8869b00e2f3 100644 --- a/sbin/iked/policy.c +++ b/sbin/iked/policy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: policy.c,v 1.83 2021/09/01 15:30:06 tobhe Exp $ */ +/* $OpenBSD: policy.c,v 1.84 2021/10/12 10:01:59 tobhe Exp $ */ /* * Copyright (c) 2020-2021 Tobias Heider <tobhe@openbsd.org> @@ -53,7 +53,7 @@ static __inline int static int policy_test_flows(struct iked_policy *, struct iked_policy *); static int proposals_match(struct iked_proposal *, struct iked_proposal *, - struct iked_transform **, int); + struct iked_transform **, int, int); void policy_init(struct iked *env) @@ -276,7 +276,7 @@ policy_test(struct iked *env, struct iked_policy *key) /* Make sure the proposals are compatible */ if (TAILQ_FIRST(&key->pol_proposals) && proposals_negotiate(NULL, &p->pol_proposals, - &key->pol_proposals, 0) == -1) { + &key->pol_proposals, 0, -1) == -1) { p = TAILQ_NEXT(p, pol_entry); continue; } @@ -971,7 +971,7 @@ user_cmp(struct iked_user *a, struct iked_user *b) */ int proposals_negotiate(struct iked_proposals *result, struct iked_proposals *local, - struct iked_proposals *peer, int rekey) + struct iked_proposals *peer, int rekey, int groupid) { struct iked_proposal *ppeer = NULL, *plocal, *prop, vpeer, vlocal; struct iked_transform chosen[IKEV2_XFORMTYPE_MAX]; @@ -996,7 +996,7 @@ proposals_negotiate(struct iked_proposals *result, struct iked_proposals *local, continue; bzero(match, sizeof(match)); score = proposals_match(plocal, ppeer, match, - rekey); + rekey, groupid); log_debug("%s: score %d", __func__, score); if (score && (!chosen_score || score < chosen_score)) { chosen_score = score; @@ -1051,10 +1051,11 @@ proposals_negotiate(struct iked_proposals *result, struct iked_proposals *local, static int proposals_match(struct iked_proposal *local, struct iked_proposal *peer, - struct iked_transform **xforms, int rekey) + struct iked_transform **xforms, int rekey, int dhgroup) { struct iked_transform *tpeer, *tlocal; unsigned int i, j, type, score, requiredh = 0, nodh = 0, noauth = 0; + unsigned int dhforced = 0; uint8_t protoid = peer->prop_protoid; uint8_t peerxfs[IKEV2_XFORMTYPE_MAX]; @@ -1112,6 +1113,18 @@ proposals_match(struct iked_proposal *local, struct iked_proposal *peer, continue; type = tpeer->xform_type; + if (rekey && nodh == 0 && dhgroup >= 0 && + protoid == IKEV2_SAPROTO_ESP && + type == IKEV2_XFORMTYPE_DH) { + if (dhforced) + continue; + /* reset xform, so this xform w/matching group is enforced */ + if (tlocal->xform_id == dhgroup) { + xforms[type] = NULL; + dhforced = 1; + } + } + if (xforms[type] == NULL || tlocal->xform_score < xforms[type]->xform_score) { xforms[type] = tlocal; |