summaryrefslogtreecommitdiff
path: root/src/libpts/swid
diff options
context:
space:
mode:
Diffstat (limited to 'src/libpts/swid')
-rw-r--r--src/libpts/swid/swid_error.c2
-rw-r--r--src/libpts/swid/swid_inventory.c238
-rw-r--r--src/libpts/swid/swid_inventory.h9
-rw-r--r--src/libpts/swid/swid_tag.c40
-rw-r--r--src/libpts/swid/swid_tag.h19
-rw-r--r--src/libpts/swid/swid_tag_id.c42
-rw-r--r--src/libpts/swid/swid_tag_id.h19
7 files changed, 303 insertions, 66 deletions
diff --git a/src/libpts/swid/swid_error.c b/src/libpts/swid/swid_error.c
index 7f7da7688..7f3c34476 100644
--- a/src/libpts/swid/swid_error.c
+++ b/src/libpts/swid/swid_error.c
@@ -40,7 +40,7 @@ pa_tnc_attr_t* swid_error_create(swid_error_code_t code, u_int32_t request_id,
writer->write_uint32(writer, request_id);
if (code == TCG_SWID_RESPONSE_TOO_LARGE)
{
- writer->write_uint16(writer, max_attr_size);
+ writer->write_uint32(writer, max_attr_size);
}
if (description)
{
diff --git a/src/libpts/swid/swid_inventory.c b/src/libpts/swid/swid_inventory.c
index a71682f43..a9f081efa 100644
--- a/src/libpts/swid/swid_inventory.c
+++ b/src/libpts/swid/swid_inventory.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Andreas Steffen
+ * Copyright (C) 2013-2014 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -18,6 +18,7 @@
#include "swid_tag_id.h"
#include <collections/linked_list.h>
+#include <bio/bio_writer.h>
#include <utils/debug.h>
#include <stdio.h>
@@ -51,6 +52,194 @@ 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)
+{
+ swid_tag_t *tag;
+ bio_writer_t *writer;
+ chunk_t tag_encoding, tag_file_path = chunk_empty;
+ bool more_tags = TRUE, last_newline, end_of_tag;
+ char line[8192];
+ size_t len;
+
+ while (more_tags)
+ {
+ last_newline = TRUE;
+ end_of_tag = FALSE;
+ writer = bio_writer_create(512);
+ do
+ {
+ if (!fgets(line, sizeof(line), file))
+ {
+ more_tags = FALSE;
+ end_of_tag = TRUE;
+ break;
+ }
+ len = strlen(line);
+
+ if (last_newline && line[0] == '\n')
+ {
+ end_of_tag = TRUE;
+ break;
+ }
+ else
+ {
+ last_newline = (line[len-1] == '\n');
+ writer->write_data(writer, chunk_create(line, len));
+ }
+ }
+ while (!end_of_tag);
+
+ 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'";
+
+ status_t status = SUCCESS;
+
+ 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);
+ }
+
+ /* 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;
+ }
+
+ if (this->full_tags)
+ {
+ DBG2(DBG_IMC, "SWID tag generation by package manager");
+ status = read_swid_tags(this, file);
+ }
+ else
+ {
+ DBG2(DBG_IMC, "SWID tag ID generation by package manager");
+ status = read_swid_tag_ids(this, file);
+ }
+ pclose(file);
+ }
+ else if (this->full_tags)
+ {
+ swid_tag_id_t *tag_id;
+ enumerator_t *enumerator;
+
+ enumerator = targets->create_enumerator(targets);
+ while (enumerator->enumerate(enumerator, &tag_id))
+ {
+ char software_id[BUF_LEN];
+ chunk_t tag_creator, unique_sw_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)
+ {
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+
+ return status;
+}
+
static bool collect_tags(private_swid_inventory_t *this, char *pathname,
swid_inventory_t *targets)
{
@@ -72,7 +261,8 @@ static bool collect_tags(private_swid_inventory_t *this, char *pathname,
{
char * start, *stop;
chunk_t tag_creator;
- chunk_t unique_sw_id = chunk_empty, unique_seq_id = chunk_empty;
+ chunk_t unique_sw_id = chunk_empty, tag_file_path = chunk_empty;
+
if (!strstr(rel_name, "regid."))
{
continue;
@@ -121,14 +311,7 @@ static bool collect_tags(private_swid_inventory_t *this, char *pathname,
goto end;
}
tag_creator = chunk_create(start, stop-start);
-
start = stop + 1;
- stop = strchr(start, '_');
- if (stop)
- {
- unique_sw_id = chunk_create(start, stop-start);
- start = stop + 1;
- }
stop = strstr(start, ".swidtag");
if (!stop)
@@ -137,18 +320,13 @@ static bool collect_tags(private_swid_inventory_t *this, char *pathname,
DBG1(DBG_IMC, " swidtag postfix not found");
goto end;
}
- if (unique_sw_id.ptr)
- {
- unique_seq_id = chunk_create(start, stop-start);
- }
- else
- {
- unique_sw_id = chunk_create(start, stop-start);
- }
+ unique_sw_id = chunk_create(start, stop-start);
+ tag_file_path = chunk_from_str(abs_name);
/* In case of a targeted request */
if (targets->get_count(targets))
{
+ chunk_t target_unique_sw_id, target_tag_creator;
enumerator_t *target_enumerator;
swid_tag_id_t *tag_id;
bool match = FALSE;
@@ -156,10 +334,11 @@ static bool collect_tags(private_swid_inventory_t *this, char *pathname,
target_enumerator = targets->create_enumerator(targets);
while (target_enumerator->enumerate(target_enumerator, &tag_id))
{
- if (chunk_equals(tag_id->get_unique_sw_id(tag_id, NULL),
- unique_sw_id) &&
- chunk_equals(tag_id->get_tag_creator(tag_id),
- tag_creator))
+ target_unique_sw_id = tag_id->get_unique_sw_id(tag_id, NULL);
+ 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))
{
match = TRUE;
break;
@@ -187,7 +366,7 @@ static bool collect_tags(private_swid_inventory_t *this, char *pathname,
goto end;
}
- tag = swid_tag_create(*xml_tag, unique_seq_id);
+ tag = swid_tag_create(*xml_tag, tag_file_path);
this->list->insert_last(this->list, tag);
chunk_unmap(xml_tag);
}
@@ -195,10 +374,9 @@ static bool collect_tags(private_swid_inventory_t *this, char *pathname,
{
swid_tag_id_t *tag_id;
- tag_id = swid_tag_id_create(tag_creator, unique_sw_id, unique_seq_id);
+ tag_id = swid_tag_id_create(tag_creator, unique_sw_id, tag_file_path);
this->list->insert_last(this->list, tag_id);
}
-
}
success = TRUE;
@@ -210,8 +388,18 @@ end:
}
METHOD(swid_inventory_t, collect, bool,
- private_swid_inventory_t *this, char *directory, swid_inventory_t *targets)
+ private_swid_inventory_t *this, char *directory, char *generator,
+ swid_inventory_t *targets, bool pretty, bool full)
{
+ /**
+ * Tags are generated by a package manager
+ */
+ generate_tags(this, generator, targets, pretty, full);
+
+ /**
+ * Collect swidtag files by iteratively entering all directories in
+ * the tree under the "directory" path.
+ */
return collect_tags(this, directory, targets);
}
diff --git a/src/libpts/swid/swid_inventory.h b/src/libpts/swid/swid_inventory.h
index 68d3047aa..7de8bb221 100644
--- a/src/libpts/swid/swid_inventory.h
+++ b/src/libpts/swid/swid_inventory.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Andreas Steffen
+ * Copyright (C) 2013-2014 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -34,11 +34,14 @@ 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,
- swid_inventory_t *targets);
+ bool (*collect)(swid_inventory_t *this, char *directory, char *generator,
+ swid_inventory_t *targets, bool pretty, bool full);
/**
* Collect the SWID tags stored on the endpoint
diff --git a/src/libpts/swid/swid_tag.c b/src/libpts/swid/swid_tag.c
index 0b6519693..c71d5d2bd 100644
--- a/src/libpts/swid/swid_tag.c
+++ b/src/libpts/swid/swid_tag.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Andreas Steffen
+ * Copyright (C) 2013-2014 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -34,10 +34,14 @@ struct private_swid_tag_t {
chunk_t encoding;
/**
- * Optional Unique Sequence ID
+ * Optional Tag File Path
*/
- chunk_t unique_seq_id;
+ chunk_t tag_file_path;
+ /**
+ * Reference count
+ */
+ refcount_t ref;
};
METHOD(swid_tag_t, get_encoding, chunk_t,
@@ -46,39 +50,51 @@ METHOD(swid_tag_t, get_encoding, chunk_t,
return this->encoding;
}
-METHOD(swid_tag_t, get_unique_seq_id, chunk_t,
+METHOD(swid_tag_t, get_tag_file_path, chunk_t,
private_swid_tag_t *this)
{
- return this->unique_seq_id;
+ return this->tag_file_path;
+}
+
+METHOD(swid_tag_t, get_ref, swid_tag_t*,
+ private_swid_tag_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public;
}
METHOD(swid_tag_t, destroy, void,
private_swid_tag_t *this)
{
- free(this->encoding.ptr);
- free(this->unique_seq_id.ptr);
- free(this);
+ if (ref_put(&this->ref))
+ {
+ free(this->encoding.ptr);
+ free(this->tag_file_path.ptr);
+ free(this);
+ }
}
/**
* See header
*/
-swid_tag_t *swid_tag_create(chunk_t encoding, chunk_t unique_seq_id)
+swid_tag_t *swid_tag_create(chunk_t encoding, chunk_t tag_file_path)
{
private_swid_tag_t *this;
INIT(this,
.public = {
.get_encoding = _get_encoding,
- .get_unique_seq_id = _get_unique_seq_id,
+ .get_tag_file_path = _get_tag_file_path,
+ .get_ref = _get_ref,
.destroy = _destroy,
},
.encoding = chunk_clone(encoding),
+ .ref = 1,
);
- if (unique_seq_id.len > 0)
+ if (tag_file_path.len > 0)
{
- this->unique_seq_id = chunk_clone(unique_seq_id);
+ this->tag_file_path = chunk_clone(tag_file_path);
}
return &this->public;
diff --git a/src/libpts/swid/swid_tag.h b/src/libpts/swid/swid_tag.h
index 9d3f86333..e20c538ea 100644
--- a/src/libpts/swid/swid_tag.h
+++ b/src/libpts/swid/swid_tag.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Andreas Steffen
+ * Copyright (C) 2013-2014 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -39,11 +39,18 @@ struct swid_tag_t {
chunk_t (*get_encoding)(swid_tag_t *this);
/**
- * Get th Optional Unique Sequence ID
+ * Get th Optional Tag File Path
*
- * @return Optional Unique Sequence ID
+ * @return Optional Tag File Path
*/
- chunk_t (*get_unique_seq_id)(swid_tag_t *this);
+ chunk_t (*get_tag_file_path)(swid_tag_t *this);
+
+ /**
+ * Get a new reference to the swid_tag object
+ *
+ * @return this, with an increased refcount
+ */
+ swid_tag_t* (*get_ref)(swid_tag_t *this);
/**
* Destroys a swid_tag_t object.
@@ -56,8 +63,8 @@ struct swid_tag_t {
* Creates a swid_tag_t object
*
* @param encoding XML encoding of SWID tag
- * @param unique_seq_id Unique Sequence ID or empty chunk
+ * @param tag_file_path Tag File Path or empty chunk
*/
-swid_tag_t* swid_tag_create(chunk_t encoding, chunk_t unique_seq_id);
+swid_tag_t* swid_tag_create(chunk_t encoding, chunk_t tag_file_path);
#endif /** SWID_TAG_H_ @}*/
diff --git a/src/libpts/swid/swid_tag_id.c b/src/libpts/swid/swid_tag_id.c
index 7ad486d4b..8bede28a0 100644
--- a/src/libpts/swid/swid_tag_id.c
+++ b/src/libpts/swid/swid_tag_id.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Andreas Steffen
+ * Copyright (C) 2013-2014 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -39,10 +39,14 @@ struct private_swid_tag_id_t {
chunk_t unique_sw_id;
/**
- * Optional Unique Sequence ID
+ * Tag File Path
*/
- chunk_t unique_seq_id;
+ chunk_t tag_file_path;
+ /**
+ * Reference count
+ */
+ refcount_t ref;
};
METHOD(swid_tag_id_t, get_tag_creator, chunk_t,
@@ -52,29 +56,39 @@ METHOD(swid_tag_id_t, get_tag_creator, chunk_t,
}
METHOD(swid_tag_id_t, get_unique_sw_id, chunk_t,
- private_swid_tag_id_t *this, chunk_t *unique_seq_id)
+ private_swid_tag_id_t *this, chunk_t *tag_file_path)
{
- if (unique_seq_id)
+ if (tag_file_path)
{
- *unique_seq_id = this->unique_seq_id;
+ *tag_file_path = this->tag_file_path;
}
return this->unique_sw_id;
}
+METHOD(swid_tag_id_t, get_ref, swid_tag_id_t*,
+ private_swid_tag_id_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public;
+}
+
METHOD(swid_tag_id_t, destroy, void,
private_swid_tag_id_t *this)
{
- free(this->tag_creator.ptr);
- free(this->unique_sw_id.ptr);
- free(this->unique_seq_id.ptr);
- free(this);
+ if (ref_put(&this->ref))
+ {
+ free(this->tag_creator.ptr);
+ free(this->unique_sw_id.ptr);
+ free(this->tag_file_path.ptr);
+ free(this);
+ }
}
/**
* See header
*/
swid_tag_id_t *swid_tag_id_create(chunk_t tag_creator, chunk_t unique_sw_id,
- chunk_t unique_seq_id)
+ chunk_t tag_file_path)
{
private_swid_tag_id_t *this;
@@ -82,15 +96,17 @@ swid_tag_id_t *swid_tag_id_create(chunk_t tag_creator, chunk_t unique_sw_id,
.public = {
.get_tag_creator = _get_tag_creator,
.get_unique_sw_id = _get_unique_sw_id,
+ .get_ref = _get_ref,
.destroy = _destroy,
},
.tag_creator = chunk_clone(tag_creator),
.unique_sw_id = chunk_clone(unique_sw_id),
+ .ref = 1,
);
- if (unique_seq_id.len > 0)
+ if (tag_file_path.len > 0)
{
- this->unique_seq_id = chunk_clone(unique_seq_id);
+ this->tag_file_path = chunk_clone(tag_file_path);
}
return &this->public;
diff --git a/src/libpts/swid/swid_tag_id.h b/src/libpts/swid/swid_tag_id.h
index d4715967d..d2a783b35 100644
--- a/src/libpts/swid/swid_tag_id.h
+++ b/src/libpts/swid/swid_tag_id.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Andreas Steffen
+ * Copyright (C) 2013-2014 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -39,12 +39,19 @@ struct swid_tag_id_t {
chunk_t (*get_tag_creator)(swid_tag_id_t *this);
/**
- * Get the Unique Software ID and optional Unique Sequence ID
+ * Get the Unique Software ID and optional Tag File Path
*
- * @param Optional Unique Sequence ID
+ * @param Optional Tag File Path
* @return Unique Software ID
*/
- chunk_t (*get_unique_sw_id)(swid_tag_id_t *this, chunk_t *unique_seq_id);
+ chunk_t (*get_unique_sw_id)(swid_tag_id_t *this, chunk_t *tag_file_path);
+
+ /**
+ * Get a new reference to the swid_tag_id object
+ *
+ * @return this, with an increased refcount
+ */
+ swid_tag_id_t* (*get_ref)(swid_tag_id_t *this);
/**
* Destroys a swid_tag_id_t object.
@@ -58,9 +65,9 @@ struct swid_tag_id_t {
*
* @param tag_creator Tag Creator
* @param unique_sw_id Unique Software ID
- * @param unique_seq_id Unique Sequence ID or empty chunk
+ * @param tag_file_path Tag File Path or empty chunk
*/
swid_tag_id_t* swid_tag_id_create(chunk_t tag_creator, chunk_t unique_sw_id,
- chunk_t unique_seq_id);
+ chunk_t tag_file_path);
#endif /** SWID_TAG_ID_H_ @}*/