diff options
Diffstat (limited to 'src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c')
-rw-r--r-- | src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c | 149 |
1 files changed, 127 insertions, 22 deletions
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c b/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c index 05d7b7ace..683efc10b 100644 --- a/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c +++ b/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c @@ -17,7 +17,128 @@ #include "tnc_imc_manager.h" #include "tnc_imc.h" +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> + #include <daemon.h> +#include <utils/lexparser.h> + +/** + * load IMCs from a configuration file + */ +static bool load_imcs(char *filename) +{ + int fd, line_nr = 0; + chunk_t src, line; + struct stat sb; + void *addr; + + DBG1(DBG_TNC, "loading IMCs from '%s'", filename); + fd = open(filename, O_RDONLY); + if (fd == -1) + { + DBG1(DBG_TNC, "opening configuration file '%s' failed: %s", filename, + strerror(errno)); + return FALSE; + } + if (fstat(fd, &sb) == -1) + { + DBG1(DBG_LIB, "getting file size of '%s' failed: %s", filename, + strerror(errno)); + close(fd); + return FALSE; + } + addr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + if (addr == MAP_FAILED) + { + DBG1(DBG_LIB, "mapping '%s' failed: %s", filename, strerror(errno)); + close(fd); + return FALSE; + } + src = chunk_create(addr, sb.st_size); + + while (fetchline(&src, &line)) + { + char *name, *path; + chunk_t token; + imc_t *imc; + + line_nr++; + + /* skip comments or empty lines */ + if (*line.ptr == '#' || !eat_whitespace(&line)) + { + continue; + } + + /* determine keyword */ + if (!extract_token(&token, ' ', &line)) + { + DBG1(DBG_TNC, "line %d: keyword must be followed by a space", + line_nr); + return FALSE; + } + + /* only interested in IMCs */ + if (!match("IMC", &token)) + { + continue; + } + + /* advance to the IMC name and extract it */ + if (!extract_token(&token, '"', &line) || + !extract_token(&token, '"', &line)) + { + DBG1(DBG_TNC, "line %d: IMC name must be set in double quotes", + line_nr); + return FALSE; + } + + /* copy the IMC name */ + name = malloc(token.len + 1); + memcpy(name, token.ptr, token.len); + name[token.len] = '\0'; + + /* advance to the IMC path and extract it */ + if (!eat_whitespace(&line)) + { + DBG1(DBG_TNC, "line %d: IMC path is missing", line_nr); + free(name); + return FALSE; + } + if (!extract_token(&token, ' ', &line)) + { + token = line; + } + + /* copy the IMC path */ + path = malloc(token.len + 1); + memcpy(path, token.ptr, token.len); + path[token.len] = '\0'; + + /* load and register IMC instance */ + imc = tnc_imc_create(name, path); + if (!imc) + { + free(name); + free(path); + return FALSE; + } + if (!charon->imcs->add(charon->imcs, imc)) + { + imc->destroy(imc); + return FALSE; + } + DBG1(DBG_TNC, "IMC \"%s\" loaded from '%s'", name, path); + } + munmap(addr, sb.st_size); + close(fd); + return TRUE; +} METHOD(plugin_t, destroy, void, tnc_imc_plugin_t *this) @@ -31,9 +152,8 @@ METHOD(plugin_t, destroy, void, */ plugin_t *tnc_imc_plugin_create() { - char *tnc_config, *pref_lang, *name, *filename; + char *tnc_config, *pref_lang; tnc_imc_plugin_t *this; - imc_t *imc; INIT(this, .plugin = { @@ -49,27 +169,12 @@ plugin_t *tnc_imc_plugin_create() /* Create IMC manager */ charon->imcs = tnc_imc_manager_create(); - /** - * Create, register and initialize IMCs - * Abort if one of the IMCs fails to initialize successfully - */ + /* Load IMCs and abort if not all instances initalize successfully */ + if (!load_imcs(tnc_config)) { - name = "Dummy"; - filename = "/usr/local/lib/libdummyimc.so"; - imc = tnc_imc_create(name, filename); - if (!imc) - { - charon->imcs->destroy(charon->imcs); - free(this); - return NULL; - } - if (!charon->imcs->add(charon->imcs, imc)) - { - imc->destroy(imc); - charon->imcs->destroy(charon->imcs); - free(this); - return NULL; - } + charon->imcs->destroy(charon->imcs); + free(this); + return NULL; } return &this->plugin; } |