diff options
author | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2010-02-23 10:42:46 +0000 |
---|---|---|
committer | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2010-02-23 10:42:46 +0000 |
commit | de6b12502cdf42d5d92118f1c0e38dc31becf7c5 (patch) | |
tree | 0edac9c79f5a43e01913dd7f71c7abc487e5727b /src/charon/sa/tasks/ike_init.c | |
parent | 172642669d4a23e17f1ed411fbc8629dcaa5fb46 (diff) | |
download | vyos-strongswan-de6b12502cdf42d5d92118f1c0e38dc31becf7c5.tar.gz vyos-strongswan-de6b12502cdf42d5d92118f1c0e38dc31becf7c5.zip |
Updated to new upstream release. interfaces Patch is not from upstream.
Diffstat (limited to 'src/charon/sa/tasks/ike_init.c')
-rw-r--r-- | src/charon/sa/tasks/ike_init.c | 168 |
1 files changed, 64 insertions, 104 deletions
diff --git a/src/charon/sa/tasks/ike_init.c b/src/charon/sa/tasks/ike_init.c index 2705f5886..5eb33b540 100644 --- a/src/charon/sa/tasks/ike_init.c +++ b/src/charon/sa/tasks/ike_init.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Tobias Brunner + * Copyright (C) 2008-2009 Tobias Brunner * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -24,7 +24,6 @@ #include <encoding/payloads/sa_payload.h> #include <encoding/payloads/ke_payload.h> #include <encoding/payloads/nonce_payload.h> -#include <encoding/payloads/vendor_id_payload.h> /** maximum retries to do with cookies/other dh groups */ #define MAX_RETRIES 5 @@ -35,67 +34,67 @@ typedef struct private_ike_init_t private_ike_init_t; * Private members of a ike_init_t task. */ struct private_ike_init_t { - + /** * Public methods and task_t interface. */ ike_init_t public; - + /** * Assigned IKE_SA. */ ike_sa_t *ike_sa; - + /** * Are we the initiator? */ bool initiator; - + /** * IKE config to establish */ ike_cfg_t *config; - + /** * diffie hellman group to use */ diffie_hellman_group_t dh_group; - + /** * diffie hellman key exchange */ diffie_hellman_t *dh; - + /** * Keymat derivation (from IKE_SA) */ keymat_t *keymat; - + /** * nonce chosen by us */ chunk_t my_nonce; - + /** * nonce chosen by peer */ chunk_t other_nonce; - + /** * Negotiated proposal used for IKE_SA */ proposal_t *proposal; - + /** * Old IKE_SA which gets rekeyed */ ike_sa_t *old_sa; - + /** * cookie received from responder */ chunk_t cookie; - + /** * retries done so far after failure (cookie or bad dh group) */ @@ -114,16 +113,16 @@ static void build_payloads(private_ike_init_t *this, message_t *message) ike_sa_id_t *id; proposal_t *proposal; iterator_t *iterator; - + id = this->ike_sa->get_id(this->ike_sa); - + this->config = this->ike_sa->get_ike_cfg(this->ike_sa); if (this->initiator) { proposal_list = this->config->get_proposals(this->config); if (this->old_sa) - { + { /* include SPI of new IKE_SA when we are rekeying */ iterator = proposal_list->create_iterator(proposal_list, TRUE); while (iterator->iterate(iterator, (void**)&proposal)) @@ -132,7 +131,7 @@ static void build_payloads(private_ike_init_t *this, message_t *message) } iterator->destroy(iterator); } - + sa_payload = sa_payload_create_from_proposal_list(proposal_list); proposal_list->destroy_offset(proposal_list, offsetof(proposal_t, destroy)); } @@ -146,11 +145,11 @@ static void build_payloads(private_ike_init_t *this, message_t *message) sa_payload = sa_payload_create_from_proposal(this->proposal); } message->add_payload(message, (payload_t*)sa_payload); - + nonce_payload = nonce_payload_create(); nonce_payload->set_nonce(nonce_payload, this->my_nonce); ke_payload = ke_payload_create_from_diffie_hellman(this->dh); - + if (this->old_sa) { /* payload order differs if we are rekeying */ message->add_payload(message, (payload_t*)nonce_payload); @@ -170,7 +169,7 @@ static void process_payloads(private_ike_init_t *this, message_t *message) { enumerator_t *enumerator; payload_t *payload; - + enumerator = message->create_payload_enumerator(message); while (enumerator->enumerate(enumerator, &payload)) { @@ -180,18 +179,21 @@ static void process_payloads(private_ike_init_t *this, message_t *message) { sa_payload_t *sa_payload = (sa_payload_t*)payload; linked_list_t *proposal_list; - + bool private; + proposal_list = sa_payload->get_proposals(sa_payload); + private = this->ike_sa->supports_extension(this->ike_sa, + EXT_STRONGSWAN); this->proposal = this->config->select_proposal(this->config, - proposal_list); - proposal_list->destroy_offset(proposal_list, + proposal_list, private); + proposal_list->destroy_offset(proposal_list, offsetof(proposal_t, destroy)); break; } case KEY_EXCHANGE: { ke_payload_t *ke_payload = (ke_payload_t*)payload; - + this->dh_group = ke_payload->get_dh_group_number(ke_payload); if (!this->initiator) { @@ -212,13 +214,6 @@ static void process_payloads(private_ike_init_t *this, message_t *message) this->other_nonce = nonce_payload->get_nonce(nonce_payload); break; } - case VENDOR_ID: - { - vendor_id_payload_t *vendor_id = (vendor_id_payload_t*)payload; - chunk_t vid = vendor_id->get_data(vendor_id); - - DBG1(DBG_ENC, "received vendor id: %#B", &vid); - } default: break; } @@ -232,20 +227,20 @@ static void process_payloads(private_ike_init_t *this, message_t *message) static status_t build_i(private_ike_init_t *this, message_t *message) { rng_t *rng; - + this->config = this->ike_sa->get_ike_cfg(this->ike_sa); DBG0(DBG_IKE, "initiating IKE_SA %s[%d] to %H", this->ike_sa->get_name(this->ike_sa), this->ike_sa->get_unique_id(this->ike_sa), this->ike_sa->get_other_host(this->ike_sa)); this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING); - - if (this->retry++ >= MAX_RETRIES) + + if (this->retry >= MAX_RETRIES) { DBG1(DBG_IKE, "giving up after %d retries", MAX_RETRIES); return FAILED; } - + /* if the DH group is set via use_dh_group(), we already have a DH object */ if (!this->dh) { @@ -258,7 +253,7 @@ static status_t build_i(private_ike_init_t *this, message_t *message) return FAILED; } } - + /* generate nonce only when we are trying the first time */ if (this->my_nonce.ptr == NULL) { @@ -271,12 +266,12 @@ static status_t build_i(private_ike_init_t *this, message_t *message) rng->allocate_bytes(rng, NONCE_SIZE, &this->my_nonce); rng->destroy(rng); } - + if (this->cookie.ptr) { message->add_notify(message, FALSE, COOKIE, this->cookie); } - + build_payloads(this, message); #ifdef ME @@ -288,7 +283,7 @@ static status_t build_i(private_ike_init_t *this, message_t *message) } } #endif /* ME */ - + return NEED_MORE; } @@ -296,9 +291,9 @@ static status_t build_i(private_ike_init_t *this, message_t *message) * Implementation of task_t.process for responder */ static status_t process_r(private_ike_init_t *this, message_t *message) -{ +{ rng_t *rng; - + this->config = this->ike_sa->get_ike_cfg(this->ike_sa); DBG0(DBG_IKE, "%H is initiating an IKE_SA", message->get_source(message)); this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING); @@ -311,59 +306,22 @@ static status_t process_r(private_ike_init_t *this, message_t *message) } rng->allocate_bytes(rng, NONCE_SIZE, &this->my_nonce); rng->destroy(rng); - + #ifdef ME { - chunk_t connect_id = chunk_empty; - enumerator_t *enumerator; - payload_t *payload; - - /* check for a ME_CONNECTID notify */ - enumerator = message->create_payload_enumerator(message); - while (enumerator->enumerate(enumerator, &payload)) - { - if (payload->get_type(payload) == NOTIFY) - { - notify_payload_t *notify = (notify_payload_t*)payload; - notify_type_t type = notify->get_notify_type(notify); - - switch (type) - { - case ME_CONNECTID: - { - chunk_free(&connect_id); - connect_id = chunk_clone(notify->get_notification_data(notify)); - DBG2(DBG_IKE, "received ME_CONNECTID %#B", &connect_id); - break; - } - default: - { - if (type < 16383) - { - DBG1(DBG_IKE, "received %N notify error", - notify_type_names, type); - break; - } - DBG2(DBG_IKE, "received %N notify", - notify_type_names, type); - break; - } - } - } - } - enumerator->destroy(enumerator); - - if (connect_id.ptr) + notify_payload_t *notify = message->get_notify(message, ME_CONNECTID); + if (notify) { + chunk_t connect_id = notify->get_notification_data(notify); + DBG2(DBG_IKE, "received ME_CONNECTID %#B", &connect_id); charon->connect_manager->stop_checks(charon->connect_manager, - connect_id); - chunk_free(&connect_id); + connect_id); } } #endif /* ME */ - + process_payloads(this, message); - + return NEED_MORE; } @@ -377,7 +335,7 @@ static bool derive_keys(private_ike_init_t *this, pseudo_random_function_t prf_alg = PRF_UNDEFINED; chunk_t skd = chunk_empty; ike_sa_id_t *id; - + id = this->ike_sa->get_id(this->ike_sa); if (this->old_sa) { @@ -417,12 +375,12 @@ static status_t build_r(private_ike_init_t *this, message_t *message) return FAILED; } this->ike_sa->set_proposal(this->ike_sa, this->proposal); - + if (this->dh == NULL || !this->proposal->has_dh_group(this->proposal, this->dh_group)) { u_int16_t group; - + if (this->proposal->get_algorithm(this->proposal, DIFFIE_HELLMAN_GROUP, &group, NULL)) { @@ -440,7 +398,7 @@ static status_t build_r(private_ike_init_t *this, message_t *message) } return FAILED; } - + if (!derive_keys(this, this->other_nonce, this->my_nonce)) { DBG1(DBG_IKE, "key derivation failed"); @@ -458,7 +416,7 @@ static status_t process_i(private_ike_init_t *this, message_t *message) { enumerator_t *enumerator; payload_t *payload; - + /* check for erronous notifies */ enumerator = message->create_payload_enumerator(message); while (enumerator->enumerate(enumerator, &payload)) @@ -467,27 +425,28 @@ static status_t process_i(private_ike_init_t *this, message_t *message) { notify_payload_t *notify = (notify_payload_t*)payload; notify_type_t type = notify->get_notify_type(notify); - + switch (type) { case INVALID_KE_PAYLOAD: { chunk_t data; diffie_hellman_group_t bad_group; - + bad_group = this->dh_group; data = notify->get_notification_data(notify); this->dh_group = ntohs(*((u_int16_t*)data.ptr)); DBG1(DBG_IKE, "peer didn't accept DH group %N, " "it requested %N", diffie_hellman_group_names, bad_group, diffie_hellman_group_names, this->dh_group); - + if (this->old_sa == NULL) { /* reset the IKE_SA if we are not rekeying */ this->ike_sa->reset(this->ike_sa); } - + enumerator->destroy(enumerator); + this->retry++; return NEED_MORE; } case NAT_DETECTION_SOURCE_IP: @@ -504,6 +463,7 @@ static status_t process_i(private_ike_init_t *this, message_t *message) this->ike_sa->reset(this->ike_sa); enumerator->destroy(enumerator); DBG2(DBG_IKE, "received %N notify", notify_type_names, type); + this->retry++; return NEED_MORE; } default: @@ -513,7 +473,7 @@ static status_t process_i(private_ike_init_t *this, message_t *message) DBG1(DBG_IKE, "received %N notify error", notify_type_names, type); enumerator->destroy(enumerator); - return FAILED; + return FAILED; } DBG2(DBG_IKE, "received %N notify", notify_type_names, type); @@ -523,7 +483,7 @@ static status_t process_i(private_ike_init_t *this, message_t *message) } } enumerator->destroy(enumerator); - + process_payloads(this, message); /* check if we have everything */ @@ -534,14 +494,14 @@ static status_t process_i(private_ike_init_t *this, message_t *message) return FAILED; } this->ike_sa->set_proposal(this->ike_sa, this->proposal); - + if (this->dh == NULL || !this->proposal->has_dh_group(this->proposal, this->dh_group)) { DBG1(DBG_IKE, "peer DH group selection invalid"); return FAILED; } - + if (!derive_keys(this, this->my_nonce, this->other_nonce)) { DBG1(DBG_IKE, "key derivation failed"); @@ -581,7 +541,7 @@ static void migrate(private_ike_init_t *this, ike_sa_t *ike_sa) { DESTROY_IF(this->proposal); chunk_free(&this->other_nonce); - + this->ike_sa = ike_sa; this->proposal = NULL; DESTROY_IF(this->dh); @@ -622,7 +582,7 @@ ike_init_t *ike_init_create(ike_sa_t *ike_sa, bool initiator, ike_sa_t *old_sa) this->public.task.build = (status_t(*)(task_t*,message_t*))build_r; this->public.task.process = (status_t(*)(task_t*,message_t*))process_r; } - + this->ike_sa = ike_sa; this->initiator = initiator; this->dh_group = MODP_NONE; @@ -635,6 +595,6 @@ ike_init_t *ike_init_create(ike_sa_t *ike_sa, bool initiator, ike_sa_t *old_sa) this->config = NULL; this->old_sa = old_sa; this->retry = 0; - + return &this->public; } |