summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins/tnc_imv
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/plugins/tnc_imv')
-rw-r--r--src/libcharon/plugins/tnc_imv/Makefile.am11
-rw-r--r--src/libcharon/plugins/tnc_imv/Makefile.in23
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv.c211
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c117
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv_manager.c142
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c179
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.c29
7 files changed, 490 insertions, 222 deletions
diff --git a/src/libcharon/plugins/tnc_imv/Makefile.am b/src/libcharon/plugins/tnc_imv/Makefile.am
index 3ba283bb7..eca3b377b 100644
--- a/src/libcharon/plugins/tnc_imv/Makefile.am
+++ b/src/libcharon/plugins/tnc_imv/Makefile.am
@@ -1,6 +1,10 @@
-INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon
+INCLUDES = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon \
+ -I$(top_srcdir)/src/libtncif \
+ -I$(top_srcdir)/src/libtnccs
AM_CFLAGS = -rdynamic
@@ -8,6 +12,9 @@ if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-tnc-imv.la
else
plugin_LTLIBRARIES = libstrongswan-tnc-imv.la
+libstrongswan_tnc_imv_la_LIBADD = \
+ $(top_builddir)/src/libtncif/libtncif.la \
+ $(top_builddir)/src/libtnccs/libtnccs.la
endif
libstrongswan_tnc_imv_la_SOURCES = \
diff --git a/src/libcharon/plugins/tnc_imv/Makefile.in b/src/libcharon/plugins/tnc_imv/Makefile.in
index fb96150f4..cf58f0dc3 100644
--- a/src/libcharon/plugins/tnc_imv/Makefile.in
+++ b/src/libcharon/plugins/tnc_imv/Makefile.in
@@ -74,7 +74,9 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
-libstrongswan_tnc_imv_la_LIBADD =
+@MONOLITHIC_FALSE@libstrongswan_tnc_imv_la_DEPENDENCIES = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la
am_libstrongswan_tnc_imv_la_OBJECTS = tnc_imv_plugin.lo tnc_imv.lo \
tnc_imv_manager.lo tnc_imv_bind_function.lo \
tnc_imv_recommendations.lo
@@ -195,6 +197,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +208,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +225,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +275,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -277,12 +286,20 @@ top_srcdir = @top_srcdir@
urandom_device = @urandom_device@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
-INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon
+INCLUDES = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon \
+ -I$(top_srcdir)/src/libtncif \
+ -I$(top_srcdir)/src/libtnccs
AM_CFLAGS = -rdynamic
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnc-imv.la
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnc-imv.la
+@MONOLITHIC_FALSE@libstrongswan_tnc_imv_la_LIBADD = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la
+
libstrongswan_tnc_imv_la_SOURCES = \
tnc_imv_plugin.h tnc_imv_plugin.c tnc_imv.h tnc_imv.c \
tnc_imv_manager.h tnc_imv_manager.c tnc_imv_bind_function.c \
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv.c b/src/libcharon/plugins/tnc_imv/tnc_imv.c
index fe628ee7e..f0b150743 100644
--- a/src/libcharon/plugins/tnc_imv/tnc_imv.c
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006 Mike McCauley
- * Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2010-2011 Andreas Steffen,
+ * HSR Hochschule fuer Technik Rapperswil
*
* 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
@@ -17,8 +18,11 @@
#include <dlfcn.h>
+#include <tncif_pa_subtypes.h>
+
#include <debug.h>
#include <library.h>
+#include <utils/linked_list.h>
#include <threading/mutex.h>
typedef struct private_tnc_imv_t private_tnc_imv_t;
@@ -54,9 +58,19 @@ struct private_tnc_imv_t {
TNC_IMVID id;
/**
- * List of message types supported by IMC
+ * List of additional IMV IDs
*/
- TNC_MessageTypeList supported_types;
+ linked_list_t *additional_ids;
+
+ /**
+ * List of message types supported by IMV - Vendor ID part
+ */
+ TNC_VendorIDList supported_vids;
+
+ /**
+ * List of message types supported by IMV - Subtype part
+ */
+ TNC_MessageSubtypeList supported_subtypes;
/**
* Number of supported message types
@@ -81,6 +95,50 @@ METHOD(imv_t, get_id, TNC_IMVID,
return this->id;
}
+METHOD(imv_t, add_id, void,
+ private_tnc_imv_t *this, TNC_IMVID id)
+{
+ TNC_IMVID *new_id;
+
+ new_id = malloc_thing(TNC_IMVID);
+ *new_id = id;
+ this->additional_ids->insert_last(this->additional_ids, new_id);
+}
+
+METHOD(imv_t, has_id, bool,
+ private_tnc_imv_t *this, TNC_IMVID id)
+{
+ enumerator_t *enumerator;
+ TNC_IMVID *additional_id;
+ bool found = FALSE;
+
+ /* check primary IMV ID */
+ if (id == this->id)
+ {
+ return TRUE;
+ }
+
+ /* return if there are no additional IMV IDs */
+ if (this->additional_ids->get_count(this->additional_ids) == 0)
+ {
+ return FALSE;
+ }
+
+ /* check additional IMV IDs */
+ enumerator = this->additional_ids->create_enumerator(this->additional_ids);
+ while (enumerator->enumerate(enumerator, &additional_id))
+ {
+ if (id == *additional_id)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return found;
+}
+
METHOD(imv_t, get_name, char*,
private_tnc_imv_t *this)
{
@@ -91,67 +149,150 @@ METHOD(imv_t, set_message_types, void,
private_tnc_imv_t *this, TNC_MessageTypeList supported_types,
TNC_UInt32 type_count)
{
- char buf[512];
+ char buf[BUF_LEN];
char *pos = buf;
int len = sizeof(buf);
- int written;
+ int i, written;
+ size_t size;
+ TNC_VendorID vid;
+ TNC_MessageSubtype subtype;
+ enum_name_t *pa_subtype_names;
/* lock the imv_t instance */
this->mutex->lock(this->mutex);
- /* Free an existing MessageType list */
- free(this->supported_types);
- this->supported_types = NULL;
+ /* Free existing VendorID and MessageSubtype lists */
+ free(this->supported_vids);
+ this->supported_vids = NULL;
+ free(this->supported_subtypes);
+ this->supported_subtypes = NULL;
/* Store the new MessageType list */
this->type_count = type_count;
if (type_count && supported_types)
{
- size_t size = type_count * sizeof(TNC_MessageType);
-
- int i;
+ size = type_count * sizeof(TNC_VendorID);
+ this->supported_vids = malloc(size);
+ size = type_count * sizeof(TNC_MessageSubtype);
+ this->supported_subtypes = malloc(size);
for (i = 0; i < type_count; i++)
{
- written = snprintf(pos, len, " 0x%08x", supported_types[i]);
+ vid = (supported_types[i] >> 8) & TNC_VENDORID_ANY;
+ subtype = supported_types[i] & TNC_SUBTYPE_ANY;
+
+ pa_subtype_names = get_pa_subtype_names(vid);
+ if (pa_subtype_names)
+ {
+ written = snprintf(pos, len," '%N/%N' 0x%06x/0x%02x",
+ pen_names, vid, pa_subtype_names, subtype,
+ vid, subtype);
+ }
+ else
+ {
+ written = snprintf(pos, len," '%N' 0x%06x/0x%02x",
+ pen_names, vid, vid, subtype);
+ }
if (written >= len)
{
break;
}
pos += written;
len -= written;
+
+ this->supported_vids[i] = vid;
+ this->supported_subtypes[i] = subtype;
}
- this->supported_types = malloc(size);
- memcpy(this->supported_types, supported_types, size);
}
*pos = '\0';
- DBG2(DBG_TNC, "IMV %u supports %u message types:%s",
- this->id, type_count, buf);
+ DBG2(DBG_TNC, "IMV %u supports %u message type%s:%s",
+ this->id, type_count, (type_count == 1) ? "":"s", buf);
+
+ /* unlock the imv_t instance */
+ this->mutex->unlock(this->mutex);
+}
+
+METHOD(imv_t, set_message_types_long, void,
+ private_tnc_imv_t *this, TNC_VendorIDList supported_vids,
+ TNC_MessageSubtypeList supported_subtypes, TNC_UInt32 type_count)
+{
+ char buf[BUF_LEN];
+ char *pos = buf;
+ int len = sizeof(buf);
+ int i, written;
+ size_t size;
+ TNC_VendorID vid;
+ TNC_MessageSubtype subtype;
+ enum_name_t *pa_subtype_names;
/* lock the imv_t instance */
+ this->mutex->lock(this->mutex);
+
+ /* Free existing VendorID and MessageSubtype lists */
+ free(this->supported_vids);
+ this->supported_vids = NULL;
+ free(this->supported_subtypes);
+ this->supported_subtypes = NULL;
+
+ /* Store the new MessageType list */
+ this->type_count = type_count;
+ if (type_count && supported_vids && supported_subtypes)
+ {
+ size = type_count * sizeof(TNC_VendorID);
+ this->supported_vids = malloc(size);
+ memcpy(this->supported_vids, supported_vids, size);
+ size = type_count * sizeof(TNC_MessageSubtype);
+ this->supported_subtypes = malloc(size);
+ memcpy(this->supported_subtypes, supported_subtypes, size);
+
+ for (i = 0; i < type_count; i++)
+ {
+ vid = supported_vids[i];
+ subtype = supported_subtypes[i];
+
+ pa_subtype_names = get_pa_subtype_names(vid);
+ if (pa_subtype_names)
+ {
+ written = snprintf(pos, len," '%N/%N' 0x%06x/0x%08x",
+ pen_names, vid, pa_subtype_names, subtype,
+ vid, subtype);
+ }
+ else
+ {
+ written = snprintf(pos, len," '%N' 0x%06x/0x%08x",
+ pen_names, vid, vid, subtype);
+ }
+ if (written >= len)
+ {
+ break;
+ }
+ pos += written;
+ len -= written;
+ }
+ }
+ *pos = '\0';
+ DBG2(DBG_TNC, "IMV %u supports %u message type%s:%s",
+ this->id, type_count, (type_count == 1) ? "":"s", buf);
+
+ /* unlock the imv_t instance */
this->mutex->unlock(this->mutex);
}
METHOD(imv_t, type_supported, bool,
- private_tnc_imv_t *this, TNC_MessageType message_type)
+ private_tnc_imv_t *this, TNC_VendorID msg_vid, TNC_MessageSubtype msg_subtype)
{
- TNC_VendorID msg_vid, vid;
- TNC_MessageSubtype msg_subtype, subtype;
+ TNC_VendorID vid;
+ TNC_MessageSubtype subtype;
int i;
- msg_vid = (message_type >> 8) & TNC_VENDORID_ANY;
- msg_subtype = message_type & TNC_SUBTYPE_ANY;
-
for (i = 0; i < this->type_count; i++)
{
- vid = (this->supported_types[i] >> 8) & TNC_VENDORID_ANY;
- subtype = this->supported_types[i] & TNC_SUBTYPE_ANY;
-
- if (this->supported_types[i] == message_type
- || (subtype == TNC_SUBTYPE_ANY
- && (msg_vid == vid || vid == TNC_VENDORID_ANY))
- || (vid == TNC_VENDORID_ANY
- && (msg_subtype == subtype || subtype == TNC_SUBTYPE_ANY)))
+ vid = this->supported_vids[i];
+ subtype = this->supported_subtypes[i];
+
+ if ((vid == TNC_VENDORID_ANY && subtype == TNC_SUBTYPE_ANY) ||
+ (vid == msg_vid && (subtype == TNC_SUBTYPE_ANY ||
+ subtype == msg_subtype)))
{
return TRUE;
}
@@ -164,7 +305,9 @@ METHOD(imv_t, destroy, void,
{
dlclose(this->handle);
this->mutex->destroy(this->mutex);
- free(this->supported_types);
+ this->additional_ids->destroy_function(this->additional_ids, free);
+ free(this->supported_vids);
+ free(this->supported_subtypes);
free(this->name);
free(this->path);
free(this);
@@ -181,13 +324,17 @@ imv_t* tnc_imv_create(char *name, char *path)
.public = {
.set_id = _set_id,
.get_id = _get_id,
+ .add_id = _add_id,
+ .has_id = _has_id,
.get_name = _get_name,
.set_message_types = _set_message_types,
+ .set_message_types_long = _set_message_types_long,
.type_supported = _type_supported,
.destroy = _destroy,
},
.name = name,
.path = path,
+ .additional_ids = linked_list_create(),
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
);
@@ -222,6 +369,8 @@ imv_t* tnc_imv_create(char *name, char *path)
}
this->public.receive_message =
dlsym(this->handle, "TNC_IMV_ReceiveMessage");
+ this->public.receive_message_long =
+ dlsym(this->handle, "TNC_IMV_ReceiveMessageLong");
this->public.batch_ending =
dlsym(this->handle, "TNC_IMV_BatchEnding");
this->public.terminate =
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c b/src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c
index 0ed00b001..dd11c5009 100644
--- a/src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006 Mike McCauley
- * Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2010-2011 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
*
* 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
@@ -13,12 +14,11 @@
* for more details.
*/
-#include "tnc_imv.h"
+#include <tnc/tnc.h>
+#include <tnc/imv/imv_manager.h>
+#include <tnc/tnccs/tnccs_manager.h>
#include <debug.h>
-#include <daemon.h>
-
-#define TNC_IMCID_ANY 0xffff
/**
* Called by the IMV to inform a TNCS about the set of message types the IMV
@@ -28,14 +28,33 @@ TNC_Result TNC_TNCS_ReportMessageTypes(TNC_IMVID imv_id,
TNC_MessageTypeList supported_types,
TNC_UInt32 type_count)
{
- if (!charon->imvs->is_registered(charon->imvs, imv_id))
+ if (!tnc->imvs->is_registered(tnc->imvs, imv_id))
{
DBG1(DBG_TNC, "ignoring ReportMessageTypes() from unregistered IMV %u",
imv_id);
return TNC_RESULT_INVALID_PARAMETER;
}
- return charon->imvs->set_message_types(charon->imvs, imv_id,
- supported_types, type_count);
+ return tnc->imvs->set_message_types(tnc->imvs, imv_id, supported_types,
+ type_count);
+}
+
+/**
+ * Called by the IMV to inform a TNCS about the set of message types the IMV
+ * is able to receive. This function supports long message types.
+ */
+TNC_Result TNC_TNCS_ReportMessageTypesLong(TNC_IMVID imv_id,
+ TNC_VendorIDList supported_vids,
+ TNC_MessageSubtypeList supported_subtypes,
+ TNC_UInt32 type_count)
+{
+ if (!tnc->imvs->is_registered(tnc->imvs, imv_id))
+ {
+ DBG1(DBG_TNC, "ignoring ReportMessageTypesLong() from unregistered IMV %u",
+ imv_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ return tnc->imvs->set_message_types_long(tnc->imvs, imv_id, supported_vids,
+ supported_subtypes, type_count);
}
/**
@@ -45,14 +64,14 @@ TNC_Result TNC_TNCS_RequestHandshakeRetry(TNC_IMVID imv_id,
TNC_ConnectionID connection_id,
TNC_RetryReason reason)
{
- if (!charon->imvs->is_registered(charon->imvs, imv_id))
+ if (!tnc->imvs->is_registered(tnc->imvs, imv_id))
{
DBG1(DBG_TNC, "ignoring RequestHandshakeRetry() from unregistered IMV %u",
imv_id);
return TNC_RESULT_INVALID_PARAMETER;
}
- return charon->tnccs->request_handshake_retry(charon->tnccs, FALSE, imv_id,
- connection_id, reason);
+ return tnc->tnccs->request_handshake_retry(tnc->tnccs, FALSE, imv_id,
+ connection_id, reason);
}
/**
@@ -64,14 +83,42 @@ TNC_Result TNC_TNCS_SendMessage(TNC_IMVID imv_id,
TNC_UInt32 msg_len,
TNC_MessageType msg_type)
{
- if (!charon->imvs->is_registered(charon->imvs, imv_id))
+ TNC_VendorID msg_vid;
+ TNC_MessageSubtype msg_subtype;
+
+ if (!tnc->imvs->is_registered(tnc->imvs, imv_id))
{
DBG1(DBG_TNC, "ignoring SendMessage() from unregistered IMV %u",
imv_id);
return TNC_RESULT_INVALID_PARAMETER;
}
- return charon->tnccs->send_message(charon->tnccs, TNC_IMCID_ANY, imv_id,
- connection_id, msg, msg_len, msg_type);
+ msg_vid = (msg_type >> 8) & TNC_VENDORID_ANY;
+ msg_subtype = msg_type & TNC_SUBTYPE_ANY;
+
+ return tnc->tnccs->send_message(tnc->tnccs, TNC_IMCID_ANY, imv_id,
+ connection_id, 0, msg, msg_len, msg_vid, msg_subtype);
+}
+
+/**
+ * Called by the IMV when an IMV-IMC message is to be sent over IF-TNCCS 2.0
+ */
+TNC_Result TNC_TNCS_SendMessageLong(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_UInt32 msg_flags,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 imc_id)
+{
+ if (!tnc->imvs->is_registered(tnc->imvs, imv_id))
+ {
+ DBG1(DBG_TNC, "ignoring SendMessageLong() from unregistered IMV %u",
+ imv_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ return tnc->tnccs->send_message(tnc->tnccs, imc_id, imv_id, connection_id,
+ msg_flags, msg, msg_len, msg_vid, msg_subtype);
}
/**
@@ -83,14 +130,14 @@ TNC_Result TNC_TNCS_ProvideRecommendation(TNC_IMVID imv_id,
TNC_IMV_Action_Recommendation recommendation,
TNC_IMV_Evaluation_Result evaluation)
{
- if (!charon->imvs->is_registered(charon->imvs, imv_id))
+ if (!tnc->imvs->is_registered(tnc->imvs, imv_id))
{
DBG1(DBG_TNC, "ignoring ProvideRecommendation() from unregistered IMV %u",
imv_id);
return TNC_RESULT_INVALID_PARAMETER;
}
- return charon->tnccs->provide_recommendation(charon->tnccs, imv_id,
- connection_id, recommendation, evaluation);
+ return tnc->tnccs->provide_recommendation(tnc->tnccs, imv_id, connection_id,
+ recommendation, evaluation);
}
/**
@@ -104,13 +151,13 @@ TNC_Result TNC_TNCS_GetAttribute(TNC_IMVID imv_id,
TNC_BufferReference buffer,
TNC_UInt32 *out_value_len)
{
- if (!charon->imvs->is_registered(charon->imvs, imv_id))
+ if (!tnc->imvs->is_registered(tnc->imvs, imv_id))
{
DBG1(DBG_TNC, "ignoring GetAttribute() from unregistered IMV %u",
imv_id);
return TNC_RESULT_INVALID_PARAMETER;
}
- return charon->tnccs->get_attribute(charon->tnccs, imv_id, connection_id,
+ return tnc->tnccs->get_attribute(tnc->tnccs, FALSE, imv_id, connection_id,
attribute_id, buffer_len, buffer, out_value_len);
}
@@ -124,14 +171,28 @@ TNC_Result TNC_TNCS_SetAttribute(TNC_IMVID imv_id,
TNC_UInt32 buffer_len,
TNC_BufferReference buffer)
{
- if (!charon->imvs->is_registered(charon->imvs, imv_id))
+ if (!tnc->imvs->is_registered(tnc->imvs, imv_id))
{
DBG1(DBG_TNC, "ignoring SetAttribute() from unregistered IMV %u",
imv_id);
return TNC_RESULT_INVALID_PARAMETER;
}
- return charon->tnccs->set_attribute(charon->tnccs, imv_id, connection_id,
- attribute_id, buffer_len, buffer);
+ return tnc->tnccs->set_attribute(tnc->tnccs, FALSE, imv_id, connection_id,
+ attribute_id, buffer_len, buffer);
+}
+
+/**
+ * Called by the IMV when it wants to reserve an additional IMV ID for itself
+ */
+TNC_Result TNC_TNCS_ReserveAdditionalIMVID(TNC_IMVID imv_id, TNC_UInt32 *new_id)
+{
+ if (tnc->imvs->reserve_id(tnc->imvs, imv_id, new_id))
+ {
+ return TNC_RESULT_SUCCESS;
+ }
+ DBG1(DBG_TNC, "ignoring ReserveAdditionalIMVID() from unregistered IMV %u",
+ imv_id);
+ return TNC_RESULT_INVALID_PARAMETER;
}
/**
@@ -145,6 +206,10 @@ TNC_Result TNC_TNCS_BindFunction(TNC_IMVID id,
{
*function_pointer = (void*)TNC_TNCS_ReportMessageTypes;
}
+ else if (streq(function_name, "TNC_TNCS_ReportMessageTypesLong"))
+ {
+ *function_pointer = (void*)TNC_TNCS_ReportMessageTypesLong;
+ }
else if (streq(function_name, "TNC_TNCS_RequestHandshakeRetry"))
{
*function_pointer = (void*)TNC_TNCS_RequestHandshakeRetry;
@@ -153,6 +218,10 @@ TNC_Result TNC_TNCS_BindFunction(TNC_IMVID id,
{
*function_pointer = (void*)TNC_TNCS_SendMessage;
}
+ else if (streq(function_name, "TNC_TNCS_SendMessageLong"))
+ {
+ *function_pointer = (void*)TNC_TNCS_SendMessageLong;
+ }
else if (streq(function_name, "TNC_TNCS_ProvideRecommendation"))
{
*function_pointer = (void*)TNC_TNCS_ProvideRecommendation;
@@ -165,6 +234,10 @@ TNC_Result TNC_TNCS_BindFunction(TNC_IMVID id,
{
*function_pointer = (void*)TNC_TNCS_SetAttribute;
}
+ else if (streq(function_name, "TNC_TNCS_ReserveAdditionalIMVID"))
+ {
+ *function_pointer = (void*)TNC_TNCS_ReserveAdditionalIMVID;
+ }
else
{
return TNC_RESULT_INVALID_PARAMETER;
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c b/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c
index 579ab06ff..b1da73156 100644
--- a/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006 Mike McCauley
- * Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2010-2011 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
*
* 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
@@ -14,13 +15,22 @@
*/
#include "tnc_imv_manager.h"
+#include "tnc_imv.h"
#include "tnc_imv_recommendations.h"
-#include <tnc/imv/imv_manager.h>
-#include <tnc/tncifimv.h>
+#include <tncifimv.h>
+#include <tncif_names.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
-#include <debug.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;
@@ -101,6 +111,33 @@ METHOD(imv_manager_t, remove_, imv_t*,
return removed_imv;
}
+METHOD(imv_manager_t, load, bool,
+ private_tnc_imv_manager_t *this, char *name, char *path)
+{
+ imv_t *imv;
+
+ 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);
+ return TRUE;
+}
+
METHOD(imv_manager_t, is_registered, bool,
private_tnc_imv_manager_t *this, TNC_IMVID id)
{
@@ -111,9 +148,34 @@ METHOD(imv_manager_t, is_registered, bool,
enumerator = this->imvs->create_enumerator(this->imvs);
while (enumerator->enumerate(enumerator, &imv))
{
- if (id == imv->get_id(imv))
+ if (imv->has_id(imv, id))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return found;
+}
+
+METHOD(imv_manager_t, reserve_id, bool,
+ private_tnc_imv_manager_t *this, TNC_IMVID id, TNC_UInt32 *new_id)
+{
+ enumerator_t *enumerator;
+ imv_t *imv;
+ bool found = FALSE;
+
+ enumerator = this->imvs->create_enumerator(this->imvs);
+ while (enumerator->enumerate(enumerator, &imv))
+ {
+ if (imv->get_id(imv))
{
found = TRUE;
+ *new_id = this->next_imv_id++;
+ imv->add_id(imv, *new_id);
+ DBG2(DBG_TNC, "additional ID %u reserved for IMV with primary ID %u",
+ *new_id, id);
break;
}
}
@@ -231,6 +293,31 @@ METHOD(imv_manager_t, set_message_types, TNC_Result,
return result;
}
+METHOD(imv_manager_t, set_message_types_long, TNC_Result,
+ private_tnc_imv_manager_t *this, TNC_IMVID id,
+ TNC_VendorIDList supported_vids,
+ TNC_MessageSubtypeList supported_subtypes,
+ TNC_UInt32 type_count)
+{
+ enumerator_t *enumerator;
+ imv_t *imv;
+ TNC_Result result = TNC_RESULT_FATAL;
+
+ enumerator = this->imvs->create_enumerator(this->imvs);
+ while (enumerator->enumerate(enumerator, &imv))
+ {
+ if (id == imv->get_id(imv))
+ {
+ imv->set_message_types_long(imv, supported_vids, supported_subtypes,
+ type_count);
+ result = TNC_RESULT_SUCCESS;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return result;
+}
+
METHOD(imv_manager_t, solicit_recommendation, void,
private_tnc_imv_manager_t *this, TNC_ConnectionID id)
{
@@ -247,28 +334,52 @@ METHOD(imv_manager_t, solicit_recommendation, void,
METHOD(imv_manager_t, receive_message, void,
private_tnc_imv_manager_t *this, TNC_ConnectionID connection_id,
- TNC_BufferReference message,
- TNC_UInt32 message_len,
- TNC_MessageType message_type)
+ bool excl,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 src_imc_id,
+ TNC_UInt32 dst_imv_id)
{
bool type_supported = FALSE;
+ TNC_MessageType msg_type;
+ TNC_UInt32 msg_flags;
enumerator_t *enumerator;
imv_t *imv;
+ msg_type = (msg_vid << 8) | msg_subtype;
+
enumerator = this->imvs->create_enumerator(this->imvs);
while (enumerator->enumerate(enumerator, &imv))
{
- if (imv->receive_message && imv->type_supported(imv, message_type))
+ if (imv->type_supported(imv, msg_vid, msg_subtype) &&
+ (!excl || (excl && imv->has_id(imv, dst_imv_id)) ))
{
- type_supported = TRUE;
- imv->receive_message(imv->get_id(imv), connection_id,
- message, message_len, message_type);
+ if (imv->receive_message_long && src_imc_id)
+ {
+ type_supported = TRUE;
+ msg_flags = excl ? TNC_MESSAGE_FLAGS_EXCLUSIVE : 0;
+ imv->receive_message_long(imv->get_id(imv), connection_id,
+ msg_flags, msg, msg_len, msg_vid, msg_subtype,
+ src_imc_id, dst_imv_id);
+
+ }
+ else if (imv->receive_message && msg_vid <= TNC_VENDORID_ANY &&
+ msg_subtype <= TNC_SUBTYPE_ANY)
+ {
+ type_supported = TRUE;
+ msg_type = (msg_vid << 8) | msg_subtype;
+ imv->receive_message(imv->get_id(imv), connection_id,
+ msg, msg_len, msg_type);
+ }
}
}
enumerator->destroy(enumerator);
if (!type_supported)
{
- DBG2(DBG_TNC, "message type 0x%08x not supported by any IMV", message_type);
+ DBG2(DBG_TNC, "message type 0x%06x/0x%08x not supported by any IMV",
+ msg_vid, msg_subtype);
}
}
@@ -289,6 +400,7 @@ METHOD(imv_manager_t, batch_ending, void,
enumerator->destroy(enumerator);
}
+
METHOD(imv_manager_t, destroy, void,
private_tnc_imv_manager_t *this)
{
@@ -320,12 +432,15 @@ imv_manager_t* tnc_imv_manager_create(void)
.public = {
.add = _add,
.remove = _remove_, /* avoid name conflict with stdio.h */
+ .load = _load,
.is_registered = _is_registered,
+ .reserve_id = _reserve_id,
.get_recommendation_policy = _get_recommendation_policy,
.create_recommendations = _create_recommendations,
.enforce_recommendation = _enforce_recommendation,
.notify_connection_change = _notify_connection_change,
.set_message_types = _set_message_types,
+ .set_message_types_long = _set_message_types_long,
.solicit_recommendation = _solicit_recommendation,
.receive_message = _receive_message,
.batch_ending = _batch_ending,
@@ -334,6 +449,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"));
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c b/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c
index 45cf95c1b..c16f6b9e1 100644
--- a/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Andreas Steffen
+ * Copyright (C) 2010-2011 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -15,137 +15,24 @@
#include "tnc_imv_plugin.h"
#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 <tnc/tnc.h>
-#include <daemon.h>
-#include <utils/lexparser.h>
+
+typedef struct private_tnc_imv_plugin_t private_tnc_imv_plugin_t;
/**
- * load IMVs from a configuration file
+ * Private data of a tnc_imv_plugin_t object.
*/
-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;
- }
+struct private_tnc_imv_plugin_t {
- /* copy the IMV name */
- name = malloc(token.len + 1);
- memcpy(name, token.ptr, token.len);
- name[token.len] = '\0';
+ /**
+ * Public interface.
+ */
+ tnc_imv_plugin_t public;
- /* 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))
- {
- 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(plugin_t, get_name, char*,
tnc_imv_plugin_t *this)
@@ -153,10 +40,21 @@ METHOD(plugin_t, get_name, char*,
return "tnc-imv";
}
+METHOD(plugin_t, get_features, int,
+ private_tnc_imv_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(tnc_manager_register, tnc_imv_manager_create),
+ PLUGIN_PROVIDE(CUSTOM, "imv-manager"),
+ PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
- tnc_imv_plugin_t *this)
+ private_tnc_imv_plugin_t *this)
{
- charon->imvs->destroy(charon->imvs);
free(this);
}
@@ -165,31 +63,18 @@ METHOD(plugin_t, destroy, void,
*/
plugin_t *tnc_imv_plugin_create()
{
- char *tnc_config;
- tnc_imv_plugin_t *this;
+ private_tnc_imv_plugin_t *this;
INIT(this,
- .plugin = {
- .get_name = _get_name,
- .reload = (void*)return_false,
- .destroy = _destroy,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .get_features = _get_features,
+ .destroy = _destroy,
+ },
},
);
- tnc_config = lib->settings->get_str(lib->settings,
- "charon.plugins.tnc-imv.tnc_config", "/etc/tnc_config");
-
- /* Create IMV manager */
- charon->imvs = tnc_imv_manager_create();
-
- /* Load IMVs and abort if not all instances initalize successfully */
- if (!load_imvs(tnc_config))
- {
- charon->imvs->destroy(charon->imvs);
- charon->imvs = NULL;
- free(this);
- return NULL;
- }
- return &this->plugin;
+ return &this->public.plugin;
}
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.c b/src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.c
index 5cc6b0ced..7843293a1 100644
--- a/src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.c
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.c
@@ -12,12 +12,17 @@
* for more details.
*/
-#include <debug.h>
-#include <daemon.h>
-#include <tnc/tncifimv.h>
+#include <tncifimv.h>
+#include <tncif_names.h>
+
+#include <tnc/tnc.h>
#include <tnc/imv/imv.h>
+#include <tnc/imv/imv_manager.h>
#include <tnc/imv/imv_recommendations.h>
+#include <debug.h>
+#include <utils/linked_list.h>
+
typedef struct private_tnc_imv_recommendations_t private_tnc_imv_recommendations_t;
typedef struct recommendation_entry_t recommendation_entry_t;
@@ -126,7 +131,7 @@ METHOD(recommendations_t, have_recommendation, bool,
DBG1(DBG_TNC, "there are no IMVs to make a recommendation");
return TRUE;
}
- policy = charon->imvs->get_recommendation_policy(charon->imvs);
+ policy = tnc->imvs->get_recommendation_policy(tnc->imvs);
enumerator = this->recs->create_enumerator(this->recs);
while (enumerator->enumerate(enumerator, &entry))
@@ -357,6 +362,21 @@ METHOD(recommendations_t, create_reason_enumerator, enumerator_t*,
(void*)reason_filter, NULL, NULL);
}
+METHOD(recommendations_t, clear_reasons, void,
+ private_tnc_imv_recommendations_t *this)
+{
+ enumerator_t *enumerator;
+ recommendation_entry_t *entry;
+
+ enumerator = this->recs->create_enumerator(this->recs);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ chunk_clear(&entry->reason);
+ chunk_clear(&entry->reason_language);
+ }
+ enumerator->destroy(enumerator);
+}
+
METHOD(recommendations_t, destroy, void,
private_tnc_imv_recommendations_t *this)
{
@@ -392,6 +412,7 @@ recommendations_t* tnc_imv_recommendations_create(linked_list_t *imv_list)
.set_reason_string = _set_reason_string,
.set_reason_language = _set_reason_language,
.create_reason_enumerator = _create_reason_enumerator,
+ .clear_reasons = _clear_reasons,
.destroy = _destroy,
},
.recs = linked_list_create(),