From: Tobias Brunner Date: Tue, 8 Feb 2022 13:23:37 +0000 (+0100) Subject: ikev2: Reject IKE_INTERMEDIATE requests after IKE_AUTH X-Git-Tag: 6.0.0rc1~56^2~37 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=aedf73f7cf6e6ee1a99afe644b74011ab9011258;p=thirdparty%2Fstrongswan.git ikev2: Reject IKE_INTERMEDIATE requests after IKE_AUTH 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. --- diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index 8c07cf272d..c5cc34f0e7 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -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)); }