diff options
author | Yves-Alexis Perez <corsac@corsac.net> | 2012-06-28 21:16:07 +0200 |
---|---|---|
committer | Yves-Alexis Perez <corsac@corsac.net> | 2012-06-28 21:16:07 +0200 |
commit | a3b482a8facde4b453ad821bfe40effbe3d17903 (patch) | |
tree | 636f02074b05b7473f5db1fe60fa2bceb0094a62 /src/libcharon/plugins/tnc_imc | |
parent | d816a1afbd841e9943bb439fe4e110b7c4970550 (diff) | |
parent | b34738ed08c2227300d554b139e2495ca5da97d6 (diff) | |
download | vyos-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.am | 9 | ||||
-rw-r--r-- | src/libcharon/plugins/tnc_imc/Makefile.in | 21 | ||||
-rw-r--r-- | src/libcharon/plugins/tnc_imc/tnc_imc.c | 214 | ||||
-rw-r--r-- | src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c | 147 | ||||
-rw-r--r-- | src/libcharon/plugins/tnc_imc/tnc_imc_manager.c | 130 | ||||
-rw-r--r-- | src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c | 183 |
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; } |