diff options
author | Martin Willi <martin@strongswan.org> | 2006-06-08 14:20:05 +0000 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2006-06-08 14:20:05 +0000 |
commit | 5238c9afefb7783b639e154ae882cec1f8651c70 (patch) | |
tree | fa47ce291a4dcbb696b39311de7542db17a4ddfe /src | |
parent | c0d63ac9db44ae1b0161b7398bb61385a6f4ac88 (diff) | |
download | strongswan-5238c9afefb7783b639e154ae882cec1f8651c70.tar.bz2 strongswan-5238c9afefb7783b639e154ae882cec1f8651c70.tar.xz |
fixed compile warnings when using -Wall
further CHILD_SA rekeying work done:
creation of a new CHILD_SA on a expire from a kernel works
delete of old CHILD_SA still missing
some issues when both initiate rekeing
Diffstat (limited to 'src')
25 files changed, 829 insertions, 206 deletions
diff --git a/src/charon/Makefile.am b/src/charon/Makefile.am index a94a6dce4..93546c987 100644 --- a/src/charon/Makefile.am +++ b/src/charon/Makefile.am @@ -12,7 +12,7 @@ sa/states/state.c sa/states/state.h sa/states/ike_sa_init_requested.c sa/states/ sa/states/ike_sa_init_responded.c sa/states/ike_sa_established.c sa/states/ike_sa_established.h \ sa/states/responder_init.c sa/states/responder_init.h sa/states/initiator_init.c sa/states/initiator_init.h \ sa/states/ike_sa_init_responded.h sa/states/ike_auth_requested.c sa/states/ike_auth_requested.h \ -sa/states/delete_requested.h sa/states/delete_requested.c \ +sa/states/delete_ike_sa_requested.h sa/states/delete_ike_sa_requested.c \ sa/states/create_child_sa_requested.c sa/states/create_child_sa_requested.h \ sa/child_sa.c sa/child_sa.h sa/ike_sa.c sa/ike_sa.h sa/ike_sa_manager.c sa/ike_sa_manager.h \ sa/ike_sa_id.c sa/ike_sa_id.h sa/authenticator.c sa/authenticator.h encoding/payloads/encryption_payload.c \ diff --git a/src/charon/config/connections/local_connection_store.c b/src/charon/config/connections/local_connection_store.c index fa3bd555d..af0ee0879 100644 --- a/src/charon/config/connections/local_connection_store.c +++ b/src/charon/config/connections/local_connection_store.c @@ -218,7 +218,7 @@ static status_t add_connection(private_local_connection_store_t *this, connectio void log_connections(private_local_connection_store_t *this, logger_t *logger, char *name) { iterator_t *iterator; - connection_t *current, *found = NULL; + connection_t *current; if (logger == NULL) { diff --git a/src/charon/config/credentials/local_credential_store.c b/src/charon/config/credentials/local_credential_store.c index 4ab32fe62..09eac6aaa 100644 --- a/src/charon/config/credentials/local_credential_store.c +++ b/src/charon/config/credentials/local_credential_store.c @@ -185,20 +185,19 @@ static void add_certificate(private_local_credential_store_t *this, x509_t *cert static void log_certificates(private_local_credential_store_t *this, logger_t *logger, bool utc) { iterator_t *iterator = this->certs->create_iterator(this->certs, TRUE); - + if (iterator->get_count(iterator)) { logger->log(logger, CONTROL, ""); logger->log(logger, CONTROL, "List of X.509 End Entity Certificates:"); logger->log(logger, CONTROL, ""); } - + while (iterator->has_next(iterator)) { x509_t *cert; - rsa_private_key_t *key; bool has_key; - + iterator->current(iterator, (void**)&cert); has_key = has_rsa_private_key(this, cert->get_public_key(cert)); cert->log_certificate(cert, logger, utc, has_key); diff --git a/src/charon/config/policies/local_policy_store.c b/src/charon/config/policies/local_policy_store.c index 764843526..8ba65d24e 100644 --- a/src/charon/config/policies/local_policy_store.c +++ b/src/charon/config/policies/local_policy_store.c @@ -20,6 +20,8 @@ * for more details. */ +#include <string.h> + #include "local_policy_store.h" #include <utils/linked_list.h> diff --git a/src/charon/config/policies/policy.c b/src/charon/config/policies/policy.c index ac30afe74..3e5837714 100644 --- a/src/charon/config/policies/policy.c +++ b/src/charon/config/policies/policy.c @@ -20,6 +20,9 @@ * for more details. */ +#include <time.h> +#include <string.h> + #include "policy.h" #include <utils/linked_list.h> @@ -293,7 +296,8 @@ static void add_proposal(private_policy_t *this, proposal_t *proposal) */ static u_int32_t get_soft_lifetime(policy_t *this) { - return 0; /*5 + random() % 5; */ + srandom(time(NULL)); + return 0; //5 + random() % 3; } /** @@ -301,7 +305,7 @@ static u_int32_t get_soft_lifetime(policy_t *this) */ static u_int32_t get_hard_lifetime(policy_t *this) { - return 0; /*20; */ + return 0; //9; } /** diff --git a/src/charon/config/proposal.c b/src/charon/config/proposal.c index 09fa150db..0e12e6bf6 100644 --- a/src/charon/config/proposal.c +++ b/src/charon/config/proposal.c @@ -258,7 +258,6 @@ static proposal_t *select_proposal(private_proposal_t *this, private_proposal_t u_int16_t algo; size_t key_size; bool add; - u_int64_t spi; /* check protocol */ if (this->protocol != other->protocol) diff --git a/src/charon/queues/jobs/delete_established_ike_sa_job.c b/src/charon/queues/jobs/delete_established_ike_sa_job.c index 78f5c9ed1..515340da9 100644 --- a/src/charon/queues/jobs/delete_established_ike_sa_job.c +++ b/src/charon/queues/jobs/delete_established_ike_sa_job.c @@ -61,7 +61,6 @@ static job_type_t get_type(private_delete_established_ike_sa_job_t *this) */ static status_t execute(private_delete_established_ike_sa_job_t *this) { - ike_sa_t *ike_sa; status_t status; status = charon->ike_sa_manager->delete(charon->ike_sa_manager, this->ike_sa_id); diff --git a/src/charon/queues/jobs/delete_half_open_ike_sa_job.c b/src/charon/queues/jobs/delete_half_open_ike_sa_job.c index 5de3cb222..c81783446 100644 --- a/src/charon/queues/jobs/delete_half_open_ike_sa_job.c +++ b/src/charon/queues/jobs/delete_half_open_ike_sa_job.c @@ -76,7 +76,7 @@ static status_t execute(private_delete_half_open_ike_sa_job_t *this) case IKE_SA_INIT_REQUESTED: case IKE_SA_INIT_RESPONDED: case IKE_AUTH_REQUESTED: - case DELETE_REQUESTED: + case DELETE_IKE_SA_REQUESTED: { /* IKE_SA is half open and gets deleted! */ status = charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa); diff --git a/src/charon/queues/jobs/incoming_packet_job.c b/src/charon/queues/jobs/incoming_packet_job.c index 834b14bb2..6043b03ca 100644 --- a/src/charon/queues/jobs/incoming_packet_job.c +++ b/src/charon/queues/jobs/incoming_packet_job.c @@ -24,6 +24,7 @@ #include "incoming_packet_job.h" #include <daemon.h> +#include <queues/jobs/delete_half_open_ike_sa_job.h> typedef struct private_incoming_packet_job_t private_incoming_packet_job_t; diff --git a/src/charon/queues/jobs/initiate_ike_sa_job.c b/src/charon/queues/jobs/initiate_ike_sa_job.c index fa8513659..16e440768 100644 --- a/src/charon/queues/jobs/initiate_ike_sa_job.c +++ b/src/charon/queues/jobs/initiate_ike_sa_job.c @@ -26,6 +26,7 @@ #include "initiate_ike_sa_job.h" #include <daemon.h> +#include <queues/jobs/delete_half_open_ike_sa_job.h> typedef struct private_initiate_ike_sa_job_t private_initiate_ike_sa_job_t; diff --git a/src/charon/sa/child_sa.c b/src/charon/sa/child_sa.c index 2321e4696..87fcea0cb 100644 --- a/src/charon/sa/child_sa.c +++ b/src/charon/sa/child_sa.c @@ -135,7 +135,6 @@ static status_t alloc(private_child_sa_t *this, linked_list_t *proposals) iterator_t *iterator; proposal_t *proposal; status_t status; - u_int i; /* iterator through proposals */ iterator = proposals->create_iterator(proposals, TRUE); @@ -146,9 +145,9 @@ static status_t alloc(private_child_sa_t *this, linked_list_t *proposals) status = charon->kernel_interface->get_spi( charon->kernel_interface, - this->me.addr, this->other.addr, + this->other.addr, this->me.addr, protocol, FALSE, - &(this->me.spi)); + &this->me.spi); if (status != SUCCESS) { @@ -178,15 +177,15 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal, prf_plus /* we must assign the roles to correctly set up the SAs */ if (mine) - { - src = this->me.addr; - dst = this->other.addr; - } - else - { + { dst = this->me.addr; src = this->other.addr; } + else + { + src = this->me.addr; + dst = this->other.addr; + } this->protocol = proposal->get_protocol(proposal); diff --git a/src/charon/sa/ike_sa.c b/src/charon/sa/ike_sa.c index 363e2264d..bc1871317 100644 --- a/src/charon/sa/ike_sa.c +++ b/src/charon/sa/ike_sa.c @@ -42,6 +42,7 @@ #include <sa/states/initiator_init.h> #include <sa/states/responder_init.h> #include <sa/states/create_child_sa_requested.h> +#include <sa/states/delete_ike_sa_requested.h> #include <queues/jobs/retransmit_request_job.h> #include <queues/jobs/delete_established_ike_sa_job.h> #include <queues/jobs/delete_half_open_ike_sa_job.h> @@ -664,7 +665,9 @@ static status_t send_response(private_ike_sa_t *this, message_t *message) if (message->get_message_id(message) != this->message_id_in) { - this->logger->log(this->logger, ERROR, "Message could not be sent cause id was not as expected"); + + this->logger->log(this->logger, ERROR, "Message could not be sent cause id (%d) was not as expected (%d)", + message->get_message_id(message),this->message_id_in); return FAILED; } @@ -779,80 +782,6 @@ static void add_child_sa(private_ike_sa_t *this, child_sa_t *child_sa) } /** - * Process an informational request - */ -static status_t process_informational(private_ike_sa_t *this, message_t *request) -{ - delete_payload_t *delete_request = NULL; - message_t *response; - iterator_t *payloads; - state_t *old_state; - - build_message(this, INFORMATIONAL, FALSE, &response); - - payloads = request->get_payload_iterator(request); - while (payloads->has_next(payloads)) - { - payload_t *payload; - payloads->current(payloads, (void**)&payload); - - switch (payload->get_type(payload)) - { - case DELETE: - { - delete_request = (delete_payload_t *) payload; - break; - } - default: - { - this->logger->log(this->logger, ERROR|LEVEL1, "Ignoring Payload %s (%d)", - mapping_find(payload_type_m, payload->get_type(payload)), - payload->get_type(payload)); - break; - } - } - } - /* iterator can be destroyed */ - payloads->destroy(payloads); - - if (delete_request) - { - if (delete_request->get_protocol_id(delete_request) == PROTO_IKE) - { - this->logger->log(this->logger, CONTROL, "DELETE request for IKE_SA received"); - if (send_response(this, response) != SUCCESS) - { - /* something is seriously wrong, kill connection */ - this->logger->log(this->logger, AUDIT, "Unable to send reply. Deleting IKE_SA"); - response->destroy(response); - } - /* switch to delete_requested. This is not absolutly correct, but we - * allow the clean destruction of an SA only in this state. */ - old_state = this->current_state; - set_new_state(this, (state_t*)delete_requested_create(this)); - old_state->destroy(old_state); - return DESTROY_ME; - } - else - { - this->logger->log(this->logger, CONTROL, "DELETE request for CHILD_SA received. Ignored"); - response->destroy(response); - return FAILED; - } - } - return SUCCESS; -} - - -/** - * Process an informational request - */ -static status_t process_create_child_sa(private_ike_sa_t *this, message_t *request) -{ - -} - -/** * Implementation of ike_sa_t.process_message. */ static status_t process_message(private_ike_sa_t *this, message_t *message) @@ -860,9 +789,6 @@ static status_t process_message(private_ike_sa_t *this, message_t *message) u_int32_t message_id; exchange_type_t exchange_type; bool is_request; - status_t status; - crypter_t *crypter; - signer_t *signer; /* Find out type of message (request or response) */ is_request = message->get_request(message); @@ -916,60 +842,13 @@ static status_t process_message(private_ike_sa_t *this, message_t *message) } } - if (this->current_state->get_state(this->current_state) == IKE_SA_ESTABLISHED) - { - if (is_request) - { - /* get signer for verification and crypter for decryption */ - if (!this->ike_sa_id->is_initiator(this->ike_sa_id)) - { - crypter = this->crypter_initiator; - signer = this->signer_initiator; - } - else - { - crypter = this->crypter_responder; - signer = this->signer_responder; - } - - /* parse incoming message */ - status = message->parse_body(message, crypter, signer); - if (status != SUCCESS) - { - this->logger->log(this->logger, AUDIT, "%s request decryption failed. Ignoring message", - mapping_find(exchange_type_m, message->get_exchange_type(message))); - return status; - } - switch (message->get_exchange_type(message)) - { - case CREATE_CHILD_SA: - return process_create_child_sa(this, message); - case INFORMATIONAL: - return process_informational(this, message); - default: - this->logger->log(this->logger, CONTROL, - "Received a %s request, ignored", - mapping_find(exchange_type_m, exchange_type)); - } - } - else - { - this->logger->log(this->logger, ERROR|LEVEL1, - "Received an unexpected %s response, ignored", - mapping_find(exchange_type_m, exchange_type)); - } - return FAILED; - } - else - { - /* now the message is processed by the current state object. - * The specific state object is responsible to check if a message can be received in - * the state it represents. - * The current state is also responsible to change the state object to the next state - * by calling protected_ike_sa_t.set_new_state - */ - return this->current_state->process_message(this->current_state, message); - } + /* now the message is processed by the current state object. + * The specific state object is responsible to check if a message can be received in + * the state it represents. + * The current state is also responsible to change the state object to the next state + * by calling protected_ike_sa_t.set_new_state + */ + return this->current_state->process_message(this->current_state, message); } /** @@ -1033,8 +912,6 @@ static status_t rekey_child_sa(private_ike_sa_t *this, u_int32_t reqid) sa_payload_t *sa_payload; ts_payload_t *tsi_payload, *tsr_payload; nonce_payload_t *nonce_payload; - policy_t *policy; - randomizer_t *randomizer; linked_list_t *proposals; chunk_t nonce; linked_list_t *my_ts, *other_ts; @@ -1062,6 +939,11 @@ static status_t rekey_child_sa(private_ike_sa_t *this, u_int32_t reqid) request->add_payload(request, (payload_t*)notify); proposals = this->policy->get_proposals(this->policy); + child_sa = child_sa_create(this->connection->get_my_host(this->connection), + this->connection->get_other_host(this->connection), + this->policy->get_soft_lifetime(this->policy), + this->policy->get_hard_lifetime(this->policy)); + child_sa->alloc(child_sa, proposals); sa_payload = sa_payload_create_from_proposal_list(proposals); request->add_payload(request, (payload_t*)sa_payload); @@ -1076,7 +958,7 @@ static status_t rekey_child_sa(private_ike_sa_t *this, u_int32_t reqid) request->add_payload(request, (payload_t*)nonce_payload); my_ts = this->policy->get_my_traffic_selectors(this->policy); - other_ts = this->policy->get_my_traffic_selectors(this->policy); + other_ts = this->policy->get_other_traffic_selectors(this->policy); tsi_payload = ts_payload_create_from_traffic_selectors(TRUE, my_ts); tsr_payload = ts_payload_create_from_traffic_selectors(FALSE, other_ts); request->add_payload(request, (payload_t*)tsi_payload); @@ -1085,7 +967,7 @@ static status_t rekey_child_sa(private_ike_sa_t *this, u_int32_t reqid) send_request(this, request); old_state = this->current_state; - set_new_state(this, (state_t*)create_child_sa_requested_create(&this->protected, nonce)); + set_new_state(this, (state_t*)create_child_sa_requested_create(&this->protected, child_sa, nonce)); old_state->destroy(old_state); return SUCCESS; @@ -1187,7 +1069,6 @@ static status_t delete_(private_ike_sa_t *this) if (get_state(this) != IKE_SA_ESTABLISHED) { - this->logger->log(this->logger, ERROR, "Closing a not established IKE SA not allowed, aborting!"); return INVALID_STATE; } @@ -1204,9 +1085,9 @@ static status_t delete_(private_ike_sa_t *this) informational_request->destroy(informational_request); } - /* transit to state delete_requested */ + /* transit to state delete_ike_sa_requested */ old_state = this->current_state; - set_new_state(this, (state_t*)delete_requested_create(this)); + set_new_state(this, (state_t*)delete_ike_sa_requested_create(&this->protected)); old_state->destroy(old_state); /* there is no guarantee that the other peer will acknowledge the delete, diff --git a/src/charon/sa/states/create_child_sa_requested.c b/src/charon/sa/states/create_child_sa_requested.c index 2ff37983b..cb5313966 100644 --- a/src/charon/sa/states/create_child_sa_requested.c +++ b/src/charon/sa/states/create_child_sa_requested.c @@ -20,9 +20,13 @@ * for more details. */ +#include <string.h> + #include "create_child_sa_requested.h" #include <sa/child_sa.h> +#include <sa/states/delete_ike_sa_requested.h> +#include <sa/states/ike_sa_established.h> #include <encoding/payloads/ts_payload.h> #include <encoding/payloads/sa_payload.h> #include <encoding/payloads/nonce_payload.h> @@ -57,6 +61,31 @@ struct private_create_child_sa_requested_t { chunk_t nonce_r; /** + * Policy to use for new child_sa + */ + policy_t *policy; + + /** + * Proposal negotiated + */ + proposal_t *proposal; + + /** + * Negotiated list of traffic selectors for local site + */ + linked_list_t *my_ts; + + /** + * Negotiated list of traffic selectors for remote site + */ + linked_list_t *other_ts; + + /** + * Child SA to create + */ + child_sa_t *child_sa; + + /** * Assigned logger. * * Is logger of ike_sa! @@ -65,11 +94,277 @@ struct private_create_child_sa_requested_t { }; /** - * Implements state_t.get_state + * Implementation of private_create_child_sa_requested_t.process_sa_payload. */ -static status_t process_message(private_create_child_sa_requested_t *this, message_t *request) +static status_t process_sa_payload(private_create_child_sa_requested_t *this, sa_payload_t *sa_payload) { - this->logger->log(this->logger, ERROR, "NOT IMPLEMENTED"); + proposal_t *proposal, *proposal_tmp; + linked_list_t *proposal_list; + + /* get his selected proposal */ + proposal_list = sa_payload->get_proposals(sa_payload); + /* check count of proposals */ + if (proposal_list->get_count(proposal_list) == 0) + { + /* no proposal? we accept this, but no child sa is built */ + this->logger->log(this->logger, AUDIT, "CREATE_CHILD_SA reply contained no proposals. CHILD_SA not created"); + proposal_list->destroy(proposal_list); + return FAILED; + } + if (proposal_list->get_count(proposal_list) > 1) + { + this->logger->log(this->logger, AUDIT, "CREATE_CHILD_SA reply contained %d proposals. Aborting", + proposal_list->get_count(proposal_list)); + while (proposal_list->remove_last(proposal_list, (void**)&proposal) == SUCCESS) + { + proposal->destroy(proposal); + } + proposal_list->destroy(proposal_list); + return FAILED; + } + + /* we have to re-check here if other's selection is valid */ + proposal = this->policy->select_proposal(this->policy, proposal_list); + /* list not needed anymore */ + while (proposal_list->remove_last(proposal_list, (void**)&proposal_tmp) == SUCCESS) + { + proposal_tmp->destroy(proposal_tmp); + } + proposal_list->destroy(proposal_list); + /* got a match? */ + if (proposal == NULL) + { + this->logger->log(this->logger, AUDIT, "CREATE_CHILD_SA reply contained a not offered proposal. Aborting"); + return FAILED; + } + + /* apply proposal */ + this->proposal = proposal; + + return SUCCESS; +} + +/** + * Implementation of private_create_child_sa_requested_t.process_ts_payload. + */ +static status_t process_ts_payload(private_create_child_sa_requested_t *this, bool ts_initiator, ts_payload_t *ts_payload) +{ + linked_list_t *ts_received, *ts_selected; + traffic_selector_t *ts; + + /* get ts form payload */ + ts_received = ts_payload->get_traffic_selectors(ts_payload); + /* select ts depending on payload type */ + if (ts_initiator) + { + ts_selected = this->policy->select_my_traffic_selectors(this->policy, ts_received); + this->my_ts = ts_selected; + } + else + { + ts_selected = this->policy->select_other_traffic_selectors(this->policy, ts_received); + this->other_ts = ts_selected; + } + /* check if the responder selected valid proposals */ + if (ts_selected->get_count(ts_selected) != ts_received->get_count(ts_received)) + { + this->logger->log(this->logger, AUDIT, "IKE_AUTH reply contained not offered traffic selectors."); + } + + /* cleanup */ + while (ts_received->remove_last(ts_received, (void**)&ts) == SUCCESS) + { + ts->destroy(ts); + } + ts_received->destroy(ts_received); + + return SUCCESS; +} + +/** + * Implementation of private_create_child_sa_requested_t.process_nonce_payload. + */ +static status_t process_nonce_payload(private_create_child_sa_requested_t *this, nonce_payload_t *nonce_request) +{ + this->nonce_r = nonce_request->get_nonce(nonce_request); + return SUCCESS; +} + +/** + * Process a CREATE_CHILD_SA response + */ +static status_t process_message(private_create_child_sa_requested_t *this, message_t *response) +{ + ts_payload_t *tsi_request = NULL, *tsr_request = NULL; + sa_payload_t *sa_request = NULL; + nonce_payload_t *nonce_request = NULL; + ike_sa_id_t *ike_sa_id; + iterator_t *payloads; + crypter_t *crypter; + signer_t *signer; + status_t status; + chunk_t seed; + prf_plus_t *prf_plus; + + this->policy = this->ike_sa->get_policy(this->ike_sa); + if (response->get_exchange_type(response) != CREATE_CHILD_SA) + { + this->logger->log(this->logger, ERROR | LEVEL1, "Message of type %s not supported in state create_child_sa_requested", + mapping_find(exchange_type_m, response->get_exchange_type(response))); + return FAILED; + } + + if (response->get_request(response)) + { + this->logger->log(this->logger, ERROR | LEVEL1, "CREATE_CHILD_SA requests not allowed state create_child_sa_requested"); + return FAILED; + } + + /* get signer for verification and crypter for decryption */ + ike_sa_id = this->ike_sa->public.get_id(&this->ike_sa->public); + if (!ike_sa_id->is_initiator(ike_sa_id)) + { + crypter = this->ike_sa->get_crypter_initiator(this->ike_sa); + signer = this->ike_sa->get_signer_initiator(this->ike_sa); + } + else + { + crypter = this->ike_sa->get_crypter_responder(this->ike_sa); + signer = this->ike_sa->get_signer_responder(this->ike_sa); + } + + /* parse incoming message */ + status = response->parse_body(response, crypter, signer); + if (status != SUCCESS) + { + this->logger->log(this->logger, AUDIT, "CREATE_CHILD_SA r decryption failed. Ignoring message"); + return status; + } + + /* iterate over incoming payloads. Message is verified, we can be sure there are the required payloads */ + payloads = response->get_payload_iterator(response); + while (payloads->has_next(payloads)) + { + payload_t *payload; + payloads->current(payloads, (void**)&payload); + + switch (payload->get_type(payload)) + { + case SECURITY_ASSOCIATION: + { + sa_request = (sa_payload_t*)payload; + break; + } + case TRAFFIC_SELECTOR_INITIATOR: + { + tsi_request = (ts_payload_t*)payload; + break; + } + case TRAFFIC_SELECTOR_RESPONDER: + { + tsr_request = (ts_payload_t*)payload; + break; + } + case NONCE: + { + nonce_request = (nonce_payload_t*)payload; + break; + } + case NOTIFY: + { + /* TODO: handle notifys */ + break; + } + default: + { + this->logger->log(this->logger, ERROR|LEVEL1, "Ignoring payload %s (%d)", + mapping_find(payload_type_m, payload->get_type(payload)), payload->get_type(payload)); + break; + } + } + } + /* iterator can be destroyed */ + payloads->destroy(payloads); + + /* check if we have all payloads */ + if (!(sa_request && nonce_request && tsi_request && tsr_request)) + { + this->logger->log(this->logger, AUDIT, "CREATE_CHILD_SA request did not contain all required payloads. Ignored"); + return FAILED; + } + + /* add payloads to it */ + status = process_nonce_payload(this, nonce_request); + if (status != SUCCESS) + { + response->destroy(response); + return status; + } + status = process_sa_payload(this, sa_request); + if (status != SUCCESS) + { + response->destroy(response); + return status; + } + status = process_ts_payload(this, TRUE, tsi_request); + if (status != SUCCESS) + { + response->destroy(response); + return status; + } + status = process_ts_payload(this, FALSE, tsr_request); + if (status != SUCCESS) + { + response->destroy(response); + return status; + } + + /* install child SAs for AH and esp */ + if (!this->proposal) + { + this->logger->log(this->logger, CONTROL, "Proposal negotiation failed, no CHILD_SA built"); + this->child_sa->destroy(this->child_sa); + this->child_sa = NULL; + } + else if (this->my_ts->get_count(this->my_ts) == 0 || this->other_ts->get_count(this->other_ts) == 0) + { + this->logger->log(this->logger, CONTROL, "Traffic selector negotiation failed, no CHILD_SA built"); + this->child_sa->destroy(this->child_sa); + this->child_sa = NULL; + } + else + { + seed = chunk_alloc(this->nonce_i.len + this->nonce_r.len); + memcpy(seed.ptr, this->nonce_i.ptr, this->nonce_i.len); + memcpy(seed.ptr + this->nonce_i.len, this->nonce_r.ptr, this->nonce_r.len); + prf_plus = prf_plus_create(this->ike_sa->get_child_prf(this->ike_sa), seed); + + this->logger->log_chunk(this->logger, CONTROL, "Seed", seed); + chunk_free(&seed); + + status = this->child_sa->update(this->child_sa, this->proposal, prf_plus); + prf_plus->destroy(prf_plus); + if (status != SUCCESS) + { + this->logger->log(this->logger, AUDIT, "Could not install CHILD_SA! Deleting IKE_SA"); + return DESTROY_ME; + } + status = this->child_sa->add_policies(this->child_sa, this->my_ts, this->other_ts); + if (status != SUCCESS) + { + this->logger->log(this->logger, AUDIT, "Could not install CHILD_SA policy! Deleting IKE_SA"); + return DESTROY_ME; + } + this->ike_sa->add_child_sa(this->ike_sa, this->child_sa); + } + + this->ike_sa->set_last_replied_message_id(this->ike_sa, response->get_message_id(response)); + + /* create new state */ + this->ike_sa->set_new_state(this->ike_sa, (state_t*)ike_sa_established_create(this->ike_sa)); + this->public.state_interface.destroy(&this->public.state_interface); + + return SUCCESS; } /** @@ -93,7 +388,7 @@ static void destroy(private_create_child_sa_requested_t *this) /* * Described in header. */ -create_child_sa_requested_t *create_child_sa_requested_create(protected_ike_sa_t *ike_sa, chunk_t nonce_i) +create_child_sa_requested_t *create_child_sa_requested_create(protected_ike_sa_t *ike_sa, child_sa_t *child_sa, chunk_t nonce_i) { private_create_child_sa_requested_t *this = malloc_thing(private_create_child_sa_requested_t); @@ -104,6 +399,7 @@ create_child_sa_requested_t *create_child_sa_requested_create(protected_ike_sa_t /* private data */ this->ike_sa = ike_sa; + this->child_sa = child_sa; this->nonce_i = nonce_i; this->nonce_r = CHUNK_INITIALIZER; this->logger = logger_manager->get_logger(logger_manager, IKE_SA); diff --git a/src/charon/sa/states/create_child_sa_requested.h b/src/charon/sa/states/create_child_sa_requested.h index f6f8f011d..ced6273b0 100644 --- a/src/charon/sa/states/create_child_sa_requested.h +++ b/src/charon/sa/states/create_child_sa_requested.h @@ -25,6 +25,7 @@ #include <sa/states/state.h> #include <sa/ike_sa.h> +#include <sa/child_sa.h> typedef struct create_child_sa_requested_t create_child_sa_requested_t; @@ -47,11 +48,12 @@ struct create_child_sa_requested_t { * @brief Constructor of class create_child_sa_requested_t * * @param ike_sa assigned ike_sa + * @param child_sa newly created child sa to complete * @param nonce nonce sent at initialization * @return created create_child_sa_requested_t object * * @ingroup states */ -create_child_sa_requested_t *create_child_sa_requested_create(protected_ike_sa_t *ike_sa, chunk_t nonce_i); +create_child_sa_requested_t *create_child_sa_requested_create(protected_ike_sa_t *ike_sa, child_sa_t *child_sa, chunk_t nonce_i); #endif /*CREATE_CHILD_SA_REQEUSTED_H_*/ diff --git a/src/charon/sa/states/delete_requested.c b/src/charon/sa/states/delete_ike_sa_requested.c index ff6ec1d48..36e9c2fb2 100644 --- a/src/charon/sa/states/delete_requested.c +++ b/src/charon/sa/states/delete_ike_sa_requested.c @@ -1,7 +1,7 @@ /** - * @file delete_requested.c + * @file delete_ike_sa_requested.c * - * @brief Implementation of delete_requested_t. + * @brief Implementation of delete_ike_sa_requested_t. * */ @@ -20,22 +20,22 @@ * for more details. */ -#include "delete_requested.h" +#include "delete_ike_sa_requested.h" #include <daemon.h> -typedef struct private_delete_requested_t private_delete_requested_t; +typedef struct private_delete_ike_sa_requested_t private_delete_ike_sa_requested_t; /** - * Private data of a delete_requested_t object. + * Private data of a delete_ike_sa_requested_t object. */ -struct private_delete_requested_t { +struct private_delete_ike_sa_requested_t { /** * methods of the state_t interface */ - delete_requested_t public; + delete_ike_sa_requested_t public; /** * Assigned IKE_SA. @@ -51,7 +51,7 @@ struct private_delete_requested_t { /** * Implements state_t.get_state */ -static status_t process_message(private_delete_requested_t *this, message_t *message) +static status_t process_message(private_delete_ike_sa_requested_t *this, message_t *message) { ike_sa_id_t *ike_sa_id; crypter_t *crypter; @@ -86,7 +86,7 @@ static status_t process_message(private_delete_requested_t *this, message_t *mes /* anything other than information is ignored. We can an will not handle * messages such as CREATE_CHILD_SA */ this->logger->log(this->logger, ERROR | LEVEL1, - "%s messages not supported in state delete_requested. Ignored", + "%s messages not supported in state delete_ike_sa_requested. Ignored", mapping_find(exchange_type_m, message->get_exchange_type(message))); return FAILED; } @@ -130,15 +130,15 @@ static status_t process_message(private_delete_requested_t *this, message_t *mes /** * Implementation of state_t.get_state. */ -static ike_sa_state_t get_state(private_delete_requested_t *this) +static ike_sa_state_t get_state(private_delete_ike_sa_requested_t *this) { - return DELETE_REQUESTED; + return DELETE_IKE_SA_REQUESTED; } /** * Implementation of state_t.get_state */ -static void destroy(private_delete_requested_t *this) +static void destroy(private_delete_ike_sa_requested_t *this) { free(this); } @@ -146,9 +146,9 @@ static void destroy(private_delete_requested_t *this) /* * Described in header. */ -delete_requested_t *delete_requested_create(protected_ike_sa_t *ike_sa) +delete_ike_sa_requested_t *delete_ike_sa_requested_create(protected_ike_sa_t *ike_sa) { - private_delete_requested_t *this = malloc_thing(private_delete_requested_t); + private_delete_ike_sa_requested_t *this = malloc_thing(private_delete_ike_sa_requested_t); /* interface functions */ this->public.state_interface.process_message = (status_t (*) (state_t *,message_t *)) process_message; diff --git a/src/charon/sa/states/delete_requested.h b/src/charon/sa/states/delete_ike_sa_requested.h index a4c6daba0..a010a0f5b 100644 --- a/src/charon/sa/states/delete_requested.h +++ b/src/charon/sa/states/delete_ike_sa_requested.h @@ -1,7 +1,7 @@ /** - * @file delete_requested.h + * @file delete_ike_sa_requested.h * - * @brief Interface of delete_requested_t. + * @brief Interface of delete_ike_sa_requested_t. * */ @@ -20,23 +20,23 @@ * for more details. */ -#ifndef DELETE_REQUESTED_H_ -#define DELETE_REQUESTED_H_ +#ifndef DELETE_IKE_SA_REQUESTED_H_ +#define DELETE_IKE_SA_REQUESTED_H_ #include <sa/states/state.h> #include <sa/ike_sa.h> -typedef struct delete_requested_t delete_requested_t; +typedef struct delete_ike_sa_requested_t delete_ike_sa_requested_t; /** * @brief This class represents an the state of a half closed IKE_SA. * * @b Constructors: - * - delete_requested_create() + * - delete_ike_sa_requested_create() * * @ingroup states */ -struct delete_requested_t { +struct delete_ike_sa_requested_t { /** * methods of the state_t interface */ @@ -45,13 +45,13 @@ struct delete_requested_t { }; /** - * @brief Constructor of class delete_requested_t + * @brief Constructor of class delete_ike_sa_requested_t * * @param ike_sa assigned ike_sa - * @return created delete_requested_t object + * @return created delete_ike_sa_requested_t object * * @ingroup states */ -delete_requested_t *delete_requested_create(protected_ike_sa_t *ike_sa); +delete_ike_sa_requested_t *delete_ike_sa_requested_create(protected_ike_sa_t *ike_sa); -#endif /*DELETE_REQUESTED_H_*/ +#endif /*DELETE_IKE_SA_REQUESTED_H_*/ diff --git a/src/charon/sa/states/ike_auth_requested.c b/src/charon/sa/states/ike_auth_requested.c index 5e5fcda19..1cbec5b52 100644 --- a/src/charon/sa/states/ike_auth_requested.c +++ b/src/charon/sa/states/ike_auth_requested.c @@ -379,7 +379,6 @@ static status_t process_message(private_ike_auth_requested_t *this, message_t *i static status_t process_idr_payload(private_ike_auth_requested_t *this, id_payload_t *idr_payload) { identification_t *other_id, *configured_other_id; - connection_t *connection; other_id = idr_payload->get_identification(idr_payload); configured_other_id = this->policy->get_other_id(this->policy); diff --git a/src/charon/sa/states/ike_sa_established.c b/src/charon/sa/states/ike_sa_established.c index acbbb3781..d408988d0 100644 --- a/src/charon/sa/states/ike_sa_established.c +++ b/src/charon/sa/states/ike_sa_established.c @@ -19,11 +19,18 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ - + +#include <string.h> + #include "ike_sa_established.h" #include <daemon.h> #include <encoding/payloads/delete_payload.h> +#include <encoding/payloads/sa_payload.h> +#include <encoding/payloads/ts_payload.h> +#include <encoding/payloads/nonce_payload.h> +#include <sa/child_sa.h> +#include <sa/states/delete_ike_sa_requested.h> typedef struct private_ike_sa_established_t private_ike_sa_established_t; @@ -42,19 +49,438 @@ struct private_ike_sa_established_t { */ protected_ike_sa_t *ike_sa; + /** + * Nonce for a new child SA, chosen by initiator + */ + chunk_t nonce_i; + + /** + * Nonce for a new child SA, chosen by responder + */ + chunk_t nonce_r; + + /** + * Traffic selectors for a new child SA, responder side + */ + linked_list_t *my_ts; + + /** + * Traffic selectors for a new child SA, initiator side + */ + linked_list_t *other_ts; + + /** + * Newly set up child sa + */ + child_sa_t *child_sa; + /** * Assigned logger. Use logger of IKE_SA. */ logger_t *logger; }; +/** + * Implementation of private_ike_sa_established_t.build_sa_payload. + */ +static status_t build_sa_payload(private_ike_sa_established_t *this, sa_payload_t *request, message_t *response) +{ + proposal_t *proposal, *proposal_tmp; + linked_list_t *proposal_list; + sa_payload_t *sa_response; + chunk_t seed; + prf_plus_t *prf_plus; + status_t status; + connection_t *connection; + policy_t *policy; + + /* prepare reply */ + sa_response = sa_payload_create(); + + /* get proposals from request, and select one with ours */ + policy = this->ike_sa->get_policy(this->ike_sa); + proposal_list = request->get_proposals(request); + this->logger->log(this->logger, CONTROL|LEVEL1, "Selecting proposals:"); + proposal = policy->select_proposal(policy, proposal_list); + /* list is not needed anymore */ + while (proposal_list->remove_last(proposal_list, (void**)&proposal_tmp) == SUCCESS) + { + proposal_tmp->destroy(proposal_tmp); + } + proposal_list->destroy(proposal_list); + /* do we have a proposal? */ + if (proposal == NULL) + { + notify_payload_t *notify; + this->logger->log(this->logger, AUDIT, "CREATE_CHILD_SA request did not contain any proposals we accept. " + "Adding NO_PROPOSAL_CHOSEN notify"); + /* add NO_PROPOSAL_CHOSEN and an empty SA payload */ + notify = notify_payload_create_from_protocol_and_type(PROTO_IKE, NO_PROPOSAL_CHOSEN); + response->add_payload(response, (payload_t*)notify); + } + else + { + /* set up child sa */ + seed = chunk_alloc(this->nonce_i.len + this->nonce_r.len); + memcpy(seed.ptr, this->nonce_i.ptr, this->nonce_i.len); + memcpy(seed.ptr + this->nonce_i.len, this->nonce_r.ptr, this->nonce_r.len); + prf_plus = prf_plus_create(this->ike_sa->get_child_prf(this->ike_sa), seed); + this->logger->log_chunk(this->logger, CONTROL, "Seed", seed); + chunk_free(&seed); + + policy = this->ike_sa->get_policy(this->ike_sa); + connection = this->ike_sa->get_connection(this->ike_sa); + this->child_sa = child_sa_create(connection->get_my_host(connection), + connection->get_other_host(connection), + policy->get_soft_lifetime(policy), + policy->get_hard_lifetime(policy)); + + status = this->child_sa->add(this->child_sa, proposal, prf_plus); + prf_plus->destroy(prf_plus); + if (status != SUCCESS) + { + this->logger->log(this->logger, AUDIT, "Could not install CHILD_SA!"); + sa_response->destroy(sa_response); + proposal->destroy(proposal); + return DESTROY_ME; + } + + /* add proposal to sa payload */ + sa_response->add_proposal(sa_response, proposal); + proposal->destroy(proposal); + } + response->add_payload(response, (payload_t*)sa_response); + return SUCCESS; +} /** - * Implements state_t.get_state + * Implementation of private_ike_sa_established_t.build_ts_payload. */ -static status_t process_message(private_ike_sa_established_t *this, message_t *message) +static status_t build_ts_payload(private_ike_sa_established_t *this, bool ts_initiator, ts_payload_t *request, message_t* response) +{ + linked_list_t *ts_received, *ts_selected; + traffic_selector_t *ts; + status_t status = SUCCESS; + ts_payload_t *ts_response; + policy_t *policy; + + policy = this->ike_sa->get_policy(this->ike_sa); + + /* build a reply payload with selected traffic selectors */ + ts_received = request->get_traffic_selectors(request); + /* select ts depending on payload type */ + if (ts_initiator) + { + ts_selected = policy->select_other_traffic_selectors(policy, ts_received); + this->other_ts = ts_selected; + } + else + { + ts_selected = policy->select_my_traffic_selectors(policy, ts_received); + this->my_ts = ts_selected; + } + + ts_response = ts_payload_create_from_traffic_selectors(ts_initiator, ts_selected); + response->add_payload(response, (payload_t*)ts_response); + + /* add notify if traffic selectors do not match */ + if (!ts_initiator && + (ts_selected->get_count(ts_selected) == 0 || this->other_ts->get_count(this->other_ts) == 0)) + { + notify_payload_t *notify; + + this->logger->log(this->logger, AUDIT, "IKE_AUTH request did not contain any traffic selectors we accept. " + "Adding TS_UNACCEPTABLE notify"); + + notify = notify_payload_create_from_protocol_and_type(0, TS_UNACCEPTABLE); + response->add_payload(response, (payload_t*)notify); + } + + /* cleanup */ + while (ts_received->remove_last(ts_received, (void**)&ts) == SUCCESS) + { + ts->destroy(ts); + } + ts_received->destroy(ts_received); + + return status; +} + +/** + * Implementation of private_ike_sa_established_t.build_nonce_payload. + */ +static status_t build_nonce_payload(private_ike_sa_established_t *this, nonce_payload_t *nonce_request, message_t *response) { + nonce_payload_t *nonce_payload; + randomizer_t *randomizer; + status_t status; + + this->nonce_i = nonce_request->get_nonce(nonce_request); + + randomizer = this->ike_sa->get_randomizer(this->ike_sa); + status = randomizer->allocate_pseudo_random_bytes(randomizer, NONCE_SIZE, &this->nonce_r); + if (status != SUCCESS) + { + return status; + } + + nonce_payload = nonce_payload_create(); + nonce_payload->set_nonce(nonce_payload, this->nonce_r); + + response->add_payload(response,(payload_t *) nonce_payload); + + return SUCCESS; +} + +/** + * Process a CREATE_CHILD_SA request + */ +static status_t process_create_child_sa(private_ike_sa_established_t *this, message_t *request, message_t *response) +{ + ts_payload_t *tsi_request = NULL, *tsr_request = NULL; + sa_payload_t *sa_request = NULL; + nonce_payload_t *nonce_request = NULL; + iterator_t *payloads; + status_t status; + + /* iterate over incoming payloads. Message is verified, we can be sure there are the required payloads */ + payloads = request->get_payload_iterator(request); + while (payloads->has_next(payloads)) + { + payload_t *payload; + payloads->current(payloads, (void**)&payload); + + switch (payload->get_type(payload)) + { + case SECURITY_ASSOCIATION: + { + sa_request = (sa_payload_t*)payload; + break; + } + case TRAFFIC_SELECTOR_INITIATOR: + { + tsi_request = (ts_payload_t*)payload; + break; + } + case TRAFFIC_SELECTOR_RESPONDER: + { + tsr_request = (ts_payload_t*)payload; + break; + } + case NONCE: + { + nonce_request = (nonce_payload_t*)payload; + break; + } + case NOTIFY: + { + /* TODO: handle notifys */ + break; + } + default: + { + this->logger->log(this->logger, ERROR|LEVEL1, "Ignoring payload %s (%d)", + mapping_find(payload_type_m, payload->get_type(payload)), payload->get_type(payload)); + break; + } + } + } + /* iterator can be destroyed */ + payloads->destroy(payloads); + + /* check if we have all payloads */ + if (!(sa_request && nonce_request && tsi_request && tsr_request)) + { + this->logger->log(this->logger, AUDIT, "CREATE_CHILD_SA request did not contain all required payloads. Ignored"); + return FAILED; + } + + /* build response */ + this->ike_sa->build_message(this->ike_sa, CREATE_CHILD_SA, FALSE, &response); + + /* add payloads to it */ + status = build_nonce_payload(this, nonce_request, response); + if (status != SUCCESS) + { + response->destroy(response); + return status; + } + status = build_sa_payload(this, sa_request, response); + if (status != SUCCESS) + { + response->destroy(response); + return status; + } + status = build_ts_payload(this, TRUE, tsi_request, response); + if (status != SUCCESS) + { + response->destroy(response); + return status; + } + status = build_ts_payload(this, FALSE, tsr_request, response); + if (status != SUCCESS) + { + response->destroy(response); + return status; + } + + status = this->ike_sa->send_response(this->ike_sa, response); + /* message can now be sent (must not be destroyed) */ + if (status != SUCCESS) + { + this->logger->log(this->logger, AUDIT, "Unable to send CREATE_CHILD_SA reply. Ignored"); + response->destroy(response); + return FAILED; + } + + /* install child SA policies */ + if (!this->child_sa) + { + this->logger->log(this->logger, ERROR, "Proposal negotiation failed, no CHILD_SA built"); + } + else if (this->my_ts->get_count(this->my_ts) == 0 || this->other_ts->get_count(this->other_ts) == 0) + { + this->logger->log(this->logger, ERROR, "Traffic selector negotiation failed, no CHILD_SA built"); + this->child_sa->destroy(this->child_sa); + this->child_sa = NULL; + } + else + { + status = this->child_sa->add_policies(this->child_sa, this->my_ts, this->other_ts); + if (status != SUCCESS) + { + this->logger->log(this->logger, AUDIT, "Could not install CHILD_SA policy!"); + } + this->ike_sa->add_child_sa(this->ike_sa, this->child_sa); + } + + return SUCCESS; +} + +/** + * Process an informational request + */ +static status_t process_informational(private_ike_sa_established_t *this, message_t *request, message_t *response) +{ + delete_payload_t *delete_request = NULL; + iterator_t *payloads = request->get_payload_iterator(request); + + while (payloads->has_next(payloads)) + { + payload_t *payload; + payloads->current(payloads, (void**)&payload); + + switch (payload->get_type(payload)) + { + case DELETE: + { + delete_request = (delete_payload_t *) payload; + break; + } + default: + { + this->logger->log(this->logger, ERROR|LEVEL1, "Ignoring Payload %s (%d)", + mapping_find(payload_type_m, payload->get_type(payload)), + payload->get_type(payload)); + break; + } + } + } + /* iterator can be destroyed */ + payloads->destroy(payloads); + + if (delete_request) + { + if (delete_request->get_protocol_id(delete_request) == PROTO_IKE) + { + this->logger->log(this->logger, CONTROL, "DELETE request for IKE_SA received"); + /* switch to delete_ike_sa_requested. This is not absolutly correct, but we + * allow the clean destruction of an SA only in this state. */ + this->ike_sa->set_new_state(this->ike_sa, (state_t*)delete_ike_sa_requested_create(this->ike_sa)); + this->public.state_interface.destroy(&(this->public.state_interface)); + return DESTROY_ME; + } + else + { + this->logger->log(this->logger, CONTROL, "DELETE request for CHILD_SA received. Ignored"); + return SUCCESS; + } + } + + if (this->ike_sa->send_response(this->ike_sa, response) != SUCCESS) + { + /* something is seriously wrong, kill connection */ + this->logger->log(this->logger, AUDIT, "Unable to send reply. Deleting IKE_SA"); + response->destroy(response); + return DESTROY_ME; + } + return SUCCESS; +} + +/** + * Implements state_t.process_message + */ +static status_t process_message(private_ike_sa_established_t *this, message_t *message) +{ + ike_sa_id_t *ike_sa_id; + message_t *response; + crypter_t *crypter; + signer_t *signer; + status_t status; + + /* only requests are allowed, responses are handled in other state */ + if (!message->get_request(message)) + { + this->logger->log(this->logger, ERROR|LEVEL1, + "Response not handled in state ike_sa_established"); + return FAILED; + } + + /* get signer for verification and crypter for decryption */ + ike_sa_id = this->ike_sa->public.get_id(&this->ike_sa->public); + if (!ike_sa_id->is_initiator(ike_sa_id)) + { + crypter = this->ike_sa->get_crypter_initiator(this->ike_sa); + signer = this->ike_sa->get_signer_initiator(this->ike_sa); + } + else + { + crypter = this->ike_sa->get_crypter_responder(this->ike_sa); + signer = this->ike_sa->get_signer_responder(this->ike_sa); + } + + /* parse incoming message */ + status = message->parse_body(message, crypter, signer); + if (status != SUCCESS) + { + this->logger->log(this->logger, AUDIT, "%s request decryption failed. Ignoring message", + mapping_find(exchange_type_m, message->get_exchange_type(message))); + return status; + } + + /* prepare a reply of the same type */ + this->ike_sa->build_message(this->ike_sa, message->get_exchange_type(message), FALSE, &response); + + /* handle the different message types in their functions */ + switch (message->get_exchange_type(message)) + { + case INFORMATIONAL: + status = process_informational(this, message, response); + break; + case CREATE_CHILD_SA: + status = process_create_child_sa(this, message, response); + break; + default: + this->logger->log(this->logger, ERROR | LEVEL1, + "Message of type %s not supported in state ike_sa_established", + mapping_find(exchange_type_m, message->get_exchange_type(message))); + status = NOT_SUPPORTED; + } + /* clean up private members */ + chunk_free(&this->nonce_i); + chunk_free(&this->nonce_r); + return status; } /** @@ -88,6 +514,8 @@ ike_sa_established_t *ike_sa_established_create(protected_ike_sa_t *ike_sa) /* private data */ this->ike_sa = ike_sa; this->logger = logger_manager->get_logger(logger_manager, IKE_SA); + this->nonce_i = CHUNK_INITIALIZER; + this->nonce_r = CHUNK_INITIALIZER; return &(this->public); } diff --git a/src/charon/sa/states/state.c b/src/charon/sa/states/state.c index b91c6cfe1..e79d33e03 100644 --- a/src/charon/sa/states/state.c +++ b/src/charon/sa/states/state.c @@ -33,7 +33,8 @@ mapping_t ike_sa_state_m[] = { {IKE_SA_INIT_RESPONDED, "IKE_SA_INIT_RESPONDED"}, {IKE_AUTH_REQUESTED, "IKE_AUTH_REQUESTED"}, {IKE_SA_ESTABLISHED, "IKE_SA_ESTABLISHED"}, - {DELETE_REQUESTED, "DELETE_REQUESTED"}, + {DELETE_IKE_SA_REQUESTED, "DELETE_IKE_SA_REQUESTED"}, {CREATE_CHILD_SA_REQUESTED, "CREATE_CHILD_SA_REQUESTED"}, + {DELETE_CHILD_SA_REQUESTED, "DELETE_CHILD_SA_REQUESTED"}, {MAPPING_END, NULL} }; diff --git a/src/charon/sa/states/state.h b/src/charon/sa/states/state.h index 77193e7cf..e1cd490fa 100644 --- a/src/charon/sa/states/state.h +++ b/src/charon/sa/states/state.h @@ -97,6 +97,20 @@ enum ike_sa_state_t { IKE_SA_ESTABLISHED, /** + * @brief A rekeying/create CHILD_SA request was sent. + * + * Implemented in class create_child_sa_requested. + */ + CREATE_CHILD_SA_REQUESTED, + + /** + * @brief A delete CHILD_SA request was sent. + * + * Implemented in class delete_child_sa_requested. + */ + DELETE_CHILD_SA_REQUESTED, + + /** * @brief An IKE SA has sent a DELETE IKE_SA to the other peer. * * After a call to ike_sa.close(), the IKE_SA sends a delete message @@ -105,9 +119,7 @@ enum ike_sa_state_t { * * Implemented in class delete_requested. */ - DELETE_REQUESTED, - - CREATE_CHILD_SA_REQUESTED, + DELETE_IKE_SA_REQUESTED, }; diff --git a/src/charon/testing/Makefile.am b/src/charon/testing/Makefile.am index e34b8291a..6648fbb92 100644 --- a/src/charon/testing/Makefile.am +++ b/src/charon/testing/Makefile.am @@ -19,7 +19,7 @@ $(top_srcdir)/src/charon/connection.o $(top_srcdir)/src/charon/local_connection_ $(top_srcdir)/src/charon/local_policy_store.o $(top_srcdir)/src/charon/local_credential_store.o $(top_srcdir)/src/charon/traffic_selector.o \ $(top_srcdir)/src/charon/proposal.o $(top_srcdir)/src/charon/configuration.o $(top_srcdir)/src/charon/state.o $(top_srcdir)/src/charon/ike_sa_init_requested.o \ $(top_srcdir)/src/charon/ike_sa_init_responded.o $(top_srcdir)/src/charon/ike_sa_established.o $(top_srcdir)/src/charon/responder_init.o \ -$(top_srcdir)/src/charon/initiator_init.o $(top_srcdir)/src/charon/ike_auth_requested.o $(top_srcdir)/src/charon/delete_requested.o \ +$(top_srcdir)/src/charon/initiator_init.o $(top_srcdir)/src/charon/ike_auth_requested.o $(top_srcdir)/src/charon/delete_ike_sa_requested.o \ $(top_srcdir)/src/charon/child_sa.o $(top_srcdir)/src/charon/ike_sa.o $(top_srcdir)/src/charon/ike_sa_manager.o $(top_srcdir)/src/charon/ike_sa_id.o \ $(top_srcdir)/src/charon/authenticator.o $(top_srcdir)/src/charon/encryption_payload.o $(top_srcdir)/src/charon/cert_payload.o \ $(top_srcdir)/src/charon/traffic_selector_substructure.o $(top_srcdir)/src/charon/transform_attribute.o $(top_srcdir)/src/charon/configuration_attribute.o \ diff --git a/src/charon/testing/generator_test.c b/src/charon/testing/generator_test.c index 8ce7cf5b7..38f4c364b 100644 --- a/src/charon/testing/generator_test.c +++ b/src/charon/testing/generator_test.c @@ -695,7 +695,7 @@ void test_generator_with_notify_payload(protected_tester_t *tester) notify_payload_t *notify_payload; logger_t *logger; chunk_t generated_data; - chunk_t spi,notification_data; + chunk_t notification_data; logger = logger_manager->get_logger(logger_manager,TESTER); @@ -710,7 +710,7 @@ void test_generator_with_notify_payload(protected_tester_t *tester) notify_payload->set_protocol_id(notify_payload,255); notify_payload->set_notify_message_type(notify_payload,63333); /* Hex F765 */ - notify_payload->set_spi(notify_payload, 0x3132333435); + notify_payload->set_spi(notify_payload, 0x3132333435ll); notify_payload->set_notification_data(notify_payload,notification_data); generator->generate_payload(generator,(payload_t *)notify_payload); diff --git a/src/charon/testing/kernel_interface_test.c b/src/charon/testing/kernel_interface_test.c index cf01b0297..29b3dc34e 100644 --- a/src/charon/testing/kernel_interface_test.c +++ b/src/charon/testing/kernel_interface_test.c @@ -20,7 +20,8 @@ * for more details. */ - +#include <unistd.h> + #include "kernel_interface_test.h" #include <daemon.h> diff --git a/src/charon/threads/kernel_interface.c b/src/charon/threads/kernel_interface.c index f0844ee5f..41dee48a6 100644 --- a/src/charon/threads/kernel_interface.c +++ b/src/charon/threads/kernel_interface.c @@ -360,7 +360,7 @@ static status_t add_sa( private_kernel_interface_t *this, } else if (response->e.error) { - this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_NEWSA got error %s", + this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_NEWSA received error: %s", strerror(-response->e.error)); status = FAILED; } @@ -438,9 +438,8 @@ static status_t add_policy(private_kernel_interface_t *this, request.policy.sel.proto = upper_proto; request.policy.sel.family = src->get_family(src); - request.hdr.nlmsg_type = XFRM_MSG_NEWPOLICY; + request.hdr.nlmsg_type = XFRM_MSG_UPDPOLICY; request.hdr.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(request.policy))); - request.policy.dir = direction; request.policy.priority = SPD_PRIORITY; request.policy.action = XFRM_POLICY_ALLOW; @@ -502,7 +501,7 @@ static status_t add_policy(private_kernel_interface_t *this, } else if (response->e.error) { - this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_NEWPOLICY got error %s", + this->logger->log(this->logger, ERROR, "netlink request XFRM_MSG_NEWPOLICY received error: %s", strerror(-response->e.error)); status = FAILED; } diff --git a/src/charon/threads/stroke_interface.c b/src/charon/threads/stroke_interface.c index 00d3d3b27..a0e0112b4 100755 --- a/src/charon/threads/stroke_interface.c +++ b/src/charon/threads/stroke_interface.c @@ -470,7 +470,7 @@ static void stroke_status(private_stroke_t *this, stroke_msg_t *msg) */ static void stroke_list(private_stroke_t *this, stroke_msg_t *msg, bool utc) { - if (msg->type = STR_LIST_CERTS) + if (msg->type == STR_LIST_CERTS) { charon->credentials->log_certificates(charon->credentials, this->stroke_logger, utc); charon->credentials->log_ca_certificates(charon->credentials, this->stroke_logger, utc); |