implemented IMV session control
authorAndreas Steffen <andreas.steffen@strongswan.org>
Sun, 28 Apr 2013 20:47:09 +0000 (22:47 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 21 Jun 2013 21:25:21 +0000 (23:25 +0200)
21 files changed:
src/libimcv/Makefile.am
src/libimcv/imv/imv_agent.c
src/libimcv/imv/imv_agent.h
src/libimcv/imv/imv_database.c [new file with mode: 0644]
src/libimcv/imv/imv_database.h [new file with mode: 0644]
src/libimcv/imv/imv_state.h
src/libimcv/plugins/imv_os/imv_os.c
src/libimcv/plugins/imv_os/imv_os_database.c
src/libimcv/plugins/imv_os/imv_os_database.h
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/Makefile.am
src/libpts/plugins/imv_attestation/attest.c
src/libpts/plugins/imv_attestation/attest_db.c
src/libpts/plugins/imv_attestation/attest_db.h
src/libpts/plugins/imv_attestation/imv_attestation.c
src/libpts/plugins/imv_attestation/imv_attestation_state.c
src/libpts/plugins/imv_attestation/tables.sql
src/libpts/pts/pts_database.c
src/libpts/pts/pts_database.h

index 51a7be0..470f309 100644 (file)
@@ -10,6 +10,7 @@ libimcv_la_SOURCES = \
        imc/imc_agent.h imc/imc_agent.c imc/imc_state.h \
        imc/imc_msg.h imc/imc_msg.c \
        imv/imv_agent.h imv/imv_agent.c imv/imv_state.h \
+       imv/imv_database.h imv/imv_database.c \
        imv/imv_msg.h imv/imv_msg.c \
        imv/imv_lang_string.h imv/imv_lang_string.c \
        imv/imv_reason_string.h imv/imv_reason_string.c \
index 879a010..fdc76ab 100644 (file)
@@ -63,6 +63,11 @@ 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;
@@ -402,11 +407,14 @@ METHOD(imv_agent_t, create_state, TNC_Result,
 {
        TNC_ConnectionID conn_id;
        char *tnccs_p = NULL, *tnccs_v = NULL, *t_p = NULL, *t_v = NULL;
-       bool has_long = FALSE, has_excl = FALSE, has_soh = FALSE;
+       bool has_long = FALSE, has_excl = FALSE, has_soh = FALSE, first = TRUE;
        linked_list_t *ar_identities;
        enumerator_t *enumerator;
        tncif_identity_t *tnc_id;
+       int session_id;
        u_int32_t max_msg_len;
+       u_int32_t ar_id_type = TNC_ID_UNKNOWN;
+       chunk_t ar_id_value = chunk_empty;
 
        conn_id = state->get_connection_id(state);
        if (find_connection(this, conn_id))
@@ -462,10 +470,31 @@ METHOD(imv_agent_t, create_state, TNC_Result,
                         TNC_Subject_names, tcg_subject_type,
                         id_value.len, id_value.ptr,
                         TNC_Authentication_names, tcg_auth_type);
-               state->set_ar_id(state, tcg_id_type, id_value);
+
+               if (first)
+               {
+                       ar_id_type = tcg_id_type;
+                       ar_id_value = id_value;
+                       state->set_ar_id(state, ar_id_type, ar_id_value);
+                       first = FALSE;
+               }
        }
        enumerator->destroy(enumerator);
 
+       if (this->db)
+       {
+               session_id = this->db->get_session_id(this->db, conn_id,
+                                                                                         ar_id_type, ar_id_value);
+               if (session_id)
+               {
+                       DBG2(DBG_IMV, "  assigned session ID %d", session_id);
+                       state->set_session_id(state, session_id);
+               }
+               else
+               {
+                       DBG1(DBG_IMV, "  no session ID assigned");
+               }
+       }
        ar_identities->destroy_offset(ar_identities,
                                                   offsetof(tncif_identity_t, destroy));
        free(tnccs_p);
@@ -553,6 +582,12 @@ 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)
 {
@@ -754,6 +789,7 @@ 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));
@@ -772,6 +808,7 @@ 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())
@@ -786,6 +823,7 @@ 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,
@@ -804,6 +842,13 @@ 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 6f3d2b4..5c78418 100644 (file)
@@ -23,6 +23,7 @@
 #define IMV_AGENT_H_
 
 #include "imv_state.h"
+#include "imv_database.h"
 #include "pa_tnc/pa_tnc_msg.h"
 
 #include <tncifimv.h>
