share some code between IMC and IMV managers

This commit is contained in:
Andreas Steffen
2011-10-25 09:45:35 +02:00
parent 61f7036e69
commit 5d36af6936
5 changed files with 195 additions and 251 deletions
+17 -116
View File
@@ -18,15 +18,7 @@
#include <tncifimc.h> #include <tncifimc.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <utils/linked_list.h> #include <utils/linked_list.h>
#include <utils/lexparser.h>
#include <debug.h> #include <debug.h>
typedef struct private_tnc_imc_manager_t private_tnc_imc_manager_t; typedef struct private_tnc_imc_manager_t private_tnc_imc_manager_t;
@@ -101,121 +93,30 @@ METHOD(imc_manager_t, remove_, imc_t*,
return removed_imc; return removed_imc;
} }
METHOD(imc_manager_t, load_all, bool, METHOD(imc_manager_t, load, bool,
private_tnc_imc_manager_t *this, char *filename) private_tnc_imc_manager_t *this, char *name, char *path)
{ {
int fd, line_nr = 0; imc_t *imc;
chunk_t src, line;
struct stat sb;
void *addr;
DBG1(DBG_TNC, "loading IMCs from '%s'", filename); imc = tnc_imc_create(name, path);
fd = open(filename, O_RDONLY); if (!imc)
if (fd == -1)
{ {
DBG1(DBG_TNC, "opening configuration file '%s' failed: %s", filename, free(name);
strerror(errno)); free(path);
return FALSE; return FALSE;
} }
if (fstat(fd, &sb) == -1) if (!add(this, imc))
{ {
DBG1(DBG_LIB, "getting file size of '%s' failed: %s", filename, if (imc->terminate &&
strerror(errno)); imc->terminate(imc->get_id(imc)) != TNC_RESULT_SUCCESS)
close(fd); {
DBG1(DBG_TNC, "IMC \"%s\" not terminated successfully",
imc->get_name(imc));
}
imc->destroy(imc);
return FALSE; return FALSE;
} }
addr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); DBG1(DBG_TNC, "IMC %u \"%s\" loaded from '%s'", imc->get_id(imc), name, path);
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 (!add(this, imc))
{
if (imc->terminate &&
imc->terminate(imc->get_id(imc)) != TNC_RESULT_SUCCESS)
{
DBG1(DBG_TNC, "IMC \"%s\" not terminated successfully",
imc->get_name(imc));
}
imc->destroy(imc);
return FALSE;
}
DBG1(DBG_TNC, "IMC %u \"%s\" loaded from '%s'", imc->get_id(imc),
name, path);
}
munmap(addr, sb.st_size);
close(fd);
return TRUE; return TRUE;
} }
@@ -376,7 +277,7 @@ imc_manager_t* tnc_imc_manager_create(void)
.public = { .public = {
.add = _add, .add = _add,
.remove = _remove_, /* avoid name conflict with stdio.h */ .remove = _remove_, /* avoid name conflict with stdio.h */
.load_all = _load_all, .load = _load,
.is_registered = _is_registered, .is_registered = _is_registered,
.get_preferred_language = _get_preferred_language, .get_preferred_language = _get_preferred_language,
.notify_connection_change = _notify_connection_change, .notify_connection_change = _notify_connection_change,
+17 -108
View File
@@ -110,121 +110,30 @@ METHOD(imv_manager_t, remove_, imv_t*,
return removed_imv; return removed_imv;
} }
METHOD(imv_manager_t, load_all, bool, METHOD(imv_manager_t, load, bool,
private_tnc_imv_manager_t *this, char *filename) private_tnc_imv_manager_t *this, char *name, char *path)
{ {
int fd, line_nr = 0; imv_t *imv;
chunk_t src, line;
struct stat sb;
void *addr;
DBG1(DBG_TNC, "loading IMVs from '%s'", filename); imv = tnc_imv_create(name, path);
fd = open(filename, O_RDONLY); if (!imv)
if (fd == -1)
{ {
DBG1(DBG_TNC, "opening configuration file '%s' failed: %s", filename, free(name);
strerror(errno)); free(path);
return FALSE; return FALSE;
} }
if (fstat(fd, &sb) == -1) if (!add(this, imv))
{ {
DBG1(DBG_LIB, "getting file size of '%s' failed: %s", filename, if (imv->terminate &&
strerror(errno)); imv->terminate(imv->get_id(imv)) != TNC_RESULT_SUCCESS)
close(fd); {
DBG1(DBG_TNC, "IMV \"%s\" not terminated successfully",
imv->get_name(imv));
}
imv->destroy(imv);
return FALSE; return FALSE;
} }
addr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); DBG1(DBG_TNC, "IMV %u \"%s\" loaded from '%s'", imv->get_id(imv), name, path);
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; return TRUE;
} }
@@ -448,7 +357,7 @@ imv_manager_t* tnc_imv_manager_create(void)
.public = { .public = {
.add = _add, .add = _add,
.remove = _remove_, /* avoid name conflict with stdio.h */ .remove = _remove_, /* avoid name conflict with stdio.h */
.load_all = _load_all, .load = _load,
.is_registered = _is_registered, .is_registered = _is_registered,
.get_recommendation_policy = _get_recommendation_policy, .get_recommendation_policy = _get_recommendation_policy,
.create_recommendations = _create_recommendations, .create_recommendations = _create_recommendations,
+5 -4
View File
@@ -49,12 +49,13 @@ struct imc_manager_t {
imc_t* (*remove)(imc_manager_t *this, TNC_IMCID id); imc_t* (*remove)(imc_manager_t *this, TNC_IMCID id);
/** /**
* Load all IMC instances * Load and initialize an IMC as a dynamic library and add it to the list
* *
* @param filename configuration file containt IMC paths * @param name name of the IMC to be loaded
* @return TRUE if initialization of all IMCs succeeded * @param path path of the IMC dynamic library file
* @return TRUE if loading succeeded
*/ */
bool (*load_all)(imc_manager_t *this, char *filename); bool (*load)(imc_manager_t *this, char *name, char *path);
/** /**
* Check if an IMC with a given ID is registered with the IMC manager * Check if an IMC with a given ID is registered with the IMC manager
+6 -4
View File
@@ -50,12 +50,14 @@ struct imv_manager_t {
imv_t* (*remove)(imv_manager_t *this, TNC_IMVID id); imv_t* (*remove)(imv_manager_t *this, TNC_IMVID id);
/** /**
* Load all IMV instances * Load and initialize an IMV as a dynamic library and add it to the list
* *
* @param filename configuration file containing IMV paths * @param name name of the IMV to be loaded
* @return TRUE if initialization of all IMVs succeeded * @param path path of the IMV dynamic library file
* @return TRUE if loading succeeded
*/ */
bool (*load_all)(imv_manager_t *this, char *filename); bool (*load)(imv_manager_t *this, char *name, char *path);
/** /**
* Check if an IMV with a given ID is registered with the IMV manager * Check if an IMV with a given ID is registered with the IMV manager
+150 -19
View File
@@ -15,6 +15,16 @@
#include "tnc.h" #include "tnc.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <utils/lexparser.h>
#include <debug.h>
typedef struct private_tnc_t private_tnc_t; typedef struct private_tnc_t private_tnc_t;
typedef tnccs_manager_t *(*tnc_create_tnccs_manager_t)(void); typedef tnccs_manager_t *(*tnc_create_tnccs_manager_t)(void);
@@ -63,16 +73,126 @@ void libtnccs_deinit(void)
tnc = NULL; tnc = NULL;
} }
static bool load_imcvs_from_config(char *filename, bool is_imc)
{
int fd, line_nr = 0;
chunk_t src, line;
struct stat sb;
void *addr;
char *label;
label = is_imc ? "IMC" : "IMV";
DBG1(DBG_TNC, "loading %ss from '%s'", label, 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;
bool success;
chunk_t token;
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 or IMVs depending on label */
if (!match(label, &token))
{
continue;
}
/* advance to the IMC/IMV name and extract it */
if (!extract_token(&token, '"', &line) ||
!extract_token(&token, '"', &line))
{
DBG1(DBG_TNC, "line %d: %s name must be set in double quotes",
line_nr, label);
return FALSE;
}
/* copy the IMC/IMV name */
name = malloc(token.len + 1);
memcpy(name, token.ptr, token.len);
name[token.len] = '\0';
/* advance to the IMC/IMV path and extract it */
if (!eat_whitespace(&line))
{
DBG1(DBG_TNC, "line %d: %s path is missing", line_nr, label);
free(name);
return FALSE;
}
if (!extract_token(&token, ' ', &line))
{
token = line;
}
/* copy the IMC/IMV path */
path = malloc(token.len + 1);
memcpy(path, token.ptr, token.len);
path[token.len] = '\0';
/* load and register an IMC/IMV instance */
if (is_imc)
{
success = tnc->imcs->load(tnc->imcs, name, path);
}
else
{
success = tnc->imvs->load(tnc->imvs, name, path);
}
if (!success)
{
return FALSE;
}
}
munmap(addr, sb.st_size);
close(fd);
return TRUE;
}
/** /**
* Described in header. * Described in header.
*/ */
bool tnc_manager_register(plugin_t *plugin, plugin_feature_t *feature, bool tnc_manager_register(plugin_t *plugin, plugin_feature_t *feature,
bool reg, void *data) bool reg, void *data)
{ {
char *tnc_config; bool load_imcvs = FALSE;
bool is_imc = FALSE;
tnc_config = lib->settings->get_str(lib->settings,
"libtnccs.tnc_config", "/etc/tnc_config");
if (feature->type == FEATURE_CUSTOM) if (feature->type == FEATURE_CUSTOM)
{ {
@@ -93,14 +213,8 @@ bool tnc_manager_register(plugin_t *plugin, plugin_feature_t *feature,
if (reg) if (reg)
{ {
tnc->imcs = ((tnc_create_imc_manager_t)data)(); tnc->imcs = ((tnc_create_imc_manager_t)data)();
is_imc = TRUE;
load_imcvs = TRUE;
if (!tnc->imcs->load_all(tnc->imcs, tnc_config))
{
tnc->imcs->destroy(tnc->imcs);
tnc->imcs = NULL;
return FALSE;
}
} }
else else
{ {
@@ -113,13 +227,8 @@ bool tnc_manager_register(plugin_t *plugin, plugin_feature_t *feature,
if (reg) if (reg)
{ {
tnc->imvs = ((tnc_create_imv_manager_t)data)(); tnc->imvs = ((tnc_create_imv_manager_t)data)();
is_imc = FALSE;
if (!tnc->imvs->load_all(tnc->imvs, tnc_config)) load_imcvs = TRUE;
{
tnc->imvs->destroy(tnc->imvs);
tnc->imvs = NULL;
return FALSE;
}
} }
else else
{ {
@@ -131,6 +240,28 @@ bool tnc_manager_register(plugin_t *plugin, plugin_feature_t *feature,
{ {
return FALSE; return FALSE;
} }
if (load_imcvs)
{
char *tnc_config;
tnc_config = lib->settings->get_str(lib->settings,
"libtnccs.tnc_config", "/etc/tnc_config");
if (!load_imcvs_from_config(tnc_config, is_imc))
{
if (is_imc)
{
tnc->imcs->destroy(tnc->imcs);
tnc->imcs = NULL;
}
else
{
tnc->imvs->destroy(tnc->imvs);
tnc->imvs = NULL;
}
return FALSE;
}
}
} }
return TRUE; return TRUE;
} }