(no commit message)
[strongswan.git] / Source / charon / sa / states / initiator_init.c
index b120781..95fc88c 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * @file initiator_init.c
  * 
- * @brief Start state of a IKE_SA as initiator
+ * @brief Implementation of initiator_init_t.
  * 
  */
 
@@ -23,7 +23,7 @@
 #include "initiator_init.h"
 
 
-#include <globals.h>
+#include <daemon.h>
 #include <sa/states/state.h>
 #include <sa/states/ike_sa_init_requested.h>
 #include <utils/allocator.h>
@@ -36,7 +36,7 @@
 typedef struct private_initiator_init_t private_initiator_init_t;
 
 /**
- * Private data of a initiator_init_t object.
+ * Private data of a initiator_init_t object..
  *
  */
 struct private_initiator_init_t {
@@ -72,12 +72,6 @@ struct private_initiator_init_t {
         * This nonce is passed to the next state of type ike_sa_init_requested_t.
         */
        chunk_t sent_nonce;
-       
-       /**
-        * Proposals used to initiate connection.
-        * 
-        */
-       linked_list_t *proposals;
 
        /**
         * Logger used to log :-)
@@ -91,11 +85,8 @@ struct private_initiator_init_t {
         * 
         * @param this          calling object
         * @param message       the created message will be stored at this location
-        * @return                      
-        *                                      - SUCCESS
-        *                                      - OUT_OF_RES
         */
-       status_t (*build_ike_sa_init_request) (private_initiator_init_t *this, message_t **message);
+       void (*build_ike_sa_init_request) (private_initiator_init_t *this, message_t **message);
        
        /**
         * Builds the SA payload for this state.
@@ -103,11 +94,8 @@ struct private_initiator_init_t {
         * @param this          calling object
         * @param payload       The generated SA payload object of type ke_payload_t is 
         *                                      stored at this location.
-        * @return                      
-        *                                      - SUCCESS
-        *                                      - OUT_OF_RES
         */
-       status_t (*build_sa_payload) (private_initiator_init_t *this, payload_t **payload);
+       void (*build_sa_payload) (private_initiator_init_t *this, payload_t **payload);
 
        /**
         * Builds the KE payload for this state.
@@ -115,22 +103,17 @@ struct private_initiator_init_t {
         * @param this          calling object
         * @param payload       The generated KE payload object of type ke_payload_t is 
         *                                      stored at this location.
-        * @return                      
-        *                                      - SUCCESS
-        *                                      - OUT_OF_RES
         */
-       status_t (*build_ke_payload) (private_initiator_init_t *this, payload_t **payload);
+       void (*build_ke_payload) (private_initiator_init_t *this, payload_t **payload);
+       
        /**
         * Builds the NONCE payload for this state.
         * 
         * @param this          calling object
         * @param payload       The generated NONCE payload object of type ke_payload_t is 
         *                                      stored at this location.
-        * @return                      
-        *                                      - SUCCESS
-        *                                      - OUT_OF_RES
         */
-       status_t (*build_nonce_payload) (private_initiator_init_t *this, payload_t **payload);  
+       void (*build_nonce_payload) (private_initiator_init_t *this, payload_t **payload);      
        
        /**
         * Destroy function called internally of this class after state change succeeded.
@@ -138,9 +121,8 @@ struct private_initiator_init_t {
         * 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_initiator_init_t *this);
+       void (*destroy_after_state_change) (private_initiator_init_t *this);
 };
 
 /**
@@ -148,124 +130,83 @@ struct private_initiator_init_t {
  */
 static status_t initiate_connection (private_initiator_init_t *this, char *name)
 {
-       iterator_t      *proposal_iterator;
-       ike_sa_init_requested_t         *next_state;
-       message_t                               *message;
-       packet_t                                *packet;
-       status_t                                status;
-       host_t                                  *my_host;
-       host_t                                  *other_host;
-       randomizer_t                            *randomizer;
+       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);
        
-       status = global_configuration_manager->get_local_host(global_configuration_manager, name, &my_host);
+       status = charon->configuration_manager->get_init_config_for_name(charon->configuration_manager,name,&init_config);
        if (status != SUCCESS)
        {       
-               this->logger->log(this->logger, ERROR | MORE, "Could not retrieve local host configuration information for %s",name);
+               this->logger->log(this->logger, ERROR | MORE, "Could not retrieve INIT configuration informations for %s",name);
                return INVALID_ARG;
        }
-       this->ike_sa->set_my_host(this->ike_sa,my_host);
        
-       status = global_configuration_manager->get_remote_host(global_configuration_manager, name, &other_host);
-       if (status != SUCCESS)
-       {       
-               this->logger->log(this->logger, ERROR | MORE, "Could not retrieve remote host configuration information for %s",name);
-               return INVALID_ARG;
-       }
-       this->ike_sa->set_other_host(this->ike_sa,other_host);
+       this->ike_sa->set_init_config(this->ike_sa,init_config);
+       
+       status = charon->configuration_manager->get_sa_config_for_name(charon->configuration_manager,name,&sa_config);
        
-       status = global_configuration_manager->get_dh_group_number(global_configuration_manager, name, &(this->dh_group_number), this->dh_group_priority);
        if (status != SUCCESS)
        {       
-               this->logger->log(this->logger, ERROR | MORE, "Could not retrieve DH group number configuration for %s",name);
+               this->logger->log(this->logger, ERROR | MORE, "Could not retrieve SA configuration informations for %s",name);
                return INVALID_ARG;
        }
-
-       status = this->proposals->create_iterator(this->proposals, &proposal_iterator, FALSE);
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger, ERROR, "Fatal error: Could not create iterator on list for proposals");
-               return status;  
-       }
        
