summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins/tnc_imc
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@corsac.net>2012-06-28 21:16:07 +0200
committerYves-Alexis Perez <corsac@corsac.net>2012-06-28 21:16:07 +0200
commita3b482a8facde4b453ad821bfe40effbe3d17903 (patch)
tree636f02074b05b7473f5db1fe60fa2bceb0094a62 /src/libcharon/plugins/tnc_imc
parentd816a1afbd841e9943bb439fe4e110b7c4970550 (diff)
parentb34738ed08c2227300d554b139e2495ca5da97d6 (diff)
downloadvyos-strongswan-a3b482a8facde4b453ad821bfe40effbe3d17903.tar.gz
vyos-strongswan-a3b482a8facde4b453ad821bfe40effbe3d17903.zip
Merge tag 'upstream/4.6.4'
Upstream version 4.6.4
Diffstat (limited to 'src/libcharon/plugins/tnc_imc')
-rw-r--r--src/libcharon/plugins/tnc_imc/Makefile.am9
-rw-r--r--src/libcharon/plugins/tnc_imc/Makefile.in21
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc.c214
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c147
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc_manager.c130
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c183
6 files changed, 492 insertions, 212 deletions
diff --git a/src/libcharon/plugins/tnc_imc/Makefile.am b/src/libcharon/plugins/tnc_imc/Makefile.am
index 2c551813e..fc1979525 100644
--- a/src/libcharon/plugins/tnc_imc/Makefile.am
+++ b/src/libcharon/plugins/tnc_imc/Makefile.am
@@ -1,6 +1,8 @@
-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/libtncif \
+ -I$(top_srcdir)/src/libtnccs
AM_CFLAGS = -rdynamic
@@ -8,6 +10,9 @@ if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-tnc-imc.la
else
plugin_LTLIBRARIES = libstrongswan-tnc-imc.la
+libstrongswan_tnc_imc_la_LIBADD = \
+ $(top_builddir)/src/libtncif/libtncif.la \
+ $(top_builddir)/src/libtnccs/libtnccs.la
endif
libstrongswan_tnc_imc_la_SOURCES = \
diff --git a/src/libcharon/plugins/tnc_imc/Makefile.in b/src/libcharon/plugins/tnc_imc/Makefile.in
index c2bc35dc5..550c0516c 100644
--- a/src/libcharon/plugins/tnc_imc/Makefile.in
+++ b/src/libcharon/plugins/tnc_imc/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_imc_la_LIBADD =
+@MONOLITHIC_FALSE@libstrongswan_tnc_imc_la_DEPENDENCIES = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la
am_libstrongswan_tnc_imc_la_OBJECTS = tnc_imc_plugin.lo tnc_imc.lo \
tnc_imc_manager.lo tnc_imc_bind_function.lo
libstrongswan_tnc_imc_la_OBJECTS = \
@@ -194,6 +196,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@
@@ -202,6 +207,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@
@@ -218,11 +224,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@
@@ -266,6 +274,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@
@@ -276,12 +285,18 @@ 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/libtncif \
+ -I$(top_srcdir)/src/libtnccs
AM_CFLAGS = -rdynamic
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnc-imc.la
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnc-imc.la
+@MONOLITHIC_FALSE@libstrongswan_tnc_imc_la_LIBADD = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la
+
libstrongswan_tnc_imc_la_SOURCES = \
tnc_imc_plugin.h tnc_imc_plugin.c tnc_imc.h tnc_imc.c \
tnc_imc_manager.h tnc_imc_manager.c tnc_imc_bind_function.c
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc.c b/src/libcharon/plugins/tnc_imc/tnc_imc.c
index d7fc2c65d..a1f2d770f 100644
--- a/src/libcharon/plugins/tnc_imc/tnc_imc.c
+++ b/src/libcharon/plugins/tnc_imc/tnc_imc.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_imc_t private_tnc_imc_t;
@@ -54,9 +58,19 @@ struct private_tnc_imc_t {
TNC_IMCID id;
/**
- * List of message types supported by IMC
+ * list of additional IMC IDs
*/
- TNC_MessageTypeList supported_types;
+ linked_list_t *additional_ids;
+
+ /**
+ * List of message types supported by IMC - Vendor ID part
+ */
+ TNC_VendorIDList supported_vids;
+
+ /**
+ * List of message types supported by IMC - Subtype part
+ */
+ TNC_MessageSubtypeList supported_subtypes;
/**
* Number of supported message types
@@ -81,6 +95,54 @@ METHOD(imc_t, get_id, TNC_IMCID,
return this->id;
}
+METHOD(imc_t, add_id, void,
+ private_tnc_imc_t *this, TNC_IMCID id)
+{
+ void *pointer;
+
+ /* store the scalar value in the pointer */
+ pointer = (void*)id;
+ this->additional_ids->insert_last(this->additional_ids, pointer);
+}
+
+METHOD(imc_t, has_id, bool,
+ private_tnc_imc_t *this, TNC_IMCID id)
+{
+ enumerator_t *enumerator;
+ TNC_IMCID additional_id;
+ void *pointer;
+ bool found = FALSE;
+
+ /* check primary IMC ID */
+ if (id == this->id)
+ {
+ return TRUE;
+ }
+
+ /* return if there are no additional IMC IDs */
+ if (this->additional_ids->get_count(this->additional_ids) == 0)
+ {
+ return FALSE;
+ }
+
+ /* check additional IMC IDs */
+ enumerator = this->additional_ids->create_enumerator(this->additional_ids);
+ while (enumerator->enumerate(enumerator, &pointer))
+ {
+ /* interpret pointer as scalar value */
+ additional_id = (TNC_UInt32)pointer;
+
+ if (id == additional_id)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return found;
+}
+
METHOD(imc_t, get_name, char*,
private_tnc_imc_t *this)
{
@@ -91,66 +153,150 @@ METHOD(imc_t, set_message_types, void,
private_tnc_imc_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 imc_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, "IMC %u supports %u message types:%s",
- this->id, type_count, buf);
+ DBG2(DBG_TNC, "IMC %u supports %u message type%s:%s",
+ this->id, type_count, (type_count == 1) ? "":"s", buf);
+
+ /* unlock the imc_t instance */
+ this->mutex->unlock(this->mutex);
+}
+
+METHOD(imc_t, set_message_types_long, void,
+ private_tnc_imc_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 imc_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, "IMC %u supports %u message type%s:%s",
+ this->id, type_count, (type_count == 1) ? "":"s", buf);
+
+ /* unlock the imc_t instance */
this->mutex->unlock(this->mutex);
}
METHOD(imc_t, type_supported, bool,
- private_tnc_imc_t *this, TNC_MessageType message_type)
+ private_tnc_imc_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;
}
@@ -163,7 +309,9 @@ METHOD(imc_t, destroy, void,
{
dlclose(this->handle);
this->mutex->destroy(this->mutex);
- free(this->supported_types);
+ this->additional_ids->destroy(this->additional_ids);
+ free(this->supported_vids);
+ free(this->supported_subtypes);
free(this->name);
free(this->path);
free(this);
@@ -180,13 +328,17 @@ imc_t* tnc_imc_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),
);
@@ -220,6 +372,8 @@ imc_t* tnc_imc_create(char *name, char *path)
}
this->public.receive_message =
dlsym(this->handle, "TNC_IMC_ReceiveMessage");
+ this->public.receive_message_long =
+ dlsym(this->handle, "TNC_IMC_ReceiveMessageLong");
this->public.batch_ending =
dlsym(this->handle, "TNC_IMC_BatchEnding");
this->public.terminate =
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c b/src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c
index 25a6a1cc4..90a607ccc 100644
--- a/src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c
+++ b/src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c
@@ -13,12 +13,11 @@
* for more details.
*/
-#include "tnc_imc.h"
+#include <tnc/tnc.h>
+#include <tnc/imc/imc_manager.h>
+#include <tnc/tnccs/tnccs_manager.h>
#include <debug.h>
-#include <daemon.h>
-
-#define TNC_IMVID_ANY 0xffff
/**
* Called by the IMC to inform a TNCC about the set of message types the IMC
@@ -28,14 +27,33 @@ TNC_Result TNC_TNCC_ReportMessageTypes(TNC_IMCID imc_id,
TNC_MessageTypeList supported_types,
TNC_UInt32 type_count)
{
- if (!charon->imcs->is_registered(charon->imcs, imc_id))
+ if (!tnc->imcs->is_registered(tnc->imcs, imc_id))
{
DBG1(DBG_TNC, "ignoring ReportMessageTypes() from unregistered IMC %u",
imc_id);
return TNC_RESULT_INVALID_PARAMETER;
}
- return charon->imcs->set_message_types(charon->imcs, imc_id,
- supported_types, type_count);
+ return tnc->imcs->set_message_types(tnc->imcs, imc_id, supported_types,
+ type_count);
+}
+
+/**
+ * Called by the IMC to inform a TNCC about the set of message types the IMC
+ * is able to receive. This function supports long message types.
+ */
+TNC_Result TNC_TNCC_ReportMessageTypesLong(TNC_IMCID imc_id,
+ TNC_VendorIDList supported_vids,
+ TNC_MessageSubtypeList supported_subtypes,
+ TNC_UInt32 type_count)
+{
+ if (!tnc->imcs->is_registered(tnc->imcs, imc_id))
+ {
+ DBG1(DBG_TNC, "ignoring ReportMessageTypesLong() from unregistered IMC %u",
+ imc_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ return tnc->imcs->set_message_types_long(tnc->imcs, imc_id, supported_vids,
+ supported_subtypes, type_count);
}
/**
@@ -45,14 +63,14 @@ TNC_Result TNC_TNCC_RequestHandshakeRetry(TNC_IMCID imc_id,
TNC_ConnectionID connection_id,
TNC_RetryReason reason)
{
- if (!charon->imcs->is_registered(charon->imcs, imc_id))
+ if (!tnc->imcs->is_registered(tnc->imcs, imc_id))
{
DBG1(DBG_TNC, "ignoring RequestHandshakeRetry() from unregistered IMC %u",
imc_id);
return TNC_RESULT_INVALID_PARAMETER;
}
- return charon->tnccs->request_handshake_retry(charon->tnccs, TRUE, imc_id,
- connection_id, reason);
+ return tnc->tnccs->request_handshake_retry(tnc->tnccs, TRUE, imc_id,
+ connection_id, reason);
}
/**
@@ -64,14 +82,97 @@ TNC_Result TNC_TNCC_SendMessage(TNC_IMCID imc_id,
TNC_UInt32 msg_len,
TNC_MessageType msg_type)
{
- if (!charon->imcs->is_registered(charon->imcs, imc_id))
+ TNC_VendorID msg_vid;
+ TNC_MessageSubtype msg_subtype;
+
+ if (!tnc->imcs->is_registered(tnc->imcs, imc_id))
+ {
+ DBG1(DBG_TNC, "ignoring SendMessage() from unregistered IMC %u",
+ imc_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ msg_vid = (msg_type >> 8) & TNC_VENDORID_ANY;
+ msg_subtype = msg_type & TNC_SUBTYPE_ANY;
+
+ return tnc->tnccs->send_message(tnc->tnccs, imc_id, TNC_IMVID_ANY,
+ connection_id, 0, msg, msg_len, msg_vid, msg_subtype);
+}
+
+/**
+ * Called by the IMC when an IMC-IMV message is to be sent over IF-TNCCS 2.0
+ */
+TNC_Result TNC_TNCC_SendMessageLong(TNC_IMCID imc_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 imv_id)
+{
+ if (!tnc->imcs->is_registered(tnc->imcs, imc_id))
{
DBG1(DBG_TNC, "ignoring SendMessage() from unregistered IMC %u",
imc_id);
return TNC_RESULT_INVALID_PARAMETER;
}
- return charon->tnccs->send_message(charon->tnccs, imc_id, TNC_IMVID_ANY,
- connection_id, msg, msg_len, msg_type);
+ return tnc->tnccs->send_message(tnc->tnccs, imc_id, imv_id, connection_id,
+ msg_flags, msg, msg_len, msg_vid, msg_subtype);
+}
+
+/**
+ * Called by the IMC to get the value of an attribute associated with a
+ * connection or with the TNCC as a whole.
+ */
+TNC_Result TNC_TNCC_GetAttribute(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_AttributeID attribute_id,
+ TNC_UInt32 buffer_len,
+ TNC_BufferReference buffer,
+ TNC_UInt32 *out_value_len)
+{
+ if (!tnc->imcs->is_registered(tnc->imcs, imc_id))
+ {
+ DBG1(DBG_TNC, "ignoring GetAttribute() from unregistered IMC %u",
+ imc_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ return tnc->tnccs->get_attribute(tnc->tnccs, TRUE, imc_id, connection_id,
+ attribute_id, buffer_len, buffer, out_value_len);
+}
+
+/**
+ * Called by the IMC to set the value of an attribute associated with a
+ * connection or with the TNCC as a whole.
+ */
+TNC_Result TNC_TNCC_SetAttribute(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_AttributeID attribute_id,
+ TNC_UInt32 buffer_len,
+ TNC_BufferReference buffer)
+{
+ if (!tnc->imcs->is_registered(tnc->imcs, imc_id))
+ {
+ DBG1(DBG_TNC, "ignoring SetAttribute() from unregistered IMC %u",
+ imc_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ return tnc->tnccs->set_attribute(tnc->tnccs, TRUE, imc_id, connection_id,
+ attribute_id, buffer_len, buffer);
+}
+
+/**
+ * Called by the IMC when it wants to reserve an additional IMC ID for itself
+ */
+TNC_Result TNC_TNCC_ReserveAdditionalIMCID(TNC_IMCID imc_id, TNC_UInt32 *new_id)
+{
+ if (tnc->imcs->reserve_id(tnc->imcs, imc_id, new_id))
+ {
+ return TNC_RESULT_SUCCESS;
+ }
+ DBG1(DBG_TNC, "ignoring ReserveAdditionalIMCID() from unregistered IMC %u",
+ imc_id);
+ return TNC_RESULT_INVALID_PARAMETER;
}
/**
@@ -85,6 +186,10 @@ TNC_Result TNC_TNCC_BindFunction(TNC_IMCID id,
{
*function_pointer = (void*)TNC_TNCC_ReportMessageTypes;
}
+ else if (streq(function_name, "TNC_TNCC_ReportMessageTypesLong"))
+ {
+ *function_pointer = (void*)TNC_TNCC_ReportMessageTypesLong;
+ }
else if (streq(function_name, "TNC_TNCC_RequestHandshakeRetry"))
{
*function_pointer = (void*)TNC_TNCC_RequestHandshakeRetry;
@@ -93,6 +198,22 @@ TNC_Result TNC_TNCC_BindFunction(TNC_IMCID id,
{
*function_pointer = (void*)TNC_TNCC_SendMessage;
}
+ else if (streq(function_name, "TNC_TNCC_SendMessageLong"))
+ {
+ *function_pointer = (void*)TNC_TNCC_SendMessageLong;
+ }
+ else if (streq(function_name, "TNC_TNCC_GetAttribute"))
+ {
+ *function_pointer = (void*)TNC_TNCC_GetAttribute;
+ }
+ else if (streq(function_name, "TNC_TNCC_SetAttribute"))
+ {
+ *function_pointer = (void*)TNC_TNCC_SetAttribute;
+ }
+ else if (streq(function_name, "TNC_TNCC_ReserveAdditionalIMCID"))
+ {
+ *function_pointer = (void*)TNC_TNCC_ReserveAdditionalIMCID;
+ }
else
{
return TNC_RESULT_INVALID_PARAMETER;
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c b/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c
index ccf6aea67..e101cf974 100644
--- a/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c
+++ b/src/libcharon/plugins/tnc_imc/tnc_imc_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,12 @@
*/
#include "tnc_imc_manager.h"
+#include "tnc_imc.h"
-#include <tnc/imc/imc_manager.h>
-#include <tnc/tncifimc.h>
+#include <tncifimc.h>
-#include <debug.h>
-#include <library.h>
#include <utils/linked_list.h>
+#include <debug.h>
typedef struct private_tnc_imc_manager_t private_tnc_imc_manager_t;
@@ -94,6 +94,33 @@ METHOD(imc_manager_t, remove_, imc_t*,
return removed_imc;
}
+METHOD(imc_manager_t, load, bool,
+ private_tnc_imc_manager_t *this, char *name, char *path)
+{
+ imc_t *imc;
+
+ 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);
+ return TRUE;
+}
+
METHOD(imc_manager_t, is_registered, bool,
private_tnc_imc_manager_t *this, TNC_IMCID id)
{
@@ -104,9 +131,34 @@ METHOD(imc_manager_t, is_registered, bool,
enumerator = this->imcs->create_enumerator(this->imcs);
while (enumerator->enumerate(enumerator, &imc))
{
- if (id == imc->get_id(imc))
+ if (imc->has_id(imc, id))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return found;
+}
+
+METHOD(imc_manager_t, reserve_id, bool,
+ private_tnc_imc_manager_t *this, TNC_IMCID id, TNC_UInt32 *new_id)
+{
+ enumerator_t *enumerator;
+ imc_t *imc;
+ bool found = FALSE;
+
+ enumerator = this->imcs->create_enumerator(this->imcs);
+ while (enumerator->enumerate(enumerator, &imc))
+ {
+ if (imc->get_id(imc))
{
found = TRUE;
+ *new_id = this->next_imc_id++;
+ imc->add_id(imc, *new_id);
+ DBG2(DBG_TNC, "additional ID %u reserved for IMC with primary ID %u",
+ *new_id, id);
break;
}
}
@@ -177,30 +229,77 @@ METHOD(imc_manager_t, set_message_types, TNC_Result,
return result;
}
+METHOD(imc_manager_t, set_message_types_long, TNC_Result,
+ private_tnc_imc_manager_t *this, TNC_IMCID id,
+ TNC_VendorIDList supported_vids,
+ TNC_MessageSubtypeList supported_subtypes,
+ TNC_UInt32 type_count)
+{
+ enumerator_t *enumerator;
+ imc_t *imc;
+ TNC_Result result = TNC_RESULT_FATAL;
+
+ enumerator = this->imcs->create_enumerator(this->imcs);
+ while (enumerator->enumerate(enumerator, &imc))
+ {
+ if (id == imc->get_id(imc))
+ {
+ imc->set_message_types_long(imc, supported_vids, supported_subtypes,
+ type_count);
+ result = TNC_RESULT_SUCCESS;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return result;
+}
+
METHOD(imc_manager_t, receive_message, void,
private_tnc_imc_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_imv_id,
+ TNC_UInt32 dst_imc_id)
{
bool type_supported = FALSE;
+ TNC_MessageType msg_type;
+ TNC_UInt32 msg_flags;
enumerator_t *enumerator;
imc_t *imc;
enumerator = this->imcs->create_enumerator(this->imcs);
while (enumerator->enumerate(enumerator, &imc))
{
- if (imc->receive_message && imc->type_supported(imc, message_type))
+ if (imc->type_supported(imc, msg_vid, msg_subtype) &&
+ (!excl || (excl && imc->has_id(imc, dst_imc_id)) ))
{
- type_supported = TRUE;
- imc->receive_message(imc->get_id(imc), connection_id,
- message, message_len, message_type);
+ if (imc->receive_message_long && src_imv_id)
+ {
+ type_supported = TRUE;
+ msg_flags = excl ? TNC_MESSAGE_FLAGS_EXCLUSIVE : 0;
+ imc->receive_message_long(imc->get_id(imc), connection_id,
+ msg_flags, msg, msg_len, msg_vid, msg_subtype,
+ src_imv_id, dst_imc_id);
+
+ }
+ else if (imc->receive_message && msg_vid <= TNC_VENDORID_ANY &&
+ msg_subtype <= TNC_SUBTYPE_ANY)
+ {
+ type_supported = TRUE;
+ msg_type = (msg_vid << 8) | msg_subtype;
+ imc->receive_message(imc->get_id(imc), connection_id,
+ msg, msg_len, msg_type);
+ }
}
}
enumerator->destroy(enumerator);
if (!type_supported)
{
- DBG2(DBG_TNC, "message type 0x%08x not supported by any IMC", message_type);
+ DBG2(DBG_TNC, "message type 0x%06x/0x%08x not supported by any IMC",
+ msg_vid, msg_subtype);
}
}
@@ -251,11 +350,14 @@ imc_manager_t* tnc_imc_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_preferred_language = _get_preferred_language,
.notify_connection_change = _notify_connection_change,
.begin_handshake = _begin_handshake,
.set_message_types = _set_message_types,
+ .set_message_types_long = _set_message_types_long,
.receive_message = _receive_message,
.batch_ending = _batch_ending,
.destroy = _destroy,
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c b/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c
index bc13b8735..a25b1843c 100644
--- a/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c
+++ b/src/libcharon/plugins/tnc_imc/tnc_imc_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,180 +15,63 @@
#include "tnc_imc_plugin.h"
#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 <tnc/tnc.h>
-#include <daemon.h>
-#include <utils/lexparser.h>
+typedef struct private_tnc_imc_plugin_t private_tnc_imc_plugin_t;
/**
- * load IMCs from a configuration file
+ * Private data of a tnc_imc_plugin_t object.
*/
-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;
- }
+struct private_tnc_imc_plugin_t {
- /* 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))
- {
- 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;
-}
+ /**
+ * Public interface.
+ */
+ tnc_imc_plugin_t public;
+};
METHOD(plugin_t, get_name, char*,
- tnc_imc_plugin_t *this)
+ private_tnc_imc_plugin_t *this)
{
return "tnc-imc";
}
+METHOD(plugin_t, get_features, int,
+ private_tnc_imc_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(tnc_manager_register, tnc_imc_manager_create),
+ PLUGIN_PROVIDE(CUSTOM, "imc-manager"),
+ PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
- tnc_imc_plugin_t *this)
+ private_tnc_imc_plugin_t *this)
{
- charon->imcs->destroy(charon->imcs);
free(this);
}
/*
* see header file
*/
-plugin_t *tnc_imc_plugin_create()
+plugin_t *tnc_imc_plugin_create(void)
{
- char *tnc_config;
- tnc_imc_plugin_t *this;
+ private_tnc_imc_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,
+ },
},
);
- /* Create IMC manager */
- charon->imcs = tnc_imc_manager_create();
-
- /* Load IMCs and abort if not all instances initalize successfully */
- tnc_config = lib->settings->get_str(lib->settings,
- "charon.plugins.tnc-imc.tnc_config", "/etc/tnc_config");
- if (!load_imcs(tnc_config))
- {
- charon->imcs->destroy(charon->imcs);
- charon->imcs = NULL;
- free(this);
- return NULL;
- }
- return &this->plugin;
+ return &this->public.plugin;
}