implement IMC and IMV manager classes
authorAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 5 Nov 2010 23:54:10 +0000 (00:54 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 9 Nov 2010 19:43:50 +0000 (20:43 +0100)
20 files changed:
src/libcharon/Makefile.am
src/libcharon/daemon.c
src/libcharon/daemon.h
src/libcharon/plugins/tnc_imc/Makefile.am
src/libcharon/plugins/tnc_imc/tnc_imc.c
src/libcharon/plugins/tnc_imc/tnc_imc.h
src/libcharon/plugins/tnc_imc/tnc_imc_manager.c [new file with mode: 0644]
src/libcharon/plugins/tnc_imc/tnc_imc_manager.h [new file with mode: 0644]
src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c
src/libcharon/plugins/tnc_imv/Makefile.am
src/libcharon/plugins/tnc_imv/tnc_imv.c
src/libcharon/plugins/tnc_imv/tnc_imv.h
src/libcharon/plugins/tnc_imv/tnc_imv_manager.c [new file with mode: 0644]
src/libcharon/plugins/tnc_imv/tnc_imv_manager.h [new file with mode: 0644]
src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c
src/libcharon/plugins/tnccs_20/tnccs_20.c
src/libcharon/tnc/imc/imc.h
src/libcharon/tnc/imc/imc_manager.h [new file with mode: 0644]
src/libcharon/tnc/imv/imv.h
src/libcharon/tnc/imv/imv_manager.h [new file with mode: 0644]

index 3cf4871..602128a 100644 (file)
@@ -88,9 +88,10 @@ sa/tasks/ike_auth_lifetime.c sa/tasks/ike_auth_lifetime.h \
 sa/tasks/ike_vendor.c sa/tasks/ike_vendor.h \
 sa/tasks/task.c sa/tasks/task.h \
 tnc/tncif.h tnc/tncifimc.h tnc/tncifimv.h \
-tnc/imc/imc.h tnc/imv/imv.h \
+tnc/imc/imc.h tnc/imc/imc_manager.h \
+tnc/imv/imv.h tnc/imv/imv_manager.h \
 tnc/tnccs/tnccs.c tnc/tnccs/tnccs.h \
-tnc/tnccs/tnccs_manager.h tnc/tnccs/tnccs_manager.c
+tnc/tnccs/tnccs_manager.c tnc/tnccs/tnccs_manager.h
 
 daemon.lo :            $(top_builddir)/config.status
 
index 2f36938..4b8e1fa 100644 (file)
@@ -128,10 +128,6 @@ static void destroy(private_daemon_t *this)
        DESTROY_IF(this->public.backends);
        DESTROY_IF(this->public.socket);
 
-       /* destroy lists of TNC IMCs and IMVs */
-       DESTROY_IF(this->public.imcs);
-       DESTROY_IF(this->public.imvs);
-
        /* rehook library logging, shutdown logging */
        dbg = dbg_old;
        DESTROY_IF(this->public.bus);
@@ -424,8 +420,6 @@ private_daemon_t *daemon_create()
                        .start = _start,
                        .file_loggers = linked_list_create(),
                        .sys_loggers = linked_list_create(),
-                       .imcs = linked_list_create(),
-                       .imvs = linked_list_create(),
                },
        );
 
index 9a2ca8f..78c78b3 100644 (file)
@@ -149,6 +149,8 @@ typedef struct daemon_t daemon_t;
 #include <config/backend_manager.h>
 #include <sa/authenticators/eap/eap_manager.h>
 #include <sa/authenticators/eap/sim_manager.h>
+#include <tnc/imc/imc_manager.h>
+#include <tnc/imv/imv_manager.h>
 #include <tnc/tnccs/tnccs_manager.h>
 
 #ifdef ME
