From 7b6cc33eb258a0ce22687525864a4234a221ff66 Mon Sep 17 00:00:00 2001 From: Andreas Steffen Date: Wed, 28 Nov 2012 10:50:56 +0100 Subject: [PATCH] store collected device information in database --- src/libimcv/plugins/imv_os/imv_os.c | 11 +++- src/libimcv/plugins/imv_os/imv_os_database.c | 58 +++++++++++++++++++ src/libimcv/plugins/imv_os/imv_os_database.h | 12 ++++ .../plugins/imv_attestation/attest_db.c | 29 ++++++++-- .../plugins/imv_attestation/attest_usage.c | 3 + src/libpts/plugins/imv_attestation/tables.sql | 2 +- 6 files changed, 107 insertions(+), 8 deletions(-) diff --git a/src/libimcv/plugins/imv_os/imv_os.c b/src/libimcv/plugins/imv_os/imv_os.c index bf0d6f23d..16906bc35 100644 --- a/src/libimcv/plugins/imv_os/imv_os.c +++ b/src/libimcv/plugins/imv_os/imv_os.c @@ -373,7 +373,7 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg) !os_state->get_package_request(os_state) && !os_state->get_angel_count(os_state)) { - int count, count_update, count_blacklist, count_ok; + int device_id, count, count_update, count_blacklist, count_ok; os_state->get_count(os_state, &count, &count_update, &count_blacklist, &count_ok); @@ -381,6 +381,15 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg) "%d ok, %d not found", count, count_update, count_blacklist, count_ok, count - count_update - count_blacklist - count_ok); + /* Store device information in database */ + device_id = os_state->get_device_id(os_state); + if (os_db && device_id) + { + os_db->set_device_info(os_db, device_id, + os_state->get_info(os_state, NULL, NULL, NULL), + count, count_update, count_blacklist); + } + if (count_update || count_blacklist || os_state->get_os_settings(os_state)) { diff --git a/src/libimcv/plugins/imv_os/imv_os_database.c b/src/libimcv/plugins/imv_os/imv_os_database.c index 721bf619d..23164b668 100644 --- a/src/libimcv/plugins/imv_os/imv_os_database.c +++ b/src/libimcv/plugins/imv_os/imv_os_database.c @@ -213,6 +213,63 @@ METHOD(imv_os_database_t, get_device_id, int, id : 0; } +METHOD(imv_os_database_t, set_device_info, void, + private_imv_os_database_t *this, int device_id, char *os_info, + int count, int count_update, int count_blacklist) +{ + enumerator_t *e; + time_t last_time; + int pid = 0, last_pid = 0, last_count_update = 0, last_count_blacklist = 0; + 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 ifo 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 latest device info record if it exists */ + e = this->db->query(this->db, + "SELECT time, product, count_update, count_blacklist " + "FROM device_infos WHERE device = ? ORDER BY time DESC", + DB_INT, device_id, DB_UINT, DB_INT, DB_INT, DB_INT); + if (e) + { + found = e->enumerate(e, &last_time, &last_pid, &last_count_update, + &last_count_blacklist); + e->destroy(e); + } + if (found && !last_count_update && !last_count_blacklist && pid == last_pid) + { + /* update device info */ + this->db->execute(this->db, NULL, + "UPDATE device_infos SET time = ?, count = ?, count_update = ?, " + "count_blacklist = ? WHERE device = ? AND time = ?", + DB_UINT, time(NULL), DB_INT, count, DB_INT, count_update, + DB_INT, count_blacklist, DB_INT, device_id, DB_UINT, last_time); + } + else + { + /* insert device info */ + this->db->execute(this->db, NULL, + "INSERT INTO device_infos (device, time, product, " + "count, count_update, count_blacklist) VALUES (?, ?, ?, ?, ?, ?)", + DB_INT, device_id, DB_UINT, time(NULL), DB_INT, pid, + DB_INT, count, DB_INT, count_update, DB_INT, count_blacklist); + } +} + METHOD(imv_os_database_t, destroy, void, private_imv_os_database_t *this) { @@ -231,6 +288,7 @@ imv_os_database_t *imv_os_database_create(char *uri) .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), diff --git a/src/libimcv/plugins/imv_os/imv_os_database.h b/src/libimcv/plugins/imv_os/imv_os_database.h index 00b35367b..a98ecb544 100644 --- a/src/libimcv/plugins/imv_os/imv_os_database.h +++ b/src/libimcv/plugins/imv_os/imv_os_database.h @@ -49,6 +49,18 @@ struct imv_os_database_t { */ 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 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 + */ + void (*set_device_info)(imv_os_database_t *this, int device_id, char *os_info, + int count, int count_update, int count_blacklist); + /** * Destroys an imv_os_database_t object. */ diff --git a/src/libpts/plugins/imv_attestation/attest_db.c b/src/libpts/plugins/imv_attestation/attest_db.c index d01c182d6..944ed837e 100644 --- a/src/libpts/plugins/imv_attestation/attest_db.c +++ b/src/libpts/plugins/imv_attestation/attest_db.c @@ -795,19 +795,36 @@ METHOD(attest_db_t, list_devices, void, { enumerator_t *e; chunk_t value; - int id, count = 0; + char *product; + time_t timestamp; + int id, last_id = 0, device_count = 0; + int count, count_update, count_blacklist; e = this->db->query(this->db, - "SELECT id, value FROM devices", DB_INT, DB_BLOB); + "SELECT d.id, d.value, i.time, i.count, i.count_update, " + "i.count_blacklist, 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_TEXT); + if (e) { - while (e->enumerate(e, &id, &value)) + while (e->enumerate(e, &id, &value, ×tamp, &count, &count_update, + &count_blacklist, &product)) { - printf("%4d: %.*s\n", id, value.len, value.ptr); - count++; + if (id != last_id) + { + printf("%4d: %.*s\n", id, value.len, value.ptr); + device_count++; + last_id = id; + } + printf(" %T, %4d, %3d, %3d, '%s'\n", ×tamp, TRUE, + count, count_update, count_blacklist, product); } e->destroy(e); - printf("%d device%s found\n", count, (count == 1) ? "" : "s"); + printf("%d device%s found\n", device_count, + (device_count == 1) ? "" : "s"); } } diff --git a/src/libpts/plugins/imv_attestation/attest_usage.c b/src/libpts/plugins/imv_attestation/attest_usage.c index c7bf97631..df44c171c 100644 --- a/src/libpts/plugins/imv_attestation/attest_usage.c +++ b/src/libpts/plugins/imv_attestation/attest_usage.c @@ -64,6 +64,9 @@ Usage:\n\ Show a list of software packages for a given product or\n\ its primary key as an optional selector.\n\ \n\ + ipsec attest --devices\n\ + Show a list of registered devices and associated collected information\n\ + \n\ ipsec attest --add --file |--dir |--product |--component \n\ Add a file, directory, product or component entry\n\ Component entries must be of the form /-\n\ diff --git a/src/libpts/plugins/imv_attestation/tables.sql b/src/libpts/plugins/imv_attestation/tables.sql index e17318b22..8a79ea7cf 100644 --- a/src/libpts/plugins/imv_attestation/tables.sql +++ b/src/libpts/plugins/imv_attestation/tables.sql @@ -131,7 +131,7 @@ CREATE TABLE device_infos ( product INTEGER DEFAULT 0, count INTEGER DEFAULT 0, count_update INTEGER DEFAULT 0, - count_remove INTEGER DEFAULT 0, + count_blacklist INTEGER DEFAULT 0, flags INTEGER DEFAULT 0, PRIMARY KEY (device, time) );