- added deletion of IKE_SA

This commit is contained in:
Jan Hutter
2005-12-12 14:14:52 +00:00
parent 6db4e80b56
commit e9c0ca15e1
7 changed files with 267 additions and 29 deletions
+8 -4
View File
@@ -745,15 +745,19 @@ static status_t get_rsa_private_key(private_configuration_manager_t *this, ident
*/ */
static status_t get_retransmit_timeout (private_configuration_manager_t *this, u_int32_t retransmit_count, u_int32_t *timeout) static status_t get_retransmit_timeout (private_configuration_manager_t *this, u_int32_t retransmit_count, u_int32_t *timeout)
{ {
int new_timeout = this->first_retransmit_timeout, i;
if ((retransmit_count > this->max_retransmit_count) && (this->max_retransmit_count != 0)) if ((retransmit_count > this->max_retransmit_count) && (this->max_retransmit_count != 0))
{ {
return FAILED; return FAILED;
} }
/**
* TODO implement a good retransmit policy for (i = 0; i < retransmit_count; i++)
*/ {
*timeout = this->first_retransmit_timeout * (retransmit_count + 1); new_timeout *= 2;
}
*timeout = new_timeout;
return SUCCESS; return SUCCESS;
} }
+32 -14
View File
@@ -165,6 +165,27 @@ static payload_rule_t ike_auth_r_payload_rules[] = {
{CONFIGURATION,0,1,TRUE,FALSE}, {CONFIGURATION,0,1,TRUE,FALSE},
}; };
/**
* Message rule for INFORMATIONAL from initiator.
*/
static payload_rule_t informational_i_payload_rules[] = {
{NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,FALSE},
{CONFIGURATION,0,1,TRUE,FALSE},
{DELETE,0,1,TRUE,FALSE},
};
/**
* Message rule for INFORMATIONAL from responder.
*/
static payload_rule_t informational_r_payload_rules[] = {
{NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,FALSE},
{CONFIGURATION,0,1,TRUE,FALSE},
{DELETE,0,1,TRUE,FALSE},
};
/** /**
* Message rules, defines allowed payloads. * Message rules, defines allowed payloads.
*/ */
@@ -172,7 +193,9 @@ static message_rule_t message_rules[] = {
{IKE_SA_INIT,TRUE,FALSE,(sizeof(ike_sa_init_i_payload_rules)/sizeof(payload_rule_t)),ike_sa_init_i_payload_rules}, {IKE_SA_INIT,TRUE,FALSE,(sizeof(ike_sa_init_i_payload_rules)/sizeof(payload_rule_t)),ike_sa_init_i_payload_rules},
{IKE_SA_INIT,FALSE,FALSE,(sizeof(ike_sa_init_r_payload_rules)/sizeof(payload_rule_t)),ike_sa_init_r_payload_rules}, {IKE_SA_INIT,FALSE,FALSE,(sizeof(ike_sa_init_r_payload_rules)/sizeof(payload_rule_t)),ike_sa_init_r_payload_rules},
{IKE_AUTH,TRUE,TRUE,(sizeof(ike_auth_i_payload_rules)/sizeof(payload_rule_t)),ike_auth_i_payload_rules}, {IKE_AUTH,TRUE,TRUE,(sizeof(ike_auth_i_payload_rules)/sizeof(payload_rule_t)),ike_auth_i_payload_rules},
{IKE_AUTH,FALSE,TRUE,(sizeof(ike_auth_r_payload_rules)/sizeof(payload_rule_t)),ike_auth_r_payload_rules} {IKE_AUTH,FALSE,TRUE,(sizeof(ike_auth_r_payload_rules)/sizeof(payload_rule_t)),ike_auth_r_payload_rules},
{INFORMATIONAL,TRUE,TRUE,(sizeof(informational_i_payload_rules)/sizeof(payload_rule_t)),informational_i_payload_rules},
{INFORMATIONAL,FALSE,TRUE,(sizeof(informational_r_payload_rules)/sizeof(payload_rule_t)),informational_r_payload_rules}
}; };
@@ -1043,6 +1066,8 @@ static status_t encrypt_payloads (private_message_t *this,crypter_t *crypter, si
all_payloads->insert_last(all_payloads,current_payload); all_payloads->insert_last(all_payloads,current_payload);
} }
encryption_payload = encryption_payload_create();
this->logger->log(this->logger, CONTROL | LEVEL2, "Check each payloads if they have to get encrypted"); this->logger->log(this->logger, CONTROL | LEVEL2, "Check each payloads if they have to get encrypted");
while (all_payloads->get_count(all_payloads) > 0) while (all_payloads->get_count(all_payloads) > 0)
{ {
@@ -1072,10 +1097,6 @@ static status_t encrypt_payloads (private_message_t *this,crypter_t *crypter, si
if (to_encrypt) if (to_encrypt)
{ {
if (encryption_payload == NULL)
{
encryption_payload = encryption_payload_create();
}
this->logger->log(this->logger, CONTROL | LEVEL2, "Insert payload %s to encryption payload", this->logger->log(this->logger, CONTROL | LEVEL2, "Insert payload %s to encryption payload",
mapping_find(payload_type_m,current_payload->get_type(current_payload))); mapping_find(payload_type_m,current_payload->get_type(current_payload)));
@@ -1090,15 +1111,12 @@ static status_t encrypt_payloads (private_message_t *this,crypter_t *crypter, si
} }
status = SUCCESS; status = SUCCESS;
if (encryption_payload != NULL) this->logger->log(this->logger, CONTROL | LEVEL2, "Set transforms for encryption payload ");
{ encryption_payload->set_transforms(encryption_payload,crypter,signer);
this->logger->log(this->logger, CONTROL | LEVEL2, "Set transforms for encryption payload "); this->logger->log(this->logger, CONTROL | LEVEL1, "Encrypt all payloads of encrypted payload");
encryption_payload->set_transforms(encryption_payload,crypter,signer); status = encryption_payload->encrypt(encryption_payload);
this->logger->log(this->logger, CONTROL | LEVEL1, "Encrypt all payloads of encrypted payload"); this->logger->log(this->logger, CONTROL | LEVEL2, "Add encrypted payload to payload list");
status = encryption_payload->encrypt(encryption_payload); this->public.add_payload(&(this->public), (payload_t*)encryption_payload);
this->logger->log(this->logger, CONTROL | LEVEL2, "Add encrypted payload to payload list");
this->public.add_payload(&(this->public), (payload_t*)encryption_payload);
}
all_payloads->destroy(all_payloads); all_payloads->destroy(all_payloads);
+33 -1
View File
@@ -35,6 +35,7 @@
#include <encoding/payloads/sa_payload.h> #include <encoding/payloads/sa_payload.h>
#include <encoding/payloads/nonce_payload.h> #include <encoding/payloads/nonce_payload.h>
#include <encoding/payloads/ke_payload.h> #include <encoding/payloads/ke_payload.h>
#include <encoding/payloads/delete_payload.h>
#include <encoding/payloads/transform_substructure.h> #include <encoding/payloads/transform_substructure.h>
#include <encoding/payloads/transform_attribute.h> #include <encoding/payloads/transform_attribute.h>
#include <sa/states/initiator_init.h> #include <sa/states/initiator_init.h>
@@ -373,6 +374,36 @@ static status_t initialize_connection(private_ike_sa_t *this, char *name)
return status; return status;
} }
/**
* Implementation of ike_sa_t.send_delete_ike_sa_request.
*/
static void send_delete_ike_sa_request (private_ike_sa_t *this)
{
message_t *informational_request;
delete_payload_t *delete_payload;
status_t status;
if (this->current_state->get_state(this->current_state) != IKE_SA_ESTABLISHED)
{
return;
}
/* build empty INFORMATIONAL message */
this->protected.build_message(&(this->protected), INFORMATIONAL, TRUE, &informational_request);
delete_payload = delete_payload_create();
delete_payload->set_protocol_id(delete_payload,IKE);
informational_request->add_payload(informational_request,(payload_t *)delete_payload);
status = this->protected.send_request(&(this->protected), informational_request);
if (status != SUCCESS)
{
this->logger->log(this->logger, AUDIT, "Unable to send INFORMATIONAL DELETE request");
informational_request->destroy(informational_request);
}
}
/** /**
* Implementation of protected_ike_sa_t.get_id. * Implementation of protected_ike_sa_t.get_id.
*/ */
@@ -868,7 +899,7 @@ static void send_notify(private_ike_sa_t *this, exchange_type_t exchange_type, n
response->add_payload(response,(payload_t *) payload); response->add_payload(response,(payload_t *) payload);
/* generate packet */ /* generate packet */
this->logger->log(this->logger, CONTROL|LEVEL2, "Gnerate packet from message"); this->logger->log(this->logger, CONTROL|LEVEL2, "Generate packet from message");
status = response->generate(response, this->crypter_responder, this->signer_responder, &packet); status = response->generate(response, this->crypter_responder, this->signer_responder, &packet);
if (status != SUCCESS) if (status != SUCCESS)
{ {
@@ -1069,6 +1100,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->protected.public.get_id = (ike_sa_id_t*(*)(ike_sa_t*)) get_id; this->protected.public.get_id = (ike_sa_id_t*(*)(ike_sa_t*)) get_id;
this->protected.public.retransmit_request = (status_t (*) (ike_sa_t *, u_int32_t)) retransmit_request; this->protected.public.retransmit_request = (status_t (*) (ike_sa_t *, u_int32_t)) retransmit_request;
this->protected.public.get_state = (ike_sa_state_t (*) (ike_sa_t *this)) get_state; this->protected.public.get_state = (ike_sa_state_t (*) (ike_sa_t *this)) get_state;
this->protected.public.send_delete_ike_sa_request = (void (*)(ike_sa_t*)) send_delete_ike_sa_request;
this->protected.public.destroy = (void(*)(ike_sa_t*))destroy; this->protected.public.destroy = (void(*)(ike_sa_t*))destroy;
/* protected functions */ /* protected functions */
+9
View File
@@ -96,6 +96,15 @@ struct ike_sa_t {
*/ */
status_t (*retransmit_request) (ike_sa_t *this, u_int32_t message_id); status_t (*retransmit_request) (ike_sa_t *this, u_int32_t message_id);
/**
* @brief Sends a request to delete IKE_SA.
*
* Only supported in state IKE_SA_ESTABLISHED
*
* @param this calling object
*/
void (*send_delete_ike_sa_request) (ike_sa_t *this);
/** /**
* @brief Get the id of the SA. * @brief Get the id of the SA.
* *
+4 -4
View File
@@ -127,11 +127,11 @@ struct private_ike_auth_requested_t {
/** /**
* Process a notify payload * Process a notify payload
* *
* @param this calling object * @param this calling object
* @param ts_initiator TRUE if TS payload is TSi, FALSE for TSr * @param notify_payload notify payload
* @param ts_payload TS payload of responder
* *
* - SUCCESS * - SUCCESS
* - FAILED
* - DELETE_ME * - DELETE_ME
*/ */
status_t (*process_notify_payload) (private_ike_auth_requested_t *this, notify_payload_t *notify_payload); status_t (*process_notify_payload) (private_ike_auth_requested_t *this, notify_payload_t *notify_payload);
@@ -174,7 +174,7 @@ static status_t process_message(private_ike_auth_requested_t *this, message_t *i
status = ike_auth_reply->parse_body(ike_auth_reply, crypter, signer); status = ike_auth_reply->parse_body(ike_auth_reply, crypter, signer);
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, AUDIT, "IKE_AUTH reply decryption faild. Ignoring message"); this->logger->log(this->logger, AUDIT, "IKE_AUTH reply decryption failed. Ignoring message");
return status; return status;
} }
+179 -3
View File
@@ -23,6 +23,7 @@
#include "ike_sa_established.h" #include "ike_sa_established.h"
#include <utils/allocator.h> #include <utils/allocator.h>
#include <encoding/payloads/delete_payload.h>
typedef struct private_ike_sa_established_t private_ike_sa_established_t; typedef struct private_ike_sa_established_t private_ike_sa_established_t;
@@ -37,10 +38,36 @@ struct private_ike_sa_established_t {
ike_sa_established_t public; ike_sa_established_t public;
/** /**
* Assigned IKE_SA * Assigned IKE_SA.
*/ */
protected_ike_sa_t *ike_sa; protected_ike_sa_t *ike_sa;
/**
* Assigned logger. Use logger of IKE_SA.
*/
logger_t *logger;
/**
* Process received DELETE payload and build DELETE payload for INFORMATIONAL response.
*
* @param this calling object
* @param request DELETE payload received in INFORMATIONAL request
* @param response The created DELETE payload is added to this message_t object
*/
status_t (*build_delete_payload) (private_ike_sa_established_t *this, delete_payload_t *request, message_t *response);
/**
* Process a notify payload
*
* @param this calling object
* @param notify_payload notify payload
* @param response response message of type INFORMATIONAL
*
* - SUCCESS
* - FAILED
* - DELETE_ME
*/
status_t (*process_notify_payload) (private_ike_sa_established_t *this, notify_payload_t *notify_payload,message_t *response);
}; };
/** /**
@@ -48,11 +75,155 @@ struct private_ike_sa_established_t {
*/ */
static status_t process_message(private_ike_sa_established_t *this, message_t *message) static status_t process_message(private_ike_sa_established_t *this, message_t *message)
{ {
delete_payload_t *delete_request = NULL;
iterator_t *payloads;
message_t *response;
crypter_t *crypter;
signer_t *signer;
status_t status;
if (message->get_exchange_type(message) != INFORMATIONAL)
{
this->logger->log(this->logger, ERROR | LEVEL1, "Message of type %s not supported in state ike_sa_established",
mapping_find(exchange_type_m,message->get_exchange_type(message)));
return FAILED;
}
if (!message->get_request(message))
{
this->logger->log(this->logger, ERROR | LEVEL1, "INFORMATIONAL responses not handled in state ike_sa_established");
return FAILED;
}
/* get signer for verification and crypter for decryption */
signer = this->ike_sa->get_signer_responder(this->ike_sa);
crypter = this->ike_sa->get_crypter_responder(this->ike_sa);
/* parse incoming message */
status = message->parse_body(message, crypter, signer);
if (status != SUCCESS)
{
this->logger->log(this->logger, AUDIT, "INFORMATIONAL request decryption failed. Ignoring message");
return status;
}
/* build empty INFORMATIONAL message */
this->ike_sa->build_message(this->ike_sa, INFORMATIONAL, FALSE, &response);
payloads = message->get_payload_iterator(message);
while (payloads->has_next(payloads))
{
payload_t *payload;
payloads->current(payloads, (void**)&payload);
switch (payload->get_type(payload))
{
case NOTIFY:
{
notify_payload_t *notify_payload = (notify_payload_t *) payload;
/* handle the notify directly, abort if no further processing required */
status = this->process_notify_payload(this, notify_payload,response);
if (status != SUCCESS)
{
payloads->destroy(payloads);
response->destroy(response);
return status;
}
}
case DELETE:
{
delete_request = (delete_payload_t *) payload;
}
default:
{
this->logger->log(this->logger, ERROR|LEVEL1, "Ignoring Payload %s (%d)",
mapping_find(payload_type_m, payload->get_type(payload)), payload->get_type(payload));
break;
}
}
}
/* iterator can be destroyed */
payloads->destroy(payloads);
if (delete_request)
{
status = this->build_delete_payload(this, delete_request, response);
if (status == DELETE_ME)
{
status = this->ike_sa->send_response(this->ike_sa, response);
if (status != SUCCESS)
{
this->logger->log(this->logger, AUDIT, "Unable to send INFORMATIONAL reply");
response->destroy(response);
return FAILED;
}
response->destroy(response);
return status;
}
}
status = this->ike_sa->send_response(this->ike_sa, response);
/* message can now be sent (must not be destroyed) */
if (status != SUCCESS)
{
this->logger->log(this->logger, AUDIT, "Unable to send INFORMATIONAL reply");
response->destroy(response);
return FAILED;
}
return SUCCESS; return SUCCESS;
} }
/** /**
* Implements state_t.get_state * Implementation of private_ike_sa_established_t.build_sa_payload;
*/
static status_t build_delete_payload (private_ike_sa_established_t *this, delete_payload_t *request, message_t *response_message)
{
delete_payload_t *response;
if (request->get_protocol_id(request) == IKE)
{
this->logger->log(this->logger, AUDIT, "DELETE request for IKE_SA received. Create delete reply.");
response = delete_payload_create();
response->set_protocol_id(response,IKE);
response_message->add_payload(response_message,(payload_t *)response);
/* IKE_SA has to get deleted */
return DELETE_ME;
}
this->logger->log(this->logger, AUDIT, "DELETE payload for CHILD_SAs not supported and handled.");
return SUCCESS;
}
/**
* Implementation of private_ike_sa_established_t.process_notify_payload;
*/
static status_t process_notify_payload (private_ike_sa_established_t *this, notify_payload_t *notify_payload, message_t *response)
{
notify_message_type_t notify_message_type = notify_payload->get_notify_message_type(notify_payload);
this->logger->log(this->logger, CONTROL|LEVEL1, "Process notify type %s for protocol %s",
mapping_find(notify_message_type_m, notify_message_type),
mapping_find(protocol_id_m, notify_payload->get_protocol_id(notify_payload)));
switch (notify_message_type)
{
default:
{
this->logger->log(this->logger, AUDIT, "INFORMATIONAL request contained an unknown notify (%d), ignored.", notify_message_type);
}
}
return SUCCESS;
}
/**
* Implementation of state_t.get_state.
*/ */
static ike_sa_state_t get_state(private_ike_sa_established_t *this) static ike_sa_state_t get_state(private_ike_sa_established_t *this)
{ {
@@ -60,7 +231,7 @@ static ike_sa_state_t get_state(private_ike_sa_established_t *this)
} }
/** /**
* Implements state_t.get_state * Implementation of state_t.get_state
*/ */
static void destroy(private_ike_sa_established_t *this) static void destroy(private_ike_sa_established_t *this)
{ {
@@ -79,8 +250,13 @@ ike_sa_established_t *ike_sa_established_create(protected_ike_sa_t *ike_sa)
this->public.state_interface.get_state = (ike_sa_state_t (*) (state_t *)) get_state; this->public.state_interface.get_state = (ike_sa_state_t (*) (state_t *)) get_state;
this->public.state_interface.destroy = (void (*) (state_t *)) destroy; this->public.state_interface.destroy = (void (*) (state_t *)) destroy;
/* private functions */
this->process_notify_payload = process_notify_payload;
this->build_delete_payload = build_delete_payload;
/* private data */ /* private data */
this->ike_sa = ike_sa; this->ike_sa = ike_sa;
this->logger = ike_sa->get_logger(ike_sa);
return &(this->public); return &(this->public);
} }
+2 -3
View File
@@ -444,9 +444,8 @@ static void process_delete_established_ike_sa_job(private_thread_pool_t *this, d
} }
default: default:
{ {
/* this->worker_logger->log(this->worker_logger, CONTROL, "Send delete request for IKE_SA.");
* TODO Send delete notify ike_sa->send_delete_ike_sa_request(ike_sa);
*/
break; break;
} }
} }