mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-04 00:00:14 -04:00
ha: Destroy incomplete IKE_SAs after de-/activating a segment
The node that gets activated usually won't be able to complete the IKE_SA mainly because the IKE keys are now derived delayed, so the key material required to process a message often won't be available (only later IKE_AUTH messages and retransmits of earlier messages that the active node already received and synced the keys for may be decrypted). A second issue affects IKE_SAs with multiple key exchanges. Because the IntAuth value(s) are currently not synced, which are necessary to verify/create the AUTH payloads, the IKE_AUTH exchange couldn't be completed.
This commit is contained in:
parent
fd6ac87fc3
commit
97bd0e2297
@ -135,9 +135,11 @@ static void enable_disable(private_ha_segments_t *this, u_int segment,
|
|||||||
{
|
{
|
||||||
ike_sa_t *ike_sa;
|
ike_sa_t *ike_sa;
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
ike_sa_state_t old, new;
|
ike_sa_state_t old, new, cur;
|
||||||
ha_message_t *message = NULL;
|
ha_message_t *message = NULL;
|
||||||
ha_message_type_t type;
|
ha_message_type_t type;
|
||||||
|
array_t *to_destroy;
|
||||||
|
uint32_t unique_id;
|
||||||
bool changes = FALSE;
|
bool changes = FALSE;
|
||||||
|
|
||||||
if (segment > this->count)
|
if (segment > this->count)
|
||||||
@ -172,11 +174,13 @@ static void enable_disable(private_ha_segments_t *this, u_int segment,
|
|||||||
|
|
||||||
if (changes)
|
if (changes)
|
||||||
{
|
{
|
||||||
|
to_destroy = array_create(sizeof(u_int), 0);
|
||||||
enumerator = charon->ike_sa_manager->create_enumerator(
|
enumerator = charon->ike_sa_manager->create_enumerator(
|
||||||
charon->ike_sa_manager, TRUE);
|
charon->ike_sa_manager, TRUE);
|
||||||
while (enumerator->enumerate(enumerator, &ike_sa))
|
while (enumerator->enumerate(enumerator, &ike_sa))
|
||||||
{
|
{
|
||||||
if (ike_sa->get_state(ike_sa) != old)
|
cur = ike_sa->get_state(ike_sa);
|
||||||
|
if (cur != old && cur != IKE_CONNECTING)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -186,12 +190,35 @@ static void enable_disable(private_ha_segments_t *this, u_int segment,
|
|||||||
}
|
}
|
||||||
if (this->kernel->get_segment(this->kernel,
|
if (this->kernel->get_segment(this->kernel,
|
||||||
ike_sa->get_other_host(ike_sa)) == segment)
|
ike_sa->get_other_host(ike_sa)) == segment)
|
||||||
|
{
|
||||||
|
if (cur == IKE_CONNECTING)
|
||||||
|
{
|
||||||
|
unique_id = ike_sa->get_unique_id(ike_sa);
|
||||||
|
array_insert(to_destroy, ARRAY_TAIL, &unique_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
ike_sa->set_state(ike_sa, new);
|
ike_sa->set_state(ike_sa, new);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
log_segments(this, enable, segment);
|
log_segments(this, enable, segment);
|
||||||
|
|
||||||
|
while (array_remove(to_destroy, ARRAY_HEAD, &unique_id))
|
||||||
|
{
|
||||||
|
ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
|
||||||
|
unique_id);
|
||||||
|
if (ike_sa)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "destroying incomplete IKE_SA %s[%d] after "
|
||||||
|
"%sactivating HA segment %d", ike_sa->get_name(ike_sa),
|
||||||
|
unique_id, segment, enable ? "" : "de");
|
||||||
|
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
|
||||||
|
ike_sa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
array_destroy(to_destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notify)
|
if (notify)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user