@@ -138,6 +139,13 @@ 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
new file mode 100644 (file)
index 0000000..1402e2e
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * 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_database.h"
+
+#include <utils/debug.h>
+
+#include <string.h>
+#include <time.h>
+
+typedef struct private_imv_database_t private_imv_database_t;
+
+#define SESSION_TIME_DELTA_MAX         2  /* seconds */
+
+/**
+ * Private data of a imv_database_t object.
+ *
+ */
+struct private_imv_database_t {
+
+       /**
+        * Public imv_database_t interface.
+        */
+       imv_database_t public;
+
+       /**
+        * database instance
+        */
+       database_t *db;
+
+};
+
+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)
+{
+       enumerator_t *e;
+       int ar_id = 0, session_id = 0;
+       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)
+       {
+               e->enumerate(e, &session_id, &created);
+               e->destroy(e);
+       }
+
+       /* 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)
+       {
+               return session_id;
+       }
+
+       if (ar_id_value.len)
+       {
+               /* get primary key of AR identity if it exists */
+               e = this->db->query(this->db,
+                               "SELECT id FROM identities WHERE type = ? AND value = ?",
+                               DB_INT, ar_id_type, DB_BLOB, ar_id_value, DB_INT);
+               if (e)
+               {
+                       e->enumerate(e, &ar_id);
+                       e->destroy(e);
+               }
+
+               /* if AR identity has not been found - register it */
+               if (!ar_id)
+               {
+                       this->db->execute(this->db, &ar_id,
+                               "INSERT INTO identities (type, value) VALUES (?, ?)",
+                                DB_INT, ar_id_type, DB_BLOB, ar_id_value);
+               }
+       }
+
+       /* create a new session ID */
+       this->db->execute(this->db, &session_id,
+                       "INSERT INTO sessions (time, connection, identity) "
+                       "VALUES (?, ?, ?)", DB_UINT, now, DB_INT, id, DB_INT, ar_id);
+
+       return session_id;
+}
+
+METHOD(imv_database_t, add_product, int,
+       private_imv_database_t *this, int session_id, char *product)
+{
+       enumerator_t *e;
+       int pid = 0;
+
+       /* get primary key of product info string if it exists */
+       e = this->db->query(this->db,
+                       "SELECT id FROM products WHERE name = ?", DB_TEXT, product, DB_INT);
+       if (e)
+       {
+               e->enumerate(e, &pid);
+               e->destroy(e);
+       }
+
+       /* if product info string has not been found - register it */
+       if (!pid)
+       {
+               this->db->execute(this->db, &pid,
+                       "INSERT INTO products (name) VALUES (?)", DB_TEXT, product);
+       }
+       
+       /* add product reference to session */
+       if (pid)
+       {
+               this->db->execute(this->db, NULL,
+                       "UPDATE sessions SET product = ? WHERE id = ?",
+                        DB_INT, pid, DB_INT, session_id);
+       }
+
+       return pid;
+}
+
+METHOD(imv_database_t, add_device, int,
+       private_imv_database_t *this, int session_id, chunk_t device)
+{
+       enumerator_t *e;
+       int did = 0;
+
+       /* get primary key of device identification if it exists */
+       e = this->db->query(this->db,
+                       "SELECT id FROM devices WHERE value = ?", DB_BLOB, device, DB_INT);
+       if (e)
+       {
+               e->enumerate(e, &did);
+               e->destroy(e);
+       }
+
+       /* if device identification has not been found - register it */
+       if (!did)
+       {
+               this->db->execute(this->db, &did,
+                       "INSERT INTO devices (value) VALUES (?)", DB_BLOB, device);
+       }
+       
+       /* add device reference to session */
+       if (did)
+       {
+               this->db->execute(this->db, NULL,
+                       "UPDATE sessions SET device = ? WHERE id = ?",
+                        DB_INT, did, DB_INT, session_id);
+       }
+
+       return did;
+}
+
+METHOD(imv_database_t, get_database, database_t*,
+       private_imv_database_t *this)
+{
+       return this->db;
+}
+
+METHOD(imv_database_t, destroy, void,
+       private_imv_database_t *this)
+{
+       this->db->destroy(this->db);
+       free(this);
+}
+
+/**
+ * See header
+ */
+imv_database_t *imv_database_create(char *uri)
+{
+       private_imv_database_t *this;
+
+       INIT(this,
+               .public = {
+                       .get_session_id = _get_session_id,
+                       .add_product = _add_product,
+                       .add_device = _add_device,
+                       .get_database = _get_database,
+                       .destroy = _destroy,
+               },
+               .db = lib->db->create(lib->db, uri),
+       );
+
+       if (!this->db)
+       {
+               DBG1(DBG_IMV,
+                        "failed to connect to IMV database '%s'", uri);
+               free(this);
+               return NULL;
+       }
+
+       return &this->public;
+}
+
diff --git a/src/libimcv/imv/imv_database.h b/src/libimcv/imv/imv_database.h
new file mode 100644 (file)
index 0000000..3b3cbd6
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * 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_database_t imv_database
+ * @{ @ingroup libimcv_imv
+ */
+
+#ifndef IMV_DATABASE_H_
+#define IMV_DATABASE_H_
+
+#include <tncif.h>
+
+#include <library.h>
+
+typedef struct imv_database_t imv_database_t;
+
+/**
+ * IMV database interface 
+ */
+struct imv_database_t {
+
+       /**
+        * Register or get a unique session ID using the TNCCS connection ID
+        *
+        * @param 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
+        */
+        int (*get_session_id)(imv_database_t *this, TNC_ConnectionID id,
+                                                  u_int32_t ar_id_type, chunk_t ar_id_value);
+
+       /**
+        * Add product information string to a session
+        *
+        * @param session_id    Session ID
+        * @param product               Product information string
+        * @return                              Product ID or 0 if not available
+        */
+        int (*add_product)(imv_database_t *this, int session_id, char *product);
+
+       /**
+        * Add device identification to a session
+        *
+        * @param session_id    Sessiion ID
+        * @param device                Device identification
+        * @return                              Device ID or 0 if not available
+        */
+        int (*add_device)(imv_database_t *this, int session_id, chunk_t device);
+
+       /**
+        * Get database handle
+        *
+        * @return                              Database handle
+        */
+        database_t* (*get_database)(imv_database_t *this);
+
+       /**
+        * Destroys an imv_database_t object
+        */
+       void (*destroy)(imv_database_t *this);
+};
+
+/**
+ * Create an imv_database_t instance
+ *
+ * @param uri                  database uri
+ */
+imv_database_t* imv_database_create(char *uri);
+
+#endif /** IMV_DATABASE_H_ @}*/
index d1a87d2..aa0104c 100644 (file)
@@ -95,6 +95,20 @@ struct imv_state_t {
        chunk_t (*get_ar_id)(imv_state_t *this, u_int32_t *id_type);
 
        /**
+        * Set unique session ID
+        *
+        * @param session_id    Unique session ID
+        */
+       void (*set_session_id)(imv_state_t *this, int session_id);
+
+       /**
+        * Get unique session_id
+        *
+        * @return                              Unique session ID
+        */
+       int (*get_session_id)(imv_state_t *this);
+
+       /**
         * Change the connection state
         *
         * @param new_state             new connection state
index f1cb74e..48af9c5 100644 (file)
@@ -65,8 +65,6 @@ TNC_Result TNC_IMV_Initialize(TNC_IMVID imv_id,
                                                          TNC_Version max_version,
                                                          TNC_Version *actual_version)
 {
-       char *uri;
-
        if (imv_os)
        {
                DBG1(DBG_IMV, "IMV \"%s\" has already been initialized", imv_name);
@@ -84,13 +82,8 @@ TNC_Result TNC_IMV_Initialize(TNC_IMVID imv_id,
                return TNC_RESULT_NO_COMMON_VERSION;
        }
 
-       /* attach OS database */
-       uri = lib->settings->get_str(lib->settings,
-                               "libimcv.plugins.imv-os.database", NULL);
-       if (uri)
-       {
-               os_db = imv_os_database_create(uri);
-       }
+       /* attach OS database co-located with IMV database */
+       os_db = imv_os_database_create(imv_os->get_database(imv_os));
 
        return TNC_RESULT_SUCCESS;
 }
@@ -289,7 +282,9 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg)
                                case ITA_ATTR_SETTINGS:
                                {
                                        ita_attr_settings_t *attr_cast;
+                                       imv_database_t *imv_db;
                                        enumerator_t *e;
+                                       int did;
                                        char *name;
                                        chunk_t value;
 
@@ -306,8 +301,13 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg)
                                                else if ((streq(name, android_id_str) ||
                                                                  streq(name, machine_id_str)) && os_db)
                                                {
-                                                       os_state->set_device_id(os_state,
-                                                                               os_db->get_device_id(os_db, value));
+                                                       imv_db = imv_os->get_database(imv_os);
+                                                       if (imv_db)
+                                                       {
+                                                               did = imv_db->add_device(imv_db,
+                                                                               state->get_session_id(state), value);
+                                                               os_state->set_device_id(os_state, did);
+                                                       }
                                                }
                                                DBG1(DBG_IMV, "setting '%s'\n  %.*s",
                                                         name, value.len, value.ptr);
@@ -332,11 +332,19 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg)
        {
                os_type_t os_type;
                ita_attr_get_settings_t *attr_cast;
+               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)
+               {
+                       imv_db->add_product(imv_db, state->get_session_id(state),
+                                       os_state->get_info(os_state, NULL, NULL, NULL));
+               }
+
                /* requesting installed packages */
                os_state->set_package_request(os_state, TRUE);
                attr = ietf_attr_attr_request_create(PEN_IETF,
@@ -376,10 +384,8 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg)
                !os_state->get_angel_count(os_state) &&
                 os_state->get_info(os_state, NULL, NULL, NULL))
        {
-               int device_id, count, count_update, count_blacklist, count_ok;
+               int count, count_update, count_blacklist, count_ok;
                u_int os_settings;
-               u_int32_t id_type;
-               chunk_t id_value;
 
                os_settings = os_state->get_os_settings(os_state);
                os_state->get_count(os_state, &count, &count_update, &count_blacklist,
@@ -389,13 +395,10 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg)
                         count_ok, count - count_update - count_blacklist - count_ok);
 
                /* Store device information in database */
-               device_id = os_state->get_device_id(os_state);
-               id_value = state->get_ar_id(state, &id_type);
-               if (os_db && device_id)
+               if (os_db)
                {
-                       os_db->set_device_info(os_db, device_id, id_type, id_value,
-                                               os_state->get_info(os_state, NULL, NULL, NULL),
-                                               count, count_update, count_blacklist, os_settings);
+                       os_db->set_device_info(os_db, state->get_session_id(state),
+                                       count, count_update, count_blacklist, os_settings);
                }
 
                if (count_update || count_blacklist || os_settings)
@@ -589,6 +592,7 @@ TNC_Result TNC_IMV_Terminate(TNC_IMVID imv_id)
                return TNC_RESULT_NOT_INITIALIZED;
        }
        DESTROY_IF(os_db);
+       os_db = NULL;
 
        imv_os->destroy(imv_os);
        imv_os = NULL;
index a7f9f2e..6f7b29b 100644 (file)
@@ -187,148 +187,46 @@ METHOD(imv_os_database_t, check_packages, status_t,
        return status;
 }
 
