]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
ike: Don't reestablish IKE_SAs for which a deletion is queued
authorTobias Brunner <tobias@strongswan.org>
Thu, 13 Feb 2020 09:48:49 +0000 (10:48 +0100)
committerTobias Brunner <tobias@strongswan.org>
Fri, 21 Feb 2020 09:38:13 +0000 (10:38 +0100)
If an IKE_SA is terminated while a task is active, the delete task is
simply queued (unless the deletion is forced).  If the active task times
out before any optional timeout associated with the termination hits, the
IKE_SA previously was reestablished without considering the termination
request.

Fixes #3335.

src/libcharon/sa/ike_sa.c

index 53afe843d41902a134a5b27b9df63010193fdc82..81e1ff414e74c994b060ea96113a5a84ab2fd06f 100644 (file)
@@ -1928,9 +1928,10 @@ METHOD(ike_sa_t, reauth, status_t,
 }
 
 /**
- * Check if tasks to create CHILD_SAs are queued in the given queue
+ * Check if any tasks of a specific type are queued in the given queue.
  */
-static bool is_child_queued(private_ike_sa_t *this, task_queue_t queue)
+static bool is_task_queued(private_ike_sa_t *this, task_queue_t queue,
+                                                  task_type_t type)
 {
        enumerator_t *enumerator;
        task_t *task;
@@ -1940,8 +1941,7 @@ static bool is_child_queued(private_ike_sa_t *this, task_queue_t queue)
                                                                                                                        queue);
        while (enumerator->enumerate(enumerator, &task))
        {
-               if (task->get_type(task) == TASK_CHILD_CREATE ||
-                       task->get_type(task) == TASK_QUICK_MODE)
+               if (task->get_type(task) == type)
                {
                        found = TRUE;
                        break;
@@ -1951,6 +1951,24 @@ static bool is_child_queued(private_ike_sa_t *this, task_queue_t queue)
        return found;
 }
 
+/**
+ * Check if any tasks to create CHILD_SAs are queued in the given queue.
+ */
+static bool is_child_queued(private_ike_sa_t *this, task_queue_t queue)
+{
+       return is_task_queued(this, queue,
+                               this->version == IKEV1 ? TASK_QUICK_MODE : TASK_CHILD_CREATE);
+}
+
+/**
+ * Check if any tasks to delete the IKE_SA are queued in the given queue.
+ */
+static bool is_delete_queued(private_ike_sa_t *this, task_queue_t queue)
+{
+       return is_task_queued(this, queue,
+                               this->version == IKEV1 ? TASK_ISAKMP_DELETE : TASK_IKE_DELETE);
+}
+
 /**
  * Reestablish CHILD_SAs and migrate queued tasks.
  *
@@ -2036,6 +2054,12 @@ METHOD(ike_sa_t, reestablish, status_t,
        bool restart = FALSE;
        status_t status = FAILED;
 
+       if (is_delete_queued(this, TASK_QUEUE_QUEUED))
+       {       /* don't reestablish IKE_SAs that have explicitly been deleted in the
+                * mean time */
+               return FAILED;
+       }
+
        if (has_condition(this, COND_REAUTHENTICATING))
        {       /* only reauthenticate if we have children */
                if (array_count(this->child_sas) == 0