implemented reauthentication using the new reauth=yes|no parameter
This commit is contained in:
+107
-55
@@ -1730,7 +1730,7 @@ static status_t destroy_child_sa(private_ike_sa_t *this, protocol_id_t protocol,
|
||||
/**
|
||||
* Implementation of ike_sa_t.set_lifetimes.
|
||||
*/
|
||||
static void set_lifetimes(private_ike_sa_t *this,
|
||||
static void set_lifetimes(private_ike_sa_t *this, bool reauth,
|
||||
u_int32_t soft_lifetime, u_int32_t hard_lifetime)
|
||||
{
|
||||
job_t *job;
|
||||
@@ -1738,7 +1738,7 @@ static void set_lifetimes(private_ike_sa_t *this,
|
||||
if (soft_lifetime)
|
||||
{
|
||||
this->time.rekey = this->time.established + soft_lifetime;
|
||||
job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id);
|
||||
job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, reauth);
|
||||
charon->event_queue->add_relative(charon->event_queue, job,
|
||||
soft_lifetime * 1000);
|
||||
}
|
||||
@@ -1752,58 +1752,6 @@ static void set_lifetimes(private_ike_sa_t *this,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.rekey.
|
||||
*/
|
||||
static status_t rekey(private_ike_sa_t *this)
|
||||
{
|
||||
rekey_ike_sa_t *rekey_ike_sa;
|
||||
|
||||
DBG1(DBG_IKE, "rekeying IKE_SA between %H[%D]..%H[%D]",
|
||||
this->my_host, this->my_id, this->other_host, this->other_id);
|
||||
|
||||
if (this->state != IKE_ESTABLISHED)
|
||||
{
|
||||
SIG(IKE_REKEY_START, "rekeying IKE_SA");
|
||||
SIG(IKE_REKEY_FAILED, "unable to rekey IKE_SA in state %N",
|
||||
ike_sa_state_names, this->state);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
rekey_ike_sa = rekey_ike_sa_create(&this->public);
|
||||
return queue_transaction(this, (transaction_t*)rekey_ike_sa, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.get_rekeying_transaction.
|
||||
*/
|
||||
static transaction_t* get_rekeying_transaction(private_ike_sa_t *this)
|
||||
{
|
||||
return this->rekeying_transaction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.set_rekeying_transaction.
|
||||
*/
|
||||
static void set_rekeying_transaction(private_ike_sa_t *this, transaction_t *rekey)
|
||||
{
|
||||
this->rekeying_transaction = rekey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.adopt_children.
|
||||
*/
|
||||
static void adopt_children(private_ike_sa_t *this, private_ike_sa_t *other)
|
||||
{
|
||||
child_sa_t *child_sa;
|
||||
|
||||
while (other->child_sas->remove_last(other->child_sas,
|
||||
(void**)&child_sa) == SUCCESS)
|
||||
{
|
||||
this->child_sas->insert_first(this->child_sas, (void*)child_sa);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of public_ike_sa_t.delete.
|
||||
*/
|
||||
@@ -1842,6 +1790,109 @@ static status_t delete_(private_ike_sa_t *this)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.rekey.
|
||||
*/
|
||||
static status_t rekey(private_ike_sa_t *this)
|
||||
{
|
||||
rekey_ike_sa_t *rekey_ike_sa;
|
||||
|
||||
DBG1(DBG_IKE, "rekeying IKE_SA between %H[%D]..%H[%D]",
|
||||
this->my_host, this->my_id, this->other_host, this->other_id);
|
||||
|
||||
if (this->state != IKE_ESTABLISHED)
|
||||
{
|
||||
SIG(IKE_REKEY_START, "rekeying IKE_SA");
|
||||
SIG(IKE_REKEY_FAILED, "unable to rekey IKE_SA in state %N",
|
||||
ike_sa_state_names, this->state);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
rekey_ike_sa = rekey_ike_sa_create(&this->public);
|
||||
return queue_transaction(this, (transaction_t*)rekey_ike_sa, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.reauth.
|
||||
*/
|
||||
static status_t reauth(private_ike_sa_t *this)
|
||||
{
|
||||
connection_t *connection;
|
||||
child_sa_t *child_sa;
|
||||
iterator_t *iterator;
|
||||
|
||||
DBG1(DBG_IKE, "reauthenticating IKE_SA between %H[%D]..%H[%D]",
|
||||
this->my_host, this->my_id, this->other_host, this->other_id);
|
||||
|
||||
/* get a connection to initiate */
|
||||
connection = charon->connections->get_connection_by_hosts(charon->connections,
|
||||
this->my_host, this->other_host);
|
||||
if (connection == NULL)
|
||||
{
|
||||
DBG1(DBG_IKE, "no connection found to reauthenticate");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/* queue CREATE_CHILD_SA transactions to set up all CHILD_SAs */
|
||||
iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
|
||||
while (iterator->iterate(iterator, (void**)&child_sa))
|
||||
{
|
||||
job_t *job;
|
||||
policy_t *policy;
|
||||
linked_list_t *my_ts, *other_ts;
|
||||
my_ts = child_sa->get_my_traffic_selectors(child_sa);
|
||||
other_ts = child_sa->get_other_traffic_selectors(child_sa);
|
||||
policy = charon->policies->get_policy(charon->policies,
|
||||
this->my_id, this->other_id, my_ts, other_ts,
|
||||
this->my_host, this->other_host, NULL);
|
||||
if (policy == NULL)
|
||||
{
|
||||
DBG1(DBG_IKE, "policy not found to recreate CHILD_SA, skipped");
|
||||
continue;
|
||||
}
|
||||
|
||||
connection->get_ref(connection);
|
||||
job = (job_t*)initiate_job_create(connection, policy);
|
||||
charon->job_queue->add(charon->job_queue, job);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
connection->destroy(connection);
|
||||
|
||||
/* delete the old IKE_SA
|
||||
* TODO: we should delay the delete to avoid connectivity gaps?! */
|
||||
return delete_(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.get_rekeying_transaction.
|
||||
*/
|
||||
static transaction_t* get_rekeying_transaction(private_ike_sa_t *this)
|
||||
{
|
||||
return this->rekeying_transaction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.set_rekeying_transaction.
|
||||
*/
|
||||
static void set_rekeying_transaction(private_ike_sa_t *this, transaction_t *rekey)
|
||||
{
|
||||
this->rekeying_transaction = rekey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.adopt_children.
|
||||
*/
|
||||
static void adopt_children(private_ike_sa_t *this, private_ike_sa_t *other)
|
||||
{
|
||||
child_sa_t *child_sa;
|
||||
|
||||
while (other->child_sas->remove_last(other->child_sas,
|
||||
(void**)&child_sa) == SUCCESS)
|
||||
{
|
||||
this->child_sas->insert_first(this->child_sas, (void*)child_sa);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.get_next_message_id.
|
||||
*/
|
||||
@@ -1987,9 +2038,10 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
|
||||
this->public.destroy_child_sa = (status_t (*)(ike_sa_t*,protocol_id_t,u_int32_t))destroy_child_sa;
|
||||
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.set_lifetimes = (void(*)(ike_sa_t*,u_int32_t,u_int32_t))set_lifetimes;
|
||||
this->public.set_lifetimes = (void(*)(ike_sa_t*,bool,u_int32_t,u_int32_t))set_lifetimes;
|
||||
this->public.apply_connection = (void(*)(ike_sa_t*,connection_t*))apply_connection;
|
||||
this->public.rekey = (status_t(*)(ike_sa_t*))rekey;
|
||||
this->public.reauth = (status_t(*)(ike_sa_t*))reauth;
|
||||
this->public.get_rekeying_transaction = (transaction_t*(*)(ike_sa_t*))get_rekeying_transaction;
|
||||
this->public.set_rekeying_transaction = (void(*)(ike_sa_t*,transaction_t*))set_rekeying_transaction;
|
||||
this->public.adopt_children = (void(*)(ike_sa_t*,ike_sa_t*))adopt_children;
|
||||
|
||||
+13
-1
@@ -545,10 +545,11 @@ struct ike_sa_t {
|
||||
* hard_lifetime is only reached when rekeying at soft_lifetime fails.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param reauth use full reauthentication instead of rekeying.
|
||||
* @param soft_lifetime soft_lifetime
|
||||
* @param hard_lifetime hard_lifetime
|
||||
*/
|
||||
void (*set_lifetimes) (ike_sa_t *this,
|
||||
void (*set_lifetimes) (ike_sa_t *this, bool reauth,
|
||||
u_int32_t soft_lifetime, u_int32_t hard_lifetime);
|
||||
|
||||
/**
|
||||
@@ -561,6 +562,17 @@ struct ike_sa_t {
|
||||
*/
|
||||
status_t (*rekey) (ike_sa_t *this);
|
||||
|
||||
/**
|
||||
* @brief Reauthentication the IKE_SA.
|
||||
*
|
||||
* Create a completely new IKE_SA with authentication, recreates all children
|
||||
* within the IKE_SA and shuts the old SA down.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return - SUCCESS, if IKE_SA rekeying initiated
|
||||
*/
|
||||
status_t (*reauth) (ike_sa_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the transaction which rekeys this IKE_SA.
|
||||
*
|
||||
|
||||
@@ -323,6 +323,12 @@ static ike_sa_t* checkout_by_id(private_ike_sa_manager_t *this,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry->ike_sa->get_state(entry->ike_sa) == IKE_DELETING)
|
||||
{
|
||||
/* skip IKE_SA which are not useable */
|
||||
continue;
|
||||
}
|
||||
|
||||
found_my_id = entry->ike_sa->get_my_id(entry->ike_sa);
|
||||
found_other_id = entry->ike_sa->get_other_id(entry->ike_sa);
|
||||
found_my_host = entry->ike_sa->get_my_host(entry->ike_sa);
|
||||
|
||||
@@ -72,7 +72,8 @@ struct ike_sa_manager_t {
|
||||
* Allows the lookup of an IKE_SA by user IDs and hosts. It returns the
|
||||
* first found occurence, if there are multiple candidates. Supplied IDs
|
||||
* may contain wildcards, hosts may be %any.
|
||||
* If no IKE_SA is found, a new one is created.
|
||||
* If no IKE_SA is found, a new one is created. This is also the case when
|
||||
* the found IKE_SA is in the DELETING state.
|
||||
*
|
||||
* @param this the manager object
|
||||
* @param my_host address of our host
|
||||
|
||||
@@ -790,7 +790,8 @@ static status_t get_response(private_ike_sa_init_t *this,
|
||||
return DESTROY_ME;
|
||||
}
|
||||
|
||||
this->ike_sa->set_lifetimes(this->ike_sa,
|
||||
this->ike_sa->set_lifetimes(this->ike_sa,
|
||||
this->connection->get_reauth(this->connection),
|
||||
this->connection->get_soft_lifetime(this->connection),
|
||||
this->connection->get_hard_lifetime(this->connection));
|
||||
|
||||
@@ -1030,6 +1031,7 @@ static status_t conclude(private_ike_sa_init_t *this, message_t *response,
|
||||
}
|
||||
|
||||
this->ike_sa->set_lifetimes(this->ike_sa,
|
||||
this->connection->get_reauth(this->connection),
|
||||
this->connection->get_soft_lifetime(this->connection),
|
||||
this->connection->get_hard_lifetime(this->connection));
|
||||
|
||||
|
||||
@@ -366,6 +366,7 @@ static status_t switchto_new_sa(private_rekey_ike_sa_t* this, bool initiator)
|
||||
this->new_sa->apply_connection(this->new_sa, this->connection);
|
||||
this->new_sa->set_state(this->new_sa, IKE_ESTABLISHED);
|
||||
this->new_sa->set_lifetimes(this->new_sa,
|
||||
this->connection->get_reauth(this->connection),
|
||||
this->connection->get_soft_lifetime(this->connection),
|
||||
this->connection->get_hard_lifetime(this->connection));
|
||||
return SUCCESS;
|
||||
|
||||
Reference in New Issue
Block a user