-METHOD(imv_os_database_t, get_device_id, int,
-       private_imv_os_database_t *this, chunk_t value)
-{
-       enumerator_t *e;
-       int id;
-
-       /* get primary key of device ID */
-       e = this->db->query(this->db, "SELECT id FROM devices WHERE value = ?",
-                                               DB_BLOB, value, DB_INT);
-       if (!e)
-       {
-               return 0;
-       }
-       if (e->enumerate(e, &id))
-       {
-               /* device ID already exists in database - return primary key */
-               e->destroy(e);
-               return id;
-       }
-       e->destroy(e);
-
-       /* register new device ID in database and return primary key */
-       return (this->db->execute(this->db, &id,
-                       "INSERT INTO devices (value) VALUES (?)", DB_BLOB, value) == 1) ?
-                       id : 0;
-}
-
 METHOD(imv_os_database_t, set_device_info, void,
-       private_imv_os_database_t *this,  int device_id, u_int32_t ar_id_type,
-       chunk_t ar_id_value, char *os_info, int count, int count_update,
-       int count_blacklist, u_int flags)
+       private_imv_os_database_t *this,  int session_id, int count,
+       int count_update, int count_blacklist, u_int flags)
 {
        enumerator_t *e;
-       time_t last_time;
-       int pid = 0, last_pid = 0, iid = 0, last_iid;
-       int last_count_update = 0, last_count_blacklist = 0;
-       u_int last_flags;
-       bool found = FALSE;
-
-       /* get primary key of OS info string if it exists */
-       e = this->db->query(this->db,
-                       "SELECT id FROM products WHERE name = ?", DB_TEXT, os_info,
-                        DB_INT);
-       if (e)
-       {
-               e->enumerate(e, &pid);
-               e->destroy(e);
-       }
-
-       /* if OS info string has not been found - register it */
-       if (!pid)
-       {
-               this->db->execute(this->db, &pid,
-                       "INSERT INTO products (name) VALUES (?)", DB_TEXT, os_info);
-       }
-
-       /* get primary key of AR identity if it exists */
-       e = this->db->query(this->db,
-                       "SELECT id FROM identities WHERE type = ? AND data = ?",
-                        DB_INT,  ar_id_type, DB_BLOB, ar_id_value, DB_INT);
-       if (e)
-       {
-               e->enumerate(e, &iid);
-               e->destroy(e);
-       }
-
-       /* if AR identity has not been found - register it */
-       if (!iid)
-       {
-               this->db->execute(this->db, &iid,
-                       "INSERT INTO identities (type, data) VALUES (?, ?)",
-                        DB_INT, ar_id_type, DB_BLOB, ar_id_value);
-       }
 
-       /* get latest device info record if it exists */
-       e = this->db->query(this->db,
-                       "SELECT time, ar_id, product, count_update, count_blacklist, flags "
-                       "FROM device_infos WHERE device = ? ORDER BY time DESC",
-                        DB_INT, device_id, DB_INT, DB_INT, DB_INT, DB_INT, DB_INT, DB_UINT);
-       if (e)
-       {
-               found = e->enumerate(e, &last_time, &last_iid, &last_pid,
-                                                               &last_count_update, &last_count_blacklist,
-                                                               &last_flags);
-               e->destroy(e);
-       }
-       if (found && !last_count_update && !last_count_blacklist && !last_flags &&
-               iid == last_iid && pid == last_pid)
-       {
-               /* update device info */
-               this->db->execute(this->db, NULL,
-                       "UPDATE device_infos SET time = ?, count = ?, count_update = ?, "
-                       "count_blacklist = ?, flags = ? WHERE device = ? AND time = ?",
-                        DB_UINT, time(NULL), DB_INT, count, DB_INT, count_update,
-                        DB_INT, count_blacklist, DB_UINT, flags,
-                        DB_INT, device_id, DB_UINT, last_time);
-       }
-       else
-       {
-               /* insert device info */
-               this->db->execute(this->db, NULL,
-                       "INSERT INTO device_infos (device, time, ar_id, product, count, "
-                       "count_update, count_blacklist, flags) "
-                       "VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
-                        DB_INT, device_id, DB_UINT, time(NULL), DB_INT, iid, DB_INT, pid,
-                        DB_INT, count, DB_INT, count_update, DB_INT, count_blacklist,
-                        DB_UINT, flags);
-       }
+       this->db->execute(this->db, NULL,
+                       "INSERT INTO device_infos (session, count, count_update, "
+                       "count_blacklist, flags) VALUES (?, ?, ?, ?, ?)",
+                        DB_INT, session_id, DB_INT, count, DB_INT, count_update,
+                        DB_INT, count_blacklist, DB_UINT, flags);
 }
 
 METHOD(imv_os_database_t, destroy, void,
        private_imv_os_database_t *this)
 {
-       this->db->destroy(this->db);
        free(this);
 }
 
 /**
  * See header
  */
-imv_os_database_t *imv_os_database_create(char *uri)
+imv_os_database_t *imv_os_database_create(imv_database_t *imv_db)
 {
        private_imv_os_database_t *this;
 
+       if (!imv_db)
+       {
+               return NULL;
+       }
+
        INIT(this,
                .public = {
                        .check_packages = _check_packages,
-                       .get_device_id = _get_device_id,
                        .set_device_info = _set_device_info,
                        .destroy = _destroy,
                },
-               .db = lib->db->create(lib->db, uri),
+               .db = imv_db->get_database(imv_db),
        );
 
-       if (!this->db)
-       {
-               DBG1(DBG_IMV,
-                        "failed to connect to OS database '%s'", uri);
-               free(this);
-               return NULL;
-       }
-
        return &this->public;
 }
 
index 01d7e84..7b9ef3c 100644 (file)
@@ -22,6 +22,7 @@
 #define IMV_OS_DATABASE_H_
 
 #include "imv_os_state.h"
+#include "imv/imv_database.h"
 
 #include <library.h>
 
@@ -42,32 +43,20 @@ struct imv_os_database_t {
                                                           enumerator_t *package_enumerator);
 
        /**
-       * Get the primary database key of the device ID
-       *
-       * @param value                                  Device ID value
-       */
-       int (*get_device_id)(imv_os_database_t *this, chunk_t value);
-
-       /**
-       * Set health infos for a given  device
-       *
-       * @param device_id                              Device ID primary key
-       * @param ar_id_type                             Access Requestor ID Type
-       * @param ar_id_value                    Access Requestor ID Value
-       * @param os_info                                OS info string
-       * @param count                                  Number of installed packages
-       * @param count_update                   Number of packages to be updated
-       * @param count_blacklist                Number of blacklisted packages
-       * @param flags                                  Various flags, e.g. illegal OS settings
-       */
-       void (*set_device_info)(imv_os_database_t *this, int device_id,
-                                                       u_int32_t ar_id_type, chunk_t ar_id_value,
-                                                       char *os_info, int count, int count_update,
-                                                       int count_blacklist, u_int flags);
+        * Set health infos for a given  device
+        *
+        * @param sesson_id                             Session ID
+        * @param count                                 Number of installed packages
+        * @param count_update                  Number of packages to be updated
+        * @param count_blacklist               Number of blacklisted packages
+        * @param flags                                 Various flags, e.g. illegal OS settings
+        */
+       void (*set_device_info)(imv_os_database_t *this, int session_id, int count,
+                                                       int count_update, int count_blacklist, u_int flags);
 
        /**
-       * Destroys an imv_os_database_t object.
-       */
+        * Destroys an imv_os_database_t object.
+        */
        void (*destroy)(imv_os_database_t *this);
 
 };
