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.
This commit is contained in:
@@ -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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user