summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortobhe <tobhe@openbsd.org>2021-02-01 16:37:48 +0000
committertobhe <tobhe@openbsd.org>2021-02-01 16:37:48 +0000
commita5265846535cb18af074b09340caa0d0a4b8816c (patch)
treee992c050726c50ea03ac0dd8059d14ba87aa0bd8
parentdhclient(8): default_route_index(): poll(2) -> ppoll(2) (diff)
downloadwireguard-openbsd-a5265846535cb18af074b09340caa0d0a4b8816c.tar.xz
wireguard-openbsd-a5265846535cb18af074b09340caa0d0a4b8816c.zip
Take flows into consideration for policy lookup as initiator.
Fixes a bug where policies that only differ in their flow configuration lead to a handshake error. Found by claudio@ ok patrick@
-rw-r--r--sbin/iked/iked.h4
-rw-r--r--sbin/iked/ikev2.c14
-rw-r--r--sbin/iked/policy.c8
3 files changed, 15 insertions, 11 deletions
diff --git a/sbin/iked/iked.h b/sbin/iked/iked.h
index 4945fdcd70d..bf94b98bd07 100644
--- a/sbin/iked/iked.h
+++ b/sbin/iked/iked.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: iked.h,v 1.182 2021/01/28 01:20:37 mortimer Exp $ */
+/* $OpenBSD: iked.h,v 1.183 2021/02/01 16:37:48 tobhe Exp $ */
/*
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -848,7 +848,7 @@ int config_getcertpartialchain(struct iked *, struct imsg *);
/* policy.c */
void policy_init(struct iked *);
int policy_lookup(struct iked *, struct iked_message *,
- struct iked_proposals *proposals);
+ struct iked_proposals *, struct iked_flows *, int);
int policy_lookup_sa(struct iked *, struct iked_sa *);
struct iked_policy *
policy_test(struct iked *, struct iked_policy *);
diff --git a/sbin/iked/ikev2.c b/sbin/iked/ikev2.c
index e111c7c30c2..8d2af278da2 100644
--- a/sbin/iked/ikev2.c
+++ b/sbin/iked/ikev2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ikev2.c,v 1.300 2021/01/31 17:23:45 tobhe Exp $ */
+/* $OpenBSD: ikev2.c,v 1.301 2021/02/01 16:37:48 tobhe Exp $ */
/*
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -598,7 +598,7 @@ ikev2_recv(struct iked *env, struct iked_message *msg)
betoh64(hdr->ike_ispi), betoh64(hdr->ike_rspi),
initiator);
msg->msg_msgid = betoh32(hdr->ike_msgid);
- if (policy_lookup(env, msg, NULL) != 0)
+ if (policy_lookup(env, msg, NULL, NULL, 0) != 0)
return;
logit(hdr->ike_exchange == IKEV2_EXCHANGE_INFORMATIONAL ?
@@ -882,7 +882,7 @@ ikev2_ike_auth_recv(struct iked *env, struct iked_sa *sa,
old = sa->sa_policy;
sa->sa_policy = NULL;
- if (policy_lookup(env, msg, &sa->sa_proposals) != 0 ||
+ if (policy_lookup(env, msg, &sa->sa_proposals, NULL, 0) != 0 ||
msg->msg_policy == NULL) {
log_info("%s: no compatible policy found",
SPI_SA(sa, __func__));
@@ -917,8 +917,8 @@ ikev2_ike_auth_recv(struct iked *env, struct iked_sa *sa,
/* verify policy on initiator */
sa->sa_policy = NULL;
- if (policy_lookup(env, msg, &sa->sa_proposals) != 0 ||
- msg->msg_policy != old) {
+ if (policy_lookup(env, msg, &sa->sa_proposals, &old->pol_flows,
+ old->pol_nflows) != 0 || msg->msg_policy != old) {
/* get dstid */
if (msg->msg_id.id_type) {
@@ -5323,8 +5323,8 @@ ikev2_sa_responder(struct iked *env, struct iked_sa *sa, struct iked_sa *osa,
if (osa == NULL) {
old = sa->sa_policy;
sa->sa_policy = NULL;
- if (policy_lookup(env, msg, &msg->msg_proposals) != 0 ||
- msg->msg_policy == NULL) {
+ if (policy_lookup(env, msg, &msg->msg_proposals,
+ NULL, 0) != 0 || msg->msg_policy == NULL) {
sa->sa_policy = old;
log_info("%s: no proposal chosen", __func__);
msg->msg_error = IKEV2_N_NO_PROPOSAL_CHOSEN;
diff --git a/sbin/iked/policy.c b/sbin/iked/policy.c
index da25500457b..df7f2676dd1 100644
--- a/sbin/iked/policy.c
+++ b/sbin/iked/policy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: policy.c,v 1.74 2020/12/21 22:49:36 tobhe Exp $ */
+/* $OpenBSD: policy.c,v 1.75 2021/02/01 16:37:48 tobhe Exp $ */
/*
* Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
@@ -76,7 +76,8 @@ policy_init(struct iked *env)
*/
int
policy_lookup(struct iked *env, struct iked_message *msg,
- struct iked_proposals *proposals)
+ struct iked_proposals *proposals, struct iked_flows *flows,
+ int nflows)
{
struct iked_policy pol;
char *s, idstr[IKED_ID_SIZE];
@@ -92,6 +93,9 @@ policy_lookup(struct iked *env, struct iked_message *msg,
if (proposals != NULL)
pol.pol_proposals = *proposals;
pol.pol_af = msg->msg_peer.ss_family;
+ if (flows)
+ pol.pol_flows = *flows;
+ pol.pol_nflows = nflows;
if (msg->msg_flags & IKED_MSG_FLAGS_USE_TRANSPORT)
pol.pol_flags |= IKED_POLICY_TRANSPORT;
memcpy(&pol.pol_peer.addr, &msg->msg_peer, sizeof(msg->msg_peer));