aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Steffen <andreas.steffen@strongswan.org>2017-08-03 09:00:59 +0200
committerAndreas Steffen <andreas.steffen@strongswan.org>2017-08-04 19:15:26 +0200
commit88501a64ca88f196514432b33f7baab8a798fb35 (patch)
tree2fe0e413eea2025df0b7d1d062e03b798e01cc31
parent073c179a88b8eb33f63d430b0e18a0f81eb9ab69 (diff)
downloadstrongswan-88501a64ca88f196514432b33f7baab8a798fb35.tar.bz2
strongswan-88501a64ca88f196514432b33f7baab8a798fb35.tar.xz
swid-gen: Share SWID generator between sw-collector, imc-swima and imc-swid
-rw-r--r--conf/options/imcv.opt9
-rw-r--r--conf/options/sw-collector.opt9
-rw-r--r--conf/plugins/imc-swid.opt3
-rw-r--r--conf/plugins/imc-swima.opt3
-rw-r--r--src/libimcv/Makefile.am2
-rw-r--r--src/libimcv/plugins/imc_swid/imc_swid.c13
-rw-r--r--src/libimcv/plugins/imv_swid/imv_swid_agent.c6
-rw-r--r--src/libimcv/plugins/imv_swid/imv_swid_state.c13
-rw-r--r--src/libimcv/swid/swid_inventory.c223
-rw-r--r--src/libimcv/swid/swid_inventory.h5
-rw-r--r--src/libimcv/swid_gen/swid_gen.c291
-rw-r--r--src/libimcv/swid_gen/swid_gen.h69
-rw-r--r--src/libimcv/swima/swima_collector.c242
-rw-r--r--src/sw-collector/sw-collector.8.in15
-rw-r--r--src/sw-collector/sw-collector.c103
15 files changed, 561 insertions, 445 deletions
diff --git a/conf/options/imcv.opt b/conf/options/imcv.opt
index 33ab74bd5..177781ff7 100644
--- a/conf/options/imcv.opt
+++ b/conf/options/imcv.opt
@@ -21,6 +21,15 @@ charon.imcv.os_info.default_password_enabled = no
charon.imcv.policy_script = ipsec _imv_policy
Script called for each TNC connection to generate IMV policies.
+libimcv.swid_gen.command = /usr/local/bin/swid_generator
+ SWID generator command to be executed.
+
+libimcv.swid_gen.tag_creator.name = strongSwan Project
+ Name of the tagCreator entity.
+
+libimcv.swid_gen.tag_creator.regid = strongswan.org
+ regid of the tagCreator entity.
+
libimcv.debug_level = 1
Debug level for a stand-alone _libimcv_ library.
diff --git a/conf/options/sw-collector.opt b/conf/options/sw-collector.opt
index 3cd714f51..52baaba73 100644
--- a/conf/options/sw-collector.opt
+++ b/conf/options/sw-collector.opt
@@ -22,14 +22,5 @@ sw-collector.rest_api.uri =
sw-collector.rest_api.timeout = 120
Timeout of REST API HTTP POST transaction.
-sw-collector.tag_creator.name = strongSwan Project
- Name of the tagCreator entity.
-
-sw-collector.tag_creator.regid = strongswan.org
- regid of the tagCreator entity.
-
-sw-collector.swid_generator = /usr/local/bin/swid_generator
- SWID generator command to be executed.
-
sw-collector.load =
Plugins to load in sw-collector tool.
diff --git a/conf/plugins/imc-swid.opt b/conf/plugins/imc-swid.opt
index 74490c179..55e0e880e 100644
--- a/conf/plugins/imc-swid.opt
+++ b/conf/plugins/imc-swid.opt
@@ -1,9 +1,6 @@
libimcv.plugins.imc-swid.swid_directory = ${prefix}/share
Directory where SWID tags are located.
-libimcv.plugins.imc-swid.swid_generator = /usr/local/bin/swid_generator
- SWID generator command to be executed.
-
libimcv.plugins.imc-swid.swid_pretty = FALSE
Generate XML-encoded SWID tags with pretty indentation.
diff --git a/conf/plugins/imc-swima.opt b/conf/plugins/imc-swima.opt
index 73643f4ba..5dc3411e8 100644
--- a/conf/plugins/imc-swima.opt
+++ b/conf/plugins/imc-swima.opt
@@ -9,9 +9,6 @@ libimcv.plugins.imc-swima.swid_epoch = 0x11223344
libimcv.plugins.imc-swima.swid_directory = ${prefix}/share
Directory where SWID tags are located.
-libimcv.plugins.imc-swima.swid_generator = /usr/local/bin/swid_generator
- SWID generator command to be executed.
-
libimcv.plugins.imc-swima.swid_pretty = FALSE
Generate XML-encoded SWID tags with pretty indentation.
diff --git a/src/libimcv/Makefile.am b/src/libimcv/Makefile.am
index dda0c2cd8..457a2f5a7 100644
--- a/src/libimcv/Makefile.am
+++ b/src/libimcv/Makefile.am
@@ -100,6 +100,7 @@ libimcv_la_SOURCES = \
swid/swid_inventory.h swid/swid_inventory.c \
swid/swid_tag.h swid/swid_tag.c \
swid/swid_tag_id.h swid/swid_tag_id.c \
+ swid_gen/swid_gen.h swid_gen/swid_gen.c \
swima/swima_data_model.h swima/swima_data_model.c \
swima/swima_record.h swima/swima_record.c \
swima/swima_event.h swima/swima_event.c \
@@ -214,6 +215,7 @@ imcv_tests_SOURCES = \
pa_tnc/pa_tnc_attr_manager.c \
seg/seg_env.c seg/seg_contract.c \
seg/seg_contract_manager.c \
+ swid_gen/swid_gen.c \
swima/swima_data_model.c \
swima/swima_event.c \
swima/swima_events.c \
diff --git a/src/libimcv/plugins/imc_swid/imc_swid.c b/src/libimcv/plugins/imc_swid/imc_swid.c
index 0dcb9afb6..1468a59cc 100644
--- a/src/libimcv/plugins/imc_swid/imc_swid.c
+++ b/src/libimcv/plugins/imc_swid/imc_swid.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2015 Andreas Steffen
+ * Copyright (C) 2013-2017 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -30,8 +30,6 @@
#include <pen/pen.h>
#include <utils/debug.h>
-#define SWID_GENERATOR "/usr/local/bin/swid_generator"
-
/* IMC definitions */
static const char imc_name[] = "SWID";
@@ -165,7 +163,7 @@ static bool add_swid_inventory(imc_state_t *state, imc_msg_t *msg,
pa_tnc_attr_t *attr, *attr_error;
imc_swid_state_t *swid_state;
swid_inventory_t *swid_inventory;
- char *swid_directory, *swid_generator;
+ char *swid_directory;
uint32_t eid_epoch;
bool swid_pretty, swid_full;
enumerator_t *enumerator;
@@ -173,9 +171,6 @@ static bool add_swid_inventory(imc_state_t *state, imc_msg_t *msg,
swid_directory = lib->settings->get_str(lib->settings,
"%s.plugins.imc-swid.swid_directory",
SWID_DIRECTORY, lib->ns);
- swid_generator = lib->settings->get_str(lib->settings,
- "%s.plugins.imc-swid.swid_generator",
- SWID_GENERATOR, lib->ns);
swid_pretty = lib->settings->get_bool(lib->settings,
"%s.plugins.imc-swid.swid_pretty",
FALSE, lib->ns);
@@ -184,8 +179,8 @@ static bool add_swid_inventory(imc_state_t *state, imc_msg_t *msg,
FALSE, lib->ns);
swid_inventory = swid_inventory_create(full_tags);
- if (!swid_inventory->collect(swid_inventory, swid_directory, swid_generator,
- targets, swid_pretty, swid_full))
+ if (!swid_inventory->collect(swid_inventory, swid_directory, targets,
+ swid_pretty, swid_full))
{
swid_inventory->destroy(swid_inventory);
attr_error = swid_error_create(TCG_SWID_ERROR, request_id,
diff --git a/src/libimcv/plugins/imv_swid/imv_swid_agent.c b/src/libimcv/plugins/imv_swid/imv_swid_agent.c
index 09a387fd3..2884a169c 100644
--- a/src/libimcv/plugins/imv_swid/imv_swid_agent.c
+++ b/src/libimcv/plugins/imv_swid/imv_swid_agent.c
@@ -590,7 +590,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
DBG1(DBG_IMV, " %s", target);
/* Separate target into tag_creator and unique_sw_id */
- separator = strchr(target, '_');
+ separator = strstr(target, "__");
if (!separator)
{
error_str = "separation of regid from "
@@ -598,9 +598,9 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
break;
}
tag_creator = chunk_create(target, separator - target);
- separator++;
+ separator += 2;
unique_sw_id = chunk_create(separator, strlen(target) -
- tag_creator.len - 1);
+ tag_creator.len - 2);
tag_id = swid_tag_id_create(tag_creator, unique_sw_id,
chunk_empty);
cast_attr = (tcg_swid_attr_req_t*)attr;
diff --git a/src/libimcv/plugins/imv_swid/imv_swid_state.c b/src/libimcv/plugins/imv_swid/imv_swid_state.c
index fb9493a83..2b270b880 100644
--- a/src/libimcv/plugins/imv_swid/imv_swid_state.c
+++ b/src/libimcv/plugins/imv_swid/imv_swid_state.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2016 Andreas Steffen
+ * Copyright (C) 2013-2017 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -288,8 +288,8 @@ METHOD(imv_swid_state_t, get_request_id, uint32_t,
METHOD(imv_swid_state_t, set_swid_inventory, void,
private_imv_swid_state_t *this, swid_inventory_t *inventory)
{
- chunk_t tag_creator, unique_sw_id;
- char software_id[256];
+ chunk_t tag_creator, sw_id;
+ char software_id[BUF_LEN];
json_object *jstring;
swid_tag_id_t *tag_id;
enumerator_t *enumerator;
@@ -299,10 +299,9 @@ METHOD(imv_swid_state_t, set_swid_inventory, void,
{
/* Construct software ID from tag creator and unique software ID */
tag_creator = tag_id->get_tag_creator(tag_id);
- unique_sw_id = tag_id->get_unique_sw_id(tag_id, NULL);
- snprintf(software_id, 256, "%.*s_%.*s",
- tag_creator.len, tag_creator.ptr,
- unique_sw_id.len, unique_sw_id.ptr);
+ sw_id = tag_id->get_unique_sw_id(tag_id, NULL);
+ snprintf(software_id, BUF_LEN, "%.*s__%.*s",
+ tag_creator.len, tag_creator.ptr, sw_id.len, sw_id.ptr);
DBG3(DBG_IMV, " %s", software_id);
/* Add software ID to JSON array */
diff --git a/src/libimcv/swid/swid_inventory.c b/src/libimcv/swid/swid_inventory.c
index 7b05e8393..4adbb39b4 100644
--- a/src/libimcv/swid/swid_inventory.c
+++ b/src/libimcv/swid/swid_inventory.c
@@ -16,9 +16,10 @@
#include "swid_inventory.h"
#include "swid_tag.h"
#include "swid_tag_id.h"
+#include "swid_gen/swid_gen.h"
#include <collections/linked_list.h>
-#include <bio/bio_writer.h>
+#include <utils/lexparser.h>
#include <utils/debug.h>
#include <stdio.h>
@@ -52,186 +53,92 @@ struct private_swid_inventory_t {
linked_list_t *list;
};
-/**
- * Read SWID tags issued by the swid_generator tool
- */
-static status_t read_swid_tags(private_swid_inventory_t *this, FILE *file)
+static status_t generate_tags(private_swid_inventory_t *this,
+ swid_inventory_t *targets, bool pretty, bool full)
{
+ swid_gen_t *swid_gen;
swid_tag_t *tag;
- bio_writer_t *writer;
- chunk_t tag_encoding, tag_file_path = chunk_empty;
- bool more_tags = TRUE, last_newline;
- char line[8192];
- size_t len;
-
- while (more_tags)
- {
- last_newline = TRUE;
- writer = bio_writer_create(512);
- while (TRUE)
- {
- if (!fgets(line, sizeof(line), file))
- {
- more_tags = FALSE;
- break;
- }
- len = strlen(line);
-
- if (last_newline && line[0] == '\n')
- {
- break;
- }
- else
- {
- last_newline = (line[len-1] == '\n');
- writer->write_data(writer, chunk_create(line, len));
- }
- }
-
- tag_encoding = writer->get_buf(writer);
-
- if (tag_encoding.len > 1)
- {
- /* remove trailing newline if present */
- if (tag_encoding.ptr[tag_encoding.len - 1] == '\n')
- {
- tag_encoding.len--;
- }
- DBG3(DBG_IMC, " %.*s", tag_encoding.len, tag_encoding.ptr);
-
- tag = swid_tag_create(tag_encoding, tag_file_path);
- this->list->insert_last(this->list, tag);
- }
- writer->destroy(writer);
- }
-
- return SUCCESS;
-}
-
-/**
- * Read SWID tag or software IDs issued by the swid_generator tool
- */
-static status_t read_swid_tag_ids(private_swid_inventory_t *this, FILE *file)
-{
swid_tag_id_t *tag_id;
- chunk_t tag_creator, unique_sw_id, tag_file_path = chunk_empty;
- char line[BUF_LEN];
-
- while (TRUE)
- {
- char *separator;
- size_t len;
-
- if (!fgets(line, sizeof(line), file))
- {
- return SUCCESS;
- }
- len = strlen(line);
-
- /* remove trailing newline if present */
- if (len > 0 && line[len - 1] == '\n')
- {
- len--;
- }
- DBG3(DBG_IMC, " %.*s", len, line);
-
- separator = strchr(line, '_');
- if (!separator)
- {
- DBG1(DBG_IMC, "separation of regid from unique software ID failed");
- return FAILED;
- }
- tag_creator = chunk_create(line, separator - line);
- separator++;
-
- unique_sw_id = chunk_create(separator, len - (separator - line));
- tag_id = swid_tag_id_create(tag_creator, unique_sw_id, tag_file_path);
- this->list->insert_last(this->list, tag_id);
- }
-}
-
-static status_t generate_tags(private_swid_inventory_t *this, char *generator,
- swid_inventory_t *targets, bool pretty, bool full)
-{
- FILE *file;
- char command[BUF_LEN];
- char doc_separator[] = "'\n\n'";
-
+ enumerator_t *enumerator;
status_t status = SUCCESS;
+ chunk_t out;
+
+ swid_gen = swid_gen_create();
if (targets->get_count(targets) == 0)
{
- /* Assemble the SWID generator command */
- if (this->full_tags)
- {
- snprintf(command, BUF_LEN, "%s swid --doc-separator %s%s%s",
- generator, doc_separator, pretty ? " --pretty" : "",
- full ? " --full" : "");
- }
- else
- {
- snprintf(command, BUF_LEN, "%s software-id", generator);
- }
+ DBG2(DBG_IMC, "SWID tag%s generation by package manager",
+ this->full_tags ? "" : " ID");
- /* Open a pipe stream for reading the SWID generator output */
- file = popen(command, "r");
- if (!file)
+ enumerator = swid_gen->create_tag_enumerator(swid_gen, !this->full_tags,
+ full, pretty);
+ if (enumerator)
{
- DBG1(DBG_IMC, "failed to run swid_generator command");
- return NOT_SUPPORTED;
- }
+ while (enumerator->enumerate(enumerator, &out))
+ {
+ if (this->full_tags)
+ {
+ chunk_t swid_tag = out;
- if (this->full_tags)
- {
- DBG2(DBG_IMC, "SWID tag generation by package manager");
- status = read_swid_tags(this, file);
+ tag = swid_tag_create(swid_tag, chunk_empty);
+ this->list->insert_last(this->list, tag);
+ }
+ else
+ {
+ chunk_t tag_creator, sw_id = out;
+
+ if (extract_token_str(&tag_creator, "__", &sw_id))
+ {
+ tag_id = swid_tag_id_create(tag_creator, sw_id,
+ chunk_empty);
+ this->list->insert_last(this->list, tag_id);
+ }
+ else
+ {
+ DBG1(DBG_IMC, "separation of regid from unique "
+ "software ID failed");
+ status = FAILED;
+ chunk_free(&out);
+ break;
+ }
+ }
+ chunk_free(&out);
+ }
+ enumerator->destroy(enumerator);
}
else
{
- DBG2(DBG_IMC, "SWID tag ID generation by package manager");
- status = read_swid_tag_ids(this, file);
+ status = NOT_SUPPORTED;
}
- pclose(file);
}
else if (this->full_tags)
{
- swid_tag_id_t *tag_id;
- enumerator_t *enumerator;
+ DBG2(DBG_IMC, "targeted SWID tag generation");
enumerator = targets->create_enumerator(targets);
while (enumerator->enumerate(enumerator, &tag_id))
{
- char software_id[BUF_LEN];
- chunk_t tag_creator, unique_sw_id;
+ char software_id[BUF_LEN], *swid_tag;
+ chunk_t tag_creator, sw_id;
+ /* Construct software ID from tag creator and unique software ID */
tag_creator = tag_id->get_tag_creator(tag_id);
- unique_sw_id = tag_id->get_unique_sw_id(tag_id, NULL);
- snprintf(software_id, BUF_LEN, "%.*s_%.*s",
- tag_creator.len, tag_creator.ptr,
- unique_sw_id.len, unique_sw_id.ptr);
-
- /* Assemble the SWID generator command */
- snprintf(command, BUF_LEN, "%s swid --software-id %s%s%s",
- generator, software_id, pretty ? " --pretty" : "",
- full ? " --full" : "");
-
- /* Open a pipe stream for reading the SWID generator output */
- file = popen(command, "r");
- if (!file)
- {
- DBG1(DBG_IMC, "failed to run swid_generator command");
- return NOT_SUPPORTED;
- }
- status = read_swid_tags(this, file);
- pclose(file);
+ sw_id = tag_id->get_unique_sw_id(tag_id, NULL);
+ snprintf(software_id, BUF_LEN, "%.*s__%.*s",
+ tag_creator.len, tag_creator.ptr, sw_id.len, sw_id.ptr);
- if (status != SUCCESS)
+ swid_tag = swid_gen->generate_tag(swid_gen, software_id, NULL, NULL,
+ full, pretty);
+ if (swid_tag)
{
- break;
+ tag = swid_tag_create(chunk_from_str(swid_tag), chunk_empty);
+ this->list->insert_last(this->list, tag);
+ free(swid_tag);
}
}
enumerator->destroy(enumerator);
}
+ swid_gen->destroy(swid_gen);
return status;
}
@@ -284,16 +191,16 @@ static bool collect_tags(private_swid_inventory_t *this, char *pathname,
}
/* parse the swidtag filename into its components */
- separator = strchr(rel_name, '_');
+ separator = strstr(rel_name, "__");
if (!separator)
{
DBG1(DBG_IMC, " %s", rel_name);
- DBG1(DBG_IMC, " '_' separator not found");
+ DBG1(DBG_IMC, " '__' separator not found");
goto end;
}
tag_creator = chunk_create(rel_name, separator-rel_name);
- unique_sw_id = chunk_create(separator+1, suffix-separator-1);
+ unique_sw_id = chunk_create(separator+2, suffix-separator-2);
tag_file_path = chunk_from_str(abs_name);
/* In case of a targeted request */
@@ -364,13 +271,13 @@ end:
}
METHOD(swid_inventory_t, collect, bool,
- private_swid_inventory_t *this, char *directory, char *generator,
- swid_inventory_t *targets, bool pretty, bool full)
+ private_swid_inventory_t *this, char *directory, swid_inventory_t *targets,
+ bool pretty, bool full)
{
/**
* Tags are generated by a package manager
*/
- generate_tags(this, generator, targets, pretty, full);
+ generate_tags(this, targets, pretty, full);
/**
* Collect swidtag files by iteratively entering all directories in
diff --git a/src/libimcv/swid/swid_inventory.h b/src/libimcv/swid/swid_inventory.h
index 04029070e..ba2518e26 100644
--- a/src/libimcv/swid/swid_inventory.h
+++ b/src/libimcv/swid/swid_inventory.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2014 Andreas Steffen
+ * Copyright (C) 2013-2017 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -37,13 +37,12 @@ struct swid_inventory_t {
* Collect the SWID tags stored on the endpoint
*
* @param directory SWID directory path
- * @param generator Path to SWID generator
* @param targets List of target tag IDs
* @param pretty Generate indented XML SWID tags
* @param full Include file information in SWID tags
* @return TRUE if successful
*/
- bool (*collect)(swid_inventory_t *this, char *directory, char *generator,
+ bool (*collect)(swid_inventory_t *this, char *directory,
swid_inventory_t *targets, bool pretty, bool full);
/**
diff --git a/src/libimcv/swid_gen/swid_gen.c b/src/libimcv/swid_gen/swid_gen.c
new file mode 100644
index 000000000..206d41d11
--- /dev/null
+++ b/src/libimcv/swid_gen/swid_gen.c
@@ -0,0 +1,291 @@
+/*
+ * 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 "swid_gen.h"
+
+#include <bio/bio_writer.h>
+
+#define SWID_GENERATOR "/usr/local/bin/swid_generator"
+
+typedef struct private_swid_gen_t private_swid_gen_t;
+
+/**
+ * Private data of a swid_gen_t object.
+ *
+ */
+struct private_swid_gen_t {
+
+ /**
+ * Public swid_gen_t interface.
+ */
+ swid_gen_t public;
+
+ /**
+ * Path of the SWID generator command
+ */
+ char *generator;
+
+ /**
+ * Entity name of the tagCreator
+ */
+ char *entity;
+
+ /**
+ * Regid of the tagCreator
+ */
+ char *regid;
+
+};
+
+METHOD(swid_gen_t, generate_tag, char*,
+ private_swid_gen_t *this, char *sw_id, char *package, char *version,
+ bool full, bool pretty)
+{
+ char *tag = NULL;
+ size_t tag_buf_len = 8192;
+ char tag_buf[tag_buf_len], command[BUF_LEN];
+ bio_writer_t *writer;
+ chunk_t swid_tag;
+ FILE *file;
+
+ /* Compose the SWID generator command */
+ if (full || !package || !version)
+ {
+ snprintf(command, BUF_LEN, "%s swid --entity-name \"%s\" "
+ "--regid %s --software-id %s%s%s",
+ this->generator, this->entity, this->regid, sw_id,
+ full ? " --full" : "", pretty ? " --pretty" : "");
+ }
+ else
+ {
+ snprintf(command, BUF_LEN, "%s swid --entity-name \"%s\" "
+ "--regid %s --name %s --version-string %s%s",
+ this->generator, this->entity, this->regid, package,
+ version, pretty ? " --pretty" : "");
+ }
+
+ /* Open a pipe stream for reading the SWID generator output */
+ file = popen(command, "r");
+ if (file)
+ {
+ writer = bio_writer_create(tag_buf_len);
+ while (TRUE)
+ {
+ if (!fgets(tag_buf, tag_buf_len, file))
+ {
+ break;
+ }
+ writer->write_data(writer, chunk_create(tag_buf, strlen(tag_buf)));
+ }
+ pclose(file);
+ swid_tag = writer->extract_buf(writer);
+ writer->destroy(writer);
+
+ if (swid_tag.len > 0)
+ {
+ tag = swid_tag.ptr;
+ tag[swid_tag.len - 1] = '\0';
+ }
+ else
+ {
+ chunk_free(&swid_tag);
+ }
+ }
+ else
+ {
+ DBG1(DBG_IMC, "failed to run swid_generator command");
+ }
+
+ return tag;
+}
+
+typedef struct {
+ /** public enumerator interface */
+ enumerator_t public;
+ /** swid_generator output stream */
+ FILE *file;
+ /** generate software identifier only */
+ bool sw_id_only;
+} swid_gen_enumerator_t;
+
+METHOD(enumerator_t, enumerate, bool,
+ swid_gen_enumerator_t *this, va_list args)
+{
+ chunk_t *out;
+
+ VA_ARGS_VGET(args, out);
+
+ if (this->sw_id_only)
+ {
+ char line[BUF_LEN];
+ size_t len;
+
+ if (!fgets(line, sizeof(line), this->file))
+ {
+ return FALSE;
+ }
+ len = strlen(line);
+
+ if (len == 0)
+ {
+ return FALSE;
+ }
+
+ /* remove trailing newline if present */
+ if (line[len - 1] == '\n')
+ {
+ len--;
+ }
+ DBG3(DBG_IMC, " %.*s", len, line);
+ *out = chunk_clone(chunk_create(line, len));
+ }
+ else
+ {
+ bool last_newline = TRUE;
+ size_t len, line_len = 8192;
+ char line[line_len];
+ bio_writer_t *writer;
+ chunk_t swid_tag;
+
+ writer = bio_writer_create(line_len);
+ while (TRUE)
+ {
+ if (!fgets(line, line_len, this->file))
+ {
+ break;
+ }
+ len = strlen(line);
+
+ if (last_newline && line[0] == '\n')
+ {
+ break;
+ }
+ else
+ {
+ last_newline = (line[len-1] == '\n');
+ writer->write_data(writer, chunk_create(line, len));
+ }
+ }
+ swid_tag = writer->extract_buf(writer);
+ writer->destroy(writer);
+
+ if (swid_tag.len <= 1)
+ {
+ chunk_free(&swid_tag);
+ return FALSE;
+ }
+
+ /* remove trailing newline if present */
+ if (swid_tag.ptr[swid_tag.len - 1] == '\n')
+ {
+ swid_tag.len--;
+ }
+ DBG3(DBG_IMC, " %.*s", swid_tag.len, swid_tag.ptr);
+ *out = swid_tag;
+ }
+
+ return TRUE;
+}
+
+METHOD(enumerator_t, enumerator_destroy, void,
+ swid_gen_enumerator_t *this)
+{
+ pclose(this->file);
+ free(this);
+}
+
+METHOD(swid_gen_t, create_tag_enumerator, enumerator_t*,
+ private_swid_gen_t *this, bool sw_id_only, bool full, bool pretty)
+{
+ swid_gen_enumerator_t *enumerator;
+ char command[BUF_LEN];
+ char doc_separator[] = "'\n\n'";
+ FILE *file;
+
+ /* Assemble the SWID generator command */
+ if (sw_id_only)
+ {
+ snprintf(command, BUF_LEN, "%s software-id --regid %s ",
+ this->generator, this->regid);
+ }
+ else
+ {
+ snprintf(command, BUF_LEN, "%s swid --entity-name \"%s\" --regid %s "
+ "--doc-separator %s%s%s", this->generator, this->entity,
+ this->regid, doc_separator, pretty ? " --pretty" : "",
+ full ? " --full" : "");
+ }
+
+ /* Open a pipe stream for reading the SWID generator output */
+ file = popen(command, "r");
+ if (!file)
+ {
+ DBG1(DBG_IMC, "failed to run swid_generator command");
+ return NULL;
+ }
+
+ INIT(enumerator,
+ .public = {
+ .enumerate = enumerator_enumerate_default,
+ .venumerate = _enumerate,
+ .destroy = _enumerator_destroy,
+ },
+ .sw_id_only = sw_id_only,
+ .file = file,
+ );
+
+ return &enumerator->public;
+}
+
+METHOD(swid_gen_t, destroy, void,
+ private_swid_gen_t *this)
+{
+ free(this->generator);
+ free(this->entity);
+ free(this->regid);
+ free(this);
+}
+
+/**
+ * See header
+ */
+swid_gen_t *swid_gen_create(void)
+{
+ private_swid_gen_t *this;
+ char *entity, *regid, *generator;
+
+ entity = lib->settings->get_str(lib->settings,
+ "libimcv.swid_gen.tag_creator.name", "strongSwan Project");
+ regid = lib->settings->get_str(lib->settings,
+ "libimcv.swid_gen.tag_creator.regid", "strongswan.org");
+ generator = lib->settings->get_str(lib->settings,
+ "libimcv.swid_gen.command", SWID_GENERATOR);
+
+ INIT(this,
+ .public = {
+ .generate_tag = _generate_tag,
+ .create_tag_enumerator = _create_tag_enumerator,
+ .destroy = _destroy,
+ },
+ .generator = strdup(generator),
+ .entity = strdup(entity),
+ .regid = strdup(regid),
+ );
+
+ return &this->public;
+}
diff --git a/src/libimcv/swid_gen/swid_gen.h b/src/libimcv/swid_gen/swid_gen.h
new file mode 100644
index 000000000..06ca0a341
--- /dev/null
+++ b/src/libimcv/swid_gen/swid_gen.h
@@ -0,0 +1,69 @@
+/*
+ * 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 swid_gen swid_gen
+ * @{ @ingroup libimcv
+ */
+
+#ifndef SWID_GEN_H_
+#define SWID_GEN_H_
+
+#include <library.h>
+
+typedef struct swid_gen_t swid_gen_t;
+
+/**
+ * Class generating a either a full or a minimalistic ISO 19770-2:2015 SWID tag
+ */
+struct swid_gen_t {
+
+ /**
+ * Generate a SWID tag
+ *
+ * @param sw_id Software identifier
+ * @param package Package name (can be NULL)
+ * @param version Package version (can be NULL)
+ * @param full Generate full SWID tags with file information
+ * @param pretty Generate SWID tags with pretty formating
+ * @return SWID tag
+ */
+ char* (*generate_tag)(swid_gen_t *this, char *sw_id, char *package,
+ char *version, bool full, bool pretty);
+
+ /**
+ * Generate a SWID tag
+ *
+ * @param sw_id_only Return software identifier only
+ * @param full Generate full SWID tags with file information
+ * @param pretty Generate SWID tags with pretty formating
+ * @return Tag enumerator (sw_id, tag)
+ */
+ enumerator_t* (*create_tag_enumerator)(swid_gen_t *this, bool sw_id_only,
+ bool full, bool pretty);
+
+ /**
+ * Destroys a swid_gen_t object.
+ */
+ void (*destroy)(swid_gen_t *this);
+
+};
+
+/**
+ * Creates a swid_gen_t object
+ */
+swid_gen_t* swid_gen_create(void);
+
+#endif /** SWID_GEN_H_ @}*/
diff --git a/src/libimcv/swima/swima_collector.c b/src/libimcv/swima/swima_collector.c
index 0fd3d14b3..096093b01 100644
--- a/src/libimcv/swima/swima_collector.c
+++ b/src/libimcv/swima/swima_collector.c
@@ -15,8 +15,9 @@
#include "swima_collector.h"
+#include <swid_gen/swid_gen.h>
+
#include <collections/linked_list.h>
-#include <bio/bio_writer.h>
#include <utils/debug.h>
#include <stdio.h>
@@ -33,8 +34,6 @@
#define SWID_DIRECTORY NULL
#endif
-#define SWID_GENERATOR "/usr/local/bin/swid_generator"
-
/**
* Directories to be skipped by collector
*/
@@ -133,104 +132,6 @@ end:
return status;
}
-/**
- * Read SWID tags issued by the swid_generator tool
- */
-static status_t read_swid_tags(private_swima_collector_t *this, FILE *file)
-{
- swima_record_t *sw_record;
- bio_writer_t *writer;
- chunk_t sw_id, swid_tag;
- bool more_tags = TRUE, last_newline;
- char line[8192];
- size_t len;
- status_t status;
-
- while (more_tags)
- {
- last_newline = TRUE;
- writer = bio_writer_create(512);
- while (TRUE)
- {
- if (!fgets(line, sizeof(line), file))
- {
- more_tags = FALSE;
- break;
- }
- len = strlen(line);
-
- if (last_newline && line[0] == '\n')
- {
- break;
- }
- else
- {
- last_newline = (line[len-1] == '\n');
- writer->write_data(writer, chunk_create(line, len));
- }
- }
- swid_tag = writer->get_buf(writer);
-
- if (swid_tag.len > 1)
- {
- /* remove trailing newline if present */
- if (swid_tag.ptr[swid_tag.len - 1] == '\n')
- {
- swid_tag.len--;
- }
- DBG3(DBG_IMC, " %.*s", swid_tag.len, swid_tag.ptr);
-
- status = extract_sw_id(swid_tag, &sw_id);
- if (status != SUCCESS)
- {
- DBG1(DBG_IMC, "software id could not be extracted from tag");
- writer->destroy(writer);
- return status;
- }
- sw_record = swima_record_create(0, sw_id, chunk_empty);
- sw_record->set_source_id(sw_record, SOURCE_ID_GENERATOR);
- sw_record->set_record(sw_record, swid_tag);
- this->inventory->add(this->inventory, sw_record);
- chunk_free(&sw_id);
- }
- writer->destroy(writer);
- }
-
- return SUCCESS;
-}
-
-/**
- * Read Software Identifiers issued by the swid_generator tool
- */
-static status_t read_swid_tag_ids(private_swima_collector_t *this, FILE *file)
-{
- swima_record_t *sw_record;
- chunk_t sw_id;
- char line[BUF_LEN];
- size_t len;
-
- while (TRUE)
- {
- if (!fgets(line, sizeof(line), file))
- {
- return SUCCESS;
- }
- len = strlen(line);
-
- /* remove trailing newline if present */
- if (len > 0 && line[len - 1] == '\n')
- {
- len--;
- }
- DBG3(DBG_IMC, " %.*s", len, line);
-
- sw_id = chunk_create(line, len);
- sw_record = swima_record_create(0, sw_id, chunk_empty);
- sw_record->set_source_id(sw_record, SOURCE_ID_GENERATOR);
- this->inventory->add(this->inventory, sw_record);
- }
-}
-
static status_t retrieve_inventory(private_swima_collector_t *this,
swima_inventory_t *targets)
{
@@ -299,82 +200,118 @@ static status_t retrieve_events(private_swima_collector_t *this,
return SUCCESS;
}
-static status_t generate_tags(private_swima_collector_t *this, char *generator,
- swima_inventory_t *targets, bool pretty, bool full)
+static status_t generate_tags(private_swima_collector_t *this,
+ swima_inventory_t *targets, bool pretty, bool full)
{
- FILE *file;
- char command[BUF_LEN];
- char doc_separator[] = "'\n\n'";
-
+ swid_gen_t *swid_gen;
+ swima_record_t *target, *sw_record;
+ enumerator_t *enumerator;
status_t status = SUCCESS;
+ swid_gen = swid_gen_create();
+
if (targets->get_count(targets) == 0)
{
- /* Assemble the SWID generator command */
- if (this->sw_id_only)
- {
- snprintf(command, BUF_LEN, "%s software-id", generator);
- }
- else
- {
- snprintf(command, BUF_LEN, "%s swid --doc-separator %s%s%s",
- generator, doc_separator, pretty ? " --pretty" : "",
- full ? " --full" : "");
- }
+ chunk_t out, sw_id, swid_tag = chunk_empty;
- /* Open a pipe stream for reading the SWID generator output */
- file = popen(command, "r");
- if (!file)
- {
- DBG1(DBG_IMC, "failed to run swid_generator command");
- return NOT_SUPPORTED;
- }
+ DBG2(DBG_IMC, "SWID tag%s generation by package manager",
+ this->sw_id_only ? " ID" : "");
- if (this->sw_id_only)
+ enumerator = swid_gen->create_tag_enumerator(swid_gen, this->sw_id_only,
+ full, pretty);
+ if (enumerator)
{
- DBG2(DBG_IMC, "SWID tag ID generation by package manager");
- status = read_swid_tag_ids(this, file);
+ while (enumerator->enumerate(enumerator, &out))
+ {
+ if (this->sw_id_only)
+ {
+ sw_id = out;
+ }
+ else
+ {
+ swid_tag = out;
+ status = extract_sw_id(swid_tag, &sw_id);
+ if (status != SUCCESS)
+ {
+ DBG1(DBG_IMC, "software id could not be extracted "
+ "from tag");
+ chunk_free(&swid_tag);
+ break;
+ }
+ }
+ sw_record = swima_record_create(0, sw_id, chunk_empty);
+ sw_record->set_source_id(sw_record, SOURCE_ID_GENERATOR);
+ if (!this->sw_id_only)
+ {
+ sw_record->set_record(sw_record, swid_tag);
+ chunk_free(&swid_tag);
+ }
+ this->inventory->add(this->inventory, sw_record);
+ chunk_free(&sw_id);
+ }
+ enumerator->destroy(enumerator);
}
else
{
- DBG2(DBG_IMC, "SWID tag generation by package manager");
- status = read_swid_tags(this, file);
+ status = NOT_SUPPORTED;
}
- pclose(file);
}
else if (!this->sw_id_only)
{
- swima_record_t *target;
- enumerator_t *enumerator;
- chunk_t sw_id;
+ DBG2(DBG_IMC, "targeted SWID tag generation");
enumerator = targets->create_enumerator(targets);
while (enumerator->enumerate(enumerator, &target))
{
- sw_id = target->get_sw_id(target, NULL);
+ swima_record_t *sw_record;
+ char *tag = NULL, *name, *package, *version;
+ u_int installed;
+ chunk_t sw_id;
+ enumerator_t *e;
- /* Assemble the SWID generator command */
- snprintf(command, BUF_LEN, "%s swid --software-id %.*s%s%s",
- generator, sw_id.len, sw_id.ptr,
- pretty ? " --pretty" : "", full ? " --full" : "");
+ sw_id = target->get_sw_id(target, NULL);
+ name = strndup(sw_id.ptr, sw_id.len);
- /* Open a pipe stream for reading the SWID generator output */
- file = popen(command, "r");
- if (!file)
+ if (this->db)
+ {
+ e = this->db->query(this->db,
+ "SELECT package, version, installed "
+ "FROM sw_identifiers WHERE name = ?", DB_TEXT, name,
+ DB_TEXT, DB_TEXT, DB_UINT);
+ if (!e)
+ {
+ DBG1(DBG_IMC, "database query for sw_identifiers failed");
+ status = FAILED;
+ free(name);
+ break;
+ }
+ if (e->enumerate(e, &package, &version, &installed))
+ {
+ tag = swid_gen->generate_tag(swid_gen, name, package,
+ version, full && installed, pretty);
+ }
+ e->destroy(e);
+ }
+ else
{
- DBG1(DBG_IMC, "failed to run swid_generator command");
- return NOT_SUPPORTED;
+ tag = swid_gen->generate_tag(swid_gen, name, NULL, NULL,
+ full, pretty);
}
- status = read_swid_tags(this, file);
- pclose(file);
+ free(name);
- if (status != SUCCESS)
+ if (tag)
{
- break;
+ DBG2(DBG_IMC, " %.*s", sw_id.len, sw_id.ptr);
+ sw_record = swima_record_create(0, sw_id, chunk_empty);
+ sw_record->set_source_id(sw_record, SOURCE_ID_GENERATOR);
+ sw_record->set_record(sw_record, chunk_from_str(tag));
+ this->inventory->add(this->inventory, sw_record);
+ free(tag);
}
}
enumerator->destroy(enumerator);
}
+ swid_gen->destroy(swid_gen);
return status;
}
@@ -480,6 +417,7 @@ static bool collect_tags(private_swima_collector_t *this, char *pathname,
{
if (chunk_equals(target->get_sw_id(target, NULL), sw_id))
{
+ DBG2(DBG_IMC, " %.*s", sw_id.len, sw_id.ptr);
match = TRUE;
break;
}
@@ -518,16 +456,13 @@ end:
METHOD(swima_collector_t, collect_inventory, swima_inventory_t*,
private_swima_collector_t *this, bool sw_id_only, swima_inventory_t *targets)
{
- char *directory, *generator;
bool pretty, full;
+ char *directory;
status_t status;
directory = lib->settings->get_str(lib->settings,
"%s.plugins.imc-swima.swid_directory",
SWID_DIRECTORY, lib->ns);
- generator = lib->settings->get_str(lib->settings,
- "%s.plugins.imc-swima.swid_generator",
- SWID_GENERATOR, lib->ns);
pretty = lib->settings->get_bool(lib->settings,
"%s.plugins.imc-swima.swid_pretty",
FALSE, lib->ns);
@@ -550,13 +485,14 @@ METHOD(swima_collector_t, collect_inventory, swima_inventory_t*,
}
else
{
- status = generate_tags(this, generator, targets, pretty, full);
+ status = generate_tags(this, targets, pretty, full);
}
/**
* Source 2: Collect swidtag files by iteratively entering all
* directories in the tree under the "directory" path.
*/
+ DBG2(DBG_IMC, "SWID tag%s collection", sw_id_only ? " ID" : "");
collect_tags(this, directory, targets, FALSE);
return status == SUCCESS ? this->inventory : NULL;
diff --git a/src/sw-collector/sw-collector.8.in b/src/sw-collector/sw-collector.8.in
index da713cd36..8560ba095 100644
--- a/src/sw-collector/sw-collector.8.in
+++ b/src/sw-collector/sw-collector.8.in
@@ -99,9 +99,18 @@ The following parameters can be configured in strongswan.conf:
uri = https://admin-user:ietf99hackathon@tnc.strongswan.org/api/
timeout = 120
}
- tag_creator {
- name = strongSwan Project
- regid = strongswan.org
+ }
+.P
+The parameters of the swid_generator used with the \-\-generate command can
+be changed in the libimcv section of strongswan.conf:
+.P
+ libimcv {
+ swid_gen {
+ command = /usr/local/bin/swid_generator
+ tag_creator {
+ name = strongSwan Project
+ regid = strongswan.org
+ }
}
}
.
diff --git a/src/sw-collector/sw-collector.c b/src/sw-collector/sw-collector.c
index 0bdd59813..e08f94868 100644
--- a/src/sw-collector/sw-collector.c
+++ b/src/sw-collector/sw-collector.c
@@ -30,13 +30,11 @@
#include "sw_collector_dpkg.h"
#
#include <library.h>
-#include <bio/bio_writer.h>
#include <utils/debug.h>
#include <utils/lexparser.h>
#include <imv/imv_os_info.h>
-
-#define SWID_GENERATOR "/usr/local/bin/swid_generator"
+#include <swid_gen/swid_gen.h>
/**
* global debug output variables
@@ -470,105 +468,21 @@ static int unregistered_identifiers(sw_collector_db_t *db,
}
/**
- * Generate a either a full or a minimalistic ISO 19770-2:2015 SWID tag
- */
-static char* generate_tag(char *name, char *package, char *version,
- char* entity, char *regid, char *product,
- bool full_tag, char *generator)
-{
- char *tag = NULL;
-
- if (full_tag)
- {
- size_t tag_buf_len = 8192;
- char tag_buf[tag_buf_len], command[BUF_LEN];
- bio_writer_t *writer;
- chunk_t tag_chunk;
- FILE *file;
-
- /* Compose the SWID generator command */
- snprintf(command, BUF_LEN, "%s swid --full --regid %s --entity-name "
- "\"%s\" --package %s", generator, regid, entity, package);
-\
- /* Open a pipe stream for reading the SWID generator output */
- file = popen(command, "r");
- if (file)
- {
- writer = bio_writer_create(tag_buf_len);
- while (TRUE)
- {
- if (!fgets(tag_buf, tag_buf_len, file))
- {
- break;
- }
- writer->write_data(writer,
- chunk_create(tag_buf, strlen(tag_buf)));
- }
- pclose(file);
- tag_chunk = writer->extract_buf(writer);
- writer->destroy(writer);
- if (tag_chunk.len > 1)
- {
- tag = tag_chunk.ptr;
- tag[tag_chunk.len - 1] = '\0';
- }
- }
- else
- {
- DBG1(DBG_IMC, "failed to run swid_generator command");
- }
- }
-
- /* Generate minimalistic SWID tag */
- if (!tag)
- {
- char *tag_id;
-
- tag_id = strstr(name, "__");
- if (!tag_id)
- {
- return NULL;
- }
- tag_id += 2;
-
- if (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) == -1)
- {
- tag = NULL;
- }
- }
-
- return tag;
-}
-
-/**
- * Generate a minimalistic ISO 19770-2:2015 SWID tag for
- * all removed SW identifiers that are not registered centrally
+ * Generate ISO 19770-2:2015 SWID tags for [installed|removed|all]
+ * SW identifiers that are not registered centrally
*/
static int generate_tags(sw_collector_info_t *info, sw_collector_db_t *db,
bool full_tags, sw_collector_db_query_t type)
{
+ swid_gen_t * swid_gen;
sw_collector_rest_api_t *rest_api;
- char *name, *package, *version, *entity, *regid, *product, *generator, *tag;
+ char *name, *package, *version, *tag;
enumerator_t *enumerator;
uint32_t sw_id;
bool installed;
int count = 0, installed_count = 0, 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);
- generator = lib->settings->get_str(lib->settings, "%s.swid_generator",
- SWID_GENERATOR, lib->ns);
- info->get_os(info, &product);
-
+ swid_gen = swid_gen_create();
rest_api = sw_collector_rest_api_create(db);
if (!rest_api)
{
@@ -585,8 +499,8 @@ static int generate_tags(sw_collector_info_t *info, sw_collector_db_t *db,
sw_id = db->get_sw_id(db, name, &package, &version, NULL, &installed);
if (sw_id)
{
- tag = generate_tag(name, package, version, entity, regid, product,
- full_tags && installed, generator);
+ tag = swid_gen->generate_tag(swid_gen, name, package, version,
+ full_tags && installed, FALSE);
if (tag)
{
DBG2(DBG_IMC, " creating %s", name);
@@ -623,6 +537,7 @@ static int generate_tags(sw_collector_info_t *info, sw_collector_db_t *db,
}
end:
+ swid_gen->destroy(swid_gen);
DESTROY_IF(rest_api);
return status;