From 7b3d13891920cd935a876019f3220cc598fb4486 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Fri, 18 Nov 2005 13:59:21 +0000 Subject: [PATCH] - changed ike_sa_id interface - definition of private ike_sa methods --- Source/charon/ike_sa.c | 68 ++++++++++++++--------------- Source/charon/ike_sa_id.c | 51 ++++++++++++---------- Source/charon/ike_sa_id.h | 31 +++++++------ Source/charon/ike_sa_manager.c | 5 ++- Source/charon/message.c | 25 ++++++++--- Source/charon/payloads/ike_header.c | 14 +++++- Source/charon/thread_pool.c | 17 ++++---- 7 files changed, 123 insertions(+), 88 deletions(-) diff --git a/Source/charon/ike_sa.c b/Source/charon/ike_sa.c index 329c3e829..1d83c6edf 100644 --- a/Source/charon/ike_sa.c +++ b/Source/charon/ike_sa.c @@ -100,10 +100,13 @@ struct private_ike_sa_s { ike_sa_t public; status_t (*build_sa_payload) (private_ike_sa_t *this, sa_payload_t **payload); + status_t (*build_ke_payload) (private_ike_sa_t *this, ke_payload_t **payload); status_t (*build_nonce_payload) (private_ike_sa_t *this, nonce_payload_t **payload); - status_t (*build_message) (private_ike_sa_t *this, exchange_type_t type, bool request); + status_t (*build_message) (private_ike_sa_t *this, exchange_type_t type, bool request, message_t **message); + + status_t (*transto_ike_sa_init_requested) (private_ike_sa_t *this, char *name); status_t (*transto_ike_sa_init_responded) (private_ike_sa_t *this, message_t *message); status_t (*transto_ike_auth_requested) (private_ike_sa_t *this, message_t *message); @@ -123,11 +126,6 @@ struct private_ike_sa_s { */ ike_sa_state_t state; - /** - * is this IKE_SA the original initiator of this IKE_SA - */ - bool original_initiator; - /** * this SA's source for random data */ @@ -232,14 +230,14 @@ static status_t process_message (private_ike_sa_t *this, message_t *message) } -static status_t build_message(private_ike_sa_t *this, exchange_type_t type, bool request) +static status_t build_message(private_ike_sa_t *this, exchange_type_t type, bool request, message_t **message) { status_t status; - message_t *message; + message_t *new_message; host_t *source, *destination; - message = message_create(); - if (message == NULL) + new_message = message_create(); + if (new_message == NULL) { return OUT_OF_RES; } @@ -248,20 +246,28 @@ static status_t build_message(private_ike_sa_t *this, exchange_type_t type, bool status |= this->other.host->clone(this->other.host, &destination); if (status != SUCCESS) { - message->destroy(message); + new_message->destroy(new_message); return status; } - message->set_source(message, source); - message->set_destination(message, destination); + new_message->set_source(new_message, source); + new_message->set_destination(new_message, destination); - message->set_exchange_type(message, type); - message->set_request(message, request); + new_message->set_exchange_type(new_message, type); + new_message->set_request(new_message, request); - message->set_ike_sa_id(message, this->ike_sa_id); + new_message->set_ike_sa_id(new_message, this->ike_sa_id); + + *message = new_message; return SUCCESS; } + +static status_t transto_ike_sa_init_requested(private_ike_sa_t *this, char *name) +{ + +} + static status_t transto_ike_sa_init_responded(private_ike_sa_t *this, message_t *message) { status_t status; @@ -360,9 +366,7 @@ static status_t initialize_connection(private_ike_sa_t *this, char *name) status_t status; this->logger->log(this->logger, CONTROL, "initializing connection"); - - this->original_initiator = TRUE; - + status = global_configuration_manager->get_local_host(global_configuration_manager, name, &(this->me.host)); if (status != SUCCESS) { @@ -381,22 +385,12 @@ static status_t initialize_connection(private_ike_sa_t *this, char *name) return INVALID_ARG; } - message = message_create(); - - if (message == NULL) - { - return OUT_OF_RES; + status = this->build_message(this, IKE_SA_INIT, TRUE, &message); + if (status != SUCCESS) + { + return status; } - - message->set_source(message, this->me.host); - message->set_destination(message, this->other.host); - - message->set_exchange_type(message, IKE_SA_INIT); - message->set_original_initiator(message, this->original_initiator); - message->set_message_id(message, this->message_id_out++); - message->set_ike_sa_id(message, this->ike_sa_id); - message->set_request(message, TRUE); status = this->build_sa_payload(this, (sa_payload_t**)&payload); if (status != SUCCESS) @@ -405,7 +399,6 @@ static status_t initialize_connection(private_ike_sa_t *this, char *name) message->destroy(message); return status; } - payload->set_next_type(payload, KEY_EXCHANGE); message->add_payload(message, payload); { @@ -459,7 +452,6 @@ static status_t initialize_connection(private_ike_sa_t *this, char *name) payload = (payload_t *) ke_payload; } - payload->set_next_type(payload, NONCE); message->add_payload(message, payload); status = this->build_nonce_payload(this, (nonce_payload_t**)&payload); @@ -532,6 +524,10 @@ static status_t build_sa_payload(private_ike_sa_t *this, sa_payload_t **payload) return SUCCESS; } +static status_t build_ke_payload(private_ike_sa_t *this, ke_payload_t **payload) +{ + +} /** * implements private_ike_sa_t.build_nonce_payload @@ -613,8 +609,10 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id) this->build_sa_payload = build_sa_payload; this->build_nonce_payload = build_nonce_payload; + this->build_ke_payload = build_ke_payload; this->build_message = build_message; + this->transto_ike_sa_init_requested = transto_ike_sa_init_requested; this->transto_ike_sa_init_responded = transto_ike_sa_init_responded; this->transto_ike_auth_requested = transto_ike_auth_requested; diff --git a/Source/charon/ike_sa_id.c b/Source/charon/ike_sa_id.c index c822d2bf5..1453daeec 100644 --- a/Source/charon/ike_sa_id.c +++ b/Source/charon/ike_sa_id.c @@ -55,7 +55,7 @@ struct private_ike_sa_id_s { /** * Role for specific IKE_SA */ - bool is_initiator; + bool is_initiator_flag; }; @@ -76,19 +76,19 @@ static status_t set_initiator_spi(private_ike_sa_id_t *this, u_int64_t initiator } /** - * @brief implements function initiator_spi_is_set of ike_sa_id_t + * @brief implements ike_sa_id_t.get_initiator_spi */ -static bool initiator_spi_is_set (private_ike_sa_id_t *this) +static u_int64_t get_initiator_spi (private_ike_sa_id_t *this) { - return (this->initiator_spi != 0); + return this->initiator_spi; } /** - * @brief implements function responder_spi_is_set of ike_sa_id_t + * @brief implements ike_sa_id_t.get_responder_spi */ -static bool responder_spi_is_set (private_ike_sa_id_t *this) +static u_int64_t get_responder_spi (private_ike_sa_id_t *this) { - return (this->responder_spi != 0); + return this->responder_spi; } /** @@ -100,7 +100,7 @@ static status_t equals (private_ike_sa_id_t *this,private_ike_sa_id_t *other, bo { return FAILED; } - if ((this->is_initiator == other->is_initiator) && + if ((this->is_initiator_flag == other->is_initiator_flag) && (this->initiator_spi == other->initiator_spi) && (this->responder_spi == other->responder_spi)) @@ -129,22 +129,26 @@ status_t replace_values (private_ike_sa_id_t *this, private_ike_sa_id_t *other) this->initiator_spi = other->initiator_spi; this->responder_spi = other->responder_spi; - this->is_initiator = other->is_initiator; + this->is_initiator_flag = other->is_initiator_flag; return SUCCESS; } + /** - * @brief implements function ike_sa_id_t.get_values + * @brief implements ike_sa_id_t.is_initiator */ -static status_t get_values(private_ike_sa_id_t *this, u_int64_t *initiator, u_int64_t *responder, bool *is_initiator) +static bool is_initiator(private_ike_sa_id_t *this) { - memcpy(initiator, &(this->initiator_spi), sizeof(this->initiator_spi)); - memcpy(responder, &(this->responder_spi), sizeof(this->responder_spi)); + return this->is_initiator_flag; +} - *is_initiator = this->is_initiator; - - return SUCCESS; +/** + * @brief implements ike_sa_id_t.switch_initiator + */ +static bool switch_initiator(private_ike_sa_id_t *this) +{ + return (this->is_initiator_flag = !this->is_initiator_flag); } @@ -153,7 +157,7 @@ static status_t get_values(private_ike_sa_id_t *this, u_int64_t *initiator, u_in */ static status_t clone (private_ike_sa_id_t *this, ike_sa_id_t **clone_of_this) { - *clone_of_this = ike_sa_id_create(this->initiator_spi, this->responder_spi, this->is_initiator); + *clone_of_this = ike_sa_id_create(this->initiator_spi, this->responder_spi, this->is_initiator_flag); return (*clone_of_this == NULL) ? OUT_OF_RES : SUCCESS; } @@ -170,7 +174,7 @@ static status_t destroy (private_ike_sa_id_t *this) /* * Described in Header-File */ -ike_sa_id_t * ike_sa_id_create(u_int64_t initiator_spi, u_int64_t responder_spi, bool is_initiator) +ike_sa_id_t * ike_sa_id_create(u_int64_t initiator_spi, u_int64_t responder_spi, bool is_initiator_flag) { private_ike_sa_id_t *this = allocator_alloc_thing(private_ike_sa_id_t); if (this == NULL) @@ -181,18 +185,21 @@ ike_sa_id_t * ike_sa_id_create(u_int64_t initiator_spi, u_int64_t responder_spi, /* Public functions */ this->public.set_responder_spi = (status_t(*)(ike_sa_id_t*,u_int64_t)) set_responder_spi; this->public.set_initiator_spi = (status_t(*)(ike_sa_id_t*,u_int64_t)) set_initiator_spi; - this->public.responder_spi_is_set = (bool(*)(ike_sa_id_t*)) responder_spi_is_set; - this->public.initiator_spi_is_set = (bool(*)(ike_sa_id_t*)) initiator_spi_is_set; + this->public.get_responder_spi = (u_int64_t(*)(ike_sa_id_t*)) get_responder_spi; + this->public.get_initiator_spi = (u_int64_t(*)(ike_sa_id_t*)) get_initiator_spi; this->public.equals = (status_t(*)(ike_sa_id_t*,ike_sa_id_t*,bool*)) equals; this->public.replace_values = (status_t(*)(ike_sa_id_t*,ike_sa_id_t*)) replace_values; - this->public.get_values = (status_t(*)(ike_sa_id_t*,u_int64_t*,u_int64_t*,bool*)) get_values; + + this->public.is_initiator = (bool(*)(ike_sa_id_t*)) is_initiator; + this->public.switch_initiator = (bool(*)(ike_sa_id_t*)) switch_initiator; + this->public.clone = (status_t(*)(ike_sa_id_t*,ike_sa_id_t**)) clone; this->public.destroy = (status_t(*)(ike_sa_id_t*))destroy; /* private data */ this->initiator_spi = initiator_spi; this->responder_spi = responder_spi; - this->is_initiator = is_initiator; + this->is_initiator_flag = is_initiator_flag; return (&this->public); } diff --git a/Source/charon/ike_sa_id.h b/Source/charon/ike_sa_id.h index 9c3ef4e90..f7e0e6540 100644 --- a/Source/charon/ike_sa_id.h +++ b/Source/charon/ike_sa_id.h @@ -59,20 +59,20 @@ struct ike_sa_id_s { status_t (*set_initiator_spi) (ike_sa_id_t *this, u_int64_t initiator_spi); /** - * @brief Returns TRUE if the initiator spi is set (not zero) + * @brief Returns the initiator spi * * @param this ike_sa_id_t object - * @return TRUE if the initiator spi is set, FALSE otherwise + * @return spi of the initiator */ - bool (*initiator_spi_is_set) (ike_sa_id_t *this); + u_int64_t (*get_initiator_spi) (ike_sa_id_t *this); /** - * @brief Returns TRUE if the responder spi is set (not zero) + * @brief Returns the responder spi * * @param this ike_sa_id_t object - * @return TRUE if the responder spi is set, FALSE otherwise + * @return spi of the responder */ - bool (*responder_spi_is_set) (ike_sa_id_t *this); + u_int64_t (*get_responder_spi) (ike_sa_id_t *this); /** * @brief Check if two ike_sa_ids are equal @@ -92,18 +92,23 @@ struct ike_sa_id_s { * @param other ike_sa_id_t object which values will be taken * @return SUCCESSFUL if succeeded, FAILED otherwise */ - status_t (*replace_values) (ike_sa_id_t *this,ike_sa_id_t *other); + status_t (*replace_values) (ike_sa_id_t *this, ike_sa_id_t *other); /** - * @brief get spis and role of an ike_sa_id + * @brief gets the initiator flag * * @param this ike_sa_id_t object - * @param initiator address to write initator spi - * @param responder address to write responder spi - * @param is_initiator address to write role - * @return SUCCESSFUL if succeeded, FAILED otherwise + * @return TRUE if we are the original initator */ - status_t (*get_values) (ike_sa_id_t *this, u_int64_t *initiator, u_int64_t *responder,bool *is_initiator); + bool (*is_initiator) (ike_sa_id_t *this); + + /** + * @brief switches the initiator flag + * + * @param this ike_sa_id_t object + * @return TRUE if we are the original initator after switch + */ + bool (*switch_initiator) (ike_sa_id_t *this); /** * @brief Clones a given ike_sa_id_t object diff --git a/Source/charon/ike_sa_manager.c b/Source/charon/ike_sa_manager.c index 58d4f8709..3cbd07225 100644 --- a/Source/charon/ike_sa_manager.c +++ b/Source/charon/ike_sa_manager.c @@ -316,8 +316,8 @@ static status_t checkout(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id, pthread_mutex_lock(&(this->mutex)); - responder_spi_set = ike_sa_id->responder_spi_is_set(ike_sa_id); - initiator_spi_set = ike_sa_id->initiator_spi_is_set(ike_sa_id); + responder_spi_set = (FALSE != ike_sa_id->get_responder_spi(ike_sa_id)); + initiator_spi_set = (FALSE != ike_sa_id->get_initiator_spi(ike_sa_id)); if (initiator_spi_set && responder_spi_set) { @@ -385,6 +385,7 @@ static status_t checkout(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id, */ u_int64_t responder_spi; ike_sa_entry_t *new_ike_sa_entry; + /* set SPIs, we are the responder */ retval = this->get_next_spi(this, &responder_spi); diff --git a/Source/charon/message.c b/Source/charon/message.c index 07e85a20c..c0618c800 100644 --- a/Source/charon/message.c +++ b/Source/charon/message.c @@ -368,10 +368,25 @@ static exchange_type_t get_request (private_message_t *this) static status_t add_payload(private_message_t *this, payload_t *payload) { + payload_t *last_payload; + if (this->payloads->get_last(this->payloads,(void **) &last_payload) != SUCCESS) + { + return OUT_OF_RES; + } + if (this->payloads->insert_last(this->payloads, payload) != SUCCESS) { return OUT_OF_RES; } + if (this->payloads->get_count(this->payloads) == 1) + { + this->first_payload = payload->get_type(payload); + } + else + { + last_payload->set_next_type(last_payload,payload->get_type(payload)); + } + return SUCCESS; } @@ -424,8 +439,6 @@ static status_t generate(private_message_t *this, packet_t **packet) ike_header_t *ike_header; payload_t *payload, *next_payload; linked_list_iterator_t *iterator; - u_int64_t initiator_spi, responder_spi; - bool is_initiator; status_t status; if (this->exchange_type == EXCHANGE_TYPE_UNDEFINED) @@ -445,15 +458,13 @@ static status_t generate(private_message_t *this, packet_t **packet) return OUT_OF_RES; } - this->ike_sa_id->get_values(this->ike_sa_id, &initiator_spi, &responder_spi, &is_initiator); ike_header->set_exchange_type(ike_header, this->exchange_type); - ike_header->set_initiator_flag(ike_header, is_initiator); ike_header->set_message_id(ike_header, this->message_id); ike_header->set_response_flag(ike_header, !this->is_request); - ike_header->set_initiator_flag(ike_header, is_initiator); - ike_header->set_initiator_spi(ike_header, initiator_spi); - ike_header->set_responder_spi(ike_header, responder_spi); + ike_header->set_initiator_flag(ike_header, this->ike_sa_id->is_initiator(this->ike_sa_id)); + ike_header->set_initiator_spi(ike_header, this->ike_sa_id->get_initiator_spi(this->ike_sa_id)); + ike_header->set_responder_spi(ike_header, this->ike_sa_id->get_responder_spi(this->ike_sa_id)); generator = generator_create(); if (generator == NULL) diff --git a/Source/charon/payloads/ike_header.c b/Source/charon/payloads/ike_header.c index 9141e846d..18c9e00b5 100644 --- a/Source/charon/payloads/ike_header.c +++ b/Source/charon/payloads/ike_header.c @@ -173,12 +173,24 @@ static status_t verify(private_ike_header_t *this) /* unsupported exchange type */ return FAILED; } - if ((this->initiator_spi == 0) && (this->responder_spi != 0)) + if (this->initiator_spi == 0) { /* initiator spi not set */ return FAILED; } + if ((this->responder_spi == 0) && (!this->flags.initiator)) + { + /* must be original initiator*/ + return FAILED; + } + + if ((this->responder_spi == 0) && (this->flags.response)) + { + /* must be request*/ + return FAILED; + } + /* verification of version is not done in here */ return SUCCESS; diff --git a/Source/charon/thread_pool.c b/Source/charon/thread_pool.c index 9b47b1265..7054ae88c 100644 --- a/Source/charon/thread_pool.c +++ b/Source/charon/thread_pool.c @@ -128,6 +128,10 @@ static void job_processing(private_thread_pool_t *this) message->destroy(message); break; } + /* we must switch the initiator flag here, because the sender + * interprets this flag the other way round + */ + ike_sa_id->switch_initiator(ike_sa_id); status = global_ike_sa_manager->checkout(global_ike_sa_manager,ike_sa_id, &ike_sa); if (status != SUCCESS) @@ -141,10 +145,8 @@ static void job_processing(private_thread_pool_t *this) /* only for logging */ ike_sa_id_t *checked_out_ike_sa_id; checked_out_ike_sa_id = ike_sa->get_id(ike_sa); - u_int64_t initiator; - u_int64_t responder; - bool is_initiator; - checked_out_ike_sa_id->get_values(checked_out_ike_sa_id,&initiator,&responder,&is_initiator); + u_int64_t initiator = checked_out_ike_sa_id->get_initiator_spi(checked_out_ike_sa_id); + u_int64_t responder = checked_out_ike_sa_id->get_responder_spi(checked_out_ike_sa_id); this->logger->log(this->logger, CONTROL|MORE, "IKE SA with SPI's I:%d, R:%d checked out", initiator,responder); } @@ -188,6 +190,7 @@ static void job_processing(private_thread_pool_t *this) break; } + status = global_ike_sa_manager->checkout(global_ike_sa_manager, ike_sa_id, &ike_sa); ike_sa_id->destroy(ike_sa_id); if (status != SUCCESS) @@ -228,10 +231,8 @@ static void job_processing(private_thread_pool_t *this) { /* only for logging */ - u_int64_t initiator; - u_int64_t responder; - bool is_initiator; - ike_sa_id->get_values(ike_sa_id,&initiator,&responder,&is_initiator); + u_int64_t initiator = ike_sa_id->get_initiator_spi(ike_sa_id); + u_int64_t responder = ike_sa_id->get_responder_spi(ike_sa_id); this->logger->log(this->logger, CONTROL|MORE, "thread %u: Going to delete IKE SA with SPI's I:%d, R:%d", pthread_self(),initiator,responder); } status = global_ike_sa_manager->delete(global_ike_sa_manager, ike_sa_id);