ike-delete: Continue break-before-make reauth if server concurrently deletes SA
There seem to be servers around that, upon receiving a delete from the client, instead of responding with an empty INFORMATIONAL, send a delete themselves.
This commit is contained in:
@@ -168,6 +168,33 @@ METHOD(task_t, process_r, status_t,
|
|||||||
return NEED_MORE;
|
return NEED_MORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if we are currently deleting this IKE_SA in a break-before-make reauth.
|
||||||
|
*/
|
||||||
|
static bool is_reauthenticating(private_ike_delete_t *this)
|
||||||
|
{
|
||||||
|
enumerator_t *tasks;
|
||||||
|
task_t *task;
|
||||||
|
|
||||||
|
if (!this->ike_sa->has_condition(this->ike_sa, COND_REAUTHENTICATING))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks = this->ike_sa->create_task_enumerator(this->ike_sa,
|
||||||
|
TASK_QUEUE_ACTIVE);
|
||||||
|
while (tasks->enumerate(tasks, &task))
|
||||||
|
{
|
||||||
|
if (task->get_type(task) == TASK_IKE_REAUTH)
|
||||||
|
{
|
||||||
|
tasks->destroy(tasks);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tasks->destroy(tasks);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(task_t, build_r, status_t,
|
METHOD(task_t, build_r, status_t,
|
||||||
private_ike_delete_t *this, message_t *message)
|
private_ike_delete_t *this, message_t *message)
|
||||||
{
|
{
|
||||||
@@ -177,6 +204,18 @@ METHOD(task_t, build_r, status_t,
|
|||||||
{ /* invoke ike_down() hook if SA has not been rekeyed */
|
{ /* invoke ike_down() hook if SA has not been rekeyed */
|
||||||
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
|
charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if we are currently deleting this IKE_SA due to a break-before-make
|
||||||
|
* reauthentication, make sure to not just silently destroy the SA if
|
||||||
|
* the peer concurrently deletes it */
|
||||||
|
if (is_reauthenticating(this))
|
||||||
|
{
|
||||||
|
if (this->ike_sa->reestablish(this->ike_sa) != SUCCESS)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "reauthenticating IKE_SA failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* completed, delete IKE_SA by returning DESTROY_ME */
|
/* completed, delete IKE_SA by returning DESTROY_ME */
|
||||||
return DESTROY_ME;
|
return DESTROY_ME;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user