From 19fb5a0ef1b9b1e7d264a6e5538fe04e7ab083f0 Mon Sep 17 00:00:00 2001 From: Jan Hutter Date: Tue, 22 Nov 2005 11:57:44 +0000 Subject: [PATCH] - implemented until state change --- Source/charon/states/responder_init.c | 115 +++++++++++++++++++++++++++------- 1 file changed, 94 insertions(+), 21 deletions(-) diff --git a/Source/charon/states/responder_init.c b/Source/charon/states/responder_init.c index 0e2bc70..7a2d385 100644 --- a/Source/charon/states/responder_init.c +++ b/Source/charon/states/responder_init.c @@ -22,6 +22,7 @@ #include "responder_init.h" +#include "ike_sa_init_responded.h" #include "../globals.h" #include "../utils/allocator.h" #include "../payloads/sa_payload.h" @@ -72,6 +73,8 @@ struct private_responder_init_s { /** * Received nonce value + * + * This value is passed to the next state of type ike_sa_init_responded_t. */ chunk_t received_nonce; @@ -121,6 +124,16 @@ struct private_responder_init_s { * - OUT_OF_RES */ status_t (*build_nonce_payload) (private_responder_init_t *this, payload_t **payload); + + /** + * Destroy function called internally of this class after state change succeeded. + * + * This destroy function does not destroy objects which were passed to the new state. + * + * @param this calling object + * @return SUCCESS in any case + */ + status_t (*destroy_after_state_change) (private_responder_init_t *this); }; /** @@ -134,6 +147,22 @@ static status_t process_message(private_responder_init_t *this, message_t *messa message_t *response; payload_t *payload; packet_t *packet; + chunk_t shared_secret; + exchange_type_t exchange_type; + ike_sa_init_responded_t *next_state; + + 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; + } + + 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; + } /* this is the first message we process, so copy host infos */ message->get_source(message, &source); @@ -263,15 +292,20 @@ static status_t process_message(private_responder_init_t *this, message_t *messa case NONCE: { nonce_payload_t *nonce_payload = (nonce_payload_t*)payload; - chunk_t nonce; + + if (this->received_nonce.ptr != NULL) + { + this->logger->log(this->logger, CONTROL | MOST, "Destroy stored received nonce"); + allocator_free(this->received_nonce.ptr); + this->received_nonce.ptr = NULL; + this->received_nonce.len = 0; + } this->logger->log(this->logger, CONTROL | MORE, "Get nonce value and store it"); - nonce_payload->get_nonce(nonce_payload, &nonce); - /** @todo free if there is already one */ - this->received_nonce.ptr = allocator_clone_bytes(nonce.ptr, nonce.len); - this->received_nonce.len = nonce.len; - if (this->received_nonce.ptr == NULL) + status = nonce_payload->get_nonce(nonce_payload, &(this->received_nonce)); + if (status != SUCCESS) { + this->logger->log(this->logger, ERROR, "Fatal error: Could not get nonce"); payloads->destroy(payloads); return OUT_OF_RES; } @@ -291,17 +325,6 @@ static status_t process_message(private_responder_init_t *this, message_t *messa } /* iterator can be destroyed */ payloads->destroy(payloads); - - /********************/ - diffie_hellman_t *dh = this->diffie_hellman; - chunk_t shared_secret; - - status = dh->get_shared_secret(dh, &shared_secret); - this->logger->log_chunk(this->logger, RAW, "Shared secret", &shared_secret); - - allocator_free_chunk(shared_secret); - /********************/ - this->logger->log(this->logger, CONTROL | MORE, "Request successfully handled. Going to create reply."); @@ -386,19 +409,40 @@ static status_t process_message(private_responder_init_t *this, message_t *messa return status; } + status = this->diffie_hellman->get_shared_secret(this->diffie_hellman, &shared_secret); + this->logger->log_chunk(this->logger, PRIVATE, "Shared secret", &shared_secret); + + + /* state can now be changed */ + this ->logger->log(this->logger, CONTROL|MOST, "Create next state object"); + + next_state = ike_sa_init_responded_create(this->ike_sa, shared_secret, this->received_nonce, this->sent_nonce); + + if (next_state == NULL) + { + this ->logger->log(this->logger, ERROR, "Fatal error: could not create next state object of type ike_sa_init_responded_t"); + allocator_free_chunk(shared_secret); + return FAILED; + } + if ( this->ike_sa->last_responded_message != NULL) { /* destroy message */ this ->logger->log(this->logger, CONTROL|MOST, "Destroy stored last responded message"); this->ike_sa->last_responded_message->destroy(this->ike_sa->last_responded_message); } - this->ike_sa->last_responded_message = response; + /* message counter can now be increased */ + this ->logger->log(this->logger, CONTROL|MOST, "Increate message counter for incoming messages"); + this->ike_sa->message_id_in++; + + *new_state = (state_t *) next_state; /* state has NOW changed :-) */ -// this ->logger->log(this->logger, CONTROL|MORE, "Change state of IKE_SA from %s to %s",mapping_find(ike_sa_state_m,this->state),mapping_find(ike_sa_state_m,IKE_SA_INIT_REQUESTED) ); - - *new_state = &(this->public.state_interface); + this ->logger->log(this->logger, CONTROL|MORE, "Changed state of IKE_SA from %s to %s",mapping_find(ike_sa_state_m,RESPONDER_INIT),mapping_find(ike_sa_state_m,IKE_SA_INIT_RESPONDED) ); + + this ->logger->log(this->logger, CONTROL|MOST, "Destroy old sate object"); + this->destroy_after_state_change(this); return SUCCESS; } @@ -595,6 +639,34 @@ static status_t destroy(private_responder_init_t *this) } +/** + * Implements private_responder_init_t.destroy_after_state_change + */ +static status_t 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"); + while (this->proposals->get_count(this->proposals) > 0) + { + proposal_substructure_t *current_proposal; + this->proposals->remove_first(this->proposals,(void **)¤t_proposal); + current_proposal->destroy(current_proposal); + } + this->proposals->destroy(this->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); + } + + allocator_free(this); + return SUCCESS; +} + /* * Described in header. */ @@ -616,6 +688,7 @@ responder_init_t *responder_init_create(protected_ike_sa_t *ike_sa) this->build_sa_payload = build_sa_payload; this->build_ke_payload = build_ke_payload; this->build_nonce_payload = build_nonce_payload; + this->destroy_after_state_change = destroy_after_state_change; /* private data */ this->ike_sa = ike_sa; -- 2.7.4