diff options
Diffstat (limited to 'src/libcharon/sa/tasks')
-rw-r--r-- | src/libcharon/sa/tasks/child_create.c | 4 | ||||
-rw-r--r-- | src/libcharon/sa/tasks/child_delete.c | 17 | ||||
-rw-r--r-- | src/libcharon/sa/tasks/child_rekey.c | 31 | ||||
-rw-r--r-- | src/libcharon/sa/tasks/ike_auth.c | 12 | ||||
-rw-r--r-- | src/libcharon/sa/tasks/ike_init.c | 2 | ||||
-rw-r--r-- | src/libcharon/sa/tasks/ike_me.c | 10 | ||||
-rw-r--r-- | src/libcharon/sa/tasks/ike_mobike.c | 215 | ||||
-rw-r--r-- | src/libcharon/sa/tasks/ike_mobike.h | 5 | ||||
-rw-r--r-- | src/libcharon/sa/tasks/ike_natd.c | 41 | ||||
-rw-r--r-- | src/libcharon/sa/tasks/ike_rekey.c | 83 | ||||
-rw-r--r-- | src/libcharon/sa/tasks/ike_vendor.c | 14 |
11 files changed, 230 insertions, 204 deletions
diff --git a/src/libcharon/sa/tasks/child_create.c b/src/libcharon/sa/tasks/child_create.c index 3de27ee3f..57beedba9 100644 --- a/src/libcharon/sa/tasks/child_create.c +++ b/src/libcharon/sa/tasks/child_create.c @@ -261,7 +261,7 @@ static void schedule_inactivity_timeout(private_child_create_t *this) { close_ike = lib->settings->get_bool(lib->settings, "charon.inactivity_close_ike", FALSE); - charon->scheduler->schedule_job(charon->scheduler, (job_t*) + lib->scheduler->schedule_job(lib->scheduler, (job_t*) inactivity_job_create(this->child_sa->get_reqid(this->child_sa), timeout, close_ike), timeout); } @@ -871,7 +871,7 @@ static void handle_child_sa_failure(private_child_create_t *this, /* we delay the delete for 100ms, as the IKE_AUTH response must arrive * first */ DBG1(DBG_IKE, "closing IKE_SA due CHILD_SA setup failure"); - charon->scheduler->schedule_job_ms(charon->scheduler, (job_t*) + lib->scheduler->schedule_job_ms(lib->scheduler, (job_t*) delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE), 100); } diff --git a/src/libcharon/sa/tasks/child_delete.c b/src/libcharon/sa/tasks/child_delete.c index b0cd30e1e..45e97e4cd 100644 --- a/src/libcharon/sa/tasks/child_delete.c +++ b/src/libcharon/sa/tasks/child_delete.c @@ -117,11 +117,10 @@ static void build_payloads(private_child_delete_t *this, message_t *message) */ static void process_payloads(private_child_delete_t *this, message_t *message) { - enumerator_t *payloads; - iterator_t *spis; + enumerator_t *payloads, *spis; payload_t *payload; delete_payload_t *delete_payload; - u_int32_t *spi; + u_int32_t spi; protocol_id_t protocol; child_sa_t *child_sa; @@ -136,19 +135,19 @@ static void process_payloads(private_child_delete_t *this, message_t *message) { continue; } - spis = delete_payload->create_spi_iterator(delete_payload); - while (spis->iterate(spis, (void**)&spi)) + spis = delete_payload->create_spi_enumerator(delete_payload); + while (spis->enumerate(spis, &spi)) { child_sa = this->ike_sa->get_child_sa(this->ike_sa, protocol, - *spi, FALSE); + spi, FALSE); if (child_sa == NULL) { DBG1(DBG_IKE, "received DELETE for %N CHILD_SA with SPI %.8x, " - "but no such SA", protocol_id_names, protocol, ntohl(*spi)); + "but no such SA", protocol_id_names, protocol, ntohl(spi)); continue; } DBG1(DBG_IKE, "received DELETE for %N CHILD_SA with SPI %.8x", - protocol_id_names, protocol, ntohl(*spi)); + protocol_id_names, protocol, ntohl(spi)); switch (child_sa->get_state(child_sa)) { @@ -161,7 +160,7 @@ static void process_payloads(private_child_delete_t *this, message_t *message) if (!this->initiator) { this->ike_sa->destroy_child_sa(this->ike_sa, - protocol, *spi); + protocol, spi); continue; } case CHILD_INSTALLED: diff --git a/src/libcharon/sa/tasks/child_rekey.c b/src/libcharon/sa/tasks/child_rekey.c index fb3452efd..fdaaea4b8 100644 --- a/src/libcharon/sa/tasks/child_rekey.c +++ b/src/libcharon/sa/tasks/child_rekey.c @@ -75,6 +75,15 @@ struct private_child_rekey_t { * colliding task, may be delete or rekey */ task_t *collision; + + /** + * Indicate that peer destroyed the redundant child from collision. + * This happens if a peer's delete notification for the redundant + * child gets processed before the rekey job. If so, we must not + * touch the child created in the collision since it points to + * memory already freed. + */ + bool other_child_destroyed; }; /** @@ -239,9 +248,13 @@ static child_sa_t *handle_collision(private_child_rekey_t *this) DBG1(DBG_IKE, "CHILD_SA rekey collision won, " "deleting rekeyed child"); to_delete = this->child_sa; - /* disable close action for the redundand child */ - child_sa = other->child_create->get_child(other->child_create); - child_sa->set_close_action(child_sa, ACTION_NONE); + /* don't touch child other created, it has already been deleted */ + if (!this->other_child_destroyed) + { + /* disable close action for the redundand child */ + child_sa = other->child_create->get_child(other->child_create); + child_sa->set_close_action(child_sa, ACTION_NONE); + } } else { @@ -286,7 +299,7 @@ static status_t process_i(private_child_rekey_t *this, message_t *message) 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, + lib->processor->queue_job(lib->processor, (job_t*)rekey_ike_sa_job_create( this->ike_sa->get_id(this->ike_sa), TRUE)); return SUCCESS; @@ -316,7 +329,7 @@ static status_t process_i(private_child_rekey_t *this, message_t *message) DBG1(DBG_IKE, "CHILD_SA rekeying failed, " "trying again in %d seconds", retry); this->child_sa->set_state(this->child_sa, CHILD_INSTALLED); - charon->scheduler->schedule_job(charon->scheduler, job, retry); + lib->scheduler->schedule_job(lib->scheduler, job, retry); } return SUCCESS; } @@ -380,6 +393,13 @@ static void collide(private_child_rekey_t *this, task_t *other) else if (other->get_type(other) == CHILD_DELETE) { child_delete_t *del = (child_delete_t*)other; + if (del->get_child(del) == this->child_create->get_child(this->child_create)) + { + /* peer deletes redundant child created in collision */ + this->other_child_destroyed = TRUE; + other->destroy(other); + return; + } if (del == NULL || del->get_child(del) != this->child_sa) { /* not the same child => no collision */ @@ -466,6 +486,7 @@ child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, protocol_id_t protocol, this->spi = spi; this->collision = NULL; this->child_delete = NULL; + this->other_child_destroyed = FALSE; return &this->public; } diff --git a/src/libcharon/sa/tasks/ike_auth.c b/src/libcharon/sa/tasks/ike_auth.c index a954782f2..b440ec811 100644 --- a/src/libcharon/sa/tasks/ike_auth.c +++ b/src/libcharon/sa/tasks/ike_auth.c @@ -481,9 +481,8 @@ static status_t process_r(private_ike_auth_t *this, message_t *message) { this->ike_sa->enable_extension(this->ike_sa, EXT_MULTIPLE_AUTH); } - if (this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN) && - message->get_notify(message, EAP_ONLY_AUTHENTICATION)) - { /* EAP-only has no official notify, accept only from strongSwan */ + if (message->get_notify(message, EAP_ONLY_AUTHENTICATION)) + { this->ike_sa->enable_extension(this->ike_sa, EXT_EAP_ONLY_AUTHENTICATION); } @@ -538,6 +537,11 @@ static status_t process_r(private_ike_auth_t *this, message_t *message) { cfg->add(cfg, AUTH_RULE_EAP_IDENTITY, id->clone(id)); } + id = (identification_t*)cand->get(cand, AUTH_RULE_AAA_IDENTITY); + if (id) + { + cfg->add(cfg, AUTH_RULE_AAA_IDENTITY, id->clone(id)); + } } /* verify authentication data */ @@ -821,7 +825,7 @@ static status_t process_i(private_ike_auth_t *this, message_t *message) break; default: { - if (type < 16383) + if (type <= 16383) { DBG1(DBG_IKE, "received %N notify error", notify_type_names, type); diff --git a/src/libcharon/sa/tasks/ike_init.c b/src/libcharon/sa/tasks/ike_init.c index 38fb572f4..dd4a5f5c0 100644 --- a/src/libcharon/sa/tasks/ike_init.c +++ b/src/libcharon/sa/tasks/ike_init.c @@ -468,7 +468,7 @@ static status_t process_i(private_ike_init_t *this, message_t *message) } default: { - if (type < 16383) + if (type <= 16383) { DBG1(DBG_IKE, "received %N notify error", notify_type_names, type); diff --git a/src/libcharon/sa/tasks/ike_me.c b/src/libcharon/sa/tasks/ike_me.c index 2d2847ae0..1de6ae8fc 100644 --- a/src/libcharon/sa/tasks/ike_me.c +++ b/src/libcharon/sa/tasks/ike_me.c @@ -17,6 +17,7 @@ #include <string.h> +#include <hydra.h> #include <daemon.h> #include <config/peer_cfg.h> #include <encoding/payloads/id_payload.h> @@ -134,8 +135,8 @@ static void gather_and_add_endpoints(private_ike_me_t *this, message_t *message) host = this->ike_sa->get_my_host(this->ike_sa); port = host->get_port(host); - enumerator = charon->kernel_interface->create_address_enumerator( - charon->kernel_interface, FALSE, FALSE); + enumerator = hydra->kernel_interface->create_address_enumerator( + hydra->kernel_interface, FALSE, FALSE); while (enumerator->enumerate(enumerator, (void**)&addr)) { host = addr->clone(addr); @@ -454,6 +455,9 @@ static status_t process_i(private_ike_me_t *this, message_t *message) DBG1(DBG_IKE, "server did not return a ME_MEDIATION, aborting"); return FAILED; } + /* if we are on a mediation connection we switch to port 4500 even + * if no NAT is detected. */ + this->ike_sa->float_ports(this->ike_sa); return NEED_MORE; } case IKE_AUTH: @@ -689,7 +693,7 @@ static status_t build_r_ms(private_ike_me_t *this, message_t *message) job_t *job = (job_t*)mediation_job_create(this->peer_id, this->ike_sa->get_other_id(this->ike_sa), this->connect_id, this->connect_key, this->remote_endpoints, this->response); - charon->processor->queue_job(charon->processor, job); + lib->processor->queue_job(lib->processor, job); break; } default: diff --git a/src/libcharon/sa/tasks/ike_mobike.c b/src/libcharon/sa/tasks/ike_mobike.c index a62886f02..5b12eaaac 100644 --- a/src/libcharon/sa/tasks/ike_mobike.c +++ b/src/libcharon/sa/tasks/ike_mobike.c @@ -17,6 +17,7 @@ #include <string.h> +#include <hydra.h> #include <daemon.h> #include <sa/tasks/ike_natd.h> #include <encoding/payloads/notify_payload.h> @@ -70,6 +71,11 @@ struct private_ike_mobike_t { * include address list update */ bool address; + + /** + * additional addresses got updated + */ + bool addresses_updated; }; /** @@ -153,6 +159,7 @@ static void process_payloads(private_ike_mobike_t *this, message_t *message) host = host_create_from_chunk(family, data, 0); DBG2(DBG_IKE, "got additional MOBIKE peer address: %H", host); this->ike_sa->add_additional_address(this->ike_sa, host); + this->addresses_updated = TRUE; break; } case UPDATE_SA_ADDRESSES: @@ -163,6 +170,7 @@ static void process_payloads(private_ike_mobike_t *this, message_t *message) case NO_ADDITIONAL_ADDRESSES: { flush_additional_addresses(this); + this->addresses_updated = TRUE; break; } case NAT_DETECTION_SOURCE_IP: @@ -193,8 +201,8 @@ static void build_address_list(private_ike_mobike_t *this, message_t *message) int added = 0; me = this->ike_sa->get_my_host(this->ike_sa); - enumerator = charon->kernel_interface->create_address_enumerator( - charon->kernel_interface, FALSE, FALSE); + enumerator = hydra->kernel_interface->create_address_enumerator( + hydra->kernel_interface, FALSE, FALSE); while (enumerator->enumerate(enumerator, (void**)&host)) { if (me->ip_equals(me, host)) @@ -269,32 +277,23 @@ static void update_children(private_ike_mobike_t *this) } /** - * Apply port of old address if it equals new, port otherwise + * Apply the port of the old host, if its ip equals the new, use port otherwise. */ -static void apply_port(private_ike_mobike_t *this, host_t *host, host_t *old, - u_int16_t port) +static void apply_port(host_t *host, host_t *old, u_int16_t port) { if (host->ip_equals(host, old)) { - host->set_port(host, old->get_port(old)); + port = old->get_port(old); } - else + else if (port == IKEV2_UDP_PORT) { - if (port == IKEV2_UDP_PORT) - { - host->set_port(host, IKEV2_NATT_PORT); - } - else - { - host->set_port(host, port); - } + port = IKEV2_NATT_PORT; } + host->set_port(host, port); } -/** - * Implementation of ike_mobike_t.transmit - */ -static void transmit(private_ike_mobike_t *this, packet_t *packet) +METHOD(ike_mobike_t, transmit, void, + private_ike_mobike_t *this, packet_t *packet) { host_t *me, *other, *me_old, *other_old; iterator_t *iterator; @@ -310,11 +309,11 @@ static void transmit(private_ike_mobike_t *this, packet_t *packet) other_old = this->ike_sa->get_other_host(this->ike_sa); ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa); - me = charon->kernel_interface->get_source_addr( - charon->kernel_interface, other_old, NULL); + me = hydra->kernel_interface->get_source_addr( + hydra->kernel_interface, other_old, NULL); if (me) { - apply_port(this, me, me_old, ike_cfg->get_my_port(ike_cfg)); + apply_port(me, me_old, ike_cfg->get_my_port(ike_cfg)); DBG1(DBG_IKE, "checking original path %#H - %#H", me, other_old); copy = packet->clone(packet); copy->set_source(copy, me); @@ -324,8 +323,8 @@ static void transmit(private_ike_mobike_t *this, packet_t *packet) iterator = this->ike_sa->create_additional_address_iterator(this->ike_sa); while (iterator->iterate(iterator, (void**)&other)) { - me = charon->kernel_interface->get_source_addr( - charon->kernel_interface, other, NULL); + me = hydra->kernel_interface->get_source_addr( + hydra->kernel_interface, other, NULL); if (me) { if (me->get_family(me) != other->get_family(other)) @@ -334,9 +333,9 @@ static void transmit(private_ike_mobike_t *this, packet_t *packet) continue; } /* reuse port for an active address, 4500 otherwise */ - apply_port(this, me, me_old, ike_cfg->get_my_port(ike_cfg)); + apply_port(me, me_old, ike_cfg->get_my_port(ike_cfg)); other = other->clone(other); - apply_port(this, other, other_old, ike_cfg->get_other_port(ike_cfg)); + apply_port(other, other_old, ike_cfg->get_other_port(ike_cfg)); DBG1(DBG_IKE, "checking path %#H - %#H", me, other); copy = packet->clone(packet); copy->set_source(copy, me); @@ -347,12 +346,11 @@ static void transmit(private_ike_mobike_t *this, packet_t *packet) iterator->destroy(iterator); } -/** - * Implementation of task_t.process for initiator - */ -static status_t build_i(private_ike_mobike_t *this, message_t *message) +METHOD(task_t, build_i, status_t, + private_ike_mobike_t *this, message_t *message) { - if (message->get_message_id(message) == 1) + if (message->get_exchange_type(message) == IKE_AUTH && + message->get_message_id(message) == 1) { /* only in first IKE_AUTH */ message->add_notify(message, FALSE, MOBIKE_SUPPORTED, chunk_empty); build_address_list(this, message); @@ -363,7 +361,7 @@ static status_t build_i(private_ike_mobike_t *this, message_t *message) /* we check if the existing address is still valid */ old = message->get_source(message); - new = charon->kernel_interface->get_source_addr(charon->kernel_interface, + new = hydra->kernel_interface->get_source_addr(hydra->kernel_interface, message->get_destination(message), old); if (new) { @@ -379,11 +377,12 @@ static status_t build_i(private_ike_mobike_t *this, message_t *message) } if (this->update) { - message->add_notify(message, FALSE, UPDATE_SA_ADDRESSES, chunk_empty); + message->add_notify(message, FALSE, UPDATE_SA_ADDRESSES, + chunk_empty); build_cookie(this, message); update_children(this); } - if (this->address) + if (this->address && !this->check) { build_address_list(this, message); } @@ -395,12 +394,11 @@ static status_t build_i(private_ike_mobike_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.process for responder - */ -static status_t process_r(private_ike_mobike_t *this, message_t *message) +METHOD(task_t, process_r, status_t, + private_ike_mobike_t *this, message_t *message) { - if (message->get_message_id(message) == 1) + if (message->get_exchange_type(message) == IKE_AUTH && + message->get_message_id(message) == 1) { /* only first IKE_AUTH */ process_payloads(this, message); } @@ -421,14 +419,25 @@ static status_t process_r(private_ike_mobike_t *this, message_t *message) { this->natd->task.process(&this->natd->task, message); } + if (this->addresses_updated && this->ike_sa->has_condition(this->ike_sa, + COND_ORIGINAL_INITIATOR)) + { + host_t *other = message->get_source(message); + host_t *other_old = this->ike_sa->get_other_host(this->ike_sa); + if (!other->equals(other, other_old)) + { + DBG1(DBG_IKE, "remote address changed from %H to %H", other_old, + other); + this->ike_sa->set_other_host(this->ike_sa, other->clone(other)); + this->update = TRUE; + } + } } return NEED_MORE; } -/** - * Implementation of task_t.build for responder - */ -static status_t build_r(private_ike_mobike_t *this, message_t *message) +METHOD(task_t, build_r, status_t, + private_ike_mobike_t *this, message_t *message) { if (message->get_exchange_type(message) == IKE_AUTH && this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED) @@ -460,10 +469,8 @@ static status_t build_r(private_ike_mobike_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of task_t.process for initiator - */ -static status_t process_i(private_ike_mobike_t *this, message_t *message) +METHOD(task_t, process_i, status_t, + private_ike_mobike_t *this, message_t *message) { if (message->get_exchange_type(message) == IKE_AUTH && this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED) @@ -536,14 +543,22 @@ static status_t process_i(private_ike_mobike_t *this, message_t *message) } if (this->update) { - /* start the update with the same task */ - this->check = FALSE; - this->address = FALSE; - if (this->natd) - { - this->natd->task.destroy(&this->natd->task); + /* use the same task to ... */ + if (!this->ike_sa->has_condition(this->ike_sa, + COND_ORIGINAL_INITIATOR)) + { /*... send an updated list of addresses as responder */ + update_children(this); + this->update = FALSE; + } + else + { /* ... send the update as original initiator */ + if (this->natd) + { + this->natd->task.destroy(&this->natd->task); + } + this->natd = ike_natd_create(this->ike_sa, this->initiator); } - this->natd = ike_natd_create(this->ike_sa, this->initiator); + this->check = FALSE; this->ike_sa->set_pending_updates(this->ike_sa, 1); return NEED_MORE; } @@ -553,51 +568,48 @@ static status_t process_i(private_ike_mobike_t *this, message_t *message) return NEED_MORE; } -/** - * Implementation of ike_mobike_t.roam. - */ -static void roam(private_ike_mobike_t *this, bool address) +METHOD(ike_mobike_t, addresses, void, + private_ike_mobike_t *this) +{ + this->address = TRUE; + this->ike_sa->set_pending_updates(this->ike_sa, + this->ike_sa->get_pending_updates(this->ike_sa) + 1); +} + +METHOD(ike_mobike_t, roam, void, + private_ike_mobike_t *this, bool address) { this->check = TRUE; this->address = address; this->ike_sa->set_pending_updates(this->ike_sa, - this->ike_sa->get_pending_updates(this->ike_sa) + 1); + this->ike_sa->get_pending_updates(this->ike_sa) + 1); } -/** - * Implementation of ike_mobike_t.dpd - */ -static void dpd(private_ike_mobike_t *this) +METHOD(ike_mobike_t, dpd, void, + private_ike_mobike_t *this) { if (!this->natd) { this->natd = ike_natd_create(this->ike_sa, this->initiator); } - this->address = FALSE; this->ike_sa->set_pending_updates(this->ike_sa, - this->ike_sa->get_pending_updates(this->ike_sa) + 1); + this->ike_sa->get_pending_updates(this->ike_sa) + 1); } -/** - * Implementation of ike_mobike_t.is_probing. - */ -static bool is_probing(private_ike_mobike_t *this) +METHOD(ike_mobike_t, is_probing, bool, + private_ike_mobike_t *this) { return this->check; } -/** - * Implementation of task_t.get_type - */ -static task_type_t get_type(private_ike_mobike_t *this) +METHOD(task_t, get_type, task_type_t, + private_ike_mobike_t *this) { return IKE_MOBIKE; } -/** - * Implementation of task_t.migrate - */ -static void migrate(private_ike_mobike_t *this, ike_sa_t *ike_sa) +METHOD(task_t, migrate, void, + private_ike_mobike_t *this, ike_sa_t *ike_sa) { chunk_free(&this->cookie2); this->ike_sa = ike_sa; @@ -607,10 +619,8 @@ static void migrate(private_ike_mobike_t *this, ike_sa_t *ike_sa) } } -/** - * Implementation of task_t.destroy - */ -static void destroy(private_ike_mobike_t *this) +METHOD(task_t, destroy, void, + private_ike_mobike_t *this) { chunk_free(&this->cookie2); if (this->natd) @@ -625,35 +635,36 @@ static void destroy(private_ike_mobike_t *this) */ ike_mobike_t *ike_mobike_create(ike_sa_t *ike_sa, bool initiator) { - private_ike_mobike_t *this = malloc_thing(private_ike_mobike_t); - - this->public.roam = (void(*)(ike_mobike_t*,bool))roam; - this->public.dpd = (void(*)(ike_mobike_t*))dpd; - this->public.transmit = (void(*)(ike_mobike_t*,packet_t*))transmit; - this->public.is_probing = (bool(*)(ike_mobike_t*))is_probing; - this->public.task.get_type = (task_type_t(*)(task_t*))get_type; - this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate; - this->public.task.destroy = (void(*)(task_t*))destroy; + private_ike_mobike_t *this; + + INIT(this, + .public = { + .task = { + .get_type = _get_type, + .migrate = _migrate, + .destroy = _destroy, + }, + .addresses = _addresses, + .roam = _roam, + .dpd = _dpd, + .transmit = _transmit, + .is_probing = _is_probing, + }, + .ike_sa = ike_sa, + .initiator = initiator, + ); if (initiator) { - this->public.task.build = (status_t(*)(task_t*,message_t*))build_i; - this->public.task.process = (status_t(*)(task_t*,message_t*))process_i; + this->public.task.build = _build_i; + this->public.task.process = _process_i; } else { - 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->public.task.build = _build_r; + this->public.task.process = _process_r; } - this->ike_sa = ike_sa; - this->initiator = initiator; - this->update = FALSE; - this->check = FALSE; - this->address = TRUE; - this->cookie2 = chunk_empty; - this->natd = NULL; - return &this->public; } diff --git a/src/libcharon/sa/tasks/ike_mobike.h b/src/libcharon/sa/tasks/ike_mobike.h index 05b2224d1..16611939e 100644 --- a/src/libcharon/sa/tasks/ike_mobike.h +++ b/src/libcharon/sa/tasks/ike_mobike.h @@ -46,6 +46,11 @@ struct ike_mobike_t { task_t task; /** + * Use the task to update the list of additional addresses. + */ + void (*addresses)(ike_mobike_t *this); + + /** * Use the task to roam to other addresses. * * @param address TRUE to include address list update diff --git a/src/libcharon/sa/tasks/ike_natd.c b/src/libcharon/sa/tasks/ike_natd.c index 9ea20ba36..7839b52eb 100644 --- a/src/libcharon/sa/tasks/ike_natd.c +++ b/src/libcharon/sa/tasks/ike_natd.c @@ -18,6 +18,7 @@ #include <string.h> +#include <hydra.h> #include <daemon.h> #include <config/peer_cfg.h> #include <crypto/hashers/hasher.h> @@ -265,41 +266,15 @@ static status_t process_i(private_ike_natd_t *this, message_t *message) if (message->get_exchange_type(message) == IKE_SA_INIT) { peer_cfg_t *peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa); - -#ifdef ME - /* if we are on a mediated connection we have already switched to - * port 4500 and the correct destination port is already configured, - * therefore we must not switch again */ - if (peer_cfg->get_mediated_by(peer_cfg)) - { - return SUCCESS; - } -#endif /* ME */ - if (this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY) || -#ifdef ME - /* if we are on a mediation connection we switch to port 4500 even - * if no NAT is detected. */ - peer_cfg->is_mediation(peer_cfg) || -#endif /* ME */ /* if peer supports NAT-T, we switch to port 4500 even - * if no NAT is detected. MOBIKE requires this. */ + * if no NAT is detected. can't be done later (when we would know + * whether the peer supports MOBIKE) because there would be no + * exchange to actually do the switch (other than a forced DPD). */ (peer_cfg->use_mobike(peer_cfg) && this->ike_sa->supports_extension(this->ike_sa, EXT_NATT))) { - host_t *me, *other; - - /* do not switch if we have a custom port from mobike/NAT */ - me = this->ike_sa->get_my_host(this->ike_sa); - if (me->get_port(me) == IKEV2_UDP_PORT) - { - me->set_port(me, IKEV2_NATT_PORT); - } - other = this->ike_sa->get_other_host(this->ike_sa); - if (other->get_port(other) == IKEV2_UDP_PORT) - { - other->set_port(other, IKEV2_NATT_PORT); - } + this->ike_sa->float_ports(this->ike_sa); } } @@ -342,7 +317,7 @@ static status_t build_i(private_ike_natd_t *this, message_t *message) } else { - host = charon->kernel_interface->get_source_addr(charon->kernel_interface, + host = hydra->kernel_interface->get_source_addr(hydra->kernel_interface, this->ike_sa->get_other_host(this->ike_sa), NULL); if (host) { /* 2. */ @@ -353,8 +328,8 @@ static status_t build_i(private_ike_natd_t *this, message_t *message) } else { /* 3. */ - enumerator = charon->kernel_interface->create_address_enumerator( - charon->kernel_interface, FALSE, FALSE); + enumerator = hydra->kernel_interface->create_address_enumerator( + hydra->kernel_interface, FALSE, FALSE); while (enumerator->enumerate(enumerator, (void**)&host)) { /* apply port 500 to host, but work on a copy */ diff --git a/src/libcharon/sa/tasks/ike_rekey.c b/src/libcharon/sa/tasks/ike_rekey.c index a2275e796..1a6c140c4 100644 --- a/src/libcharon/sa/tasks/ike_rekey.c +++ b/src/libcharon/sa/tasks/ike_rekey.c @@ -196,7 +196,7 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message) 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, + lib->processor->queue_job(lib->processor, (job_t*)rekey_ike_sa_job_create( this->ike_sa->get_id(this->ike_sa), TRUE)); return SUCCESS; @@ -217,7 +217,7 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message) DBG1(DBG_IKE, "IKE_SA rekeying failed, " "trying again in %d seconds", retry); this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED); - charon->scheduler->schedule_job(charon->scheduler, job, retry); + lib->scheduler->schedule_job(lib->scheduler, job, retry); } return SUCCESS; case NEED_MORE: @@ -241,51 +241,56 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message) if (this->collision && this->collision->get_type(this->collision) == IKE_REKEY) { - chunk_t this_nonce, other_nonce; - host_t *host; private_ike_rekey_t *other = (private_ike_rekey_t*)this->collision; - this_nonce = this->ike_init->get_lower_nonce(this->ike_init); - other_nonce = other->ike_init->get_lower_nonce(other->ike_init); - - /* if we have the lower nonce, delete rekeyed SA. If not, delete - * the redundant. */ - if (memcmp(this_nonce.ptr, other_nonce.ptr, - min(this_nonce.len, other_nonce.len)) < 0) - { - /* peer should delete this SA. Add a timeout just in case. */ - job_t *job = (job_t*)delete_ike_sa_job_create( - other->new_sa->get_id(other->new_sa), TRUE); - charon->scheduler->schedule_job(charon->scheduler, job, 10); - DBG1(DBG_IKE, "IKE_SA rekey collision won, deleting rekeyed IKE_SA"); - charon->ike_sa_manager->checkin(charon->ike_sa_manager, other->new_sa); - other->new_sa = NULL; - } - else + /* ike_init can be NULL, if child_sa is half-open */ + if (other->ike_init) { - DBG1(DBG_IKE, "IKE_SA rekey collision lost, deleting redundant IKE_SA"); - /* apply host for a proper delete */ - host = this->ike_sa->get_my_host(this->ike_sa); - this->new_sa->set_my_host(this->new_sa, host->clone(host)); - host = this->ike_sa->get_other_host(this->ike_sa); - this->new_sa->set_other_host(this->new_sa, host->clone(host)); - this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED); - if (this->new_sa->delete(this->new_sa) == DESTROY_ME) + host_t *host; + chunk_t this_nonce, other_nonce; + + this_nonce = this->ike_init->get_lower_nonce(this->ike_init); + other_nonce = other->ike_init->get_lower_nonce(other->ike_init); + + /* if we have the lower nonce, delete rekeyed SA. If not, delete + * the redundant. */ + if (memcmp(this_nonce.ptr, other_nonce.ptr, + min(this_nonce.len, other_nonce.len)) < 0) { - charon->ike_sa_manager->checkin_and_destroy( - charon->ike_sa_manager, this->new_sa); + /* peer should delete this SA. Add a timeout just in case. */ + job_t *job = (job_t*)delete_ike_sa_job_create( + other->new_sa->get_id(other->new_sa), TRUE); + lib->scheduler->schedule_job(lib->scheduler, job, 10); + DBG1(DBG_IKE, "IKE_SA rekey collision won, deleting rekeyed IKE_SA"); + charon->ike_sa_manager->checkin(charon->ike_sa_manager, other->new_sa); + other->new_sa = NULL; } else { - charon->ike_sa_manager->checkin( - charon->ike_sa_manager, this->new_sa); + DBG1(DBG_IKE, "IKE_SA rekey collision lost, deleting redundant IKE_SA"); + /* apply host for a proper delete */ + host = this->ike_sa->get_my_host(this->ike_sa); + this->new_sa->set_my_host(this->new_sa, host->clone(host)); + host = this->ike_sa->get_other_host(this->ike_sa); + this->new_sa->set_other_host(this->new_sa, host->clone(host)); + this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED); + if (this->new_sa->delete(this->new_sa) == DESTROY_ME) + { + charon->ike_sa_manager->checkin_and_destroy( + charon->ike_sa_manager, this->new_sa); + } + else + { + charon->ike_sa_manager->checkin( + charon->ike_sa_manager, this->new_sa); + } + /* set threads active IKE_SA after checkin */ + charon->bus->set_sa(charon->bus, this->ike_sa); + /* inherit to other->new_sa in destroy() */ + this->new_sa = other->new_sa; + other->new_sa = NULL; + return SUCCESS; } - /* set threads active IKE_SA after checkin */ - charon->bus->set_sa(charon->bus, this->ike_sa); - /* inherit to other->new_sa in destroy() */ - this->new_sa = other->new_sa; - other->new_sa = NULL; - return SUCCESS; } /* set threads active IKE_SA after checkin */ charon->bus->set_sa(charon->bus, this->ike_sa); diff --git a/src/libcharon/sa/tasks/ike_vendor.c b/src/libcharon/sa/tasks/ike_vendor.c index 7c435b6d1..1c14ee06b 100644 --- a/src/libcharon/sa/tasks/ike_vendor.c +++ b/src/libcharon/sa/tasks/ike_vendor.c @@ -123,12 +123,14 @@ ike_vendor_t *ike_vendor_create(ike_sa_t *ike_sa, bool initiator) private_ike_vendor_t *this; INIT(this, - .public.task = { - .build = _build, - .process = _process, - .migrate = _migrate, - .get_type = _get_type, - .destroy = _destroy, + .public = { + .task = { + .build = _build, + .process = _process, + .migrate = _migrate, + .get_type = _get_type, + .destroy = _destroy, + }, }, .initiator = initiator, .ike_sa = ike_sa, |