aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndreas Steffen <andreas.steffen@strongswan.org>2010-11-10 10:57:01 +0100
committerAndreas Steffen <andreas.steffen@strongswan.org>2010-11-10 10:57:01 +0100
commit7ead19a700a4c8afe2e838876fec309c59a03692 (patch)
treed7a972496eb09b1d03dd65456fa5559198f152a7 /src
parentfa1a82f47a861043479deb79533fca9be648e0a0 (diff)
downloadstrongswan-7ead19a700a4c8afe2e838876fec309c59a03692.tar.bz2
strongswan-7ead19a700a4c8afe2e838876fec309c59a03692.tar.xz
read IMC/IMV configurations from /etc/tnc_config
Diffstat (limited to 'src')
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc.c25
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc_manager.c7
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c149
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv.c22
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv_manager.c7
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c150
6 files changed, 288 insertions, 72 deletions
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc.c b/src/libcharon/plugins/tnc_imc/tnc_imc.c
index e0f06e57d..fa5e2e499 100644
--- a/src/libcharon/plugins/tnc_imc/tnc_imc.c
+++ b/src/libcharon/plugins/tnc_imc/tnc_imc.c
@@ -33,6 +33,11 @@ struct private_tnc_imc_t {
imc_t public;
/**
+ * Path of loaded IMC
+ */
+ char *path;
+
+ /**
* Name of loaded IMC
*/
char *name;
@@ -129,13 +134,14 @@ METHOD(imc_t, destroy, void,
dlclose(this->handle);
free(this->supported_types);
free(this->name);
+ free(this->path);
free(this);
}
/**
* Described in header.
*/
-imc_t* tnc_imc_create(char* name, char *filename)
+imc_t* tnc_imc_create(char *name, char *path)
{
private_tnc_imc_t *this;
@@ -148,25 +154,23 @@ imc_t* tnc_imc_create(char* name, char *filename)
.type_supported = _type_supported,
.destroy = _destroy,
},
+ .name = name,
+ .path = path,
);
- this->handle = dlopen(filename, RTLD_NOW);
+ this->handle = dlopen(path, RTLD_NOW);
if (!this->handle)
{
- DBG1(DBG_TNC, "IMC '%s' failed to load from '%s': %s",
- name, filename, dlerror());
+ DBG1(DBG_TNC, "IMC \"%s\" failed to load: %s", name, dlerror());
free(this);
return NULL;
}
- /* we do not store or free dlopen() this->handles, leak_detective requires
- * the modules to keep loaded until leak report */
-
this->public.initialize = dlsym(this->handle, "TNC_IMC_Initialize");
if (!this->public.initialize)
{
DBG1(DBG_TNC, "could not resolve TNC_IMC_Initialize in %s: %s\n",
- filename, dlerror());
+ path, dlerror());
dlclose(this->handle);
free(this);
return NULL;
@@ -177,7 +181,7 @@ imc_t* tnc_imc_create(char* name, char *filename)
if (!this->public.begin_handshake)
{
DBG1(DBG_TNC, "could not resolve TNC_IMC_BeginHandshake in %s: %s\n",
- filename, dlerror());
+ path, dlerror());
dlclose(this->handle);
free(this);
return NULL;
@@ -193,12 +197,11 @@ imc_t* tnc_imc_create(char* name, char *filename)
if (!this->public.provide_bind_function)
{
DBG1(DBG_TNC, "could not resolve TNC_IMC_ProvideBindFunction in %s: %s\n",
- filename, dlerror());
+ path, dlerror());
dlclose(this->handle);
free(this);
return NULL;
}
- this->name = strdup(name);
return &this->public;
}
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c b/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c
index d78c92a25..f8761672f 100644
--- a/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c
+++ b/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c
@@ -55,8 +55,7 @@ METHOD(imc_manager_t, add, bool,
if (imc->initialize(imc->get_id(imc), TNC_IFIMC_VERSION_1,
TNC_IFIMC_VERSION_1, &version) != TNC_RESULT_SUCCESS)
{
- DBG1(DBG_TNC, "could not initialize IMC '%s'",
- imc->get_name(imc));
+ DBG1(DBG_TNC, "IMC \"%s\" failed to initialize", imc->get_name(imc));
return FALSE;
}
this->imcs->insert_last(this->imcs, imc);
@@ -65,7 +64,7 @@ METHOD(imc_manager_t, add, bool,
if (imc->provide_bind_function(imc->get_id(imc), TNC_TNCC_BindFunction)
!= TNC_RESULT_SUCCESS)
{
- DBG1(DBG_TNC, "could not provide bind function for IMC '%s'",
+ DBG1(DBG_TNC, "IMC \"%s\" failed to obtain bind function",
imc->get_name(imc));
this->imcs->remove_last(this->imcs, (void**)&imc);
return FALSE;
@@ -202,7 +201,7 @@ METHOD(imc_manager_t, destroy, void,
if (imc->terminate &&
imc->terminate(imc->get_id(imc)) != TNC_RESULT_SUCCESS)
{
- DBG1(DBG_TNC, "IMC '%s' not terminated successfully",
+ DBG1(DBG_TNC, "IMC \"%s\" not terminated successfully",
imc->get_name(imc));
}
imc->destroy(imc);
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;
}
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv.c b/src/libcharon/plugins/tnc_imv/tnc_imv.c
index f04ecc71e..29161f513 100644
--- a/src/libcharon/plugins/tnc_imv/tnc_imv.c
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv.c
@@ -33,6 +33,11 @@ struct private_tnc_imv_t {
imv_t public;
/**
+ * Path of loaded IMV
+ */
+ char *path;
+
+ /**
* Name of loaded IMV
*/
char *name;
@@ -129,13 +134,14 @@ METHOD(imv_t, destroy, void,
dlclose(this->handle);
free(this->supported_types);
free(this->name);
+ free(this->path);
free(this);
}
/**
* Described in header.
*/
-imv_t* tnc_imv_create(char *name, char *filename)
+imv_t* tnc_imv_create(char *name, char *path)
{
private_tnc_imv_t *this;
@@ -148,13 +154,14 @@ imv_t* tnc_imv_create(char *name, char *filename)
.type_supported = _type_supported,
.destroy = _destroy,
},
+ .name = name,
+ .path = path,
);
- this->handle = dlopen(filename, RTLD_NOW);
+ this->handle = dlopen(path, RTLD_NOW);
if (!this->handle)
{
- DBG1(DBG_TNC, "IMV '%s' failed to load from '%s': %s",
- name, filename, dlerror());
+ DBG1(DBG_TNC, "IMV \"%s\" failed to load: %s", name, dlerror());
free(this);
return NULL;
}
@@ -163,7 +170,7 @@ imv_t* tnc_imv_create(char *name, char *filename)
if (!this->public.initialize)
{
DBG1(DBG_TNC, "could not resolve TNC_IMV_Initialize in %s: %s\n",
- filename, dlerror());
+ path, dlerror());
dlclose(this->handle);
free(this);
return NULL;
@@ -175,7 +182,7 @@ imv_t* tnc_imv_create(char *name, char *filename)
if (!this->public.solicit_recommendation)
{
DBG1(DBG_TNC, "could not resolve TNC_IMV_SolicitRecommendation in %s: %s\n",
- filename, dlerror());
+ path, dlerror());
dlclose(this->handle);
free(this);
return NULL;
@@ -191,12 +198,11 @@ imv_t* tnc_imv_create(char *name, char *filename)
if (!this->public.provide_bind_function)
{
DBG1(DBG_TNC, "could not resolve TNC_IMV_ProvideBindFunction in %s: %s\n",
- filename, dlerror());
+ path, dlerror());
dlclose(this->handle);
free(this);
return NULL;
}
- this->name = strdup(name);
return &this->public;
}
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c b/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c
index 9e4bc50d7..00060bbce 100644
--- a/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c
@@ -55,8 +55,7 @@ METHOD(imv_manager_t, add, bool,
if (imv->initialize(imv->get_id(imv), TNC_IFIMV_VERSION_1,
TNC_IFIMV_VERSION_1, &version) != TNC_RESULT_SUCCESS)
{
- DBG1(DBG_TNC, "could not initialize IMV '%s'",
- imv->get_name(imv));
+ DBG1(DBG_TNC, "IMV \"%s\" failed to initialize", imv->get_name(imv));
return FALSE;
}
this->imvs->insert_last(this->imvs, imv);
@@ -65,7 +64,7 @@ METHOD(imv_manager_t, add, bool,
if (imv->provide_bind_function(imv->get_id(imv), TNC_TNCS_BindFunction)
!= TNC_RESULT_SUCCESS)
{
- DBG1(DBG_TNC, "could not provide bind function for IMV '%s'",
+ DBG1(DBG_TNC, "IMV \"%s\" could failed to obtain bind function",
imv->get_name(imv));
this->imvs->remove_last(this->imvs, (void**)&imv);
return FALSE;
@@ -202,7 +201,7 @@ METHOD(imv_manager_t, destroy, void,
if (imv->terminate &&
imv->terminate(imv->get_id(imv)) != TNC_RESULT_SUCCESS)
{
- DBG1(DBG_TNC, "IMV '%s' not terminated successfully",
+ DBG1(DBG_TNC, "IMV \"%s\" not terminated successfully",
imv->get_name(imv));
}
imv->destroy(imv);
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c b/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c
index 49321051f..54162656b 100644
--- a/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c
@@ -17,7 +17,128 @@
#include "tnc_imv_manager.h"
#include "tnc_imv.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 IMVs from a configuration file
+ */
+static bool load_imvs(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 (!charon->imvs->add(charon->imvs, imv))
+ {
+ imv->destroy(imv);
+ return FALSE;
+ }
+ DBG1(DBG_TNC, "IMV \"%s\" loaded from '%s'", name, path);
+ }
+ munmap(addr, sb.st_size);
+ close(fd);
+ return TRUE;
+}
METHOD(plugin_t, destroy, void,
tnc_imv_plugin_t *this)
@@ -31,9 +152,8 @@ METHOD(plugin_t, destroy, void,
*/
plugin_t *tnc_imv_plugin_create()
{
- char *tnc_config, *name, *filename;
+ char *tnc_config;
tnc_imv_plugin_t *this;
- imv_t *imv;
INIT(this,
.plugin = {
@@ -47,28 +167,12 @@ plugin_t *tnc_imv_plugin_create()
/* Create IMV manager */
charon->imvs = tnc_imv_manager_create();
- /**
- * Create, register and initialize IMVs
- * Abort if one of the IMVs fails to initialize successfully
- */
+ /* Load IMVs and abort if not all instances initalize successfully */
+ if (!load_imvs(tnc_config))
{
- name = "Dummy";
- filename = "/usr/local/lib/libdummyimv.so";
- imv = tnc_imv_create(name, filename);
-
- if (!imv)
- {
- charon->imvs->destroy(charon->imvs);
- free(this);
- return NULL;
- }
- if (!charon->imvs->add(charon->imvs, imv))
- {
- imv->destroy(imv);
- charon->imvs->destroy(charon->imvs);
- free(this);
- return NULL;
- }
+ charon->imvs->destroy(charon->imvs);
+ free(this);
+ return NULL;
}
return &this->plugin;
}