introduced refcounting on policy and connections

aren't stored in the IKE_SA anymore, they are queried on the fly
	are immutable now, allows it to share them
policy selection based on traffic selectors, leads to valid lookup results
	rekeying queries the policy based on its traffic selectors
This commit is contained in:
Martin Willi
2006-07-20 10:09:32 +00:00
parent 92ee45a0ee
commit 8dfbe71b34
28 changed files with 1069 additions and 903 deletions
+101 -66
View File
@@ -69,11 +69,6 @@ struct private_create_child_sa_t {
*/
u_int32_t rekey_spi;
/**
* connection of IKE_SA
*/
connection_t *connection;
/**
* policy definition used
*/
@@ -151,6 +146,14 @@ static u_int32_t requested(private_create_child_sa_t *this)
return this->requested++;
}
/**
* Implementation of create_child_sa_t.set_policy.
*/
static void set_policy(private_create_child_sa_t *this, policy_t *policy)
{
this->policy = policy;
}
/**
* Implementation of create_child_sa_t.rekeys_child.
*/
@@ -168,6 +171,22 @@ static void cancel(private_create_child_sa_t *this)
this->lost = TRUE;
}
/**
* destroy a list of traffic selectors
*/
static void destroy_ts_list(linked_list_t *list)
{
if (list)
{
traffic_selector_t *ts;
while (list->remove_last(list, (void**)&ts) == SUCCESS)
{
ts->destroy(ts);
}
list->destroy(list);
}
}
/**
* Implementation of transaction_t.get_request.
*/
@@ -176,6 +195,13 @@ static status_t get_request(private_create_child_sa_t *this, message_t **result)
message_t *request;
host_t *me, *other;
/* check if we already have built a message (retransmission) */
if (this->message)
{
*result = this->message;
return SUCCESS;
}
/* check if we are not already rekeying */
if (this->rekeyed_sa)
{
@@ -195,17 +221,8 @@ static status_t get_request(private_create_child_sa_t *this, message_t **result)
this->rekeyed_sa->set_state(this->rekeyed_sa, CHILD_REKEYING);
}
/* check if we already have built a message (retransmission) */
if (this->message)
{
*result = this->message;
return SUCCESS;
}
this->connection = this->ike_sa->get_connection(this->ike_sa);
me = this->connection->get_my_host(this->connection);
other = this->connection->get_other_host(this->connection);
this->policy = this->ike_sa->get_policy(this->ike_sa);
me = this->ike_sa->get_my_host(this->ike_sa);
other = this->ike_sa->get_other_host(this->ike_sa);
/* build the request */
request = message_create();
@@ -223,9 +240,31 @@ static status_t get_request(private_create_child_sa_t *this, message_t **result)
bool use_natt;
u_int32_t reqid = 0;
/* get a policy, if we are rekeying */
if (this->rekeyed_sa)
{
linked_list_t *my_ts, *other_ts;
identification_t *my_id, *other_id;
my_ts = this->rekeyed_sa->get_my_traffic_selectors(this->rekeyed_sa);
other_ts = this->rekeyed_sa->get_other_traffic_selectors(this->rekeyed_sa);
my_id = this->ike_sa->get_my_id(this->ike_sa);
other_id = this->ike_sa->get_other_id(this->ike_sa);
this->policy = charon->policies->get_policy(charon->policies,
my_id, other_id,
my_ts, other_ts,
me, other);
reqid = this->rekeyed_sa->get_reqid(this->rekeyed_sa);
if (this->policy == NULL)
{
this->logger->log(this->logger, ERROR,
"no policy found to rekey CHILD_SA with reqid %d",
reqid);
return FAILED;
}
}
proposals = this->policy->get_proposals(this->policy);
@@ -261,8 +300,9 @@ static status_t get_request(private_create_child_sa_t *this, message_t **result)
linked_list_t *ts_list;
ts_payload_t *ts_payload;
ts_list = this->policy->get_my_traffic_selectors(this->policy);
ts_list = this->policy->get_my_traffic_selectors(this->policy, me);
ts_payload = ts_payload_create_from_traffic_selectors(TRUE, ts_list);
destroy_ts_list(ts_list);
request->add_payload(request, (payload_t*)ts_payload);
}
@@ -270,8 +310,9 @@ static status_t get_request(private_create_child_sa_t *this, message_t **result)
linked_list_t *ts_list;
ts_payload_t *ts_payload;
ts_list = this->policy->get_other_traffic_selectors(this->policy);
ts_list = this->policy->get_other_traffic_selectors(this->policy, other);
ts_payload = ts_payload_create_from_traffic_selectors(FALSE, ts_list);
destroy_ts_list(ts_list);
request->add_payload(request, (payload_t*)ts_payload);
}
@@ -438,22 +479,6 @@ static status_t install_child_sa(private_create_child_sa_t *this, bool initiator
return SUCCESS;
}
/**
* destroy a list of traffic selectors
*/
static void destroy_ts_list(linked_list_t *list)
{
if (list)
{
traffic_selector_t *ts;
while (list->remove_last(list, (void**)&ts) == SUCCESS)
{
ts->destroy(ts);
}
list->destroy(list);
}
}
/**
* Implementation of transaction_t.get_response.
*/
@@ -477,10 +502,8 @@ static status_t get_response(private_create_child_sa_t *this, message_t *request
return SUCCESS;
}
this->connection = this->ike_sa->get_connection(this->ike_sa);
me = this->connection->get_my_host(this->connection);
other = this->connection->get_other_host(this->connection);
this->policy = this->ike_sa->get_policy(this->ike_sa);
me = this->ike_sa->get_my_host(this->ike_sa);
other = this->ike_sa->get_other_host(this->ike_sa);
this->message_id = request->get_message_id(request);
/* set up response */
@@ -573,16 +596,35 @@ static status_t get_response(private_create_child_sa_t *this, message_t *request
nonce_response->set_nonce(nonce_response, this->nonce_r);
}
{ /* process traffic selectors for other */
linked_list_t *ts_received = tsi_request->get_traffic_selectors(tsi_request);
this->tsi = this->policy->select_other_traffic_selectors(this->policy, ts_received);
destroy_ts_list(ts_received);
}
{ /* process traffic selectors for us */
linked_list_t *ts_received = ts_received = tsr_request->get_traffic_selectors(tsr_request);
this->tsr = this->policy->select_my_traffic_selectors(this->policy, ts_received);
destroy_ts_list(ts_received);
{ /* get a policy and process traffic selectors */
identification_t *my_id, *other_id;
linked_list_t *my_ts, *other_ts;
my_id = this->ike_sa->get_my_id(this->ike_sa);
other_id = this->ike_sa->get_other_id(this->ike_sa);
my_ts = tsr_request->get_traffic_selectors(tsr_request);
other_ts = tsi_request->get_traffic_selectors(tsi_request);
this->policy = charon->policies->get_policy(charon->policies,
my_id, other_id,
my_ts, other_ts,
me, other);
if (this->policy)
{
this->tsr = this->policy->select_my_traffic_selectors(this->policy, my_ts, me);
this->tsi = this->policy->select_other_traffic_selectors(this->policy, other_ts, other);
}
destroy_ts_list(my_ts);
destroy_ts_list(other_ts);
if (this->policy == NULL)
{
this->logger->log(this->logger, AUDIT,
"no acceptable policy found, adding TS_UNACCEPTABLE notify");
build_notify(TS_UNACCEPTABLE, CHUNK_INITIALIZER, response, TRUE);
return FAILED;
}
}
{ /* process SA payload */
@@ -705,8 +747,8 @@ static status_t conclude(private_create_child_sa_t *this, message_t *response,
return FAILED;
}
me = this->connection->get_my_host(this->connection);
other = this->connection->get_other_host(this->connection);
me = this->ike_sa->get_my_host(this->ike_sa);
other = this->ike_sa->get_other_host(this->ike_sa);
/* Iterate over all payloads to collect them */
payloads = response->get_payload_iterator(response);
@@ -761,13 +803,13 @@ static status_t conclude(private_create_child_sa_t *this, message_t *response,
{ /* process traffic selectors for us */
linked_list_t *ts_received = tsi_payload->get_traffic_selectors(tsi_payload);
this->tsi = this->policy->select_my_traffic_selectors(this->policy, ts_received);
this->tsi = this->policy->select_my_traffic_selectors(this->policy, ts_received, me);
destroy_ts_list(ts_received);
}
{ /* process traffic selectors for other */
linked_list_t *ts_received = tsr_payload->get_traffic_selectors(tsr_payload);
this->tsr = this->policy->select_other_traffic_selectors(this->policy, ts_received);
this->tsr = this->policy->select_other_traffic_selectors(this->policy, ts_received, other);
destroy_ts_list(ts_received);
}
@@ -790,8 +832,7 @@ static status_t conclude(private_create_child_sa_t *this, message_t *response,
this->tsi->get_count(this->tsi) == 0 ||
this->tsr->get_count(this->tsr) == 0)
{
this->logger->log(this->logger, AUDIT,
"CHILD_SA creation failed");
this->logger->log(this->logger, AUDIT, "CHILD_SA creation failed");
return FAILED;
}
new_child = this->child_sa;
@@ -863,18 +904,10 @@ static status_t conclude(private_create_child_sa_t *this, message_t *response,
*/
static void destroy(private_create_child_sa_t *this)
{
if (this->message)
{
this->message->destroy(this->message);
}
if (this->proposal)
{
this->proposal->destroy(this->proposal);
}
if (this->child_sa)
{
this->child_sa->destroy(this->child_sa);
}
DESTROY_IF(this->message);
DESTROY_IF(this->proposal);
DESTROY_IF(this->child_sa);
DESTROY_IF(this->policy);
destroy_ts_list(this->tsi);
destroy_ts_list(this->tsr);
chunk_free(&this->nonce_i);
@@ -900,6 +933,7 @@ create_child_sa_t *create_child_sa_create(ike_sa_t *ike_sa)
this->public.transaction.destroy = (void(*)(transaction_t*))destroy;
/* public functions */
this->public.set_policy = (void(*)(create_child_sa_t*,policy_t*))set_policy;
this->public.rekeys_child = (void(*)(create_child_sa_t*,child_sa_t*))rekeys_child;
this->public.cancel = (void(*)(create_child_sa_t*))cancel;
@@ -916,6 +950,7 @@ create_child_sa_t *create_child_sa_create(ike_sa_t *ike_sa)
this->rekeyed_sa = NULL;
this->lost = FALSE;
this->proposal = NULL;
this->policy = NULL;
this->tsi = NULL;
this->tsr = NULL;
this->randomizer = randomizer_create();
+14 -5
View File
@@ -33,6 +33,10 @@ typedef struct create_child_sa_t create_child_sa_t;
/**
* @brief A transaction to create a new or rekey an existing CHILD_SA.
*
* If the CHILD_SA is intended to create a new CHILD_SA, set the policy
* with set_policy(). If it is intended to rekey an existing CHILD_SA,
* set the appropriate CHILD_SA with rekeys_child().
*
* Rekeying of an CHILD_SA works the same way as creating a new one,
* but includes an additional REKEY_SA notify and deletes the old
* one (in a separate transaction).
@@ -68,10 +72,15 @@ struct create_child_sa_t {
transaction_t transaction;
/**
* @brief Set the CHILD_SA which gets rekeyed by the new one.
* @brief Set the policy to use for creating a new CHILD_SA.
*
* If this transaction is used for rekeying, set the inbound
* SPI of the CHILD_SA which the new CHILD_SA rekeys.
* @param this calling object
* @param policy policy for CHILD_SA
*/
void (*set_policy) (create_child_sa_t* this, policy_t *policy);
/**
* @brief Set the CHILD_SA which gets rekeyed by the new one.
*
* @param this calling object
* @param child_sa CHILD_SA to rekey
@@ -79,9 +88,9 @@ struct create_child_sa_t {
void (*rekeys_child) (create_child_sa_t* this, child_sa_t *child_sa);
/**
* @brief Cancel a rekeying request.
* @brief Cancel the request.
*
* Cancelling a rekeying request will set a flag in the transaction. When
* Cancelling the request will set a flag in the transaction. When
* the response for the transaction is received, the created CHILD_SA
* gets deleted afterwards.
*
@@ -85,7 +85,6 @@ static u_int32_t requested(private_dead_peer_detection_t *this)
static status_t get_request(private_dead_peer_detection_t *this, message_t **result)
{
message_t *request;
connection_t *connection;
host_t *me, *other;
/* check if we already have built a message (retransmission) */
@@ -95,9 +94,8 @@ static status_t get_request(private_dead_peer_detection_t *this, message_t **res
return SUCCESS;
}
connection = this->ike_sa->get_connection(this->ike_sa);
me = connection->get_my_host(connection);
other = connection->get_other_host(connection);
me = this->ike_sa->get_my_host(this->ike_sa);
other = this->ike_sa->get_other_host(this->ike_sa);
/* build the request */
request = message_create();
@@ -124,7 +122,6 @@ static status_t get_response(private_dead_peer_detection_t *this, message_t *req
{
host_t *me, *other;
message_t *response;
connection_t *connection;
/* check if we already have built a response (retransmission) */
if (this->message)
@@ -133,9 +130,8 @@ static status_t get_response(private_dead_peer_detection_t *this, message_t *req
return SUCCESS;
}
connection = this->ike_sa->get_connection(this->ike_sa);
me = connection->get_my_host(connection);
other = connection->get_other_host(connection);
me = this->ike_sa->get_my_host(this->ike_sa);
other = this->ike_sa->get_other_host(this->ike_sa);
this->message_id = request->get_message_id(request);
/* set up response */
@@ -167,10 +163,7 @@ static status_t conclude(private_dead_peer_detection_t *this, message_t *respons
*/
static void destroy(private_dead_peer_detection_t *this)
{
if (this->message)
{
this->message->destroy(this->message);
}
DESTROY_IF(this->message);
free(this);
}
+5 -12
View File
@@ -100,7 +100,6 @@ static void set_child_sa(private_delete_child_sa_t *this, child_sa_t *child_sa)
static status_t get_request(private_delete_child_sa_t *this, message_t **result)
{
message_t *request;
connection_t *connection;
host_t *me, *other;
/* check if we already have built a message (retransmission) */
@@ -110,9 +109,8 @@ static status_t get_request(private_delete_child_sa_t *this, message_t **result)
return SUCCESS;
}
connection = this->ike_sa->get_connection(this->ike_sa);
me = connection->get_my_host(connection);
other = connection->get_other_host(connection);
me = this->ike_sa->get_my_host(this->ike_sa);
other = this->ike_sa->get_other_host(this->ike_sa);
/* build the request */
request = message_create();
@@ -228,7 +226,6 @@ static status_t get_response(private_delete_child_sa_t *this, message_t *request
host_t *me, *other;
message_t *response;
iterator_t *payloads;
connection_t *connection;
/* check if we already have built a response (retransmission) */
if (this->message)
@@ -237,9 +234,8 @@ static status_t get_response(private_delete_child_sa_t *this, message_t *request
return SUCCESS;
}
connection = this->ike_sa->get_connection(this->ike_sa);
me = connection->get_my_host(connection);
other = connection->get_other_host(connection);
me = this->ike_sa->get_my_host(this->ike_sa);
other = this->ike_sa->get_other_host(this->ike_sa);
this->message_id = request->get_message_id(request);
/* set up response */
@@ -335,10 +331,7 @@ static status_t conclude(private_delete_child_sa_t *this, message_t *response,
*/
static void destroy(private_delete_child_sa_t *this)
{
if (this->message)
{
this->message->destroy(this->message);
}
DESTROY_IF(this->message);
free(this);
}
+5 -12
View File
@@ -86,7 +86,6 @@ static u_int32_t requested(private_delete_ike_sa_t *this)
static status_t get_request(private_delete_ike_sa_t *this, message_t **result)
{
message_t *request;
connection_t *connection;
host_t *me, *other;
delete_payload_t *delete_payload;
@@ -97,9 +96,8 @@ static status_t get_request(private_delete_ike_sa_t *this, message_t **result)
return SUCCESS;
}
connection = this->ike_sa->get_connection(this->ike_sa);
me = connection->get_my_host(connection);
other = connection->get_other_host(connection);
me = this->ike_sa->get_my_host(this->ike_sa);
other = this->ike_sa->get_other_host(this->ike_sa);
/* build the request */
request = message_create();
@@ -134,7 +132,6 @@ static status_t get_response(private_delete_ike_sa_t *this, message_t *request,
message_t *response;
iterator_t *payloads;
delete_payload_t *delete_request = NULL;
connection_t *connection;
/* check if we already have built a response (retransmission)
* this only happens in special simultanous transaction cases,
@@ -145,9 +142,8 @@ static status_t get_response(private_delete_ike_sa_t *this, message_t *request,
return SUCCESS;
}
connection = this->ike_sa->get_connection(this->ike_sa);
me = connection->get_my_host(connection);
other = connection->get_other_host(connection);
me = this->ike_sa->get_my_host(this->ike_sa);
other = this->ike_sa->get_other_host(this->ike_sa);
this->message_id = request->get_message_id(request);
/* set up response */
@@ -240,10 +236,7 @@ static status_t conclude(private_delete_ike_sa_t *this, message_t *response,
*/
static void destroy(private_delete_ike_sa_t *this)
{
if (this->message)
{
this->message->destroy(this->message);
}
DESTROY_IF(this->message);
free(this);
}
+84 -72
View File
@@ -90,12 +90,12 @@ struct private_ike_auth_t {
chunk_t init_response;
/**
* connection definition used
* connection definition used for IKE_SA setup
*/
connection_t *connection;
/**
* policy definition used
* policy definition used CHILD_SA creation
*/
policy_t *policy;
@@ -146,6 +146,16 @@ static u_int32_t requested(private_ike_auth_t *this)
return this->requested++;
}
/**
* Implementation of transaction_t.set_config.
*/
static void set_config(private_ike_auth_t *this,
connection_t *connection, policy_t *policy)
{
this->connection = connection;
this->policy = policy;
}
/**
* Implementation of transaction_t.set_nonces.
*/
@@ -164,6 +174,23 @@ static void set_init_messages(private_ike_auth_t *this, chunk_t init_request, ch
this->init_response = init_response;
}
/**
* destroy a list of traffic selectors
*/
static void destroy_ts_list(linked_list_t *list)
{
if (list)
{
traffic_selector_t *ts;
while (list->remove_last(list, (void**)&ts) == SUCCESS)
{
ts->destroy(ts);
}
list->destroy(list);
}
}
/**
* Implementation of transaction_t.get_request.
*/
@@ -181,10 +208,8 @@ static status_t get_request(private_ike_auth_t *this, message_t **result)
return SUCCESS;
}
this->connection = this->ike_sa->get_connection(this->ike_sa);
me = this->connection->get_my_host(this->connection);
other = this->connection->get_other_host(this->connection);
this->policy = this->ike_sa->get_policy(this->ike_sa);
me = this->ike_sa->get_my_host(this->ike_sa);
other = this->ike_sa->get_other_host(this->ike_sa);
my_id = this->policy->get_my_id(this->policy);
other_id = this->policy->get_other_id(this->policy);
@@ -203,6 +228,7 @@ static status_t get_request(private_ike_auth_t *this, message_t **result)
{ /* build ID payload */
my_id_payload = id_payload_create_from_identification(TRUE, my_id);
request->add_payload(request, (payload_t*)my_id_payload);
this->ike_sa->set_my_id(this->ike_sa, my_id->clone(my_id));
}
{ /* TODO: build certreq payload */
@@ -239,9 +265,11 @@ static status_t get_request(private_ike_auth_t *this, message_t **result)
{ /* build auth payload */
authenticator_t *authenticator;
auth_payload_t *auth_payload;
auth_method_t auth_method;
status_t status;
authenticator = authenticator_create(this->ike_sa);
auth_method = this->connection->get_auth_method(this->connection);
authenticator = authenticator_create(this->ike_sa, auth_method);
status = authenticator->compute_auth_data(authenticator, &auth_payload,
this->init_request, this->nonce_r, my_id_payload, TRUE);
authenticator->destroy(authenticator);
@@ -278,8 +306,9 @@ static status_t get_request(private_ike_auth_t *this, message_t **result)
linked_list_t *ts_list;
ts_payload_t *ts_payload;
ts_list = this->policy->get_my_traffic_selectors(this->policy);
ts_list = this->policy->get_my_traffic_selectors(this->policy, me);
ts_payload = ts_payload_create_from_traffic_selectors(TRUE, ts_list);
destroy_ts_list(ts_list);
request->add_payload(request, (payload_t*)ts_payload);
}
@@ -288,8 +317,9 @@ static status_t get_request(private_ike_auth_t *this, message_t **result)
linked_list_t *ts_list;
ts_payload_t *ts_payload;
ts_list = this->policy->get_other_traffic_selectors(this->policy);
ts_list = this->policy->get_other_traffic_selectors(this->policy, other);
ts_payload = ts_payload_create_from_traffic_selectors(FALSE, ts_list);
destroy_ts_list(ts_list);
request->add_payload(request, (payload_t*)ts_payload);
}
@@ -464,23 +494,6 @@ static status_t install_child_sa(private_ike_auth_t *this, bool initiator)
return SUCCESS;
}
/**
* destroy a list of traffic selectors
*/
static void destroy_ts_list(linked_list_t *list)
{
if (list)
{
traffic_selector_t *ts;
while (list->remove_last(list, (void**)&ts) == SUCCESS)
{
ts->destroy(ts);
}
list->destroy(list);
}
}
/**
* Implementation of transaction_t.get_response.
*/
@@ -508,9 +521,8 @@ static status_t get_response(private_ike_auth_t *this, message_t *request,
return SUCCESS;
}
this->connection = this->ike_sa->get_connection(this->ike_sa);
me = this->connection->get_my_host(this->connection);
other = this->connection->get_other_host(this->connection);
me = this->ike_sa->get_my_host(this->ike_sa);
other = this->ike_sa->get_other_host(this->ike_sa);
this->message_id = request->get_message_id(request);
/* set up response */
@@ -607,13 +619,32 @@ static status_t get_response(private_ike_auth_t *this, message_t *request,
{
my_id = identification_create_from_encoding(ID_ANY, CHUNK_INITIALIZER);
}
}
{ /* get a policy and process traffic selectors */
linked_list_t *my_ts, *other_ts;
/* get policy from store */
this->policy = charon->policies->get_policy_by_ids(charon->policies, my_id, other_id);
my_ts = tsr_request->get_traffic_selectors(tsr_request);
other_ts = tsi_request->get_traffic_selectors(tsi_request);
this->policy = charon->policies->get_policy(charon->policies,
my_id, other_id,
my_ts, other_ts,
me, other);
if (this->policy)
{
this->tsr = this->policy->select_my_traffic_selectors(this->policy, my_ts, me);
this->tsi = this->policy->select_other_traffic_selectors(this->policy, other_ts, other);
}
destroy_ts_list(my_ts);
destroy_ts_list(other_ts);
/* TODO: We should check somehow if we have a policy, but with other
* traffic selectors. Then we would create a IKE_SA without a CHILD_SA. */
if (this->policy == NULL)
{
this->logger->log(this->logger, AUDIT,
"we don't have a policy for IDs %s - %s, deleting IKE_SA",
"no acceptable policy for IDs %s - %s found, deleting IKE_SA",
my_id->get_string(my_id), other_id->get_string(other_id));
my_id->destroy(my_id);
other_id->destroy(other_id);
@@ -621,16 +652,12 @@ static status_t get_response(private_ike_auth_t *this, message_t *request,
return DESTROY_ME;
}
my_id->destroy(my_id);
other_id->destroy(other_id);
/* get my id from policy, which must contain a fully qualified valid id */
my_id = this->policy->get_my_id(this->policy);
this->ike_sa->set_my_id(this->ike_sa, my_id->clone(my_id));
this->ike_sa->set_other_id(this->ike_sa, other_id);
/* update others traffic selectors with actually used address */
this->policy->update_my_ts(this->policy, me);
this->policy->update_other_ts(this->policy, other);
this->ike_sa->set_policy(this->ike_sa, this->policy);
idr_response = id_payload_create_from_identification(FALSE, my_id);
response->add_payload(response, (payload_t*)idr_response);
}
@@ -658,9 +685,11 @@ static status_t get_response(private_ike_auth_t *this, message_t *request,
{ /* process auth payload */
authenticator_t *authenticator;
auth_payload_t *auth_response;
auth_method_t auth_method;
status_t status;
authenticator = authenticator_create(this->ike_sa);
auth_method = this->connection->get_auth_method(this->connection);
authenticator = authenticator_create(this->ike_sa, auth_method);
status = authenticator->verify_auth_data(authenticator, auth_request,
this->init_request,
this->nonce_r, idi_request,
@@ -688,18 +717,6 @@ static status_t get_response(private_ike_auth_t *this, message_t *request,
response->add_payload(response, (payload_t*)auth_response);
}
{ /* process traffic selectors for other */
linked_list_t *ts_received = tsi_request->get_traffic_selectors(tsi_request);
this->tsi = this->policy->select_other_traffic_selectors(this->policy, ts_received);
destroy_ts_list(ts_received);
}
{ /* process traffic selectors for us */
linked_list_t *ts_received = ts_received = tsr_request->get_traffic_selectors(tsr_request);
this->tsr = this->policy->select_my_traffic_selectors(this->policy, ts_received);
destroy_ts_list(ts_received);
}
{ /* process SA payload */
proposal_t *proposal;
linked_list_t *proposal_list;
@@ -793,8 +810,8 @@ static status_t conclude(private_ike_auth_t *this, message_t *response,
return DESTROY_ME;
}
me = this->connection->get_my_host(this->connection);
other = this->connection->get_other_host(this->connection);
me = this->ike_sa->get_my_host(this->ike_sa);
other = this->ike_sa->get_other_host(this->ike_sa);
/* Iterate over all payloads to collect them */
payloads = response->get_payload_iterator(response);
@@ -872,8 +889,7 @@ static status_t conclude(private_ike_auth_t *this, message_t *response,
configured_other_id->get_string(configured_other_id));
return DESTROY_ME;
}
this->policy->update_other_id(this->policy, other_id);
this->ike_sa->set_other_id(this->ike_sa, other_id);
}
if (cert_payload)
@@ -883,9 +899,11 @@ static status_t conclude(private_ike_auth_t *this, message_t *response,
{ /* authenticate peer */
authenticator_t *authenticator;
auth_method_t auth_method;
status_t status;
authenticator = authenticator_create(this->ike_sa);
auth_method = this->connection->get_auth_method(this->connection);
authenticator = authenticator_create(this->ike_sa, auth_method);
status = authenticator->verify_auth_data(authenticator, auth_payload,
this->init_response,
this->nonce_i, idr_payload,
@@ -900,13 +918,13 @@ static status_t conclude(private_ike_auth_t *this, message_t *response,
{ /* process traffic selectors for us */
linked_list_t *ts_received = tsi_payload->get_traffic_selectors(tsi_payload);
this->tsi = this->policy->select_my_traffic_selectors(this->policy, ts_received);
this->tsi = this->policy->select_my_traffic_selectors(this->policy, ts_received, me);
destroy_ts_list(ts_received);
}
{ /* process traffic selectors for other */
linked_list_t *ts_received = tsr_payload->get_traffic_selectors(tsr_payload);
this->tsr = this->policy->select_other_traffic_selectors(this->policy, ts_received);
this->tsr = this->policy->select_other_traffic_selectors(this->policy, ts_received, other);
destroy_ts_list(ts_received);
}
@@ -952,18 +970,11 @@ static status_t conclude(private_ike_auth_t *this, message_t *response,
*/
static void destroy(private_ike_auth_t *this)
{
if (this->message)
{
this->message->destroy(this->message);
}
if (this->proposal)
{
this->proposal->destroy(this->proposal);
}
if (this->child_sa)
{
this->child_sa->destroy(this->child_sa);
}
DESTROY_IF(this->message);
DESTROY_IF(this->proposal);
DESTROY_IF(this->child_sa);
DESTROY_IF(this->policy);
DESTROY_IF(this->connection);
destroy_ts_list(this->tsi);
destroy_ts_list(this->tsr);
chunk_free(&this->nonce_i);
@@ -989,6 +1000,7 @@ ike_auth_t *ike_auth_create(ike_sa_t *ike_sa)
this->public.transaction.destroy = (void(*)(transaction_t*))destroy;
/* public functions */
this->public.set_config = (void(*)(ike_auth_t*,connection_t*,policy_t*))set_config;
this->public.set_nonces = (void(*)(ike_auth_t*,chunk_t,chunk_t))set_nonces;
this->public.set_init_messages = (void(*)(ike_auth_t*,chunk_t,chunk_t))set_init_messages;
+14
View File
@@ -49,6 +49,20 @@ struct ike_auth_t {
*/
transaction_t transaction;
/**
* @brief Set the config used for the ike_auth exchange.
*
* The connection definition is used to complete IKE_SA setup, the
* policy defines the CHILD_SA which is created along with the ike_auth
* exchange.
*
* @param this calling object
* @param connection connection definition
* @param policy policy definition
*/
void (*set_config) (ike_auth_t* this,
connection_t *connection, policy_t *policy);
/**
* @brief Set the nonces used in the previous ike_sa_init transaction.
*
+35 -23
View File
@@ -90,10 +90,15 @@ struct private_ike_sa_init_t {
chunk_t nonce_r;
/**
* connection definition used
* connection definition used for initiation
*/
connection_t *connection;
/**
* policy definition forwarded to ike_auth transaction
*/
policy_t *policy;
/**
* Negotiated proposal used for IKE_SA
*/
@@ -150,8 +155,6 @@ struct private_ike_sa_init_t {
*/
static bool use_dh_group(private_ike_sa_init_t *this, diffie_hellman_group_t dh_group)
{
this->connection = this->ike_sa->get_connection(this->ike_sa);
if (this->connection->check_dh_group(this->connection, dh_group))
{
this->diffie_hellman = diffie_hellman_create(dh_group);
@@ -163,6 +166,16 @@ static bool use_dh_group(private_ike_sa_init_t *this, diffie_hellman_group_t dh_
return FALSE;
}
/**
* Implementation of ike_sa_init_t.set_config.
*/
static void set_config(private_ike_sa_init_t *this,
connection_t *connection, policy_t *policy)
{
this->connection = connection;
this->policy = policy;
}
/**
* Implementation of transaction_t.get_message_id.
*/
@@ -264,7 +277,6 @@ static status_t get_request(private_ike_sa_init_t *this, message_t **result)
return SUCCESS;
}
this->connection = this->ike_sa->get_connection(this->ike_sa);
me = this->connection->get_my_host(this->connection);
other = this->connection->get_other_host(this->connection);
@@ -398,6 +410,9 @@ static status_t process_notifys(private_ike_sa_init_t *this, notify_payload_t *n
return DESTROY_ME;
}
retry = ike_sa_init_create(this->ike_sa);
retry->set_config(retry, this->connection, this->policy);
this->connection = NULL;
this->policy = NULL;
retry->use_dh_group(retry, dh_group);
*this->next = (transaction_t*)retry;
return FAILED;
@@ -523,7 +538,8 @@ static status_t get_response(private_ike_sa_init_t *this,
me->get_string(me), other->get_string(other));
return DESTROY_ME;
}
this->ike_sa->set_connection(this->ike_sa, this->connection);
this->ike_sa->set_name(this->ike_sa,
this->connection->get_name(this->connection));
/* Precompute NAT-D hashes for incoming NAT notify comparison */
ike_sa_id = request->get_ike_sa_id(request);
@@ -769,6 +785,9 @@ static status_t get_response(private_ike_sa_init_t *this,
/* create next transaction, for which we except a message */
ike_auth = ike_auth_create(this->ike_sa);
ike_auth->set_config(ike_auth, this->connection, this->policy);
this->connection = NULL;
this->policy = NULL;
ike_auth->set_nonces(ike_auth,
chunk_clone(this->nonce_i),
chunk_clone(this->nonce_r));
@@ -802,7 +821,6 @@ static status_t conclude(private_ike_sa_init_t *this, message_t *response,
sa_payload_t *sa_payload = NULL;
ke_payload_t *ke_payload = NULL;
nonce_payload_t *nonce_payload = NULL;
policy_t *policy;
status_t status;
/* check message type */
@@ -816,7 +834,6 @@ static status_t conclude(private_ike_sa_init_t *this, message_t *response,
/* allow setting of next transaction in other functions */
this->next = next;
this->connection = this->ike_sa->get_connection(this->ike_sa);
me = this->connection->get_my_host(this->connection);
other = this->connection->get_other_host(this->connection);
@@ -971,9 +988,6 @@ static status_t conclude(private_ike_sa_init_t *this, message_t *response,
other->set_port(other, IKEV2_NATT_PORT);
this->logger->log(this->logger, CONTROL|LEVEL1, "switching to port %d", IKEV2_NATT_PORT);
}
policy = this->ike_sa->get_policy(this->ike_sa);
policy->update_my_ts(policy, me);
policy->update_other_ts(policy, other);
}
/* because we are original initiator we have to update the responder SPI to the new one */
@@ -1000,6 +1014,9 @@ static status_t conclude(private_ike_sa_init_t *this, message_t *response,
/* create next transaction, for which we except a message */
ike_auth = ike_auth_create(this->ike_sa);
ike_auth->set_config(ike_auth, this->connection, this->policy);
this->connection = NULL;
this->policy = NULL;
ike_auth->set_nonces(ike_auth,
chunk_clone(this->nonce_i),
chunk_clone(this->nonce_r));
@@ -1012,18 +1029,11 @@ static status_t conclude(private_ike_sa_init_t *this, message_t *response,
static void destroy(private_ike_sa_init_t *this)
{
if (this->message)
{
this->message->destroy(this->message);
}
if (this->diffie_hellman)
{
this->diffie_hellman->destroy(this->diffie_hellman);
}
if (this->proposal)
{
this->proposal->destroy(this->proposal);
}
DESTROY_IF(this->message);
DESTROY_IF(this->diffie_hellman);
DESTROY_IF(this->proposal);
DESTROY_IF(this->connection);
DESTROY_IF(this->policy);
chunk_free(&this->nonce_i);
chunk_free(&this->nonce_r);
this->randomizer->destroy(this->randomizer);
@@ -1049,6 +1059,7 @@ ike_sa_init_t *ike_sa_init_create(ike_sa_t *ike_sa)
this->public.transaction.destroy = (void(*)(transaction_t*))destroy;
/* public functions */
this->public.set_config = (void(*)(ike_sa_init_t*,connection_t*,policy_t*))set_config;
this->public.use_dh_group = (bool(*)(ike_sa_init_t*,diffie_hellman_group_t))use_dh_group;
/* private data */
@@ -1060,6 +1071,7 @@ ike_sa_init_t *ike_sa_init_create(ike_sa_t *ike_sa)
this->nonce_i = CHUNK_INITIALIZER;
this->nonce_r = CHUNK_INITIALIZER;
this->connection = NULL;
this->policy = NULL;
this->proposal = NULL;
this->randomizer = randomizer_create();
this->nat_hasher = hasher_create(HASH_SHA1);
@@ -1070,6 +1082,6 @@ ike_sa_init_t *ike_sa_init_create(ike_sa_t *ike_sa)
this->natd_src_matched = FALSE;
this->natd_dst_matched = FALSE;
this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
return &this->public;
}
+13
View File
@@ -46,6 +46,19 @@ struct ike_sa_init_t {
*/
transaction_t transaction;
/**
* @brief Set connection & policy to use for initiation.
*
* The policy is not used directly, but forwarded to the
* ike_auth transaction.
*
* @param this calling object
* @param connection connection to use for initiation
* @param policy policy used in ike_auth transaction
*/
void (*set_config) (ike_sa_init_t* this,
connection_t *connection, policy_t *policy);
/**
* @brief Set the Diffie Hellman group to use for initiating.
*