diff options
23 files changed, 885 insertions, 596 deletions
diff --git a/src/libimcv/Makefile.am b/src/libimcv/Makefile.am index e1c68f37a..13531fef6 100644 --- a/src/libimcv/Makefile.am +++ b/src/libimcv/Makefile.am @@ -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 \ diff --git a/src/libimcv/imc/imc_agent.c b/src/libimcv/imc/imc_agent.c index f309abe74..7dc3abddd 100644 --- a/src/libimcv/imc/imc_agent.c +++ b/src/libimcv/imc/imc_agent.c @@ -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; } diff --git a/src/libimcv/imcv.c b/src/libimcv/imcv.c index f9ecf793d..cb0222e0e 100644 --- a/src/libimcv/imcv.c +++ b/src/libimcv/imcv.c @@ -22,7 +22,10 @@ #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 @@ -30,6 +33,11 @@ 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)) diff --git a/src/libimcv/imcv.h b/src/libimcv/imcv.h index 3a37e3d8c..10c66e65a 100644 --- a/src/libimcv/imcv.h +++ b/src/libimcv/imcv.h @@ -35,15 +35,17 @@ #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_ @}*/ diff --git a/src/libimcv/imv/imv_agent.c b/src/libimcv/imv/imv_agent.c index fdc76abf9..ae20f2b18 100644 --- a/src/libimcv/imv/imv_agent.c +++ b/src/libimcv/imv/imv_agent.c @@ -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); diff --git a/src/libimcv/imv/imv_agent.h b/src/libimcv/imv/imv_agent.h index 5c7841886..d58af260b 100644 --- a/src/libimcv/imv/imv_agent.h +++ b/src/libimcv/imv/imv_agent.h @@ -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 diff --git a/src/libimcv/imv/imv_database.c b/src/libimcv/imv/imv_database.c index bf11d785d..4c35d7504 100644 --- a/src/libimcv/imv/imv_database.c +++ b/src/libimcv/imv/imv_database.c @@ -21,19 +21,14 @@ #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, ¤t)) { - 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, ¤t)) + { + 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; } diff --git a/src/libimcv/imv/imv_database.h b/src/libimcv/imv/imv_database.h index abe49dc87..3c4bf83d8 100644 --- a/src/libimcv/imv/imv_database.h +++ b/src/libimcv/imv/imv_database.h @@ -22,7 +22,10 @@ #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 index 000000000..754f1f74c --- /dev/null +++ b/src/libimcv/imv/imv_session.c @@ -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 index 000000000..d38b2aca5 --- /dev/null +++ b/src/libimcv/imv/imv_session.h @@ -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_ @}*/ diff --git a/src/libimcv/imv/imv_state.h b/src/libimcv/imv/imv_state.h index 4bc890ec1..53df6714e 100644 --- a/src/libimcv/imv/imv_state.h +++ b/src/libimcv/imv/imv_state.h @@ -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 diff --git a/src/libimcv/imv/imv_workitem.c b/src/libimcv/imv/imv_workitem.c index 62b62bb5f..e4403e75a 100644 --- a/src/libimcv/imv/imv_workitem.c +++ b/src/libimcv/imv/imv_workitem.c @@ -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, diff --git a/src/libimcv/imv/imv_workitem.h b/src/libimcv/imv/imv_workitem.h index 2b437826b..507e99e85 100644 --- a/src/libimcv/imv/imv_workitem.h +++ b/src/libimcv/imv/imv_workitem.h @@ -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); diff --git a/src/libimcv/plugins/imv_os/imv_os.c b/src/libimcv/plugins/imv_os/imv_os.c index 89946459c..f25c547d3 100644 --- a/src/libimcv/plugins/imv_os/imv_os.c +++ b/src/libimcv/plugins/imv_os/imv_os.c @@ -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); diff --git a/src/libimcv/plugins/imv_os/imv_os_state.c b/src/libimcv/plugins/imv_os/imv_os_state.c index a9ed3c895..3cfe6b39c 100644 --- a/src/libimcv/plugins/imv_os/imv_os_state.c +++ b/src/libimcv/plugins/imv_os/imv_os_state.c @@ -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(), ); diff --git a/src/libimcv/plugins/imv_scanner/imv_scanner_state.c b/src/libimcv/plugins/imv_scanner/imv_scanner_state.c index c26bc43a3..de0ed6230 100644 --- a/src/libimcv/plugins/imv_scanner/imv_scanner_state.c +++ b/src/libimcv/plugins/imv_scanner/imv_scanner_state.c @@ -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(), ); diff --git a/src/libimcv/plugins/imv_test/imv_test_state.c b/src/libimcv/plugins/imv_test/imv_test_state.c index 2118fa675..0da09df67 100644 --- a/src/libimcv/plugins/imv_test/imv_test_state.c +++ b/src/libimcv/plugins/imv_test/imv_test_state.c @@ -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, diff --git a/src/libpts/plugins/imv_attestation/attest.c b/src/libpts/plugins/imv_attestation/attest.c index 365a7cb1c..031883ab1 100644 --- a/src/libpts/plugins/imv_attestation/attest.c +++ b/src/libpts/plugins/imv_attestation/attest.c @@ -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); diff --git a/src/libpts/plugins/imv_attestation/imv_attestation.c b/src/libpts/plugins/imv_attestation/imv_attestation.c index fb32fcf4e..74eee8117 100644 --- a/src/libpts/plugins/imv_attestation/imv_attestation.c +++ b/src/libpts/plugins/imv_attestation/imv_attestation.c @@ -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; } diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_state.c b/src/libpts/plugins/imv_attestation/imv_attestation_state.c index 59f2bc1a0..442ffdd03 100644 --- a/src/libpts/plugins/imv_attestation/imv_attestation_state.c +++ b/src/libpts/plugins/imv_attestation/imv_attestation_state.c @@ -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, diff --git a/src/libtncif/Makefile.am b/src/libtncif/Makefile.am index 6da1201f3..6176478a2 100644 --- a/src/libtncif/Makefile.am +++ b/src/libtncif/Makefile.am @@ -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 index 000000000..740f2b69f --- /dev/null +++ b/src/libtncif/tncif_policy.c @@ -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 index 000000000..d9f553b72 --- /dev/null +++ b/src/libtncif/tncif_policy.h @@ -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_ @}*/ |