@@ -237,19 +239,19 @@ struct daemon_t {
        sim_manager_t *sim;
 
        /**
-        * TNCCS manager to maintain registered TNCCS protocols
+        * TNC IMC manager controlling Integrity Measurement Collectors
         */
-       tnccs_manager_t *tnccs;
+       imc_manager_t *imcs;
 
        /**
-        * A list of installed TNC Integrity Measurement Collectors
+        * TNC IMV manager controlling Integrity Measurement Verifiers
         */
-       linked_list_t *imcs;
+       imv_manager_t *imvs;
 
        /**
-        * A list of installed TNC Integrity Measurement Verifiers
+        * TNCCS manager to maintain registered TNCCS protocols
         */
-       linked_list_t *imvs;
+       tnccs_manager_t *tnccs;
 
 #ifdef ME
        /**
index 44f647f..4b54d45 100644 (file)
@@ -11,7 +11,8 @@ plugin_LTLIBRARIES = libstrongswan-tnc-imc.la
 endif
 
 libstrongswan_tnc_imc_la_SOURCES = \
-       tnc_imc_plugin.h tnc_imc_plugin.c tnc_imc.h tnc_imc.c
+       tnc_imc_plugin.h tnc_imc_plugin.c tnc_imc.h tnc_imc.c \
+       tnc_imc_manager.h tnc_imc_manager.c
 
 libstrongswan_tnc_imc_la_LDFLAGS = -module -avoid-version
 
index 60f907a..6e0b4a5 100644 (file)
@@ -40,6 +40,12 @@ struct private_tnc_imc_t {
        TNC_IMCID id;
 };
 
+METHOD(imc_t, set_id, void,
+       private_tnc_imc_t *this, TNC_IMCID id)
+{
+       this->id = id;
+}
+
 METHOD(imc_t, get_id, TNC_IMCID,
        private_tnc_imc_t *this)
 {
@@ -62,14 +68,16 @@ METHOD(imc_t, destroy, void,
 /**
  * Described in header.
  */
-imc_t* tnc_imc_create(char* name, char *filename, TNC_IMCID id)
+imc_t* tnc_imc_create(char* name, char *filename)
 {
        private_tnc_imc_t *this;
        void *handle;
 
        INIT(this,
                .public = {
+                       .set_id = _set_id,
                        .get_id = _get_id,
+                       .get_name = _get_name,
                        .destroy = _destroy,
         },
        );
@@ -79,7 +87,6 @@ imc_t* tnc_imc_create(char* name, char *filename, TNC_IMCID id)
        {
                DBG1(DBG_TNC, "IMC '%s' failed to load from '%s': %s",
                                           name, filename, dlerror());
-               free(this->name);
                free(this);
                return NULL;
        }
@@ -120,10 +127,105 @@ imc_t* tnc_imc_create(char* name, char *filename, TNC_IMCID id)
                free(this);
                return NULL;
        }
-       DBG2(DBG_TNC, "IMC '%s' loaded successfully with ID %u", name, id);
        this->name = strdup(name);
-       this->id = id;
 
        return &this->public;
 }
 
