diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2017-07-16 09:52:52 +0200 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2017-07-18 07:25:45 +0200 |
commit | 964bf73237a6729e5c559eeb698884f64b72548f (patch) | |
tree | 9bc1ba09efef89d82e86978a33d77821c1226f56 /src/libimcv/plugins/imc_swima | |
parent | 34cade8b845b964d847f579cd76734a8c2146af0 (diff) | |
download | strongswan-964bf73237a6729e5c559eeb698884f64b72548f.tar.bz2 strongswan-964bf73237a6729e5c559eeb698884f64b72548f.tar.xz |
sw-collector: Moved to its own directory and added man page
Diffstat (limited to 'src/libimcv/plugins/imc_swima')
13 files changed, 1 insertions, 2518 deletions
diff --git a/src/libimcv/plugins/imc_swima/Makefile.am b/src/libimcv/plugins/imc_swima/Makefile.am index e14556c62..4a29e7949 100644 --- a/src/libimcv/plugins/imc_swima/Makefile.am +++ b/src/libimcv/plugins/imc_swima/Makefile.am @@ -19,8 +19,7 @@ $(swid_tag) : $(regid)__strongSwan.swidtag.in AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ -I$(top_srcdir)/src/libtncif \ - -I$(top_srcdir)/src/libimcv \ - -DPLUGINS=\""random openssl sqlite curl"\" + -I$(top_srcdir)/src/libimcv AM_CFLAGS = \ $(PLUGIN_CFLAGS) $(json_CFLAGS) @@ -32,23 +31,3 @@ imc_swima_la_LIBADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la imc_swima_la_SOURCES = imc_swima.c imc_swima_state.h imc_swima_state.c imc_swima_la_LDFLAGS = -module -avoid-version -no-undefined - -ipsec_PROGRAMS = sw-collector -sw_collector_SOURCES = \ - sw_collector/sw-collector.c \ - sw_collector/sw_collector_db.h sw_collector/sw_collector_db.c \ - sw_collector/sw_collector_dpkg.h sw_collector/sw_collector_dpkg.c \ - sw_collector/sw_collector_history.h sw_collector/sw_collector_history.c \ - sw_collector/sw_collector_info.h sw_collector/sw_collector_info.c \ - sw_collector/sw_collector_rest_api.h sw_collector/sw_collector_rest_api.c - -sw_collector_LDADD = \ - $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libimcv/libimcv.la \ - $(json_LIBS) - -sw-collector.o : $(top_builddir)/config.status - -templatesdir = $(pkgdatadir)/templates/database/sw-collector -dist_templates_DATA = sw_collector/sw_collector_tables.sql - diff --git a/src/libimcv/plugins/imc_swima/sw_collector/sw-collector.c b/src/libimcv/plugins/imc_swima/sw_collector/sw-collector.c deleted file mode 100644 index d76f75161..000000000 --- a/src/libimcv/plugins/imc_swima/sw_collector/sw-collector.c +++ /dev/null @@ -1,632 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -#define _GNU_SOURCE -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <getopt.h> -#include <unistd.h> -#ifdef HAVE_SYSLOG -# include <syslog.h> -#endif - -#include "sw_collector_info.h" -#include "sw_collector_db.h" -#include "sw_collector_history.h" -#include "sw_collector_rest_api.h" -#include "sw_collector_dpkg.h" -# -#include <library.h> -#include <utils/debug.h> -#include <utils/lexparser.h> - -#include <imv/imv_os_info.h> - -/** - * global debug output variables - */ -static int debug_level = 2; -static bool stderr_quiet = FALSE; -static int count = 0; - -typedef enum collector_op_t collector_op_t; - -enum collector_op_t { - COLLECTOR_OP_EXTRACT, - COLLECTOR_OP_LIST, - COLLECTOR_OP_UNREGISTERED, - COLLECTOR_OP_GENERATE, - COLLECTOR_OP_MIGRATE -}; - -/** - * sw_collector dbg function - */ -static void sw_collector_dbg(debug_t group, level_t level, char *fmt, ...) -{ - va_list args; - - if (level <= debug_level) - { - if (!stderr_quiet) - { - va_start(args, fmt); - vfprintf(stderr, fmt, args); - fprintf(stderr, "\n"); - va_end(args); - } - -#ifdef HAVE_SYSLOG - { - int priority = LOG_INFO; - char buffer[8192]; - char *current = buffer, *next; - - /* write in memory buffer first */ - va_start(args, fmt); - vsnprintf(buffer, sizeof(buffer), fmt, args); - va_end(args); - - /* do a syslog with every line */ - while (current) - { - next = strchr(current, '\n'); - if (next) - { - *(next++) = '\0'; - } - syslog(priority, "%s\n", current); - current = next; - } - } -#endif /* HAVE_SYSLOG */ - } -} - -/** - * atexit handler - */ -static void cleanup(void) -{ - library_deinit(); -#ifdef HAVE_SYSLOG - closelog(); -#endif -} - -/** - * Display usage of sw-collector command - */ -static void usage(void) -{ - printf("\ -Usage:\n\ - sw-collector --help\n\ - sw-collector [--debug <level>] [--quiet] [--count <event count>]\n\ - sw-collector [--debug <level>] [--quiet] --list|-unregistered\n\ - sw-collector [--debug <level>] [--quiet] ---generate|--migrate\n"); -} - -/** - * Parse command line options - */ -static collector_op_t do_args(int argc, char *argv[]) -{ - collector_op_t op = COLLECTOR_OP_EXTRACT; - - /* reinit getopt state */ - optind = 0; - - while (TRUE) - { - int c; - - struct option long_opts[] = { - { "help", no_argument, NULL, 'h' }, - { "count", required_argument, NULL, 'c' }, - { "debug", required_argument, NULL, 'd' }, - { "generate", no_argument, NULL, 'g' }, - { "list", no_argument, NULL, 'l' }, - { "migrate", no_argument, NULL, 'm' }, - { "quiet", no_argument, NULL, 'q' }, - { "unregistered", no_argument, NULL, 'u' }, - { 0,0,0,0 } - }; - - c = getopt_long(argc, argv, "hc:d:lmqu", long_opts, NULL); - switch (c) - { - case EOF: - break; - case 'h': - usage(); - exit(SUCCESS); - break; - case 'c': - count = atoi(optarg); - continue; - case 'd': - debug_level = atoi(optarg); - continue; - case 'g': - op = COLLECTOR_OP_GENERATE; - continue; - case 'l': - op = COLLECTOR_OP_LIST; - continue; - case 'm': - op = COLLECTOR_OP_MIGRATE; - continue; - case 'q': - stderr_quiet = TRUE; - continue; - case 'u': - op = COLLECTOR_OP_UNREGISTERED; - continue; - default: - usage(); - exit(EXIT_FAILURE); - } - break; - } - return op; -} - -/** - * Extract software events from apt history log files - */ -static int extract_history(sw_collector_info_t *info, sw_collector_db_t *db) -{ - sw_collector_history_t *history = NULL; - uint32_t epoch, last_eid, eid = 0; - char *history_path, *os, *last_time = NULL, rfc_time[21]; - chunk_t *h, history_chunk, line, cmd; - os_type_t os_type; - int status = EXIT_FAILURE; - bool skip = TRUE; - - /* check if OS supports apg/dpkg history logs */ - info->get_os(info, &os); - os_type = info->get_os_type(info); - - if (os_type != OS_TYPE_DEBIAN && os_type != OS_TYPE_UBUNTU) - { - DBG1(DBG_IMC, "%.*s not supported", os); - return EXIT_FAILURE; - } - - /* open history file for reading */ - history_path= lib->settings->get_str(lib->settings, "%s.history", NULL, - lib->ns); - if (!history_path) - { - fprintf(stderr, "sw-collector.history path not set.\n"); - return EXIT_FAILURE; - } - h = chunk_map(history_path, FALSE); - if (!h) - { - fprintf(stderr, "opening '%s' failed: %s", history, strerror(errno)); - return EXIT_FAILURE; - } - history_chunk = *h; - - /* Instantiate history extractor */ - history = sw_collector_history_create(info, db, 1); - - /* retrieve last event in database */ - if (!db->get_last_event(db, &last_eid, &epoch, &last_time) || !last_eid) - { - goto end; - } - DBG0(DBG_IMC, "Last-Event: %s, eid = %u, epoch = %u", - last_time, last_eid, epoch); - - /* parse history file */ - while (fetchline(&history_chunk, &line)) - { - if (line.len == 0) - { - continue; - } - if (!extract_token(&cmd, ':', &line)) - { - fprintf(stderr, "terminator symbol ':' not found.\n"); - goto end; - } - if (match("Start-Date", &cmd)) - { - if (!history->extract_timestamp(history, line, rfc_time)) - { - goto end; - } - - /* have we reached new history entries? */ - if (skip && strcmp(rfc_time, last_time) > 0) - { - skip = FALSE; - } - if (skip) - { - continue; - } - - /* insert new event into database */ - eid = db->add_event(db, rfc_time); - if (!eid) - { - goto end; - } - DBG1(DBG_IMC, "Start-Date: %s, eid = %u, epoch = %u", - rfc_time, eid, epoch); - } - else if (skip) - { - /* skip old history entries which have already been processed */ - continue; - } - else if (match("Install", &cmd)) - { - DBG1(DBG_IMC, " Install:"); - if (!history->extract_packages(history, line, eid, SW_OP_INSTALL)) - { - goto end; - } - } - else if (match("Upgrade", &cmd)) - { - DBG1(DBG_IMC, " Upgrade:"); - if (!history->extract_packages(history, line, eid, SW_OP_UPGRADE)) - { - goto end; - } - } - else if (match("Remove", &cmd)) - { - DBG1(DBG_IMC, " Remove:"); - if (!history->extract_packages(history, line, eid, SW_OP_REMOVE)) - { - goto end; - } - } - else if (match("Purge", &cmd)) - { - DBG1(DBG_IMC, " Purge:"); - if (!history->extract_packages(history, line, eid, SW_OP_REMOVE)) - { - goto end; - } - } - else if (match("End-Date", &cmd)) - { - /* Process 'count' events at a time */ - if (count > 0 && eid - last_eid == count) - { - fprintf(stderr, "added %d events\n", count); - goto end; - } - } - } - - if (history->merge_installed_packages(history)) - { - status = EXIT_SUCCESS; - } - -end: - free(last_time); - history->destroy(history); - chunk_unmap(h); - - return status; -} - -/** - * List all endpoint software identifiers stored in local collector database - */ -static int list_identifiers(sw_collector_db_t *db) -{ - enumerator_t *e; - char *name, *package, *version; - uint32_t sw_id, count = 0, installed_count = 0, installed; - - e = db->create_sw_enumerator(db, SW_QUERY_ALL, NULL); - if (!e) - { - return EXIT_FAILURE; - } - while (e->enumerate(e, &sw_id, &name, &package, &version, &installed)) - { - printf("%s,%s,%s,%d\n", name, package, version, installed); - if (installed) - { - installed_count++; - } - count++; - } - e->destroy(e); - DBG1(DBG_IMC, "retrieved %u software identities with %u installed and %u " - "deleted", count, installed_count, count - installed_count); - - return EXIT_SUCCESS; -} - -static bool query_registry(sw_collector_rest_api_t *rest_api, bool installed) -{ - sw_collector_db_query_t type; - enumerator_t *enumerator; - char *sw_id; - int count = 0; - - type = installed ? SW_QUERY_INSTALLED : SW_QUERY_DELETED; - enumerator = rest_api->create_sw_enumerator(rest_api, type); - if (!enumerator) - { - return FALSE; - } - while (enumerator->enumerate(enumerator, &sw_id)) - { - printf("%s,%s\n", sw_id, installed ? "1" : "0"); - count++; - } - enumerator->destroy(enumerator); - DBG1(DBG_IMC, "%d %s software identifiers not registered", count, - installed ? "installed" : "deleted"); - return TRUE; -} - - -/** - * List all endpoint software identifiers stored in local collector database - * that are not registered yet in central collelector database - */ -static int unregistered_identifiers(sw_collector_db_t *db) -{ - sw_collector_rest_api_t *rest_api; - int status = EXIT_SUCCESS; - - rest_api = sw_collector_rest_api_create(db); - if (!rest_api) - { - return EXIT_FAILURE; - } - - /* List installed software identifiers not registered centrally */ - if (!query_registry(rest_api, TRUE)) - { - status = EXIT_FAILURE; - } - - /* List deleted software identifiers not registered centrally */ - if (!query_registry(rest_api, FALSE)) - { - status = EXIT_FAILURE; - } - rest_api->destroy(rest_api); - - return status; -} - -/** - * Generate a minimalistic ISO 19770-2:2015 SWID tag - */ -static char* generate_tag(char *name, char *package, char *version, - char* entity, char *regid, char *product) -{ - char *tag_id, *tag; - int res; - - tag_id = strstr(name, "__"); - if (!tag_id) - { - return NULL; - } - tag_id += 2; - - res = asprintf(&tag, "<?xml version=\"1.0\" encoding=\"utf-8\"?>" - "<SoftwareIdentity name=\"%s\" tagId=\"%s\" version=\"%s\" " - "versionScheme=\"alphanumeric\" " - "xmlns=\"http://standards.iso.org/iso/19770/-2/2015/schema.xsd\">" - "<Entity name=\"%s\" regid=\"%s\" role=\"tagCreator\"/>" - "<Meta product=\"%s\"/>" - "</SoftwareIdentity>", - package, tag_id, version, entity, regid, product); - - return (res == -1) ? NULL : tag; -} - -/** - * Generate a minimalistic ISO 19770-2:2015 SWID tag for - * all deleted SW identifiers that are not registered centrally - */ -static int generate_tags(sw_collector_info_t *info, sw_collector_db_t *db) -{ - sw_collector_rest_api_t *rest_api; - char *pos, *name, *package, *version, *entity, *regid, *product, *tag; - enumerator_t *enumerator; - uint32_t sw_id; - int status = EXIT_FAILURE; - - entity = lib->settings->get_str(lib->settings, "%s.tag_creator.name", - "strongSwan Project", lib->ns); - regid = lib->settings->get_str(lib->settings, "%s.tag_creator.regid", - "strongswan.org", lib->ns); - info->get_os(info, &product); - - rest_api = sw_collector_rest_api_create(db); - if (!rest_api) - { - goto end; - } - - enumerator = rest_api->create_sw_enumerator(rest_api, SW_QUERY_DELETED); - if (!enumerator) - { - goto end; - } - while (enumerator->enumerate(enumerator, &name)) - { - sw_id = db->get_sw_id(db, name, &package, &version, NULL, NULL); - if (sw_id) - { - /* Remove architecture from package name */ - pos = strchr(package, ':'); - if (pos) - { - *pos = '\0'; - } - tag = generate_tag(name, package, version, entity, regid, product); - if (tag) - { - printf("%s\n", tag); - free(tag); - count++; - } - free(package); - free(version); - } - } - enumerator->destroy(enumerator); - status = EXIT_SUCCESS; - DBG1(DBG_IMC, "%d tags for deleted unregistered software identifiers", - count); - -end: - DESTROY_IF(rest_api); - - return status; -} - -/** - * Append missing architecture suffix to package entries in the database - */ -static int migrate(sw_collector_info_t *info, sw_collector_db_t *db) -{ - sw_collector_dpkg_t *dpkg; - - char *package, *arch, *version; - char package_filter[BUF_LEN]; - int res, count = 0; - int status = EXIT_SUCCESS; - enumerator_t *enumerator; - - dpkg = sw_collector_dpkg_create(); - if (!dpkg) - { - return FAILED; - } - - enumerator = dpkg->create_sw_enumerator(dpkg); - while (enumerator->enumerate(enumerator, &package, &arch, &version)) - { - - /* Look for package names with architecture suffix */ - snprintf(package_filter, BUF_LEN, "%s:%%", package); - - res = db->update_package(db, package_filter, package); - if (res < 0) - { - status = EXIT_FAILURE; - break; - } - else if (res > 0) - { - count += res; - DBG2(DBG_IMC, "%s: removed arch suffix %d times", package, res); - } - } - enumerator->destroy(enumerator); - dpkg->destroy(dpkg); - - DBG1(DBG_IMC, "migrated %d sw identifier records", count); - - return status; -} - - -int main(int argc, char *argv[]) -{ - sw_collector_db_t *db = NULL; - sw_collector_info_t *info; - collector_op_t op; - char *uri, *tag_creator; - int status = EXIT_FAILURE; - - op = do_args(argc, argv); - - /* enable sw_collector debugging hook */ - dbg = sw_collector_dbg; -#ifdef HAVE_SYSLOG - openlog("sw-collector", 0, LOG_DEBUG); -#endif - - atexit(cleanup); - - /* initialize library */ - if (!library_init(NULL, "sw-collector")) - { - exit(SS_RC_LIBSTRONGSWAN_INTEGRITY); - } - - /* load sw-collector plugins */ - if (!lib->plugins->load(lib->plugins, - lib->settings->get_str(lib->settings, "%s.load", PLUGINS, lib->ns))) - { - exit(SS_RC_INITIALIZATION_FAILED); - } - - /* connect to sw-collector database */ - uri = lib->settings->get_str(lib->settings, "%s.database", NULL, lib->ns); - if (!uri) - { - fprintf(stderr, "sw-collector.database URI not set.\n"); - exit(EXIT_FAILURE); - } - db = sw_collector_db_create(uri); - if (!db) - { - fprintf(stderr, "connection to sw-collector database failed.\n"); - exit(EXIT_FAILURE); - } - - /* Attach OS info */ - tag_creator = lib->settings->get_str(lib->settings, "%s.tag_creator.regid", - "strongswan.org", lib->ns); - info = sw_collector_info_create(tag_creator); - - switch (op) - { - case COLLECTOR_OP_EXTRACT: - status = extract_history(info, db); - break; - case COLLECTOR_OP_LIST: - status = list_identifiers(db); - break; - case COLLECTOR_OP_UNREGISTERED: - status = unregistered_identifiers(db); - break; - case COLLECTOR_OP_GENERATE: - status = generate_tags(info, db); - break; - case COLLECTOR_OP_MIGRATE: - status = migrate(info, db); - break; - } - db->destroy(db); - info->destroy(info); - - exit(status); -} diff --git a/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_db.c b/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_db.c deleted file mode 100644 index 6f14818e6..000000000 --- a/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_db.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * Copyright (C) 2017 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 "sw_collector_db.h" - -#include "swima/swima_event.h" - -typedef struct private_sw_collector_db_t private_sw_collector_db_t; - -/** - * Private data of an sw_collector_db_t object. - */ -struct private_sw_collector_db_t { - - /** - * Public members of sw_collector_db_state_t - */ - sw_collector_db_t public; - - /** - * Epoch - */ - uint32_t epoch; - - /** - * Event ID of last event stored in database - */ - uint32_t last_eid; - - /** - * Software collector database - */ - database_t *db; - -}; - -METHOD(sw_collector_db_t, add_event, uint32_t, - private_sw_collector_db_t *this, char *timestamp) -{ - uint32_t eid = 0; - - if (this->db->execute(this->db, &eid, - "INSERT INTO events (epoch, timestamp) VALUES (?, ?)", - DB_UINT, this->epoch, DB_TEXT, timestamp) != 1) - { - DBG1(DBG_IMC, "unable to insert event into database"); - return 0; - } - - return eid; -} - -METHOD(sw_collector_db_t, get_last_event, bool, - private_sw_collector_db_t *this, uint32_t *eid, uint32_t *epoch, - char **last_time) -{ - char *timestamp; - enumerator_t *e; - - e = this->db->query(this->db, - "SELECT id, epoch, timestamp FROM events ORDER BY timestamp DESC", - DB_UINT, DB_UINT, DB_TEXT); - if (!e) - { - DBG1(DBG_IMC, "database query for event failed"); - return FALSE; - } - if (e->enumerate(e, eid, epoch, ×tamp)) - { - if (last_time) - { - *last_time = strdup(timestamp); - } - } - else - { - *eid = 0; - } - e->destroy(e); - - return TRUE; -} - -METHOD(sw_collector_db_t, add_sw_event, bool, - private_sw_collector_db_t *this, uint32_t eid, uint32_t sw_id, - uint8_t action) -{ - if (this->db->execute(this->db, NULL, - "INSERT INTO sw_events (eid, sw_id, action) VALUES (?, ?, ?)", - DB_UINT, eid, DB_UINT, sw_id, DB_UINT, action) != 1) - { - DBG1(DBG_IMC, "unable to insert sw_event into database"); - return FALSE; - } - - return TRUE; -} - -METHOD(sw_collector_db_t, set_sw_id, uint32_t, - private_sw_collector_db_t *this, char *name, char *package, char *version, - uint8_t source, bool installed) -{ - uint32_t sw_id; - - if (this->db->execute(this->db, &sw_id, - "INSERT INTO sw_identifiers " - "(name, package, version, source, installed) VALUES (?, ?, ?, ?, ?)", - DB_TEXT, name, DB_TEXT, package, DB_TEXT, version, DB_UINT, source, - DB_UINT, installed) != 1) - { - DBG1(DBG_IMC, "unable to insert sw_id into database"); - return 0; - } - - return sw_id; -} - -METHOD(sw_collector_db_t, get_sw_id, uint32_t, - private_sw_collector_db_t *this, char *name, char **package, char **version, - uint8_t *source, bool *installed) -{ - char *sw_package, *sw_version; - uint32_t sw_id = 0, sw_source, sw_installed; - enumerator_t *e; - - /* Does software identifier already exist in database? */ - e = this->db->query(this->db, - "SELECT id, package, version, source, installed " - "FROM sw_identifiers WHERE name = ?", - DB_TEXT, name, DB_UINT, DB_TEXT, DB_TEXT, DB_UINT, DB_UINT); - if (!e) - { - DBG1(DBG_IMC, "database query for sw_identifier failed"); - return 0; - } - if (e->enumerate(e, &sw_id, &sw_package, &sw_version, &sw_source, - &sw_installed)) - { - if (package) - { - *package = strdup(sw_package); - } - if (version) - { - *version = strdup(sw_version); - } - if (source) - { - *source = sw_source; - } - if (installed) - { - *installed = sw_installed; - } - } - e->destroy(e); - - return sw_id; -} - -METHOD(sw_collector_db_t, get_sw_id_count, uint32_t, - private_sw_collector_db_t *this, sw_collector_db_query_t type) -{ - uint32_t count, installed; - enumerator_t *e; - - if (type == SW_QUERY_ALL) - { - e = this->db->query(this->db, - "SELECT COUNT(installed) FROM sw_identifiers", DB_UINT); - } - else - { - installed = (type == SW_QUERY_INSTALLED); - e = this->db->query(this->db, - "SELECT COUNT(installed) FROM sw_identifiers WHERE installed = ?", - DB_UINT, installed, DB_UINT); - } - - if (!e) - { - DBG1(DBG_IMC, "database query for sw_identifier count failed"); - return 0; - } - if (!e->enumerate(e, &count)) - { - count = 0; - } - e->destroy(e); - - return count; -} - -METHOD(sw_collector_db_t, update_sw_id, bool, - private_sw_collector_db_t *this, uint32_t sw_id, char *name, char *version, - bool installed) -{ - int res; - - if (name && version) - { - res = this->db->execute(this->db, NULL, - "UPDATE sw_identifiers SET name = ?, version = ?, installed = ? " - "WHERE id = ?", DB_TEXT, name, DB_TEXT, version, DB_UINT, installed, - DB_UINT, sw_id); - } - else - { - res = this->db->execute(this->db, NULL, - "UPDATE sw_identifiers SET installed = ? WHERE id = ?", - DB_UINT, installed, DB_UINT, sw_id); - } - if (res != 1) - { - DBG1(DBG_IMC, "unable to update software identifier in database"); - return FALSE; - } - return TRUE; -} - -METHOD(sw_collector_db_t, update_package, int, - private_sw_collector_db_t *this, char *package_filter, char *package) -{ - int count; - - count = this->db->execute(this->db, NULL, - "UPDATE sw_identifiers SET package = ? WHERE package LIKE ?", - DB_TEXT, package, DB_TEXT, package_filter); - if (count < 0) - { - DBG1(DBG_IMC, "unable to update package name in database"); - } - - return count; -} - -METHOD(sw_collector_db_t, create_sw_enumerator, enumerator_t*, - private_sw_collector_db_t *this, sw_collector_db_query_t type, char *package) -{ - enumerator_t *e; - u_int installed; - - if (type == SW_QUERY_ALL) - { - if (package) - { - e = this->db->query(this->db, - "SELECT id, name, package, version, installed " - "FROM sw_identifiers WHERE package = ? ORDER BY name ASC", - DB_TEXT, package, DB_UINT, DB_TEXT, DB_TEXT, DB_TEXT, DB_UINT); - } - else - { - e = this->db->query(this->db, - "SELECT id, name, package, version, installed " - "FROM sw_identifiers ORDER BY name ASC", - DB_UINT, DB_TEXT, DB_TEXT, DB_TEXT, DB_UINT); - } - } - else - { - installed = (type == SW_QUERY_INSTALLED); - - if (package) - { - e = this->db->query(this->db, - "SELECT id, name, package, version, installed " - "FROM sw_identifiers WHERE package = ? AND installed = ? " - "ORDER BY name ASC", DB_TEXT, package, DB_UINT, installed, - DB_UINT, DB_TEXT, DB_TEXT, DB_TEXT, DB_UINT); - } - else - { - e = this->db->query(this->db, - "SELECT id, name, package, version, installed " - "FROM sw_identifiers WHERE installed = ? ORDER BY name ASC", - DB_UINT, installed, DB_UINT, DB_TEXT, DB_TEXT, DB_TEXT, DB_UINT); - } - } - if (!e) - { - DBG1(DBG_IMC, "database query for sw_identifier count failed"); - return NULL; - } - - return e; -} - -METHOD(sw_collector_db_t, destroy, void, - private_sw_collector_db_t *this) -{ - this->db->destroy(this->db); - free(this); -} - -/** - * Described in header. - */ -sw_collector_db_t *sw_collector_db_create(char *uri) -{ - private_sw_collector_db_t *this; - uint32_t first_eid, last_eid; - char *first_time; - - INIT(this, - .public = { - .add_event = _add_event, - .get_last_event = _get_last_event, - .add_sw_event = _add_sw_event, - .set_sw_id = _set_sw_id, - .get_sw_id = _get_sw_id, - .get_sw_id_count = _get_sw_id_count, - .update_sw_id = _update_sw_id, - .update_package = _update_package, - .create_sw_enumerator = _create_sw_enumerator, - .destroy = _destroy, - }, - .db = lib->db->create(lib->db, uri), - ); - - if (!this->db) - { - DBG1(DBG_IMC, "opening database URI '%s' failed", uri); - return NULL; - } - - /* Retrieve last event in database */ - if (!get_last_event(this, &last_eid, &this->epoch, NULL)) - { - destroy(this); - return NULL; - } - - /* Create random epoch and first event if no events exist yet */ - if (!last_eid) - { - rng_t *rng; - - rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG); - if (!rng || - !rng->get_bytes(rng, sizeof(uint32_t), (uint8_t*)&this->epoch)) - { - DESTROY_IF(rng); - destroy(this); - DBG1(DBG_IMC, "generating random epoch value failed"); - return NULL; - } - rng->destroy(rng); - - /* strongTNC workaround - limit epoch to 31 bit unsigned integer */ - this->epoch &= 0x7fffffff; - - /* Create first event when the OS was installed */ - first_time = lib->settings->get_str(lib->settings, - "sw-collector.first_time", "0000-00-00T00:00:00Z"); - first_eid = add_event(this, first_time); - if (!first_eid) - { - destroy(this); - return NULL; - } - DBG0(DBG_IMC, "First-Date: %s, eid = %u, epoch = %u", - first_time, first_eid, this->epoch); - } - - return &this->public; -} diff --git a/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_db.h b/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_db.h deleted file mode 100644 index 7aa41b0c1..000000000 --- a/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_db.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 2017 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 sw_collector_db_t sw_collector_db - * @{ @ingroup imc_swima - */ - -#ifndef SW_COLLECTOR_DB_H_ -#define SW_COLLECTOR_DB_H_ - -#include <library.h> - -typedef struct sw_collector_db_t sw_collector_db_t; -typedef enum sw_collector_db_query_t sw_collector_db_query_t; - -/** - * Type of software identifier queries - */ -enum sw_collector_db_query_t { - SW_QUERY_ALL, - SW_QUERY_INSTALLED, - SW_QUERY_DELETED -}; - -/** - * Software collector database object - */ -struct sw_collector_db_t { - - /** - * bAdd event to database - * - * @param timestamp Timestamp in 20 octet RFC 3339 format - * @return Primary key pointing to event ID or 0 if failed - */ - uint32_t (*add_event)(sw_collector_db_t *this, char *timestamp); - - /** - * Get last event, zero EID if none exists - * - * @param eid Primary key pointing to last event - * @param epoch Epoch - * @param last_time Timestamp in 20 octet RFC 3339 format of last event - * @return - */ - bool (*get_last_event)(sw_collector_db_t *this, uint32_t *eid, - uint32_t *epoch, char **last_time); - - /** - * Add software identifier event to database - * - * @param eid Foreign key pointing to an event ID - * @param sw_id Foreign key pointing to a software identifier - * @param action 1 for CREATION, 2 for deletion - * @return TRUE if successful - */ - bool (*add_sw_event)(sw_collector_db_t *this, uint32_t eid, uint32_t sw_id, - uint8_t action); - - /** - * Set software_identifier, checking if the identifier already exists - * - * @param name Software identifier - * @param package Software package - * @param version Version of software package - * @param source Source ID of the software collector - * @param installed Installation status to be set, TRUE if installed - * @return Primary key pointing to SW ID or 0 if failed - */ - uint32_t (*set_sw_id)(sw_collector_db_t *this, char *name, char *package, - char *version, uint8_t source, bool installed); - - /** - * Get software_identifier record - * - * @param name Software identifier - * @param package Software package - * @param version Version of software package - * @param source Source ID of the software collector - * @param installed Installation status - * @return Primary key pointing to SW ID or 0 if failed - */ - uint32_t (*get_sw_id)(sw_collector_db_t *this, char *name, char **package, - char **version, uint8_t *source, bool *installed); - - /** - * Get number of installed or deleted software identifiers - * - * @param type Query type (ALL, INSTALLED, DELETED) - * @return Count - */ - uint32_t (*get_sw_id_count)(sw_collector_db_t *this, - sw_collector_db_query_t type); - - /** - * Update the software identifier version - * - * @param sw_id Primary key of software identifier - * @param name Software identifier - * @param version Package version - * @param installed Installation status - * @return TRUE if update successful - */ - bool (*update_sw_id)(sw_collector_db_t *this, uint32_t sw_id, char *name, - char *version, bool installed); - - /** - * Update the package name - * - * @param package_filter Package name[s] to be changed - * @param package New package name - * @return TRUE if update successful - */ - int (*update_package)(sw_collector_db_t *this, char *package_filter, - char *package); - - /** - * Enumerate over all collected [installed] software identities - * - * @param type Query type (ALL, INSTALLED, DELETED) - * @param package If not NULL enumerate over all package versions - * @return Enumerator - */ - enumerator_t* (*create_sw_enumerator)(sw_collector_db_t *this, - sw_collector_db_query_t type, - char *package); - - /** - * Destroy sw_collector_db_t object - */ - void (*destroy)(sw_collector_db_t *this); - -}; - -/** - * Create an sw_collector_db_t instance - * - * @param uri database URI - */ -sw_collector_db_t* sw_collector_db_create(char *uri); - -#endif /** SW_COLLECTOR_DB_H_ @}*/ diff --git a/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_dpkg.c b/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_dpkg.c deleted file mode 100644 index b5a858297..000000000 --- a/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_dpkg.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -#define _GNU_SOURCE -#include <stdio.h> - -#include "sw_collector_dpkg.h" - -typedef struct private_sw_collector_dpkg_t private_sw_collector_dpkg_t; - -/** - * Private data of an sw_collector_dpkg_t object. - */ -struct private_sw_collector_dpkg_t { - - /** - * Public members of sw_collector_dpkg_state_t - */ - sw_collector_dpkg_t public; - -}; - -typedef struct { - /** public enumerator interface */ - enumerator_t public; - /** dpkg output stream */ - FILE *file; - /** current dpkg output line */ - char line[BUF_LEN]; -} dpkg_enumerator_t; - -METHOD(enumerator_t, enumerate, bool, - dpkg_enumerator_t *this, va_list args) -{ - char **package, **arch, **version, *state, *pos; - - VA_ARGS_VGET(args, package, arch, version); - - while (TRUE) - { - if (!fgets(this->line, BUF_LEN, this->file)) - { - return FALSE; - } - - *package = this->line; - pos = strchr(this->line, '\t'); - if (!pos) - { - return FALSE; - } - *pos = '\0'; - - *arch = ++pos; - pos = strchr(pos, '\t'); - if (!pos) - { - return FALSE; - } - *pos = '\0'; - - *version = ++pos; - pos = strchr(pos, '\t'); - if (!pos) - { - return FALSE; - } - *pos = '\0'; - - state = ++pos; - pos = strchr(pos, '\n'); - if (!pos) - { - return FALSE; - } - *pos = '\0'; - - if (streq(state, "install ok installed")) - { - return TRUE; - } - } -} - -METHOD(enumerator_t, enumerator_destroy, void, - dpkg_enumerator_t *this) -{ - pclose(this->file); - free(this); -} - -METHOD(sw_collector_dpkg_t, create_sw_enumerator, enumerator_t*, - private_sw_collector_dpkg_t *this) -{ - dpkg_enumerator_t *enumerator; - char cmd[] = "dpkg-query -W -f=" - "\'${Package}\t${Architecture}\t${Version}\t${Status}\n\'"; - FILE *file; - - file = popen(cmd, "r"); - if (!file) - { - DBG1(DBG_IMC, "failed to run dpgk-query command"); - return NULL; - } - - INIT(enumerator, - .public = { - .enumerate = enumerator_enumerate_default, - .venumerate = _enumerate, - .destroy = _enumerator_destroy, - }, - .file = file, - ); - - return &enumerator->public; -} - -METHOD(sw_collector_dpkg_t, destroy, void, - private_sw_collector_dpkg_t *this) -{ - free(this); -} - -/** - * Described in header. - */ -sw_collector_dpkg_t *sw_collector_dpkg_create(void) -{ - private_sw_collector_dpkg_t *this; - - INIT(this, - .public = { - .create_sw_enumerator = _create_sw_enumerator, - .destroy = _destroy, - }, - ); - - return &this->public; -} diff --git a/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_dpkg.h b/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_dpkg.h deleted file mode 100644 index eab792e8a..000000000 --- a/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_dpkg.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2017 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 sw_collector_dpkg_t sw_collector_dpkg - * @{ @ingroup sw_collector - */ - -#ifndef SW_COLLECTOR_DPKG_H_ -#define SW_COLLECTOR_DPKG_H_ - -#include <library.h> - -typedef struct sw_collector_dpkg_t sw_collector_dpkg_t; - -/** - * Software collector dpkg object - */ -struct sw_collector_dpkg_t { - - /** - * List of installed software identifiers managed by the - * Debian "dpkg" package manager - * - * @return Enumerator - */ - enumerator_t* (*create_sw_enumerator)(sw_collector_dpkg_t *this); - - /** - * Destroy sw_collector_dpkg_t object - */ - void (*destroy)(sw_collector_dpkg_t *this); - -}; - -/** - * Create an sw_collector_dpkg_t instance - */ -sw_collector_dpkg_t* sw_collector_dpkg_create(void); - -#endif /** SW_COLLECTOR_DPKG_H_ @}*/ diff --git a/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_history.c b/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_history.c deleted file mode 100644 index 71f888c46..000000000 --- a/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_history.c +++ /dev/null @@ -1,503 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -#define _GNU_SOURCE -#include <stdio.h> -#include <time.h> - -#include "sw_collector_history.h" -#include "sw_collector_dpkg.h" - -#include "swima/swima_event.h" - -typedef struct private_sw_collector_history_t private_sw_collector_history_t; - -/** - * Private data of an sw_collector_history_t object. - */ -struct private_sw_collector_history_t { - - /** - * Public members of sw_collector_history_state_t - */ - sw_collector_history_t public; - - /** - * Software Event Source Number - */ - uint8_t source; - - /** - * Reference to OS info object - */ - sw_collector_info_t *info; - - /** - * Reference to collector database - */ - sw_collector_db_t *db; - -}; - -/** - * Define auxiliary package_t list item object - */ -typedef struct package_t package_t; - -struct package_t { - char *package; - char *version; - char *old_version; - char *sw_id; - char *old_sw_id; -}; - -/** - * Create package_t list item object - */ -static package_t* create_package(sw_collector_info_t *info, chunk_t package, - chunk_t version, chunk_t old_version) -{ - package_t *this; - - INIT(this, - .package = strndup(package.ptr, package.len), - .version = strndup(version.ptr, version.len), - .old_version = strndup(old_version.ptr, old_version.len), - ) - - this->sw_id = info->create_sw_id(info, this->package, this->version); - if (old_version.len) - { - this->old_sw_id = info->create_sw_id(info, this->package, - this->old_version); - } - - return this; -} - -/** - * Free package_t list item object - */ -static void free_package(package_t *this) -{ - if (this) - { - free(this->package); - free(this->version); - free(this->old_version); - free(this->sw_id); - free(this->old_sw_id); - free(this); - } -} - -/** - * Extract and parse a single package item - */ -static package_t* extract_package(chunk_t item, sw_collector_info_t *info, - sw_collector_history_op_t op) -{ - chunk_t package, package_stripped, version, old_version; - package_t *p; - - /* extract package name */ - if (!extract_token(&package, ' ', &item)) - { - fprintf(stderr, "version not found.\n"); - return NULL; - } - item = chunk_skip(item, 1); - - /* strip architecture suffix if present */ - if (extract_token(&package_stripped, ':', &package)) - { - package = package_stripped; - } - - /* extract versions */ - version = old_version = chunk_empty; - - if (item.len > 0) - { - if (extract_token(&version, ',', &item)) - { - eat_whitespace(&item); - if (!match("automatic", &item)) - { - old_version = version; - version = item; - } - } - else - { - version = item; - } - } - p = create_package(info, package, version, old_version); - - /* generate log entry */ - if (op == SW_OP_UPGRADE) - { - DBG2(DBG_IMC, " %s (%s, %s)", p->package, p->old_version, p->version); - DBG2(DBG_IMC, " +%s", p->sw_id); - DBG2(DBG_IMC, " -%s", p->old_sw_id); - } - else - { - DBG2(DBG_IMC, " %s (%s)", p->package, p->version); - DBG2(DBG_IMC, " %s%s", (op == SW_OP_INSTALL) ? "+" : "-", p->sw_id); - } - - return p; -} - -METHOD(sw_collector_history_t, extract_timestamp, bool, - private_sw_collector_history_t *this, chunk_t args, char *buf) -{ - struct tm loc, utc; - chunk_t t1, t2; - time_t t; - - /* Break down local time with format t1 = yyyy-mm-dd and t2 = hh:mm:ss */ - if (!eat_whitespace(&args) || !extract_token(&t1, ' ', &args) || - !eat_whitespace(&args) || t1.len != 10 || args.len != 8) - { - DBG1(DBG_IMC, "unable to parse start-date"); - return FALSE; - } - t2 = args; - - if (sscanf(t1.ptr, "%4d-%2d-%2d", - &loc.tm_year, &loc.tm_mon, &loc.tm_mday) != 3) - { - DBG1(DBG_IMC, "unable to parse date format yyyy-mm-dd"); - return FALSE; - } - loc.tm_year -= 1900; - loc.tm_mon -= 1; - loc.tm_isdst = -1; - - if (sscanf(t2.ptr, "%2d:%2d:%2d", - &loc.tm_hour, &loc.tm_min, &loc.tm_sec) != 3) - { - DBG1(DBG_IMC, "unable to parse time format hh:mm:ss"); - return FALSE; - } - - /* Convert from local time to UTC */ - t = mktime(&loc); - gmtime_r(&t, &utc); - utc.tm_year += 1900; - utc.tm_mon += 1; - - /* Form timestamp according to RFC 3339 (20 characters) */ - snprintf(buf, 21, "%4d-%02d-%02dT%02d:%02d:%02dZ", - utc.tm_year, utc.tm_mon, utc.tm_mday, - utc.tm_hour, utc.tm_min, utc.tm_sec); - - return TRUE; -} - -METHOD(sw_collector_history_t, extract_packages, bool, - private_sw_collector_history_t *this, chunk_t args, uint32_t eid, - sw_collector_history_op_t op) -{ - bool success = FALSE; - package_t *p = NULL; - chunk_t item; - - eat_whitespace(&args); - - while (extract_token(&item, ')', &args)) - { - char *del_sw_id = NULL, *del_version = NULL; - char *nx, *px, *vx, *v1; - bool installed; - u_int sw_idx, ix; - uint32_t sw_id, sw_id_epoch_less = 0; - enumerator_t *e; - - p = extract_package(item, this->info, op); - if (!p) - { - goto end; - } - - /* packages without version information cannot be handled */ - if (strlen(p->version) == 0) - { - free_package(p); - continue; - } - - switch (op) - { - case SW_OP_REMOVE: - /* prepare subsequent deletion sw event */ - del_sw_id = p->sw_id; - del_version = p->version; - break; - case SW_OP_UPGRADE: - /* prepare subsequent deletion sw event */ - del_sw_id = p->old_sw_id; - del_version = p->old_version; - /* fall through to next case */ - case SW_OP_INSTALL: - sw_id = this->db->get_sw_id(this->db, p->sw_id, NULL, NULL, - NULL, &installed); - if (sw_id) - { - /* sw identifier exists - update state to 'installed' */ - if (installed) - { - /* this case should not occur */ - DBG1(DBG_IMC, " warning: sw_id %d is already " - "installed", sw_id); - } - else if (!this->db->update_sw_id(this->db, sw_id, NULL, - NULL, TRUE)) - { - goto end; - } - } - else - { - /* new sw identifier - create with state 'installed' */ - sw_id = this->db->set_sw_id(this->db, p->sw_id, p->package, - p->version, this->source, TRUE); - if (!sw_id) - { - goto end; - } - } - - /* add creation sw event with current eid */ - if (!this->db->add_sw_event(this->db, eid, sw_id, - SWIMA_EVENT_ACTION_CREATION)) - { - goto end; - } - break; - } - - if (op != SW_OP_INSTALL) - { - sw_id = 0; - - /* look for existing installed package versions */ - e = this->db->create_sw_enumerator(this->db, SW_QUERY_INSTALLED, - p->package); - if (!e) - { - goto end; - } - - while (e->enumerate(e, &sw_idx, &nx, &px, &vx, &ix)) - { - if (streq(vx, del_version)) - { - /* full match with epoch */ - sw_id = sw_idx; - break; - } - v1 = strchr(vx, ':'); - if (v1 && streq(++v1, del_version)) - { - /* match with stripped epoch */ - sw_id_epoch_less = sw_idx; - } - } - e->destroy(e); - - if (!sw_id && sw_id_epoch_less) - { - /* no full match - fall back to epoch-less match */ - sw_id = sw_id_epoch_less; - } - if (sw_id) - { - /* sw identifier exists - update state to 'deleted' */ - if (!this->db->update_sw_id(this->db, sw_id, NULL, NULL, FALSE)) - { - goto end; - } - } - else - { - /* new sw identifier - create with state 'deleted' */ - sw_id = this->db->set_sw_id(this->db, del_sw_id, p->package, - del_version, this->source, FALSE); - - /* add creation sw event with eid = 1 */ - if (!sw_id || !this->db->add_sw_event(this->db, 1, sw_id, - SWIMA_EVENT_ACTION_CREATION)) - { - goto end; - } - } - - /* add creation sw event with current eid */ - if (!this->db->add_sw_event(this->db, eid, sw_id, - SWIMA_EVENT_ACTION_DELETION)) - { - goto end; - } - } - free_package(p); - - if (args.len < 2) - { - break; - } - args = chunk_skip(args, 2); - } - p = NULL; - success = TRUE; - -end: - free_package(p); - - return success; -} - -METHOD(sw_collector_history_t, merge_installed_packages, bool, - private_sw_collector_history_t *this) -{ - uint32_t sw_id, count = 0; - char *package, *arch, *version, *v1, *name, *n1; - bool installed, success = FALSE; - sw_collector_dpkg_t *dpkg; - enumerator_t *enumerator; - - DBG1(DBG_IMC, "Merging:"); - - dpkg = sw_collector_dpkg_create(); - if (!dpkg) - { - return FALSE; - } - - enumerator = dpkg->create_sw_enumerator(dpkg); - while (enumerator->enumerate(enumerator, &package, &arch, &version)) - { - name = this->info->create_sw_id(this->info, package, version); - DBG3(DBG_IMC, " %s merged", name); - - sw_id = this->db->get_sw_id(this->db, name, NULL, NULL, NULL, - &installed); - if (sw_id) - { - if (!installed) - { - DBG1(DBG_IMC, " warning: existing sw_id %u" - " is not installed", sw_id); - - if (!this->db->update_sw_id(this->db, sw_id, name, version, - TRUE)) - { - free(name); - goto end; - } - } - } - else - { - /* check for a Debian epoch number */ - v1 = strchr(version, ':'); - if (v1) - { - /* check for existing and installed epoch-less version */ - n1 = this->info->create_sw_id(this->info, package, ++v1); - sw_id = this->db->get_sw_id(this->db, n1, NULL, NULL, NULL, - &installed); - free(n1); - - if (sw_id && installed) - { - /* add epoch to existing version */ - if (!this->db->update_sw_id(this->db, sw_id, name, version, - installed)) - { - free(name); - goto end; - } - } - else - { - sw_id = 0; - } - } - } - - if (!sw_id) - { - /* new sw identifier - create with state 'installed' */ - sw_id = this->db->set_sw_id(this->db, name, package, version, - this->source, TRUE); - - /* add creation sw event with eid = 1 */ - if (!sw_id || !this->db->add_sw_event(this->db, 1, sw_id, - SWIMA_EVENT_ACTION_CREATION)) - { - free(name); - goto end; - } - - } - free(name); - count++; - } - success = TRUE; - - DBG1(DBG_IMC, " merged %u installed packages, %u registered in database", - count, this->db->get_sw_id_count(this->db, SW_QUERY_INSTALLED)); - -end: - enumerator->destroy(enumerator); - dpkg->destroy(dpkg); - - return success; -} - -METHOD(sw_collector_history_t, destroy, void, - private_sw_collector_history_t *this) -{ - free(this); -} - -/** - * Described in header. - */ -sw_collector_history_t *sw_collector_history_create(sw_collector_info_t *info, - sw_collector_db_t *db, - uint8_t source) -{ - private_sw_collector_history_t *this; - - INIT(this, - .public = { - .extract_timestamp = _extract_timestamp, - .extract_packages = _extract_packages, - .merge_installed_packages = _merge_installed_packages, - .destroy = _destroy, - }, - .source = source, - .info = info, - .db = db, - ); - - return &this->public; -} diff --git a/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_history.h b/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_history.h deleted file mode 100644 index 857cc17d2..000000000 --- a/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_history.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2017 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 sw_collector_history_t sw_collector_history - * @{ @ingroup sw_collector - */ - -#ifndef SW_COLLECTOR_HISTORY_H_ -#define SW_COLLECTOR_HISTORY_H_ - -#include "sw_collector_history.h" -#include "sw_collector_info.h" -#include "sw_collector_db.h" - -#include <library.h> -#include <utils/debug.h> -#include <utils/lexparser.h> - -typedef struct sw_collector_history_t sw_collector_history_t; -typedef enum sw_collector_history_op_t sw_collector_history_op_t; - -/** - * Define major history event operations - */ -enum sw_collector_history_op_t { - SW_OP_INSTALL, - SW_OP_UPGRADE, - SW_OP_REMOVE -}; - -/** - * Software collector history object - */ -struct sw_collector_history_t { - - /** - * Extract timestamp from event in installation history - * - * @param args Arguments to be processed - * @param buf timestamp buffer for 21 byte RFC 3339 string - * @return TRUE if extraction succeeded - */ - bool (*extract_timestamp)(sw_collector_history_t *this, chunk_t args, - char *buf); - - /** - * Extract packages from event in installation history - * - * @param args Arguments to be processed - * @param eid Primary key pointing to current event - * @param op Extraction operation - * @return TRUE if extraction succeeded - */ - bool (*extract_packages)(sw_collector_history_t *this, chunk_t args, - uint32_t eid, sw_collector_history_op_t op); - - /** - * Merge packages from initial installation - * - * @return TRUE if merge succeeded - */ - bool (*merge_installed_packages)(sw_collector_history_t *this); - - /** - * Destroy sw_collector_history_t object - */ - void (*destroy)(sw_collector_history_t *this); - -}; - -/** - * Create an sw_collector_history_t instance - * - * @param info Internal reference to collector info - * @param db Internal reference to collector database - * @param source Software event source number - */ -sw_collector_history_t* sw_collector_history_create(sw_collector_info_t *info, - sw_collector_db_t *db, - uint8_t source); - -#endif /** SW_COLLECTOR_HISTORY_H_ @}*/ diff --git a/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_info.c b/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_info.c deleted file mode 100644 index b04645030..000000000 --- a/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_info.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -#define _GNU_SOURCE -#include <stdio.h> - -#include "sw_collector_info.h" - -#include <library.h> -#include <utils/lexparser.h> - -typedef struct private_sw_collector_info_t private_sw_collector_info_t; - -/** - * Private data of an sw_collector_info_t object. - */ -struct private_sw_collector_info_t { - - /** - * Public members of sw_collector_info_state_t - */ - sw_collector_info_t public; - - /** - * tagCreator - */ - char *tag_creator; - - /** - * OS string 'Name_Version-Arch' - */ - char *os; - - /** - * Product string 'Name Version Arch' - */ - char *product; - - /** - * OS info about endpoint - */ - imc_os_info_t *os_info; - -}; - -/** - * Replaces invalid character by a valid one - */ -static void sanitize_uri(char *uri, char a, char b) -{ - char *pos = uri; - - while (TRUE) - { - pos = strchr(pos, a); - if (!pos) - { - break; - } - *pos = b; - pos++; - } -} - -METHOD(sw_collector_info_t, get_os_type, os_type_t, - private_sw_collector_info_t *this) -{ - return this->os_info->get_type(this->os_info); -} - -METHOD(sw_collector_info_t, get_os, char*, - private_sw_collector_info_t *this, char **product) -{ - if (product) - { - *product = this->product; - } - return this->os; -} - -METHOD(sw_collector_info_t, create_sw_id, char*, - private_sw_collector_info_t *this, char *package, char *version) -{ - char *sw_id; - - if (asprintf(&sw_id, "%s__%s-%s%s%s", this->tag_creator, this->os, - package, strlen(version) ? "-" : "", version) == -1) - { - return NULL; - } - sanitize_uri(sw_id, ':', '~'); - sanitize_uri(sw_id, '+', '~'); - - return sw_id; -} - -METHOD(sw_collector_info_t, destroy, void, - private_sw_collector_info_t *this) -{ - this->os_info->destroy(this->os_info); - free(this->os); - free(this->product); - free(this->tag_creator); - free(this); -} - -/** - * Described in header. - */ -sw_collector_info_t *sw_collector_info_create(char *tag_creator) -{ - private_sw_collector_info_t *this; - chunk_t os_name, os_version, os_arch; - - INIT(this, - .public = { - .get_os_type = _get_os_type, - .get_os = _get_os, - .create_sw_id = _create_sw_id, - .destroy = _destroy, - }, - .os_info = imc_os_info_create(), - .tag_creator = strdup(tag_creator), - ); - - os_name = this->os_info->get_name(this->os_info); - os_arch = this->os_info->get_version(this->os_info); - - /* get_version() returns version followed by arch */ - if (!extract_token(&os_version, ' ', &os_arch)) - { - DBG1(DBG_IMC, "separation of OS version from arch failed"); - destroy(this); - return NULL; - } - - /* construct OS string */ - if (asprintf(&this->os, "%.*s_%.*s-%.*s", os_name.len, os_name.ptr, - os_version.len, os_version.ptr, - os_arch.len, os_arch.ptr) == -1) - { - DBG1(DBG_IMC, "constructon of OS string failed"); - destroy(this); - return NULL; - } - - /* construct product string */ - if (asprintf(&this->product, "%.*s %.*s %.*s", os_name.len, os_name.ptr, - os_version.len, os_version.ptr, - os_arch.len, os_arch.ptr) == -1) - { - DBG1(DBG_IMC, "constructon of product string failed"); - destroy(this); - return NULL; - } - - return &this->public; -} diff --git a/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_info.h b/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_info.h deleted file mode 100644 index a54d788f4..000000000 --- a/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_info.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2017 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 sw_collector_info_t sw_collector_info - * @{ @ingroup sw_collector - */ - -#ifndef SW_COLLECTOR_INFO_H_ -#define SW_COLLECTOR_INFO_H_ - -typedef struct sw_collector_info_t sw_collector_info_t; - -#include "imc/imc_os_info.h" - -struct sw_collector_info_t { - - /** - * Get OS type - * - * @return OS type - */ - os_type_t (*get_os_type)(sw_collector_info_t *this); - - /** - * Get OS and product strings - * - * @param product Product string 'Name Version Arch' - * @return OS string 'Name_Version-Arch' - */ - char* (*get_os)(sw_collector_info_t *this, char **product); - - /** - * Create software identifier including tagCreator and OS - * - * @param package Package string - * @param version Version string - * @return Software Identifier string - */ - char* (*create_sw_id)(sw_collector_info_t *this, char *package, - char *version); - - /** - * Destroy sw_collector_info_t object - */ - void (*destroy)(sw_collector_info_t *this); - -}; - -/** - * Create an sw_collector_info_t instance - * - * @param tag_creator Regid of tagCreator - */ -sw_collector_info_t* sw_collector_info_create(char *tag_creator); - -#endif /** SW_COLLECTOR_INFO_H_ @}*/ diff --git a/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_rest_api.c b/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_rest_api.c deleted file mode 100644 index 6b9b7b96a..000000000 --- a/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_rest_api.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (C) 2017 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 "sw_collector_rest_api.h" - -#include <rest/rest.h> -#include <utils/debug.h> - -typedef struct private_sw_collector_rest_api_t private_sw_collector_rest_api_t; - -/** - * Private data of an sw_collector_rest_api_t object. - */ -struct private_sw_collector_rest_api_t { - - /** - * Public members of sw_collector_rest_api_state_t - */ - sw_collector_rest_api_t public; - - /** - * Software collector database - */ - sw_collector_db_t *db; - - /** - * REST API of central collector database - */ - rest_t *rest_api; - -}; - -/** - * Put all locally retrieved software identifiers into a json object - */ -static json_object* create_rest_request(private_sw_collector_rest_api_t *this, - sw_collector_db_query_t type) -{ - json_object *jrequest, *jarray, *jstring; - char *name, *package, *version; - uint32_t sw_id, i; - enumerator_t *e; - - jrequest = json_object_new_object(); - jarray = json_object_new_array(); - json_object_object_add(jrequest, "data", jarray); - - e = this->db->create_sw_enumerator(this->db, type, NULL); - if (!e) - { - return NULL; - } - while (e->enumerate(e, &sw_id, &name, &package, &version, &i)) - { - jstring = json_object_new_string(name); - json_object_array_add(jarray, jstring); - } - e->destroy(e); - - return jrequest; -} - -typedef struct { - /** public enumerator interface */ - enumerator_t public; - /** enumerated json array */ - json_object *jarray; - /** current index +1, initialized at 0 */ - int idx; -} json_array_enumerator_t; - -METHOD(enumerator_t, enumerate, bool, - json_array_enumerator_t *this, va_list args) -{ - json_object *jvalue; - char **out; - - VA_ARGS_VGET(args, out); - - if (this->idx >= json_object_array_length(this->jarray)) - { - return FALSE; - } - - jvalue = json_object_array_get_idx(this->jarray, this->idx++); - if (json_object_get_type(jvalue) != json_type_string) - { - DBG1(DBG_IMC, "json_string element expected in json_array"); - return FALSE; - } - *out = (char*)json_object_get_string(jvalue); - - return TRUE; -} - -METHOD(enumerator_t, enumerator_destroy, void, - json_array_enumerator_t *this) -{ - json_object_put(this->jarray); - free(this); -} - -METHOD(sw_collector_rest_api_t, create_sw_enumerator, enumerator_t*, - private_sw_collector_rest_api_t *this, sw_collector_db_query_t type) -{ - json_array_enumerator_t *enumerator; - json_object *jrequest, *jresponse; - char cmd[BUF_LEN]; - status_t status; - - jrequest = create_rest_request(this, type); - if (!jrequest) - { - return NULL; - } - snprintf(cmd, BUF_LEN, "sessions/0/swid-measurement/"); - - status = this->rest_api->post(this->rest_api, cmd, jrequest, &jresponse); - json_object_put(jrequest); - - switch (status) - { - case SUCCESS: - case NOT_FOUND: - jresponse = json_object_new_array(); - break; - case NEED_MORE: - if (json_object_get_type(jresponse) != json_type_array) - { - DBG1(DBG_IMC, "REST response was not a json_array"); - json_object_put(jresponse); - return NULL; - } - break; - case FAILED: - default: - return NULL; - } - - INIT(enumerator, - .public = { - .enumerate = enumerator_enumerate_default, - .venumerate = _enumerate, - .destroy = _enumerator_destroy, - }, - .jarray = jresponse, - ); - - return &enumerator->public; -} - -METHOD(sw_collector_rest_api_t, destroy, void, - private_sw_collector_rest_api_t *this) -{ - this->rest_api->destroy(this->rest_api); - free(this); -} - -/** - * Described in header. - */ -sw_collector_rest_api_t *sw_collector_rest_api_create(sw_collector_db_t *db) -{ - private_sw_collector_rest_api_t *this; - int timeout; - char *uri; - - uri = lib->settings->get_str(lib->settings, "%s.rest_api.uri", NULL, - lib->ns); - timeout = lib->settings->get_int(lib->settings, "%s.rest_api.timeout", 120, - lib->ns); - if (!uri) - { - DBG1(DBG_IMC, "REST URI to central collector database not set"); - return NULL; - } - - INIT(this, - .public = { - .create_sw_enumerator = _create_sw_enumerator, - .destroy = _destroy, - }, - .db = db, - .rest_api = rest_create(uri, timeout), - ); - - return &this->public; -} diff --git a/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_rest_api.h b/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_rest_api.h deleted file mode 100644 index ca45230e6..000000000 --- a/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_rest_api.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2017 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 sw_collector_rest_api_t sw_collector_rest_api - * @{ @ingroup imc_swima - */ - -#ifndef SW_COLLECTOR_REST_API_H_ -#define SW_COLLECTOR_REST_API_H_ - -#include "sw_collector_db.h" - -typedef struct sw_collector_rest_api_t sw_collector_rest_api_t; - -/** - * Software collector REST API object - */ -struct sw_collector_rest_api_t { - - /** - * List of locally stored software identifiers that are not registered - * in a central collector database - * - * @param type Query type (ALL, INSTALLED, DELETED) - * @return Enumerator - */ - enumerator_t* (*create_sw_enumerator)(sw_collector_rest_api_t *this, - sw_collector_db_query_t type); - - /** - * Destroy sw_collector_rest_api_t object - */ - void (*destroy)(sw_collector_rest_api_t *this); - -}; - -/** - * Create an sw_collector_rest_api_t instance - * - * @param db Software collector database to be used - */ -sw_collector_rest_api_t* sw_collector_rest_api_create(sw_collector_db_t *db); - -#endif /** SW_COLLECTOR_REST_API_H_ @}*/ diff --git a/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_tables.sql b/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_tables.sql deleted file mode 100644 index b7b430b3c..000000000 --- a/src/libimcv/plugins/imc_swima/sw_collector/sw_collector_tables.sql +++ /dev/null @@ -1,31 +0,0 @@ -/* SQLit database for an Endpoint Collector */ - -DROP TABLE IF EXISTS "events"; -CREATE TABLE "events" ( - "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - "epoch" INTEGER NOT NULL, - "timestamp" CHAR(20) NOT NULL -); - -DROP TABLE IF EXISTS "sw_identifiers"; -CREATE TABLE "sw_identifiers" ( - "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - "name" VARCHAR(255) NOT NULL, - "package" VARCHAR(255) NOT NULL, - "version" VARCHAR(255) NOT NULL, - "source" INTEGER DEFAULT 0, - "installed" INTEGER DEFAULT 1, - "tag" TEXT - ); -DROP INDEX IF EXISTS "sw_identifiers_name"; -CREATE INDEX "sw_identifiers_name" ON "sw_identifiers" ( - "name" -); - -DROP TABLE IF EXISTS "sw_events"; -CREATE TABLE "sw_events" ( - "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - "eid" INTEGER REFERENCES "events" ("id"), - "sw_id" INTEGER NOT NULL REFERENCES "sw_identifiers" ("id"), - "action" INTEGER NOT NULL -); |