From 2848a7ba33ee0158c9dfee383c3ea8be02060f7e Mon Sep 17 00:00:00 2001 From: Jan Hutter Date: Fri, 2 Dec 2005 08:52:01 +0000 Subject: [PATCH] responder_init does return DELETE_ME in case of error --- Source/charon/encoding/payloads/ke_payload.c | 8 +- Source/charon/sa/states/ike_sa_init_requested.c | 8 ++ Source/charon/sa/states/initiator_init.c | 41 ++++--- Source/charon/sa/states/initiator_init.h | 12 +- Source/charon/sa/states/responder_init.c | 153 +++++++++++++----------- 5 files changed, 133 insertions(+), 89 deletions(-) diff --git a/Source/charon/encoding/payloads/ke_payload.c b/Source/charon/encoding/payloads/ke_payload.c index 9f1e7bd..da1b28f 100644 --- a/Source/charon/encoding/payloads/ke_payload.c +++ b/Source/charon/encoding/payloads/ke_payload.c @@ -98,11 +98,11 @@ encoding_rule_t ke_payload_encodings[] = { /* Length of the whole payload*/ { PAYLOAD_LENGTH, offsetof(private_ke_payload_t, payload_length) }, /* DH Group number as 16 bit field*/ - { U_INT_16, offsetof(private_ke_payload_t, dh_group_number) }, - { RESERVED_BYTE, 0 }, - { RESERVED_BYTE, 0 }, + { U_INT_16, offsetof(private_ke_payload_t, dh_group_number) }, + { RESERVED_BYTE, 0 }, + { RESERVED_BYTE, 0 }, /* Key Exchange Data is from variable size */ - { KEY_EXCHANGE_DATA, offsetof(private_ke_payload_t, key_exchange_data) } + { KEY_EXCHANGE_DATA, offsetof(private_ke_payload_t, key_exchange_data)} }; /* diff --git a/Source/charon/sa/states/ike_sa_init_requested.c b/Source/charon/sa/states/ike_sa_init_requested.c index 39e2403..756b6b9 100644 --- a/Source/charon/sa/states/ike_sa_init_requested.c +++ b/Source/charon/sa/states/ike_sa_init_requested.c @@ -218,6 +218,14 @@ static status_t process_message(private_ike_sa_init_requested_t *this, message_t this->logger->log(this->logger, CONTROL|MORE, "Processing payload %s", mapping_find(payload_type_m, payload->get_type(payload))); switch (payload->get_type(payload)) { + /** + * TODO check for notify of type + * + * and change to state INITIATOR_INIT; + * + * call destroy after state change not destroy_after_state_change!!! + */ + case SECURITY_ASSOCIATION: { sa_payload_t *sa_payload = (sa_payload_t*)payload; diff --git a/Source/charon/sa/states/initiator_init.c b/Source/charon/sa/states/initiator_init.c index 95fc88c..445d507 100644 --- a/Source/charon/sa/states/initiator_init.c +++ b/Source/charon/sa/states/initiator_init.c @@ -126,16 +126,12 @@ struct private_initiator_init_t { }; /** - * Implements function initiator_init_t.initiate_connection. + * Implementation of initiator_init_t.initiate_connection. */ static status_t initiate_connection (private_initiator_init_t *this, char *name) { - ike_sa_init_requested_t *next_state; init_config_t *init_config; - randomizer_t *randomizer; sa_config_t *sa_config; - message_t *message; - packet_t *packet; status_t status; this->logger->log(this->logger, CONTROL, "Initializing connection %s",name); @@ -159,8 +155,7 @@ static status_t initiate_connection (private_initiator_init_t *this, char *name) this->ike_sa->set_sa_config(this->ike_sa,sa_config); - - + /* host informations are read from configuration */ this->ike_sa->set_other_host(this->ike_sa,init_config->get_other_host_clone(init_config)); this->ike_sa->set_my_host(this->ike_sa,init_config->get_my_host_clone(init_config)); @@ -171,17 +166,32 @@ static status_t initiate_connection (private_initiator_init_t *this, char *name) return INVALID_ARG; } - /* a diffie hellman object could allready exist caused by an failed initiate_connection call */ - if (this->diffie_hellman == NULL) - { - this->diffie_hellman = diffie_hellman_create(this->dh_group_number); - } + /* next step is done in retry_initiate_connection */ + return this->public.retry_initiate_connection(&(this->public),this->dh_group_priority); +} + +/** + * Implementation of initiator_init_t.retry_initiate_connection. + */ +status_t retry_initiate_connection (private_initiator_init_t *this, int dh_group_priority) +{ + ike_sa_init_requested_t *next_state; + init_config_t *init_config; + randomizer_t *randomizer; + message_t *message; + packet_t *packet; + status_t status; + + init_config = this->ike_sa->get_init_config(this->ike_sa); - if (this->sent_nonce.ptr != NULL) + this->dh_group_number = init_config->get_dh_group_number(init_config,dh_group_priority); + if (this->dh_group_number == MODP_UNDEFINED) { - allocator_free(this->sent_nonce.ptr); - this->sent_nonce = CHUNK_INITIALIZER; + this->logger->log(this->logger, ERROR | MORE, "Diffie hellman group could not be retrieved with priority %d", this->dh_group_priority); + return INVALID_ARG; } + + this->diffie_hellman = diffie_hellman_create(this->dh_group_number); this->logger->log(this->logger, CONTROL|MOST, "Get pseudo random bytes for nonce"); randomizer = this->ike_sa->get_randomizer(this->ike_sa); @@ -387,6 +397,7 @@ initiator_init_t *initiator_init_create(protected_ike_sa_t *ike_sa) /* public functions */ this->public.initiate_connection = (status_t (*)(initiator_init_t *, char *)) initiate_connection; + this->public.retry_initiate_connection = (status_t (*)(initiator_init_t *, int )) retry_initiate_connection; /* private functions */ this->destroy_after_state_change = destroy_after_state_change; diff --git a/Source/charon/sa/states/initiator_init.h b/Source/charon/sa/states/initiator_init.h index f8c9e39..4643ca6 100644 --- a/Source/charon/sa/states/initiator_init.h +++ b/Source/charon/sa/states/initiator_init.h @@ -46,10 +46,20 @@ struct initiator_init_t { * Initiate a new connection with given configuration name * * @param this calling object + * * @param name name of the configuration * @return TODO */ - status_t (*initiate_connection) (initiator_init_t *this, char *name); + status_t (*initiate_connection) (initiator_init_t *this, char *name); + + /** + * Retries to initiate a new connection with another dh_group_priority + * + * @param this calling object + * @param dh_group_priority dh group priority to try with + * @return TODO + */ + status_t (*retry_initiate_connection) (initiator_init_t *this, int dh_group_priority); }; /** diff --git a/Source/charon/sa/states/responder_init.c b/Source/charon/sa/states/responder_init.c index fd730db..6734d68 100644 --- a/Source/charon/sa/states/responder_init.c +++ b/Source/charon/sa/states/responder_init.c @@ -94,6 +94,14 @@ struct private_responder_init_t { ike_proposal_t selected_proposal; /** + * Builds the IKE_SA_INIT reply message + * + * @param this calling object + * @param message the message will be written to this location. + */ + void (*build_ike_sa_init_reply) (private_responder_init_t *this, message_t **message); + + /** * Builds the SA payload for this state. * * @param this calling object @@ -135,48 +143,44 @@ struct private_responder_init_t { */ static status_t process_message(private_responder_init_t *this, message_t *message) { - iterator_t *payloads; + ike_sa_init_responded_t *next_state; + exchange_type_t exchange_type; host_t *source, *destination; - status_t status; + init_config_t *init_config; + randomizer_t *randomizer; + chunk_t shared_secret; + iterator_t *payloads; message_t *response; - payload_t *payload; + host_t *other_host; packet_t *packet; - chunk_t shared_secret; - exchange_type_t exchange_type; - ike_sa_init_responded_t *next_state; host_t *my_host; - host_t *other_host; - randomizer_t *randomizer; - init_config_t *init_config; - diffie_hellman_group_t dh_group = MODP_UNDEFINED; + status_t status; exchange_type = message->get_exchange_type(message); if (exchange_type != IKE_SA_INIT) { this->logger->log(this->logger, ERROR | MORE, "Message of type %s not supported in state responder_init",mapping_find(exchange_type_m,exchange_type)); - return FAILED; + return DELETE_ME; } if (!message->get_request(message)) { this->logger->log(this->logger, ERROR | MORE, "Only requests of type IKE_SA_INIT supported in state responder_init"); - return FAILED; + return DELETE_ME; } - /* this is the first message we process, so copy host infos */ + /* this is the first message we process, so get host infos */ source = message->get_source(message); destination = message->get_destination(message); status = charon->configuration_manager->get_init_config_for_host(charon->configuration_manager,destination,source,&init_config); - if (status != SUCCESS) { /* no configuration matches given host */ this->logger->log(this->logger, ERROR | MORE, "No INIT configuration found for given remote and local hosts"); - return FAILED; + return DELETE_ME; } this->ike_sa->set_init_config(this->ike_sa,init_config); - /* we need to clone them, since we destroy the message later */ my_host = destination->clone(destination); other_host = source->clone(source); @@ -189,8 +193,9 @@ static status_t process_message(private_responder_init_t *this, message_t *messa if (status != SUCCESS) { this->logger->log(this->logger, ERROR | MORE, "Could not parse body of request message"); - return status; + return DELETE_ME; } + /* iterate over incoming payloads. We can be sure, the message contains only accepted payloads! */ payloads = message->get_payload_iterator(message); @@ -216,7 +221,7 @@ static status_t process_message(private_responder_init_t *this, message_t *messa { this->logger->log(this->logger, ERROR | MORE, "SA payload does not contain IKE proposals"); payloads->destroy(payloads); - return status; + return DELETE_ME; } status = init_config->select_proposal(init_config, ike_proposals,proposal_count,&(this->selected_proposal)); @@ -225,17 +230,17 @@ static status_t process_message(private_responder_init_t *this, message_t *messa { this->logger->log(this->logger, ERROR | MORE, "No proposal of suggested proposals selected"); payloads->destroy(payloads); - return status; + return DELETE_ME; } - dh_group = this->selected_proposal.diffie_hellman_group; + this->dh_group_number = this->selected_proposal.diffie_hellman_group; status = this->ike_sa->create_transforms_from_proposal(this->ike_sa,&(this->selected_proposal)); if (status != SUCCESS) { this->logger->log(this->logger, ERROR | MORE, "Transform objects could not be created from selected proposal"); payloads->destroy(payloads); - return status; + return DELETE_ME; } this->logger->log(this->logger, CONTROL | MORE, "SA Payload processed"); @@ -247,28 +252,31 @@ static status_t process_message(private_responder_init_t *this, message_t *messa ke_payload_t *ke_payload = (ke_payload_t*)payload; diffie_hellman_group_t group; diffie_hellman_t *dh; - bool allowed_group; group = ke_payload->get_dh_group_number(ke_payload); - if (dh_group == MODP_UNDEFINED) + if (group == MODP_UNDEFINED) { - this->logger->log(this->logger, ERROR | MORE, "Could not get informations about DH group. SA payload before KE payload?"); + this->logger->log(this->logger, ERROR | MORE, "Diffie hellman group set to undefined!"); payloads->destroy(payloads); - return status; + return DELETE_ME; } - if (!allowed_group) + if (this->dh_group_number != group) { - /** @todo Send info reply */ + /* group not same as selected one */ + + /** + * TODO send notify reply + */ } /* create diffie hellman object to handle DH exchange */ dh = diffie_hellman_create(group); if (dh == NULL) { - this->logger->log(this->logger, ERROR, "Could not generate DH object"); + this->logger->log(this->logger, ERROR, "Could not generate DH object with group %d",mapping_find(diffie_hellman_group_m,group) ); payloads->destroy(payloads); - return NOT_SUPPORTED; + return DELETE_ME; } this->logger->log(this->logger, CONTROL | MORE, "Set other DH public value"); @@ -276,7 +284,7 @@ static status_t process_message(private_responder_init_t *this, message_t *messa this->diffie_hellman = dh; - this->logger->log(this->logger, CONTROL | MORE, "KE Payload processed"); + this->logger->log(this->logger, CONTROL | MORE, "KE Payload processed."); break; } case NONCE: @@ -296,7 +304,7 @@ static status_t process_message(private_responder_init_t *this, message_t *messa { this->logger->log(this->logger, ERROR | MORE, "Payload type not supported!"); payloads->destroy(payloads); - return NOT_SUPPORTED; + return DELETE_ME; } } } @@ -308,34 +316,16 @@ static status_t process_message(private_responder_init_t *this, message_t *messa this->logger->log(this->logger, CONTROL | MOST, "Going to create nonce."); randomizer = this->ike_sa->get_randomizer(this->ike_sa); - randomizer->allocate_pseudo_random_bytes(randomizer, NONCE_SIZE, &(this->sent_nonce)); /* store shared secret */ - this->logger->log(this->logger, CONTROL | MOST, "Retrieve shared secret and store it"); + this->logger->log(this->logger, CONTROL | MOST, "Retrieve shared secret and store it."); status = this->diffie_hellman->get_shared_secret(this->diffie_hellman, &shared_secret); this->logger->log_chunk(this->logger, PRIVATE, "Shared secret", &shared_secret); this->ike_sa->compute_secrets(this->ike_sa,shared_secret,this->received_nonce, this->sent_nonce); - /* set up the reply */ - this->ike_sa->build_message(this->ike_sa, IKE_SA_INIT, FALSE, &response); - - - /* build SA payload */ - this->build_sa_payload(this, &payload); - this->logger->log(this->logger, CONTROL|MOST, "add SA payload to message"); - response->add_payload(response, payload); - - /* build KE payload */ - this->build_ke_payload(this,&payload); - this->logger->log(this->logger, CONTROL|MOST, "add KE payload to message"); - response->add_payload(response, payload); - - /* build Nonce payload */ - this->build_nonce_payload(this, &payload); - this->logger->log(this->logger, CONTROL|MOST, "add nonce payload to message"); - response->add_payload(response, payload); + this->build_ike_sa_init_reply(this,&response); /* generate packet */ this->logger->log(this->logger, CONTROL|MOST, "generate packet from message"); @@ -343,7 +333,7 @@ static status_t process_message(private_responder_init_t *this, message_t *messa if (status != SUCCESS) { this->logger->log(this->logger, ERROR, "could not generate packet from message"); - return status; + return DELETE_ME; } this->logger->log(this->logger, CONTROL|MOST, "Add packet to global send queue"); @@ -362,7 +352,7 @@ static status_t process_message(private_responder_init_t *this, message_t *messa this->logger->log(this->logger, ERROR, "Could not set last responded message"); response->destroy(response); (next_state->state_interface).destroy(&(next_state->state_interface)); - return status; + return DELETE_ME; } /* state can now be changed */ @@ -376,6 +366,37 @@ static status_t process_message(private_responder_init_t *this, message_t *messa return SUCCESS; } + +/** + * implements private_responder_init_t.build_ike_sa_init_reply + */ +static void build_ike_sa_init_reply (private_responder_init_t *this, message_t **message) +{ + message_t *response; + payload_t *payload; + + this->logger->log(this->logger, CONTROL|MOST, "Going to build message"); + /* set up the reply */ + this->ike_sa->build_message(this->ike_sa, IKE_SA_INIT, FALSE, &response); + + /* build SA payload */ + this->build_sa_payload(this, &payload); + this->logger->log(this->logger, CONTROL|MOST, "add SA payload to message"); + response->add_payload(response, payload); + + /* build KE payload */ + this->build_ke_payload(this,&payload); + this->logger->log(this->logger, CONTROL|MOST, "add KE payload to message"); + response->add_payload(response, payload); + + /* build Nonce payload */ + this->build_nonce_payload(this, &payload); + this->logger->log(this->logger, CONTROL|MOST, "add nonce payload to message"); + response->add_payload(response, payload); + + *message = response; +} + /** * implements private_initiator_init_t.build_sa_payload */ @@ -383,10 +404,7 @@ static void build_sa_payload(private_responder_init_t *this, payload_t **payload { sa_payload_t* sa_payload; - /* SA payload takes proposals from this->ike_sa_init_data.proposals and writes them to the created sa_payload */ - this->logger->log(this->logger, CONTROL|MORE, "building sa payload"); - sa_payload = sa_payload_create_from_ike_proposals(&(this->selected_proposal),1); *payload = (payload_t *) sa_payload; @@ -405,9 +423,9 @@ static void build_ke_payload(private_responder_init_t *this, payload_t **payload ke_payload = ke_payload_create(); ke_payload->set_key_exchange_data(ke_payload,key_data); - ke_payload->set_dh_group_number(ke_payload, MODP_1024_BIT); - + ke_payload->set_dh_group_number(ke_payload, this->dh_group_number); allocator_free_chunk(&key_data); + *payload = (payload_t *) ke_payload; } @@ -417,13 +435,10 @@ static void build_ke_payload(private_responder_init_t *this, payload_t **payload static void build_nonce_payload(private_responder_init_t *this, payload_t **payload) { nonce_payload_t *nonce_payload; - status_t status; this->logger->log(this->logger, CONTROL|MORE, "building nonce payload"); - nonce_payload = nonce_payload_create(); - - status = nonce_payload->set_nonce(nonce_payload, this->sent_nonce); + nonce_payload->set_nonce(nonce_payload, this->sent_nonce); *payload = (payload_t *) nonce_payload; } @@ -444,16 +459,17 @@ static void destroy(private_responder_init_t *this) { this->logger->log(this->logger, CONTROL | MORE, "Going to destroy responder init state object"); - /* destroy stored proposal */ - this->logger->log(this->logger, CONTROL | MOST, "Destroy stored proposals"); - + this->logger->log(this->logger, CONTROL | MOST, "Destroy sent nonce"); allocator_free(this->sent_nonce.ptr); + this->logger->log(this->logger, CONTROL | MOST, "Destroy received nonce"); allocator_free(this->received_nonce.ptr); if (this->diffie_hellman != NULL) { + this->logger->log(this->logger, CONTROL | MOST, "Destroy diffie_hellman_t hellman object"); this->diffie_hellman->destroy(this->diffie_hellman); } + this->logger->log(this->logger, CONTROL | MOST, "Destroy object"); allocator_free(this); } @@ -464,16 +480,14 @@ static void destroy_after_state_change (private_responder_init_t *this) { this->logger->log(this->logger, CONTROL | MORE, "Going to destroy responder_init_t state object"); - /* destroy stored proposal */ - this->logger->log(this->logger, CONTROL | MOST, "Destroy stored proposals"); - /* destroy diffie hellman object */ if (this->diffie_hellman != NULL) { this->logger->log(this->logger, CONTROL | MOST, "Destroy diffie_hellman_t object"); this->diffie_hellman->destroy(this->diffie_hellman); } - + + this->logger->log(this->logger, CONTROL | MOST, "Destroy object"); allocator_free(this); } @@ -490,6 +504,7 @@ responder_init_t *responder_init_create(protected_ike_sa_t *ike_sa) this->public.state_interface.destroy = (void (*) (state_t *)) destroy; /* private functions */ + this->build_ike_sa_init_reply = build_ike_sa_init_reply; this->build_sa_payload = build_sa_payload; this->build_ke_payload = build_ke_payload; this->build_nonce_payload = build_nonce_payload; -- 2.7.4