child-cfg: Strip DH groups from both compared proposals
authorTobias Brunner <tobias@strongswan.org>
Mon, 22 Jan 2018 13:33:40 +0000 (14:33 +0100)
committerTobias Brunner <tobias@strongswan.org>
Fri, 9 Feb 2018 09:18:59 +0000 (10:18 +0100)
This fixes two issues, one is a bug if a DH group is configured for the
local ESP proposals and charon.prefer_configured_proposals is disabled.
This would cause the DH groups to get stripped not from the configured but
from the supplied proposal, which usually already has them stripped.  So
the proposals wouldn't match.  We'd have to always strip them from the local
proposal.  Since there are apparently implementations that, incorrectly, don't
remove the DH groups in the IKE_AUTH exchange (e.g. WatchGuard XTM25
appliances) we just strip them from both proposals.  It's a bit more lenient
that way and we don't have to complicate the code to only clone and strip the
local proposal, which would depend on a flag.

References #2503.

src/libcharon/config/child_cfg.c

index ec2a124..3d110e9 100644 (file)
@@ -224,6 +224,10 @@ METHOD(child_cfg_t, select_proposal, proposal_t*,
        while (prefer_enum->enumerate(prefer_enum, &proposal))
        {
                proposal = proposal->clone(proposal);
+               if (strip_dh)
+               {
+                       proposal->strip_dh(proposal, MODP_NONE);
+               }
                if (prefer_self)
                {
                        proposals->reset_enumerator(proposals, match_enum);
@@ -234,11 +238,13 @@ METHOD(child_cfg_t, select_proposal, proposal_t*,
                }
                while (match_enum->enumerate(match_enum, &match))
                {
+                       match = match->clone(match);
                        if (strip_dh)
                        {
-                               proposal->strip_dh(proposal, MODP_NONE);
+                               match->strip_dh(match, MODP_NONE);
                        }
                        selected = proposal->select(proposal, match, prefer_self, private);
+                       match->destroy(match);
                        if (selected)
                        {
                                DBG2(DBG_CFG, "received proposals: %#P", proposals);