@@ -75,8 +64,8 @@ struct imv_os_database_t {
 /**
  * Create an imv_os_database_t instance
  *
- * @param uri                  database uri
+ * @param imv_db                       Already attached IMV database
  */
-imv_os_database_t* imv_os_database_create(char *uri);
+imv_os_database_t* imv_os_database_create(imv_database_t *imv_db);
 
 #endif /** IMV_OS_DATABASE_H_ @}*/
index 073d713..e9661ec 100644 (file)
@@ -72,6 +72,11 @@ struct private_imv_os_state_t {
        chunk_t ar_id_value;
 
        /**
+        * Unique session ID
+        */
+       int session_id;
+
+       /**
         * IMV action recommendation
         */
        TNC_IMV_Action_Recommendation rec;
@@ -346,6 +351,18 @@ 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)
+{
+       this->session_id = session_id;
+}
+
+METHOD(imv_state_t, get_session_id, int,
+       private_imv_os_state_t *this)
+{
+       return this->session_id;
+}
+
 METHOD(imv_state_t, change_state, void,
        private_imv_os_state_t *this, TNC_ConnectionState new_state)
 {
@@ -633,6 +650,8 @@ 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,
                                .change_state = _change_state,
                                .get_recommendation = _get_recommendation,
                                .set_recommendation = _set_recommendation,
index 2123af7..f75dce5 100644 (file)
@@ -69,6 +69,11 @@ struct private_imv_scanner_state_t {
        chunk_t ar_id_value;
 
        /**
+        * Unique session ID
+        */
+       int session_id;
+
+       /**
         * IMV action recommendation
         */
        TNC_IMV_Action_Recommendation rec;
@@ -182,6 +187,18 @@ METHOD(imv_state_t, set_ar_id, void,
        this->ar_id_value = chunk_clone(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, get_ar_id, chunk_t,
        private_imv_scanner_state_t *this, u_int32_t *id_type)
 {
@@ -296,6 +313,8 @@ 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,
                                .change_state = _change_state,
                                .get_recommendation = _get_recommendation,
                                .set_recommendation = _set_recommendation,
index 41da44d..4f91618 100644 (file)
@@ -69,6 +69,11 @@ struct private_imv_test_state_t {
        chunk_t ar_id_value;
 
        /**
+        * Unique session ID
+        */
+       int session_id;
+
+       /**
         * IMV action recommendation
         */
        TNC_IMV_Action_Recommendation rec;
@@ -170,6 +175,18 @@ 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)
+{
+       this->session_id = session_id;
+}
+
+METHOD(imv_state_t, get_session_id, int,
+       private_imv_test_state_t *this)
+{
+       return this->session_id;
+}
+
 METHOD(imv_state_t, change_state, void,
        private_imv_test_state_t *this, TNC_ConnectionState new_state)
 {
@@ -307,6 +324,8 @@ 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,
                                .change_state = _change_state,
                                .get_recommendation = _get_recommendation,
                                .set_recommendation = _set_recommendation,
index edf3f74..7810e98 100644 (file)
@@ -1,5 +1,8 @@
 
-INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libimcv
+INCLUDES = \
+       -I$(top_srcdir)/src/libstrongswan \
+       -I$(top_srcdir)/src/libtncif \
+       -I$(top_srcdir)/src/libimcv
 
 ipseclib_LTLIBRARIES = libpts.la
 
index 944716a..365a7cb 100644 (file)
@@ -108,6 +108,7 @@ static void do_args(int argc, char *argv[])
                OP_MEASUREMENTS,
                OP_PACKAGES,
                OP_PRODUCTS,
+               OP_SESSIONS,
                OP_ADD,
                OP_DEL,
        } op = OP_UNDEF;
@@ -131,6 +132,7 @@ static void do_args(int argc, char *argv[])
                        { "products", no_argument, NULL, 'p' },
                        { "hashes", no_argument, NULL, 'H' },
                        { "measurements", no_argument, NULL, 'm' },
+                       { "sessions", no_argument, NULL, 's' },
                        { "add", no_argument, NULL, 'a' },
                        { "delete", no_argument, NULL, 'r' },
                        { "del", no_argument, NULL, 'r' },
@@ -201,6 +203,9 @@ static void do_args(int argc, char *argv[])
                        case 'm':
                                op = OP_MEASUREMENTS;
                                continue;
+                       case 's':
+                               op = OP_SESSIONS;
+                               continue;
                        case 'a':
                                op = OP_ADD;
                                continue;
@@ -408,6 +413,9 @@ static void do_args(int argc, char *argv[])
                case OP_MEASUREMENTS:
                        attest->list_measurements(attest);
                        break;
+               case OP_SESSIONS:
+                       attest->list_sessions(attest);
+                       break;
                case OP_ADD:
                        attest->add(attest);
                        break;
index 8459e2b..633d6c5 100644 (file)
  * for more details.
  */
 
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <libgen.h>
+#include <time.h>
+
 #include "attest_db.h"
 
 #include "libpts.h"
 #include "pts/pts_meas_algo.h"
 #include "pts/pts_file_meas.h"
 #include "pts/components/pts_comp_func_name.h"
-
-#include <libgen.h>
-#include <time.h>
-
 #define IMA_MAX_NAME_LEN       255
 
 typedef struct private_attest_db_t private_attest_db_t;
@@ -815,18 +817,19 @@ METHOD(attest_db_t, list_devices, void,
        u_int tstamp, flags = 0;
 
        e = this->db->query(this->db,
-                       "SELECT d.id, d.value, i.time, i.count, i.count_update, "
-                       "i.count_blacklist, i.flags, i.ar_id, p.name FROM devices AS d "
-                       "JOIN device_infos AS i ON d.id = i.device "
-                       "JOIN products AS p ON p.id = i.product "
-                       "ORDER BY d.value, i.time DESC",
-                        DB_INT, DB_BLOB, DB_UINT, DB_INT, DB_INT, DB_INT, DB_UINT,
-                        DB_INT, DB_TEXT);
+                       "SELECT d.id, d.value, s.time, s.identity, p.name, "
+                       "i.count, i.count_update, i.count_blacklist, i.flags "
+                       "FROM devices AS d "
+                       "JOIN sessions AS s ON d.id = s.device "
+                       "JOIN products AS p ON p.id = s.product "
+                       "JOIN device_infos AS i ON i.session = s.id "
+                       "ORDER BY d.value, s.time DESC", DB_INT, DB_BLOB, DB_UINT,
+                        DB_INT, DB_TEXT, DB_INT, DB_INT, DB_INT, DB_UINT);
 
        if (e)
        {
-               while (e->enumerate(e, &id, &value, &tstamp, &count, &count_update,
-                                                          &count_blacklist, &flags, &ar_id, &product))
+               while (e->enumerate(e, &id, &value, &tstamp, &ar_id, &product,
+                                                       &count, &count_update, &count_blacklist, &flags))
                {
                        if (id != last_id)
                        {
@@ -843,7 +846,7 @@ METHOD(attest_db_t, list_devices, void,
                                {
                                        chunk_free(&ar_id_value);
                                        e_ar = this->db->query(this->db,
-                                                               "SELECT type, data FROM identities "
+                                                               "SELECT type, value FROM identities "
                                                                "WHERE id = ?", DB_INT, ar_id, DB_INT, DB_BLOB);
                                        if (e_ar)
                                        {
@@ -1124,67 +1127,63 @@ METHOD(attest_db_t, list_products, void,
        printf("\n");
 }
 
-/**
- * get the directory if there is one from the files tables
- */
-static void get_directory(private_attest_db_t *this, int did, char **directory)
+METHOD(attest_db_t, list_hashes, void,
+       private_attest_db_t *this)
 {
        enumerator_t *e;
-       char *dir;
-
-       free(*directory);
-       *directory = strdup("");
+       chunk_t hash;
+       char *file, *dir, *product;
+       int id, fid, fid_old = 0, did, did_old = 0, pid, pid_old = 0, count = 0;
 
-       if (did)
+       if (this->pid && this->fid && this->did)
        {
+               printf("%4d: %s\n", this->did, this->dir);
+               printf("%4d:   %s\n", this->fid, this->file);
                e = this->db->query(this->db,
-                               "SELECT path from files WHERE id = ?",
-                               DB_UINT, did, DB_TEXT);
+                               "SELECT id, hash FROM file_hashes "
+                               "WHERE algo = ? AND file = ? AND product = ?",
+                               DB_INT, this->algo, DB_INT, this->fid, DB_INT, this->pid,
+                               DB_INT, DB_BLOB);
                if (e)
                {
-                       if (e->enumerate(e, &dir))
+                       while (e->enumerate(e, &id, &hash))
                        {
-                               free(*directory);
-                               *directory = strdup(dir);
+                               printf("%4d:     %#B\n", id, &hash);
+                               count++;
                        }
                        e->destroy(e);
+
+                       printf("%d %N value%s found for product '%s'\n", count,
+                                  pts_meas_algorithm_names, this->algo,
+                                  (count == 1) ? "" : "s", this->product);
                }
        }
-}
-
-static bool slash(char *directory, char *file)
-{
-       return *file != '/' && directory[max(0, strlen(directory)-1)] != '/';
-}
-
-METHOD(attest_db_t, list_hashes, void,
-       private_attest_db_t *this)
-{
-       enumerator_t *e;
-       chunk_t hash;
-       char *file, *dir, *product;
-       int fid, fid_old = 0, did, did_old = 0, count = 0;
-
-       dir = strdup("");
-
-       if (this->pid && this->fid & this->did)
+       else if (this->pid && this->file)
        {
                e = this->db->query(this->db,
-                               "SELECT hash FROM file_hashes "
-                               "WHERE algo = ? AND file = ? AND directory = ? AND product = ?",
-                               DB_INT, this->algo, DB_INT, this->fid, DB_INT, this->did,
-                               DB_INT, this->pid, DB_BLOB);
+                               "SELECT h.id, h.hash, f.id, d.id, d.path "
+                               "FROM file_hashes AS h "
+                               "JOIN files AS f ON h.file = f.id "
+                               "JOIN directories AS d ON f.dir = d.id "
+                               "WHERE h.algo = ? AND h.product = ? AND f.name = ? "
+                               "ORDER BY d.path, f.name, h.hash",
+                               DB_INT, this->algo, DB_INT, this->pid, DB_TEXT, this->file,
+                               DB_INT, DB_BLOB, DB_INT, DB_INT, DB_TEXT);
                if (e)
                {
-                       while (e->enumerate(e, &hash))
+                       while (e->enumerate(e, &id, &hash, &fid, &did, &dir))
                        {
-                               if (this->fid != fid_old)
+                               if (did != did_old)
                                {
-                                       printf("%4d: %s%s%s\n", this->fid, this->dir,
-                                                  slash(this->dir, this->file) ? "/" : "", this->file);
-                                       fid_old = this->fid;
+                                       printf("%4d: %s\n", did, dir);
+                                       did_old = did;
+                               }
+                               if (fid != fid_old)
+                               {
+                                       printf("%4d:   %s\n", fid, this->file);
+                                       fid_old = fid;
                                }
-                               printf("      %#B\n", &hash);
+                               printf("%4d:     %#B\n", id, &hash);
                                count++;
                        }
                        e->destroy(e);
@@ -1194,22 +1193,27 @@ METHOD(attest_db_t, list_hashes, void,
                                   (count == 1) ? "" : "s", this->product);
                }
        }
-       else if (this->pid && this->fid)
+       else if (this->pid && this->did)
        {
+               printf("%4d: %s\n", this->did, this->dir);
                e = this->db->query(this->db,
-                               "SELECT f.path, fh.hash FROM file_hashes AS fh "
-                               "JOIN files AS f ON f.id = fh.file "
-                               "WHERE algo = ? AND file = ? AND product = ?",
-                               DB_INT, this->algo, DB_INT, this->fid, DB_INT, this->pid,
-                               DB_TEXT, DB_BLOB);
+                               "SELECT h.id, h.hash, f.id, f.name "
+                               "FROM file_hashes AS h "
+                               "JOIN files AS f ON h.file = f.id "
+                               "WHERE h.algo = ? AND h.product = ? AND f.dir = ? "
+                               "ORDER BY f.name, h.hash",
+                               DB_INT, this->algo, DB_INT, this->pid, DB_INT, this->did,
+                               DB_INT, DB_BLOB, DB_INT, DB_TEXT);
                if (e)
                {
-                       free(dir);
-                       while (e->enumerate(e, &dir, &hash))
+                       while (e->enumerate(e, &id, &hash, &fid, &file))
                        {
-                               printf("%4d: %s%s%s\n", this->fid, dir,
-                                                  slash(dir, this->file) ? "/" : "", this->file);
-                               printf("      %#B\n", &hash);
+                               if (fid != fid_old)
+                               {
+                                       printf("%4d:   %s\n", fid, file);
+                                       fid_old = fid;
+                               }
+                               printf("%4d:     %#B\n", id, &hash);
                                count++;
                        }
                        e->destroy(e);
@@ -1217,35 +1221,34 @@ METHOD(attest_db_t, list_hashes, void,
                        printf("%d %N value%s found for product '%s'\n", count,
                                   pts_meas_algorithm_names, this->algo,
                                   (count == 1) ? "" : "s", this->product);
-                       dir = NULL;
                }
        }
        else if (this->pid)
        {
                e = this->db->query(this->db,
-                               "SELECT f.id, f. f.path, fh.hash, fh.directory "
-                               "FROM file_hashes AS fh "
-                               "JOIN files AS f ON f.id = fh.file "
-                               "WHERE fh.algo = ? AND fh.product = ? "
-                               "ORDER BY fh.directory, f.path",
-                               DB_INT, this->algo, DB_UINT, this->pid,
-                               DB_INT, DB_TEXT, DB_BLOB, DB_INT);
+                               "SELECT h.id, h.hash, f.id, f.name, d.id, d.path "
+                               "FROM file_hashes AS h "
+                               "JOIN files AS f ON h.file = f.id "
+                               "JOIN directories AS d ON f.dir = d.id "
+                               "WHERE h.algo = ? AND h.product = ? "
+                               "ORDER BY d.path, f.name, h.hash",
+                               DB_INT, this->algo, DB_INT, this->pid,
+                               DB_INT, DB_BLOB, DB_INT, DB_TEXT, DB_INT, DB_TEXT);
                if (e)
                {
-                       while (e->enumerate(e, &fid,  &file, &hash, &did))
+                       while (e->enumerate(e, &id, &hash, &fid, &file, &did, &dir))
                        {
-                               if (fid != fid_old || did != did_old)
+                               if (did != did_old)
                                {
-                                       if (did != did_old)
-                                       {
-                                               get_directory(this, did, &dir);
-                                       }
-                                       printf("%4d: %s%s%s\n", fid,
-                                                  dir, slash(dir, file) ? "/" : "", file);
-                                       fid_old = fid;
+                                       printf("%4d: %s\n", did, dir);
                                        did_old = did;
                                }
-                               printf("      %#B\n", &hash);
+                               if (fid != fid_old)
+                               {
+                                       printf("%4d:   %s\n", fid, file);
+                                       fid_old = fid;
+                               }
+                               printf("%4d:     %#B\n", id, &hash);
                                count++;
                        }
                        e->destroy(e);
@@ -1255,58 +1258,147 @@ METHOD(attest_db_t, list_hashes, void,
                                   (count == 1) ? "" : "s", this->product);
                }
        }
-       else if (this->fid)
+       else if (this->fid && this->did)
        {
                e = this->db->query(this->db,
-                               "SELECT p.name, fh.hash, fh.directory "
-                               "FROM file_hashes AS fh "
-                               "JOIN products AS p ON p.id = fh.product "
-                               "WHERE fh.algo = ? AND fh.file = ? AND fh.directory = ?"
-                               "ORDER BY p.name",
-                               DB_INT, this->algo, DB_UINT, this->fid, DB_UINT, this->did,
-                               DB_TEXT, DB_BLOB, DB_INT);
+                               "SELECT h.id, h.hash, p.id, p.name FROM file_hashes AS h "
+                               "JOIN products AS p ON h.product = p.id "
+                               "WHERE h.algo = ? AND h.file = ? "
+                               "ORDER BY p.name, h.hash",
+                               DB_INT, this->algo, DB_INT, this->fid,
+                               DB_INT, DB_BLOB, DB_INT, DB_TEXT);
                if (e)
                {
-                       while (e->enumerate(e, &product, &hash, &did))
+                       while (e->enumerate(e, &id, &hash, &pid, &product))
                        {
-                               printf("%#B '%s'\n", &hash, product);
+                               if (pid != pid_old)
+                               {
+                                       printf("%4d: %s\n", pid, product);
+                                       pid_old = pid;
+                               }
+                               printf("%4d:   %#B\n", id, &hash);
                                count++;
                        }
                        e->destroy(e);
 
-                       printf("%d %N value%s found for file '%s%s%s'\n",
-                                  count, pts_meas_algorithm_names, this->algo,
+                       printf("%d %N value%s found for file '%s%s%s'\n", count,
+                                  pts_meas_algorithm_names, this->algo,
                                   (count == 1) ? "" : "s", this->dir,
-                                  slash(this->dir, this->file) ? "/" : "", this->file);
+                                  streq(this->dir, "/") ? "" : "/", this->file);
+               }
+       }
+       else if (this->file)
+       {
+               e = this->db->query(this->db,
+                               "SELECT h.id, h.hash, f.id, d.id, d.path, p.id, p.name "
+                               "FROM file_hashes AS h "
+                               "JOIN files AS f ON h.file = f.id "
+                               "JOIN directories AS d ON f.dir = d.id "
+                               "JOIN products AS p ON h.product = p.id "
+                               "WHERE h.algo = ? AND f.name = ? "
+                               "ORDER BY d.path, f.name, p.name, h.hash",
+                               DB_INT, this->algo, DB_TEXT, this->file,
+                               DB_INT, DB_BLOB, DB_INT, DB_INT, DB_TEXT, DB_INT, DB_TEXT);
+               if (e)
+               {
+                       while (e->enumerate(e, &id, &hash, &fid, &did, &dir, &pid, &product))
+                       {
+                               if (did != did_old)
+                               {
+                                       printf("%4d: %s\n", did, dir);
+                                       did_old = did;
+                               }
+                               if (fid != fid_old)
+                               {
+                                       printf("%4d:   %s\n", fid, this->file);
+                                       fid_old = fid;
+                                       pid_old = 0;
+                               }
+                               if (pid != pid_old)
+                               {
+                                       printf("%4d:     %s\n", pid, product);
+                                       pid_old = pid;
+                               }
+                               printf("%4d:     %#B\n", id, &hash);
+                               count++;
+                       }
+                       e->destroy(e);
+
+                       printf("%d %N value%s found\n", count, pts_meas_algorithm_names,
+                                  this->algo, (count == 1) ? "" : "s");
+               }
+
+       }
+       else if (this->did)
+       {
+               e = this->db->query(this->db,
+                               "SELECT h.id, h.hash, f.id, f.name, p.id, p.name "
+                               "FROM file_hashes AS h "
+                               "JOIN files AS f ON h.file = f.id "
+                               "JOIN products AS p ON h.product = p.id "
+                               "WHERE h.algo = ? AND f.dir = ? "
+                               "ORDER BY f.name, p.name, h.hash",
+                               DB_INT, this->algo, DB_INT, this->did,
+                               DB_INT, DB_BLOB, DB_INT, DB_TEXT, DB_INT, DB_TEXT);
+               if (e)
+               {
+                       while (e->enumerate(e, &id, &hash, &fid, &file, &pid, &product))
+                       {
+                               if (fid != fid_old)
+                               {
+                                       printf("%4d: %s\n", fid, file);
+                                       fid_old = fid;
+                                       pid_old = 0;
+                               }
+                               if (pid != pid_old)
+                               {
+                                       printf("%4d:   %s\n", pid, product);
+                                       pid_old = pid;
+                               }
+                               printf("%4d:     %#B\n", id, &hash);
+                               count++;
+                       }
+                       e->destroy(e);
+
+                       printf("%d %N value%s found for directory '%s'\n", count,
+                                  pts_meas_algorithm_names, this->algo,
+                                  (count == 1) ? "" : "s", this->dir);
                }
        }
        else
        {
                e = this->db->query(this->db,
-                               "SELECT f.id, f.path, p.name, fh.hash, fh.directory "
-                               "FROM file_hashes AS fh "
-                               "JOIN files AS f ON f.id = fh.file "
-                               "JOIN products AS p ON p.id = fh.product "
-                               "WHERE fh.algo = ? "
-                               "ORDER BY fh.directory, f.path, p.name",
-                               DB_INT, this->algo,
-                               DB_INT, DB_TEXT, DB_TEXT, DB_BLOB, DB_INT);
+                               "SELECT h.id, h.hash, f.id, f.name, d.id, d.path, p.id, p.name "
+                               "FROM file_hashes AS h "
+                               "JOIN files AS f ON h.file = f.id "
+                               "JOIN directories AS d ON f.dir = d.id "
+                               "JOIN products AS p on h.product = p.id "
+                               "WHERE h.algo = ? "
+                               "ORDER BY d.path, f.name, p.name, h.hash",
+                               DB_INT, this->algo, DB_INT, DB_BLOB, DB_INT, DB_TEXT,
+                               DB_INT, DB_TEXT, DB_INT, DB_TEXT);
                if (e)
                {
-                       while (e->enumerate(e, &fid, &file, &product, &hash, &did))
+                       while (e->enumerate(e, &id, &hash, &fid, &file, &did, &dir, &pid,
+                                                               &product))
                        {
-                               if (fid != fid_old || did != did_old)
+                               if (did != did_old)
                                {
-                                       if (did != did_old)
-                                       {
-                                               get_directory(this, did, &dir);
-                                               did_old = did;
-                                       }
-                                       printf("%4d: %s%s%s\n", fid,
-                                                  dir, slash(dir, file) ? "/" : "", file);
+                                       printf("%4d: %s\n", did, dir);
+                                       did_old = did;
+                               }
+                               if (fid != fid_old)
+                               {
+                                       printf("%4d:   %s\n", fid, file);
                                        fid_old = fid;
+                                       pid_old = 0;
+                               }
+                               if (pid != pid_old)
+                               {
+                                       printf("%4d:     %s\n", pid, product);
+                                       pid_old = pid;
                                }
-                               printf("      %#B '%s'\n", &hash, product);
+                               printf("%4d:       %#B\n", id, &hash);
                                count++;
                        }
                        e->destroy(e);
@@ -1315,7 +1407,6 @@ METHOD(attest_db_t, list_hashes, void,
                                   this->algo, (count == 1) ? "" : "s");
                }
        }
-       free(dir);
 }
 
 METHOD(attest_db_t, list_measurements, void,
@@ -1422,9 +1513,49 @@ METHOD(attest_db_t, list_measurements, void,
        }
 }
 
-bool insert_file_hash(private_attest_db_t *this, pts_meas_algorithms_t algo,
-                                         chunk_t measurement, int fid, int did, bool ima,
-                                         int *hashes_added, int *hashes_updated)
+METHOD(attest_db_t, list_sessions, void,
+       private_attest_db_t *this)
+{
+       enumerator_t *e;
+       chunk_t device, identity;
+       char *product;
+       int session_id, conn_id;
+       time_t created;
+       u_int t;
+
+       e = this->db->query(this->db,
+                               "SELECT s.id, s.time, s.connection, p.name, d.value, i.value "
+                               "FROM sessions AS s "
+                               "LEFT JOIN products AS p ON s.product = p.id "
+                               "LEFT JOIN devices AS d ON s.device = d.id "
+                               "LEFT JOIN identities AS i ON s.identity = i.id "
+                               "ORDER BY s.time DESC",
+                                DB_INT, DB_UINT, DB_INT, DB_TEXT, DB_BLOB, DB_BLOB);
+       if (e)
+       {
+               while (e->enumerate(e, &session_id, &t, &conn_id, &product, &device,
+                                                          &identity))
+               {
+                       created = t;
+                       product = product ? product : "-";
+                       device = device.len ? device : chunk_from_str("-");
+                       device.len = min(device.len, 20);
+                       identity = identity.len ? identity : chunk_from_str("-");
+                       printf("%4d: %T %2d %-20s %.*s%*s %.*s\n", session_id, &created,
+                                  FALSE, conn_id, product, device.len, device.ptr,
+                                  20-device.len, " ", identity.len, identity.ptr);
+               }
+               e->destroy(e);
+       }
+}
+
+/**
+ * Insert a file hash into the database
+ */
+static bool insert_file_hash(private_attest_db_t *this,
+                                                        pts_meas_algorithms_t algo,
+                                                        chunk_t measurement, int fid, bool ima,
+                                                        int *hashes_added, int *hashes_updated)
 {
        enumerator_t *e;
        chunk_t hash;
@@ -1434,8 +1565,8 @@ bool insert_file_hash(private_attest_db_t *this, pts_meas_algorithms_t algo,
 
        e = this->db->query(this->db,
                "SELECT hash FROM file_hashes WHERE algo = ? "
-               "AND file = ? AND directory = ? AND product = ? and key = 0",
-               DB_INT, algo, DB_UINT, fid, DB_UINT, did, DB_UINT, this->pid, DB_BLOB);
+               "AND file = ? AND product = ? AND device = 0",
+               DB_INT, algo, DB_UINT, fid, DB_UINT, this->pid, DB_BLOB);
        if (!e)
        {
                printf("file_hashes query failed\n");
@@ -1451,8 +1582,8 @@ bool insert_file_hash(private_attest_db_t *this, pts_meas_algorithms_t algo,
                {
                        if (this->db->execute(this->db, NULL,
                                "UPDATE file_hashes SET hash = ? WHERE algo = ? "
-                               "AND file = ? AND directory = ? AND product = ? and key = 0",
-                               DB_BLOB, measurement, DB_INT, algo, DB_UINT, fid, DB_UINT, did,
+                               "AND file = ? AND product = ? and device = 0",
+                               DB_BLOB, measurement, DB_INT, algo, DB_UINT, fid,
                                DB_UINT, this->pid) == 1)
                        {
                                label = "updated";
@@ -1464,9 +1595,9 @@ bool insert_file_hash(private_attest_db_t *this, pts_meas_algorithms_t algo,
        {
                if (this->db->execute(this->db, NULL,
                        "INSERT INTO file_hashes "
-                       "(file, directory, product, key, algo, hash) "
-                       "VALUES (?, ?, ?, 0, ?, ?)",
-                       DB_UINT, fid, DB_UINT, did, DB_UINT, this->pid,
+                       "(file, product, device, algo, hash) "
+                       "VALUES (?, ?, 0, ?, ?)",
+                       DB_UINT, fid, DB_UINT, this->pid,
                        DB_INT, algo, DB_BLOB, measurement) == 1)
                {
                        label = "created";
@@ -1479,77 +1610,75 @@ bool insert_file_hash(private_attest_db_t *this, pts_meas_algorithms_t algo,
        return TRUE;
 }
 
-METHOD(attest_db_t, add, bool,
-       private_attest_db_t *this)
+/**
+ * Add hash measurement for a single file or all files in a directory
+ */
+static bool add_hash(private_attest_db_t *this)
 {
-       bool success = FALSE;
-
-       /* add key/component pair */
-       if (this->kid && this->cid)
-       {
-               success = this->db->execute(this->db, NULL,
-                                       "INSERT INTO key_component (key, component, seq_no) "
-                                       "VALUES (?, ?, ?)",
-                                       DB_UINT, this->kid, DB_UINT, this->cid,
-                                       DB_UINT, this->seq_no) == 1;
-
-               printf("key/component pair (%d/%d) %sinserted into database at "
-                          "position %d\n", this->kid, this->cid,
-                           success ? "" : "could not be ", this->seq_no);
-
-               return success;
-       }
-
-       /* add directory or file measurement for a given product */
-       if ((this->did || this->fid) && this->pid)
-       {
-               char *pathname, *filename, *label;
-               char ima_buffer[IMA_MAX_NAME_LEN + 1];
-               chunk_t measurement, ima_template;
-               pts_file_meas_t *measurements;
-               hasher_t *hasher = NULL;
-               bool ima = FALSE;
-               int fid, did;
-               int files_added = 0, hashes_added = 0, hashes_updated = 0;
-               int ima_hashes_added = 0, ima_hashes_updated = 0;
-               enumerator_t *enumerator, *e;
-
-               if (this->algo == PTS_MEAS_ALGO_SHA1_IMA)
+       char *pathname, *filename, *sep, *label, *pos;
+       char ima_buffer[IMA_MAX_NAME_LEN + 1];
+       chunk_t measurement, ima_template;
+       pts_file_meas_t *measurements;
+       hasher_t *hasher = NULL;
+       bool ima = FALSE;
+       int fid, files_added = 0, hashes_added = 0, hashes_updated = 0;
+       int len, ima_hashes_added = 0, ima_hashes_updated = 0;
+       enumerator_t *enumerator, *e;
+
+       if (this->algo == PTS_MEAS_ALGO_SHA1_IMA)
+       {
+               ima = TRUE;
+               this->algo = PTS_MEAS_ALGO_SHA1;
+               hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+               if (!hasher)
                {
-                       ima = TRUE;
-                       this->algo = PTS_MEAS_ALGO_SHA1;
-                       hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
-                       if (!hasher)
-                       {
-                               printf("could not create hasher\n");
-                               return FALSE;
-                       }
+                       printf("could not create hasher\n");
+                       return FALSE;
                }
+       }
+       sep = streq(this->dir, "/") ? "" : "/";
 
-               pathname = this->did ? this->dir : this->file;
-               measurements = pts_file_meas_create_from_path(0, pathname, this->did,
-                                                                                               this->relative, this->algo);
-               if (!measurements)
+       if (this->fid)
+       {
+               /* build pathname from directory path and relative filename */
+               if (asprintf(&pathname, "%s%s%s", this->dir, sep, this->file) == -1)
                {
-                       printf("file measurement failed\n");
-                       DESTROY_IF(hasher);
                        return FALSE;
                }
-               if (this->fid && this->relative)
+               measurements = pts_file_meas_create_from_path(0, pathname, FALSE,
+                                                                                                         TRUE, this->algo);
+               free(pathname);
+       }
+       else
+       {
+               measurements = pts_file_meas_create_from_path(0, pathname, TRUE,
+                                                                                                         TRUE, this->algo);
+       }
+       if (!measurements)
+       {
+               printf("file measurement failed\n");
+               DESTROY_IF(hasher);
+               return FALSE;
+       }
+
+       enumerator = measurements->create_enumerator(measurements);
+       while (enumerator->enumerate(enumerator, &filename, &measurement))
+       {
+               if (this->fid)
                {
-                       set_directory(this, dirname(pathname), TRUE);
+                       /* a single file already exists */
+                       filename = this->file;
+                       fid = this->fid;
+                       label = "exists";
                }
-               did = this->relative ? this->did : 0;
-
-               enumerator = measurements->create_enumerator(measurements);
-               while (enumerator->enumerate(enumerator, &filename, &measurement))
+               else
                {
                        /* retrieve or create filename */
                        label = "could not be created";
 
                        e = this->db->query(this->db,
-                               "SELECT id FROM files WHERE path = ?",
-                               DB_TEXT, filename, DB_INT);
+                               "SELECT id FROM files WHERE name = ? AND dir = ?",
+                               DB_TEXT, filename, DB_INT, this->did, DB_INT);
                        if (!e)
                        {
                                printf("files query failed\n");
@@ -1562,65 +1691,101 @@ METHOD(attest_db_t, add, bool,
                        else
                        {
                                if (this->db->execute(this->db, &fid,
-                                       "INSERT INTO files (type, path) VALUES (0, ?)",
-                                       DB_TEXT, filename) == 1)
+                                       "INSERT INTO files (name, dir) VALUES (?, ?)",
+                                       DB_TEXT, filename, DB_INT, this->did) == 1)
                                {
                                        label = "created";
                                        files_added++;
                                }
                        }
                        e->destroy(e);
+               }
+               printf("%4d: %s - %s\n", fid, filename, label);
 
-                       printf("%4d: %s - %s\n", fid, filename, label);
-
-                       /* compute file measurement hash */
-                       if (!insert_file_hash(this, this->algo, measurement,
-                                                                 fid, did, FALSE,
-                                                                 &hashes_added, &hashes_updated))
-                       {
-                               break;
-                       }
-
-                       if (!ima)
-                       {
-                               continue;
-                       }
-
-                       /* compute IMA template hash */
-                       strncpy(ima_buffer, filename, IMA_MAX_NAME_LEN);
-                       ima_buffer[IMA_MAX_NAME_LEN] = '\0';
-                       ima_template = chunk_create(ima_buffer, sizeof(ima_buffer));
-                       if (!hasher->get_hash(hasher, measurement, NULL) ||
-                               !hasher->get_hash(hasher, ima_template, measurement.ptr))
-                       {
-                               printf("could not compute IMA template hash\n");
-                               break;
-                       }
-                       if (!insert_file_hash(this, PTS_MEAS_ALGO_SHA1_IMA, measurement,
-                                                                 fid, did, TRUE,
-                                                                 &ima_hashes_added, &ima_hashes_updated))
-                       {
-                               break;
-                       }
+               /* compute file measurement hash */
+               if (!insert_file_hash(this, this->algo, measurement, fid, FALSE,
+                                                         &hashes_added, &hashes_updated))
+               {
+                       break;
+               }
+               if (!ima)
+               {
+                       continue;
                }
-               enumerator->destroy(enumerator);
 
-               printf("%d measurements, added %d new files, %d file hashes",
-                           measurements->get_file_count(measurements), files_added,
-                               hashes_added);
-               if (ima)
+               /* compute IMA template hash */
+               pos = ima_buffer;
+               len = IMA_MAX_NAME_LEN;
+               if (!this->relative)
+               {
+                       strncpy(pos, this->dir, len);
+                       len = max(0, len - strlen(this->dir));
+                       pos = ima_buffer + IMA_MAX_NAME_LEN - len;
+                       strncpy(pos, sep, len);
+                       len = max(0, len - strlen(sep));
+                       pos = ima_buffer + IMA_MAX_NAME_LEN - len;
+               }
+               strncpy(pos, filename, len);
+               ima_buffer[IMA_MAX_NAME_LEN] = '\0';
+               ima_template = chunk_create(ima_buffer, sizeof(ima_buffer));
+               if (!hasher->get_hash(hasher, measurement, NULL) ||
+                       !hasher->get_hash(hasher, ima_template, measurement.ptr))
                {
-                       printf(", %d ima hashes", ima_hashes_added);
-                       hasher->destroy(hasher);
+                       printf("could not compute IMA template hash\n");
+                       break;
                }
-               printf(", updated %d file hashes", hashes_updated);
-               if (ima)
+               if (!insert_file_hash(this, PTS_MEAS_ALGO_SHA1_IMA, measurement, fid,
+                                                         TRUE, &ima_hashes_added, &ima_hashes_updated))
                {
-                       printf(", %d ima hashes", ima_hashes_updated);
+                       break;
                }
-               printf("\n");
-               measurements->destroy(measurements);
-               success = TRUE;
+       }
+       enumerator->destroy(enumerator);
+
+       printf("%d measurements, added %d new files, %d file hashes",
+                   measurements->get_file_count(measurements), files_added,
+                       hashes_added);
+       if (ima)
+       {
+               printf(", %d ima hashes", ima_hashes_added);
+               hasher->destroy(hasher);
+       }
+       printf(", updated %d file hashes", hashes_updated);
+       if (ima)
+       {
+               printf(", %d ima hashes", ima_hashes_updated);
+       }
+       printf("\n");
+       measurements->destroy(measurements);
+
+       return TRUE;
+}
+
+METHOD(attest_db_t, add, bool,
+       private_attest_db_t *this)
+{
+       bool success = FALSE;
+
+       /* add key/component pair */
+       if (this->kid && this->cid)
+       {
+               success = this->db->execute(this->db, NULL,
+                                       "INSERT INTO key_component (key, component, seq_no) "
+                                       "VALUES (?, ?, ?)",
+                                       DB_UINT, this->kid, DB_UINT, this->cid,
+                                       DB_UINT, this->seq_no) == 1;
+
+               printf("key/component pair (%d/%d) %sinserted into database at "
+                          "position %d\n", this->kid, this->cid,
+                           success ? "" : "could not be ", this->seq_no);
+
+               return success;
+       }
+
+       /* add directory or file hash measurement for a given product */
+       if (this->did && this->pid)
+       {
+               return add_hash(this);
        }
 
        /* insert package version */
@@ -1656,13 +1821,12 @@ METHOD(attest_db_t, delete, bool,
        {
                success = this->db->execute(this->db, NULL,
                                                                "DELETE FROM file_hashes "
-                                                               "WHERE algo = ? AND product = ? "
-                                                               "AND file = ? AND directory = ?",
+                                                               "WHERE algo = ? AND product = ? AND file = ?",
                                                                DB_UINT, this->algo, DB_UINT, this->pid,
-                                                               DB_UINT, this->fid, DB_UINT, this->did) > 0;
+                                                               DB_UINT, this->fid) > 0;
 
-               printf("%4d: %s%s%s\n", this->fid, this->dir, this->did ? "/":"",
-                                                               this->file);
+               printf("%4d: %s%s%s\n", this->fid, this->dir,
+                               streq(this->dir, "/") ? "" : "/", this->file);
                printf("%N value for product '%s' %sdeleted from database\n",
                                pts_meas_algorithm_names, this->algo, this->product,
                                success ? "" : "could not be ");
@@ -1829,6 +1993,7 @@ attest_db_t *attest_db_create(char *uri)
                        .list_keys = _list_keys,
                        .list_hashes = _list_hashes,
                        .list_measurements = _list_measurements,
+                       .list_sessions = _list_sessions,
                        .add = _add,
                        .delete = _delete,
                        .destroy = _destroy,
index a110be9..0d29be9 100644 (file)
@@ -228,6 +228,11 @@ struct attest_db_t {
        void (*list_measurements)(attest_db_t *this);
 
        /**
+        * List sessions stored in the database
+        */
+       void (*list_sessions)(attest_db_t *this);
+
+       /**
         * Add an entry to the database
         */
        bool (*add)(attest_db_t *this);
index 3c5488e..fb32fcf 100644 (file)
@@ -83,7 +83,7 @@ TNC_Result TNC_IMV_Initialize(TNC_IMVID imv_id,
                                                          TNC_Version max_version,
                                                          TNC_Version *actual_version)
 {
-       char *hash_alg, *dh_group, *uri, *cadir;
+       char *hash_alg, *dh_group, *cadir;
 
        if (imv_attestation)
        {
@@ -133,10 +133,8 @@ TNC_Result TNC_IMV_Initialize(TNC_IMVID imv_id,
                pts_credmgr->add_set(pts_credmgr, pts_creds->get_set(pts_creds));
        }
 
-       /* attach file measurement database */
-       uri = lib->settings->get_str(lib->settings,
-                               "libimcv.plugins.imv-attestation.database", NULL);
-       pts_db = pts_database_create(uri);
+       /* attach PTS database co-located with IMV database */
+       pts_db = pts_database_create(imv_attestation->get_database(imv_attestation));
 
        return TNC_RESULT_SUCCESS;
 }
@@ -473,7 +471,9 @@ TNC_Result TNC_IMV_Terminate(TNC_IMVID imv_id)
                pts_creds->destroy(pts_creds);
        }
        DESTROY_IF(pts_db);
+       pts_db = NULL;
        DESTROY_IF(pts_credmgr);
+       pts_credmgr = NULL;
 
        libpts_deinit();
 
index fc42466..8f0fb36 100644 (file)
@@ -74,6 +74,11 @@ struct private_imv_attestation_state_t {
        chunk_t ar_id_value;
 
        /**
+        * Unique session ID
+        */
+       int session_id;
+
+       /**
         * IMV Attestation handshake state
         */
        imv_attestation_handshake_state_t handshake_state;
@@ -243,6 +248,18 @@ 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, change_state, void,
        private_imv_attestation_state_t *this, TNC_ConnectionState new_state)
 {
@@ -510,6 +527,8 @@ 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,
                                .change_state = _change_state,
                                .get_recommendation = _get_recommendation,
                                .set_recommendation = _set_recommendation,
index 5e9f4d7..64802c9 100644 (file)
@@ -13,7 +13,7 @@ CREATE INDEX directories_path ON directories (
 DROP TABLE IF EXISTS files;
 CREATE TABLE files (
   id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
-  dir INTEGER DEFAULT 0,
+  dir INTEGER DEFAULT 0 REFERENCES directories(id),
   name TEXT NOT NULL
 );
 DROP INDEX IF EXISTS files_name;
@@ -31,22 +31,41 @@ CREATE INDEX products_name ON products (
   name
 );
 
+DROP TABLE IF EXISTS product_file;
+CREATE TABLE product_file (
+  product INTEGER NOT NULL REFERENCES products(id),
+  file INTEGER NOT NULL REFERENCES files(id),
+  measurement INTEGER DEFAULT 0,
+  metadata INTEGER DEFAULT 0,
+  PRIMARY KEY (product, file)
+);
+
 DROP TABLE IF EXISTS algorithms;
 CREATE TABLE algorithms (
   id INTEGER PRIMARY KEY,
-  name TEXT not NULL
+  name VARCHAR(20) not NULL
 );
 
 DROP TABLE IF EXISTS file_hashes;
 CREATE TABLE file_hashes (
   id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
-  file INTEGER NOT NULL,
-  product INTEGER NOT NULL,
+  file INTEGER NOT NULL REFERENCES files(id),
+  product INTEGER NOT NULL REFERENCES products(id),
   device INTEGER DEFAULT 0,
-  algo INTEGER NOT NULL,
+  algo INTEGER NOT NULL REFERENCES algorithms(id),
   hash BLOB NOT NULL
 );
 
+DROP TABLE IF EXISTS sessions;
+CREATE TABLE sessions (
+  id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+  time INTEGER NOT NULL,
+  connection INTEGER NOT NULL,
+  identity INTEGER DEFAULT 0 REFERENCES identities(id),
+  device INTEGER DEFAULT 0 REFERENCES devices(id),
+  product INTEGER DEFAULT 0 REFERENCES products(id)
+);
+
 DROP TABLE IF EXISTS components;
 CREATE TABLE components (
   id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
@@ -118,10 +137,7 @@ CREATE INDEX devices_value ON devices (
 DROP TABLE IF EXISTS device_infos;
 CREATE TABLE device_infos (
   id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
-  device INTEGER NOT NULL,
-  time INTEGER NOT NULL,
-  ar_id INTEGER DEFAULT 0,
-  product INTEGER DEFAULT 0,
+  session INTEGER NOT NULL REFERENCES sessions(id),
   count INTEGER DEFAULT 0,
   count_update INTEGER DEFAULT 0,
   count_blacklist INTEGER DEFAULT 0,
@@ -132,6 +148,6 @@ DROP TABLE IF EXISTS identities;
 CREATE TABLE identities (
   id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
   type INTEGER NOT NULL,
-  data BLOB NOT NULL,
-  UNIQUE (type, data)
+  value BLOB NOT NULL,
+  UNIQUE (type, value)
 );
index e0778aa..561db86 100644 (file)
@@ -308,17 +308,21 @@ METHOD(pts_database_t, get_comp_measurement_count, status_t,
 METHOD(pts_database_t, destroy, void,
        private_pts_database_t *this)
 {
-       this->db->destroy(this->db);
        free(this);
 }
 
 /**
  * See header
  */
-pts_database_t *pts_database_create(char *uri)
+pts_database_t *pts_database_create(imv_database_t *imv_db)
 {
        private_pts_database_t *this;
 
+       if (!imv_db)
+       {
+               return NULL;
+       }
+
        INIT(this,
                .public = {
                        .create_file_meas_enumerator = _create_file_meas_enumerator,
@@ -333,17 +337,9 @@ pts_database_t *pts_database_create(char *uri)
                        .get_comp_measurement_count = _get_comp_measurement_count,
                        .destroy = _destroy,
                },
-               .db = lib->db->create(lib->db, uri),
+               .db = imv_db->get_database(imv_db),
        );
 
-       if (!this->db)
-       {
-               DBG1(DBG_PTS,
-                        "failed to connect to PTS file measurement database '%s'", uri);
-               free(this);
-               return NULL;
-       }
-
        return &this->public;
 }
 
index 649ef0e..6303421 100644 (file)
@@ -25,6 +25,8 @@ typedef struct pts_database_t pts_database_t;
 
 #include "pts_meas_algo.h"
 #include "components/pts_comp_func_name.h"
+
+#include <imv/imv_database.h>
 #include <library.h>
 
 /**
@@ -159,8 +161,8 @@ struct pts_database_t {
 /**
  * Creates an pts_database_t object
  *
- * @param uri                          database uri
+ * @param imv_db                       Already attached IMV database
  */
-pts_database_t* pts_database_create(char *uri);
+pts_database_t* pts_database_create(imv_database_t *imv_db);
 
 #endif /** PTS_DATABASE_H_ @}*/