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.
This commit is contained in:
Tobias Brunner 2018-05-29 16:57:49 +02:00
parent 29e7fe63c3
commit da288a07aa
1 changed files with 14 additions and 1 deletions

View 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;