store unique device_id in database
authorAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 27 Nov 2012 22:48:40 +0000 (23:48 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 27 Nov 2012 22:48:40 +0000 (23:48 +0100)
src/libimcv/ita/ita_attr_settings.c
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_os/imv_os_state.h
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/attest_usage.c
src/libpts/plugins/imv_attestation/tables.sql

index be8cc2d..7941cf6 100644 (file)
@@ -198,6 +198,11 @@ METHOD(pa_tnc_attr_t, process, status_t,
                }
                *offset += 2 + value.len;
 
+               /* remove a terminating newline character */
+               if (value.len && value.ptr[value.len - 1] == '\n')
+               {
+                       value.len--;
+               }
                entry = malloc_thing(entry_t);
                entry->name = strndup(name.ptr, name.len);
                entry->value = chunk_clone(value);
index 7ec7d34..bf0d6f2 100644 (file)
@@ -122,23 +122,6 @@ TNC_Result TNC_IMV_NotifyConnectionChange(TNC_IMVID imv_id,
        }
 }
 
-/**
- * print multi-line values to debug output
- */
-static void dbg_imv_multi_line(chunk_t value)
-{
-       chunk_t line;
-
-       while (extract_token(&line, '\n', &value))
-       {
-               DBG2(DBG_IMV, "  %.*s", line.len, line.ptr);
-       }
-       if (value.len)
-       {
-               DBG2(DBG_IMV, "  %.*s", value.len, value.ptr);
-       }
-}
-
 static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg)
 {
        imv_msg_t *out_msg;
@@ -151,6 +134,8 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg)
        chunk_t os_version = chunk_empty;
        bool fatal_error = FALSE, assessment = FALSE;
        char non_market_apps_str[] = "install_non_market_apps";
+       char android_id_str[] = "android_id";
+       char machine_id_str[] = "/var/lib/dbus/machine-id";
 
        os_state = (imv_os_state_t*)state;
 
@@ -318,8 +303,14 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg)
                                                        os_state->set_os_settings(os_state,
                                                                                                OS_SETTINGS_NON_MARKET_APPS);
                                                }
-                                               DBG1(DBG_IMV, "setting '%s'", name);
-                                               dbg_imv_multi_line(value);
+                                               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));
+                                               }
+                                               DBG1(DBG_IMV, "setting '%s'\n  %.*s",
+                                                        name, value.len, value.ptr);
                                        }
                                        e->destroy(e);
                                        break;
@@ -358,12 +349,12 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg)
 
                if (os_type == OS_TYPE_ANDROID)
                {
-                       attr_cast->add(attr_cast, "android_id");
+                       attr_cast->add(attr_cast, android_id_str);
                        attr_cast->add(attr_cast, non_market_apps_str);
                }
                else
                {
-                       attr_cast->add(attr_cast, "/proc/sys/kernel/random/boot_id");
+                       attr_cast->add(attr_cast, machine_id_str);
                        attr_cast->add(attr_cast, "/proc/sys/kernel/tainted");
                }
                out_msg->add_attribute(out_msg, attr);
index 9b0cdc0..721bf61 100644 (file)
@@ -187,6 +187,32 @@ 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;
+       }
+
+       /* 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, destroy, void,
        private_imv_os_database_t *this)
 {
@@ -204,6 +230,7 @@ imv_os_database_t *imv_os_database_create(char *uri)
        INIT(this,
                .public = {
                        .check_packages = _check_packages,
+                       .get_device_id = _get_device_id,
                        .destroy = _destroy,
                },
                .db = lib->db->create(lib->db, uri),
index b5c6037..00b3536 100644 (file)
@@ -43,6 +43,13 @@ 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);
+
+       /**
        * Destroys an imv_os_database_t object.
        */
        void (*destroy)(imv_os_database_t *this);
