diff options
Diffstat (limited to 'src/libpts/swid')
-rw-r--r-- | src/libpts/swid/swid_error.c | 2 | ||||
-rw-r--r-- | src/libpts/swid/swid_inventory.c | 238 | ||||
-rw-r--r-- | src/libpts/swid/swid_inventory.h | 9 | ||||
-rw-r--r-- | src/libpts/swid/swid_tag.c | 40 | ||||
-rw-r--r-- | src/libpts/swid/swid_tag.h | 19 | ||||
-rw-r--r-- | src/libpts/swid/swid_tag_id.c | 42 | ||||
-rw-r--r-- | src/libpts/swid/swid_tag_id.h | 19 |
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_ @}*/ |