diff options
Diffstat (limited to 'src/libcharon/bus')
-rw-r--r-- | src/libcharon/bus/bus.c | 212 | ||||
-rw-r--r-- | src/libcharon/bus/bus.h | 42 | ||||
-rw-r--r-- | src/libcharon/bus/listeners/file_logger.c | 32 | ||||
-rw-r--r-- | src/libcharon/bus/listeners/file_logger.h | 7 | ||||
-rw-r--r-- | src/libcharon/bus/listeners/listener.h | 19 | ||||
-rw-r--r-- | src/libcharon/bus/listeners/sys_logger.c | 1 | ||||
-rw-r--r-- | src/libcharon/bus/listeners/sys_logger.h | 2 |
7 files changed, 194 insertions, 121 deletions
diff --git a/src/libcharon/bus/bus.c b/src/libcharon/bus/bus.c index 764744a41..441009e5e 100644 --- a/src/libcharon/bus/bus.c +++ b/src/libcharon/bus/bus.c @@ -102,20 +102,16 @@ static void entry_destroy(entry_t *entry) free(entry); } -/** - * Implementation of bus_t.add_listener. - */ -static void add_listener(private_bus_t *this, listener_t *listener) +METHOD(bus_t, add_listener, void, + private_bus_t *this, listener_t *listener) { this->mutex->lock(this->mutex); this->listeners->insert_last(this->listeners, entry_create(listener, FALSE)); this->mutex->unlock(this->mutex); } -/** - * Implementation of bus_t.remove_listener. - */ -static void remove_listener(private_bus_t *this, listener_t *listener) +METHOD(bus_t, remove_listener, void, + private_bus_t *this, listener_t *listener) { enumerator_t *enumerator; entry_t *entry; @@ -156,10 +152,8 @@ static void listener_cleanup(cleanup_data_t *data) entry_destroy(data->entry); } -/** - * Implementation of bus_t.listen. - */ -static void listen_(private_bus_t *this, listener_t *listener, job_t *job) +METHOD(bus_t, listen_, void, + private_bus_t *this, listener_t *listener, job_t *job) { bool old; cleanup_data_t data; @@ -184,18 +178,14 @@ static void listen_(private_bus_t *this, listener_t *listener, job_t *job) entry_destroy(data.entry); } -/** - * Implementation of bus_t.set_sa. - */ -static void set_sa(private_bus_t *this, ike_sa_t *ike_sa) +METHOD(bus_t, set_sa, void, + private_bus_t *this, ike_sa_t *ike_sa) { this->thread_sa->set(this->thread_sa, ike_sa); } -/** - * Implementation of bus_t.get_sa - */ -static ike_sa_t* get_sa(private_bus_t *this) +METHOD(bus_t, get_sa, ike_sa_t*, + private_bus_t *this) { return this->thread_sa->get(this->thread_sa); } @@ -252,11 +242,9 @@ static bool log_cb(entry_t *entry, log_data_t *data) return FALSE; } -/** - * Implementation of bus_t.vlog. - */ -static void vlog(private_bus_t *this, debug_t group, level_t level, - char* format, va_list args) +METHOD(bus_t, vlog, void, + private_bus_t *this, debug_t group, level_t level, + char* format, va_list args) { log_data_t data; @@ -276,11 +264,8 @@ static void vlog(private_bus_t *this, debug_t group, level_t level, va_end(data.args); } -/** - * Implementation of bus_t.log. - */ -static void log_(private_bus_t *this, debug_t group, level_t level, - char* format, ...) +METHOD(bus_t, log_, void, + private_bus_t *this, debug_t group, level_t level, char* format, ...) { va_list args; @@ -307,10 +292,8 @@ static void unregister_listener(private_bus_t *this, entry_t *entry, this->listeners->remove_at(this->listeners, enumerator); } -/** - * Implementation of bus_t.alert - */ -static void alert(private_bus_t *this, alert_t alert, ...) +METHOD(bus_t, alert, void, + private_bus_t *this, alert_t alert, ...) { enumerator_t *enumerator; ike_sa_t *ike_sa; @@ -342,11 +325,8 @@ static void alert(private_bus_t *this, alert_t alert, ...) this->mutex->unlock(this->mutex); } -/** - * Implementation of bus_t.ike_state_change - */ -static void ike_state_change(private_bus_t *this, ike_sa_t *ike_sa, - ike_sa_state_t state) +METHOD(bus_t, ike_state_change, void, + private_bus_t *this, ike_sa_t *ike_sa, ike_sa_state_t state) { enumerator_t *enumerator; entry_t *entry; @@ -372,11 +352,8 @@ static void ike_state_change(private_bus_t *this, ike_sa_t *ike_sa, this->mutex->unlock(this->mutex); } -/** - * Implementation of bus_t.child_state_change - */ -static void child_state_change(private_bus_t *this, child_sa_t *child_sa, - child_sa_state_t state) +METHOD(bus_t, child_state_change, void, + private_bus_t *this, child_sa_t *child_sa, child_sa_state_t state) { enumerator_t *enumerator; ike_sa_t *ike_sa; @@ -406,10 +383,8 @@ static void child_state_change(private_bus_t *this, child_sa_t *child_sa, this->mutex->unlock(this->mutex); } -/** - * Implementation of bus_t.message - */ -static void message(private_bus_t *this, message_t *message, bool incoming) +METHOD(bus_t, message, void, + private_bus_t *this, message_t *message, bool incoming) { enumerator_t *enumerator; ike_sa_t *ike_sa; @@ -439,12 +414,9 @@ static void message(private_bus_t *this, message_t *message, bool incoming) this->mutex->unlock(this->mutex); } -/** - * Implementation of bus_t.ike_keys - */ -static void ike_keys(private_bus_t *this, ike_sa_t *ike_sa, - diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r, - ike_sa_t *rekey) +METHOD(bus_t, ike_keys, void, + private_bus_t *this, ike_sa_t *ike_sa, diffie_hellman_t *dh, + chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey) { enumerator_t *enumerator; entry_t *entry; @@ -471,11 +443,9 @@ static void ike_keys(private_bus_t *this, ike_sa_t *ike_sa, this->mutex->unlock(this->mutex); } -/** - * Implementation of bus_t.child_keys - */ -static void child_keys(private_bus_t *this, child_sa_t *child_sa, - diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r) +METHOD(bus_t, child_keys, void, + private_bus_t *this, child_sa_t *child_sa, bool initiator, + diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r) { enumerator_t *enumerator; ike_sa_t *ike_sa; @@ -494,7 +464,7 @@ static void child_keys(private_bus_t *this, child_sa_t *child_sa, } entry->calling++; keep = entry->listener->child_keys(entry->listener, ike_sa, child_sa, - dh, nonce_i, nonce_r); + initiator, dh, nonce_i, nonce_r); entry->calling--; if (!keep) { @@ -505,10 +475,8 @@ static void child_keys(private_bus_t *this, child_sa_t *child_sa, this->mutex->unlock(this->mutex); } -/** - * Implementation of bus_t.child_updown - */ -static void child_updown(private_bus_t *this, child_sa_t *child_sa, bool up) +METHOD(bus_t, child_updown, void, + private_bus_t *this, child_sa_t *child_sa, bool up) { enumerator_t *enumerator; ike_sa_t *ike_sa; @@ -538,10 +506,8 @@ static void child_updown(private_bus_t *this, child_sa_t *child_sa, bool up) 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) +METHOD(bus_t, child_rekey, void, + private_bus_t *this, child_sa_t *old, child_sa_t *new) { enumerator_t *enumerator; ike_sa_t *ike_sa; @@ -570,10 +536,8 @@ static void child_rekey(private_bus_t *this, child_sa_t *old, child_sa_t *new) this->mutex->unlock(this->mutex); } -/** - * Implementation of bus_t.ike_updown - */ -static void ike_updown(private_bus_t *this, ike_sa_t *ike_sa, bool up) +METHOD(bus_t, ike_updown, void, + private_bus_t *this, ike_sa_t *ike_sa, bool up) { enumerator_t *enumerator; entry_t *entry; @@ -613,10 +577,8 @@ static void ike_updown(private_bus_t *this, ike_sa_t *ike_sa, bool up) } } -/** - * Implementation of bus_t.ike_rekey - */ -static void ike_rekey(private_bus_t *this, ike_sa_t *old, ike_sa_t *new) +METHOD(bus_t, ike_rekey, void, + private_bus_t *this, ike_sa_t *old, ike_sa_t *new) { enumerator_t *enumerator; entry_t *entry; @@ -642,10 +604,8 @@ static void ike_rekey(private_bus_t *this, ike_sa_t *old, ike_sa_t *new) this->mutex->unlock(this->mutex); } -/** - * Implementation of bus_t.authorize - */ -static bool authorize(private_bus_t *this, bool final) +METHOD(bus_t, authorize, bool, + private_bus_t *this, bool final) { enumerator_t *enumerator; ike_sa_t *ike_sa; @@ -680,10 +640,40 @@ static bool authorize(private_bus_t *this, bool final) return success; } -/** - * Implementation of bus_t.destroy. - */ -static void destroy(private_bus_t *this) +METHOD(bus_t, narrow, void, + private_bus_t *this, child_sa_t *child_sa, narrow_hook_t type, + linked_list_t *local, linked_list_t *remote) +{ + enumerator_t *enumerator; + ike_sa_t *ike_sa; + entry_t *entry; + bool keep; + + ike_sa = this->thread_sa->get(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->narrow) + { + continue; + } + entry->calling++; + keep = entry->listener->narrow(entry->listener, ike_sa, child_sa, + type, local, remote); + entry->calling--; + if (!keep) + { + unregister_listener(this, entry, enumerator); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + +METHOD(bus_t, destroy, void, + private_bus_t *this) { this->thread_sa->destroy(this->thread_sa); this->mutex->destroy(this->mutex); @@ -696,31 +686,35 @@ static void destroy(private_bus_t *this) */ bus_t *bus_create() { - private_bus_t *this = malloc_thing(private_bus_t); - - this->public.add_listener = (void(*)(bus_t*,listener_t*))add_listener; - this->public.remove_listener = (void(*)(bus_t*,listener_t*))remove_listener; - this->public.listen = (void(*)(bus_t*, listener_t *listener, job_t *job))listen_; - this->public.set_sa = (void(*)(bus_t*,ike_sa_t*))set_sa; - this->public.get_sa = (ike_sa_t*(*)(bus_t*))get_sa; - this->public.log = (void(*)(bus_t*,debug_t,level_t,char*,...))log_; - this->public.vlog = (void(*)(bus_t*,debug_t,level_t,char*,va_list))vlog; - this->public.alert = (void(*)(bus_t*, alert_t alert, ...))alert; - this->public.ike_state_change = (void(*)(bus_t*,ike_sa_t*,ike_sa_state_t))ike_state_change; - this->public.child_state_change = (void(*)(bus_t*,child_sa_t*,child_sa_state_t))child_state_change; - 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_updown = (void(*)(bus_t*, ike_sa_t *ike_sa, bool up))ike_updown; - this->public.ike_rekey = (void(*)(bus_t*, ike_sa_t *old, ike_sa_t *new))ike_rekey; - this->public.child_updown = (void(*)(bus_t*, child_sa_t *child_sa, bool up))child_updown; - this->public.child_rekey = (void(*)(bus_t*, child_sa_t *old, child_sa_t *new))child_rekey; - this->public.authorize = (bool(*)(bus_t*, bool final))authorize; - this->public.destroy = (void(*)(bus_t*)) destroy; - - this->listeners = linked_list_create(); - this->mutex = mutex_create(MUTEX_TYPE_RECURSIVE); - this->thread_sa = thread_value_create(NULL); + private_bus_t *this; + + INIT(this, + .public = { + .add_listener = _add_listener, + .remove_listener = _remove_listener, + .listen = _listen_, + .set_sa = _set_sa, + .get_sa = _get_sa, + .log = _log_, + .vlog = _vlog, + .alert = _alert, + .ike_state_change = _ike_state_change, + .child_state_change = _child_state_change, + .message = _message, + .ike_keys = _ike_keys, + .child_keys = _child_keys, + .ike_updown = _ike_updown, + .ike_rekey = _ike_rekey, + .child_updown = _child_updown, + .child_rekey = _child_rekey, + .authorize = _authorize, + .narrow = _narrow, + .destroy = _destroy, + }, + .listeners = linked_list_create(), + .mutex = mutex_create(MUTEX_TYPE_RECURSIVE), + .thread_sa = thread_value_create(NULL), + ); return &this->public; } diff --git a/src/libcharon/bus/bus.h b/src/libcharon/bus/bus.h index 8cf392eae..6a306afcc 100644 --- a/src/libcharon/bus/bus.h +++ b/src/libcharon/bus/bus.h @@ -22,6 +22,7 @@ #define BUS_H_ typedef enum alert_t alert_t; +typedef enum narrow_hook_t narrow_hook_t; typedef struct bus_t bus_t; #include <stdarg.h> @@ -86,6 +87,31 @@ enum alert_t { }; /** + * Kind of narrow hook. + * + * There is a non-authenticated (IKE_AUTH) and a authenticated + * (CREATE_CHILD_SA) narrowing hook for the initiator. Only one of these + * hooks is invoked before the exchange. + * To verify the traffic selectors negotiated, each PRE hook has a POST + * counterpart that follows. POST hooks are invoked with an authenticated peer. + * It is usually not a good idea to narrow in the POST hooks, + * as the resulting traffic selector is not negotiated and results + * in non-matching policies. + */ +enum narrow_hook_t { + /** invoked as initiator before exchange, peer is not yet authenticated */ + NARROW_INITIATOR_PRE_NOAUTH, + /** invoked as initiator before exchange, peer is authenticated */ + NARROW_INITIATOR_PRE_AUTH, + /** invoked as responder during exchange, peer is authenticated */ + NARROW_RESPONDER, + /** invoked as initiator after exchange, follows a INITIATOR_PRE_NOAUTH */ + NARROW_INITIATOR_POST_NOAUTH, + /** invoked as initiator after exchange, follows a INITIATOR_PRE_AUTH */ + NARROW_INITIATOR_POST_AUTH, +}; + +/** * The bus receives events and sends them to all registered listeners. * * Any events sent to are delivered to all registered listeners. Threads @@ -217,6 +243,17 @@ struct bus_t { bool (*authorize)(bus_t *this, bool final); /** + * CHILD_SA traffic selector narrowing hook. + * + * @param child_sa CHILD_SA set up with these traffic selectors + * @param type type of hook getting invoked + * @param local list of local traffic selectors to narrow + * @param remote list of remote traffic selectors to narrow + */ + void (*narrow)(bus_t *this, child_sa_t *child_sa, narrow_hook_t type, + linked_list_t *local, linked_list_t *remote); + + /** * IKE_SA keymat hook. * * @param ike_sa IKE_SA this keymat belongs to @@ -231,12 +268,13 @@ struct bus_t { * CHILD_SA keymat hook. * * @param child_sa CHILD_SA this keymat is used for + * @param initiator initiator of the CREATE_CHILD_SA exchange * @param dh diffie hellman shared secret * @param nonce_i initiators nonce * @param nonce_r responders nonce */ - void (*child_keys)(bus_t *this, child_sa_t *child_sa, diffie_hellman_t *dh, - chunk_t nonce_i, chunk_t nonce_r); + void (*child_keys)(bus_t *this, child_sa_t *child_sa, bool initiator, + diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r); /** * IKE_SA up/down hook. diff --git a/src/libcharon/bus/listeners/file_logger.c b/src/libcharon/bus/listeners/file_logger.c index 12587deaf..87db532f5 100644 --- a/src/libcharon/bus/listeners/file_logger.c +++ b/src/libcharon/bus/listeners/file_logger.c @@ -15,6 +15,7 @@ #include <stdio.h> #include <string.h> +#include <time.h> #include "file_logger.h" @@ -40,6 +41,11 @@ struct private_file_logger_t { * Maximum level to log, for each group */ level_t levels[DBG_MAX]; + + /** + * strftime() format of time prefix, if any + */ + char *time_format; }; /** @@ -50,8 +56,17 @@ static bool log_(private_file_logger_t *this, debug_t group, level_t level, { if (level <= this->levels[group]) { - char buffer[8192]; + char buffer[8192], timestr[128]; char *current = buffer, *next; + struct tm tm; + time_t t; + + if (this->time_format) + { + t = time(NULL); + localtime_r(&t, &tm); + strftime(timestr, sizeof(timestr), this->time_format, &tm); + } /* write in memory buffer first */ vsnprintf(buffer, sizeof(buffer), format, args); @@ -64,8 +79,16 @@ static bool log_(private_file_logger_t *this, debug_t group, level_t level, { *(next++) = '\0'; } - fprintf(this->out, "%.2d[%N] %s\n", - thread, debug_names, group, current); + if (this->time_format) + { + fprintf(this->out, "%s %.2d[%N] %s\n", + timestr, thread, debug_names, group, current); + } + else + { + fprintf(this->out, "%.2d[%N] %s\n", + thread, debug_names, group, current); + } current = next; } } @@ -106,7 +129,7 @@ static void destroy(private_file_logger_t *this) /* * Described in header. */ -file_logger_t *file_logger_create(FILE *out) +file_logger_t *file_logger_create(FILE *out, char *time_format) { private_file_logger_t *this = malloc_thing(private_file_logger_t); @@ -118,6 +141,7 @@ file_logger_t *file_logger_create(FILE *out) /* private variables */ this->out = out; + this->time_format = time_format; set_level(this, DBG_ANY, LEVEL_SILENT); return &this->public; diff --git a/src/libcharon/bus/listeners/file_logger.h b/src/libcharon/bus/listeners/file_logger.h index bd443fdb8..e02a12c0c 100644 --- a/src/libcharon/bus/listeners/file_logger.h +++ b/src/libcharon/bus/listeners/file_logger.h @@ -52,9 +52,10 @@ struct file_logger_t { /** * Constructor to create a file_logger_t object. * - * @param out FILE to write to - * @return file_logger_t object + * @param out FILE to write to + * @param time_format format of timestamp prefix, as in strftime() + * @return file_logger_t object */ -file_logger_t *file_logger_create(FILE *out); +file_logger_t *file_logger_create(FILE *out, char *time_format); #endif /** FILE_LOGGER_H_ @}*/ diff --git a/src/libcharon/bus/listeners/listener.h b/src/libcharon/bus/listeners/listener.h index 9a51a2ef4..e7873ee8c 100644 --- a/src/libcharon/bus/listeners/listener.h +++ b/src/libcharon/bus/listeners/listener.h @@ -110,13 +110,15 @@ struct listener_t { * * @param ike_sa IKE_SA the child sa belongs to * @param child_sa CHILD_SA this keymat is used for + * @param initiator initiator of the CREATE_CHILD_SA exchange * @param dh diffie hellman shared secret * @param nonce_i initiators nonce * @param nonce_r responders nonce * @return TRUE to stay registered, FALSE to unregister */ bool (*child_keys)(listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, - diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r); + bool initiator, diffie_hellman_t *dh, + chunk_t nonce_i, chunk_t nonce_r); /** * Hook called if an IKE_SA gets up or down. @@ -173,6 +175,21 @@ struct listener_t { */ bool (*authorize)(listener_t *this, ike_sa_t *ike_sa, bool final, bool *success); + + /** + * CHILD_SA traffic selector narrowing hook. + * + * This hook is invoked for each CHILD_SA and allows plugins to modify + * the traffic selector list negotiated for this CHILD_SA. + * + * @param ike_sa IKE_SA the created CHILD_SA is created in + * @param child_sa CHILD_SA set up with these traffic selectors + * @param type type of hook getting invoked + * @param local list of local traffic selectors to narrow + * @param remote list of remote traffic selectors to narrow + */ + bool (*narrow)(listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, + narrow_hook_t type, linked_list_t *local, linked_list_t *remote); }; #endif /** LISTENER_H_ @}*/ diff --git a/src/libcharon/bus/listeners/sys_logger.c b/src/libcharon/bus/listeners/sys_logger.c index 11421ad05..5bc1d581a 100644 --- a/src/libcharon/bus/listeners/sys_logger.c +++ b/src/libcharon/bus/listeners/sys_logger.c @@ -15,6 +15,7 @@ #include <stdio.h> #include <string.h> +#include <syslog.h> #include "sys_logger.h" diff --git a/src/libcharon/bus/listeners/sys_logger.h b/src/libcharon/bus/listeners/sys_logger.h index 730890d68..58d4de529 100644 --- a/src/libcharon/bus/listeners/sys_logger.h +++ b/src/libcharon/bus/listeners/sys_logger.h @@ -21,8 +21,6 @@ #ifndef SYS_LOGGER_H_ #define SYS_LOGGER_H_ -#include <syslog.h> - #include <bus/listeners/listener.h> typedef struct sys_logger_t sys_logger_t; |