From: Tobias Brunner Date: Mon, 14 Oct 2019 15:24:15 +0000 (+0200) Subject: ike-delete: Continue break-before-make reauth if server concurrently deletes SA X-Git-Tag: 5.8.2dr1~7^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=60457e2aef415e27a05f7f86f0ad7b1c1d06c2d9;p=thirdparty%2Fstrongswan.git 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. --- diff --git a/src/libcharon/sa/ikev2/tasks/ike_delete.c b/src/libcharon/sa/ikev2/tasks/ike_delete.c index fd36b144a2..49cd663708 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_delete.c +++ b/src/libcharon/sa/ikev2/tasks/ike_delete.c @@ -168,6 +168,33 @@ METHOD(task_t, process_r, status_t, 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, 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 */ 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 */ return DESTROY_ME; }