From ae3012a0ea0e06e29212f1967b5b71e90460fb43 Mon Sep 17 00:00:00 2001 From: Jan Hutter Date: Fri, 2 Dec 2005 11:38:56 +0000 Subject: [PATCH] - added notify message handling to ike_sa_init_requested_t and responder_init_t --- Source/charon/encoding/message.c | 55 ++++++++++------- Source/charon/encoding/payloads/notify_payload.c | 35 ++++++++++- Source/charon/encoding/payloads/notify_payload.h | 47 +++++++++++++++ .../encoding/payloads/proposal_substructure.c | 12 ++++ .../encoding/payloads/proposal_substructure.h | 7 ++- Source/charon/sa/ike_sa.c | 26 ++++++++- Source/charon/sa/ike_sa.h | 6 ++ Source/charon/sa/states/ike_sa_init_requested.c | 68 +++++++++++++++++++++- Source/charon/sa/states/initiator_init.c | 25 ++++---- Source/charon/sa/states/responder_init.c | 67 +++++++++++++++++++-- Source/charon/threads/thread_pool.c | 14 ++++- 11 files changed, 320 insertions(+), 42 deletions(-) diff --git a/Source/charon/encoding/message.c b/Source/charon/encoding/message.c index d3b92f3..bf33c50 100644 --- a/Source/charon/encoding/message.c +++ b/Source/charon/encoding/message.c @@ -63,6 +63,11 @@ struct supported_payload_entry_t { * TRUE if payload has to get encrypted */ bool encrypted; + + /** + * Verifying can stop after checking this payload. + */ + bool can_be_last; }; typedef struct message_rule_t message_rule_t; @@ -104,9 +109,9 @@ struct message_rule_t { */ static supported_payload_entry_t supported_ike_sa_init_i_payloads[] = { - {SECURITY_ASSOCIATION,1,1,FALSE}, - {KEY_EXCHANGE,1,1,FALSE}, - {NONCE,1,1,FALSE}, + {SECURITY_ASSOCIATION,1,1,FALSE,FALSE}, + {KEY_EXCHANGE,1,1,FALSE,FALSE}, + {NONCE,1,1,FALSE,FALSE}, }; /** @@ -114,9 +119,10 @@ static supported_payload_entry_t supported_ike_sa_init_i_payloads[] = */ static supported_payload_entry_t supported_ike_sa_init_r_payloads[] = { - {SECURITY_ASSOCIATION,1,1,FALSE}, - {KEY_EXCHANGE,1,1,FALSE}, - {NONCE,1,1,FALSE}, + {NOTIFY,0,1,FALSE,TRUE}, + {SECURITY_ASSOCIATION,1,1,FALSE,FALSE}, + {KEY_EXCHANGE,1,1,FALSE,FALSE}, + {NONCE,1,1,FALSE,FALSE}, }; /** @@ -124,14 +130,14 @@ static supported_payload_entry_t supported_ike_sa_init_r_payloads[] = */ static supported_payload_entry_t supported_ike_auth_i_payloads[] = { - {ID_INITIATOR,1,1,TRUE}, - {CERTIFICATE,0,1,TRUE}, - {CERTIFICATE_REQUEST,0,1,TRUE}, - {ID_RESPONDER,0,1,TRUE}, - {AUTHENTICATION,1,1,TRUE}, - {SECURITY_ASSOCIATION,1,1,TRUE}, - {TRAFFIC_SELECTOR_INITIATOR,1,1,TRUE}, - {TRAFFIC_SELECTOR_RESPONDER,1,1,TRUE}, + {ID_INITIATOR,1,1,TRUE,FALSE}, + {CERTIFICATE,0,1,TRUE,FALSE}, + {CERTIFICATE_REQUEST,0,1,TRUE,FALSE}, + {ID_RESPONDER,0,1,TRUE,FALSE}, + {AUTHENTICATION,1,1,TRUE,FALSE}, + {SECURITY_ASSOCIATION,1,1,TRUE,FALSE}, + {TRAFFIC_SELECTOR_INITIATOR,1,1,TRUE,FALSE}, + {TRAFFIC_SELECTOR_RESPONDER,1,1,TRUE,FALSE}, }; /** @@ -139,12 +145,12 @@ static supported_payload_entry_t supported_ike_auth_i_payloads[] = */ static supported_payload_entry_t supported_ike_auth_r_payloads[] = { - {CERTIFICATE,0,1,TRUE}, - {ID_RESPONDER,0,1,TRUE}, - {AUTHENTICATION,1,1,TRUE}, - {SECURITY_ASSOCIATION,1,1,TRUE}, - {TRAFFIC_SELECTOR_INITIATOR,1,1,TRUE}, - {TRAFFIC_SELECTOR_RESPONDER,1,1,TRUE}, + {CERTIFICATE,0,1,TRUE,FALSE}, + {ID_RESPONDER,0,1,TRUE,FALSE}, + {AUTHENTICATION,1,1,TRUE,FALSE}, + {SECURITY_ASSOCIATION,1,1,TRUE,FALSE}, + {TRAFFIC_SELECTOR_INITIATOR,1,1,TRUE,FALSE}, + {TRAFFIC_SELECTOR_RESPONDER,1,1,TRUE,FALSE}, }; /** @@ -749,6 +755,7 @@ static status_t verify(private_message_t *this) status_t status; iterator_t *iterator; message_rule_t *message_rule; + size_t total_found_payloads = 0; this->logger->log(this->logger, CONTROL|MORE, "Verifying message structure"); @@ -759,7 +766,7 @@ static status_t verify(private_message_t *this) mapping_find(exchange_type_m,this->exchange_type)); return status; } - + iterator = this->payloads->create_iterator(this->payloads,TRUE); /* check for payloads with wrong count*/ for (i = 0; i < message_rule->supported_payloads_count;i++) @@ -776,6 +783,7 @@ static status_t verify(private_message_t *this) if (current_payload->get_type(current_payload) == message_rule->supported_payloads[i].payload_type) { found_payloads++; + total_found_payloads++; this->logger->log(this->logger, CONTROL | MOST, "Found payload of type %s", mapping_find(payload_type_m,message_rule->supported_payloads[i].payload_type)); @@ -798,6 +806,11 @@ static status_t verify(private_message_t *this) iterator->destroy(iterator); return NOT_SUPPORTED; } + if ((message_rule->supported_payloads[i].can_be_last) && (this->payloads->get_count(this->payloads) == total_found_payloads)) + { + iterator->destroy(iterator); + return SUCCESS; + } } iterator->destroy(iterator); diff --git a/Source/charon/encoding/payloads/notify_payload.c b/Source/charon/encoding/payloads/notify_payload.c index 31e02d2..3bbc44d 100644 --- a/Source/charon/encoding/payloads/notify_payload.c +++ b/Source/charon/encoding/payloads/notify_payload.c @@ -28,6 +28,27 @@ #include #include +/** + * String mappings for notify_message_type_t. + */ +mapping_t notify_message_type_m[] = { + {UNSUPPORTED_CRITICAL_PAYLOAD, "UNSUPPORTED_CRITICAL_PAYLOAD"}, + {INVALID_IKE_SPI, "INVALID_IKE_SPI"}, + {INVALID_MAJOR_VERSION, "INVALID_MAJOR_VERSION"}, + {INVALID_SYNTAX, "INVALID_SYNTAX"}, + {INVALID_MESSAGE_ID, "MODP_2048_BIT"}, + {INVALID_SPI, "INVALID_SPI"}, + {NO_PROPOSAL_CHOSEN, "NO_PROPOSAL_CHOSEN"}, + {INVALID_KE_PAYLOAD, "INVALID_KE_PAYLOAD"}, + {AUTHENTICATION_FAILED, "AUTHENTICATION_FAILED"}, + {SINGLE_PAIR_REQUIRED, "SINGLE_PAIR_REQUIRED"}, + {NO_ADDITIONAL_SAS, "NO_ADDITIONAL_SAS"}, + {INTERNAL_ADDRESS_FAILURE, "INTERNAL_ADDRESS_FAILURE"}, + {FAILED_CP_REQUIRED, "FAILED_CP_REQUIRED"}, + {TS_UACCEPTABLE, "TS_UACCEPTABLE"}, + {INVALID_SELECTORS, "INVALID_SELECTORS"}, + {MAPPING_END, NULL} +}; typedef struct private_notify_payload_t private_notify_payload_t; @@ -176,7 +197,7 @@ static void get_encoding_rules(private_notify_payload_t *this, encoding_rule_t * */ static payload_type_t get_type(private_notify_payload_t *this) { - return KEY_EXCHANGE; + return NOTIFY; } /** @@ -378,3 +399,15 @@ notify_payload_t *notify_payload_create() return (&(this->public)); } +/* + * Described in header. + */ +notify_payload_t *notify_payload_create_from_protocol_and_type(protocol_id_t protocol_id, notify_message_type_t notify_message_type) +{ + notify_payload_t *notify = notify_payload_create(); + + notify->set_notify_message_type(notify,notify_message_type); + notify->set_protocol_id(notify,protocol_id); + + return notify; +} diff --git a/Source/charon/encoding/payloads/notify_payload.h b/Source/charon/encoding/payloads/notify_payload.h index 19dd14e..e877e07 100644 --- a/Source/charon/encoding/payloads/notify_payload.h +++ b/Source/charon/encoding/payloads/notify_payload.h @@ -26,6 +26,7 @@ #include #include +#include #include /** @@ -42,6 +43,41 @@ */ #define NOTIFY_PAYLOAD_HEADER_LENGTH 8 +typedef enum notify_message_type_t notify_message_type_t; + + +/** + * @brief Notify message types. + * + * Ssee IKEv2 draft 3.10.1. + * + * @ingroup payloads + */ +enum notify_message_type_t { + UNSUPPORTED_CRITICAL_PAYLOAD = 1, + INVALID_IKE_SPI = 4, + INVALID_MAJOR_VERSION = 5, + INVALID_SYNTAX = 7, + INVALID_MESSAGE_ID = 9, + INVALID_SPI = 11, + NO_PROPOSAL_CHOSEN = 14, + INVALID_KE_PAYLOAD = 17, + AUTHENTICATION_FAILED = 24, + SINGLE_PAIR_REQUIRED = 34, + NO_ADDITIONAL_SAS = 35, + INTERNAL_ADDRESS_FAILURE = 36, + FAILED_CP_REQUIRED = 37, + TS_UACCEPTABLE = 38, + INVALID_SELECTORS = 39 +}; + +/** + * String mappings for notify_message_type_t. + */ +extern mapping_t notify_message_type_m[]; + + + typedef struct notify_payload_t notify_payload_t; /** @@ -147,5 +183,16 @@ struct notify_payload_t { */ notify_payload_t *notify_payload_create(); +/** + * @brief Creates an notify_payload_t object of specific type for specific protocol id. + * + * @param protocol_id protocol id (IKE, AH or ESP) + * @param notify_message_type notify type (see notify_message_type_t) + * @return created notify_payload_t object + * + * @ingroup payloads + */ +notify_payload_t *notify_payload_create_from_protocol_and_type(protocol_id_t protocol_id, notify_message_type_t notify_message_type); + #endif /*NOTIFY_PAYLOAD_H_*/ diff --git a/Source/charon/encoding/payloads/proposal_substructure.c b/Source/charon/encoding/payloads/proposal_substructure.c index 05b375e..e207e77 100644 --- a/Source/charon/encoding/payloads/proposal_substructure.c +++ b/Source/charon/encoding/payloads/proposal_substructure.c @@ -31,6 +31,18 @@ #include #include +/** + * String mappings for protocol_id_t. + */ +mapping_t protocol_id_m[] = { + {UNDEFINED_PROTOCOL_ID, "UNDEFINED_PROTOCOL_ID"}, + {IKE, "IKE"}, + {AH, "AH"}, + {ESP, "ESP"}, + {MAPPING_END, NULL} +}; + + typedef struct private_proposal_substructure_t private_proposal_substructure_t; /** diff --git a/Source/charon/encoding/payloads/proposal_substructure.h b/Source/charon/encoding/payloads/proposal_substructure.h index a2015fb..736987f 100644 --- a/Source/charon/encoding/payloads/proposal_substructure.h +++ b/Source/charon/encoding/payloads/proposal_substructure.h @@ -56,7 +56,12 @@ enum protocol_id_t { IKE = 1, AH = 2, ESP = 3, -}; +}; + +/** + * String mappings for protocol_id_t. + */ +extern mapping_t protocol_id_m[]; typedef struct proposal_substructure_t proposal_substructure_t; diff --git a/Source/charon/sa/ike_sa.c b/Source/charon/sa/ike_sa.c index 1ab5d2f..9acd891 100644 --- a/Source/charon/sa/ike_sa.c +++ b/Source/charon/sa/ike_sa.c @@ -665,9 +665,32 @@ static status_t set_last_responded_message (private_ike_sa_t *this,message_t * m return SUCCESS; } +/** + * Implementation of protected_ike_sa_t.destroy. + */ +static void reset_message_buffers (private_ike_sa_t *this) +{ + this->logger->log(this->logger, CONTROL|MOST, "Reset message counters and destroy stored messages"); + /* destroy stored requested message */ + if (this->last_requested_message != NULL) + { + this->last_requested_message->destroy(this->last_requested_message); + this->last_requested_message = NULL; + } + + /* destroy stored responded messages */ + if (this->last_responded_message != NULL) + { + this->last_responded_message->destroy(this->last_responded_message); + this->last_responded_message = NULL; + } + + this->message_id_out = 0; + this->message_id_in = 0; +} /** - * Implements protected_ike_sa_t.destroy. + * Implementation of protected_ike_sa_t.destroy. */ static void destroy (private_ike_sa_t *this) { @@ -792,6 +815,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id) this->protected.set_new_state = (void (*) (protected_ike_sa_t *,state_t *)) set_new_state; this->protected.get_crypter_initiator = (crypter_t *(*) (protected_ike_sa_t *)) get_crypter_initiator; this->protected.get_signer_initiator = (signer_t *(*) (protected_ike_sa_t *)) get_signer_initiator; + this->protected.reset_message_buffers = (void (*) (protected_ike_sa_t *)) reset_message_buffers; /* private functions */ this->resend_last_reply = resend_last_reply; diff --git a/Source/charon/sa/ike_sa.h b/Source/charon/sa/ike_sa.h index a5cf637..6fd6f0e 100644 --- a/Source/charon/sa/ike_sa.h +++ b/Source/charon/sa/ike_sa.h @@ -283,6 +283,12 @@ struct protected_ike_sa_t { */ signer_t *(*get_signer_initiator) (protected_ike_sa_t *this); + /** + * Resets message id counters and does destroy stored received and sent messages. + * + * @param this calling object + */ + void (*reset_message_buffers) (protected_ike_sa_t *this); }; diff --git a/Source/charon/sa/states/ike_sa_init_requested.c b/Source/charon/sa/states/ike_sa_init_requested.c index 756b6b9..aa12cd1 100644 --- a/Source/charon/sa/states/ike_sa_init_requested.c +++ b/Source/charon/sa/states/ike_sa_init_requested.c @@ -27,11 +27,13 @@ #include #include #include +#include #include #include #include #include #include +#include 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; diff --git a/Source/charon/sa/states/initiator_init.c b/Source/charon/sa/states/initiator_init.c index 445d507..7c63a45 100644 --- a/Source/charon/sa/states/initiator_init.c +++ b/Source/charon/sa/states/initiator_init.c @@ -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; } diff --git a/Source/charon/sa/states/responder_init.c b/Source/charon/sa/states/responder_init.c index 6734d68..ee9584e 100644 --- a/Source/charon/sa/states/responder_init.c +++ b/Source/charon/sa/states/responder_init.c @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -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 */ @@ -453,6 +472,44 @@ static ike_sa_state_t get_state(private_responder_init_t *this) } /** + * 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 */ static void destroy(private_responder_init_t *this) @@ -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); } diff --git a/Source/charon/threads/thread_pool.c b/Source/charon/threads/thread_pool.c index 661d0fd..f6f5278 100644 --- a/Source/charon/threads/thread_pool.c +++ b/Source/charon/threads/thread_pool.c @@ -182,7 +182,9 @@ static void process_incoming_packet_job(private_thread_pool_t *this, incoming_pa this->worker_logger->log(this->worker_logger, ERROR, "IKE version %d.%d not supported", message->get_major_version(message), message->get_minor_version(message)); - /* Todo send notify */ + /* + * TODO send notify reply of type INVALID_MAJOR_VERSION + */ } message->get_ike_sa_id(message, &ike_sa_id); @@ -200,16 +202,22 @@ static void process_incoming_packet_job(private_thread_pool_t *this, incoming_pa this->worker_logger->log(this->worker_logger, ERROR, "IKE SA could not be checked out"); ike_sa_id->destroy(ike_sa_id); message->destroy(message); + + /* + * TODO send notify reply of type INVALID_IKE_SPI if SPI could not be found + */ + return; } status = ike_sa->process_message(ike_sa, message); - if (status != SUCCESS) + if ((status != SUCCESS) && (status != DELETE_ME)) { this->worker_logger->log(this->worker_logger, ERROR, "message could not be processed by IKE SA"); } - this->worker_logger->log(this->worker_logger, CONTROL|MOST, "checking in IKE SA %lld:%lld, role %s", + this->worker_logger->log(this->worker_logger, CONTROL|MOST, "%s IKE SA %lld:%lld, role %s", + (status == DELETE_ME) ? "Checkin and delete" : "Checkin", ike_sa_id->get_initiator_spi(ike_sa_id), ike_sa_id->get_responder_spi(ike_sa_id), ike_sa_id->is_initiator(ike_sa_id) ? "initiator" : "responder"); -- 2.7.4