Take flows into consideration for policy lookup as initiator.
authortobhe <tobhe@openbsd.org>
Mon, 1 Feb 2021 16:37:48 +0000 (16:37 +0000)
committertobhe <tobhe@openbsd.org>
Mon, 1 Feb 2021 16:37:48 +0000 (16:37 +0000)
Fixes a bug where policies that only differ in their flow
configuration lead to a handshake error.

Found by claudio@
ok patrick@

sbin/iked/iked.h
sbin/iked/ikev2.c
sbin/iked/policy.c

index 4945fdc..bf94b98 100644 (file)
@@ -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 *);
index e111c7c..8d2af27 100644 (file)
@@ -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;
index da25500..df7f267 100644 (file)
@@ -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));