-       status = global_configuration_manager->get_proposals_for_host(global_configuration_manager, this->ike_sa->get_other_host(this->ike_sa), proposal_iterator);
-       /* not needed anymore */
-       proposal_iterator->destroy(proposal_iterator);
-       if (status != SUCCESS)
+       this->ike_sa->set_sa_config(this->ike_sa,sa_config);
+       
+       
+       
+       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));
+       
+       this->dh_group_number = init_config->get_dh_group_number(init_config,this->dh_group_priority);
+       if (this->dh_group_number == MODP_UNDEFINED)
        {
-               this->logger->log(this->logger, ERROR | MORE, "Could not retrieve Proposals for %s",name);
-               return status;
+               this->logger->log(this->logger, ERROR | MORE, "Diffie hellman group could not be  retrieved with priority %d", this->dh_group_priority);
+               return INVALID_ARG;
        }
-
+       
        /* a diffie hellman object could allready exist caused by an failed initiate_connection call */ 
        if (this->diffie_hellman == NULL)
        {
-               this    ->logger->log(this->logger, CONTROL|MOST, "create diffie hellman object");
                this->diffie_hellman = diffie_hellman_create(this->dh_group_number);
        }
        
-       if (this->diffie_hellman == NULL)
-       {
-               this->logger->log(this->logger, ERROR, "Object of type diffie_hellman_t could not be created!");
-               return FAILED;                  
-       }
-       
        if (this->sent_nonce.ptr != NULL)
        {
-               this->logger->log(this->logger, ERROR, "Free existing sent nonce!");
                allocator_free(this->sent_nonce.ptr);
                this->sent_nonce = CHUNK_INITIALIZER;
        }
 
-       this    ->logger->log(this->logger, CONTROL|MOST, "Get pseudo random bytes for nonce");
+       this->logger->log(this->logger, CONTROL|MOST, "Get pseudo random bytes for nonce");
        randomizer = this->ike_sa->get_randomizer(this->ike_sa);
-       if (randomizer->allocate_pseudo_random_bytes(randomizer, NONCE_SIZE, &(this->sent_nonce)) != SUCCESS)
-       {
-               this->logger->log(this->logger, ERROR, "Could not create nonce!");
-               return OUT_OF_RES;
-       }
-       this    ->logger->log(this->logger, RAW|MOST, "Nonce",&(this->sent_nonce));
+       randomizer->allocate_pseudo_random_bytes(randomizer, NONCE_SIZE, &(this->sent_nonce));
+
+       this->logger->log(this->logger, RAW|MOST, "Nonce",&(this->sent_nonce));
+
+       this->build_ike_sa_init_request (this,&message);
 
-       
-       
-       status = this->build_ike_sa_init_request (this,&message);
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger, ERROR, "Fatal error: could not build IKE_SA_INIT request message");
-               return status;
-       }
-       
        /* generate packet */   
        this->logger->log(this->logger, CONTROL|MOST, "generate packet from message");
