From 622b56a52e688792c73edd921ca56478ddb4e3bc Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Wed, 8 Jul 2009 14:33:24 +0200 Subject: [PATCH] implemented ike_rekey()/child_rekey() bus hooks --- src/charon/bus/bus.c | 63 +++++++++++++++++++++++++++++++ src/charon/bus/bus.h | 17 +++++++++ src/charon/sa/tasks/child_rekey.c | 10 +++++ src/charon/sa/tasks/ike_rekey.c | 2 + 4 files changed, 92 insertions(+) diff --git a/src/charon/bus/bus.c b/src/charon/bus/bus.c index db0ba9a11..3a3112217 100644 --- a/src/charon/bus/bus.c +++ b/src/charon/bus/bus.c @@ -513,6 +513,67 @@ static void child_keys(private_bus_t *this, child_sa_t *child_sa, this->mutex->unlock(this->mutex); } +/** + * Implementation of bus_t.ike_rekey + */ +static void ike_rekey(private_bus_t *this, ike_sa_t *old, ike_sa_t *new) +{ + enumerator_t *enumerator; + entry_t *entry; + bool keep; + + this->mutex->lock(this->mutex); + enumerator = this->listeners->create_enumerator(this->listeners); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->calling || !entry->listener->ike_rekey) + { + continue; + } + entry->calling++; + keep = entry->listener->ike_rekey(entry->listener, old, new); + entry->calling--; + if (!keep) + { + unregister_listener(this, entry, enumerator); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + +/** + * Implementation of bus_t.child_rekey + */ +static void child_rekey(private_bus_t *this, child_sa_t *old, child_sa_t *new) +{ + enumerator_t *enumerator; + ike_sa_t *ike_sa; + entry_t *entry; + bool keep; + + ike_sa = pthread_getspecific(this->thread_sa); + + this->mutex->lock(this->mutex); + enumerator = this->listeners->create_enumerator(this->listeners); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->calling || !entry->listener->child_rekey) + { + continue; + } + entry->calling++; + keep = entry->listener->child_rekey(entry->listener, ike_sa, old, new); + entry->calling--; + if (!keep) + { + unregister_listener(this, entry, enumerator); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + /** * Implementation of bus_t.authorize */ @@ -579,6 +640,8 @@ bus_t *bus_create() this->public.message = (void(*)(bus_t*, message_t *message, bool incoming))message; this->public.ike_keys = (void(*)(bus_t*, ike_sa_t *ike_sa, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey))ike_keys; this->public.child_keys = (void(*)(bus_t*, child_sa_t *child_sa, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r))child_keys; + this->public.ike_rekey = (void(*)(bus_t*, ike_sa_t *old, ike_sa_t *new))ike_rekey; + this->public.child_rekey = (void(*)(bus_t*, child_sa_t *old, child_sa_t *new))child_rekey; this->public.authorize = (bool(*)(bus_t*, linked_list_t *auth, bool final))authorize; this->public.destroy = (void(*)(bus_t*)) destroy; diff --git a/src/charon/bus/bus.h b/src/charon/bus/bus.h index 4fe6522da..f8de63a04 100644 --- a/src/charon/bus/bus.h +++ b/src/charon/bus/bus.h @@ -260,6 +260,23 @@ struct bus_t { */ void (*child_keys)(bus_t *this, child_sa_t *child_sa, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r); + + /** + * IKE_SA rekeying hook. + * + * @param old rekeyed and obsolete IKE_SA + * @param new new IKE_SA replacing old + */ + void (*ike_rekey)(bus_t *this, ike_sa_t *old, ike_sa_t *new); + + /** + * CHILD_SA rekeying hook. + * + * @param old rekeyed and obsolete CHILD_SA + * @param new new CHILD_SA replacing old + */ + void (*child_rekey)(bus_t *this, child_sa_t *old, child_sa_t *new); + /** * Destroy the event bus. */ diff --git a/src/charon/sa/tasks/child_rekey.c b/src/charon/sa/tasks/child_rekey.c index 6ab00dc5b..b5e3789ed 100644 --- a/src/charon/sa/tasks/child_rekey.c +++ b/src/charon/sa/tasks/child_rekey.c @@ -207,6 +207,10 @@ static status_t build_r(private_child_rekey_t *this, message_t *message) } this->child_sa->set_state(this->child_sa, CHILD_REKEYING); + + /* invoke rekey hook */ + charon->bus->child_rekey(charon->bus, this->child_sa, + this->child_create->get_child(this->child_create)); return SUCCESS; } @@ -303,6 +307,12 @@ static status_t process_i(private_child_rekey_t *this, message_t *message) } } + if (to_delete != this->child_create->get_child(this->child_create)) + { /* invoke rekey hook if rekeying successful */ + charon->bus->child_rekey(charon->bus, this->child_sa, + this->child_create->get_child(this->child_create)); + } + spi = to_delete->get_spi(to_delete, TRUE); protocol = to_delete->get_protocol(to_delete); diff --git a/src/charon/sa/tasks/ike_rekey.c b/src/charon/sa/tasks/ike_rekey.c index bead408a6..3a049b566 100644 --- a/src/charon/sa/tasks/ike_rekey.c +++ b/src/charon/sa/tasks/ike_rekey.c @@ -367,6 +367,8 @@ static void destroy(private_ike_rekey_t *this) if (this->new_sa->get_state(this->new_sa) == IKE_ESTABLISHED && this->new_sa->inherit(this->new_sa, this->ike_sa) != DESTROY_ME) { + /* invoke hook if rekeying was successful */ + charon->bus->ike_rekey(charon->bus, this->ike_sa, this->new_sa); charon->ike_sa_manager->checkin(charon->ike_sa_manager, this->new_sa); } else