]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
ike-auth: Consider negotiated IKE proposal when selecting peer configs
authorTobias Brunner <tobias@strongswan.org>
Tue, 29 May 2018 14:57:49 +0000 (16:57 +0200)
committerTobias Brunner <tobias@strongswan.org>
Thu, 28 Jun 2018 16:46:41 +0000 (18:46 +0200)
In some scenarios we might find multiple usable peer configs with different
IKE proposals.  This is a problem if we use a config with non-matching
proposals that later causes IKE rekeying to fail.  It might even be a problem
already when creating the CHILD_SA if the proposals of IKE and CHILD_SA
are consistent.

src/libcharon/sa/ikev2/tasks/ike_auth.c

index 6b63197d54b949732753012aee21789835b8385a..96405f2b8744a5f9cdc340ba1c6cd36183c7508d 100644 (file)
@@ -285,13 +285,18 @@ static bool load_cfg_candidates(private_ike_auth_t *this)
 {
        enumerator_t *enumerator;
        peer_cfg_t *peer_cfg;
+       ike_cfg_t *ike_cfg;
        host_t *me, *other;
        identification_t *my_id, *other_id;
+       proposal_t *ike_proposal;
+       bool private;
 
        me = this->ike_sa->get_my_host(this->ike_sa);
        other = this->ike_sa->get_other_host(this->ike_sa);
        my_id = this->ike_sa->get_my_id(this->ike_sa);
        other_id = this->ike_sa->get_other_id(this->ike_sa);
+       ike_proposal = this->ike_sa->get_proposal(this->ike_sa);
+       private = this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN);
 
        DBG1(DBG_CFG, "looking for peer configs matching %H[%Y]...%H[%Y]",
                 me, my_id, other, other_id);
@@ -299,11 +304,18 @@ static bool load_cfg_candidates(private_ike_auth_t *this)
                                                                                        me, other, my_id, other_id, IKEV2);
        while (enumerator->enumerate(enumerator, &peer_cfg))
        {
+               /* ignore all configs that have no matching IKE proposal */
+               ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
+               if (!ike_cfg->has_proposal(ike_cfg, ike_proposal, private))
+               {
+                       DBG2(DBG_CFG, "ignore candidate '%s' without matching IKE proposal",
+                                peer_cfg->get_name(peer_cfg));
+                       continue;
+               }
                peer_cfg->get_ref(peer_cfg);
                if (this->peer_cfg == NULL)
                {       /* best match */
                        this->peer_cfg = peer_cfg;
-                       this->ike_sa->set_peer_cfg(this->ike_sa, peer_cfg);
                }
                else
                {
@@ -313,6 +325,7 @@ static bool load_cfg_candidates(private_ike_auth_t *this)
        enumerator->destroy(enumerator);
        if (this->peer_cfg)
        {
+               this->ike_sa->set_peer_cfg(this->ike_sa, this->peer_cfg);
                DBG1(DBG_CFG, "selected peer config '%s'",
                         this->peer_cfg->get_name(this->peer_cfg));
                return TRUE;