-       status = message->generate(message, &packet);
+       status = message->generate(message, NULL, NULL, &packet);
        if (status != SUCCESS)
        {
-               this->logger->log(this->logger, ERROR, "Fatal error: could not generate packet from message");
+               this->logger->log(this->logger, ERROR, "could not generate packet from message");
                message->destroy(message);
                return status;
        }
        
        this->logger->log(this->logger, CONTROL|MOST, "Add packet to global send queue");
-       status = global_send_queue->add(global_send_queue, packet);
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger, ERROR, "Could not add packet to send queue");
-               packet->destroy(packet);
-               message->destroy(message);
-               return status;
-       }
+       charon->send_queue->add(charon->send_queue, packet);
 
        /* state can now be changed */
        this->logger->log(this->logger, CONTROL|MOST, "Create next state object");
        next_state = ike_sa_init_requested_create(this->ike_sa, this->dh_group_number, this->diffie_hellman, 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_requested_t");
-               message->destroy(message);
-               return FAILED;
-       }
 
        /* last message can now be set */
        status = this->ike_sa->set_last_requested_message(this->ike_sa, message);
@@ -282,7 +223,7 @@ static status_t initiate_connection (private_initiator_init_t *this, char *name)
        this->ike_sa->set_new_state(this->ike_sa,(state_t *) next_state);
 
        /* state has NOW changed :-) */
-       this->logger->log(this->logger, CONTROL|MORE, "Changed state of IKE_SA from %s to %s",mapping_find(ike_sa_state_m,INITIATOR_INIT),mapping_find(ike_sa_state_m,IKE_SA_INIT_REQUESTED) );
+       this->logger->log(this->logger, CONTROL|MORE, "Changed state of IKE_SA from %s to %s", mapping_find(ike_sa_state_m,INITIATOR_INIT),mapping_find(ike_sa_state_m,IKE_SA_INIT_REQUESTED) );
 
        this->logger->log(this->logger, CONTROL|MOST, "Destroy old sate object");
        this->destroy_after_state_change(this);
@@ -293,221 +234,89 @@ static status_t initiate_connection (private_initiator_init_t *this, char *name)
 /**
  * implements private_initiator_init_t.build_ike_sa_init_request
  */
-static status_t build_ike_sa_init_request (private_initiator_init_t *this, message_t **request)
+static void build_ike_sa_init_request (private_initiator_init_t *this, message_t **request)
 {
-       status_t status;
        payload_t *payload;
        message_t *message;
        
        /* going to build message */
-       this    ->logger->log(this->logger, CONTROL|MOST, "Going to build message");
-       status = this->ike_sa->build_message(this->ike_sa, IKE_SA_INIT, TRUE, &message);
-       if (status != SUCCESS)
-       {       
-               this->logger->log(this->logger, ERROR, "Could not build empty message");
-               return status;
-       }
-
+       this->logger->log(this->logger, CONTROL|MOST, "Going to build message");
+       this->ike_sa->build_message(this->ike_sa, IKE_SA_INIT, TRUE, &message);
+       
        /* build SA payload */          
-       status = this->build_sa_payload(this, &payload);
-       if (status != SUCCESS)
-       {       
-               this->logger->log(this->logger, ERROR, "Could not build SA payload");
-               message->destroy(message);
-               return status;
-       }
+       this->build_sa_payload(this, &payload);
+       this->logger->log(this->logger, CONTROL|MOST, "add SA payload to message");
+       message->add_payload(message, payload);
        
-       this    ->logger->log(this->logger, CONTROL|MOST, "add SA payload to message");
-       status = message->add_payload(message, payload);
-       if (status != SUCCESS)
-       {       
-               this->logger->log(this->logger, ERROR, "Could not add SA payload to message");
-               payload->destroy(payload);
-               message->destroy(message);
-               return status;
-       }
-
        /* build KE payload */
-       status = this->build_ke_payload(this, &payload);
-       if (status != SUCCESS)
-       {       
-               this->logger->log(this->logger, ERROR, "Could not build KE payload");
-               message->destroy(message);
-               return status;
-       }
-
-       this    ->logger->log(this->logger, CONTROL|MOST, "add KE payload to message");
-       status = message->add_payload(message, payload);
-       if (status != SUCCESS)
-       {       
-               this->logger->log(this->logger, ERROR, "Could not add KE payload to message");
-               payload->destroy(payload);
-               message->destroy(message);
-               return status;
-       }
+       this->build_ke_payload(this, &payload);
+       this->logger->log(this->logger, CONTROL|MOST, "add KE payload to message");
+       message->add_payload(message, payload);
        
        /* build Nonce payload */
-       status = this->build_nonce_payload(this, &payload);
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger, ERROR, "Could not build NONCE payload");
-               message->destroy(message);
-               return status;
-       }
-
-       this    ->logger->log(this->logger, CONTROL|MOST, "add nonce payload to message");
-       status = message->add_payload(message, payload);
-       if (status != SUCCESS)
-       {       
-               this->logger->log(this->logger, ERROR, "Could not add nonce payload to message");
-               payload->destroy(payload);
-               message->destroy(message);
-               return status;
-       }
+       this->build_nonce_payload(this, &payload);
+       this->logger->log(this->logger, CONTROL|MOST, "add nonce payload to message");
+       message->add_payload(message, payload);
        
        *request = message;
