diff options
author | Martin Willi <martin@revosec.ch> | 2010-10-26 10:51:28 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2011-01-05 16:45:40 +0100 |
commit | f452a5a1f8c94359601cf843f635ba385d08ad5e (patch) | |
tree | 22a63aeb8de71cb780ab4c1d7d94dd5f29ed50d9 | |
parent | b318e0ab57d9a9e85445ca16c5c5c8926cc7a456 (diff) | |
download | strongswan-f452a5a1f8c94359601cf843f635ba385d08ad5e.tar.bz2 strongswan-f452a5a1f8c94359601cf843f635ba385d08ad5e.tar.xz |
Load hooks based on listener dynamically
-rw-r--r-- | src/conftest/Makefile.am | 4 | ||||
-rw-r--r-- | src/conftest/conftest.c | 69 | ||||
-rw-r--r-- | src/conftest/conftest.h | 5 | ||||
-rw-r--r-- | src/conftest/hooks/hook.h | 45 |
4 files changed, 108 insertions, 15 deletions
diff --git a/src/conftest/Makefile.am b/src/conftest/Makefile.am index d975810cb..0b041a42c 100644 --- a/src/conftest/Makefile.am +++ b/src/conftest/Makefile.am @@ -1,6 +1,8 @@ ipsec_PROGRAMS = conftest -conftest_SOURCES = conftest.c +AM_CFLAGS = -rdynamic + +conftest_SOURCES = conftest.c hooks/hook.h INCLUDES = \ -I$(top_srcdir)/src/libstrongswan \ diff --git a/src/conftest/conftest.c b/src/conftest/conftest.c index 777cf6817..881db5d92 100644 --- a/src/conftest/conftest.c +++ b/src/conftest/conftest.c @@ -13,14 +13,17 @@ * for more details. */ +#define _GNU_SOURCE #include <unistd.h> #include <stdio.h> #include <errno.h> #include <signal.h> #include <getopt.h> +#include <dlfcn.h> #include <libgen.h> #include "conftest.h" +#include "hooks/hook.h" #include <threading/thread.h> @@ -32,19 +35,8 @@ conftest_t *conftest; /** * Print usage information */ -static void usage(char *error) +static void usage(FILE *out) { - FILE *out = stdout; - - if (error) - { - out = stderr; - fprintf(out, "%s\n", error); - } - else - { - fprintf(out, "strongSwan %s conftest\n", VERSION); - } fprintf(out, "Usage:\n"); fprintf(out, " --help show usage information\n"); fprintf(out, " --version show conftest version\n"); @@ -147,14 +139,59 @@ static bool load_certs() } /** + * Load configured hooks + */ +static bool load_hooks() +{ + enumerator_t *enumerator; + char *name, buf[64]; + hook_t *(*create)(void); + hook_t *hook; + + enumerator = conftest->test->create_section_enumerator(conftest->test, + "hooks"); + while (enumerator->enumerate(enumerator, &name)) + { + snprintf(buf, sizeof(buf), "%s_hook_create", name); + create = dlsym(RTLD_DEFAULT, buf); + if (create) + { + hook = create(); + if (hook) + { + conftest->hooks->insert_last(conftest->hooks, hook); + charon->bus->add_listener(charon->bus, &hook->listener); + } + } + else + { + fprintf(stderr, "dlsym() for hook '%s' failed: %s\n", name, dlerror()); + enumerator->destroy(enumerator); + return FALSE; + } + } + enumerator->destroy(enumerator); + return TRUE; +} + +/** * atexit() cleanup handler */ static void cleanup() { + hook_t *hook; + DESTROY_IF(conftest->suite); DESTROY_IF(conftest->test); lib->credmgr->remove_set(lib->credmgr, &conftest->creds->set); conftest->creds->destroy(conftest->creds); + while (conftest->hooks->remove_last(conftest->hooks, + (void**)&hook) == SUCCESS) + { + charon->bus->remove_listener(charon->bus, &hook->listener); + hook->destroy(hook); + } + conftest->hooks->destroy(conftest->hooks); free(conftest->suite_dir); free(conftest->test_dir); free(conftest); @@ -221,7 +258,7 @@ int main(int argc, char *argv[]) case EOF: break; case 'h': - usage(NULL); + usage(stdout); return 0; case 'v': printf("strongSwan %s conftest\n", VERSION); @@ -233,7 +270,7 @@ int main(int argc, char *argv[]) test_file = optarg; continue; default: - usage("Invalid option."); + usage(stderr); return 1; } break; @@ -251,6 +288,10 @@ int main(int argc, char *argv[]) { return 1; } + if (!load_hooks()) + { + return 1; + } /* set up thread specific handlers */ action.sa_handler = segv_handler; diff --git a/src/conftest/conftest.h b/src/conftest/conftest.h index 22d3deb1b..614248ef4 100644 --- a/src/conftest/conftest.h +++ b/src/conftest/conftest.h @@ -56,6 +56,11 @@ struct conftest_t { * Credentials loaded from configuration */ mem_cred_t *creds; + + /** + * Loaded hooks + */ + linked_list_t *hooks; }; /** diff --git a/src/conftest/hooks/hook.h b/src/conftest/hooks/hook.h new file mode 100644 index 000000000..39a15f21b --- /dev/null +++ b/src/conftest/hooks/hook.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2010 Martin Willi + * Copyright (C) 2010 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup hook hook + * @{ @ingroup hooks + */ + +#ifndef HOOK_H_ +#define HOOK_H_ + +typedef struct hook_t hook_t; + +#include <daemon.h> +#include <conftest.h> + +/** + * Hook providing interface. + */ +struct hook_t { + + /** + * Implements listener_t. + */ + listener_t listener; + + /** + * Destroy a hook_t. + */ + void (*destroy)(hook_t *this); +}; + +#endif /** HOOK_H_ @}*/ |