refactored IMV policy management
authorAndreas Steffen <andreas.steffen@strongswan.org>
Thu, 16 May 2013 21:07:24 +0000 (23:07 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 21 Jun 2013 21:25:22 +0000 (23:25 +0200)
23 files changed:
src/libimcv/Makefile.am
src/libimcv/imc/imc_agent.c
src/libimcv/imcv.c
src/libimcv/imcv.h
src/libimcv/imv/imv_agent.c
src/libimcv/imv/imv_agent.h
src/libimcv/imv/imv_database.c
src/libimcv/imv/imv_database.h
src/libimcv/imv/imv_session.c [new file with mode: 0644]
src/libimcv/imv/imv_session.h [new file with mode: 0644]
src/libimcv/imv/imv_state.h
src/libimcv/imv/imv_workitem.c
src/libimcv/imv/imv_workitem.h
src/libimcv/plugins/imv_os/imv_os.c
src/libimcv/plugins/imv_os/imv_os_state.c
src/libimcv/plugins/imv_scanner/imv_scanner_state.c
src/libimcv/plugins/imv_test/imv_test_state.c
src/libpts/plugins/imv_attestation/attest.c
src/libpts/plugins/imv_attestation/imv_attestation.c
src/libpts/plugins/imv_attestation/imv_attestation_state.c
src/libtncif/Makefile.am
src/libtncif/tncif_policy.c [new file with mode: 0644]
src/libtncif/tncif_policy.h [new file with mode: 0644]

index e1c68f3..13531fe 100644 (file)
@@ -15,6 +15,7 @@ libimcv_la_SOURCES = \
        imv/imv_lang_string.h imv/imv_lang_string.c \
        imv/imv_reason_string.h imv/imv_reason_string.c \
        imv/imv_remediation_string.h imv/imv_remediation_string.c \
+       imv/imv_session.h imv/imv_session.c \
        imv/imv_workitem.h imv/imv_workitem.c \
        imv/tables.sql imv/data.sql \
        ietf/ietf_attr.h ietf/ietf_attr.c \
index f309abe..7dc3abd 100644 (file)
@@ -533,7 +533,7 @@ imc_agent_t *imc_agent_create(const char *name,
        private_imc_agent_t *this;
 
        /* initialize  or increase the reference count */
-       if (!libimcv_init())
+       if (!libimcv_init(FALSE))
        {
                return NULL;
        }
index f9ecf79..cb0222e 100644 (file)
 
 #include <syslog.h>
 
-#define IMCV_DEBUG_LEVEL       1
+#define IMCV_DEBUG_LEVEL                       1
+#define IMCV_DEFAULT_DATABASE_URI      "sqlite:///etc/pts/config.db"
+#define IMCV_DEFAULT_POLICY_SCRIPT     "ipsec _imv_policy"
+
 
 /**
  * PA-TNC attribute manager
 pa_tnc_attr_manager_t *imcv_pa_tnc_attributes;
 
 /**
+ * Global IMV database
+ */
+imv_database_t *imcv_db;
+
+/**
  * Reference count for libimcv
  */
 static refcount_t libimcv_ref = 0;
@@ -88,7 +96,7 @@ static void imcv_dbg(debug_t group, level_t level, char *fmt, ...)
 /**
  * Described in header.
  */
-bool libimcv_init(void)
+bool libimcv_init(bool is_imv)
 {
        /* initialize libstrongswan library only once */
        if (lib)
@@ -129,12 +137,27 @@ bool libimcv_init(void)
 
        if (libimcv_ref == 0)
        {
+               char *uri, *script;
+
                /* initialize the PA-TNC attribute manager */
                imcv_pa_tnc_attributes = pa_tnc_attr_manager_create();
                imcv_pa_tnc_attributes->add_vendor(imcv_pa_tnc_attributes, PEN_IETF,
                                                        ietf_attr_create_from_data, ietf_attr_names);
                imcv_pa_tnc_attributes->add_vendor(imcv_pa_tnc_attributes, PEN_ITA,
                                                        ita_attr_create_from_data, ita_attr_names);
+
+               /* attach global IMV database */
+               if (is_imv)
+               {
+                       uri = lib->settings->get_str(lib->settings,
+                                               "libimcv.database", IMCV_DEFAULT_DATABASE_URI);
+                       script = lib->settings->get_str(lib->settings,
+                                               "libimcv.policy_script", IMCV_DEFAULT_POLICY_SCRIPT);
+                       if (uri)
+                       {
+                               imcv_db = imv_database_create(uri, script);
+                       }
+               }
                DBG1(DBG_LIB, "libimcv initialized");
        }
        ref_get(&libimcv_ref);
@@ -152,6 +175,7 @@ void libimcv_deinit(void)
                imcv_pa_tnc_attributes->remove_vendor(imcv_pa_tnc_attributes, PEN_IETF);
                imcv_pa_tnc_attributes->remove_vendor(imcv_pa_tnc_attributes, PEN_ITA);
                DESTROY_IF(imcv_pa_tnc_attributes);
+               DESTROY_IF(imcv_db);
                DBG1(DBG_LIB, "libimcv terminated");
        }
        if (ref_put(&libstrongswan_ref))
index 3a37e3d..10c66e6 100644 (file)
 #define IMCV_H_
 
 #include "pa_tnc/pa_tnc_attr_manager.h"
+#include "imv/imv_database.h"
 
 #include <library.h>
 
 /**
  * Initialize libimcv.
  *
+ * @param is_imv               TRUE if called by IMV, FALSE if by IMC
  * @return                             FALSE if initialization failed
  */
-bool libimcv_init(void);
+bool libimcv_init(bool is_imv);
 
 /**
  * Deinitialize libimcv.
@@ -55,4 +57,9 @@ void libimcv_deinit(void);
  */
 extern pa_tnc_attr_manager_t* imcv_pa_tnc_attributes;
 
+/**
+ * Global IMV database object
+ */
+extern imv_database_t* imcv_db;
+
 #endif /** IMCV_H_ @}*/
index fdc76ab..ae20f2b 100644 (file)
@@ -15,6 +15,8 @@
 
 #include "imcv.h"
 #include "imv_agent.h"
+#include "imv_session.h"
+
 #include "ietf/ietf_attr_assess_result.h"
 
 #include <tncif_names.h>
@@ -63,11 +65,6 @@ struct private_imv_agent_t {
        linked_list_t *additional_ids;
 
        /**
-        * IMV database
-        */
-       imv_database_t *db;
-
-       /**
         * list of TNCS connection entries
         */
        linked_list_t *connections;
@@ -411,7 +408,7 @@ METHOD(imv_agent_t, create_state, TNC_Result,
        linked_list_t *ar_identities;
        enumerator_t *enumerator;
        tncif_identity_t *tnc_id;
-       int session_id;
+       imv_session_t *session;
        u_int32_t max_msg_len;
        u_int32_t ar_id_type = TNC_ID_UNKNOWN;
        chunk_t ar_id_value = chunk_empty;
@@ -481,14 +478,14 @@ METHOD(imv_agent_t, create_state, TNC_Result,
        }
        enumerator->destroy(enumerator);
 
-       if (this->db)
+       if (imcv_db)
        {
-               session_id = this->db->get_session_id(this->db, conn_id,
-                                                                                         ar_id_type, ar_id_value);
-               if (session_id)
+               session = imcv_db->get_session(imcv_db, conn_id, ar_id_type, ar_id_value);
+               if (session)
                {
-                       DBG2(DBG_IMV, "  assigned session ID %d", session_id);
-                       state->set_session_id(state, session_id);
+                       DBG2(DBG_IMV, "  assigned session ID %d",
+                                session->get_session_id(session));
+                       state->set_session(state, session);
                }
                else
                {
@@ -582,12 +579,6 @@ METHOD(imv_agent_t, get_state, bool,
        return TRUE;
 }
 
-METHOD(imv_agent_t, get_database, imv_database_t*,
-       private_imv_agent_t *this)
-{
-       return  this->db;
-}
-
 METHOD(imv_agent_t, get_name, const char*,
        private_imv_agent_t *this)
 {
@@ -789,7 +780,6 @@ METHOD(imv_agent_t, destroy, void,
        private_imv_agent_t *this)
 {
        DBG1(DBG_IMV, "IMV %u \"%s\" terminated", this->id, this->name);
-       DESTROY_IF(this->db);
        this->additional_ids->destroy(this->additional_ids);
        this->connections->destroy_offset(this->connections,
                                                                          offsetof(imv_state_t, destroy));
@@ -808,10 +798,9 @@ imv_agent_t *imv_agent_create(const char *name,
                                                          TNC_IMVID id, TNC_Version *actual_version)
 {
        private_imv_agent_t *this;
-       char *uri;
 
        /* initialize  or increase the reference count */
-       if (!libimcv_init())
+       if (!libimcv_init(TRUE))
        {
                return NULL;
        }
@@ -823,7 +812,6 @@ imv_agent_t *imv_agent_create(const char *name,
                        .delete_state = _delete_state,
                        .change_state = _change_state,
                        .get_state = _get_state,
-                       .get_database = _get_database,
                        .get_name = _get_name,
                        .get_id = _get_id,
                        .reserve_additional_ids = _reserve_additional_ids,
@@ -842,13 +830,6 @@ imv_agent_t *imv_agent_create(const char *name,
                .connection_lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
        );
 
-       /* attach IMV database */
-       uri = lib->settings->get_str(lib->settings, "libimcv.database", NULL);
-       if (uri)
-       {
-               this->db = imv_database_create(uri);
-       }
-
        *actual_version = TNC_IFIMV_VERSION_1;
        DBG1(DBG_IMV, "IMV %u \"%s\" initialized", this->id, this->name);
 
index 5c78418..d58af26 100644 (file)
@@ -139,13 +139,6 @@ struct imv_agent_t {
                                          TNC_ConnectionID connection_id, imv_state_t **state);
 
        /**
-        * Get IMV database
-        *
-        * @return                                      IMV database if it exists, NULL otherwise
-        */
-       imv_database_t* (*get_database)(imv_agent_t *this);
-
-       /**
         * Get IMV name
         *
         * return                                       IMV name
index bf11d78..4c35d75 100644 (file)
 #include <time.h>
 
 #include "imv_database.h"
-#include "imv_workitem.h"
 
 #include <utils/debug.h>
+#include <threading/mutex.h>
 
 typedef struct private_imv_database_t private_imv_database_t;
 
-#define SESSION_TIME_DELTA_MAX         2  /* seconds */
-
-#define DEFAULT_POLICY_SCRIPT          "ipsec _imv_policy"
-
 /**
  * Private data of a imv_database_t object.
- *
  */
 struct private_imv_database_t {
 
@@ -52,34 +47,46 @@ struct private_imv_database_t {
         */
        char *script;
 
+       /**
+        * Session list
+        */
+       linked_list_t *sessions;
+
+       /**
+        * mutex used to lock session list
+        */
+       mutex_t *mutex;
+
 };
 
-METHOD(imv_database_t, get_session_id, int,
-       private_imv_database_t *this, TNC_ConnectionID id, u_int32_t ar_id_type,
-       chunk_t ar_id_value)
+METHOD(imv_database_t, get_session, imv_session_t*,
+       private_imv_database_t *this, TNC_ConnectionID conn_id,
+       u_int32_t ar_id_type, chunk_t ar_id_value)
 {
-       enumerator_t *e;
-       int ar_id = 0, session_id = 0;
+       enumerator_t *enumerator, *e;
+       imv_session_t *current, *session = NULL;
+       int ar_id = 0, session_id;
        u_int created;
-       time_t now;
 
-       /* get most recent session for a given connection ID if available */
-       e = this->db->query(this->db,
-                       "SELECT id, time FROM sessions WHERE connection = ? "
-                       "ORDER BY time DESC", DB_INT, id, DB_INT, DB_UINT);
-       if (e)
+       this->mutex->lock(this->mutex);
+
+       /* check if a session has already been assigned */
+       enumerator = this->sessions->create_enumerator(this->sessions);
+       while (enumerator->enumerate(enumerator, &current))
        {
-               e->enumerate(e, &session_id, &created);
-               e->destroy(e);
+               if (conn_id == current->get_connection_id(current))
+               {
+                       session = current;
+                       break;
+               }
        }
+       enumerator->destroy(enumerator);
 
-       /* get current time */
-       now = time(NULL);
-
-       /* check if a new session has already been created by another IMV */
-       if (session_id && (now - created) <= SESSION_TIME_DELTA_MAX)
+       /* session already exists */
+       if (session)
        {
-               return session_id;
+               this->mutex->unlock(this->mutex);
+               return session->get_ref(session);
        }
 
        if (ar_id_value.len)
@@ -102,17 +109,22 @@ METHOD(imv_database_t, get_session_id, int,
                                 DB_INT, ar_id_type, DB_BLOB, ar_id_value);
                }
        }
-
-       /* create a new session ID */
+       /* create a new session entry */
+       created = time(NULL);
        this->db->execute(this->db, &session_id,
-                       "INSERT INTO sessions (time, connection, identity) "
-                       "VALUES (?, ?, ?)", DB_UINT, now, DB_INT, id, DB_INT, ar_id);
+                               "INSERT INTO sessions (time, connection, identity) "
+                               "VALUES (?, ?, ?)",
+                               DB_UINT, created, DB_INT, conn_id, DB_INT, ar_id);
+       session = imv_session_create(session_id, conn_id);
+       this->sessions->insert_last(this->sessions, session);
+
+       this->mutex->unlock(this->mutex);
 
-       return session_id;
+       return session;
 }
 
 METHOD(imv_database_t, add_product, int,
-       private_imv_database_t *this, int session_id, char *product)
+       private_imv_database_t *this, imv_session_t *session, char *product)
 {
        enumerator_t *e;
        int pid = 0;
@@ -138,14 +150,14 @@ METHOD(imv_database_t, add_product, int,
        {
                this->db->execute(this->db, NULL,
                        "UPDATE sessions SET product = ? WHERE id = ?",
-                        DB_INT, pid, DB_INT, session_id);
+                        DB_INT, pid, DB_INT, session->get_session_id(session));
        }
 
        return pid;
 }
 
 METHOD(imv_database_t, add_device, int,
-       private_imv_database_t *this, int session_id, chunk_t device)
+       private_imv_database_t *this, imv_session_t *session, chunk_t device)
 {
        enumerator_t *e;
        int did = 0;
@@ -171,18 +183,25 @@ METHOD(imv_database_t, add_device, int,
        {
                this->db->execute(this->db, NULL,
                        "UPDATE sessions SET device = ? WHERE id = ?",
-                        DB_INT, did, DB_INT, session_id);
+                        DB_INT, did, DB_INT, session->get_session_id(session));
        }
 
        return did;
 }
 
 METHOD(imv_database_t, policy_script, bool,
-       private_imv_database_t *this, int session_id, bool start)
+       private_imv_database_t *this, imv_session_t *session, bool start)
 {
-       char command[512], resp[128], *last;
+       imv_workitem_t *workitem;
+       imv_workitem_type_t type;
+       imv_session_t *current;
+       int id, session_id, rec_fail, rec_noresult;
+       enumerator_t *enumerator, *e;
+       char command[512], resp[128], *last, *argument;
        FILE *shell;
 
+       session_id = session->get_session_id(session);
+
        snprintf(command, sizeof(command), "2>&1 TNC_SESSION_ID='%d' %s %s",
                         session_id, this->script, start ? "start" : "stop");
        DBG3(DBG_IMV, "running policy script: %s", command);
@@ -217,75 +236,62 @@ METHOD(imv_database_t, policy_script, bool,
        }
        pclose(shell);
 
-       return TRUE;
-}
-
-typedef struct {
-       /** implements enumerator_t */
-       enumerator_t public;
-       /** session ID */
-       int session_id;
-       /** database enumerator */
-       enumerator_t *e;
-} workitem_enumerator_t;
-
-/**
- * Implementation of enumerator.enumerate
- */
-static bool workitem_enumerator_enumerate(workitem_enumerator_t *this, ...)
-{
-       imv_workitem_t **workitem;
-       imv_workitem_type_t type;
-       int rec_fail, rec_noresult;
-       char *argument;
-       va_list args;
-
-       va_start(args, this);
-       workitem = va_arg(args, imv_workitem_t**);
-       va_end(args);
+       if (start && !session->get_policy_started(session))
+       {
+               /* get workitem list generated by policy manager */
+               e = this->db->query(this->db,
+                               "SELECT id, type, argument, rec_fail, rec_noresult "
+                               "FROM workitems WHERE session = ?",
+                               DB_INT, session_id,     DB_INT, DB_INT, DB_TEXT, DB_INT, DB_INT);
+               if (!e)
+               {
+                       DBG1(DBG_IMV, "no workitem enumerator returned");
+                       return FALSE;
+               }
+               while (e->enumerate(e, &id, &type, &argument, &rec_fail, &rec_noresult))
+               {
+                       workitem = imv_workitem_create(id, type, argument, rec_fail,
+                                                                                  rec_noresult);
+                       session->insert_workitem(session, workitem);
+               }
+               e->destroy(e);
 
-       if (this->e->enumerate(this->e, &type, &argument, &rec_fail, &rec_noresult))
+               session->set_policy_started(session, TRUE);
+       }
+       else if (!start && session->get_policy_started(session))
        {
-               *workitem = imv_workitem_create(this->session_id, type, argument,
-                                                                               rec_fail, rec_noresult);
-               return TRUE;
+               /* remove session */
+               this->mutex->lock(this->mutex);
+               enumerator = this->sessions->create_enumerator(this->sessions);
+               while (enumerator->enumerate(enumerator, &current))
+               {
+                       if (current == session)
+                       {
+                               this->sessions->remove_at(this->sessions, enumerator);
+                               break;
+                       }
+               }
+               enumerator->destroy(enumerator);
+               this->mutex->unlock(this->mutex);
+
+               session->set_policy_started(session, FALSE);
        }
-       return FALSE;
-}
 
-/**
- * Implementation of enumerator.destroy
- */
-static void workitem_enumerator_destroy(workitem_enumerator_t *this)
-{
-       this->e->destroy(this->e);
-       free(this);
+       return TRUE;
 }
 
-METHOD(imv_database_t, create_workitem_enumerator, enumerator_t*,
-       private_imv_database_t *this, int session_id)
+METHOD(imv_database_t, finalize_workitem, bool,
+       private_imv_database_t *this, imv_workitem_t *workitem)
 {
-       workitem_enumerator_t *enumerator;
-       enumerator_t *e;
+       char *result;
+       int rec;
 
-       e = this->db->query(this->db,
-                               "SELECT type, argument, rec_fail, rec_noresult "
-                               "FROM workitems WHERE session = ?",
-                               DB_INT, session_id, DB_INT, DB_TEXT, DB_INT, DB_INT);
-       if (!e)
-       {
-               return NULL;
-       }
-
-       INIT(enumerator,
-               .public = {
-                       .enumerate = (void*)workitem_enumerator_enumerate,
-                       .destroy = (void*)workitem_enumerator_destroy,
-               },
-               .e = e,
-       );
+       rec = workitem->get_result(workitem, &result);
 
-       return (enumerator_t*)enumerator;
+       return this->db->execute(this->db, NULL,
+                               "UPDATE workitems SET result = ?, rec_final = ? WHERE id = ?",
+                               DB_TEXT, result, DB_INT, rec,
+                               DB_INT, workitem->get_id(workitem)) == 1;
 }
 
 METHOD(imv_database_t, get_database, database_t*,
@@ -298,36 +304,40 @@ METHOD(imv_database_t, destroy, void,
        private_imv_database_t *this)
 {
        this->db->destroy(this->db);
+       this->sessions->destroy_offset(this->sessions,
+                                                       offsetof(imv_session_t, destroy));
+       this->mutex->destroy(this->mutex);
        free(this);
 }
 
 /**
  * See header
  */
-imv_database_t *imv_database_create(char *uri)
+imv_database_t *imv_database_create(char *uri, char *script)
 {
        private_imv_database_t *this;
 
        INIT(this,
                .public = {
-                       .get_session_id = _get_session_id,
+                       .get_session = _get_session,
                        .add_product = _add_product,
                        .add_device = _add_device,
                        .policy_script = _policy_script,
-                       .create_workitem_enumerator = _create_workitem_enumerator,
+                       .finalize_workitem = _finalize_workitem,
                        .get_database = _get_database,
                        .destroy = _destroy,
                },
                .db = lib->db->create(lib->db, uri),
-               .script = lib->settings->get_str(lib->settings,
-                                       "libimcv.policy_script", DEFAULT_POLICY_SCRIPT),
+               .script = script,
+               .sessions = linked_list_create(),
+               .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
        );
 
        if (!this->db)
        {
                DBG1(DBG_IMV,
                         "failed to connect to IMV database '%s'", uri);
-               free(this);
+               destroy(this);
                return NULL;
        }
 
index abe49dc..3c4bf83 100644 (file)
 #ifndef IMV_DATABASE_H_
 #define IMV_DATABASE_H_
 
-#include <tncif.h>
+#include "imv_session.h"
+#include "imv_workitem.h"
+
+#include <tncifimv.h>
 
 #include <library.h>
 
@@ -34,51 +37,53 @@ typedef struct imv_database_t imv_database_t;
 struct imv_database_t {
 
        /**
-        * Register or get a unique session ID using the TNCCS connection ID
+        * Create or get a session associated with a TNCCS connection
         *
-        * @param id                    TNCCS Connection ID
+        * @param conn_id               TNCCS Connection ID
         * @param ar_id_type    Access Requestor identity type
         * @param ar_id_value   Access Requestor identity value
-        * @return                              Session ID or 0 if not available
+        * @return                              Session associated with TNCCS Connection
         */
-        int (*get_session_id)(imv_database_t *this, TNC_ConnectionID id,
-                                                  u_int32_t ar_id_type, chunk_t ar_id_value);
+        imv_session_t* (*get_session)(imv_database_t *this,
+                                                                  TNC_ConnectionID conn_id,
+                                                                  u_int32_t ar_id_type, chunk_t ar_id_value);
 
        /**
-        * Add product information string to a session
+        * Add product information string to a session database entry
         *
-        * @param session_id    Session ID
+        * @param session               Session
         * @param product               Product information string
-        * @return                              Product ID or 0 if not available
+        * @return                              Product ID
         */
-        int (*add_product)(imv_database_t *this, int session_id, char *product);
+        int (*add_product)(imv_database_t *this, imv_session_t *session,
+                                               char *product);
 
        /**
-        * Add device identification to a session
+        * Add device identification to a session database entry
         *
-        * @param session_id    Session ID
+        * @param session               Session
         * @param device                Device identification
-        * @return                              Device ID or 0 if not available
+        * @return                              Device ID
         */
-        int (*add_device)(imv_database_t *this, int session_id, chunk_t device);
+        int (*add_device)(imv_database_t *this, imv_session_t *session,
+                                          chunk_t device);
 
        /**
         * Announce session start/stop to policy script
         *
-        * @param session_id    Session ID
+        * @param session               Session
         * @param start                 TRUE if session start, FALSE if session stop
         * @return                              TRUE if command successful, FALSE otherwise
         */
-        bool (*policy_script)(imv_database_t *this, int session_id, bool start);
+        bool (*policy_script)(imv_database_t *this, imv_session_t *session,
+                                                  bool start);
 
        /**
-        * Create enumerator for workitems assigned to a session ID
+        * Finalize a workitem
         *
-        * @param session_id    Session ID
-        * @return                              Enumerator of workitems assigned to session ID
+        * @param workitem              Workitem to be finalized
         */
-        enumerator_t* (*create_workitem_enumerator)(imv_database_t *this,
-                                       int session_id);
+       bool (*finalize_workitem)(imv_database_t *this, imv_workitem_t *workitem);
 
        /**
         * Get database handle
@@ -96,8 +101,9 @@ struct imv_database_t {
 /**
  * Create an imv_database_t instance
  *
- * @param uri                  database uri
+ * @param uri                          Database uri
+ * @param script                       Policy Manager script
  */
-imv_database_t* imv_database_create(char *uri);
+imv_database_t* imv_database_create(char *uri, char *script);
 
 #endif /** IMV_DATABASE_H_ @}*/
diff --git a/src/libimcv/imv/imv_session.c b/src/libimcv/imv/imv_session.c
new file mode 100644 (file)
index 0000000..754f1f7
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2013 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 "imv_session.h"
+
+#include <utils/debug.h>
+
+typedef struct private_imv_session_t private_imv_session_t;
+
+/**
+ * Private data of a imv_session_t object.
+ */
+struct private_imv_session_t {
+
+       /**
+        * Public imv_session_t interface.
+        */
+       imv_session_t public;
+
+       /**
+        * Unique Session ID
+        */
+       int session_id;
+
+       /**
+        * TNCCS connection ID
+        */
+       TNC_ConnectionID conn_id;
+
+       /**
+        * Have the workitems been generated?
+        */
+       bool policy_started;
+
+       /**
+        * List of worklist items
+        */
+       linked_list_t *workitems;
+
+       /**
+        * Reference count
+        */
+       refcount_t ref;
+
+};
+
+METHOD(imv_session_t, get_session_id, int,
+       private_imv_session_t *this)
+{
+       return this->session_id;
+}
+
+METHOD(imv_session_t, get_connection_id, TNC_ConnectionID,
+       private_imv_session_t *this)
+{
+       return this->conn_id;
+}
+
+METHOD(imv_session_t, set_policy_started, void,
+       private_imv_session_t *this, bool start)
+{
+       this->policy_started = start;
+}
+
+METHOD(imv_session_t, get_policy_started, bool,
+       private_imv_session_t *this)
+{
+       return this->policy_started;
+}
+
+METHOD(imv_session_t, insert_workitem, void,
+       private_imv_session_t *this, imv_workitem_t *workitem)
+{
+       this->workitems->insert_last(this->workitems, workitem);
+}
+
+METHOD(imv_session_t, remove_workitem, void,
+       private_imv_session_t *this, enumerator_t *enumerator)
+{
+       this->workitems->remove_at(this->workitems, enumerator);
+}
+
+METHOD(imv_session_t, create_workitem_enumerator, enumerator_t*,
+       private_imv_session_t *this)
+{
+       if (!this->policy_started)
+       {
+               return NULL;
+       }
+       return this->workitems->create_enumerator(this->workitems);
+}
+
+METHOD(imv_session_t, get_workitem_count, int,
+       private_imv_session_t *this, TNC_IMVID imv_id)
+{
+       enumerator_t *enumerator;
+       imv_workitem_t *workitem;
+       int count = 0;
+
+       enumerator = this->workitems->create_enumerator(this->workitems);
+       while (enumerator->enumerate(enumerator, &workitem))
+       {
+               if (workitem->get_imv_id(workitem) == imv_id)
+               {
+                       count++;
+               }
+       }
+       enumerator->destroy(enumerator);
+
+       return count;
+}
+
+METHOD(imv_session_t, get_ref, imv_session_t*,
+       private_imv_session_t *this)
+{
+       ref_get(&this->ref);
+
+       return &this->public;
+}
+
+METHOD(imv_session_t, destroy, void,
+       private_imv_session_t *this)
+{
+       if (ref_put(&this->ref))
+       {
+               this->workitems->destroy_offset(this->workitems,
+                                                                offsetof(imv_workitem_t, destroy));
+               free(this);
+       }
+}
+
+/**
+ * See header
+ */
+imv_session_t *imv_session_create(int session_id, TNC_ConnectionID conn_id)
+{
+       private_imv_session_t *this;
+
+       INIT(this,
+               .public = {
+                       .get_session_id = _get_session_id,
+                       .get_connection_id = _get_connection_id,
+                       .set_policy_started = _set_policy_started,
+                       .get_policy_started = _get_policy_started,
+                       .insert_workitem = _insert_workitem,
+                       .remove_workitem = _remove_workitem,
+                       .create_workitem_enumerator = _create_workitem_enumerator,
+                       .get_workitem_count = _get_workitem_count,
+                       .get_ref = _get_ref,
+                       .destroy = _destroy,
+               },
+               .session_id = session_id,
+               .conn_id = conn_id,
+               .workitems = linked_list_create(),
+               .ref = 1,
+       );
+
+       return &this->public;
+}
diff --git a/src/libimcv/imv/imv_session.h b/src/libimcv/imv/imv_session.h
new file mode 100644 (file)
index 0000000..d38b2ac
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2013 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_session_t imv_session
+ * @{ @ingroup libimcv_imv
+ */
+
+#ifndef  IMV_SESSION_H_
+#define  IMV_SESSION_H_
+
+#include "imv_workitem.h"
+
+#include <tncifimv.h>
+
+#include <library.h>
+
+typedef struct imv_session_t imv_session_t;
+
+/**
+ * IMV session interface 
+ */
+struct imv_session_t {
+
+       /**
+        * Get unique session ID
+        *
+        * @return                              Session ID
+        */
+       int (*get_session_id)(imv_session_t *this);
+
+       /**
+        * Get TNCCS Connection ID
+        *
+        * @return                              TNCCS Connection ID
+        */
+       TNC_ConnectionID (*get_connection_id)(imv_session_t *this);
+
+       /**
+        * Set policy_started status
+        *
+        * @param start                 TRUE if policy started, FALSE if policy stopped
+        */
+       void (*set_policy_started)(imv_session_t *this, bool start);
+
+       /**
+        * Get policy_started status
+        *
+        * @return                              TRUE if policy started, FALSE if policy stopped
+        */
+       bool (*get_policy_started)(imv_session_t *this);
+
+       /**
+        * Insert workitem into list
+        *
+        * @param workitem              Workitem to be inserted
+        */
+       void (*insert_workitem)(imv_session_t *this, imv_workitem_t *workitem);
+
+       /**
+        * Remove workitem from list
+        *
+        * @param enumerator    Enumerator pointing to workitem to be removed
+        */
+       void (*remove_workitem)(imv_session_t *this, enumerator_t *enumerator);
+
+       /**
+        * Create workitem enumerator
+        *
+        */
+        enumerator_t* (*create_workitem_enumerator)(imv_session_t *this);
+
+       /**
+        * Get number of workitem allocated to a given IMV
+        *
+        * @param imv_id                IMV ID
+        * @return                              Number of workitems assigned to given IMV
+        */
+        int (*get_workitem_count)(imv_session_t *this, TNC_IMVID imv_id);
+
+       /**
+        * Get reference to session
+        */
+       imv_session_t* (*get_ref)(imv_session_t*);
+
+       /**
+        * Destroys an imv_session_t object
+        */
+       void (*destroy)(imv_session_t *this);
+};
+
+/**
+ * Create an imv_session_t instance
+ *
+ * @param session_id           Unique Session ID
+ * @param conn_id                      Associated Connection ID
+ */
+imv_session_t* imv_session_create(int session_id, TNC_ConnectionID id);
+
+#endif /**  IMV_SESSION_H_ @}*/
index 4bc890e..53df671 100644 (file)
@@ -22,7 +22,7 @@
 #ifndef IMV_STATE_H_
 #define IMV_STATE_H_
 
-#include "imv_workitem.h"
+#include "imv_session.h"
 
 #include <tncifimv.h>
 
@@ -36,9 +36,9 @@ typedef struct imv_state_t imv_state_t;
 struct imv_state_t {
 
        /**
-        * Get the TNCS connection ID attached to the state
+        * Get the TNCCS connection ID attached to the state
         *
-        * @return                              TNCS connection ID of the state
+        * @return                              TNCCS connection ID of the state
         */
         TNC_ConnectionID (*get_connection_id)(imv_state_t *this);
 
@@ -97,51 +97,18 @@ struct imv_state_t {
        chunk_t (*get_ar_id)(imv_state_t *this, u_int32_t *id_type);
 
        /**
-        * Set unique session ID
+        * Set session associated with TNCCS Connection
         *
-        * @param session_id    Unique session ID
+        * @param session               Session associated with TNCCS Connection
         */
-       void (*set_session_id)(imv_state_t *this, int session_id);
+       void (*set_session)(imv_state_t *this, imv_session_t *session);
 
        /**
-        * Get unique session_id
+        * Get session associated with TNCCS Connection
         *
-        * @return                              Unique session ID
+        * @return                              Session associated with TNCCS Connection
         */
-       int (*get_session_id)(imv_state_t *this);
-
-       /**
-        * Add workitem to list
-        *
-        * @param workitem              Workitem to be added
-        */
-       void (*add_workitem)(imv_state_t *this, imv_workitem_t *workitem);
-
-       /**
-        * Return number of pending workitems
-        *
-        * @return                              Number of pending workitems
-        */
-       int (*get_workitem_count)(imv_state_t *this);
-
-       /**
-        * Create an enumerator over the pending workitems
-        *
-        * @return                              Workitem enumerator
-        */
-       enumerator_t* (*create_workitem_enumerator)(imv_state_t *this);
-
-       /**
-        * Finalize a workitem
-        *
-        * @param enumerator    Current enumerator position pointing to workitem
-        * @param workitem              Workitem to be finalized
-        * @param result                Result description as a text
-        * @param eval                  Evaluation Result
-        */
-       void (*finalize_workitem)(imv_state_t *this, enumerator_t *enumerator,
-                                                         imv_workitem_t *workitem,  char *result,
-                                                         TNC_IMV_Evaluation_Result eval);
+       imv_session_t* (*get_session)(imv_state_t *this);
 
        /**
         * Change the connection state
@@ -173,6 +140,17 @@ struct imv_state_t {
                                                           TNC_IMV_Evaluation_Result eval);
 
        /**
+        * Update IMV action recommendation and evaluation result
+        *
+        * @param rec                   IMV action recommendation
+        * @param eval                  IMV evaluation result
+        *
+        */
+       void (*update_recommendation)(imv_state_t *this,
+                                                                 TNC_IMV_Action_Recommendation rec,
+                                                                 TNC_IMV_Evaluation_Result eval);
+
+       /**
         * Get reason string based on the preferred language
         *
         * @param language_enumerator   language enumerator
index 62b62bb..e4403e7 100644 (file)
@@ -20,8 +20,7 @@
 
 typedef struct private_imv_workitem_t private_imv_workitem_t;
 
-ENUM(imv_workitem_type_names, IMV_WORKITEM_START, IMV_WORKITEM_UDP_SCAN,
-       "START",
+ENUM(imv_workitem_type_names, IMV_WORKITEM_PACKAGES, IMV_WORKITEM_UDP_SCAN,
        "PCKGS",
        "UNSRC",
        "FWDEN",
@@ -44,9 +43,14 @@ struct private_imv_workitem_t {
        imv_workitem_t public;
 
        /**
-        * Session ID
+        * Primary workitem key
         */
-       int session_id;
+       int id;
+
+       /**
+        * IMV ID
+        */
+       TNC_IMVID imv_id;
 
        /**
         * Workitem type
@@ -80,10 +84,22 @@ struct private_imv_workitem_t {
 
 };
 
-METHOD(imv_workitem_t, get_session_id, int,
+METHOD(imv_workitem_t, get_id, int,
        private_imv_workitem_t *this)
 {
-       return this->session_id;
+       return this->id;
+}
+
+METHOD(imv_workitem_t, set_imv_id, void,
+       private_imv_workitem_t *this, TNC_IMVID imv_id)
+{
+       this->imv_id = imv_id;
+}
+
+METHOD(imv_workitem_t, get_imv_id, TNC_IMVID,
+       private_imv_workitem_t *this)
+{
+       return this->imv_id;
 }
 
 METHOD(imv_workitem_t, get_type, imv_workitem_type_t,
@@ -124,6 +140,16 @@ METHOD(imv_workitem_t, set_result, TNC_IMV_Action_Recommendation,
        return this->rec_final; 
 }
 
+METHOD(imv_workitem_t, get_result, TNC_IMV_Action_Recommendation,
+       private_imv_workitem_t *this, char **result)
+{
+       if (result)
+       {
+               *result = this->result;
+       }
+       return this->rec_final;
+}
+
 METHOD(imv_workitem_t, destroy, void,
        private_imv_workitem_t *this)
 {
@@ -135,7 +161,7 @@ METHOD(imv_workitem_t, destroy, void,
 /**
  * See header
  */
-imv_workitem_t *imv_workitem_create(int session_id, imv_workitem_type_t type,
+imv_workitem_t *imv_workitem_create(int id, imv_workitem_type_t type,
                                                                        char *argument,
                                                                        TNC_IMV_Action_Recommendation rec_fail,
                                                                        TNC_IMV_Action_Recommendation rec_noresult)
@@ -144,13 +170,16 @@ imv_workitem_t *imv_workitem_create(int session_id, imv_workitem_type_t type,
 
        INIT(this,
                .public = {
-                       .get_session_id = _get_session_id,
+                       .get_id = _get_id,
+                       .set_imv_id = _set_imv_id,
+                       .get_imv_id = _get_imv_id,
                        .get_type = _get_type,
                        .get_argument = _get_argument,
                        .set_result = _set_result,
+                       .get_result = _get_result,
                        .destroy = _destroy,
                },
-               .session_id = session_id,
+               .id = id,
                .type = type,
                .argument = strdup(argument),
                .rec_fail = rec_fail,
index 2b43782..507e99e 100644 (file)
@@ -30,7 +30,6 @@ typedef struct imv_workitem_t imv_workitem_t;
 typedef enum imv_workitem_type_t imv_workitem_type_t;
 
 enum imv_workitem_type_t {
-       IMV_WORKITEM_START =          0,
        IMV_WORKITEM_PACKAGES =       1,
        IMV_WORKITEM_UNKNOWN_SOURCE = 2,
        IMV_WORKITEM_FORWARDING =     3,
@@ -49,11 +48,11 @@ extern enum_name_t *imv_workitem_type_names;
 struct imv_workitem_t {
 
        /**
-        * Get workitem type
+        * Get primary workitem key 
         *
-        * @return                              Session ID
+        * @return                              Primary workitem key
         */
-        int (*get_session_id)(imv_workitem_t *this);
+        int (*get_id)(imv_workitem_t *this);
 
        /**
         * Get workitem type
@@ -63,6 +62,20 @@ struct imv_workitem_t {
         imv_workitem_type_t (*get_type)(imv_workitem_t *this);
 
        /**
+        * Set IMV ID
+        *
+        * @param id                    IMV ID
+        */
+        void (*set_imv_id)(imv_workitem_t *this, TNC_IMVID imv_id);
+
+       /**
+        * Get IMV ID
+        *
+        * @return                              IMV ID
+        */
+        TNC_IMVID (*get_imv_id)(imv_workitem_t *this);
+
+       /**
         * Get argument string
         *
         * @return                              Argument string
@@ -74,11 +87,21 @@ struct imv_workitem_t {
         *
         * @param result                Result string
         * @param eval                  Evaluation Result
+        * @return                              Action Recommendation
         */
-        TNC_IMV_Action_Recommendation(*set_result)(imv_workitem_t *this, 
+        TNC_IMV_Action_Recommendation (*set_result)(imv_workitem_t *this, 
                                                char *result, TNC_IMV_Evaluation_Result eval);
 
        /**
+        * Set result string
+        *
+        * @param result                Result string
+        * @return                              Action Recommendatino
+        */
+        TNC_IMV_Action_Recommendation (*get_result)(imv_workitem_t *this, 
+                                                                                                char **result);
+
+       /**
         * Destroys an imv_workitem_t object
         */
        void (*destroy)(imv_workitem_t *this);
@@ -87,13 +110,13 @@ struct imv_workitem_t {
 /**
  * Create an imv_workitem_t instance
  *
- * @param session_id           Session ID to which workitem is assigned
+ * @param id                           Primary workitem key
  * @param type                         Workitem type
  * @param argument                     Argument string
  * @param rec_fail                     Recommendation with minor/major non-compliance case
  * @param rec_noresult         Recommendation in don't know/error case
  */
-imv_workitem_t *imv_workitem_create(int session_id, imv_workitem_type_t type,
+imv_workitem_t *imv_workitem_create(int id, imv_workitem_type_t type,
                                                                        char *argument,
                                                                        TNC_IMV_Action_Recommendation rec_fail,
                                                                        TNC_IMV_Action_Recommendation rec_noresult);
index 8994645..f25c547 100644 (file)
@@ -18,6 +18,7 @@
 #include "imv_os_state.h"
 #include "imv_os_database.h"
 
+#include <imcv.h>
 #include <imv/imv_agent.h>
 #include <imv/imv_msg.h>
 #include <ietf/ietf_attr.h>
@@ -106,7 +107,7 @@ TNC_Result TNC_IMV_Initialize(TNC_IMVID imv_id,
        }
 
        /* attach OS database co-located with IMV database */
-       os_db = imv_os_database_create(imv_os->get_database(imv_os));
+       os_db = imv_os_database_create(imcv_db);
 
        return TNC_RESULT_SUCCESS;
 }
@@ -119,8 +120,7 @@ TNC_Result TNC_IMV_NotifyConnectionChange(TNC_IMVID imv_id,
                                                                                  TNC_ConnectionState new_state)
 {
        imv_state_t *state;
-       imv_database_t *imv_db;
-       int session_id;
+       imv_session_t *session;
 
        if (!imv_os)
        {
@@ -133,11 +133,10 @@ TNC_Result TNC_IMV_NotifyConnectionChange(TNC_IMVID imv_id,
                        state = imv_os_state_create(connection_id);
                        return imv_os->create_state(imv_os, state);
                case TNC_CONNECTION_STATE_DELETE:
-                       imv_db = imv_os->get_database(imv_os);
-                       if (imv_db && imv_os->get_state(imv_os, connection_id, &state))
+                       if (imcv_db && imv_os->get_state(imv_os, connection_id, &state))
                        {
-                               session_id = state->get_session_id(state);
-                               imv_db->policy_script(imv_db, session_id, FALSE);
+                               session = state->get_session(state);
+                               imcv_db->policy_script(imcv_db, session, FALSE);
                        }
                        return imv_os->delete_state(imv_os, connection_id);
                default:
@@ -345,8 +344,8 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg)
                                }
                                case ITA_ATTR_DEVICE_ID:
                                {
-                                       imv_database_t *imv_db;
-                                       int session_id, device_id;
+                                       imv_session_t *session;
+                                       int device_id;
                                        chunk_t value;
 
                                        os_state->set_received(os_state, IMV_OS_ATTR_DEVICE_ID);
@@ -354,11 +353,10 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg)
                                        value = attr->get_value(attr);
                                        DBG1(DBG_IMV, "device ID is %.*s", value.len, value.ptr);
 
-                                       imv_db = imv_os->get_database(imv_os);
-                                       if (imv_db)
+                                       if (imcv_db)
                                        {
-                                               session_id = state->get_session_id(state);
-                                               device_id = imv_db->add_device(imv_db, session_id, value);
+                                               session = state->get_session(state);
+                                               device_id = imcv_db->add_device(imcv_db, session, value);
                                                os_state->set_device_id(os_state, device_id);
                                        }
                                        break;
@@ -383,16 +381,14 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg)
        if (os_name.len && os_version.len)
        {
                os_type_t os_type;
-               imv_database_t *imv_db;
 
                /* set the OS type, name and version */
                os_type = os_type_from_name(os_name);
                os_state->set_info(os_state,os_type, os_name, os_version);
 
-               imv_db = imv_os->get_database(imv_os);
-               if (imv_db)
+               if (imcv_db)
                {
-                       imv_db->add_product(imv_db, state->get_session_id(state),
+                       imcv_db->add_product(imcv_db, state->get_session(state),
                                        os_state->get_info(os_state, NULL, NULL, NULL));
                }
        }
@@ -553,29 +549,24 @@ static pa_tnc_attr_t* build_attr_request(u_int received)
 /**
  * see section 3.8.8 of TCG TNC IF-IMV Specification 1.3
  */
-TNC_Result TNC_IMV_BatchEnding(TNC_IMVID imv_id,
-                                                          TNC_ConnectionID connection_id)
+TNC_Result TNC_IMV_BatchEnding(TNC_IMVID imv_id, TNC_ConnectionID connection_id)
 {
        imv_msg_t *out_msg;
        imv_state_t *state;
-       imv_database_t *imv_db;
        imv_workitem_t *workitem;
        imv_os_state_t *os_state;
        imv_os_handshake_state_t handshake_state;
        pa_tnc_attr_t *attr;
        TNC_Result result = TNC_RESULT_SUCCESS;
        enumerator_t *enumerator;
+       imv_session_t *session;
        u_int received;
-       char *result_str;
-       bool fail;
 
        if (!imv_os)
        {
                DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name);
                return TNC_RESULT_NOT_INITIALIZED;
        }
-       imv_db = imv_os->get_database(imv_os);
-
        if (!imv_os->get_state(imv_os, connection_id, &state))
        {
                return TNC_RESULT_FATAL;
@@ -583,6 +574,7 @@ TNC_Result TNC_IMV_BatchEnding(TNC_IMVID imv_id,
        os_state = (imv_os_state_t*)state;
        handshake_state = os_state->get_handshake_state(os_state);
        received = os_state->get_received(os_state);
+       session = state->get_session(state);
 
        /* create an empty out message - we might need it */
        out_msg = imv_msg_create(imv_os, state, connection_id, imv_id,
@@ -604,10 +596,10 @@ TNC_Result TNC_IMV_BatchEnding(TNC_IMVID imv_id,
                        ((received & IMV_OS_ATTR_DEVICE_ID) ||
                         (handshake_state == IMV_OS_STATE_ATTR_REQ)))
                {
-                       if (imv_db)
+                       if (imcv_db)
                        {
                                /* trigger the policy manager */
-                               imv_db->policy_script(imv_db, state->get_session_id(state), TRUE);
+                               imcv_db->policy_script(imcv_db, session, TRUE);
                        }
                        handshake_state = IMV_OS_STATE_POLICY_START;
                }
@@ -638,138 +630,132 @@ TNC_Result TNC_IMV_BatchEnding(TNC_IMVID imv_id,
                os_state->set_handshake_state(os_state, handshake_state);
        }
 
-       if (handshake_state == IMV_OS_STATE_POLICY_START)
+       if (handshake_state == IMV_OS_STATE_POLICY_START && session)
        {
-               if (imv_db)
+               enumerator = session->create_workitem_enumerator(session);
+               if (enumerator)
                {
-                       enumerator = imv_db->create_workitem_enumerator(imv_db,
-                                                                       state->get_session_id(state));
-                       if (!enumerator)
-                       {
-                               return TNC_RESULT_SUCCESS;
-                       }
                        while (enumerator->enumerate(enumerator, &workitem))
                        {
+                               if (workitem->get_imv_id(workitem) != 0)
+                               {
+                                       continue;
+                               }
                                switch (workitem->get_type(workitem))
                                {
                                        case IMV_WORKITEM_PACKAGES:
                                                attr = ietf_attr_attr_request_create(PEN_IETF,
                                                                                IETF_ATTR_INSTALLED_PACKAGES);
                                                out_msg->add_attribute(out_msg, attr);
-                                               state->add_workitem(state, workitem);
                                                break;
                                        case IMV_WORKITEM_UNKNOWN_SOURCE:
                                                attr = ita_attr_get_settings_create(non_market_apps_str);
                                                out_msg->add_attribute(out_msg, attr);
-                                               state->add_workitem(state, workitem);
                                                break;
                                        case IMV_WORKITEM_FORWARDING:
                                        case IMV_WORKITEM_DEFAULT_PWD:
-                                               state->add_workitem(state, workitem);
                                                break;
-                                       case IMV_WORKITEM_START:
-                                               handshake_state = IMV_OS_STATE_WORKITEMS;
-                                               /* fall through to default */
                                        default:
-                                               workitem->destroy(workitem);
+                                               continue;
                                }
+                               workitem->set_imv_id(workitem, imv_id);
                        }
                        enumerator->destroy(enumerator);
-               }
-               else
-               {
-                       /* TODO: define workitems without DB access */
+
                        handshake_state = IMV_OS_STATE_WORKITEMS;
+                       os_state->set_handshake_state(os_state, handshake_state);
                }
-               os_state->set_handshake_state(os_state, handshake_state);
        }
 
-       if (handshake_state == IMV_OS_STATE_WORKITEMS)
+       if (handshake_state == IMV_OS_STATE_WORKITEMS && session)
        {
-               enumerator = state->create_workitem_enumerator(state);
+               TNC_IMV_Evaluation_Result eval;
+               TNC_IMV_Action_Recommendation rec;
+               char buf[BUF_LEN], *result_str;
+               bool fail;
+
+               enumerator = session->create_workitem_enumerator(session);
                while (enumerator->enumerate(enumerator, &workitem))
                {
+                       if (workitem->get_imv_id(workitem) != imv_id)
+                       {
+                               continue;
+                       }
+                       eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW;
+
                        switch (workitem->get_type(workitem))
                        {
                                case IMV_WORKITEM_PACKAGES:
                                {
-                                       int count, count_update, count_blacklist, count_ok, ret;
+                                       int count, count_update, count_blacklist, count_ok;
 
                                        if (!(received & IMV_OS_ATTR_INSTALLED_PACKAGES) ||
                                                os_state->get_angel_count(os_state))
                                        {
-                                               break;
+                                               continue;
                                        }
                                        os_state->get_count(os_state, &count, &count_update,
                                                                                &count_blacklist, &count_ok);
                                        fail = count_update || count_blacklist;
-                                       ret = asprintf(&result_str, "processed %d packages: "
+                                       eval = fail ? TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR :
+                                                                 TNC_IMV_EVALUATION_RESULT_COMPLIANT;
+                                       snprintf(buf, BUF_LEN, "processed %d packages: "
                                                        "%d not updated, %d blacklisted, %d ok, "
                                                        "%d not found",
                                                        count, count_update, count_blacklist, count_ok,
                                                        count - count_update - count_blacklist - count_ok);
-                                       if (ret == -1)
-                                       {
-                                               result_str = strdup("");
-                                       }
-
-                                       state->finalize_workitem(state, enumerator, workitem,
-                                                               result_str, fail ?
-                                                               TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR :
-                                                               TNC_IMV_EVALUATION_RESULT_COMPLIANT);
-                                       free(result_str);
+                                       result_str = buf;
                                        break;
                                }
                                case IMV_WORKITEM_UNKNOWN_SOURCE:
                                        if (!(received & IMV_OS_ATTR_SETTINGS))
                                        {
-                                               break;
+                                               continue;
                                        }
                                        fail = os_state->get_os_settings(os_state) &
                                                                OS_SETTINGS_UNKNOWN_SOURCE;
+                                       eval = fail ? TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR :
+                                                                 TNC_IMV_EVALUATION_RESULT_COMPLIANT;
                                        result_str = fail ? "unknown sources enabled" : "";
-
-                                       state->finalize_workitem(state, enumerator, workitem,
-                                                               result_str, fail ?
-                                                               TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR :
-                                                               TNC_IMV_EVALUATION_RESULT_COMPLIANT);
                                        break;                                  
                                case IMV_WORKITEM_FORWARDING:
                                        if (!(received & IMV_OS_ATTR_FORWARDING_ENABLED))
                                        {
-                                               break;
+                                               continue;
                                        }
                                        fail = os_state->get_os_settings(os_state) &
                                                                OS_SETTINGS_FWD_ENABLED;
+                                       eval = fail ? TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR :
+                                                                 TNC_IMV_EVALUATION_RESULT_COMPLIANT;
                                        result_str = fail ? "forwarding enabled" : "";
-
-                                       state->finalize_workitem(state, enumerator, workitem,
-                                                               result_str, fail ?
-                                                               TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR :
-                                                               TNC_IMV_EVALUATION_RESULT_COMPLIANT);
                                        break;
                                case IMV_WORKITEM_DEFAULT_PWD:
                                        if (!(received & IMV_OS_ATTR_FACTORY_DEFAULT_PWD_ENABLED))
                                        {
-                                               break;
+                                               continue;
                                        }
                                        fail = os_state->get_os_settings(os_state) &
                                                                OS_SETTINGS_DEFAULT_PWD_ENABLED;
+                                       eval = fail ? TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR :
+                                                                 TNC_IMV_EVALUATION_RESULT_COMPLIANT;
                                        result_str = fail ? "default password enabled" : "";
-
-                                       state->finalize_workitem(state, enumerator, workitem,
-                                                               result_str, fail ?
-                                                               TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR :
-                                                               TNC_IMV_EVALUATION_RESULT_COMPLIANT);
                                        break;
                                default:
-                                       break;
+                                       continue;
+                       }
+                       if (eval != TNC_IMV_EVALUATION_RESULT_DONT_KNOW)
+                       {
+                               session->remove_workitem(session, enumerator);
+                               rec = workitem->set_result(workitem, result_str, eval);
+                               state->update_recommendation(state, rec, eval);
+                               imcv_db->finalize_workitem(imcv_db, workitem);
+                               workitem->destroy(workitem);
                        }
                }
                enumerator->destroy(enumerator);
 
                /* finalized all workitems ? */
-               if (state->get_workitem_count(state) == 0)
+               if (session->get_workitem_count(session, imv_id) == 0)
                {
                        result = out_msg->send_assessment(out_msg);
                        out_msg->destroy(out_msg);
index a9ed3c8..3cfe6b3 100644 (file)
@@ -19,6 +19,8 @@
 #include "imv/imv_reason_string.h"
 #include "imv/imv_remediation_string.h"
 
+#include <tncif_policy.h>
+
 #include <utils/debug.h>
 #include <collections/linked_list.h>
 
@@ -73,14 +75,9 @@ struct private_imv_os_state_t {
        chunk_t ar_id_value;
 
        /**
-        * Unique session ID
-        */
-       int session_id;
-
-       /**
-        * List of workitems
+        * IMV database session associated with TNCCS connection
         */
-       linked_list_t *workitems;
+       imv_session_t *session;
 
        /**
         * IMV action recommendation
@@ -357,122 +354,40 @@ METHOD(imv_state_t, get_ar_id, chunk_t,
        return this->ar_id_value;
 }
 
-METHOD(imv_state_t, set_session_id, void,
-       private_imv_os_state_t *this, int session_id)
+METHOD(imv_state_t, set_session, void,
+       private_imv_os_state_t *this, imv_session_t *session)
 {
-       this->session_id = session_id;
+       this->session = session;
 }
 
-METHOD(imv_state_t, get_session_id, int,
+METHOD(imv_state_t, get_session, imv_session_t*,
        private_imv_os_state_t *this)
 {
-       return this->session_id;
+       return this->session;
 }
 
-METHOD(imv_state_t, add_workitem, void,
-       private_imv_os_state_t *this, imv_workitem_t *workitem)
-{
-       this->workitems->insert_last(this->workitems, workitem);
-}
-
-METHOD(imv_state_t, get_workitem_count, int,
-       private_imv_os_state_t *this)
+METHOD(imv_state_t, get_recommendation, void,
+       private_imv_os_state_t *this, TNC_IMV_Action_Recommendation *rec,
+                                                                 TNC_IMV_Evaluation_Result *eval)
 {
-       return this->workitems->get_count(this->workitems);
+       *rec = this->rec;
+       *eval = this->eval;
 }
 
-METHOD(imv_state_t, create_workitem_enumerator, enumerator_t*,
-       private_imv_os_state_t *this)
+METHOD(imv_state_t, set_recommendation, void,
+       private_imv_os_state_t *this, TNC_IMV_Action_Recommendation rec,
+                                                                 TNC_IMV_Evaluation_Result eval)
 {
-       return this->workitems->create_enumerator(this->workitems);
+       this->rec = rec;
+       this->eval = eval;
 }
 
-METHOD(imv_state_t, finalize_workitem, void,
-       private_imv_os_state_t *this, enumerator_t *enumerator,
-       imv_workitem_t *workitem, char *result, TNC_IMV_Evaluation_Result eval)
+METHOD(imv_state_t, update_recommendation, void,
+       private_imv_os_state_t *this, TNC_IMV_Action_Recommendation rec,
+                                                                 TNC_IMV_Evaluation_Result eval)
 {
-       TNC_IMV_Action_Recommendation rec;
-
-       this->workitems->remove_at(this->workitems, enumerator);
-       rec = workitem->set_result(workitem, result, eval);
-
-       /* Update overall evaluation result */
-       switch (this->eval)
-       {
-               case TNC_IMV_EVALUATION_RESULT_COMPLIANT:
-                       switch (eval)
-                       {
-                               case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR:
-                               case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR:
-                               case TNC_IMV_EVALUATION_RESULT_ERROR:
-                                       this->eval = eval;
-                                       break;
-                               default:
-                                       break;
-                       }
-                       break;
-               case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR:
-                       switch (eval)
-                       {
-                               case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR:
-                               case TNC_IMV_EVALUATION_RESULT_ERROR:
-                                       this->eval = eval;
-                                       break;
-                               default:
-                                       break;
-                       }
-                       break;
-               case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR:
-                       switch (eval)
-                       {
-                               case TNC_IMV_EVALUATION_RESULT_ERROR:
-                                       this->eval = eval;
-                                       break;
-                               default:
-                                       break;
-                       }
-                       break;
-               case TNC_IMV_EVALUATION_RESULT_DONT_KNOW:
-                       this->eval = eval;
-                       break;
-               default:
-                       break;
-       }
-
-       /* Update overall action recommendation */
-       switch (this->rec)
-       {
-               case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
-                       switch (rec)
-                       {
-                               case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
-                               case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
-                                       this->rec = rec;
-                                       break;
-                               default:
-                                       break;
-                       }
-                       break;
-               case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
-                       switch (rec)
-                       {
-                               case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
-                                       this->rec = rec;
-                                       break;
-                               default:
-                                       break;
-                       }
-                       break;
-               case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:
-                       this->rec = rec;
-                       break;
-               default:
-                       break;
-       }
-
-       /* TODO update workitem in IMV database */
-
-       workitem->destroy(workitem);
+       this->rec  = tncif_policy_update_recommendation(this->rec, rec);
+       this->eval = tncif_policy_update_evaluation(this->eval, eval);
 }
 
 METHOD(imv_state_t, change_state, void,
@@ -481,22 +396,6 @@ METHOD(imv_state_t, change_state, void,
        this->state = new_state;
 }
 
-METHOD(imv_state_t, get_recommendation, void,
-       private_imv_os_state_t *this, TNC_IMV_Action_Recommendation *rec,
-                                                                       TNC_IMV_Evaluation_Result *eval)
-{
-       *rec = this->rec;
-       *eval = this->eval;
-}
-
-METHOD(imv_state_t, set_recommendation, void,
-       private_imv_os_state_t *this, TNC_IMV_Action_Recommendation rec,
-                                                                       TNC_IMV_Evaluation_Result eval)
-{
-       this->rec = rec;
-       this->eval = eval;
-}
-
 METHOD(imv_state_t, get_reason_string, bool,
        private_imv_os_state_t *this, enumerator_t *language_enumerator,
        chunk_t *reason_string, char **reason_language)
@@ -591,10 +490,9 @@ METHOD(imv_state_t, get_remediation_instructions, bool,
 METHOD(imv_state_t, destroy, void,
        private_imv_os_state_t *this)
 {
+       DESTROY_IF(this->session);
        DESTROY_IF(this->reason_string);
        DESTROY_IF(this->remediation_string);
-       this->workitems->destroy_offset(this->workitems,
-                                                                       offsetof(imv_workitem_t, destroy));
        this->update_packages->destroy_function(this->update_packages, free);
        this->remove_packages->destroy_function(this->remove_packages, free);
        free(this->info);
@@ -764,15 +662,12 @@ imv_state_t *imv_os_state_create(TNC_ConnectionID connection_id)
                                .get_max_msg_len = _get_max_msg_len,
                                .set_ar_id = _set_ar_id,
                                .get_ar_id = _get_ar_id,
-                               .set_session_id = _set_session_id,
-                               .get_session_id = _get_session_id,
-                               .add_workitem = _add_workitem,
-                               .get_workitem_count = _get_workitem_count,
-                               .create_workitem_enumerator = _create_workitem_enumerator,
-                               .finalize_workitem = _finalize_workitem,
+                               .set_session = _set_session,
+                               .get_session = _get_session,
                                .change_state = _change_state,
                                .get_recommendation = _get_recommendation,
                                .set_recommendation = _set_recommendation,
+                               .update_recommendation = _update_recommendation,
                                .get_reason_string = _get_reason_string,
                                .get_remediation_instructions = _get_remediation_instructions,
                                .destroy = _destroy,
@@ -797,7 +692,6 @@ imv_state_t *imv_os_state_create(TNC_ConnectionID connection_id)
                .rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
                .eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW,
                .connection_id = connection_id,
-               .workitems = linked_list_create(),
                .update_packages = linked_list_create(),
                .remove_packages = linked_list_create(),
        );
index c26bc43..de0ed62 100644 (file)
@@ -18,6 +18,8 @@
 #include "imv/imv_reason_string.h"
 #include "imv/imv_remediation_string.h"
 
+#include <tncif_policy.h>
+
 #include <utils/lexparser.h>
 #include <utils/debug.h>
 
@@ -69,14 +71,9 @@ struct private_imv_scanner_state_t {
        chunk_t ar_id_value;
 
        /**
-        * Unique session ID
-        */
-       int session_id;
-
-       /**
-        * List of workitems
+        * IMV database session associatied with TNCCS connection
         */
-       linked_list_t *workitems;
+       imv_session_t *session;
 
        /**
         * IMV action recommendation
@@ -202,46 +199,16 @@ METHOD(imv_state_t, get_ar_id, chunk_t,
        return this->ar_id_value;
 }
 
-METHOD(imv_state_t, set_session_id, void,
-       private_imv_scanner_state_t *this, int session_id)
-{
-       this->session_id = session_id;
-}
-
-METHOD(imv_state_t, get_session_id, int,
-       private_imv_scanner_state_t *this)
-{
-       return this->session_id;
-}
-
-METHOD(imv_state_t, add_workitem, void,
-       private_imv_scanner_state_t *this, imv_workitem_t *workitem)
-{
-       this->workitems->insert_last(this->workitems, workitem);
-}
-
-METHOD(imv_state_t, get_workitem_count, int,
-       private_imv_scanner_state_t *this)
+METHOD(imv_state_t, set_session, void,
+       private_imv_scanner_state_t *this, imv_session_t *session)
 {
-       return this->workitems->get_count(this->workitems);
+       this->session = session;
 }
 
-METHOD(imv_state_t, create_workitem_enumerator, enumerator_t*,
+METHOD(imv_state_t, get_session, imv_session_t*,
        private_imv_scanner_state_t *this)
 {
-       return this->workitems->create_enumerator(this->workitems);
-}
-
-METHOD(imv_state_t, finalize_workitem, void,
-       private_imv_scanner_state_t *this, enumerator_t *enumerator,
-       imv_workitem_t *workitem, char *result, TNC_IMV_Evaluation_Result eval)
-{
-       TNC_IMV_Action_Recommendation rec;
-
-       this->workitems->remove_at(this->workitems, enumerator);
-       rec = workitem->set_result(workitem, result, eval);
-       /* TODO update workitem in IMV database */
-       workitem->destroy(workitem);
+       return this->session;
 }
 
 METHOD(imv_state_t, change_state, void,
@@ -252,7 +219,7 @@ METHOD(imv_state_t, change_state, void,
 
 METHOD(imv_state_t, get_recommendation, void,
        private_imv_scanner_state_t *this, TNC_IMV_Action_Recommendation *rec,
-                                                                       TNC_IMV_Evaluation_Result *eval)
+                                                                          TNC_IMV_Evaluation_Result *eval)
 {
        *rec = this->rec;
        *eval = this->eval;
@@ -260,12 +227,20 @@ METHOD(imv_state_t, get_recommendation, void,
 
 METHOD(imv_state_t, set_recommendation, void,
        private_imv_scanner_state_t *this, TNC_IMV_Action_Recommendation rec,
-                                                                       TNC_IMV_Evaluation_Result eval)
+                                                                          TNC_IMV_Evaluation_Result eval)
 {
        this->rec = rec;
        this->eval = eval;
 }
 
+METHOD(imv_state_t, update_recommendation, void,
+       private_imv_scanner_state_t *this, TNC_IMV_Action_Recommendation rec,
+                                                                          TNC_IMV_Evaluation_Result eval)
+{
+       this->rec  = tncif_policy_update_recommendation(this->rec, rec);
+       this->eval = tncif_policy_update_evaluation(this->eval, eval);
+}
+
 METHOD(imv_state_t, get_reason_string, bool,
        private_imv_scanner_state_t *this, enumerator_t *language_enumerator,
        chunk_t *reason_string, char **reason_language)
@@ -317,10 +292,9 @@ METHOD(imv_state_t, get_remediation_instructions, bool,
 METHOD(imv_state_t, destroy, void,
        private_imv_scanner_state_t *this)
 {
+       DESTROY_IF(this->session);
        DESTROY_IF(this->reason_string);
        DESTROY_IF(this->remediation_string);
-       this->workitems->destroy_offset(this->workitems,
-                                                                       offsetof(imv_workitem_t, destroy));
        this->violating_ports->destroy_function(this->violating_ports, free);
        free(this->ar_id_value.ptr);
        free(this);
@@ -350,15 +324,12 @@ imv_state_t *imv_scanner_state_create(TNC_ConnectionID connection_id)
                                .get_max_msg_len = _get_max_msg_len,
                                .set_ar_id = _set_ar_id,
                                .get_ar_id = _get_ar_id,
-                               .set_session_id = _set_session_id,
-                               .get_session_id = _get_session_id,
-                               .add_workitem = _add_workitem,
-                               .get_workitem_count = _get_workitem_count,
-                               .create_workitem_enumerator = _create_workitem_enumerator,
-                               .finalize_workitem = _finalize_workitem,
+                               .set_session = _set_session,
+                               .get_session= _get_session,
                                .change_state = _change_state,
                                .get_recommendation = _get_recommendation,
                                .set_recommendation = _set_recommendation,
+                               .update_recommendation = _update_recommendation,
                                .get_reason_string = _get_reason_string,
                                .get_remediation_instructions = _get_remediation_instructions,
                                .destroy = _destroy,
@@ -369,7 +340,6 @@ imv_state_t *imv_scanner_state_create(TNC_ConnectionID connection_id)
                .rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
                .eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW,
                .connection_id = connection_id,
-               .workitems = linked_list_create(),
                .violating_ports = linked_list_create(),
        );
 
index 2118fa6..0da09df 100644 (file)
@@ -17,6 +17,8 @@
 #include "imv/imv_lang_string.h"
 #include "imv/imv_reason_string.h"
 
+#include <tncif_policy.h>
+
 #include <utils/lexparser.h>
 #include <collections/linked_list.h>
 #include <utils/debug.h>
@@ -69,14 +71,9 @@ struct private_imv_test_state_t {
        chunk_t ar_id_value;
 
        /**
-        * Unique session ID
-        */
-       int session_id;
-
-       /**
-        * List of workitems
+        * IMV database session associated with TNCCS connection
         */
-       linked_list_t *workitems;
+       imv_session_t *session;
 
        /**
         * IMV action recommendation
@@ -180,46 +177,16 @@ METHOD(imv_state_t, get_ar_id, chunk_t,
        return this->ar_id_value;
 }
 
-METHOD(imv_state_t, set_session_id, void,
-       private_imv_test_state_t *this, int session_id)
+METHOD(imv_state_t, set_session, void,
+       private_imv_test_state_t *this, imv_session_t *session)
 {
-       this->session_id = session_id;
+       this->session = session;
 }
 
-METHOD(imv_state_t, get_session_id, int,
+METHOD(imv_state_t, get_session, imv_session_t*,
        private_imv_test_state_t *this)
 {
-       return this->session_id;
-}
-
-METHOD(imv_state_t, add_workitem, void,
-       private_imv_test_state_t *this, imv_workitem_t *workitem)
-{
-       this->workitems->insert_last(this->workitems, workitem);
-}
-
-METHOD(imv_state_t, get_workitem_count, int,
-       private_imv_test_state_t *this)
-{
-       return this->workitems->get_count(this->workitems);
-}
-
-METHOD(imv_state_t, create_workitem_enumerator, enumerator_t*,
-       private_imv_test_state_t *this)
-{
-       return this->workitems->create_enumerator(this->workitems);
-}
-
-METHOD(imv_state_t, finalize_workitem, void,
-       private_imv_test_state_t *this, enumerator_t *enumerator,
-       imv_workitem_t *workitem, char *result, TNC_IMV_Evaluation_Result eval)
-{
-       TNC_IMV_Action_Recommendation rec;
-
-       this->workitems->remove_at(this->workitems, enumerator);
-       rec = workitem->set_result(workitem, result, eval);
-       /* TODO update workitem in IMV database */
-       workitem->destroy(workitem);
+       return this->session;
 }
 
 METHOD(imv_state_t, change_state, void,
@@ -244,6 +211,14 @@ METHOD(imv_state_t, set_recommendation, void,
        this->eval = eval;
 }
 
+METHOD(imv_state_t, update_recommendation, void,
+       private_imv_test_state_t *this, TNC_IMV_Action_Recommendation rec,
+                                                                       TNC_IMV_Evaluation_Result eval)
+{
+       this->rec  = tncif_policy_update_recommendation(this->rec, rec);
+       this->eval = tncif_policy_update_evaluation(this->eval, eval);
+}
+
 METHOD(imv_state_t, get_reason_string, bool,
        private_imv_test_state_t *this, enumerator_t *language_enumerator,
        chunk_t *reason_string, char **reason_language)
@@ -270,9 +245,8 @@ METHOD(imv_state_t, get_remediation_instructions, bool,
 METHOD(imv_state_t, destroy, void,
        private_imv_test_state_t *this)
 {
+       DESTROY_IF(this->session);
        DESTROY_IF(this->reason_string);
-       this->workitems->destroy_offset(this->workitems,
-                                                                       offsetof(imv_workitem_t, destroy));
        this->imcs->destroy_function(this->imcs, free);
        free(this->ar_id_value.ptr);
        free(this);
@@ -361,15 +335,12 @@ imv_state_t *imv_test_state_create(TNC_ConnectionID connection_id)
                                .get_max_msg_len = _get_max_msg_len,
                                .set_ar_id = _set_ar_id,
                                .get_ar_id = _get_ar_id,
-                               .set_session_id = _set_session_id,
-                               .get_session_id = _get_session_id,
-                               .add_workitem = _add_workitem,
-                               .get_workitem_count = _get_workitem_count,
-                               .create_workitem_enumerator = _create_workitem_enumerator,
-                               .finalize_workitem = _finalize_workitem,
+                               .set_session = _set_session,
+                               .get_session = _get_session,
                                .change_state = _change_state,
                                .get_recommendation = _get_recommendation,
                                .set_recommendation = _set_recommendation,
+                               .update_recommendation = _update_recommendation,
                                .get_reason_string = _get_reason_string,
                                .get_remediation_instructions = _get_remediation_instructions,
                                .destroy = _destroy,
index 365a7cb..031883a 100644 (file)
@@ -461,7 +461,7 @@ int main(int argc, char *argv[])
                exit(SS_RC_INITIALIZATION_FAILED);
        }
        atexit(cleanup);
-       libimcv_init();
+       libimcv_init(FALSE);
        libpts_init();
 
        do_args(argc, argv);
index fb32fcf..74eee81 100644 (file)
@@ -17,6 +17,7 @@
 #include "imv_attestation_process.h"
 #include "imv_attestation_build.h"
 
+#include <imcv.h>
 #include <imv/imv_agent.h>
 #include <imv/imv_msg.h>
 #include <ietf/ietf_attr.h>
@@ -134,7 +135,7 @@ TNC_Result TNC_IMV_Initialize(TNC_IMVID imv_id,
        }
 
        /* attach PTS database co-located with IMV database */
-       pts_db = pts_database_create(imv_attestation->get_database(imv_attestation));
+       pts_db = pts_database_create(imcv_db);
 
        return TNC_RESULT_SUCCESS;
 }
index 59f2bc1..442ffdd 100644 (file)
@@ -21,6 +21,8 @@
 #include <imv/imv_lang_string.h>
 #include "imv/imv_reason_string.h"
 
+#include <tncif_policy.h>
+
 #include <collections/linked_list.h>
 #include <utils/debug.h>
 
@@ -74,14 +76,9 @@ struct private_imv_attestation_state_t {
        chunk_t ar_id_value;
 
        /**
-        * Unique session ID
-        */
-       int session_id;
-
-       /**
-        * List of workitems
+        * IMV database session associated with TNCCS connection
         */
-       linked_list_t *workitems;
+       imv_session_t *session;
 
        /**
         * IMV Attestation handshake state
@@ -253,46 +250,16 @@ METHOD(imv_state_t, get_ar_id, chunk_t,
        return this->ar_id_value;
 }
 
-METHOD(imv_state_t, set_session_id, void,
-       private_imv_attestation_state_t *this, int session_id)
-{
-       this->session_id = session_id;
-}
-
-METHOD(imv_state_t, get_session_id, int,
-       private_imv_attestation_state_t *this)
-{
-       return this->session_id;
-}
-
-METHOD(imv_state_t, add_workitem, void,
-       private_imv_attestation_state_t *this, imv_workitem_t *workitem)
-{
-       this->workitems->insert_last(this->workitems, workitem);
-}
-
-METHOD(imv_state_t, get_workitem_count, int,
-       private_imv_attestation_state_t *this)
+METHOD(imv_state_t, set_session, void,
+       private_imv_attestation_state_t *this, imv_session_t *session)
 {
-       return this->workitems->get_count(this->workitems);
+       this->session = session;
 }
 
-METHOD(imv_state_t, create_workitem_enumerator, enumerator_t*,
+METHOD(imv_state_t, get_session, imv_session_t*,
        private_imv_attestation_state_t *this)
 {
-       return this->workitems->create_enumerator(this->workitems);
-}
-
-METHOD(imv_state_t, finalize_workitem, void,
-       private_imv_attestation_state_t *this, enumerator_t *enumerator,
-       imv_workitem_t *workitem, char *result, TNC_IMV_Evaluation_Result eval)
-{
-       TNC_IMV_Action_Recommendation rec;
-
-       this->workitems->remove_at(this->workitems, enumerator);
-       rec = workitem->set_result(workitem, result, eval);
-       /* TODO update workitem in IMV database */
-       workitem->destroy(workitem);
+       return this->session;
 }
 
 METHOD(imv_state_t, change_state, void,
@@ -303,7 +270,7 @@ METHOD(imv_state_t, change_state, void,
 
 METHOD(imv_state_t, get_recommendation, void,
        private_imv_attestation_state_t *this, TNC_IMV_Action_Recommendation *rec,
-                                                                       TNC_IMV_Evaluation_Result *eval)
+                                                                                  TNC_IMV_Evaluation_Result *eval)
 {
        *rec = this->rec;
        *eval = this->eval;
@@ -311,12 +278,20 @@ METHOD(imv_state_t, get_recommendation, void,
 
 METHOD(imv_state_t, set_recommendation, void,
        private_imv_attestation_state_t *this, TNC_IMV_Action_Recommendation rec,
-                                                                       TNC_IMV_Evaluation_Result eval)
+                                                                                  TNC_IMV_Evaluation_Result eval)
 {
        this->rec = rec;
        this->eval = eval;
 }
 
+METHOD(imv_state_t, update_recommendation, void,
+       private_imv_attestation_state_t *this, TNC_IMV_Action_Recommendation rec,
+                                                                                  TNC_IMV_Evaluation_Result eval)
+{
+       this->rec  = tncif_policy_update_recommendation(this->rec, rec);
+       this->eval = tncif_policy_update_evaluation(this->eval, eval);
+}
+
 METHOD(imv_state_t, get_reason_string, bool,
        private_imv_attestation_state_t *this, enumerator_t *language_enumerator,
        chunk_t *reason_string, char **reason_language)
@@ -368,9 +343,8 @@ METHOD(imv_state_t, get_remediation_instructions, bool,
 METHOD(imv_state_t, destroy, void,
        private_imv_attestation_state_t *this)
 {
+       DESTROY_IF(this->session);
        DESTROY_IF(this->reason_string);
-       this->workitems->destroy_offset(this->workitems,
-                                                                       offsetof(imv_workitem_t, destroy));
        this->file_meas_requests->destroy_function(this->file_meas_requests, free);
        this->components->destroy_function(this->components, (void *)free_func_comp);
        this->pts->destroy(this->pts);
@@ -564,15 +538,12 @@ imv_state_t *imv_attestation_state_create(TNC_ConnectionID connection_id)
                                .get_max_msg_len = _get_max_msg_len,
                                .set_ar_id = _set_ar_id,
                                .get_ar_id = _get_ar_id,
-                               .set_session_id = _set_session_id,
-                               .get_session_id = _get_session_id,
-                               .add_workitem = _add_workitem,
-                               .get_workitem_count = _get_workitem_count,
-                               .create_workitem_enumerator = _create_workitem_enumerator,
-                               .finalize_workitem = _finalize_workitem,
+                               .set_session = _set_session,
+                               .get_session = _get_session,
                                .change_state = _change_state,
                                .get_recommendation = _get_recommendation,
                                .set_recommendation = _set_recommendation,
+                               .update_recommendation = _update_recommendation,
                                .get_reason_string = _get_reason_string,
                                .get_remediation_instructions = _get_remediation_instructions,
                                .destroy = _destroy,
index 6da1201..6176478 100644 (file)
@@ -5,6 +5,7 @@ noinst_LTLIBRARIES = libtncif.la
 libtncif_la_SOURCES = \
 tncif.h tncifimc.h tncifimv.h tncif_names.h tncif_names.c \
 tncif_identity.h tncif_identity.c \
-tncif_pa_subtypes.h tncif_pa_subtypes.c
+tncif_pa_subtypes.h tncif_pa_subtypes.c \
+tncif_policy.h tncif_policy.c
 
 EXTRA_DIST = Android.mk
diff --git a/src/libtncif/tncif_policy.c b/src/libtncif/tncif_policy.c
new file mode 100644 (file)
index 0000000..740f2b6
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2013 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 "tncif_policy.h"
+
+/**
+ * See header
+ */
+TNC_IMV_Evaluation_Result tncif_policy_update_evaluation(
+                                                                       TNC_IMV_Evaluation_Result eval,
+                                                                       TNC_IMV_Evaluation_Result eval_add)
+{
+       switch (eval)
+       {
+               case TNC_IMV_EVALUATION_RESULT_COMPLIANT:
+                       switch (eval_add)
+                       {
+                               case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR:
+                               case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR:
+                               case TNC_IMV_EVALUATION_RESULT_ERROR:
+                                       eval = eval_add;
+                                       break;
+                               default:
+                                       break;
+                       }
+                       break;
+               case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR:
+                       switch (eval_add)
+                       {
+                               case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR:
+                               case TNC_IMV_EVALUATION_RESULT_ERROR:
+                                       eval = eval_add;
+                                       break;
+                               default:
+                                       break;
+                       }
+                       break;
+               case TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR:
+                       switch (eval_add)
+                       {
+                               case TNC_IMV_EVALUATION_RESULT_ERROR:
+                                       eval = eval_add;
+                                       break;
+                               default:
+                                       break;
+                       }
+                       break;
+               case TNC_IMV_EVALUATION_RESULT_DONT_KNOW:
+                       eval = eval_add;
+                       break;
+               default:
+                       break;
+       }
+       return eval;
+}
+
+/**
+ * See header
+ */
+TNC_IMV_Action_Recommendation tncif_policy_update_recommendation(
+                                                                       TNC_IMV_Action_Recommendation rec,
+                                                                       TNC_IMV_Action_Recommendation rec_add)
+{
+       switch (rec)
+       {
+               case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
+                       switch (rec_add)
+                       {
+                               case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
+                               case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
+                                       rec = rec_add;
+                                       break;
+                               default:
+                                       break;
+                       }
+                       break;
+               case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
+                       switch (rec_add)
+                       {
+                               case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
+                                       rec = rec_add;
+                                       break;
+                               default:
+                                       break;
+                       }
+                       break;
+               case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:
+                       rec = rec_add;
+                       break;
+               default:
+                       break;
+       }
+       return rec;
+}
diff --git a/src/libtncif/tncif_policy.h b/src/libtncif/tncif_policy.h
new file mode 100644 (file)
index 0000000..d9f553b
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2013 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 libtncif libtncif
+ *
+ * @addtogroup libtncif
+ * TNC interface definitions
+ *
+ * @defgroup tnc_policy tnc_policy
+ * @{ @ingroup libtncif
+ */
+
+#ifndef TNCIF_POLICY_H_
+#define TNCIF_POLICY_H_
+
+#include "tncifimv.h"
+
+/**
+ * Create an empty TNC Identity object
+ *
+ * @param eval                 Existing evaluation to be updated
+ * @param eval_add             Partial evaluation to be added
+ * @return                             Updated evaluation
+ */
+TNC_IMV_Evaluation_Result tncif_policy_update_evaluation(
+                                                                       TNC_IMV_Evaluation_Result eval,
+                                                                       TNC_IMV_Evaluation_Result eval_add);
+
+/**
+ * Create an empty TNC Identity object
+ *
+ * @param rec                  Existing recommendationto be updated
+ * @param rec_add              Partial recommendation to be added
+ * @return                             Updated recommendation
+ */
+TNC_IMV_Action_Recommendation tncif_policy_update_recommendation(
+                                                                       TNC_IMV_Action_Recommendation rec,
+                                                                       TNC_IMV_Action_Recommendation rec_add);
+
+#endif /** TNCIF_POLICY_H_ @}*/