]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
ikev2: Reject IKE_INTERMEDIATE requests after IKE_AUTH
authorTobias Brunner <tobias@strongswan.org>
Tue, 8 Feb 2022 13:23:37 +0000 (14:23 +0100)
committerTobias Brunner <tobias@strongswan.org>
Wed, 7 Aug 2024 14:20:18 +0000 (16:20 +0200)
We currently only support these exchanges for additional key exchanges,
so once we have the final keys derived and the ike-init task is removed,
we don't expect any more of them.

src/libcharon/sa/ikev2/task_manager_v2.c

index 8c07cf272dba9eaf8830c8ab9e0c0c08607a01b5..c5cc34f0e7d8b6839494c70ccfce30cedd29fac7 100644 (file)
@@ -244,6 +244,49 @@ METHOD(task_manager_t, flush, void,
        flush_queue(this, TASK_QUEUE_ACTIVE);
 }
 
+/**
+ * Check if a given task has been queued already
+ */
+static bool has_queued(private_task_manager_t *this, task_queue_t queue,
+                                          task_type_t type)
+{
+       enumerator_t *enumerator;
+       array_t *array;
+       task_t *task;
+       bool found = FALSE;
+
+       switch (queue)
+       {
+               case TASK_QUEUE_ACTIVE:
+                       array = this->active_tasks;
+                       break;
+               case TASK_QUEUE_PASSIVE:
+                       array = this->passive_tasks;
+                       break;
+               case TASK_QUEUE_QUEUED:
+                       array = this->queued_tasks;
+                       break;
+               default:
+                       return FALSE;
+       }
+
+       enumerator = array_create_enumerator(array);
+       while (enumerator->enumerate(enumerator, &task))
+       {
+               if (queue == TASK_QUEUE_QUEUED)
+               {
+                       task = ((queued_task_t*)task)->task;
+               }
+               if (task->get_type(task) == type)
+               {
+                       found = TRUE;
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       return found;
+}
+
 /**
  * Move a task of a specific type from the queue to the active list, if it is
  * not delayed.
@@ -1676,6 +1719,11 @@ static inline bool reject_request(private_task_manager_t *this,
                case IKE_SA_INIT:
                        reject = state != IKE_CREATED;
                        break;
+               case IKE_INTERMEDIATE:
+                       /* only accept this if we have not yet completed the KEs */
+                       reject = state != IKE_CONNECTING ||
+                                        !has_queued(this, TASK_QUEUE_PASSIVE, TASK_IKE_INIT);
+                       break;
                case IKE_AUTH:
                        reject = state != IKE_CONNECTING;
                        break;
@@ -2029,64 +2077,42 @@ METHOD(task_manager_t, queue_task, void,
        queue_task_delayed(this, task, 0);
 }
 
-/**
- * Check if a given task has been queued already
- */
-static bool has_queued(private_task_manager_t *this, task_type_t type)
-{
-       enumerator_t *enumerator;
-       bool found = FALSE;
-       queued_task_t *queued;
-
-       enumerator = array_create_enumerator(this->queued_tasks);
-       while (enumerator->enumerate(enumerator, &queued))
-       {
-               if (queued->task->get_type(queued->task) == type)
-               {
-                       found = TRUE;
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-       return found;
-}
-
 METHOD(task_manager_t, queue_ike, void,
        private_task_manager_t *this)
 {
-       if (!has_queued(this, TASK_IKE_VENDOR))
+       if (!has_queued(this, TASK_QUEUE_QUEUED, TASK_IKE_VENDOR))
        {
                queue_task(this, (task_t*)ike_vendor_create(this->ike_sa, TRUE));
        }
-       if (!has_queued(this, TASK_IKE_INIT))
+       if (!has_queued(this, TASK_QUEUE_QUEUED, TASK_IKE_INIT))
        {
                queue_task(this, (task_t*)ike_init_create(this->ike_sa, TRUE, NULL));
        }
-       if (!has_queued(this, TASK_IKE_NATD))
+       if (!has_queued(this, TASK_QUEUE_QUEUED, TASK_IKE_NATD))
        {
                queue_task(this, (task_t*)ike_natd_create(this->ike_sa, TRUE));
        }
-       if (!has_queued(this, TASK_IKE_CERT_PRE))
+       if (!has_queued(this, TASK_QUEUE_QUEUED, TASK_IKE_CERT_PRE))
        {
                queue_task(this, (task_t*)ike_cert_pre_create(this->ike_sa, TRUE));
        }
-       if (!has_queued(this, TASK_IKE_AUTH))
+       if (!has_queued(this, TASK_QUEUE_QUEUED, TASK_IKE_AUTH))
        {
                queue_task(this, (task_t*)ike_auth_create(this->ike_sa, TRUE));
        }
-       if (!has_queued(this, TASK_IKE_CERT_POST))
+       if (!has_queued(this, TASK_QUEUE_QUEUED, TASK_IKE_CERT_POST))
        {
                queue_task(this, (task_t*)ike_cert_post_create(this->ike_sa, TRUE));
        }
-       if (!has_queued(this, TASK_IKE_CONFIG))
+       if (!has_queued(this, TASK_QUEUE_QUEUED, TASK_IKE_CONFIG))
        {
                queue_task(this, (task_t*)ike_config_create(this->ike_sa, TRUE));
        }
-       if (!has_queued(this, TASK_IKE_AUTH_LIFETIME))
+       if (!has_queued(this, TASK_QUEUE_QUEUED, TASK_IKE_AUTH_LIFETIME))
        {
                queue_task(this, (task_t*)ike_auth_lifetime_create(this->ike_sa, TRUE));
        }
-       if (!has_queued(this, TASK_IKE_MOBIKE))
+       if (!has_queued(this, TASK_QUEUE_QUEUED, TASK_IKE_MOBIKE))
        {
                peer_cfg_t *peer_cfg;
 
@@ -2096,12 +2122,12 @@ METHOD(task_manager_t, queue_ike, void,
                        queue_task(this, (task_t*)ike_mobike_create(this->ike_sa, TRUE));
                }
        }
-       if (!has_queued(this, TASK_IKE_ESTABLISH))
+       if (!has_queued(this, TASK_QUEUE_QUEUED, TASK_IKE_ESTABLISH))
        {
                queue_task(this, (task_t*)ike_establish_create(this->ike_sa, TRUE));
        }
 #ifdef ME
-       if (!has_queued(this, TASK_IKE_ME))
+       if (!has_queued(this, TASK_QUEUE_QUEUED, TASK_IKE_ME))
        {
                queue_task(this, (task_t*)ike_me_create(this->ike_sa, TRUE));
        }