proper reauthentication:
IKE_SA is closed completely before the new is initiated, resolves some issues when a dynamic IP is requested from a pool
This commit is contained in:
@@ -82,6 +82,7 @@ sa/tasks/ike_dpd.c sa/tasks/ike_dpd.h \
|
|||||||
sa/tasks/ike_init.c sa/tasks/ike_init.h \
|
sa/tasks/ike_init.c sa/tasks/ike_init.h \
|
||||||
sa/tasks/ike_natd.c sa/tasks/ike_natd.h \
|
sa/tasks/ike_natd.c sa/tasks/ike_natd.h \
|
||||||
sa/tasks/ike_rekey.c sa/tasks/ike_rekey.h \
|
sa/tasks/ike_rekey.c sa/tasks/ike_rekey.h \
|
||||||
|
sa/tasks/ike_reauth.c sa/tasks/ike_reauth.h \
|
||||||
sa/tasks/task.c sa/tasks/task.h
|
sa/tasks/task.c sa/tasks/task.h
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ static void execute(private_rekey_ike_sa_job_t *this)
|
|||||||
{
|
{
|
||||||
if (this->reauth)
|
if (this->reauth)
|
||||||
{
|
{
|
||||||
ike_sa->reestablish(ike_sa);
|
status = ike_sa->reestablish(ike_sa);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
+10
-71
@@ -52,6 +52,7 @@
|
|||||||
#include <sa/tasks/ike_config.h>
|
#include <sa/tasks/ike_config.h>
|
||||||
#include <sa/tasks/ike_cert.h>
|
#include <sa/tasks/ike_cert.h>
|
||||||
#include <sa/tasks/ike_rekey.h>
|
#include <sa/tasks/ike_rekey.h>
|
||||||
|
#include <sa/tasks/ike_reauth.h>
|
||||||
#include <sa/tasks/ike_delete.h>
|
#include <sa/tasks/ike_delete.h>
|
||||||
#include <sa/tasks/ike_dpd.h>
|
#include <sa/tasks/ike_dpd.h>
|
||||||
#include <sa/tasks/child_create.h>
|
#include <sa/tasks/child_create.h>
|
||||||
@@ -356,29 +357,25 @@ static void set_peer_cfg(private_ike_sa_t *this, peer_cfg_t *peer_cfg)
|
|||||||
if (this->my_host->is_anyaddr(this->my_host))
|
if (this->my_host->is_anyaddr(this->my_host))
|
||||||
{
|
{
|
||||||
host_t *me = this->ike_cfg->get_my_host(this->ike_cfg);
|
host_t *me = this->ike_cfg->get_my_host(this->ike_cfg);
|
||||||
|
|
||||||
set_my_host(this, me->clone(me));
|
set_my_host(this, me->clone(me));
|
||||||
}
|
}
|
||||||
if (this->other_host->is_anyaddr(this->other_host))
|
if (this->other_host->is_anyaddr(this->other_host))
|
||||||
{
|
{
|
||||||
host_t *other = this->ike_cfg->get_other_host(this->ike_cfg);
|
host_t *other = this->ike_cfg->get_other_host(this->ike_cfg);
|
||||||
|
|
||||||
set_other_host(this, other->clone(other));
|
set_other_host(this, other->clone(other));
|
||||||
}
|
}
|
||||||
/* apply IDs if they are not already set */
|
/* apply IDs if they are not already set */
|
||||||
if (this->my_id->contains_wildcards(this->my_id))
|
if (this->my_id->contains_wildcards(this->my_id))
|
||||||
{
|
{
|
||||||
identification_t *my_id = this->peer_cfg->get_my_id(this->peer_cfg);
|
|
||||||
|
|
||||||
DESTROY_IF(this->my_id);
|
DESTROY_IF(this->my_id);
|
||||||
this->my_id = my_id->clone(my_id);
|
this->my_id = this->peer_cfg->get_my_id(this->peer_cfg);
|
||||||
|
this->my_id = this->my_id->clone(this->my_id);
|
||||||
}
|
}
|
||||||
if (this->other_id->contains_wildcards(this->other_id))
|
if (this->other_id->contains_wildcards(this->other_id))
|
||||||
{
|
{
|
||||||
identification_t *other_id = this->peer_cfg->get_other_id(this->peer_cfg);
|
|
||||||
|
|
||||||
DESTROY_IF(this->other_id);
|
DESTROY_IF(this->other_id);
|
||||||
this->other_id = other_id->clone(other_id);
|
this->other_id = this->peer_cfg->get_other_id(this->peer_cfg);
|
||||||
|
this->other_id = this->other_id->clone(this->other_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1560,72 +1557,14 @@ static status_t rekey(private_ike_sa_t *this)
|
|||||||
/**
|
/**
|
||||||
* Implementation of ike_sa_t.reestablish
|
* Implementation of ike_sa_t.reestablish
|
||||||
*/
|
*/
|
||||||
static void reestablish(private_ike_sa_t *this)
|
static status_t reestablish(private_ike_sa_t *this)
|
||||||
{
|
{
|
||||||
private_ike_sa_t *other;
|
|
||||||
iterator_t *iterator;
|
|
||||||
child_sa_t *child_sa;
|
|
||||||
child_cfg_t *child_cfg;
|
|
||||||
task_t *task;
|
task_t *task;
|
||||||
job_t *job;
|
|
||||||
|
|
||||||
other = (private_ike_sa_t*)charon->ike_sa_manager->checkout_new(
|
task = (task_t*)ike_reauth_create(&this->public);
|
||||||
charon->ike_sa_manager, TRUE);
|
this->task_manager->queue_task(this->task_manager, task);
|
||||||
|
|
||||||
set_peer_cfg(other, this->peer_cfg);
|
return this->task_manager->initiate(this->task_manager);
|
||||||
other->other_host->destroy(other->other_host);
|
|
||||||
other->other_host = this->other_host->clone(this->other_host);
|
|
||||||
if (this->my_virtual_ip)
|
|
||||||
{
|
|
||||||
/* if we already have a virtual IP, we reuse it */
|
|
||||||
set_virtual_ip(other, TRUE, this->my_virtual_ip);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->state == IKE_ESTABLISHED)
|
|
||||||
{
|
|
||||||
task = (task_t*)ike_init_create(&other->public, TRUE, NULL);
|
|
||||||
other->task_manager->queue_task(other->task_manager, task);
|
|
||||||
task = (task_t*)ike_natd_create(&other->public, TRUE);
|
|
||||||
other->task_manager->queue_task(other->task_manager, task);
|
|
||||||
task = (task_t*)ike_cert_create(&other->public, TRUE);
|
|
||||||
other->task_manager->queue_task(other->task_manager, task);
|
|
||||||
task = (task_t*)ike_config_create(&other->public, TRUE);
|
|
||||||
other->task_manager->queue_task(other->task_manager, task);
|
|
||||||
task = (task_t*)ike_auth_create(&other->public, TRUE);
|
|
||||||
other->task_manager->queue_task(other->task_manager, task);
|
|
||||||
}
|
|
||||||
|
|
||||||
other->task_manager->adopt_tasks(other->task_manager, this->task_manager);
|
|
||||||
|
|
||||||
/* Create task for established children, adopt routed children directly */
|
|
||||||
iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
|
|
||||||
while(iterator->iterate(iterator, (void**)&child_sa))
|
|
||||||
{
|
|
||||||
switch (child_sa->get_state(child_sa))
|
|
||||||
{
|
|
||||||
case CHILD_ROUTED:
|
|
||||||
{
|
|
||||||
iterator->remove(iterator);
|
|
||||||
other->child_sas->insert_first(other->child_sas, child_sa);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
child_cfg = child_sa->get_config(child_sa);
|
|
||||||
task = (task_t*)child_create_create(&other->public, child_cfg);
|
|
||||||
other->task_manager->queue_task(other->task_manager, task);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
iterator->destroy(iterator);
|
|
||||||
|
|
||||||
other->task_manager->initiate(other->task_manager);
|
|
||||||
|
|
||||||
charon->ike_sa_manager->checkin(charon->ike_sa_manager, &other->public);
|
|
||||||
|
|
||||||
job = (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE);
|
|
||||||
charon->processor->queue_job(charon->processor, job);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1930,7 +1869,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
|
|||||||
this->public.enable_natt = (void (*)(ike_sa_t*, bool)) enable_natt;
|
this->public.enable_natt = (void (*)(ike_sa_t*, bool)) enable_natt;
|
||||||
this->public.is_natt_enabled = (bool (*)(ike_sa_t*)) is_natt_enabled;
|
this->public.is_natt_enabled = (bool (*)(ike_sa_t*)) is_natt_enabled;
|
||||||
this->public.rekey = (status_t (*)(ike_sa_t*))rekey;
|
this->public.rekey = (status_t (*)(ike_sa_t*))rekey;
|
||||||
this->public.reestablish = (void (*)(ike_sa_t*))reestablish;
|
this->public.reestablish = (status_t (*)(ike_sa_t*))reestablish;
|
||||||
this->public.inherit = (status_t (*)(ike_sa_t*,ike_sa_t*))inherit;
|
this->public.inherit = (status_t (*)(ike_sa_t*,ike_sa_t*))inherit;
|
||||||
this->public.generate_message = (status_t (*)(ike_sa_t*,message_t*,packet_t**))generate_message;
|
this->public.generate_message = (status_t (*)(ike_sa_t*,message_t*,packet_t**))generate_message;
|
||||||
this->public.reset = (void (*)(ike_sa_t*))reset;
|
this->public.reset = (void (*)(ike_sa_t*))reset;
|
||||||
|
|||||||
@@ -621,11 +621,12 @@ struct ike_sa_t {
|
|||||||
* @brief Restablish the IKE_SA.
|
* @brief Restablish the IKE_SA.
|
||||||
*
|
*
|
||||||
* Create a completely new IKE_SA with authentication, recreates all children
|
* Create a completely new IKE_SA with authentication, recreates all children
|
||||||
* within the IKE_SA, but lets the old IKE_SA untouched.
|
* within the IKE_SA, closes this IKE_SA.
|
||||||
*
|
*
|
||||||
* @param this calling object
|
* @param this calling object
|
||||||
|
* @return DESTROY_ME to destroy the IKE_SA
|
||||||
*/
|
*/
|
||||||
void (*reestablish) (ike_sa_t *this);
|
status_t (*reestablish) (ike_sa_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the virtual IP to use for this IKE_SA and its children.
|
* @brief Set the virtual IP to use for this IKE_SA and its children.
|
||||||
|
|||||||
@@ -302,6 +302,11 @@ static status_t build_request(private_task_manager_t *this)
|
|||||||
exchange = CREATE_CHILD_SA;
|
exchange = CREATE_CHILD_SA;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (activate_task(this, IKE_REAUTH))
|
||||||
|
{
|
||||||
|
exchange = INFORMATIONAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (activate_task(this, IKE_DEADPEER))
|
if (activate_task(this, IKE_DEADPEER))
|
||||||
{
|
{
|
||||||
exchange = INFORMATIONAL;
|
exchange = INFORMATIONAL;
|
||||||
@@ -456,7 +461,7 @@ static void handle_collisions(private_task_manager_t *this, task_t *task)
|
|||||||
|
|
||||||
/* do we have to check */
|
/* do we have to check */
|
||||||
if (type == IKE_REKEY || type == CHILD_REKEY ||
|
if (type == IKE_REKEY || type == CHILD_REKEY ||
|
||||||
type == CHILD_DELETE || type == IKE_DELETE)
|
type == CHILD_DELETE || type == IKE_DELETE || type == IKE_REAUTH)
|
||||||
{
|
{
|
||||||
/* find an exchange collision, and notify these tasks */
|
/* find an exchange collision, and notify these tasks */
|
||||||
iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE);
|
iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE);
|
||||||
@@ -465,7 +470,8 @@ static void handle_collisions(private_task_manager_t *this, task_t *task)
|
|||||||
switch (active->get_type(active))
|
switch (active->get_type(active))
|
||||||
{
|
{
|
||||||
case IKE_REKEY:
|
case IKE_REKEY:
|
||||||
if (type == IKE_REKEY || type == IKE_DELETE)
|
if (type == IKE_REKEY || type == IKE_DELETE ||
|
||||||
|
type == IKE_REAUTH)
|
||||||
{
|
{
|
||||||
ike_rekey_t *rekey = (ike_rekey_t*)active;
|
ike_rekey_t *rekey = (ike_rekey_t*)active;
|
||||||
rekey->collide(rekey, task);
|
rekey->collide(rekey, task);
|
||||||
|
|||||||
@@ -170,8 +170,9 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message)
|
|||||||
{
|
{
|
||||||
case FAILED:
|
case FAILED:
|
||||||
/* rekeying failed, fallback to old SA */
|
/* rekeying failed, fallback to old SA */
|
||||||
if (!(this->collision &&
|
if (!(this->collision && (
|
||||||
this->collision->get_type(this->collision) == IKE_DELETE))
|
this->collision->get_type(this->collision) == IKE_DELETE ||
|
||||||
|
this->collision->get_type(this->collision) == IKE_REAUTH)))
|
||||||
{
|
{
|
||||||
job_t *job;
|
job_t *job;
|
||||||
u_int32_t retry = RETRY_INTERVAL - (random() % RETRY_JITTER);
|
u_int32_t retry = RETRY_INTERVAL - (random() % RETRY_JITTER);
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ enum task_type_t {
|
|||||||
IKE_DEADPEER,
|
IKE_DEADPEER,
|
||||||
/** rekey an IKE_SA */
|
/** rekey an IKE_SA */
|
||||||
IKE_REKEY,
|
IKE_REKEY,
|
||||||
|
/** reestablish a complete IKE_SA */
|
||||||
|
IKE_REAUTH,
|
||||||
/** delete an IKE_SA */
|
/** delete an IKE_SA */
|
||||||
IKE_DELETE,
|
IKE_DELETE,
|
||||||
/** liveness check */
|
/** liveness check */
|
||||||
|
|||||||
Reference in New Issue
Block a user