From: Andreas Steffen Date: Fri, 23 May 2014 21:26:44 +0000 (+0200) Subject: Support targeted retrieval of SWID tags X-Git-Tag: 5.2.0dr5~22 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b7679e90e34519417792ac469584e1e9b8da6831;p=thirdparty%2Fstrongswan.git Support targeted retrieval of SWID tags --- diff --git a/src/libpts/swid/swid_inventory.c b/src/libpts/swid/swid_inventory.c index f81d9a92b1..4e696ef33e 100644 --- a/src/libpts/swid/swid_inventory.c +++ b/src/libpts/swid/swid_inventory.c @@ -52,120 +52,188 @@ struct private_swid_inventory_t { linked_list_t *list; }; -static status_t generate_tags(private_swid_inventory_t *this, char *generator, - swid_inventory_t *targets, bool pretty, bool full) +/** + * Read SWID tags issued by the swid_generator tool + */ +static status_t read_swid_tags(private_swid_inventory_t *this, FILE *file) { - FILE *file; - char command[512], line[2048]; - char entity_name = "strongSwan Project"; - chunk_t tag_creator, unique_sw_id, tag_file_path = chunk_empty; - swid_tag_id_t *tag_id; swid_tag_t *tag; - status_t status = SUCCESS; + bio_writer_t *writer; + chunk_t tag_encoding, tag_file_path = chunk_empty; + bool more_tags = TRUE, end_of_tag; + char line[131072]; - /* Assemble the SWID generator command */ - snprintf(command, sizeof(command), "%s %s %s%s%s%s\n", generator, - (this->full_tags) ? "swid" : "software-id", - (this->full_tags && entity_name) ? entity_name : "", - (this->full_tags && pretty) ? " --pretty" : "", - (this->full_tags && !pretty) ? " --doc-separator $'\n\n'" : "", - (this->full_tags && full) ? " --full" : ""); - - /* Open a pipe stream for reading the output of the dpkg-query commmand */ - file = popen(command, "r"); - if (!file) - { - DBG1(DBG_IMC, "failed to run swid_generator command"); - return NOT_SUPPORTED; - } - if (this->full_tags) + while (more_tags) { - bio_writer_t *writer; - chunk_t tag_encoding; - bool more_tags = TRUE, end_of_tag; - - DBG2(DBG_IMC, "SWID tags generated by package manager:"); - while (more_tags) + end_of_tag = FALSE; + writer = bio_writer_create(512); + do { - end_of_tag = FALSE; - writer = bio_writer_create(512); - do + if (fgets(line, sizeof(line), file) <= 0) { - if (fgets(line, sizeof(line), file) <= 0) - { - more_tags = FALSE; - end_of_tag = TRUE; - break; - } - if (line[0] == '\n') - { - end_of_tag = TRUE; - break; - } - else - { - writer->write_data(writer, chunk_from_str(line)); - } + more_tags = FALSE; + end_of_tag = TRUE; + break; + } + if (line[0] == '\n') + { + end_of_tag = TRUE; + break; } - while (!end_of_tag); + else + { + writer->write_data(writer, chunk_from_str(line)); + } + } + while (!end_of_tag); - tag_encoding = writer->get_buf(writer); + tag_encoding = writer->get_buf(writer); - if (tag_encoding.len > 1) + if (tag_encoding.len > 1) + { + /* remove trailing newline if present */ + if (tag_encoding.ptr[tag_encoding.len - 1] == '\n') { - /* remove trailing newline if present */ - if (tag_encoding.ptr[tag_encoding.len - 1] == '\n') - { - tag_encoding.len--; - } - DBG2(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); + tag_encoding.len--; } - writer->destroy(writer); + DBG2(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); } - else + + 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) { - DBG2(DBG_IMC, "SWID tag IDs generated by package manager:"); - while (TRUE) + char *separator; + size_t len; + + if (fgets(line, sizeof(line), file) <= 0) { - char *separator; - size_t len; + return SUCCESS; + } + len = strlen(line); - if (fgets(line, sizeof(line), file) <= 0) - { - goto end; - } - len = strlen(line); + /* remove trailing newline if present */ + if (len > 0 && line[len - 1] == '\n') + { + len--; + } + DBG2(DBG_IMC, " %.*s", len, line); - /* remove trailing newline if present */ - if (len > 0 && line[len - 1] == '\n') + 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 entity_name[] = "strongSwan Project"; + 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 --entity-name \"%s\" %s%s", + generator, entity_name, + pretty ? "--pretty" : "--doc-separator $'\n\n'", + 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 tags generated by package manager:"); + status = read_swid_tags(this, file); + } + else + { + DBG2(DBG_IMC, "SWID tag IDs generated 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 " + "--entity-name \"%s\"%s%s", + generator, software_id, entity_name, + pretty ? " --pretty" : "", + full ? " --full" : ""); + + /* Open a pipe stream for reading the SWID generator output */ + file = popen(command, "r"); + if (!file) { - len--; + DBG1(DBG_IMC, "failed to run swid_generator command"); + return NOT_SUPPORTED; } - DBG2(DBG_IMC, " %.*s", len, line); + status = read_swid_tags(this, file); + pclose(file); - separator = strchr(line, '_'); - if (!separator) + if (status != SUCCESS) { - DBG1(DBG_IMC, "separation of regid from unique software ID " - "failed"); - status = FAILED; - goto end; + break; } - 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); } + enumerator->destroy(enumerator); } -end: - pclose(file); return status; } @@ -191,6 +259,7 @@ 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, tag_file_path = chunk_empty; + if (!strstr(rel_name, "regid.")) { continue; @@ -254,6 +323,7 @@ static bool collect_tags(private_swid_inventory_t *this, char *pathname, /* 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; @@ -261,10 +331,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;