+/**
+ * Called by the IMC to inform a TNCC about the set of message types the IMC
+ * is able to receive
+ */
+TNC_Result TNC_TNCC_ReportMessageTypes(TNC_IMCID imc_id,
+                                                                          TNC_MessageTypeList supported_types,
+                                                                          TNC_UInt32 type_count)
+{
+       DBG2(DBG_TNC,"TNCC_ReportMessageTypes %u %u", imc_id, type_count);
+       return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * Called by the IMC to ask a TNCC to retry an Integrity Check Handshake
+ */
+TNC_Result TNC_TNCC_RequestHandshakeRetry(TNC_IMCID imc_id,
+                                                                                 TNC_ConnectionID connection_id,
+                                                                                 TNC_RetryReason reason)
+{
+       DBG2(DBG_TNC,"TNCC_RequestHandshakeRetry %u %u", imc_id, connection_id);
+       return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * Called by the IMC when an IMC-IMV message is to be sent
+ */
+TNC_Result TNC_TNCC_SendMessage(TNC_IMCID imc_id,
+                                                               TNC_ConnectionID connection_id,
+                                                               TNC_BufferReference message,
+                                                               TNC_UInt32 message_len,
+                                                               TNC_MessageType message_type)
+{
+       DBG2(DBG_TNC,"TNCC_SendMessage %u %u '%s' %u %0x", imc_id, connection_id,
+                                 message, message_len, message_type);
+
+       /*
+       -----TNCCS 2.0-----
+    tnc_tncc_connection* conn;
+
+    conn = libtnc_array_index(&connections, connectionID);
+    
+    TNC_MessageSubtype message_type = messageType             & TNC_SUBTYPE_ANY;
+    TNC_VendorID       message_vendor_id = (messageType >> 8) & TNC_VENDORID_ANY;
+    
+    chunk_t pa_message = tnc_create_pa_message(FALSE, message_vendor_id,
+                                                                       message_type, 0, 0, message, messageLength); 
+        
+    if(conn->current_batch.len)
+    {
+         chunk_t batch = conn->current_batch;
+         htoun32(batch.ptr + 4,batch.len + pa_message.len);
+         conn->current_batch = chunk_cat("cc", batch, pa_message);
+
+    }
+    else
+    {
+         chunk_t header = tnc_create_batch_header(TNCCS_BATCH_TYPE_CDATA, false);
+         
+         htoun32(header.ptr + 4,header.len + pa_message.len);
+         conn->current_batch = chunk_cat("cc", header, pa_message);
+
+    }
+    -----TNCCS 1.1-----
+    libtnc_mutex_lock();
+    conn = libtnc_array_index(&connections, connectionID);
+    libtnc_mutex_unlock();
+    return libtnc_tncc_add_imc_imv_message(conn, message, messageLength, messageType);
+       */
+    return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * Called by the IMC when it needs a function pointer
+ */
+TNC_Result TNC_TNCC_BindFunction(TNC_IMCID id,
+                                                                char *function_name,
+                                                                void **function_pointer)
+{
+       if (streq(function_name, "TNC_TNCC_ReportMessageTypes"))
+       {
+               *function_pointer = (void*)TNC_TNCC_ReportMessageTypes;
+       }
+    else if (streq(function_name, "TNC_TNCC_RequestHandshakeRetry"))
+       {
+               *function_pointer = (void*)TNC_TNCC_RequestHandshakeRetry;
+       }
+    else if (streq(function_name, "TNC_TNCC_SendMessage"))
+       {
+               *function_pointer = (void*)TNC_TNCC_SendMessage;
+       }
+    else
+       {
+               return TNC_RESULT_INVALID_PARAMETER;
+       }
+    return TNC_RESULT_SUCCESS;
+}
index 2becbdf..fff520f 100644 (file)
@@ -29,9 +29,8 @@
  *
  * @param name                 name of the IMC
  * @param filename             path to the dynamic IMC library
- * @param id                   ID of the IMC
  * @return                             instance of the imc_t interface
  */
-imc_t* tnc_imc_create(char *name, char *filename, TNC_IMCID id);
+imc_t* tnc_imc_create(char *name, char *filename);
 
 #endif /** TNC_IMC_H_ @}*/
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c b/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c
new file mode 100644 (file)
index 0000000..47b00da
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2006 Mike McCauley
+ * Copyright (C) 2010 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "tnc_imc_manager.h"
+
+#include <tnc/imc/imc_manager.h>
+#include <tnc/tncifimc.h>
+
+#include <debug.h>
+#include <library.h>
+#include <utils/linked_list.h>
+
+typedef struct private_tnc_imc_manager_t private_tnc_imc_manager_t;
+
+struct private_tnc_imc_manager_t {
+
+       /**
+        * Public members of imc_manager_t.
+        */
+       imc_manager_t public;
+
+       /**
+        * Linked list of IMCs
+        */
+       linked_list_t *imcs;
+
+       /**
+        * Next IMC ID to be assigned
+        */
+       TNC_IMCID next_imc_id;
+};
+
+METHOD(imc_manager_t, add, bool,
+       private_tnc_imc_manager_t *this, imc_t *imc)
+{
+       TNC_Version version;
+
+       /* Initialize the module */
+       imc->set_id(imc, this->next_imc_id);
+       if (imc->initialize(imc->get_id(imc), TNC_IFIMC_VERSION_1,
+                       TNC_IFIMC_VERSION_1, &version) != TNC_RESULT_SUCCESS)
+       {
+               DBG1(DBG_TNC, "could not initialize IMC '%s'",
+                                          imc->get_name(imc));
+               return FALSE;
+       }
+    if (imc->provide_bind_function(imc->get_id(imc), TNC_TNCC_BindFunction)
+                       != TNC_RESULT_SUCCESS)
+       {
+               DBG1(DBG_TNC, "could not provide bind function for IMC '%s'",
+                                          imc->get_name(imc));
+               return FALSE;
+       }
+       this->imcs->insert_last(this->imcs, imc);
+       this->next_imc_id++;
+
+       return TRUE;
+}
+
+METHOD(imc_manager_t, notify_connection_change, void,
+       private_tnc_imc_manager_t *this, TNC_ConnectionID id,
+       TNC_ConnectionState state)
+{
+       enumerator_t *enumerator;
+       imc_t *imc;
+
+       enumerator = this->imcs->create_enumerator(this->imcs);
+       while (enumerator->enumerate(enumerator, &imc))
+       {
+               if (imc->notify_connection_change)
+               {
+                       imc->notify_connection_change(imc->get_id(imc), id, state);
+               }
+       }
+       enumerator->destroy(enumerator);
+}
+
+METHOD(imc_manager_t, begin_handshake, void,
+       private_tnc_imc_manager_t *this, TNC_ConnectionID id)
+{
+       enumerator_t *enumerator;
+       imc_t *imc;
+
+       enumerator = this->imcs->create_enumerator(this->imcs);
+       while (enumerator->enumerate(enumerator, &imc))
+       {
+               imc->begin_handshake(imc->get_id(imc), id);
+       }
+       enumerator->destroy(enumerator);
+}
+
+METHOD(imc_manager_t, destroy, void,
+       private_tnc_imc_manager_t *this)
+{
+       imc_t *imc;
+
+       while (this->imcs->remove_last(this->imcs, (void**)&imc) == SUCCESS)
+       {
+               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);
+       }
+       this->imcs->destroy(this->imcs);
+       free(this);
+}
+
+/**
+ * Described in header.
+ */
+imc_manager_t* tnc_imc_manager_create(void)
+{
+       private_tnc_imc_manager_t *this;
+
+       INIT(this,
+               .public = {
+                       .add = _add,
+                       .notify_connection_change = _notify_connection_change,
+                       .begin_handshake = _begin_handshake,
+                       .destroy = _destroy,
+        },
+               .imcs = linked_list_create(),
+               .next_imc_id = 1,
+       );
+
+
+       return &this->public;
+}
+
+
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_manager.h b/src/libcharon/plugins/tnc_imc/tnc_imc_manager.h
new file mode 100644 (file)
index 0000000..ed49029
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2010 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ *
+ * @defgroup tnc_imc_manager tnc_imc_manager
+ * @{ @ingroup tnc_imc
+ */
+
+#ifndef TNC_IMC_MANAGER_H_
+#define TNC_IMC_MANAGER_H_
+
+#include <tnc/imc/imc_manager.h>
+
+/**
+ * Create an IMC manager instance.
+ */
+imc_manager_t *tnc_imc_manager_create();
+
+#endif /** TNC_IMC_MANAGER_H_ @}*/
index 21cca66..99baddc 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include "tnc_imc_plugin.h"
+#include "tnc_imc_manager.h"
 #include "tnc_imc.h"
 
 #include <daemon.h>
 METHOD(plugin_t, destroy, void,
        tnc_imc_plugin_t *this)
 {
-       imc_t *imc;
-
-       while (charon->imcs->remove_last(charon->imcs, (void**)&imc) == SUCCESS)
-       {
-               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);
-       }
+       charon->imcs->destroy(charon->imcs);
        free(this);
 }
 
@@ -41,8 +31,6 @@ METHOD(plugin_t, destroy, void,
  */
 plugin_t *tnc_imc_plugin_create()
 {
-       TNC_IMCID next_id = 1;
-       TNC_Version version;
        char *tnc_config, *pref_lang, *name, *filename;
        tnc_imc_plugin_t *this;
        imc_t *imc;
@@ -58,24 +46,19 @@ plugin_t *tnc_imc_plugin_create()
        tnc_config = lib->settings->get_str(lib->settings,
                                        "charon.plugins.tnc-imc.tnc_config", "/etc/tnc_config");
 
+       /* Create IMC manager */
+       charon->imcs = tnc_imc_manager_create();
+
+       /* Create and register IMCs */
        name = "Dummy";
        filename = "/usr/local/lib/libdummyimc.so";
-       imc = tnc_imc_create(name, filename, next_id);
+       imc = tnc_imc_create(name, filename);
        if (imc)
        {
-               /* Initialize the module */
-               if (imc->initialize(next_id, TNC_IFIMC_VERSION_1, TNC_IFIMC_VERSION_1,
-                                                       &version) != TNC_RESULT_SUCCESS)
+               if (!charon->imcs->add(charon->imcs, imc))
                {
-                       DBG1(DBG_TNC, "could not initialize IMC '%s'\n",
-                                                  imc->get_name(imc));
                        imc->destroy(imc);
                }
-               else
-               {
-                       charon->imcs->insert_last(charon->imcs, imc);
-                       next_id++;
-               }
        }
        return &this->plugin;
 }
index 28aa49f..5ef0bcf 100644 (file)
@@ -11,7 +11,8 @@ plugin_LTLIBRARIES = libstrongswan-tnc-imv.la
 endif
 
 libstrongswan_tnc_imv_la_SOURCES = \
-       tnc_imv_plugin.h tnc_imv_plugin.c tnc_imv.h tnc_imv.c
+       tnc_imv_plugin.h tnc_imv_plugin.c tnc_imv.h tnc_imv.c \
+       tnc_imv_manager.h tnc_imv_manager.c
 
 libstrongswan_tnc_imv_la_LDFLAGS = -module -avoid-version
 
index 27af2ac..60e81a4 100644 (file)
@@ -40,12 +40,24 @@ struct private_tnc_imv_t {
        TNC_IMVID id;
 };
 
+METHOD(imv_t, set_id, void,
+       private_tnc_imv_t *this, TNC_IMVID id)
+{
+       this->id = id;
+}
+
 METHOD(imv_t, get_id, TNC_IMVID,
        private_tnc_imv_t *this)
 {
        return this->id;
 }
 
+METHOD(imv_t, get_name, char*,
+       private_tnc_imv_t *this)
+{
+       return this->name;
+}
+
 METHOD(imv_t, destroy, void,
        private_tnc_imv_t *this)
 {
@@ -56,14 +68,16 @@ METHOD(imv_t, destroy, void,
 /**
  * Described in header.
  */
-imv_t* tnc_imv_create(char *name, char *filename, TNC_IMVID id)
+imv_t* tnc_imv_create(char *name, char *filename)
 {
        private_tnc_imv_t *this;
        void *handle;
 
        INIT(this,
                .public = {
+                       .set_id = _set_id,
                        .get_id = _get_id,
+                       .get_name = _get_name,
                        .destroy = _destroy,
         },
        );
@@ -114,10 +128,87 @@ imv_t* tnc_imv_create(char *name, char *filename, TNC_IMVID id)
                free(this);
                return NULL;
        }
-       DBG2(DBG_TNC, "IMV '%s' loaded successfully with ID %u", name, id);
        this->name = strdup(name);
-       this->id = id;
 
        return &this->public;
 }
 
+/**
+ * Called by the IMV to inform a TNCS about the set of message types the IMV
+ * is able to receive
+ */
+TNC_Result TNC_TNCS_ReportMessageTypes(TNC_IMVID imv_id,
+                                                                          TNC_MessageTypeList supported_types,
+                                                                          TNC_UInt32 type_count)
+{
+       DBG2(DBG_TNC,"TNCS_ReportMessageTypes %u %u", imv_id, type_count);
+       return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * Called by the IMV to ask a TNCS to retry an Integrity Check Handshake
+ */
+TNC_Result TNC_TNCS_RequestHandshakeRetry(TNC_IMVID imv_id,
+                                                                                 TNC_ConnectionID connection_id,
+                                                                                 TNC_RetryReason reason)
+{
+       DBG2(DBG_TNC,"TNCS_RequestHandshakeRetry %u %u", imv_id, connection_id);
+       return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * Called by the IMV when an IMV-IMC message is to be sent
+ */
+TNC_Result TNC_TNCS_SendMessage(TNC_IMVID imv_id,
+                                                               TNC_ConnectionID connection_id,
+                                                               TNC_BufferReference message,
+                                                               TNC_UInt32 message_len,
+                                                               TNC_MessageType message_type)
+{
+       DBG2(DBG_TNC,"TNCS_SendMessage %u %u '%s' %u %0x", imv_id, connection_id,
+                                 message, message_len, message_type);
+       return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * Called by the IMV to deliver its IMV Action Recommendation and IMV Evaluation
+ * Result to the TNCS
+ */
+TNC_Result TNC_TNCS_ProvideRecommendation(TNC_IMVID imv_id,
+                                                               TNC_ConnectionID connection_id,
+                                                               TNC_IMV_Action_Recommendation recommendation,
+                                                               TNC_IMV_Evaluation_Result evaluation)
+{
+       DBG2(DBG_TNC,"TNCS_ProvideRecommendation %u %u", imv_id, connection_id);
+       return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * Called by the IMV when it needs a function pointer
+ */
+TNC_Result TNC_TNCS_BindFunction(TNC_IMVID id,
+                                                                char *function_name,
+                                                                void **function_pointer)
+{
+       if (streq(function_name, "TNC_TNCS_ReportMessageTypes"))
+       {
+               *function_pointer = (void*)TNC_TNCS_ReportMessageTypes;
+       }
+    else if (streq(function_name, "TNC_TNCS_RequestHandshakeRetry"))
+       {
+               *function_pointer = (void*)TNC_TNCS_RequestHandshakeRetry;
+       }
+    else if (streq(function_name, "TNC_TNCS_SendMessage"))
+       {
+               *function_pointer = (void*)TNC_TNCS_SendMessage;
+       }
+    else if (streq(function_name, "TNC_TNCS_ProvideRecommendation"))
+       {
+               *function_pointer = (void*)TNC_TNCS_ProvideRecommendation;
+       }
+    else
+       {
+               return TNC_RESULT_INVALID_PARAMETER;
+       }
+    return TNC_RESULT_SUCCESS;
+}
index 694aa63..023bbc5 100644 (file)
@@ -29,9 +29,8 @@
  *
  * @param name                 name of the IMV
  * @param filename             path to the dynamic IMV library
- * @param id                   ID of the IMV
  * @return                             instance of the imv_t interface
  */
-imv_t* tnc_imv_create(char *name, char *filename, TNC_IMVID id);
+imv_t* tnc_imv_create(char *name, char *filename);
 
 #endif /** TNC_IMV_H_ @}*/
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c b/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c
new file mode 100644 (file)
index 0000000..44849c1
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2006 Mike McCauley
+ * Copyright (C) 2010 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "tnc_imv_manager.h"
+
+#include <tnc/imv/imv_manager.h>
+#include <tnc/tncifimv.h>
+
+#include <debug.h>
+#include <library.h>
+#include <utils/linked_list.h>
+
+typedef struct private_tnc_imv_manager_t private_tnc_imv_manager_t;
+
+struct private_tnc_imv_manager_t {
+
+       /**
+        * Public members of imv_manager_t.
+        */
+       imv_manager_t public;
+
+       /**
+        * Linked list of IMVs
+        */
+       linked_list_t *imvs;
+
+       /**
+        * Next IMV ID to be assigned
+        */
+       TNC_IMVID next_imv_id;
+};
+
+METHOD(imv_manager_t, add, bool,
+       private_tnc_imv_manager_t *this, imv_t *imv)
+{
+       TNC_Version version;
+
+       /* Initialize the IMV module */
+       imv->set_id(imv, this->next_imv_id);
+       if (imv->initialize(imv->get_id(imv), TNC_IFIMV_VERSION_1,
+               TNC_IFIMV_VERSION_1, &version) != TNC_RESULT_SUCCESS)
+       {
+               DBG1(DBG_TNC, "could not initialize IMV '%s'",
+                                          imv->get_name(imv));
+               return FALSE;
+       }
+    if (imv->provide_bind_function(imv->get_id(imv), TNC_TNCS_BindFunction)
+                       != TNC_RESULT_SUCCESS)
+       {
+               DBG1(DBG_TNC, "could not provide bind function for IMV '%s'",
+                                          imv->get_name(imv));
+               return FALSE;
+       }
+       this->imvs->insert_last(this->imvs, imv);
+       this->next_imv_id++;
+       return TRUE;
+}
+
+METHOD(imv_manager_t, notify_connection_change, void,
+       private_tnc_imv_manager_t *this, TNC_ConnectionID id,
+       TNC_ConnectionState state)
+{
+       enumerator_t *enumerator;
+       imv_t *imv;
+
+       enumerator = this->imvs->create_enumerator(this->imvs);
+       while (enumerator->enumerate(enumerator, &imv))
+       {
+               if (imv->notify_connection_change)
+               {
+                       imv->notify_connection_change(imv->get_id(imv), id, state);
+               }
+       }
+       enumerator->destroy(enumerator);
+}
+
+METHOD(imv_manager_t, destroy, void,
+       private_tnc_imv_manager_t *this)
+{
+       imv_t *imv;
+
+       while (this->imvs->remove_last(this->imvs, (void**)&imv) == SUCCESS)
+       {
+               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);
+       }
+       this->imvs->destroy(this->imvs);
+       free(this);
+}
+
+/**
+ * Described in header.
+ */
+imv_manager_t* tnc_imv_manager_create(void)
+{
+       private_tnc_imv_manager_t *this;
+
+       INIT(this,
+               .public = {
+                       .add = _add,
+                       .notify_connection_change = _notify_connection_change,
+                       .destroy = _destroy,
+        },
+               .imvs = linked_list_create(),
+               .next_imv_id = 1,
+       );
+
+
+       return &this->public;
+}
+
+
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_manager.h b/src/libcharon/plugins/tnc_imv/tnc_imv_manager.h
new file mode 100644 (file)
index 0000000..bd38165
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2010 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ *
+ * @defgroup tnc_imv_manager tnc_imv_manager
+ * @{ @ingroup tnc_imv
+ */
+
+#ifndef TNC_IMV_MANAGER_H_
+#define TNC_IMV_MANAGER_H_
+
+#include <tnc/imv/imv_manager.h>
+
+/**
+ * Create an IMC manager instance.
+ */
+imv_manager_t *tnc_imv_manager_create();
+
+#endif /** TNC_IMV_MANAGER_H_ @}*/
index 99e4dce..f3b9bb0 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include "tnc_imv_plugin.h"
+#include "tnc_imv_manager.h"
 #include "tnc_imv.h"
 
 #include <daemon.h>
 METHOD(plugin_t, destroy, void,
        tnc_imv_plugin_t *this)
 {
-       imv_t *imv;
-
-       while (charon->imvs->remove_last(charon->imvs, (void**)&imv) == SUCCESS)
-       {
-               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);
-       }
+       charon->imvs->destroy(charon->imvs);
        free(this);
 }
 
@@ -41,8 +31,6 @@ METHOD(plugin_t, destroy, void,
  */
 plugin_t *tnc_imv_plugin_create()
 {
-       TNC_IMVID next_id = 1;
-       TNC_Version version;
        char *tnc_config, *name, *filename;
        tnc_imv_plugin_t *this;
        imv_t *imv;
@@ -56,24 +44,19 @@ plugin_t *tnc_imv_plugin_create()
        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();
+
+       /* Create and register IMVs */
        name = "Dummy";
        filename = "/usr/local/lib/libdummyimv.so";
-       imv = tnc_imv_create(name, filename, next_id);
+       imv = tnc_imv_create(name, filename);
        if (imv)
        {
-               /* Initialize the module */
-               if (imv->initialize(next_id, TNC_IFIMV_VERSION_1, TNC_IFIMV_VERSION_1,
-                                                       &version) != TNC_RESULT_SUCCESS)
+               if (!charon->imvs->add(charon->imvs, imv))
                {
-                       DBG1(DBG_TNC, "could not initialize IMV '%s'\n",
-                                                  imv->get_name(imv));
                        imv->destroy(imv);
                }
-               else
-               {
-                       charon->imvs->insert_last(charon->imvs, imv);
-                       next_id++;
-               }
        }
        return &this->plugin;
 }
index 2bd1bc4..2d6bdf5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Andreas Steffen
+ * Copyright (C) 2010 Sansar Choinyanbuu
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -16,8 +16,9 @@
 #include "tnccs_20.h"
 
 #include <debug.h>
-
-static chunk_t tncc_output;
+#include <daemon.h>
+#include <tnc/tncif.h>
+#include <tnc/tnccs/tnccs.h>
 
 typedef struct private_tnccs_20_t private_tnccs_20_t;
 
@@ -35,17 +36,54 @@ struct private_tnccs_20_t {
         * TNCC if TRUE, TNCS if FALSE
         */
        bool is_server;
+
+       /**
+        * Connection ID assigned to this TNCCS connection
+        */
+       TNC_ConnectionID connection_id;
 };
 
 METHOD(tls_t, process, status_t,
        private_tnccs_20_t *this, void *buf, size_t buflen)
 {
+       if (this->is_server && !this->connection_id)
+       {
+               this->connection_id = charon->tnccs->create_connection(charon->tnccs,
+                                                                                                                         (tnccs_t*)this);
+               charon->imvs->notify_connection_change(charon->imvs,
+                                                       this->connection_id, TNC_CONNECTION_STATE_CREATE);
+       }
+       DBG1(DBG_TNC, "received TNCCS Batch (%u bytes) for Connection ID %u",
+                                  buflen, this->connection_id);
+       DBG3(DBG_TNC, "%.*s", buflen, buf);
+
        return NEED_MORE;
 }
 
 METHOD(tls_t, build, status_t,
        private_tnccs_20_t *this, void *buf, size_t *buflen, size_t *msglen)
 {
+       char *msg;
+
+       if (!this->is_server && !this->connection_id)
+       {
+               this->connection_id = charon->tnccs->create_connection(charon->tnccs,
+                                                                                                                         (tnccs_t*)this);
+               charon->imcs->notify_connection_change(charon->imcs,
+                                                       this->connection_id, TNC_CONNECTION_STATE_CREATE);
+               charon->imcs->notify_connection_change(charon->imcs,
+                                                       this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
+               charon->imcs->begin_handshake(charon->imcs, this->connection_id);
+       }
+
+       msg = this->is_server ? "tncs-tncc 2.0" : "tncc-tncs 2.0";
+       DBG1(DBG_TNC, "sending TNCCS Batch (%d bytes) for Connection ID %u",
+                                  strlen(msg), this->connection_id);
+       DBG3(DBG_TNC, "%s", msg);
+       *msglen = strlen(msg);
+       memcpy(buf, msg, *msglen);
+       *buflen = *msglen;
+
        return ALREADY_DONE;
 }
 
@@ -76,6 +114,7 @@ METHOD(tls_t, get_eap_msk, chunk_t,
 METHOD(tls_t, destroy, void,
        private_tnccs_20_t *this)
 {
+       charon->tnccs->remove_connection(charon->tnccs, this->connection_id);
        free(this);
 }
 
index 8c03ee6..bfa1573 100644 (file)
@@ -18,8 +18,8 @@
  * @{ @ingroup libcharon
  */
 
-#ifndef IMV_H_
-#define IMV_H_
+#ifndef IMC_H_
+#define IMC_H_
 
 #include <tnc/tncifimc.h>
 
@@ -122,9 +122,16 @@ struct imc_t {
                                                                                TNC_TNCC_BindFunctionPointer bindFunction);
 
        /**
+        * Sets the ID of an imc_t object.
+        *
+        * @param id                            IMC ID to be assigned
+        */
+       void (*set_id)(imc_t *this, TNC_IMCID id);
+
+       /**
         * Returns the ID of an imc_t object.
         *
-        * @result                                      IMC ID assigned by TNCC
+        * @result                                      assigned IMC ID
         */
        TNC_IMCID (*get_id)(imc_t *this);
 
@@ -141,4 +148,4 @@ struct imc_t {
        void (*destroy)(imc_t *this);
 };
 
-#endif /** IMV_H_ @}*/
+#endif /** IMC_H_ @}*/
diff --git a/src/libcharon/tnc/imc/imc_manager.h b/src/libcharon/tnc/imc/imc_manager.h
new file mode 100644 (file)
index 0000000..945a5cf
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup imc_manager imc_manager
+ * @{ @ingroup imc
+ */
+
+#ifndef IMC_MANAGER_H_
+#define IMC_MANAGER_H_
+
+#include "imc.h"
+
+#include <library.h>
+
+typedef struct imc_manager_t imc_manager_t;
+
+/**
+ * The IMC manager controls all IMC instances.
+ */
+struct imc_manager_t {
+
+       /**
+        * Add an IMC instance
+        *
+        * @param imc                   IMC instance
+        * @return                              TRUE if initialization successful
+        */
+        bool (*add)(imc_manager_t *this, imc_t *imc);
+
+       /**
+        * Notify all IMC instances
+        *
+        * @param state                 communicate the state a connection has reached
+        */
+       void (*notify_connection_change)(imc_manager_t *this,
+                                                                        TNC_ConnectionID id,
+                                                                        TNC_ConnectionState state);
+
+       /**
+        * Begin a handshake between the IMCs and a connection
+        *
+        * @param id                    Connection ID
+        */
+       void (*begin_handshake)(imc_manager_t *this, TNC_ConnectionID id);
+
+       /**
+        * Destroy an IMC manager and all its controlled instances.
+        */
+       void (*destroy)(imc_manager_t *this);
+};
+
+#endif /** IMC_MANAGER_H_ @}*/
index 6d4769f..ca07473 100644 (file)
@@ -122,6 +122,13 @@ struct imv_t {
                                                                                TNC_TNCS_BindFunctionPointer bindFunction);
 
        /**
+        * Sets the ID of an imv_t object.
+        *
+        * @param id                            IMV ID to be assigned
+        */
+       void (*set_id)(imv_t *this, TNC_IMVID id);
+
+       /**
         * Returns the ID of an imv_t object.
         *
         * @result                                      IMV ID assigned by TNCS
diff --git a/src/libcharon/tnc/imv/imv_manager.h b/src/libcharon/tnc/imv/imv_manager.h
new file mode 100644 (file)
index 0000000..b532275
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2010 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup imv_manager imv_manager
+ * @{ @ingroup imv
+ */
+
+#ifndef IMV_MANAGER_H_
+#define IMV_MANAGER_H_
+
+#include "imv.h"
+
+#include <library.h>
+
+typedef struct imv_manager_t imv_manager_t;
+
+/**
+ * The IMV manager controls all IMV instances.
+ */
+struct imv_manager_t {
+
+       /**
+        * Add an IMV instance
+        *
+        * @param imv                   IMV instance
+        * @return                              TRUE if initialization successful
+        */
+       bool (*add)(imv_manager_t *this, imv_t *imv);
+
+       /**
+        * Notify all IMV instances
+        *
+        * @param state                 communicate the state a connection has reached
+        */
+       void (*notify_connection_change)(imv_manager_t *this,
+                                                                        TNC_ConnectionID id,
+                                                                        TNC_ConnectionState state);
+       /**
+        * Destroy an IMV manager and all its controlled instances.
+        */
+       void (*destroy)(imv_manager_t *this);
+};
+
+#endif /** IMV_MANAGER_H_ @}*/