diff options
Diffstat (limited to 'src/libcharon/plugins/tnc_imv/tnc_imv_manager.c')
-rw-r--r-- | src/libcharon/plugins/tnc_imv/tnc_imv_manager.c | 134 |
1 files changed, 131 insertions, 3 deletions
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c b/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c index 971e80a93..6c0c117d6 100644 --- a/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c +++ b/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c @@ -14,15 +14,22 @@ */ #include "tnc_imv_manager.h" +#include "tnc_imv.h" #include "tnc_imv_recommendations.h" -#include <tnc/imv/imv_manager.h> - #include <tncifimv.h> #include <tncif_names.h> -#include <debug.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> +#include <debug.h> #include <threading/mutex.h> typedef struct private_tnc_imv_manager_t private_tnc_imv_manager_t; @@ -103,6 +110,124 @@ METHOD(imv_manager_t, remove_, imv_t*, return removed_imv; } +METHOD(imv_manager_t, load_all, bool, + private_tnc_imv_manager_t *this, char *filename) +{ + int fd, line_nr = 0; + chunk_t src, line; + struct stat sb; + void *addr; + + DBG1(DBG_TNC, "loading IMVs 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; + imv_t *imv; + + 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 IMVs */ + if (!match("IMV", &token)) + { + continue; + } + + /* advance to the IMV name and extract it */ + if (!extract_token(&token, '"', &line) || + !extract_token(&token, '"', &line)) + { + DBG1(DBG_TNC, "line %d: IMV name must be set in double quotes", + line_nr); + return FALSE; + } + + /* copy the IMV name */ + name = malloc(token.len + 1); + memcpy(name, token.ptr, token.len); + name[token.len] = '\0'; + + /* advance to the IMV path and extract it */ + if (!eat_whitespace(&line)) + { + DBG1(DBG_TNC, "line %d: IMV path is missing", line_nr); + free(name); + return FALSE; + } + if (!extract_token(&token, ' ', &line)) + { + token = line; + } + + /* copy the IMV path */ + path = malloc(token.len + 1); + memcpy(path, token.ptr, token.len); + path[token.len] = '\0'; + + /* load and register IMV instance */ + imv = tnc_imv_create(name, path); + if (!imv) + { + free(name); + free(path); + return FALSE; + } + if (!add(this, imv)) + { + if (imv->terminate && + imv->terminate(imv->get_id(imv)) != TNC_RESULT_SUCCESS) + { + DBG1(DBG_TNC, "IMV \"%s\" not terminated successfully", + imv->get_name(imv)); + } + imv->destroy(imv); + return FALSE; + } + DBG1(DBG_TNC, "IMV %u \"%s\" loaded from '%s'", imv->get_id(imv), + name, path); + } + munmap(addr, sb.st_size); + close(fd); + return TRUE; +} + METHOD(imv_manager_t, is_registered, bool, private_tnc_imv_manager_t *this, TNC_IMVID id) { @@ -291,6 +416,7 @@ METHOD(imv_manager_t, batch_ending, void, enumerator->destroy(enumerator); } + METHOD(imv_manager_t, destroy, void, private_tnc_imv_manager_t *this) { @@ -322,6 +448,7 @@ imv_manager_t* tnc_imv_manager_create(void) .public = { .add = _add, .remove = _remove_, /* avoid name conflict with stdio.h */ + .load_all = _load_all, .is_registered = _is_registered, .get_recommendation_policy = _get_recommendation_policy, .create_recommendations = _create_recommendations, @@ -336,6 +463,7 @@ imv_manager_t* tnc_imv_manager_create(void) .imvs = linked_list_create(), .next_imv_id = 1, ); + policy = enum_from_name(recommendation_policy_names, lib->settings->get_str(lib->settings, "charon.plugins.tnc-imv.recommendation_policy", "default")); |