-       return SUCCESS;
 }
 
 /**
  * implements private_initiator_init_t.build_sa_payload
  */
-static status_t build_sa_payload(private_initiator_init_t *this, payload_t **payload)
+static void build_sa_payload(private_initiator_init_t *this, payload_t **payload)
 {
        sa_payload_t* sa_payload;
-       iterator_t *proposal_iterator;
-       status_t status;
+       size_t proposal_count;
+       ike_proposal_t *proposals;
+       init_config_t *init_config;
        
-       /* 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");
-       status = this->proposals->create_iterator(this->proposals, &proposal_iterator, FALSE);
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger, ERROR, "Fatal error: Could not create iterator on list for proposals");
-               return status;  
-       }
        
-       sa_payload = sa_payload_create();
-       if (sa_payload == NULL)
-       {
-               this->logger->log(this->logger, ERROR, "Fatal error: Could not create SA payload object");
-               return OUT_OF_RES;
-       }
-       
-       while (proposal_iterator->has_next(proposal_iterator))
-       {
-               proposal_substructure_t *current_proposal;
-               proposal_substructure_t *current_proposal_clone;
-               status = proposal_iterator->current(proposal_iterator,(void **) &current_proposal);
-               if (status != SUCCESS)
-               {
-                       this->logger->log(this->logger, ERROR, "Could not get current proposal needed to copy");
-                       proposal_iterator->destroy(proposal_iterator);
-                       sa_payload->destroy(sa_payload);
-                       return status;  
-               }
-               status = current_proposal->clone(current_proposal,&current_proposal_clone);
-               if (status != SUCCESS)
-               {
-                       this->logger->log(this->logger, ERROR, "Could not clone current proposal");
-                       proposal_iterator->destroy(proposal_iterator);
-                       sa_payload->destroy(sa_payload);
-                       return status;  
-               }
-               
-               status = sa_payload->add_proposal_substructure(sa_payload,current_proposal_clone);
-               if (status != SUCCESS)
-               {
-                       this->logger->log(this->logger, ERROR, "Could not add cloned proposal to SA payload");
-                       proposal_iterator->destroy(proposal_iterator);
-                       sa_payload->destroy(sa_payload);
-                       return status;  
-               }
+       init_config = this->ike_sa->get_init_config(this->ike_sa);
 
-       }
-       proposal_iterator->destroy(proposal_iterator);
+       proposal_count = init_config->get_proposals(init_config,&proposals);
        
-       this->logger->log(this->logger, CONTROL|MORE, "sa payload builded");
+       sa_payload = sa_payload_create_from_ike_proposals(proposals,proposal_count);    
 
+       allocator_free(proposals);
        *payload = (payload_t *) sa_payload;    
-       return SUCCESS;
 }
 
 /**
  * implements private_initiator_init_t.build_ke_payload
  */
-static status_t build_ke_payload(private_initiator_init_t *this, payload_t **payload)
+static void build_ke_payload(private_initiator_init_t *this, payload_t **payload)
 {
        ke_payload_t *ke_payload;
        chunk_t key_data;
-       status_t status;
-
+       
        this->logger->log(this->logger, CONTROL|MORE, "building ke payload");
        
-
-       this    ->logger->log(this->logger, CONTROL|MORE, "get public dh value to send in ke payload");
-       status = this->diffie_hellman->get_my_public_value(this->diffie_hellman,&key_data);
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger, ERROR, "Could not get my DH public value");
-               return status;
-       }
+       this->diffie_hellman->get_my_public_value(this->diffie_hellman,&key_data);
 
        ke_payload = ke_payload_create();
