summaryrefslogtreecommitdiff
path: root/src/libimcv/swid/swid_inventory.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libimcv/swid/swid_inventory.c')
-rw-r--r--src/libimcv/swid/swid_inventory.c302
1 files changed, 95 insertions, 207 deletions
diff --git a/src/libimcv/swid/swid_inventory.c b/src/libimcv/swid/swid_inventory.c
index a49286954..5f6e50cb7 100644
--- a/src/libimcv/swid/swid_inventory.c
+++ b/src/libimcv/swid/swid_inventory.c
@@ -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
@@ -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,192 +53,99 @@ 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);
-
- if (status != SUCCESS)
+ sw_id = tag_id->get_unique_sw_id(tag_id, NULL);
+ snprintf(software_id, BUF_LEN, "%.*s__%.*s",
+ (int)tag_creator.len, tag_creator.ptr,
+ (int)sw_id.len, sw_id.ptr);
+
+ 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;
}
static bool collect_tags(private_swid_inventory_t *this, char *pathname,
- swid_inventory_t *targets)
+ swid_inventory_t *targets, bool is_swidtag_dir)
{
char *rel_name, *abs_name;
struct stat st;
@@ -251,72 +159,49 @@ static bool collect_tags(private_swid_inventory_t *this, char *pathname,
pathname, strerror(errno));
return FALSE;
}
- DBG2(DBG_IMC, "entering %s", pathname);
+ if (is_swidtag_dir)
+ {
+ DBG2(DBG_IMC, "entering %s", pathname);
+ }
while (enumerator->enumerate(enumerator, &rel_name, &abs_name, &st))
{
- char * start, *stop;
+ char *separator, *suffix;
chunk_t tag_creator;
chunk_t unique_sw_id = chunk_empty, tag_file_path = chunk_empty;
- if (!strstr(rel_name, "regid."))
- {
- continue;
- }
if (S_ISDIR(st.st_mode))
{
- /* In case of a targeted request */
- if (targets->get_count(targets))
- {
- enumerator_t *target_enumerator;
- swid_tag_id_t *tag_id;
- bool match = FALSE;
-
- target_enumerator = targets->create_enumerator(targets);
- while (target_enumerator->enumerate(target_enumerator, &tag_id))
- {
- if (chunk_equals(tag_id->get_tag_creator(tag_id),
- chunk_from_str(rel_name)))
- {
- match = TRUE;
- break;
- }
- }
- target_enumerator->destroy(target_enumerator);
-
- if (!match)
- {
- continue;
- }
- }
-
- if (!collect_tags(this, abs_name, targets))
+ if (!collect_tags(this, abs_name, targets, is_swidtag_dir ||
+ streq(rel_name, "swidtag")))
{
goto end;
}
continue;
}
+ if (!is_swidtag_dir)
+ {
+ continue;
+ }
- /* parse the regid filename into its components */
- start = rel_name;
- stop = strchr(start, '_');
- if (!stop)
+ /* found a swidtag file? */
+ suffix = strstr(rel_name, ".swidtag");
+ if (!suffix)
{
- DBG1(DBG_IMC, " %s", rel_name);
- DBG1(DBG_IMC, " '_' separator not found");
- goto end;
+ continue;
}
- tag_creator = chunk_create(start, stop-start);
- start = stop + 1;
- stop = strstr(start, ".swidtag");
- if (!stop)
+ /* parse the swidtag filename into its components */
+ separator = strstr(rel_name, "__");
+ if (!separator)
{
DBG1(DBG_IMC, " %s", rel_name);
- DBG1(DBG_IMC, " swidtag postfix not found");
+ DBG1(DBG_IMC, " '__' separator not found");
goto end;
}
- unique_sw_id = chunk_create(start, stop-start);
+ tag_creator = chunk_create(rel_name, separator-rel_name);
+
+ unique_sw_id = chunk_create(separator+2, suffix-separator-2);
tag_file_path = chunk_from_str(abs_name);
/* In case of a targeted request */
@@ -334,7 +219,7 @@ static bool collect_tags(private_swid_inventory_t *this, char *pathname,
target_tag_creator = tag_id->get_tag_creator(tag_id);
if (chunk_equals(target_unique_sw_id, unique_sw_id) &&
- chunk_equals(target_tag_creator, tag_creator))
+ chunk_equals(target_tag_creator, tag_creator))
{
match = TRUE;
break;
@@ -358,7 +243,7 @@ static bool collect_tags(private_swid_inventory_t *this, char *pathname,
if (!xml_tag)
{
DBG1(DBG_IMC, " opening '%s' failed: %s", abs_name,
- strerror(errno));
+ strerror(errno));
goto end;
}
@@ -378,25 +263,28 @@ static bool collect_tags(private_swid_inventory_t *this, char *pathname,
end:
enumerator->destroy(enumerator);
- DBG2(DBG_IMC, "leaving %s", pathname);
+ if (is_swidtag_dir)
+ {
+ DBG2(DBG_IMC, "leaving %s", pathname);
+ }
return success;
}
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
* the tree under the "directory" path.
*/
- return collect_tags(this, directory, targets);
+ return collect_tags(this, directory, targets, FALSE);
}
METHOD(swid_inventory_t, add, void,