- implemented until state change

This commit is contained in:
Jan Hutter
2005-11-22 11:57:44 +00:00
parent 3525276c80
commit 19fb5a0ef1
+94 -21
View File
@@ -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 **)&current_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;