index 4179233..f169836 100644 (file)
@@ -112,6 +112,11 @@ struct private_imv_os_state_t {
        imv_remediation_string_t *remediation_string;
 
        /**
+        * Primary database key of device ID
+        */
+       int device_id;
+
+       /**
         * Number of processed packages
         */
        int count;
@@ -179,7 +184,7 @@ static imv_lang_string_t reason_packages[] = {
 static imv_lang_string_t instr_update_packages_title[] = {
        { "en", "Software Security Updates" },
        { "de", "Software Sicherheitsupdates" },
-       { "pl", "aktualizacja softwaru zabezpieczajÄ…cego" },
+       { "pl", "Aktualizacja softwaru zabezpieczajÄ…cego" },
        { NULL, NULL }
 };
 
@@ -513,6 +518,18 @@ METHOD(imv_os_state_t, get_package_request, bool,
        return this->package_request;
 }
 
+METHOD(imv_os_state_t, set_device_id, void,
+       private_imv_os_state_t *this, int id)
+{
+       this->device_id = id;
+}
+
+METHOD(imv_os_state_t, get_device_id, int,
+       private_imv_os_state_t *this)
+{
+       return this->device_id;
+}
+
 METHOD(imv_os_state_t, set_os_settings, void,
        private_imv_os_state_t *this, u_int settings)
 {
@@ -582,6 +599,8 @@ imv_state_t *imv_os_state_create(TNC_ConnectionID connection_id)
                        .get_count = _get_count,
                        .set_package_request = _set_package_request,
                        .get_package_request = _get_package_request,
+                       .set_device_id = _set_device_id,
+                       .get_device_id = _get_device_id,
                        .set_os_settings = _set_os_settings,
                        .get_os_settings = _get_os_settings,
                        .set_angel_count = _set_angel_count,
index 29a851b..05abdbb 100644 (file)
@@ -102,6 +102,20 @@ struct imv_os_state_t {
        bool (*get_package_request)(imv_os_state_t *this);
 
        /**
+        * Set device ID
+        *
+        * @param device_id             Device ID primary database key
+        */
+       void (*set_device_id)(imv_os_state_t *this, int id);
+
+       /**
+        * Get device ID
+        *
+        * @return                              Device ID primary database key
+        */
+       int (*get_device_id)(imv_os_state_t *this);
+
+       /**
         * Set OS settings
         *
         * @param settings              OS settings
index 281078a..5cfc073 100644 (file)
@@ -99,6 +99,7 @@ static void do_args(int argc, char *argv[])
                OP_USAGE,
                OP_KEYS,
                OP_COMPONENTS,
+               OP_DEVICES,
                OP_FILES,
                OP_HASHES,
                OP_MEASUREMENTS,
@@ -118,6 +119,7 @@ static void do_args(int argc, char *argv[])
                struct option long_opts[] = {
                        { "help", no_argument, NULL, 'h' },
                        { "components", no_argument, NULL, 'c' },
+                       { "devices", no_argument, NULL, 'e' },
                        { "files", no_argument, NULL, 'f' },
                        { "keys", no_argument, NULL, 'k' },
                        { "packages", no_argument, NULL, 'g' },
@@ -168,6 +170,9 @@ static void do_args(int argc, char *argv[])
                        case 'c':
                                op = OP_COMPONENTS;
                                continue;
+                       case 'e':
+                               op = OP_DEVICES;
+                               continue;
                        case 'f':
                                op = OP_FILES;
                                continue;
@@ -360,6 +365,9 @@ static void do_args(int argc, char *argv[])
                case OP_COMPONENTS:
                        attest->list_components(attest);
                        break;
+               case OP_DEVICES:
+                       attest->list_devices(attest);
+                       break;
                case OP_FILES:
                        attest->list_files(attest);
                        break;
index 8e64d0a..d01c182 100644 (file)
@@ -790,6 +790,27 @@ METHOD(attest_db_t, list_components, void,
        }
 }
 
+METHOD(attest_db_t, list_devices, void,
+       private_attest_db_t *this)
+{
+       enumerator_t *e;
+       chunk_t value;
+       int id, count = 0;
+
+       e = this->db->query(this->db,
+                                               "SELECT id, value FROM devices", DB_INT, DB_BLOB);
+       if (e)
+       {
+               while (e->enumerate(e,  &id, &value))
+               {
+                       printf("%4d: %.*s\n", id, value.len, value.ptr);
+                       count++;
+               }
+               e->destroy(e);
+               printf("%d device%s found\n", count, (count == 1) ? "" : "s");
+       }
+}
+
 METHOD(attest_db_t, list_keys, void,
        private_attest_db_t *this)
 {
@@ -1660,6 +1681,7 @@ attest_db_t *attest_db_create(char *uri)
                        .list_products = _list_products,
                        .list_files = _list_files,
                        .list_components = _list_components,
+                       .list_devices = _list_devices,
                        .list_keys = _list_keys,
                        .list_hashes = _list_hashes,
                        .list_measurements = _list_measurements,
index 81dd0ad..471b0a2 100644 (file)
@@ -199,6 +199,11 @@ struct attest_db_t {
        void (*list_components)(attest_db_t *this);
 
        /**
+        * List all devices stored in the database
+        */
+       void (*list_devices)(attest_db_t *this);
+
+       /**
         * List all AIKs stored in the database
         */
        void (*list_keys)(attest_db_t *this);
index f7040f7..c7bf976 100644 (file)
@@ -60,6 +60,10 @@ Usage:\n\
     Show a list of component measurements for a given AIK or\n\
     its primary key as an optional selector.\n\
   \n\
+  ipsec attest --packages [--product <name>|--pid <id>]\n\
+    Show a list of software packages for a given product or\n\
+    its primary key as an optional selector.\n\
+  \n\
   ipsec attest --add --file <path>|--dir <path>|--product <name>|--component <cfn>\n\
     Add a file, directory, product or component entry\n\
     Component <cfn> entries must be of the form <vendor_id>/<name>-<qualifier>\n\
@@ -74,6 +78,10 @@ Usage:\n\
   ipsec attest --add --key <digest|--kid <id> --component <cfn>|--cid <id> --sequence <no>|--seq <no>\n\
     Add an ordered key/component entry\n\
   \n\
+  ipsec attest --add --package <name> --version <string> [--security|--blacklist]\n\
+              [--product <name>|--pid <id>]\n\
+    Add a package version for a given product optionally with security or blacklist flag\n\
+  \n\
   ipsec attest --del --file <path>|--fid <id>|--dir <path>|--did <id>\n\
     Delete a file or directory entry referenced either by value or primary key\n\
   \n\
index 51d6cfa..e17318b 100644 (file)
@@ -113,3 +113,26 @@ DROP INDEX IF EXISTS versions_package_product;
 CREATE INDEX versions_package_product ON versions (
   package, product
 );
+
+DROP TABLE IF EXISTS devices;
+CREATE TABLE devices (
+  id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+  value BLOB NOT NULL
+);
+DROP INDEX IF EXISTS devices_id;
+CREATE INDEX devices_value ON devices (
+  value
+);
+
+DROP TABLE IF EXISTS device_infos;
+CREATE TABLE device_infos (
+  device INTEGER NOT NULL,
+  time INTEGER NOT NULL,
+  product INTEGER DEFAULT 0,
+  count INTEGER DEFAULT 0,
+  count_update INTEGER DEFAULT 0,
+  count_remove INTEGER DEFAULT 0,
+  flags INTEGER DEFAULT 0,
+  PRIMARY KEY (device, time)
+);
+