Support targeted retrieval of SWID tags
This commit is contained in:
+176
-105
@@ -52,120 +52,188 @@ struct private_swid_inventory_t {
|
|||||||
linked_list_t *list;
|
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, end_of_tag;
|
||||||
|
char line[131072];
|
||||||
|
|
||||||
|
while (more_tags)
|
||||||
|
{
|
||||||
|
end_of_tag = FALSE;
|
||||||
|
writer = bio_writer_create(512);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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--;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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) <= 0)
|
||||||
|
{
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
len = strlen(line);
|
||||||
|
|
||||||
|
/* remove trailing newline if present */
|
||||||
|
if (len > 0 && line[len - 1] == '\n')
|
||||||
|
{
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
DBG2(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,
|
static status_t generate_tags(private_swid_inventory_t *this, char *generator,
|
||||||
swid_inventory_t *targets, bool pretty, bool full)
|
swid_inventory_t *targets, bool pretty, bool full)
|
||||||
{
|
{
|
||||||
FILE *file;
|
FILE *file;
|
||||||
char command[512], line[2048];
|
char command[BUF_LEN];
|
||||||
char entity_name = "strongSwan Project";
|
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;
|
status_t status = SUCCESS;
|
||||||
|
|
||||||
/* Assemble the SWID generator command */
|
if (targets->get_count(targets) == 0)
|
||||||
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");
|
/* Assemble the SWID generator command */
|
||||||
return NOT_SUPPORTED;
|
if (this->full_tags)
|
||||||
}
|
|
||||||
if (this->full_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;
|
snprintf(command, BUF_LEN, "%s swid --entity-name \"%s\" %s%s",
|
||||||
writer = bio_writer_create(512);
|
generator, entity_name,
|
||||||
do
|
pretty ? "--pretty" : "--doc-separator $'\n\n'",
|
||||||
{
|
full ? " --full" : "");
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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--;
|
|
||||||
}
|
|
||||||
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
|
||||||
else
|
|
||||||
{
|
|
||||||
DBG2(DBG_IMC, "SWID tag IDs generated by package manager:");
|
|
||||||
while (TRUE)
|
|
||||||
{
|
{
|
||||||
char *separator;
|
snprintf(command, BUF_LEN, "%s software-id", generator);
|
||||||
size_t len;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
separator = strchr(line, '_');
|
|
||||||
if (!separator)
|
|
||||||
{
|
|
||||||
DBG1(DBG_IMC, "separation of regid from unique software ID "
|
|
||||||
"failed");
|
|
||||||
status = FAILED;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
|
||||||
pclose(file);
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,6 +259,7 @@ static bool collect_tags(private_swid_inventory_t *this, char *pathname,
|
|||||||
char * start, *stop;
|
char * start, *stop;
|
||||||
chunk_t tag_creator;
|
chunk_t tag_creator;
|
||||||
chunk_t unique_sw_id = chunk_empty, tag_file_path = chunk_empty;
|
chunk_t unique_sw_id = chunk_empty, tag_file_path = chunk_empty;
|
||||||
|
|
||||||
if (!strstr(rel_name, "regid."))
|
if (!strstr(rel_name, "regid."))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@@ -254,6 +323,7 @@ static bool collect_tags(private_swid_inventory_t *this, char *pathname,
|
|||||||
/* In case of a targeted request */
|
/* In case of a targeted request */
|
||||||
if (targets->get_count(targets))
|
if (targets->get_count(targets))
|
||||||
{
|
{
|
||||||
|
chunk_t target_unique_sw_id, target_tag_creator;
|
||||||
enumerator_t *target_enumerator;
|
enumerator_t *target_enumerator;
|
||||||
swid_tag_id_t *tag_id;
|
swid_tag_id_t *tag_id;
|
||||||
bool match = FALSE;
|
bool match = FALSE;
|
||||||
@@ -261,10 +331,11 @@ static bool collect_tags(private_swid_inventory_t *this, char *pathname,
|
|||||||
target_enumerator = targets->create_enumerator(targets);
|
target_enumerator = targets->create_enumerator(targets);
|
||||||
while (target_enumerator->enumerate(target_enumerator, &tag_id))
|
while (target_enumerator->enumerate(target_enumerator, &tag_id))
|
||||||
{
|
{
|
||||||
if (chunk_equals(tag_id->get_unique_sw_id(tag_id, NULL),
|
target_unique_sw_id = tag_id->get_unique_sw_id(tag_id, NULL);
|
||||||
unique_sw_id) &&
|
target_tag_creator = tag_id->get_tag_creator(tag_id);
|
||||||
chunk_equals(tag_id->get_tag_creator(tag_id),
|
|
||||||
tag_creator))
|
if (chunk_equals(target_unique_sw_id, unique_sw_id) &&
|
||||||
|
chunk_equals(target_tag_creator, tag_creator))
|
||||||
{
|
{
|
||||||
match = TRUE;
|
match = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user