Destroy existing IKE_SAs with same identities when receiving INITIAL_CONTACT
This commit is contained in:
@@ -1394,7 +1394,7 @@ METHOD(ike_sa_manager_t, checkin_and_destroy, void,
|
|||||||
}
|
}
|
||||||
|
|
||||||
METHOD(ike_sa_manager_t, check_uniqueness, bool,
|
METHOD(ike_sa_manager_t, check_uniqueness, bool,
|
||||||
private_ike_sa_manager_t *this, ike_sa_t *ike_sa)
|
private_ike_sa_manager_t *this, ike_sa_t *ike_sa, bool force_replace)
|
||||||
{
|
{
|
||||||
bool cancel = FALSE;
|
bool cancel = FALSE;
|
||||||
peer_cfg_t *peer_cfg;
|
peer_cfg_t *peer_cfg;
|
||||||
@@ -1408,7 +1408,7 @@ METHOD(ike_sa_manager_t, check_uniqueness, bool,
|
|||||||
|
|
||||||
peer_cfg = ike_sa->get_peer_cfg(ike_sa);
|
peer_cfg = ike_sa->get_peer_cfg(ike_sa);
|
||||||
policy = peer_cfg->get_unique_policy(peer_cfg);
|
policy = peer_cfg->get_unique_policy(peer_cfg);
|
||||||
if (policy == UNIQUE_NO)
|
if (policy == UNIQUE_NO && !force_replace)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1456,6 +1456,13 @@ METHOD(ike_sa_manager_t, check_uniqueness, bool,
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (force_replace)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "destroying duplicate IKE_SA for peer '%Y', "
|
||||||
|
"received INITIAL_CONTACT", other);
|
||||||
|
checkin_and_destroy(this, duplicate);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
peer_cfg = duplicate->get_peer_cfg(duplicate);
|
peer_cfg = duplicate->get_peer_cfg(duplicate);
|
||||||
if (peer_cfg && peer_cfg->equals(peer_cfg, ike_sa->get_peer_cfg(ike_sa)))
|
if (peer_cfg && peer_cfg->equals(peer_cfg, ike_sa->get_peer_cfg(ike_sa)))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -106,10 +106,12 @@ struct ike_sa_manager_t {
|
|||||||
* deadlocks occur otherwise.
|
* deadlocks occur otherwise.
|
||||||
*
|
*
|
||||||
* @param ike_sa ike_sa to check
|
* @param ike_sa ike_sa to check
|
||||||
|
* @param force_replace replace existing SAs, regardless of unique policy
|
||||||
* @return TRUE, if the given IKE_SA has duplicates and
|
* @return TRUE, if the given IKE_SA has duplicates and
|
||||||
* should be deleted
|
* should be deleted
|
||||||
*/
|
*/
|
||||||
bool (*check_uniqueness)(ike_sa_manager_t *this, ike_sa_t *ike_sa);
|
bool (*check_uniqueness)(ike_sa_manager_t *this, ike_sa_t *ike_sa,
|
||||||
|
bool force_replace);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if we already have a connected IKE_SA between two identities.
|
* Check if we already have a connected IKE_SA between two identities.
|
||||||
|
|||||||
@@ -106,6 +106,11 @@ struct private_ike_auth_t {
|
|||||||
* should we send a AUTHENTICATION_FAILED notify?
|
* should we send a AUTHENTICATION_FAILED notify?
|
||||||
*/
|
*/
|
||||||
bool authentication_failed;
|
bool authentication_failed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* received an INITIAL_CONTACT?
|
||||||
|
*/
|
||||||
|
bool initial_contact;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -612,6 +617,14 @@ static status_t process_r(private_ike_auth_t *this, message_t *message)
|
|||||||
return NEED_MORE;
|
return NEED_MORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If authenticated (with non-EAP) and received INITIAL_CONTACT,
|
||||||
|
* delete any existing IKE_SAs with that peer. */
|
||||||
|
if (message->get_message_id(message) == 1 &&
|
||||||
|
message->get_notify(message, INITIAL_CONTACT))
|
||||||
|
{
|
||||||
|
this->initial_contact = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* store authentication information */
|
/* store authentication information */
|
||||||
cfg = auth_cfg_create();
|
cfg = auth_cfg_create();
|
||||||
cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, FALSE), FALSE);
|
cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, FALSE), FALSE);
|
||||||
@@ -705,6 +718,13 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
|
|||||||
get_reserved_id_bytes(this, id_payload);
|
get_reserved_id_bytes(this, id_payload);
|
||||||
message->add_payload(message, (payload_t*)id_payload);
|
message->add_payload(message, (payload_t*)id_payload);
|
||||||
|
|
||||||
|
if (this->initial_contact)
|
||||||
|
{
|
||||||
|
charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager,
|
||||||
|
this->ike_sa, TRUE);
|
||||||
|
this->initial_contact = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if ((uintptr_t)cfg->get(cfg, AUTH_RULE_AUTH_CLASS) == AUTH_CLASS_EAP)
|
if ((uintptr_t)cfg->get(cfg, AUTH_RULE_AUTH_CLASS) == AUTH_CLASS_EAP)
|
||||||
{ /* EAP-only authentication */
|
{ /* EAP-only authentication */
|
||||||
if (!this->ike_sa->supports_extension(this->ike_sa,
|
if (!this->ike_sa->supports_extension(this->ike_sa,
|
||||||
@@ -786,7 +806,7 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
|
|||||||
if (!this->do_another_auth && !this->expect_another_auth)
|
if (!this->do_another_auth && !this->expect_another_auth)
|
||||||
{
|
{
|
||||||
if (charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager,
|
if (charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager,
|
||||||
this->ike_sa))
|
this->ike_sa, FALSE))
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "cancelling IKE_SA setup due uniqueness policy");
|
DBG1(DBG_IKE, "cancelling IKE_SA setup due uniqueness policy");
|
||||||
message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
|
message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
|
||||||
|
|||||||
Reference in New Issue
Block a user