-       if (ke_payload == NULL)
-       {
-               this->logger->log(this->logger, ERROR, "Could not create KE payload");
-               allocator_free_chunk(&key_data);
-               return OUT_OF_RES;      
-       }
        ke_payload->set_dh_group_number(ke_payload, this->dh_group_number);
-       if (ke_payload->set_key_exchange_data(ke_payload, key_data) != SUCCESS)
-       {
-               this->logger->log(this->logger, ERROR, "Could not set key exchange data of KE payload");
-               ke_payload->destroy(ke_payload);
-               allocator_free_chunk(&key_data);
-               return OUT_OF_RES;
-       }
-       allocator_free_chunk(&key_data);
+       ke_payload->set_key_exchange_data(ke_payload, key_data);
        
-       this->logger->log(this->logger, CONTROL|MORE, "ke payload builded");
-
+       allocator_free_chunk(&key_data);
        *payload = (payload_t *) ke_payload;
-       return SUCCESS;                 
 }
 
 /**
  * implements private_initiator_init_t.build_nonce_payload
  */
-static status_t build_nonce_payload(private_initiator_init_t *this, payload_t **payload)
+static void build_nonce_payload(private_initiator_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();
-       if (nonce_payload == NULL)
-       {       
-               this->logger->log(this->logger, ERROR, "Fatal error: could not create nonce payload object");
-               return OUT_OF_RES;      
-       }
-
-       status = nonce_payload->set_nonce(nonce_payload, this->sent_nonce);
        
-       if (status != SUCCESS)
-       {
-               this->logger->log(this->logger, ERROR, "Fatal error: could not set nonce data of payload");
-               nonce_payload->destroy(nonce_payload);
-               return status;
-       }
-               
-       *payload = (payload_t *) nonce_payload;
+       nonce_payload = nonce_payload_create();
        
-       this->logger->log(this->logger, CONTROL|MORE, "nonce payload builded");
+       nonce_payload->set_nonce(nonce_payload, this->sent_nonce);
        
-       return SUCCESS;
+       *payload = (payload_t *) nonce_payload;
 }
 
 /**
@@ -531,20 +340,13 @@ static ike_sa_state_t get_state(private_initiator_init_t *this)
 /**
  * Implements state_t.get_state
  */
-static status_t destroy(private_initiator_init_t *this)
+static void destroy(private_initiator_init_t *this)
 {
        this->logger->log(this->logger, CONTROL | MORE, "Going to destroy initiator_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)
        {
@@ -556,29 +358,19 @@ static status_t destroy(private_initiator_init_t *this)
                this->logger->log(this->logger, CONTROL | MOST, "Free memory of sent nonce");
                allocator_free(this->sent_nonce.ptr);
        }
-       
        allocator_free(this);
-       return SUCCESS;
 }
 
 /**
  * Implements private_initiator_init_t.destroy_after_state_change
  */
-static status_t destroy_after_state_change (private_initiator_init_t *this)
+static void destroy_after_state_change (private_initiator_init_t *this)
 {
        this->logger->log(this->logger, CONTROL | MORE, "Going to destroy initiator_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);
        allocator_free(this);
-       return SUCCESS;
 }
 
 /* 
@@ -587,16 +379,11 @@ static status_t destroy_after_state_change (private_initiator_init_t *this)
 initiator_init_t *initiator_init_create(protected_ike_sa_t *ike_sa)
 {
        private_initiator_init_t *this = allocator_alloc_thing(private_initiator_init_t);
-       
-       if (this == NULL)
-       {
-               return NULL;
-       }
 
        /* interface functions */
        this->public.state_interface.process_message = (status_t (*) (state_t *,message_t *)) process_message;
        this->public.state_interface.get_state = (ike_sa_state_t (*) (state_t *)) get_state;
-       this->public.state_interface.destroy  = (status_t (*) (state_t *)) destroy;
+       this->public.state_interface.destroy  = (void (*) (state_t *)) destroy;
        
        /* public functions */
        this->public.initiate_connection = (status_t (*)(initiator_init_t *, char *)) initiate_connection;
@@ -612,13 +399,7 @@ initiator_init_t *initiator_init_create(protected_ike_sa_t *ike_sa)
        this->ike_sa = ike_sa;
        this->dh_group_priority = 1;
        this->logger = this->ike_sa->get_logger(this->ike_sa);
-       this->proposals = linked_list_create();
        this->sent_nonce = CHUNK_INITIALIZER;
-       if (this->proposals == NULL)
-       {
-               allocator_free(this);
-               return NULL;
-       }
-       
+
        return &(this->public);
 }