- added notify message handling to ike_sa_init_requested_t and
responder_init_t
This commit is contained in:
@@ -27,11 +27,13 @@
|
||||
#include <encoding/payloads/sa_payload.h>
|
||||
#include <encoding/payloads/ke_payload.h>
|
||||
#include <encoding/payloads/nonce_payload.h>
|
||||
#include <encoding/payloads/notify_payload.h>
|
||||
#include <encoding/payloads/id_payload.h>
|
||||
#include <encoding/payloads/auth_payload.h>
|
||||
#include <encoding/payloads/ts_payload.h>
|
||||
#include <transforms/diffie_hellman.h>
|
||||
#include <sa/states/ike_auth_requested.h>
|
||||
#include <sa/states/initiator_init.h>
|
||||
|
||||
|
||||
typedef struct private_ike_sa_init_requested_t private_ike_sa_init_requested_t;
|
||||
@@ -218,6 +220,70 @@ 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))
|
||||
{
|
||||
case NOTIFY:
|
||||
{
|
||||
notify_payload_t *notify_payload = (notify_payload_t *) payload;
|
||||
|
||||
|
||||
this->logger->log(this->logger, CONTROL|MORE, "Process notify type %s for protocol %s",
|
||||
mapping_find(notify_message_type_m, notify_payload->get_notify_message_type(notify_payload)),
|
||||
mapping_find(protocol_id_m, notify_payload->get_protocol_id(notify_payload)));
|
||||
|
||||
if (notify_payload->get_protocol_id(notify_payload) != IKE)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR | MORE, "Notify reply not for IKE protocol.");
|
||||
payloads->destroy(payloads);
|
||||
return FAILED;
|
||||
}
|
||||
switch (notify_payload->get_notify_message_type(notify_payload))
|
||||
{
|
||||
case NO_PROPOSAL_CHOSEN:
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "Peer didn't choose a proposal!!!");
|
||||
payloads->destroy(payloads);
|
||||
return DELETE_ME;
|
||||
}
|
||||
case INVALID_KE_PAYLOAD:
|
||||
{
|
||||
initiator_init_t *initiator_init_state;
|
||||
u_int16_t new_dh_group_priority;
|
||||
|
||||
this->logger->log(this->logger, ERROR, "Selected DH group is not the one in the proposal selected by the responder!");
|
||||
payloads->destroy(payloads);
|
||||
/* Going to change state back to initiator_init_t */
|
||||
this->logger->log(this->logger, CONTROL|MOST, "Create next state object");
|
||||
initiator_init_state = initiator_init_create(this->ike_sa);
|
||||
|
||||
/* buffer of sent and received messages has to get reseted */
|
||||
this->ike_sa->reset_message_buffers(this->ike_sa);
|
||||
|
||||
/* state can now be changed */
|
||||
this->ike_sa->set_new_state(this->ike_sa,(state_t *) initiator_init_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|MOST, "Destroy old sate object");
|
||||
this->logger->log(this->logger, CONTROL|MOST, "Going to retry initialization of connection");
|
||||
new_dh_group_priority = this->dh_group_priority + 1;
|
||||
|
||||
this->public.state_interface.destroy(&(this->public.state_interface));
|
||||
return (initiator_init_state->retry_initiate_connection (initiator_init_state,new_dh_group_priority));
|
||||
}
|
||||
default:
|
||||
{
|
||||
/*
|
||||
* If an unrecognized Notify type is received, the IKE_SA gets destroyed.
|
||||
*
|
||||
*/
|
||||
|
||||
this->logger->log(this->logger, ERROR, "Notify type %s not recognized in state ike_sa_init_requested.",
|
||||
mapping_find(notify_message_type_m,notify_payload->get_notify_message_type(notify_payload)));
|
||||
payloads->destroy(payloads);
|
||||
return DELETE_ME;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO check for notify of type
|
||||
*
|
||||
@@ -225,7 +291,7 @@ static status_t process_message(private_ike_sa_init_requested_t *this, message_t
|
||||
*
|
||||
* call destroy after state change not destroy_after_state_change!!!
|
||||
*/
|
||||
|
||||
}
|
||||
case SECURITY_ASSOCIATION:
|
||||
{
|
||||
sa_payload_t *sa_payload = (sa_payload_t*)payload;
|
||||
|
||||
@@ -140,7 +140,7 @@ static status_t initiate_connection (private_initiator_init_t *this, char *name)
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR | MORE, "Could not retrieve INIT configuration informations for %s",name);
|
||||
return INVALID_ARG;
|
||||
return DELETE_ME;
|
||||
}
|
||||
|
||||
this->ike_sa->set_init_config(this->ike_sa,init_config);
|
||||
@@ -150,7 +150,7 @@ static status_t initiate_connection (private_initiator_init_t *this, char *name)
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR | MORE, "Could not retrieve SA configuration informations for %s",name);
|
||||
return INVALID_ARG;
|
||||
return DELETE_ME;
|
||||
}
|
||||
|
||||
this->ike_sa->set_sa_config(this->ike_sa,sa_config);
|
||||
@@ -163,7 +163,7 @@ static status_t initiate_connection (private_initiator_init_t *this, char *name)
|
||||
if (this->dh_group_number == MODP_UNDEFINED)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR | MORE, "Diffie hellman group could not be retrieved with priority %d", this->dh_group_priority);
|
||||
return INVALID_ARG;
|
||||
return DELETE_ME;
|
||||
}
|
||||
|
||||
/* next step is done in retry_initiate_connection */
|
||||
@@ -181,14 +181,20 @@ status_t retry_initiate_connection (private_initiator_init_t *this, int dh_group
|
||||
message_t *message;
|
||||
packet_t *packet;
|
||||
status_t status;
|
||||
ike_sa_id_t *ike_sa_id;
|
||||
|
||||
this->dh_group_priority = dh_group_priority;
|
||||
|
||||
init_config = this->ike_sa->get_init_config(this->ike_sa);
|
||||
|
||||
ike_sa_id = this->ike_sa->public.get_id(&(this->ike_sa->public));
|
||||
ike_sa_id->set_responder_spi(ike_sa_id,0);
|
||||
|
||||
this->dh_group_number = init_config->get_dh_group_number(init_config,dh_group_priority);
|
||||
if (this->dh_group_number == MODP_UNDEFINED)
|
||||
{
|
||||
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->logger->log(this->logger, ERROR | MORE, "Diffie hellman group could not be retrieved with priority %d", dh_group_priority);
|
||||
return DELETE_ME;
|
||||
}
|
||||
|
||||
this->diffie_hellman = diffie_hellman_create(this->dh_group_number);
|
||||
@@ -208,7 +214,7 @@ status_t retry_initiate_connection (private_initiator_init_t *this, int dh_group
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "could not generate packet from message");
|
||||
message->destroy(message);
|
||||
return status;
|
||||
return DELETE_ME;
|
||||
}
|
||||
|
||||
this->logger->log(this->logger, CONTROL|MOST, "Add packet to global send queue");
|
||||
@@ -216,7 +222,7 @@ status_t retry_initiate_connection (private_initiator_init_t *this, int dh_group
|
||||
|
||||
/* 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);
|
||||
next_state = ike_sa_init_requested_create(this->ike_sa, this->dh_group_priority, this->diffie_hellman, this->sent_nonce);
|
||||
|
||||
/* last message can now be set */
|
||||
status = this->ike_sa->set_last_requested_message(this->ike_sa, message);
|
||||
@@ -226,7 +232,7 @@ status_t retry_initiate_connection (private_initiator_init_t *this, int dh_group
|
||||
this->logger->log(this->logger, ERROR, "Could not set last requested message");
|
||||
(next_state->state_interface).destroy(&(next_state->state_interface));
|
||||
message->destroy(message);
|
||||
return status;
|
||||
return DELETE_ME;
|
||||
}
|
||||
|
||||
/* state can now be changed */
|
||||
@@ -332,9 +338,8 @@ static void build_nonce_payload(private_initiator_init_t *this, payload_t **payl
|
||||
/**
|
||||
* Implements state_t.get_state
|
||||
*/
|
||||
static status_t process_message(private_initiator_init_t *this, message_t *message, state_t **new_state)
|
||||
static status_t process_message(private_initiator_init_t *this, message_t *message)
|
||||
{
|
||||
*new_state = (state_t *) this;
|
||||
this->logger->log(this->logger, ERROR|MORE, "In state INITIATOR_INIT no message is processed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <encoding/payloads/sa_payload.h>
|
||||
#include <encoding/payloads/ke_payload.h>
|
||||
#include <encoding/payloads/nonce_payload.h>
|
||||
#include <encoding/payloads/notify_payload.h>
|
||||
#include <transforms/diffie_hellman.h>
|
||||
|
||||
|
||||
@@ -136,6 +137,16 @@ struct private_responder_init_t {
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*destroy_after_state_change) (private_responder_init_t *this);
|
||||
|
||||
/**
|
||||
* Sends a IKE_SA_INIT reply with a notify payload.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param type type of notify message
|
||||
* @param data data of notify message
|
||||
*/
|
||||
void (*send_notify_reply) (private_responder_init_t *this,notify_message_type_t type, chunk_t data);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -230,6 +241,7 @@ 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);
|
||||
this->send_notify_reply(this,NO_PROPOSAL_CHOSEN,CHUNK_INITIALIZER);
|
||||
return DELETE_ME;
|
||||
}
|
||||
|
||||
@@ -263,11 +275,18 @@ static status_t process_message(private_responder_init_t *this, message_t *messa
|
||||
}
|
||||
if (this->dh_group_number != group)
|
||||
{
|
||||
/* group not same as selected one */
|
||||
u_int16_t accepted_group;
|
||||
chunk_t accepted_group_chunk;
|
||||
/* group not same as selected one
|
||||
* Maybe key exchange payload is before SA payload */
|
||||
this->logger->log(this->logger, ERROR | MORE, "Diffie hellman group not as in selected proposal!");
|
||||
payloads->destroy(payloads);
|
||||
|
||||
/**
|
||||
* TODO send notify reply
|
||||
*/
|
||||
accepted_group = htons(this->dh_group_number);
|
||||
accepted_group_chunk.ptr = (u_int8_t*) &(accepted_group);
|
||||
accepted_group_chunk.len = 2;
|
||||
this->send_notify_reply(this,INVALID_KE_PAYLOAD,accepted_group_chunk);
|
||||
return DELETE_ME;
|
||||
}
|
||||
|
||||
/* create diffie hellman object to handle DH exchange */
|
||||
@@ -452,6 +471,44 @@ static ike_sa_state_t get_state(private_responder_init_t *this)
|
||||
return RESPONDER_INIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of private_initiator_init_t.send_notify_reply.
|
||||
*/
|
||||
static void send_notify_reply (private_responder_init_t *this,notify_message_type_t type, chunk_t data)
|
||||
{
|
||||
notify_payload_t *payload;
|
||||
message_t *response;
|
||||
packet_t *packet;
|
||||
status_t status;
|
||||
|
||||
this->logger->log(this->logger, CONTROL|MOST, "Going to build message with notify payload");
|
||||
/* set up the reply */
|
||||
this->ike_sa->build_message(this->ike_sa, IKE_SA_INIT, FALSE, &response);
|
||||
payload = notify_payload_create_from_protocol_and_type(IKE,type);
|
||||
if ((data.ptr != NULL) && (data.len > 0))
|
||||
{
|
||||
this->logger->log(this->logger, CONTROL|MOST, "Add Data to notify payload");
|
||||
payload->set_notification_data(payload,data);
|
||||
}
|
||||
|
||||
this->logger->log(this->logger, CONTROL|MOST, "Add Notify payload to message");
|
||||
response->add_payload(response,(payload_t *) payload);
|
||||
|
||||
/* generate packet */
|
||||
this->logger->log(this->logger, CONTROL|MOST, "Gnerate packet from message");
|
||||
status = response->generate(response, NULL, NULL, &packet);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "Could not generate packet from message");
|
||||
return;
|
||||
}
|
||||
|
||||
this->logger->log(this->logger, CONTROL|MOST, "Add packet to global send queue");
|
||||
charon->send_queue->add(charon->send_queue, packet);
|
||||
this->logger->log(this->logger, CONTROL|MOST, "Destroy message");
|
||||
response->destroy(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements state_t.get_state
|
||||
*/
|
||||
@@ -509,12 +566,14 @@ responder_init_t *responder_init_create(protected_ike_sa_t *ike_sa)
|
||||
this->build_ke_payload = build_ke_payload;
|
||||
this->build_nonce_payload = build_nonce_payload;
|
||||
this->destroy_after_state_change = destroy_after_state_change;
|
||||
this->send_notify_reply = send_notify_reply;
|
||||
|
||||
/* private data */
|
||||
this->ike_sa = ike_sa;
|
||||
this->logger = this->ike_sa->get_logger(this->ike_sa);
|
||||
this->sent_nonce = CHUNK_INITIALIZER;
|
||||
this->received_nonce = CHUNK_INITIALIZER;
|
||||
this->dh_group_number = MODP_UNDEFINED;
|
||||
|
||||
return &(this->public);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user