From da288a07aa248a38a3ba6dde5e7b110e8f85aced Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 29 May 2018 16:57:49 +0200 Subject: [PATCH] ike-auth: Consider negotiated IKE proposal when selecting peer configs 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 | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/libcharon/sa/ikev2/tasks/ike_auth.c b/src/libcharon/sa/ikev2/tasks/ike_auth.c index 6b63197d5..96405f2b8 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_auth.c +++ b/src/libcharon/sa/ikev2/tasks/ike_auth.c @@ -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;