diff options
Diffstat (limited to 'src/charon/sa/tasks')
-rw-r--r-- | src/charon/sa/tasks/child_create.c | 223 | ||||
-rw-r--r-- | src/charon/sa/tasks/child_delete.c | 21 | ||||
-rw-r--r-- | src/charon/sa/tasks/child_rekey.c | 28 | ||||
-rw-r--r-- | src/charon/sa/tasks/ike_auth.c | 108 | ||||
-rw-r--r-- | src/charon/sa/tasks/ike_auth_lifetime.c | 7 | ||||
-rw-r--r-- | src/charon/sa/tasks/ike_delete.c | 41 | ||||
-rw-r--r-- | src/charon/sa/tasks/ike_init.c | 160 | ||||
-rw-r--r-- | src/charon/sa/tasks/ike_me.c | 10 | ||||
-rw-r--r-- | src/charon/sa/tasks/ike_mobike.c | 16 | ||||
-rw-r--r-- | src/charon/sa/tasks/ike_reauth.c | 11 | ||||
-rw-r--r-- | src/charon/sa/tasks/ike_rekey.c | 65 | ||||
-rw-r--r-- | src/charon/sa/tasks/task.c | 25 |
12 files changed, 378 insertions, 337 deletions
diff --git a/src/charon/sa/tasks/child_create.c b/src/charon/sa/tasks/child_create.c index bddca621b..767ceef55 100644 --- a/src/charon/sa/tasks/child_create.c +++ b/src/charon/sa/tasks/child_create.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2008 Tobias Brunner - * Copyright (C) 2005-2007 Martin Willi + * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -14,7 +14,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * $Id: child_create.c 4358 2008-09-25 13:56:23Z tobias $ + * $Id: child_create.c 4618 2008-11-11 09:22:00Z tobias $ */ #include "child_create.h" @@ -97,6 +97,11 @@ struct private_child_create_t { diffie_hellman_group_t dh_group; /** + * IKE_SAs keymat + */ + keymat_t *keymat; + + /** * mode the new CHILD_SA uses (transport/tunnel/beet) */ ipsec_mode_t mode; @@ -191,38 +196,22 @@ static bool ts_list_is_host(linked_list_t *list, host_t *host) */ static status_t select_and_install(private_child_create_t *this, bool no_dh) { - prf_plus_t *prf_plus; status_t status; - chunk_t nonce_i, nonce_r, secret, seed; + chunk_t nonce_i, nonce_r, encr_i, integ_i, encr_r, integ_r; linked_list_t *my_ts, *other_ts; host_t *me, *other, *other_vip, *my_vip; if (this->proposals == NULL) { - SIG_CHD(UP_FAILED, this->child_sa, "SA payload missing in message"); + DBG1(DBG_IKE, "SA payload missing in message"); return FAILED; } if (this->tsi == NULL || this->tsr == NULL) { - SIG_CHD(UP_FAILED, this->child_sa, "TS payloads missing in message"); + DBG1(DBG_IKE, "TS payloads missing in message"); return NOT_FOUND; } - if (this->initiator) - { - nonce_i = this->my_nonce; - nonce_r = this->other_nonce; - my_ts = this->tsi; - other_ts = this->tsr; - } - else - { - nonce_r = this->my_nonce; - nonce_i = this->other_nonce; - my_ts = this->tsr; - other_ts = this->tsi; - } - me = this->ike_sa->get_my_host(this->ike_sa); other = this->ike_sa->get_other_host(this->ike_sa); my_vip = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE); @@ -232,7 +221,7 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh) no_dh); if (this->proposal == NULL) { - SIG_CHD(UP_FAILED, this->child_sa, "no acceptable proposal found"); + DBG1(DBG_IKE, "no acceptable proposal found"); return FAILED; } @@ -243,15 +232,15 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh) if (this->proposal->get_algorithm(this->proposal, DIFFIE_HELLMAN_GROUP, &group, NULL)) { - SIG_CHD(UP_FAILED, this->child_sa, "DH group %N inacceptable, " - "requesting %N", diffie_hellman_group_names, this->dh_group, - diffie_hellman_group_names, group); + DBG1(DBG_IKE, "DH group %N inacceptable, requesting %N", + diffie_hellman_group_names, this->dh_group, + diffie_hellman_group_names, group); this->dh_group = group; return INVALID_ARG; } else { - SIG_CHD(UP_FAILED, this->child_sa, "no acceptable proposal found"); + DBG1(DBG_IKE, "no acceptable proposal found"); return FAILED; } } @@ -260,16 +249,25 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh) { my_vip = me; } - else if (this->initiator) - { - /* to setup firewall rules correctly, CHILD_SA needs the virtual IP */ - this->child_sa->set_virtual_ip(this->child_sa, my_vip); - } if (other_vip == NULL) { other_vip = other; } + if (this->initiator) + { + nonce_i = this->my_nonce; + nonce_r = this->other_nonce; + my_ts = this->tsi; + other_ts = this->tsr; + } + else + { + nonce_r = this->my_nonce; + nonce_i = this->other_nonce; + my_ts = this->tsr; + other_ts = this->tsi; + } my_ts = this->config->get_traffic_selectors(this->config, TRUE, my_ts, my_vip); other_ts = this->config->get_traffic_selectors(this->config, FALSE, other_ts, @@ -279,7 +277,7 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh) { my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy)); other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy)); - SIG_CHD(UP_FAILED, this->child_sa, "no acceptable traffic selectors found"); + DBG1(DBG_IKE, "no acceptable traffic selectors found"); return NOT_FOUND; } @@ -302,16 +300,18 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh) switch (this->mode) { case MODE_TRANSPORT: - if (!ts_list_is_host(this->tsi, other) || - !ts_list_is_host(this->tsr, me)) + if (!this->config->use_proxy_mode(this->config) && + (!ts_list_is_host(this->tsi, other) || + !ts_list_is_host(this->tsr, me)) + ) { this->mode = MODE_TUNNEL; - DBG1(DBG_IKE, "not using tranport mode, not host-to-host"); + DBG1(DBG_IKE, "not using transport mode, not host-to-host"); } else if (this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY)) { this->mode = MODE_TUNNEL; - DBG1(DBG_IKE, "not using tranport mode, connection NATed"); + DBG1(DBG_IKE, "not using transport mode, connection NATed"); } break; case MODE_BEET: @@ -327,55 +327,51 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh) } } - if (this->dh) + this->child_sa->set_state(this->child_sa, CHILD_INSTALLING); + + if (this->ipcomp != IPCOMP_NONE) { - if (this->dh->get_shared_secret(this->dh, &secret) != SUCCESS) - { - SIG_CHD(UP_FAILED, this->child_sa, "DH exchange incomplete"); - return FAILED; - } - DBG3(DBG_IKE, "DH secret %B", &secret); - seed = chunk_cata("mcc", secret, nonce_i, nonce_r); + this->child_sa->activate_ipcomp(this->child_sa, this->ipcomp, + this->other_cpi); } - else + + status = FAILED; + if (this->keymat->derive_child_keys(this->keymat, this->proposal, + this->dh, nonce_i, nonce_r, &encr_i, &integ_i, &encr_r, &integ_r)) { - seed = chunk_cata("cc", nonce_i, nonce_r); + if (this->initiator) + { + status = this->child_sa->update(this->child_sa, this->proposal, + this->mode, integ_r, integ_i, encr_r, encr_i); + } + else + { + status = this->child_sa->add(this->child_sa, this->proposal, + this->mode, integ_i, integ_r, encr_i, encr_r); + } } + chunk_clear(&integ_i); + chunk_clear(&integ_r); + chunk_clear(&encr_i); + chunk_clear(&encr_r); - if (this->ipcomp != IPCOMP_NONE) + if (status != SUCCESS) { - this->child_sa->activate_ipcomp(this->child_sa, this->ipcomp, - this->other_cpi); + DBG1(DBG_IKE, "unable to install IPsec SA (SAD) in kernel"); + return FAILED; } status = this->child_sa->add_policies(this->child_sa, my_ts, other_ts, this->mode, this->proposal->get_protocol(this->proposal)); if (status != SUCCESS) { - SIG_CHD(UP_FAILED, this->child_sa, - "unable to install IPsec policies (SPD) in kernel"); + DBG1(DBG_IKE, "unable to install IPsec policies (SPD) in kernel"); return NOT_FOUND; } - prf_plus = prf_plus_create(this->ike_sa->get_child_prf(this->ike_sa), seed); - if (this->initiator) - { - status = this->child_sa->update(this->child_sa, this->proposal, - this->mode, prf_plus); - } - else - { - status = this->child_sa->add(this->child_sa, this->proposal, - this->mode, prf_plus); - } - prf_plus->destroy(prf_plus); + charon->bus->child_keys(charon->bus, this->child_sa, this->dh, + nonce_i, nonce_r); - if (status != SUCCESS) - { - SIG_CHD(UP_FAILED, this->child_sa, - "unable to install IPsec SA (SAD) in kernel"); - return FAILED; - } /* add to IKE_SA, and remove from task */ this->child_sa->set_state(this->child_sa, CHILD_INSTALLED); this->ike_sa->add_child_sa(this->ike_sa, this->child_sa); @@ -499,7 +495,7 @@ static void process_payloads(private_child_create_t *this, message_t *message) if (!this->initiator) { this->dh_group = ke_payload->get_dh_group_number(ke_payload); - this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group); + this->dh = this->keymat->create_dh(this->keymat, this->dh_group); } if (this->dh) { @@ -592,13 +588,13 @@ static status_t build_i(private_child_create_t *this, message_t *message) if (this->reqid) { - SIG_CHD(UP_START, NULL, "establishing CHILD_SA %s{%d}", - this->config->get_name(this->config), this->reqid); + DBG0(DBG_IKE, "establishing CHILD_SA %s{%d}", + this->config->get_name(this->config), this->reqid); } else { - SIG_CHD(UP_START, NULL, "establishing CHILD_SA %s", - this->config->get_name(this->config)); + DBG0(DBG_IKE, "establishing CHILD_SA %s", + this->config->get_name(this->config)); } /* reuse virtual IP if we already have one */ @@ -641,23 +637,19 @@ static status_t build_i(private_child_create_t *this, message_t *message) this->dh_group == MODP_NONE); this->mode = this->config->get_mode(this->config); - this->child_sa = child_sa_create( - this->ike_sa->get_my_host(this->ike_sa), - this->ike_sa->get_other_host(this->ike_sa), - this->ike_sa->get_my_id(this->ike_sa), - this->ike_sa->get_other_id(this->ike_sa), this->config, this->reqid, + this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa), + this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid, this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY)); if (this->child_sa->alloc(this->child_sa, this->proposals) != SUCCESS) { - SIG_CHD(UP_FAILED, this->child_sa, - "unable to allocate SPIs from kernel"); + DBG1(DBG_IKE, "unable to allocate SPIs from kernel"); return FAILED; } if (this->dh_group != MODP_NONE) { - this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group); + this->dh = this->keymat->create_dh(this->keymat, this->dh_group); } if (this->config->use_ipcomp(this->config)) { @@ -679,7 +671,7 @@ static status_t build_i(private_child_create_t *this, message_t *message) } /** - * Implementation of task_t.process for initiator + * Implementation of task_t.process for responder */ static status_t process_r(private_child_create_t *this, message_t *message) { @@ -785,16 +777,15 @@ static status_t build_r(private_child_create_t *this, message_t *message) if (this->ike_sa->get_state(this->ike_sa) == IKE_REKEYING) { - SIG_CHD(UP_FAILED, NULL, - "unable to create CHILD_SA while rekeying IKE_SA"); + DBG1(DBG_IKE, "unable to create CHILD_SA while rekeying IKE_SA"); message->add_notify(message, TRUE, NO_ADDITIONAL_SAS, chunk_empty); return SUCCESS; } if (this->config == NULL) { - SIG_CHD(UP_FAILED, NULL, "traffic selectors %#R=== %#R inacceptable", - this->tsr, this->tsi); + DBG1(DBG_IKE, "traffic selectors %#R=== %#R inacceptable", + this->tsr, this->tsi); message->add_notify(message, FALSE, TS_UNACCEPTABLE, chunk_empty); handle_child_sa_failure(this, message); return SUCCESS; @@ -813,8 +804,8 @@ static status_t build_r(private_child_create_t *this, message_t *message) case INTERNAL_ADDRESS_FAILURE: case FAILED_CP_REQUIRED: { - SIG_CHD(UP_FAILED, NULL, "configuration payload negotation " - "failed, no CHILD_SA built"); + DBG1(DBG_IKE,"configuration payload negotation " + "failed, no CHILD_SA built"); iterator->destroy(iterator); handle_child_sa_failure(this, message); return SUCCESS; @@ -826,11 +817,8 @@ static status_t build_r(private_child_create_t *this, message_t *message) } iterator->destroy(iterator); - this->child_sa = child_sa_create( - this->ike_sa->get_my_host(this->ike_sa), - this->ike_sa->get_other_host(this->ike_sa), - this->ike_sa->get_my_id(this->ike_sa), - this->ike_sa->get_other_id(this->ike_sa), this->config, this->reqid, + this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa), + this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid, this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY)); if (this->config->use_ipcomp(this->config) && @@ -870,14 +858,14 @@ static status_t build_r(private_child_create_t *this, message_t *message) build_payloads(this, message); - SIG_CHD(UP_SUCCESS, this->child_sa, "CHILD_SA %s{%d} established " - "with SPIs %.8x_i %.8x_o and TS %#R=== %#R", - this->child_sa->get_name(this->child_sa), - this->child_sa->get_reqid(this->child_sa), - ntohl(this->child_sa->get_spi(this->child_sa, TRUE)), - ntohl(this->child_sa->get_spi(this->child_sa, FALSE)), - this->child_sa->get_traffic_selectors(this->child_sa, TRUE), - this->child_sa->get_traffic_selectors(this->child_sa, FALSE)); + DBG0(DBG_IKE, "CHILD_SA %s{%d} established " + "with SPIs %.8x_i %.8x_o and TS %#R=== %#R", + this->child_sa->get_name(this->child_sa), + this->child_sa->get_reqid(this->child_sa), + ntohl(this->child_sa->get_spi(this->child_sa, TRUE)), + ntohl(this->child_sa->get_spi(this->child_sa, FALSE)), + this->child_sa->get_traffic_selectors(this->child_sa, TRUE), + this->child_sa->get_traffic_selectors(this->child_sa, FALSE)); return SUCCESS; } @@ -929,8 +917,8 @@ static status_t process_i(private_child_create_t *this, message_t *message) case TS_UNACCEPTABLE: case INVALID_SELECTORS: { - SIG_CHD(UP_FAILED, this->child_sa, "received %N notify, " - "no CHILD_SA built", notify_type_names, type); + DBG1(DBG_IKE, "received %N notify, no CHILD_SA built", + notify_type_names, type); iterator->destroy(iterator); handle_child_sa_failure(this, message); /* an error in CHILD_SA creation is not critical */ @@ -963,35 +951,35 @@ static status_t process_i(private_child_create_t *this, message_t *message) if (this->ipcomp == IPCOMP_NONE && this->ipcomp_received != IPCOMP_NONE) { - SIG_CHD(UP_FAILED, this->child_sa, "received an IPCOMP_SUPPORTED notify" - " but we did not send one previously, no CHILD_SA built"); + DBG1(DBG_IKE, "received an IPCOMP_SUPPORTED notify without requesting" + " one, no CHILD_SA built"); handle_child_sa_failure(this, message); return SUCCESS; } else if (this->ipcomp != IPCOMP_NONE && this->ipcomp_received == IPCOMP_NONE) { DBG1(DBG_IKE, "peer didn't accept our proposed IPComp transforms, " - "IPComp is disabled"); + "IPComp is disabled"); this->ipcomp = IPCOMP_NONE; } else if (this->ipcomp != IPCOMP_NONE && this->ipcomp != this->ipcomp_received) { - SIG_CHD(UP_FAILED, this->child_sa, "received an IPCOMP_SUPPORTED notify" - " for a transform we did not propose, no CHILD_SA built"); + DBG1(DBG_IKE, "received an IPCOMP_SUPPORTED notify we didn't propose, " + "no CHILD_SA built"); handle_child_sa_failure(this, message); return SUCCESS; } if (select_and_install(this, no_dh) == SUCCESS) { - SIG_CHD(UP_SUCCESS, this->child_sa, "CHILD_SA %s{%d} established " - "with SPIs %.8x_i %.8x_o and TS %#R=== %#R", - this->child_sa->get_name(this->child_sa), - this->child_sa->get_reqid(this->child_sa), - ntohl(this->child_sa->get_spi(this->child_sa, TRUE)), - ntohl(this->child_sa->get_spi(this->child_sa, FALSE)), - this->child_sa->get_traffic_selectors(this->child_sa, TRUE), - this->child_sa->get_traffic_selectors(this->child_sa, FALSE)); + DBG0(DBG_IKE, "CHILD_SA %s{%d} established " + "with SPIs %.8x_i %.8x_o and TS %#R=== %#R", + this->child_sa->get_name(this->child_sa), + this->child_sa->get_reqid(this->child_sa), + ntohl(this->child_sa->get_spi(this->child_sa, TRUE)), + ntohl(this->child_sa->get_spi(this->child_sa, FALSE)), + this->child_sa->get_traffic_selectors(this->child_sa, TRUE), + this->child_sa->get_traffic_selectors(this->child_sa, FALSE)); } else { @@ -1144,6 +1132,7 @@ child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config) this->tsr = NULL; this->dh = NULL; this->dh_group = MODP_NONE; + this->keymat = ike_sa->get_keymat(ike_sa); this->child_sa = NULL; this->mode = MODE_TUNNEL; this->ipcomp = IPCOMP_NONE; diff --git a/src/charon/sa/tasks/child_delete.c b/src/charon/sa/tasks/child_delete.c index a3c74dc90..cab1d63f0 100644 --- a/src/charon/sa/tasks/child_delete.c +++ b/src/charon/sa/tasks/child_delete.c @@ -12,7 +12,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * $Id: child_delete.c 4366 2008-10-03 16:01:14Z martin $ + * $Id: child_delete.c 4434 2008-10-14 08:52:13Z martin $ */ #include "child_delete.h" @@ -222,14 +222,13 @@ static void log_children(private_child_delete_t *this) iterator = this->child_sas->create_iterator(this->child_sas, TRUE); while (iterator->iterate(iterator, (void**)&child_sa)) { - SIG_CHD(DOWN_START, child_sa, "closing CHILD_SA %s{%d} " - "with SPIs %.8x_i %.8x_o and TS %#R=== %#R", - child_sa->get_name(child_sa), - child_sa->get_reqid(child_sa), - ntohl(child_sa->get_spi(child_sa, TRUE)), - ntohl(child_sa->get_spi(child_sa, FALSE)), - child_sa->get_traffic_selectors(child_sa, TRUE), - child_sa->get_traffic_selectors(child_sa, FALSE)); + DBG0(DBG_IKE, "closing CHILD_SA %s{%d} " + "with SPIs %.8x_i %.8x_o and TS %#R=== %#R", + child_sa->get_name(child_sa), child_sa->get_reqid(child_sa), + ntohl(child_sa->get_spi(child_sa, TRUE)), + ntohl(child_sa->get_spi(child_sa, FALSE)), + child_sa->get_traffic_selectors(child_sa, TRUE), + child_sa->get_traffic_selectors(child_sa, FALSE)); } iterator->destroy(iterator); } @@ -254,7 +253,7 @@ static status_t process_i(private_child_delete_t *this, message_t *message) this->child_sas = linked_list_create(); process_payloads(this, message); - SIG_CHD(DOWN_SUCCESS, NULL, "CHILD_SA closed"); + DBG1(DBG_IKE, "CHILD_SA closed"); return destroy_and_reestablish(this); } @@ -278,7 +277,7 @@ static status_t build_r(private_child_delete_t *this, message_t *message) { build_payloads(this, message); } - SIG_CHD(DOWN_SUCCESS, NULL, "CHILD_SA closed"); + DBG1(DBG_IKE, "CHILD_SA closed"); return destroy_and_reestablish(this); } diff --git a/src/charon/sa/tasks/child_rekey.c b/src/charon/sa/tasks/child_rekey.c index 3953951a3..e50ad33be 100644 --- a/src/charon/sa/tasks/child_rekey.c +++ b/src/charon/sa/tasks/child_rekey.c @@ -13,7 +13,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * $Id: child_rekey.c 3589 2008-03-13 14:14:44Z martin $ + * $Id: child_rekey.c 4659 2008-11-14 14:05:47Z martin $ */ #include "child_rekey.h" @@ -23,6 +23,7 @@ #include <sa/tasks/child_create.h> #include <sa/tasks/child_delete.h> #include <processing/jobs/rekey_child_sa_job.h> +#include <processing/jobs/rekey_ike_sa_job.h> typedef struct private_child_rekey_t private_child_rekey_t; @@ -177,6 +178,31 @@ static status_t process_i(private_child_rekey_t *this, message_t *message) protocol_id_t protocol; u_int32_t spi; child_sa_t *to_delete; + iterator_t *iterator; + payload_t *payload; + + /* handle NO_ADDITIONAL_SAS notify */ + iterator = message->get_payload_iterator(message); + while (iterator->iterate(iterator, (void**)&payload)) + { + if (payload->get_type(payload) == NOTIFY) + { + notify_payload_t *notify = (notify_payload_t*)payload; + + if (notify->get_notify_type(notify) == NO_ADDITIONAL_SAS) + { + DBG1(DBG_IKE, "peer seems to not support CHILD_SA rekeying, " + "starting reauthentication"); + this->child_sa->set_state(this->child_sa, CHILD_INSTALLED); + charon->processor->queue_job(charon->processor, + (job_t*)rekey_ike_sa_job_create( + this->ike_sa->get_id(this->ike_sa), TRUE)); + iterator->destroy(iterator); + return SUCCESS; + } + } + } + iterator->destroy(iterator); if (this->child_create->task.process(&this->child_create->task, message) == NEED_MORE) { diff --git a/src/charon/sa/tasks/ike_auth.c b/src/charon/sa/tasks/ike_auth.c index 51f37f1b0..5c3f33cbd 100644 --- a/src/charon/sa/tasks/ike_auth.c +++ b/src/charon/sa/tasks/ike_auth.c @@ -13,7 +13,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details * - * $Id: ike_auth.c 4276 2008-08-22 10:44:51Z martin $ + * $Id: ike_auth.c 4463 2008-10-20 11:38:16Z martin $ */ #include "ike_auth.h" @@ -146,6 +146,8 @@ static bool check_uniqueness(private_ike_auth_t *this) charon->ike_sa_manager->checkin(charon->ike_sa_manager, duplicate); } } + /* set threads active IKE_SA after checkin */ + charon->bus->set_sa(charon->bus, this->ike_sa); return cancel; } @@ -201,15 +203,15 @@ static status_t build_auth(private_ike_auth_t *this, message_t *message) config = this->ike_sa->get_peer_cfg(this->ike_sa); if (!config) { - SIG_IKE(UP_FAILED, "unable to authenticate, no peer config found"); + DBG1(DBG_IKE, "unable to authenticate, no peer config found"); return FAILED; } auth = authenticator_create_from_class(this->ike_sa, get_auth_class(config)); if (auth == NULL) { - SIG_IKE(UP_FAILED, "configured authentication class %N not supported", - auth_class_names, get_auth_class(config)); + DBG1(DBG_IKE, "configured authentication class %N not supported", + auth_class_names, get_auth_class(config)); return FAILED; } @@ -218,7 +220,7 @@ static status_t build_auth(private_ike_auth_t *this, message_t *message) auth->destroy(auth); if (status != SUCCESS) { - SIG_IKE(UP_FAILED, "generating authentication data failed"); + DBG1(DBG_IKE, "generating authentication data failed"); return FAILED; } message->add_payload(message, (payload_t*)auth_payload); @@ -243,7 +245,7 @@ static status_t build_id(private_ike_auth_t *this, message_t *message) me = config->get_my_id(config); if (me->contains_wildcards(me)) { - SIG_IKE(UP_FAILED, "negotiation of own ID failed"); + DBG1(DBG_IKE, "negotiation of own ID failed"); return FAILED; } this->ike_sa->set_my_id(this->ike_sa, me->clone(me)); @@ -284,8 +286,8 @@ static status_t process_auth(private_ike_auth_t *this, message_t *message) auth_payload->get_auth_method(auth_payload)); if (auth == NULL) { - SIG_IKE(UP_FAILED, "authentication method %N used by '%D' not " - "supported", auth_method_names, auth_method, + DBG1(DBG_IKE, "authentication method %N used by '%D' not supported", + auth_method_names, auth_method, this->ike_sa->get_other_id(this->ike_sa)); return NOT_SUPPORTED; } @@ -294,7 +296,7 @@ static status_t process_auth(private_ike_auth_t *this, message_t *message) auth->destroy(auth); if (status != SUCCESS) { - SIG_IKE(UP_FAILED, "authentication of '%D' with %N failed", + DBG0(DBG_IKE, "authentication of '%D' with %N failed", this->ike_sa->get_other_id(this->ike_sa), auth_method_names, auth_method); return FAILED; @@ -315,7 +317,7 @@ static status_t process_id(private_ike_auth_t *this, message_t *message) if ((this->initiator && idr == NULL) || (!this->initiator && idi == NULL)) { - SIG_IKE(UP_FAILED, "ID payload missing in message"); + DBG1(DBG_IKE, "ID payload missing in message"); return FAILED; } @@ -325,7 +327,7 @@ static status_t process_id(private_ike_auth_t *this, message_t *message) req = this->ike_sa->get_other_id(this->ike_sa); if (!id->matches(id, req)) { - SIG_IKE(UP_FAILED, "peer ID '%D' unacceptable, '%D' required", id, req); + DBG0(DBG_IKE, "peer ID '%D' unacceptable, '%D' required", id, req); id->destroy(id); return FAILED; } @@ -402,7 +404,7 @@ static status_t build_auth_eap(private_ike_auth_t *this, message_t *message) if (auth->build(auth, this->my_packet->get_data(this->my_packet), this->other_nonce, &auth_payload) != SUCCESS) { - SIG_IKE(UP_FAILED, "generating authentication data failed"); + DBG1(DBG_IKE, "generating authentication data failed"); if (!this->initiator) { message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty); @@ -413,13 +415,13 @@ static status_t build_auth_eap(private_ike_auth_t *this, message_t *message) if (!this->initiator) { this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED); - SIG_IKE(UP_SUCCESS, "IKE_SA %s[%d] established between %H[%D]...%H[%D]", - this->ike_sa->get_name(this->ike_sa), - this->ike_sa->get_unique_id(this->ike_sa), - this->ike_sa->get_my_host(this->ike_sa), - this->ike_sa->get_my_id(this->ike_sa), - this->ike_sa->get_other_host(this->ike_sa), - this->ike_sa->get_other_id(this->ike_sa)); + DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%D]...%H[%D]", + this->ike_sa->get_name(this->ike_sa), + this->ike_sa->get_unique_id(this->ike_sa), + this->ike_sa->get_my_host(this->ike_sa), + this->ike_sa->get_my_id(this->ike_sa), + this->ike_sa->get_other_host(this->ike_sa), + this->ike_sa->get_other_id(this->ike_sa)); return SUCCESS; } return NEED_MORE; @@ -448,7 +450,7 @@ static status_t process_auth_eap(private_ike_auth_t *this, message_t *message) if (!this->peer_authenticated) { - SIG_IKE(UP_FAILED, "authentication of '%D' with %N failed", + DBG0(DBG_IKE, "authentication of '%D' with %N failed", this->ike_sa->get_other_id(this->ike_sa), auth_class_names, AUTH_CLASS_EAP); if (this->initiator) @@ -460,13 +462,13 @@ static status_t process_auth_eap(private_ike_auth_t *this, message_t *message) if (this->initiator) { this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED); - SIG_IKE(UP_SUCCESS, "IKE_SA %s[%d] established between %H[%D]...%H[%D]", - this->ike_sa->get_name(this->ike_sa), - this->ike_sa->get_unique_id(this->ike_sa), - this->ike_sa->get_my_host(this->ike_sa), - this->ike_sa->get_my_id(this->ike_sa), - this->ike_sa->get_other_host(this->ike_sa), - this->ike_sa->get_other_id(this->ike_sa)); + DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%D]...%H[%D]", + this->ike_sa->get_name(this->ike_sa), + this->ike_sa->get_unique_id(this->ike_sa), + this->ike_sa->get_my_host(this->ike_sa), + this->ike_sa->get_my_id(this->ike_sa), + this->ike_sa->get_other_host(this->ike_sa), + this->ike_sa->get_other_id(this->ike_sa)); return SUCCESS; } return NEED_MORE; @@ -482,7 +484,7 @@ static status_t process_eap_i(private_ike_auth_t *this, message_t *message) eap = (eap_payload_t*)message->get_payload(message, EXTENSIBLE_AUTHENTICATION); if (eap == NULL) { - SIG_IKE(UP_FAILED, "EAP payload missing"); + DBG1(DBG_IKE, "EAP payload missing"); return FAILED; } switch (this->eap_auth->process(this->eap_auth, eap, &eap)) @@ -498,7 +500,7 @@ static status_t process_eap_i(private_ike_auth_t *this, message_t *message) return NEED_MORE; default: this->eap_payload = NULL; - SIG_IKE(UP_FAILED, "failed to authenticate against '%D' using EAP", + DBG0(DBG_IKE, "failed to authenticate against '%D' using EAP", this->ike_sa->get_other_id(this->ike_sa)); return FAILED; } @@ -533,7 +535,7 @@ static status_t build_eap_r(private_ike_auth_t *this, message_t *message) if (this->eap_payload == NULL) { - SIG_IKE(UP_FAILED, "EAP payload missing"); + DBG1(DBG_IKE, "EAP payload missing"); return FAILED; } @@ -548,9 +550,9 @@ static status_t build_eap_r(private_ike_auth_t *this, message_t *message) this->public.task.process = (status_t(*)(task_t*,message_t*))process_auth_eap; break; default: - SIG_IKE(UP_FAILED, "authentication of '%D' with %N failed", - this->ike_sa->get_other_id(this->ike_sa), - auth_class_names, AUTH_CLASS_EAP); + DBG0(DBG_IKE, "authentication of '%D' with %N failed", + this->ike_sa->get_other_id(this->ike_sa), + auth_class_names, AUTH_CLASS_EAP); status = FAILED; break; } @@ -665,9 +667,9 @@ static status_t build_r(private_ike_auth_t *this, message_t *message) config = this->ike_sa->get_peer_cfg(this->ike_sa); if (config == NULL) { - SIG_IKE(UP_FAILED, "no matching config found for '%D'...'%D'", - this->ike_sa->get_my_id(this->ike_sa), - this->ike_sa->get_other_id(this->ike_sa)); + DBG1(DBG_IKE, "no matching config found for '%D'...'%D'", + this->ike_sa->get_my_id(this->ike_sa), + this->ike_sa->get_other_id(this->ike_sa)); message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty); return FAILED; } @@ -689,13 +691,13 @@ static status_t build_r(private_ike_auth_t *this, message_t *message) if (this->peer_authenticated) { this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED); - SIG_IKE(UP_SUCCESS, "IKE_SA %s[%d] established between %H[%D]...%H[%D]", - this->ike_sa->get_name(this->ike_sa), - this->ike_sa->get_unique_id(this->ike_sa), - this->ike_sa->get_my_host(this->ike_sa), - this->ike_sa->get_my_id(this->ike_sa), - this->ike_sa->get_other_host(this->ike_sa), - this->ike_sa->get_other_id(this->ike_sa)); + DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%D]...%H[%D]", + this->ike_sa->get_name(this->ike_sa), + this->ike_sa->get_unique_id(this->ike_sa), + this->ike_sa->get_my_host(this->ike_sa), + this->ike_sa->get_my_id(this->ike_sa), + this->ike_sa->get_other_host(this->ike_sa), + this->ike_sa->get_other_id(this->ike_sa)); return SUCCESS; } @@ -706,7 +708,7 @@ static status_t build_r(private_ike_auth_t *this, message_t *message) message->add_payload(message, (payload_t*)eap_payload); if (status != NEED_MORE) { - SIG_IKE(UP_FAILED, "unable to initiate EAP authentication"); + DBG1(DBG_IKE, "unable to initiate EAP authentication"); return FAILED; } @@ -766,7 +768,7 @@ static status_t process_i(private_ike_auth_t *this, message_t *message) { if (type < 16383) { - SIG_IKE(UP_FAILED, "received %N notify error", + DBG1(DBG_IKE, "received %N notify error", notify_type_names, type); iterator->destroy(iterator); return FAILED; @@ -798,18 +800,18 @@ static status_t process_i(private_ike_auth_t *this, message_t *message) auth = this->ike_sa->get_other_auth(this->ike_sa); if (!auth->complies(auth, config->get_auth(config))) { - SIG_IKE(UP_FAILED, "authorization of '%D' for config %s failed", + DBG0(DBG_IKE, "authorization of '%D' for config %s failed", this->ike_sa->get_other_id(this->ike_sa), config->get_name(config)); return FAILED; } this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED); - SIG_IKE(UP_SUCCESS, "IKE_SA %s[%d] established between %H[%D]...%H[%D]", - this->ike_sa->get_name(this->ike_sa), - this->ike_sa->get_unique_id(this->ike_sa), - this->ike_sa->get_my_host(this->ike_sa), - this->ike_sa->get_my_id(this->ike_sa), - this->ike_sa->get_other_host(this->ike_sa), - this->ike_sa->get_other_id(this->ike_sa)); + DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%D]...%H[%D]", + this->ike_sa->get_name(this->ike_sa), + this->ike_sa->get_unique_id(this->ike_sa), + this->ike_sa->get_my_host(this->ike_sa), + this->ike_sa->get_my_id(this->ike_sa), + this->ike_sa->get_other_host(this->ike_sa), + this->ike_sa->get_other_id(this->ike_sa)); return SUCCESS; } diff --git a/src/charon/sa/tasks/ike_auth_lifetime.c b/src/charon/sa/tasks/ike_auth_lifetime.c index 2d18c6a1e..cb17cc2dc 100644 --- a/src/charon/sa/tasks/ike_auth_lifetime.c +++ b/src/charon/sa/tasks/ike_auth_lifetime.c @@ -12,11 +12,13 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * $Id: ike_auth_lifetime.c 3589 2008-03-13 14:14:44Z martin $ + * $Id: ike_auth_lifetime.c 4576 2008-11-05 08:32:38Z martin $ */ #include "ike_auth_lifetime.h" +#include <time.h> + #include <daemon.h> #include <encoding/payloads/notify_payload.h> @@ -47,9 +49,10 @@ static void add_auth_lifetime(private_ike_auth_lifetime_t *this, message_t *mess chunk_t chunk; u_int32_t lifetime; - lifetime = this->ike_sa->get_statistic(this->ike_sa, STAT_REAUTH_TIME); + lifetime = this->ike_sa->get_statistic(this->ike_sa, STAT_REAUTH); if (lifetime) { + lifetime -= time(NULL); chunk = chunk_from_thing(lifetime); *(u_int32_t*)chunk.ptr = htonl(lifetime); message->add_notify(message, FALSE, AUTH_LIFETIME, chunk); diff --git a/src/charon/sa/tasks/ike_delete.c b/src/charon/sa/tasks/ike_delete.c index 295f908cb..1c051853c 100644 --- a/src/charon/sa/tasks/ike_delete.c +++ b/src/charon/sa/tasks/ike_delete.c @@ -12,7 +12,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * $Id: ike_delete.c 4211 2008-07-23 18:46:34Z andreas $ + * $Id: ike_delete.c 4458 2008-10-17 03:44:06Z andreas $ */ #include "ike_delete.h" @@ -56,21 +56,21 @@ static status_t build_i(private_ike_delete_t *this, message_t *message) { delete_payload_t *delete_payload; - SIG_IKE(DOWN_START, "deleting IKE_SA %s[%d] between %H[%D]...%H[%D]", - this->ike_sa->get_name(this->ike_sa), - this->ike_sa->get_unique_id(this->ike_sa), - this->ike_sa->get_my_host(this->ike_sa), - this->ike_sa->get_my_id(this->ike_sa), - this->ike_sa->get_other_host(this->ike_sa), - this->ike_sa->get_other_id(this->ike_sa)); + DBG0(DBG_IKE, "deleting IKE_SA %s[%d] between %H[%D]...%H[%D]", + this->ike_sa->get_name(this->ike_sa), + this->ike_sa->get_unique_id(this->ike_sa), + this->ike_sa->get_my_host(this->ike_sa), + this->ike_sa->get_my_id(this->ike_sa), + this->ike_sa->get_other_host(this->ike_sa), + this->ike_sa->get_other_id(this->ike_sa)); delete_payload = delete_payload_create(PROTO_IKE); message->add_payload(message, (payload_t*)delete_payload); this->ike_sa->set_state(this->ike_sa, IKE_DELETING); DBG1(DBG_IKE, "sending DELETE for IKE_SA %s[%d]", - this->ike_sa->get_name(this->ike_sa), - this->ike_sa->get_unique_id(this->ike_sa)); + this->ike_sa->get_name(this->ike_sa), + this->ike_sa->get_unique_id(this->ike_sa)); return NEED_MORE; } @@ -80,6 +80,7 @@ static status_t build_i(private_ike_delete_t *this, message_t *message) */ static status_t process_i(private_ike_delete_t *this, message_t *message) { + DBG0(DBG_IKE, "IKE_SA deleted"); /* completed, delete IKE_SA by returning FAILED */ return FAILED; } @@ -92,15 +93,15 @@ static status_t process_r(private_ike_delete_t *this, message_t *message) /* we don't even scan the payloads, as the message wouldn't have * come so far without being correct */ DBG1(DBG_IKE, "received DELETE for IKE_SA %s[%d]", - this->ike_sa->get_name(this->ike_sa), - this->ike_sa->get_unique_id(this->ike_sa)); - SIG_IKE(DOWN_START, "deleting IKE_SA %s[%d] between %H[%D]...%H[%D]", - this->ike_sa->get_name(this->ike_sa), - this->ike_sa->get_unique_id(this->ike_sa), - this->ike_sa->get_my_host(this->ike_sa), - this->ike_sa->get_my_id(this->ike_sa), - this->ike_sa->get_other_host(this->ike_sa), - this->ike_sa->get_other_id(this->ike_sa)); + this->ike_sa->get_name(this->ike_sa), + this->ike_sa->get_unique_id(this->ike_sa)); + DBG0(DBG_IKE, "deleting IKE_SA %s[%d] between %H[%D]...%H[%D]", + this->ike_sa->get_name(this->ike_sa), + this->ike_sa->get_unique_id(this->ike_sa), + this->ike_sa->get_my_host(this->ike_sa), + this->ike_sa->get_my_id(this->ike_sa), + this->ike_sa->get_other_host(this->ike_sa), + this->ike_sa->get_other_id(this->ike_sa)); switch (this->ike_sa->get_state(this->ike_sa)) { @@ -123,7 +124,7 @@ static status_t process_r(private_ike_delete_t *this, message_t *message) */ static status_t build_r(private_ike_delete_t *this, message_t *message) { - SIG_IKE(DOWN_SUCCESS, "IKE_SA deleted"); + DBG0(DBG_IKE, "IKE_SA deleted"); if (this->simultaneous) { diff --git a/src/charon/sa/tasks/ike_init.c b/src/charon/sa/tasks/ike_init.c index 609b37a39..bd2cd39bb 100644 --- a/src/charon/sa/tasks/ike_init.c +++ b/src/charon/sa/tasks/ike_init.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2008 Tobias Brunner - * Copyright (C) 2005-2007 Martin Willi + * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -14,7 +14,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * $Id: ike_init.c 4206 2008-07-22 17:10:10Z andreas $ + * $Id: ike_init.c 4531 2008-10-30 12:58:54Z martin $ */ #include "ike_init.h" @@ -64,11 +64,16 @@ struct private_ike_init_t { diffie_hellman_group_t dh_group; /** - * Diffie hellman object used to generate public DH value. + * diffie hellman key exchange */ diffie_hellman_t *dh; /** + * Keymat derivation (from IKE_SA) + */ + keymat_t *keymat; + + /** * nonce chosen by us */ chunk_t my_nonce; @@ -192,7 +197,8 @@ static void process_payloads(private_ike_init_t *this, message_t *message) this->dh_group = ke_payload->get_dh_group_number(ke_payload); if (!this->initiator) { - this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group); + this->dh = this->keymat->create_dh(this->keymat, + this->dh_group); } if (this->dh) { @@ -230,26 +236,26 @@ 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); - SIG_IKE(UP_START, "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)); + 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) { - SIG_IKE(UP_FAILED, "giving up after %d retries", 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) { this->dh_group = this->config->get_dh_group(this->config); - this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group); - if (this->dh == NULL) + this->dh = this->keymat->create_dh(this->keymat, this->dh_group); + if (!this->dh) { - SIG_IKE(UP_FAILED, "configured DH group %N not supported", + DBG1(DBG_IKE, "configured DH group %N not supported", diffie_hellman_group_names, this->dh_group); return FAILED; } @@ -261,7 +267,7 @@ static status_t build_i(private_ike_init_t *this, message_t *message) rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK); if (!rng) { - SIG_IKE(UP_FAILED, "error generating nonce"); + DBG1(DBG_IKE, "error generating nonce"); return FAILED; } rng->allocate_bytes(rng, NONCE_SIZE, &this->my_nonce); @@ -296,8 +302,7 @@ 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); - SIG_IKE(UP_START, "%H is initiating an IKE_SA", - message->get_source(message)); + DBG0(DBG_IKE, "%H is initiating an IKE_SA", message->get_source(message)); this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING); rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK); @@ -369,30 +374,30 @@ static status_t process_r(private_ike_init_t *this, message_t *message) */ static status_t build_r(private_ike_init_t *this, message_t *message) { - chunk_t secret; - status_t status; - + keymat_t *old_keymat = NULL; + ike_sa_id_t *id; + /* check if we have everything we need */ if (this->proposal == NULL || this->other_nonce.len == 0 || this->my_nonce.len == 0) { - SIG_IKE(UP_FAILED, "received proposals inacceptable"); + DBG1(DBG_IKE, "received proposals inacceptable"); message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty); 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) || - this->dh->get_shared_secret(this->dh, &secret) != SUCCESS) + !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)) { - SIG_CHD(UP_FAILED, NULL, "DH group %N inacceptable, requesting %N", - diffie_hellman_group_names, this->dh_group, - diffie_hellman_group_names, group); + DBG1(DBG_IKE, "DH group %N inacceptable, requesting %N", + diffie_hellman_group_names, this->dh_group, + diffie_hellman_group_names, group); this->dh_group = group; group = htons(group); message->add_notify(message, FALSE, INVALID_KE_PAYLOAD, @@ -400,49 +405,28 @@ static status_t build_r(private_ike_init_t *this, message_t *message) } else { - SIG_IKE(UP_FAILED, "no acceptable proposal found"); + DBG1(DBG_IKE, "no acceptable proposal found"); } return FAILED; } + id = this->ike_sa->get_id(this->ike_sa); if (this->old_sa) - { - ike_sa_id_t *id; - prf_t *prf, *child_prf; - - /* Apply SPI if we are rekeying */ - id = this->ike_sa->get_id(this->ike_sa); + { /* rekeying: Apply SPI, include keymat from old SA in key derivation */ id->set_initiator_spi(id, this->proposal->get_spi(this->proposal)); - - /* setup crypto keys for the rekeyed SA */ - prf = this->old_sa->get_prf(this->old_sa); - child_prf = this->old_sa->get_child_prf(this->old_sa); - status = this->ike_sa->derive_keys(this->ike_sa, this->proposal, secret, - this->other_nonce, this->my_nonce, - FALSE, child_prf, prf); + old_keymat = this->old_sa->get_keymat(this->old_sa); } - else + if (!this->keymat->derive_ike_keys(this->keymat, this->proposal, this->dh, + this->other_nonce, this->my_nonce, id, old_keymat)) { - /* setup crypto keys */ - status = this->ike_sa->derive_keys(this->ike_sa, this->proposal, secret, - this->other_nonce, this->my_nonce, - FALSE, NULL, NULL); - } - if (status != SUCCESS) - { - SIG_IKE(UP_FAILED, "key derivation failed"); + DBG1(DBG_IKE, "key derivation failed"); message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty); return FAILED; } - - /* Keep the selected IKE proposal for status information purposes */ - { - char buf[BUF_LEN]; - - snprintf(buf, BUF_LEN, "%P", this->proposal); - this->ike_sa->set_proposal(this->ike_sa, buf+4); - } - + + charon->bus->ike_keys(charon->bus, this->ike_sa, this->dh, + this->other_nonce, this->my_nonce, this->old_sa); + build_payloads(this, message); return SUCCESS; } @@ -452,8 +436,8 @@ static status_t build_r(private_ike_init_t *this, message_t *message) */ static status_t process_i(private_ike_init_t *this, message_t *message) { - chunk_t secret; - status_t status; + keymat_t *old_keymat = NULL; + ike_sa_id_t *id; iterator_t *iterator; payload_t *payload; @@ -505,7 +489,7 @@ static status_t process_i(private_ike_init_t *this, message_t *message) { if (type < 16383) { - SIG_IKE(UP_FAILED, "received %N notify error", + DBG1(DBG_IKE, "received %N notify error", notify_type_names, type); iterator->destroy(iterator); return FAILED; @@ -525,55 +509,34 @@ static status_t process_i(private_ike_init_t *this, message_t *message) if (this->proposal == NULL || this->other_nonce.len == 0 || this->my_nonce.len == 0) { - SIG_IKE(UP_FAILED, "peer's proposal selection invalid"); + DBG1(DBG_IKE, "peers proposal selection invalid"); 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) || - this->dh->get_shared_secret(this->dh, &secret) != SUCCESS) + !this->proposal->has_dh_group(this->proposal, this->dh_group)) { - SIG_IKE(UP_FAILED, "peer's DH group selection invalid"); + DBG1(DBG_IKE, "peer DH group selection invalid"); return FAILED; } - /* Apply SPI if we are rekeying */ + id = this->ike_sa->get_id(this->ike_sa); if (this->old_sa) - { - ike_sa_id_t *id; - prf_t *prf, *child_prf; - - id = this->ike_sa->get_id(this->ike_sa); + { /* rekeying: Apply SPI, include keymat from old SA in key derivation */ id->set_responder_spi(id, this->proposal->get_spi(this->proposal)); - - /* setup crypto keys for the rekeyed SA */ - prf = this->old_sa->get_prf(this->old_sa); - child_prf = this->old_sa->get_child_prf(this->old_sa); - status = this->ike_sa->derive_keys(this->ike_sa, this->proposal, secret, - this->my_nonce, this->other_nonce, - TRUE, child_prf, prf); + old_keymat = this->old_sa->get_keymat(this->old_sa); } - else + if (!this->keymat->derive_ike_keys(this->keymat, this->proposal, this->dh, + this->my_nonce, this->other_nonce, id, old_keymat)) { - /* setup crypto keys for a new SA */ - status = this->ike_sa->derive_keys(this->ike_sa, this->proposal, secret, - this->my_nonce, this->other_nonce, - TRUE, NULL, NULL); - } - if (status != SUCCESS) - { - SIG_IKE(UP_FAILED, "key derivation failed"); + DBG1(DBG_IKE, "key derivation failed"); return FAILED; } - - /* Keep the selected IKE proposal for status information purposes */ - { - char buf[BUF_LEN]; - - snprintf(buf, BUF_LEN, "%P", this->proposal); - this->ike_sa->set_proposal(this->ike_sa, buf+4); - } - + + charon->bus->ike_keys(charon->bus, this->ike_sa, this->dh, + this->my_nonce, this->other_nonce, this->old_sa); + return SUCCESS; } @@ -607,12 +570,12 @@ static chunk_t get_lower_nonce(private_ike_init_t *this) static void migrate(private_ike_init_t *this, ike_sa_t *ike_sa) { DESTROY_IF(this->proposal); - DESTROY_IF(this->dh); chunk_free(&this->other_nonce); this->ike_sa = ike_sa; this->proposal = NULL; - this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group); + DESTROY_IF(this->dh); + this->dh = this->keymat->create_dh(this->keymat, this->dh_group); } /** @@ -620,8 +583,8 @@ static void migrate(private_ike_init_t *this, ike_sa_t *ike_sa) */ static void destroy(private_ike_init_t *this) { - DESTROY_IF(this->proposal); DESTROY_IF(this->dh); + DESTROY_IF(this->proposal); chunk_free(&this->my_nonce); chunk_free(&this->other_nonce); chunk_free(&this->cookie); @@ -654,6 +617,7 @@ ike_init_t *ike_init_create(ike_sa_t *ike_sa, bool initiator, ike_sa_t *old_sa) this->initiator = initiator; this->dh_group = MODP_NONE; this->dh = NULL; + this->keymat = ike_sa->get_keymat(ike_sa); this->my_nonce = chunk_empty; this->other_nonce = chunk_empty; this->cookie = chunk_empty; diff --git a/src/charon/sa/tasks/ike_me.c b/src/charon/sa/tasks/ike_me.c index a203dee58..f58d51341 100644 --- a/src/charon/sa/tasks/ike_me.c +++ b/src/charon/sa/tasks/ike_me.c @@ -12,7 +12,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * $Id: ike_me.c 4355 2008-09-25 07:56:58Z tobias $ + * $Id: ike_me.c 4640 2008-11-12 16:07:17Z martin $ */ #include "ike_me.h" @@ -461,8 +461,7 @@ static status_t process_i(private_ike_me_t *this, message_t *message) this->ike_sa->set_server_reflexive_host(this->ike_sa, endpoint->clone(endpoint)); } /* FIXME: what if it failed? e.g. AUTH failure */ - SIG_CHD(UP_SUCCESS, NULL, "established mediation connection " - "without CHILD_SA successfully"); + DBG1(DBG_IKE, "established mediation connection successfully"); break; } @@ -642,8 +641,7 @@ static status_t build_r_ms(private_ike_me_t *this, message_t *message) /* FIXME: we actually must delete any existing IKE_SAs with the same remote id */ this->ike_sa->act_as_mediation_server(this->ike_sa); - SIG_CHD(UP_SUCCESS, NULL, "established mediation connection " - "without CHILD_SA successfully"); + DBG1(DBG_IKE, "established mediation connection successfully"); break; } @@ -787,7 +785,7 @@ ike_me_t *ike_me_create(ike_sa_t *ike_sa, bool initiator) this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate; this->public.task.destroy = (void(*)(task_t*))destroy; - if (ike_sa->is_ike_initiator(ike_sa)) + if (ike_sa->has_condition(ike_sa, COND_ORIGINAL_INITIATOR)) { if (initiator) { diff --git a/src/charon/sa/tasks/ike_mobike.c b/src/charon/sa/tasks/ike_mobike.c index f6ee3f6ad..a791d1892 100644 --- a/src/charon/sa/tasks/ike_mobike.c +++ b/src/charon/sa/tasks/ike_mobike.c @@ -12,7 +12,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * $Id: ike_mobike.c 4394 2008-10-09 08:25:11Z martin $ + * $Id: ike_mobike.c 4618 2008-11-11 09:22:00Z tobias $ */ #include "ike_mobike.h" @@ -251,10 +251,16 @@ static void update_children(private_ike_mobike_t *this) iterator = this->ike_sa->create_child_sa_iterator(this->ike_sa); while (iterator->iterate(iterator, (void**)&child_sa)) { - child_sa->update_hosts(child_sa, - this->ike_sa->get_my_host(this->ike_sa), - this->ike_sa->get_other_host(this->ike_sa), - this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY)); + if (child_sa->update_hosts(child_sa, + this->ike_sa->get_my_host(this->ike_sa), + this->ike_sa->get_other_host(this->ike_sa), + this->ike_sa->get_virtual_ip(this->ike_sa, TRUE), + this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY)) == NOT_SUPPORTED) + { + this->ike_sa->rekey_child_sa(this->ike_sa, + child_sa->get_protocol(child_sa), + child_sa->get_spi(child_sa, TRUE)); + } } iterator->destroy(iterator); } diff --git a/src/charon/sa/tasks/ike_reauth.c b/src/charon/sa/tasks/ike_reauth.c index b84b2a387..61701075f 100644 --- a/src/charon/sa/tasks/ike_reauth.c +++ b/src/charon/sa/tasks/ike_reauth.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2007 Martin Willi + * Copyright (C) 2006-2008 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -12,7 +12,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * $Id: ike_reauth.c 4211 2008-07-23 18:46:34Z andreas $ + * $Id: ike_reauth.c 4495 2008-10-28 16:07:06Z martin $ */ #include "ike_reauth.h" @@ -65,7 +65,6 @@ static status_t process_i(private_ike_reauth_t *this, message_t *message) /* process delete response first */ this->ike_delete->task.process(&this->ike_delete->task, message); - SIG_IKE(DOWN_SUCCESS, "IKE_SA deleted"); peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa); @@ -105,6 +104,8 @@ static status_t process_i(private_ike_reauth_t *this, message_t *message) { charon->ike_sa_manager->checkin_and_destroy( charon->ike_sa_manager, new); + /* set threads active IKE_SA after checkin */ + charon->bus->set_sa(charon->bus, this->ike_sa); DBG1(DBG_IKE, "reauthenticating IKE_SA failed"); return FAILED; } @@ -132,6 +133,8 @@ static status_t process_i(private_ike_reauth_t *this, message_t *message) iterator->destroy(iterator); charon->ike_sa_manager->checkin_and_destroy( charon->ike_sa_manager, new); + /* set threads active IKE_SA after checkin */ + charon->bus->set_sa(charon->bus, this->ike_sa); DBG1(DBG_IKE, "reauthenticating IKE_SA failed"); return FAILED; } @@ -141,6 +144,8 @@ static status_t process_i(private_ike_reauth_t *this, message_t *message) } iterator->destroy(iterator); charon->ike_sa_manager->checkin(charon->ike_sa_manager, new); + /* set threads active IKE_SA after checkin */ + charon->bus->set_sa(charon->bus, this->ike_sa); /* we always return failed to delete the obsolete IKE_SA */ return FAILED; diff --git a/src/charon/sa/tasks/ike_rekey.c b/src/charon/sa/tasks/ike_rekey.c index 6c4ef4354..28d63cca7 100644 --- a/src/charon/sa/tasks/ike_rekey.c +++ b/src/charon/sa/tasks/ike_rekey.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Martin Willi + * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -13,7 +13,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * $Id: ike_rekey.c 4211 2008-07-23 18:46:34Z andreas $ + * $Id: ike_rekey.c 4659 2008-11-14 14:05:47Z martin $ */ #include "ike_rekey.h" @@ -144,7 +144,7 @@ static status_t build_r(private_ike_rekey_t *this, message_t *message) message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty); return SUCCESS; } - + if (this->ike_init->task.build(&this->ike_init->task, message) == FAILED) { return SUCCESS; @@ -152,13 +152,13 @@ static status_t build_r(private_ike_rekey_t *this, message_t *message) this->ike_sa->set_state(this->ike_sa, IKE_REKEYING); this->new_sa->set_state(this->new_sa, IKE_ESTABLISHED); - SIG_IKE(UP_SUCCESS, "IKE_SA %s[%d] established between %H[%D]...%H[%D]", - this->new_sa->get_name(this->new_sa), - this->new_sa->get_unique_id(this->new_sa), - this->ike_sa->get_my_host(this->ike_sa), - this->ike_sa->get_my_id(this->ike_sa), - this->ike_sa->get_other_host(this->ike_sa), - this->ike_sa->get_other_id(this->ike_sa)); + DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%D]...%H[%D]", + this->new_sa->get_name(this->new_sa), + this->new_sa->get_unique_id(this->new_sa), + this->ike_sa->get_my_host(this->ike_sa), + this->ike_sa->get_my_id(this->ike_sa), + this->ike_sa->get_other_host(this->ike_sa), + this->ike_sa->get_other_id(this->ike_sa)); return SUCCESS; } @@ -170,7 +170,32 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message) { job_t *job; ike_sa_id_t *to_delete; + iterator_t *iterator; + payload_t *payload; + /* handle NO_ADDITIONAL_SAS notify */ + iterator = message->get_payload_iterator(message); + while (iterator->iterate(iterator, (void**)&payload)) + { + if (payload->get_type(payload) == NOTIFY) + { + notify_payload_t *notify = (notify_payload_t*)payload; + + if (notify->get_notify_type(notify) == NO_ADDITIONAL_SAS) + { + DBG1(DBG_IKE, "peer seems to not support IKE rekeying, " + "starting reauthentication"); + this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED); + charon->processor->queue_job(charon->processor, + (job_t*)rekey_ike_sa_job_create( + this->ike_sa->get_id(this->ike_sa), TRUE)); + iterator->destroy(iterator); + return SUCCESS; + } + } + } + iterator->destroy(iterator); + switch (this->ike_init->task.process(&this->ike_init->task, message)) { case FAILED: @@ -198,13 +223,13 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message) } this->new_sa->set_state(this->new_sa, IKE_ESTABLISHED); - SIG_IKE(UP_SUCCESS, "IKE_SA %s[%d] established between %H[%D]...%H[%D]", - this->new_sa->get_name(this->new_sa), - this->new_sa->get_unique_id(this->new_sa), - this->ike_sa->get_my_host(this->ike_sa), - this->ike_sa->get_my_id(this->ike_sa), - this->ike_sa->get_other_host(this->ike_sa), - this->ike_sa->get_other_id(this->ike_sa)); + DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%D]...%H[%D]", + this->new_sa->get_name(this->new_sa), + this->new_sa->get_unique_id(this->new_sa), + this->ike_sa->get_my_host(this->ike_sa), + this->ike_sa->get_my_id(this->ike_sa), + this->ike_sa->get_other_host(this->ike_sa), + this->ike_sa->get_other_id(this->ike_sa)); to_delete = this->ike_sa->get_id(this->ike_sa); @@ -242,6 +267,8 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message) this->new_sa = other->new_sa; other->new_sa = NULL; } + /* set threads active IKE_SA after checkin */ + charon->bus->set_sa(charon->bus, this->ike_sa); } job = (job_t*)delete_ike_sa_job_create(to_delete, TRUE); @@ -277,6 +304,8 @@ static void migrate(private_ike_rekey_t *this, ike_sa_t *ike_sa) { charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, this->new_sa); + /* set threads active IKE_SA after checkin */ + charon->bus->set_sa(charon->bus, this->ike_sa); } DESTROY_IF(this->collision); @@ -303,6 +332,8 @@ static void destroy(private_ike_rekey_t *this) charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, this->new_sa); } + /* set threads active IKE_SA after checkin */ + charon->bus->set_sa(charon->bus, this->ike_sa); } if (this->ike_init) { diff --git a/src/charon/sa/tasks/task.c b/src/charon/sa/tasks/task.c index 3192b688a..fd15379f3 100644 --- a/src/charon/sa/tasks/task.c +++ b/src/charon/sa/tasks/task.c @@ -13,11 +13,12 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * $Id: task.c 3666 2008-03-26 18:40:19Z tobias $ + * $Id: task.c 4618 2008-11-11 09:22:00Z tobias $ */ #include "task.h" +#ifdef ME ENUM(task_type_names, IKE_INIT, CHILD_REKEY, "IKE_INIT", "IKE_NATD", @@ -31,11 +32,27 @@ ENUM(task_type_names, IKE_INIT, CHILD_REKEY, "IKE_REAUTH", "IKE_DELETE", "IKE_DPD", -#ifdef ME "IKE_ME", -#endif /* ME */ "CHILD_CREATE", "CHILD_DELETE", "CHILD_REKEY", ); - +#else +ENUM(task_type_names, IKE_INIT, CHILD_REKEY, + "IKE_INIT", + "IKE_NATD", + "IKE_MOBIKE", + "IKE_AUTHENTICATE", + "IKE_AUTH_LIFETIME", + "IKE_CERT_PRE", + "IKE_CERT_POST", + "IKE_CONFIG", + "IKE_REKEY", + "IKE_REAUTH", + "IKE_DELETE", + "IKE_DPD", + "CHILD_CREATE", + "CHILD_DELETE", + "CHILD_REKEY", +); +#endif /* ME */ |