swid-gen: Share SWID generator between sw-collector, imc-swima and imc-swid
This commit is contained in:
parent
073c179a88
commit
88501a64ca
|
@ -21,6 +21,15 @@ charon.imcv.os_info.default_password_enabled = no
|
||||||
charon.imcv.policy_script = ipsec _imv_policy
|
charon.imcv.policy_script = ipsec _imv_policy
|
||||||
Script called for each TNC connection to generate IMV policies.
|
Script called for each TNC connection to generate IMV policies.
|
||||||
|
|
||||||
|
libimcv.swid_gen.command = /usr/local/bin/swid_generator
|
||||||
|
SWID generator command to be executed.
|
||||||
|
|
||||||
|
libimcv.swid_gen.tag_creator.name = strongSwan Project
|
||||||
|
Name of the tagCreator entity.
|
||||||
|
|
||||||
|
libimcv.swid_gen.tag_creator.regid = strongswan.org
|
||||||
|
regid of the tagCreator entity.
|
||||||
|
|
||||||
libimcv.debug_level = 1
|
libimcv.debug_level = 1
|
||||||
Debug level for a stand-alone _libimcv_ library.
|
Debug level for a stand-alone _libimcv_ library.
|
||||||
|
|
||||||
|
|
|
@ -22,14 +22,5 @@ sw-collector.rest_api.uri =
|
||||||
sw-collector.rest_api.timeout = 120
|
sw-collector.rest_api.timeout = 120
|
||||||
Timeout of REST API HTTP POST transaction.
|
Timeout of REST API HTTP POST transaction.
|
||||||
|
|
||||||
sw-collector.tag_creator.name = strongSwan Project
|
|
||||||
Name of the tagCreator entity.
|
|
||||||
|
|
||||||
sw-collector.tag_creator.regid = strongswan.org
|
|
||||||
regid of the tagCreator entity.
|
|
||||||
|
|
||||||
sw-collector.swid_generator = /usr/local/bin/swid_generator
|
|
||||||
SWID generator command to be executed.
|
|
||||||
|
|
||||||
sw-collector.load =
|
sw-collector.load =
|
||||||
Plugins to load in sw-collector tool.
|
Plugins to load in sw-collector tool.
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
libimcv.plugins.imc-swid.swid_directory = ${prefix}/share
|
libimcv.plugins.imc-swid.swid_directory = ${prefix}/share
|
||||||
Directory where SWID tags are located.
|
Directory where SWID tags are located.
|
||||||
|
|
||||||
libimcv.plugins.imc-swid.swid_generator = /usr/local/bin/swid_generator
|
|
||||||
SWID generator command to be executed.
|
|
||||||
|
|
||||||
libimcv.plugins.imc-swid.swid_pretty = FALSE
|
libimcv.plugins.imc-swid.swid_pretty = FALSE
|
||||||
Generate XML-encoded SWID tags with pretty indentation.
|
Generate XML-encoded SWID tags with pretty indentation.
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,6 @@ libimcv.plugins.imc-swima.swid_epoch = 0x11223344
|
||||||
libimcv.plugins.imc-swima.swid_directory = ${prefix}/share
|
libimcv.plugins.imc-swima.swid_directory = ${prefix}/share
|
||||||
Directory where SWID tags are located.
|
Directory where SWID tags are located.
|
||||||
|
|
||||||
libimcv.plugins.imc-swima.swid_generator = /usr/local/bin/swid_generator
|
|
||||||
SWID generator command to be executed.
|
|
||||||
|
|
||||||
libimcv.plugins.imc-swima.swid_pretty = FALSE
|
libimcv.plugins.imc-swima.swid_pretty = FALSE
|
||||||
Generate XML-encoded SWID tags with pretty indentation.
|
Generate XML-encoded SWID tags with pretty indentation.
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,7 @@ libimcv_la_SOURCES = \
|
||||||
swid/swid_inventory.h swid/swid_inventory.c \
|
swid/swid_inventory.h swid/swid_inventory.c \
|
||||||
swid/swid_tag.h swid/swid_tag.c \
|
swid/swid_tag.h swid/swid_tag.c \
|
||||||
swid/swid_tag_id.h swid/swid_tag_id.c \
|
swid/swid_tag_id.h swid/swid_tag_id.c \
|
||||||
|
swid_gen/swid_gen.h swid_gen/swid_gen.c \
|
||||||
swima/swima_data_model.h swima/swima_data_model.c \
|
swima/swima_data_model.h swima/swima_data_model.c \
|
||||||
swima/swima_record.h swima/swima_record.c \
|
swima/swima_record.h swima/swima_record.c \
|
||||||
swima/swima_event.h swima/swima_event.c \
|
swima/swima_event.h swima/swima_event.c \
|
||||||
|
@ -214,6 +215,7 @@ imcv_tests_SOURCES = \
|
||||||
pa_tnc/pa_tnc_attr_manager.c \
|
pa_tnc/pa_tnc_attr_manager.c \
|
||||||
seg/seg_env.c seg/seg_contract.c \
|
seg/seg_env.c seg/seg_contract.c \
|
||||||
seg/seg_contract_manager.c \
|
seg/seg_contract_manager.c \
|
||||||
|
swid_gen/swid_gen.c \
|
||||||
swima/swima_data_model.c \
|
swima/swima_data_model.c \
|
||||||
swima/swima_event.c \
|
swima/swima_event.c \
|
||||||
swima/swima_events.c \
|
swima/swima_events.c \
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2013-2015 Andreas Steffen
|
* Copyright (C) 2013-2017 Andreas Steffen
|
||||||
* HSR Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
@ -30,8 +30,6 @@
|
||||||
#include <pen/pen.h>
|
#include <pen/pen.h>
|
||||||
#include <utils/debug.h>
|
#include <utils/debug.h>
|
||||||
|
|
||||||
#define SWID_GENERATOR "/usr/local/bin/swid_generator"
|
|
||||||
|
|
||||||
/* IMC definitions */
|
/* IMC definitions */
|
||||||
|
|
||||||
static const char imc_name[] = "SWID";
|
static const char imc_name[] = "SWID";
|
||||||
|
@ -165,7 +163,7 @@ static bool add_swid_inventory(imc_state_t *state, imc_msg_t *msg,
|
||||||
pa_tnc_attr_t *attr, *attr_error;
|
pa_tnc_attr_t *attr, *attr_error;
|
||||||
imc_swid_state_t *swid_state;
|
imc_swid_state_t *swid_state;
|
||||||
swid_inventory_t *swid_inventory;
|
swid_inventory_t *swid_inventory;
|
||||||
char *swid_directory, *swid_generator;
|
char *swid_directory;
|
||||||
uint32_t eid_epoch;
|
uint32_t eid_epoch;
|
||||||
bool swid_pretty, swid_full;
|
bool swid_pretty, swid_full;
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
|
@ -173,9 +171,6 @@ static bool add_swid_inventory(imc_state_t *state, imc_msg_t *msg,
|
||||||
swid_directory = lib->settings->get_str(lib->settings,
|
swid_directory = lib->settings->get_str(lib->settings,
|
||||||
"%s.plugins.imc-swid.swid_directory",
|
"%s.plugins.imc-swid.swid_directory",
|
||||||
SWID_DIRECTORY, lib->ns);
|
SWID_DIRECTORY, lib->ns);
|
||||||
swid_generator = lib->settings->get_str(lib->settings,
|
|
||||||
"%s.plugins.imc-swid.swid_generator",
|
|
||||||
SWID_GENERATOR, lib->ns);
|
|
||||||
swid_pretty = lib->settings->get_bool(lib->settings,
|
swid_pretty = lib->settings->get_bool(lib->settings,
|
||||||
"%s.plugins.imc-swid.swid_pretty",
|
"%s.plugins.imc-swid.swid_pretty",
|
||||||
FALSE, lib->ns);
|
FALSE, lib->ns);
|
||||||
|
@ -184,8 +179,8 @@ static bool add_swid_inventory(imc_state_t *state, imc_msg_t *msg,
|
||||||
FALSE, lib->ns);
|
FALSE, lib->ns);
|
||||||
|
|
||||||
swid_inventory = swid_inventory_create(full_tags);
|
swid_inventory = swid_inventory_create(full_tags);
|
||||||
if (!swid_inventory->collect(swid_inventory, swid_directory, swid_generator,
|
if (!swid_inventory->collect(swid_inventory, swid_directory, targets,
|
||||||
targets, swid_pretty, swid_full))
|
swid_pretty, swid_full))
|
||||||
{
|
{
|
||||||
swid_inventory->destroy(swid_inventory);
|
swid_inventory->destroy(swid_inventory);
|
||||||
attr_error = swid_error_create(TCG_SWID_ERROR, request_id,
|
attr_error = swid_error_create(TCG_SWID_ERROR, request_id,
|
||||||
|
|
|
@ -590,7 +590,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
|
||||||
DBG1(DBG_IMV, " %s", target);
|
DBG1(DBG_IMV, " %s", target);
|
||||||
|
|
||||||
/* Separate target into tag_creator and unique_sw_id */
|
/* Separate target into tag_creator and unique_sw_id */
|
||||||
separator = strchr(target, '_');
|
separator = strstr(target, "__");
|
||||||
if (!separator)
|
if (!separator)
|
||||||
{
|
{
|
||||||
error_str = "separation of regid from "
|
error_str = "separation of regid from "
|
||||||
|
@ -598,9 +598,9 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tag_creator = chunk_create(target, separator - target);
|
tag_creator = chunk_create(target, separator - target);
|
||||||
separator++;
|
separator += 2;
|
||||||
unique_sw_id = chunk_create(separator, strlen(target) -
|
unique_sw_id = chunk_create(separator, strlen(target) -
|
||||||
tag_creator.len - 1);
|
tag_creator.len - 2);
|
||||||
tag_id = swid_tag_id_create(tag_creator, unique_sw_id,
|
tag_id = swid_tag_id_create(tag_creator, unique_sw_id,
|
||||||
chunk_empty);
|
chunk_empty);
|
||||||
cast_attr = (tcg_swid_attr_req_t*)attr;
|
cast_attr = (tcg_swid_attr_req_t*)attr;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2013-2016 Andreas Steffen
|
* Copyright (C) 2013-2017 Andreas Steffen
|
||||||
* HSR Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
@ -288,8 +288,8 @@ METHOD(imv_swid_state_t, get_request_id, uint32_t,
|
||||||
METHOD(imv_swid_state_t, set_swid_inventory, void,
|
METHOD(imv_swid_state_t, set_swid_inventory, void,
|
||||||
private_imv_swid_state_t *this, swid_inventory_t *inventory)
|
private_imv_swid_state_t *this, swid_inventory_t *inventory)
|
||||||
{
|
{
|
||||||
chunk_t tag_creator, unique_sw_id;
|
chunk_t tag_creator, sw_id;
|
||||||
char software_id[256];
|
char software_id[BUF_LEN];
|
||||||
json_object *jstring;
|
json_object *jstring;
|
||||||
swid_tag_id_t *tag_id;
|
swid_tag_id_t *tag_id;
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
|
@ -299,10 +299,9 @@ METHOD(imv_swid_state_t, set_swid_inventory, void,
|
||||||
{
|
{
|
||||||
/* Construct software ID from tag creator and unique software ID */
|
/* Construct software ID from tag creator and unique software ID */
|
||||||
tag_creator = tag_id->get_tag_creator(tag_id);
|
tag_creator = tag_id->get_tag_creator(tag_id);
|
||||||
unique_sw_id = tag_id->get_unique_sw_id(tag_id, NULL);
|
sw_id = tag_id->get_unique_sw_id(tag_id, NULL);
|
||||||
snprintf(software_id, 256, "%.*s_%.*s",
|
snprintf(software_id, BUF_LEN, "%.*s__%.*s",
|
||||||
tag_creator.len, tag_creator.ptr,
|
tag_creator.len, tag_creator.ptr, sw_id.len, sw_id.ptr);
|
||||||
unique_sw_id.len, unique_sw_id.ptr);
|
|
||||||
DBG3(DBG_IMV, " %s", software_id);
|
DBG3(DBG_IMV, " %s", software_id);
|
||||||
|
|
||||||
/* Add software ID to JSON array */
|
/* Add software ID to JSON array */
|
||||||
|
|
|
@ -16,9 +16,10 @@
|
||||||
#include "swid_inventory.h"
|
#include "swid_inventory.h"
|
||||||
#include "swid_tag.h"
|
#include "swid_tag.h"
|
||||||
#include "swid_tag_id.h"
|
#include "swid_tag_id.h"
|
||||||
|
#include "swid_gen/swid_gen.h"
|
||||||
|
|
||||||
#include <collections/linked_list.h>
|
#include <collections/linked_list.h>
|
||||||
#include <bio/bio_writer.h>
|
#include <utils/lexparser.h>
|
||||||
#include <utils/debug.h>
|
#include <utils/debug.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -52,186 +53,92 @@ struct private_swid_inventory_t {
|
||||||
linked_list_t *list;
|
linked_list_t *list;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
static status_t generate_tags(private_swid_inventory_t *this,
|
||||||
* 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;
|
|
||||||
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)
|
swid_inventory_t *targets, bool pretty, bool full)
|
||||||
{
|
{
|
||||||
FILE *file;
|
swid_gen_t *swid_gen;
|
||||||
char command[BUF_LEN];
|
swid_tag_t *tag;
|
||||||
char doc_separator[] = "'\n\n'";
|
swid_tag_id_t *tag_id;
|
||||||
|
enumerator_t *enumerator;
|
||||||
status_t status = SUCCESS;
|
status_t status = SUCCESS;
|
||||||
|
chunk_t out;
|
||||||
|
|
||||||
|
swid_gen = swid_gen_create();
|
||||||
|
|
||||||
if (targets->get_count(targets) == 0)
|
if (targets->get_count(targets) == 0)
|
||||||
{
|
{
|
||||||
/* Assemble the SWID generator command */
|
DBG2(DBG_IMC, "SWID tag%s generation by package manager",
|
||||||
if (this->full_tags)
|
this->full_tags ? "" : " ID");
|
||||||
|
|
||||||
|
enumerator = swid_gen->create_tag_enumerator(swid_gen, !this->full_tags,
|
||||||
|
full, pretty);
|
||||||
|
if (enumerator)
|
||||||
{
|
{
|
||||||
snprintf(command, BUF_LEN, "%s swid --doc-separator %s%s%s",
|
while (enumerator->enumerate(enumerator, &out))
|
||||||
generator, doc_separator, pretty ? " --pretty" : "",
|
{
|
||||||
full ? " --full" : "");
|
if (this->full_tags)
|
||||||
|
{
|
||||||
|
chunk_t swid_tag = out;
|
||||||
|
|
||||||
|
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
|
else
|
||||||
{
|
{
|
||||||
snprintf(command, BUF_LEN, "%s software-id", generator);
|
status = NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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)
|
else if (this->full_tags)
|
||||||
{
|
{
|
||||||
swid_tag_id_t *tag_id;
|
DBG2(DBG_IMC, "targeted SWID tag generation");
|
||||||
enumerator_t *enumerator;
|
|
||||||
|
|
||||||
enumerator = targets->create_enumerator(targets);
|
enumerator = targets->create_enumerator(targets);
|
||||||
while (enumerator->enumerate(enumerator, &tag_id))
|
while (enumerator->enumerate(enumerator, &tag_id))
|
||||||
{
|
{
|
||||||
char software_id[BUF_LEN];
|
char software_id[BUF_LEN], *swid_tag;
|
||||||
chunk_t tag_creator, unique_sw_id;
|
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);
|
tag_creator = tag_id->get_tag_creator(tag_id);
|
||||||
unique_sw_id = tag_id->get_unique_sw_id(tag_id, NULL);
|
sw_id = tag_id->get_unique_sw_id(tag_id, NULL);
|
||||||
snprintf(software_id, BUF_LEN, "%.*s_%.*s",
|
snprintf(software_id, BUF_LEN, "%.*s__%.*s",
|
||||||
tag_creator.len, tag_creator.ptr,
|
tag_creator.len, tag_creator.ptr, sw_id.len, sw_id.ptr);
|
||||||
unique_sw_id.len, unique_sw_id.ptr);
|
|
||||||
|
|
||||||
/* Assemble the SWID generator command */
|
swid_tag = swid_gen->generate_tag(swid_gen, software_id, NULL, NULL,
|
||||||
snprintf(command, BUF_LEN, "%s swid --software-id %s%s%s",
|
full, pretty);
|
||||||
generator, software_id, pretty ? " --pretty" : "",
|
if (swid_tag)
|
||||||
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");
|
tag = swid_tag_create(chunk_from_str(swid_tag), chunk_empty);
|
||||||
return NOT_SUPPORTED;
|
this->list->insert_last(this->list, tag);
|
||||||
}
|
free(swid_tag);
|
||||||
status = read_swid_tags(this, file);
|
|
||||||
pclose(file);
|
|
||||||
|
|
||||||
if (status != SUCCESS)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
}
|
}
|
||||||
|
swid_gen->destroy(swid_gen);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -284,16 +191,16 @@ static bool collect_tags(private_swid_inventory_t *this, char *pathname,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse the swidtag filename into its components */
|
/* parse the swidtag filename into its components */
|
||||||
separator = strchr(rel_name, '_');
|
separator = strstr(rel_name, "__");
|
||||||
if (!separator)
|
if (!separator)
|
||||||
{
|
{
|
||||||
DBG1(DBG_IMC, " %s", rel_name);
|
DBG1(DBG_IMC, " %s", rel_name);
|
||||||
DBG1(DBG_IMC, " '_' separator not found");
|
DBG1(DBG_IMC, " '__' separator not found");
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
tag_creator = chunk_create(rel_name, separator-rel_name);
|
tag_creator = chunk_create(rel_name, separator-rel_name);
|
||||||
|
|
||||||
unique_sw_id = chunk_create(separator+1, suffix-separator-1);
|
unique_sw_id = chunk_create(separator+2, suffix-separator-2);
|
||||||
tag_file_path = chunk_from_str(abs_name);
|
tag_file_path = chunk_from_str(abs_name);
|
||||||
|
|
||||||
/* In case of a targeted request */
|
/* In case of a targeted request */
|
||||||
|
@ -364,13 +271,13 @@ end:
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(swid_inventory_t, collect, bool,
|
METHOD(swid_inventory_t, collect, bool,
|
||||||
private_swid_inventory_t *this, char *directory, char *generator,
|
private_swid_inventory_t *this, char *directory, swid_inventory_t *targets,
|
||||||
swid_inventory_t *targets, bool pretty, bool full)
|
bool pretty, bool full)
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Tags are generated by a package manager
|
* 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
|
* Collect swidtag files by iteratively entering all directories in
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2013-2014 Andreas Steffen
|
* Copyright (C) 2013-2017 Andreas Steffen
|
||||||
* HSR Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
@ -37,13 +37,12 @@ struct swid_inventory_t {
|
||||||
* Collect the SWID tags stored on the endpoint
|
* Collect the SWID tags stored on the endpoint
|
||||||
*
|
*
|
||||||
* @param directory SWID directory path
|
* @param directory SWID directory path
|
||||||
* @param generator Path to SWID generator
|
|
||||||
* @param targets List of target tag IDs
|
* @param targets List of target tag IDs
|
||||||
* @param pretty Generate indented XML SWID tags
|
* @param pretty Generate indented XML SWID tags
|
||||||
* @param full Include file information in SWID tags
|
* @param full Include file information in SWID tags
|
||||||
* @return TRUE if successful
|
* @return TRUE if successful
|
||||||
*/
|
*/
|
||||||
bool (*collect)(swid_inventory_t *this, char *directory, char *generator,
|
bool (*collect)(swid_inventory_t *this, char *directory,
|
||||||
swid_inventory_t *targets, bool pretty, bool full);
|
swid_inventory_t *targets, bool pretty, bool full);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,291 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Andreas Steffen
|
||||||
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "swid_gen.h"
|
||||||
|
|
||||||
|
#include <bio/bio_writer.h>
|
||||||
|
|
||||||
|
#define SWID_GENERATOR "/usr/local/bin/swid_generator"
|
||||||
|
|
||||||
|
typedef struct private_swid_gen_t private_swid_gen_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private data of a swid_gen_t object.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct private_swid_gen_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public swid_gen_t interface.
|
||||||
|
*/
|
||||||
|
swid_gen_t public;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path of the SWID generator command
|
||||||
|
*/
|
||||||
|
char *generator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entity name of the tagCreator
|
||||||
|
*/
|
||||||
|
char *entity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regid of the tagCreator
|
||||||
|
*/
|
||||||
|
char *regid;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
METHOD(swid_gen_t, generate_tag, char*,
|
||||||
|
private_swid_gen_t *this, char *sw_id, char *package, char *version,
|
||||||
|
bool full, bool pretty)
|
||||||
|
{
|
||||||
|
char *tag = NULL;
|
||||||
|
size_t tag_buf_len = 8192;
|
||||||
|
char tag_buf[tag_buf_len], command[BUF_LEN];
|
||||||
|
bio_writer_t *writer;
|
||||||
|
chunk_t swid_tag;
|
||||||
|
FILE *file;
|
||||||
|
|
||||||
|
/* Compose the SWID generator command */
|
||||||
|
if (full || !package || !version)
|
||||||
|
{
|
||||||
|
snprintf(command, BUF_LEN, "%s swid --entity-name \"%s\" "
|
||||||
|
"--regid %s --software-id %s%s%s",
|
||||||
|
this->generator, this->entity, this->regid, sw_id,
|
||||||
|
full ? " --full" : "", pretty ? " --pretty" : "");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snprintf(command, BUF_LEN, "%s swid --entity-name \"%s\" "
|
||||||
|
"--regid %s --name %s --version-string %s%s",
|
||||||
|
this->generator, this->entity, this->regid, package,
|
||||||
|
version, pretty ? " --pretty" : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open a pipe stream for reading the SWID generator output */
|
||||||
|
file = popen(command, "r");
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
writer = bio_writer_create(tag_buf_len);
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
if (!fgets(tag_buf, tag_buf_len, file))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
writer->write_data(writer, chunk_create(tag_buf, strlen(tag_buf)));
|
||||||
|
}
|
||||||
|
pclose(file);
|
||||||
|
swid_tag = writer->extract_buf(writer);
|
||||||
|
writer->destroy(writer);
|
||||||
|
|
||||||
|
if (swid_tag.len > 0)
|
||||||
|
{
|
||||||
|
tag = swid_tag.ptr;
|
||||||
|
tag[swid_tag.len - 1] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chunk_free(&swid_tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG1(DBG_IMC, "failed to run swid_generator command");
|
||||||
|
}
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/** public enumerator interface */
|
||||||
|
enumerator_t public;
|
||||||
|
/** swid_generator output stream */
|
||||||
|
FILE *file;
|
||||||
|
/** generate software identifier only */
|
||||||
|
bool sw_id_only;
|
||||||
|
} swid_gen_enumerator_t;
|
||||||
|
|
||||||
|
METHOD(enumerator_t, enumerate, bool,
|
||||||
|
swid_gen_enumerator_t *this, va_list args)
|
||||||
|
{
|
||||||
|
chunk_t *out;
|
||||||
|
|
||||||
|
VA_ARGS_VGET(args, out);
|
||||||
|
|
||||||
|
if (this->sw_id_only)
|
||||||
|
{
|
||||||
|
char line[BUF_LEN];
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (!fgets(line, sizeof(line), this->file))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
len = strlen(line);
|
||||||
|
|
||||||
|
if (len == 0)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove trailing newline if present */
|
||||||
|
if (line[len - 1] == '\n')
|
||||||
|
{
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
DBG3(DBG_IMC, " %.*s", len, line);
|
||||||
|
*out = chunk_clone(chunk_create(line, len));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool last_newline = TRUE;
|
||||||
|
size_t len, line_len = 8192;
|
||||||
|
char line[line_len];
|
||||||
|
bio_writer_t *writer;
|
||||||
|
chunk_t swid_tag;
|
||||||
|
|
||||||
|
writer = bio_writer_create(line_len);
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
if (!fgets(line, line_len, this->file))
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
swid_tag = writer->extract_buf(writer);
|
||||||
|
writer->destroy(writer);
|
||||||
|
|
||||||
|
if (swid_tag.len <= 1)
|
||||||
|
{
|
||||||
|
chunk_free(&swid_tag);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove trailing newline if present */
|
||||||
|
if (swid_tag.ptr[swid_tag.len - 1] == '\n')
|
||||||
|
{
|
||||||
|
swid_tag.len--;
|
||||||
|
}
|
||||||
|
DBG3(DBG_IMC, " %.*s", swid_tag.len, swid_tag.ptr);
|
||||||
|
*out = swid_tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(enumerator_t, enumerator_destroy, void,
|
||||||
|
swid_gen_enumerator_t *this)
|
||||||
|
{
|
||||||
|
pclose(this->file);
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(swid_gen_t, create_tag_enumerator, enumerator_t*,
|
||||||
|
private_swid_gen_t *this, bool sw_id_only, bool full, bool pretty)
|
||||||
|
{
|
||||||
|
swid_gen_enumerator_t *enumerator;
|
||||||
|
char command[BUF_LEN];
|
||||||
|
char doc_separator[] = "'\n\n'";
|
||||||
|
FILE *file;
|
||||||
|
|
||||||
|
/* Assemble the SWID generator command */
|
||||||
|
if (sw_id_only)
|
||||||
|
{
|
||||||
|
snprintf(command, BUF_LEN, "%s software-id --regid %s ",
|
||||||
|
this->generator, this->regid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snprintf(command, BUF_LEN, "%s swid --entity-name \"%s\" --regid %s "
|
||||||
|
"--doc-separator %s%s%s", this->generator, this->entity,
|
||||||
|
this->regid, doc_separator, 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 NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
INIT(enumerator,
|
||||||
|
.public = {
|
||||||
|
.enumerate = enumerator_enumerate_default,
|
||||||
|
.venumerate = _enumerate,
|
||||||
|
.destroy = _enumerator_destroy,
|
||||||
|
},
|
||||||
|
.sw_id_only = sw_id_only,
|
||||||
|
.file = file,
|
||||||
|
);
|
||||||
|
|
||||||
|
return &enumerator->public;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(swid_gen_t, destroy, void,
|
||||||
|
private_swid_gen_t *this)
|
||||||
|
{
|
||||||
|
free(this->generator);
|
||||||
|
free(this->entity);
|
||||||
|
free(this->regid);
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header
|
||||||
|
*/
|
||||||
|
swid_gen_t *swid_gen_create(void)
|
||||||
|
{
|
||||||
|
private_swid_gen_t *this;
|
||||||
|
char *entity, *regid, *generator;
|
||||||
|
|
||||||
|
entity = lib->settings->get_str(lib->settings,
|
||||||
|
"libimcv.swid_gen.tag_creator.name", "strongSwan Project");
|
||||||
|
regid = lib->settings->get_str(lib->settings,
|
||||||
|
"libimcv.swid_gen.tag_creator.regid", "strongswan.org");
|
||||||
|
generator = lib->settings->get_str(lib->settings,
|
||||||
|
"libimcv.swid_gen.command", SWID_GENERATOR);
|
||||||
|
|
||||||
|
INIT(this,
|
||||||
|
.public = {
|
||||||
|
.generate_tag = _generate_tag,
|
||||||
|
.create_tag_enumerator = _create_tag_enumerator,
|
||||||
|
.destroy = _destroy,
|
||||||
|
},
|
||||||
|
.generator = strdup(generator),
|
||||||
|
.entity = strdup(entity),
|
||||||
|
.regid = strdup(regid),
|
||||||
|
);
|
||||||
|
|
||||||
|
return &this->public;
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Andreas Steffen
|
||||||
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup swid_gen swid_gen
|
||||||
|
* @{ @ingroup libimcv
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SWID_GEN_H_
|
||||||
|
#define SWID_GEN_H_
|
||||||
|
|
||||||
|
#include <library.h>
|
||||||
|
|
||||||
|
typedef struct swid_gen_t swid_gen_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class generating a either a full or a minimalistic ISO 19770-2:2015 SWID tag
|
||||||
|
*/
|
||||||
|
struct swid_gen_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a SWID tag
|
||||||
|
*
|
||||||
|
* @param sw_id Software identifier
|
||||||
|
* @param package Package name (can be NULL)
|
||||||
|
* @param version Package version (can be NULL)
|
||||||
|
* @param full Generate full SWID tags with file information
|
||||||
|
* @param pretty Generate SWID tags with pretty formating
|
||||||
|
* @return SWID tag
|
||||||
|
*/
|
||||||
|
char* (*generate_tag)(swid_gen_t *this, char *sw_id, char *package,
|
||||||
|
char *version, bool full, bool pretty);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a SWID tag
|
||||||
|
*
|
||||||
|
* @param sw_id_only Return software identifier only
|
||||||
|
* @param full Generate full SWID tags with file information
|
||||||
|
* @param pretty Generate SWID tags with pretty formating
|
||||||
|
* @return Tag enumerator (sw_id, tag)
|
||||||
|
*/
|
||||||
|
enumerator_t* (*create_tag_enumerator)(swid_gen_t *this, bool sw_id_only,
|
||||||
|
bool full, bool pretty);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys a swid_gen_t object.
|
||||||
|
*/
|
||||||
|
void (*destroy)(swid_gen_t *this);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a swid_gen_t object
|
||||||
|
*/
|
||||||
|
swid_gen_t* swid_gen_create(void);
|
||||||
|
|
||||||
|
#endif /** SWID_GEN_H_ @}*/
|
|
@ -15,8 +15,9 @@
|
||||||
|
|
||||||
#include "swima_collector.h"
|
#include "swima_collector.h"
|
||||||
|
|
||||||
|
#include <swid_gen/swid_gen.h>
|
||||||
|
|
||||||
#include <collections/linked_list.h>
|
#include <collections/linked_list.h>
|
||||||
#include <bio/bio_writer.h>
|
|
||||||
#include <utils/debug.h>
|
#include <utils/debug.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -33,8 +34,6 @@
|
||||||
#define SWID_DIRECTORY NULL
|
#define SWID_DIRECTORY NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SWID_GENERATOR "/usr/local/bin/swid_generator"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Directories to be skipped by collector
|
* Directories to be skipped by collector
|
||||||
*/
|
*/
|
||||||
|
@ -133,104 +132,6 @@ end:
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Read SWID tags issued by the swid_generator tool
|
|
||||||
*/
|
|
||||||
static status_t read_swid_tags(private_swima_collector_t *this, FILE *file)
|
|
||||||
{
|
|
||||||
swima_record_t *sw_record;
|
|
||||||
bio_writer_t *writer;
|
|
||||||
chunk_t sw_id, swid_tag;
|
|
||||||
bool more_tags = TRUE, last_newline;
|
|
||||||
char line[8192];
|
|
||||||
size_t len;
|
|
||||||
status_t status;
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
swid_tag = writer->get_buf(writer);
|
|
||||||
|
|
||||||
if (swid_tag.len > 1)
|
|
||||||
{
|
|
||||||
/* remove trailing newline if present */
|
|
||||||
if (swid_tag.ptr[swid_tag.len - 1] == '\n')
|
|
||||||
{
|
|
||||||
swid_tag.len--;
|
|
||||||
}
|
|
||||||
DBG3(DBG_IMC, " %.*s", swid_tag.len, swid_tag.ptr);
|
|
||||||
|
|
||||||
status = extract_sw_id(swid_tag, &sw_id);
|
|
||||||
if (status != SUCCESS)
|
|
||||||
{
|
|
||||||
DBG1(DBG_IMC, "software id could not be extracted from tag");
|
|
||||||
writer->destroy(writer);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
sw_record = swima_record_create(0, sw_id, chunk_empty);
|
|
||||||
sw_record->set_source_id(sw_record, SOURCE_ID_GENERATOR);
|
|
||||||
sw_record->set_record(sw_record, swid_tag);
|
|
||||||
this->inventory->add(this->inventory, sw_record);
|
|
||||||
chunk_free(&sw_id);
|
|
||||||
}
|
|
||||||
writer->destroy(writer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read Software Identifiers issued by the swid_generator tool
|
|
||||||
*/
|
|
||||||
static status_t read_swid_tag_ids(private_swima_collector_t *this, FILE *file)
|
|
||||||
{
|
|
||||||
swima_record_t *sw_record;
|
|
||||||
chunk_t sw_id;
|
|
||||||
char line[BUF_LEN];
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
while (TRUE)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
sw_id = chunk_create(line, len);
|
|
||||||
sw_record = swima_record_create(0, sw_id, chunk_empty);
|
|
||||||
sw_record->set_source_id(sw_record, SOURCE_ID_GENERATOR);
|
|
||||||
this->inventory->add(this->inventory, sw_record);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static status_t retrieve_inventory(private_swima_collector_t *this,
|
static status_t retrieve_inventory(private_swima_collector_t *this,
|
||||||
swima_inventory_t *targets)
|
swima_inventory_t *targets)
|
||||||
{
|
{
|
||||||
|
@ -299,82 +200,118 @@ static status_t retrieve_events(private_swima_collector_t *this,
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static status_t generate_tags(private_swima_collector_t *this, char *generator,
|
static status_t generate_tags(private_swima_collector_t *this,
|
||||||
swima_inventory_t *targets, bool pretty, bool full)
|
swima_inventory_t *targets, bool pretty, bool full)
|
||||||
{
|
{
|
||||||
FILE *file;
|
swid_gen_t *swid_gen;
|
||||||
char command[BUF_LEN];
|
swima_record_t *target, *sw_record;
|
||||||
char doc_separator[] = "'\n\n'";
|
enumerator_t *enumerator;
|
||||||
|
|
||||||
status_t status = SUCCESS;
|
status_t status = SUCCESS;
|
||||||
|
|
||||||
|
swid_gen = swid_gen_create();
|
||||||
|
|
||||||
if (targets->get_count(targets) == 0)
|
if (targets->get_count(targets) == 0)
|
||||||
{
|
{
|
||||||
/* Assemble the SWID generator command */
|
chunk_t out, sw_id, swid_tag = chunk_empty;
|
||||||
if (this->sw_id_only)
|
|
||||||
|
DBG2(DBG_IMC, "SWID tag%s generation by package manager",
|
||||||
|
this->sw_id_only ? " ID" : "");
|
||||||
|
|
||||||
|
enumerator = swid_gen->create_tag_enumerator(swid_gen, this->sw_id_only,
|
||||||
|
full, pretty);
|
||||||
|
if (enumerator)
|
||||||
{
|
{
|
||||||
snprintf(command, BUF_LEN, "%s software-id", generator);
|
while (enumerator->enumerate(enumerator, &out))
|
||||||
|
{
|
||||||
|
if (this->sw_id_only)
|
||||||
|
{
|
||||||
|
sw_id = out;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
swid_tag = out;
|
||||||
|
status = extract_sw_id(swid_tag, &sw_id);
|
||||||
|
if (status != SUCCESS)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IMC, "software id could not be extracted "
|
||||||
|
"from tag");
|
||||||
|
chunk_free(&swid_tag);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sw_record = swima_record_create(0, sw_id, chunk_empty);
|
||||||
|
sw_record->set_source_id(sw_record, SOURCE_ID_GENERATOR);
|
||||||
|
if (!this->sw_id_only)
|
||||||
|
{
|
||||||
|
sw_record->set_record(sw_record, swid_tag);
|
||||||
|
chunk_free(&swid_tag);
|
||||||
|
}
|
||||||
|
this->inventory->add(this->inventory, sw_record);
|
||||||
|
chunk_free(&sw_id);
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
snprintf(command, BUF_LEN, "%s swid --doc-separator %s%s%s",
|
status = NOT_SUPPORTED;
|
||||||
generator, doc_separator, 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->sw_id_only)
|
|
||||||
{
|
|
||||||
DBG2(DBG_IMC, "SWID tag ID generation by package manager");
|
|
||||||
status = read_swid_tag_ids(this, file);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBG2(DBG_IMC, "SWID tag generation by package manager");
|
|
||||||
status = read_swid_tags(this, file);
|
|
||||||
}
|
|
||||||
pclose(file);
|
|
||||||
}
|
}
|
||||||
else if (!this->sw_id_only)
|
else if (!this->sw_id_only)
|
||||||
{
|
{
|
||||||
swima_record_t *target;
|
DBG2(DBG_IMC, "targeted SWID tag generation");
|
||||||
enumerator_t *enumerator;
|
|
||||||
chunk_t sw_id;
|
|
||||||
|
|
||||||
enumerator = targets->create_enumerator(targets);
|
enumerator = targets->create_enumerator(targets);
|
||||||
while (enumerator->enumerate(enumerator, &target))
|
while (enumerator->enumerate(enumerator, &target))
|
||||||
{
|
{
|
||||||
|
swima_record_t *sw_record;
|
||||||
|
char *tag = NULL, *name, *package, *version;
|
||||||
|
u_int installed;
|
||||||
|
chunk_t sw_id;
|
||||||
|
enumerator_t *e;
|
||||||
|
|
||||||
sw_id = target->get_sw_id(target, NULL);
|
sw_id = target->get_sw_id(target, NULL);
|
||||||
|
name = strndup(sw_id.ptr, sw_id.len);
|
||||||
|
|
||||||
/* Assemble the SWID generator command */
|
if (this->db)
|
||||||
snprintf(command, BUF_LEN, "%s swid --software-id %.*s%s%s",
|
|
||||||
generator, sw_id.len, sw_id.ptr,
|
|
||||||
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");
|
e = this->db->query(this->db,
|
||||||
return NOT_SUPPORTED;
|
"SELECT package, version, installed "
|
||||||
|
"FROM sw_identifiers WHERE name = ?", DB_TEXT, name,
|
||||||
|
DB_TEXT, DB_TEXT, DB_UINT);
|
||||||
|
if (!e)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IMC, "database query for sw_identifiers failed");
|
||||||
|
status = FAILED;
|
||||||
|
free(name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (e->enumerate(e, &package, &version, &installed))
|
||||||
|
{
|
||||||
|
tag = swid_gen->generate_tag(swid_gen, name, package,
|
||||||
|
version, full && installed, pretty);
|
||||||
|
}
|
||||||
|
e->destroy(e);
|
||||||
}
|
}
|
||||||
status = read_swid_tags(this, file);
|
else
|
||||||
pclose(file);
|
|
||||||
|
|
||||||
if (status != SUCCESS)
|
|
||||||
{
|
{
|
||||||
break;
|
tag = swid_gen->generate_tag(swid_gen, name, NULL, NULL,
|
||||||
|
full, pretty);
|
||||||
|
}
|
||||||
|
free(name);
|
||||||
|
|
||||||
|
if (tag)
|
||||||
|
{
|
||||||
|
DBG2(DBG_IMC, " %.*s", sw_id.len, sw_id.ptr);
|
||||||
|
sw_record = swima_record_create(0, sw_id, chunk_empty);
|
||||||
|
sw_record->set_source_id(sw_record, SOURCE_ID_GENERATOR);
|
||||||
|
sw_record->set_record(sw_record, chunk_from_str(tag));
|
||||||
|
this->inventory->add(this->inventory, sw_record);
|
||||||
|
free(tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
}
|
}
|
||||||
|
swid_gen->destroy(swid_gen);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -480,6 +417,7 @@ static bool collect_tags(private_swima_collector_t *this, char *pathname,
|
||||||
{
|
{
|
||||||
if (chunk_equals(target->get_sw_id(target, NULL), sw_id))
|
if (chunk_equals(target->get_sw_id(target, NULL), sw_id))
|
||||||
{
|
{
|
||||||
|
DBG2(DBG_IMC, " %.*s", sw_id.len, sw_id.ptr);
|
||||||
match = TRUE;
|
match = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -518,16 +456,13 @@ end:
|
||||||
METHOD(swima_collector_t, collect_inventory, swima_inventory_t*,
|
METHOD(swima_collector_t, collect_inventory, swima_inventory_t*,
|
||||||
private_swima_collector_t *this, bool sw_id_only, swima_inventory_t *targets)
|
private_swima_collector_t *this, bool sw_id_only, swima_inventory_t *targets)
|
||||||
{
|
{
|
||||||
char *directory, *generator;
|
|
||||||
bool pretty, full;
|
bool pretty, full;
|
||||||
|
char *directory;
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
directory = lib->settings->get_str(lib->settings,
|
directory = lib->settings->get_str(lib->settings,
|
||||||
"%s.plugins.imc-swima.swid_directory",
|
"%s.plugins.imc-swima.swid_directory",
|
||||||
SWID_DIRECTORY, lib->ns);
|
SWID_DIRECTORY, lib->ns);
|
||||||
generator = lib->settings->get_str(lib->settings,
|
|
||||||
"%s.plugins.imc-swima.swid_generator",
|
|
||||||
SWID_GENERATOR, lib->ns);
|
|
||||||
pretty = lib->settings->get_bool(lib->settings,
|
pretty = lib->settings->get_bool(lib->settings,
|
||||||
"%s.plugins.imc-swima.swid_pretty",
|
"%s.plugins.imc-swima.swid_pretty",
|
||||||
FALSE, lib->ns);
|
FALSE, lib->ns);
|
||||||
|
@ -550,13 +485,14 @@ METHOD(swima_collector_t, collect_inventory, swima_inventory_t*,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
status = generate_tags(this, generator, targets, pretty, full);
|
status = generate_tags(this, targets, pretty, full);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Source 2: Collect swidtag files by iteratively entering all
|
* Source 2: Collect swidtag files by iteratively entering all
|
||||||
* directories in the tree under the "directory" path.
|
* directories in the tree under the "directory" path.
|
||||||
*/
|
*/
|
||||||
|
DBG2(DBG_IMC, "SWID tag%s collection", sw_id_only ? " ID" : "");
|
||||||
collect_tags(this, directory, targets, FALSE);
|
collect_tags(this, directory, targets, FALSE);
|
||||||
|
|
||||||
return status == SUCCESS ? this->inventory : NULL;
|
return status == SUCCESS ? this->inventory : NULL;
|
||||||
|
|
|
@ -99,9 +99,18 @@ The following parameters can be configured in strongswan.conf:
|
||||||
uri = https://admin-user:ietf99hackathon@tnc.strongswan.org/api/
|
uri = https://admin-user:ietf99hackathon@tnc.strongswan.org/api/
|
||||||
timeout = 120
|
timeout = 120
|
||||||
}
|
}
|
||||||
tag_creator {
|
}
|
||||||
name = strongSwan Project
|
.P
|
||||||
regid = strongswan.org
|
The parameters of the swid_generator used with the \-\-generate command can
|
||||||
|
be changed in the libimcv section of strongswan.conf:
|
||||||
|
.P
|
||||||
|
libimcv {
|
||||||
|
swid_gen {
|
||||||
|
command = /usr/local/bin/swid_generator
|
||||||
|
tag_creator {
|
||||||
|
name = strongSwan Project
|
||||||
|
regid = strongswan.org
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.
|
.
|
||||||
|
|
|
@ -30,13 +30,11 @@
|
||||||
#include "sw_collector_dpkg.h"
|
#include "sw_collector_dpkg.h"
|
||||||
#
|
#
|
||||||
#include <library.h>
|
#include <library.h>
|
||||||
#include <bio/bio_writer.h>
|
|
||||||
#include <utils/debug.h>
|
#include <utils/debug.h>
|
||||||
#include <utils/lexparser.h>
|
#include <utils/lexparser.h>
|
||||||
|
|
||||||
#include <imv/imv_os_info.h>
|
#include <imv/imv_os_info.h>
|
||||||
|
#include <swid_gen/swid_gen.h>
|
||||||
#define SWID_GENERATOR "/usr/local/bin/swid_generator"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* global debug output variables
|
* global debug output variables
|
||||||
|
@ -470,105 +468,21 @@ static int unregistered_identifiers(sw_collector_db_t *db,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a either a full or a minimalistic ISO 19770-2:2015 SWID tag
|
* Generate ISO 19770-2:2015 SWID tags for [installed|removed|all]
|
||||||
*/
|
* SW identifiers that are not registered centrally
|
||||||
static char* generate_tag(char *name, char *package, char *version,
|
|
||||||
char* entity, char *regid, char *product,
|
|
||||||
bool full_tag, char *generator)
|
|
||||||
{
|
|
||||||
char *tag = NULL;
|
|
||||||
|
|
||||||
if (full_tag)
|
|
||||||
{
|
|
||||||
size_t tag_buf_len = 8192;
|
|
||||||
char tag_buf[tag_buf_len], command[BUF_LEN];
|
|
||||||
bio_writer_t *writer;
|
|
||||||
chunk_t tag_chunk;
|
|
||||||
FILE *file;
|
|
||||||
|
|
||||||
/* Compose the SWID generator command */
|
|
||||||
snprintf(command, BUF_LEN, "%s swid --full --regid %s --entity-name "
|
|
||||||
"\"%s\" --package %s", generator, regid, entity, package);
|
|
||||||
\
|
|
||||||
/* Open a pipe stream for reading the SWID generator output */
|
|
||||||
file = popen(command, "r");
|
|
||||||
if (file)
|
|
||||||
{
|
|
||||||
writer = bio_writer_create(tag_buf_len);
|
|
||||||
while (TRUE)
|
|
||||||
{
|
|
||||||
if (!fgets(tag_buf, tag_buf_len, file))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
writer->write_data(writer,
|
|
||||||
chunk_create(tag_buf, strlen(tag_buf)));
|
|
||||||
}
|
|
||||||
pclose(file);
|
|
||||||
tag_chunk = writer->extract_buf(writer);
|
|
||||||
writer->destroy(writer);
|
|
||||||
if (tag_chunk.len > 1)
|
|
||||||
{
|
|
||||||
tag = tag_chunk.ptr;
|
|
||||||
tag[tag_chunk.len - 1] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBG1(DBG_IMC, "failed to run swid_generator command");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Generate minimalistic SWID tag */
|
|
||||||
if (!tag)
|
|
||||||
{
|
|
||||||
char *tag_id;
|
|
||||||
|
|
||||||
tag_id = strstr(name, "__");
|
|
||||||
if (!tag_id)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
tag_id += 2;
|
|
||||||
|
|
||||||
if (asprintf(&tag, "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
|
|
||||||
"<SoftwareIdentity name=\"%s\" tagId=\"%s\" version=\"%s\" "
|
|
||||||
"versionScheme=\"alphanumeric\" "
|
|
||||||
"xmlns=\"http://standards.iso.org/iso/19770/-2/2015/schema.xsd\">"
|
|
||||||
"<Entity name=\"%s\" regid=\"%s\" role=\"tagCreator\"/>"
|
|
||||||
"<Meta product=\"%s\"/>"
|
|
||||||
"</SoftwareIdentity>",
|
|
||||||
package, tag_id, version, entity, regid, product) == -1)
|
|
||||||
{
|
|
||||||
tag = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a minimalistic ISO 19770-2:2015 SWID tag for
|
|
||||||
* all removed SW identifiers that are not registered centrally
|
|
||||||
*/
|
*/
|
||||||
static int generate_tags(sw_collector_info_t *info, sw_collector_db_t *db,
|
static int generate_tags(sw_collector_info_t *info, sw_collector_db_t *db,
|
||||||
bool full_tags, sw_collector_db_query_t type)
|
bool full_tags, sw_collector_db_query_t type)
|
||||||
{
|
{
|
||||||
|
swid_gen_t * swid_gen;
|
||||||
sw_collector_rest_api_t *rest_api;
|
sw_collector_rest_api_t *rest_api;
|
||||||
char *name, *package, *version, *entity, *regid, *product, *generator, *tag;
|
char *name, *package, *version, *tag;
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
uint32_t sw_id;
|
uint32_t sw_id;
|
||||||
bool installed;
|
bool installed;
|
||||||
int count = 0, installed_count = 0, status = EXIT_FAILURE;
|
int count = 0, installed_count = 0, status = EXIT_FAILURE;
|
||||||
|
|
||||||
entity = lib->settings->get_str(lib->settings, "%s.tag_creator.name",
|
swid_gen = swid_gen_create();
|
||||||
"strongSwan Project", lib->ns);
|
|
||||||
regid = lib->settings->get_str(lib->settings, "%s.tag_creator.regid",
|
|
||||||
"strongswan.org", lib->ns);
|
|
||||||
generator = lib->settings->get_str(lib->settings, "%s.swid_generator",
|
|
||||||
SWID_GENERATOR, lib->ns);
|
|
||||||
info->get_os(info, &product);
|
|
||||||
|
|
||||||
rest_api = sw_collector_rest_api_create(db);
|
rest_api = sw_collector_rest_api_create(db);
|
||||||
if (!rest_api)
|
if (!rest_api)
|
||||||
{
|
{
|
||||||
|
@ -585,8 +499,8 @@ static int generate_tags(sw_collector_info_t *info, sw_collector_db_t *db,
|
||||||
sw_id = db->get_sw_id(db, name, &package, &version, NULL, &installed);
|
sw_id = db->get_sw_id(db, name, &package, &version, NULL, &installed);
|
||||||
if (sw_id)
|
if (sw_id)
|
||||||
{
|
{
|
||||||
tag = generate_tag(name, package, version, entity, regid, product,
|
tag = swid_gen->generate_tag(swid_gen, name, package, version,
|
||||||
full_tags && installed, generator);
|
full_tags && installed, FALSE);
|
||||||
if (tag)
|
if (tag)
|
||||||
{
|
{
|
||||||
DBG2(DBG_IMC, " creating %s", name);
|
DBG2(DBG_IMC, " creating %s", name);
|
||||||
|
@ -623,6 +537,7 @@ static int generate_tags(sw_collector_info_t *info, sw_collector_db_t *db,
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
swid_gen->destroy(swid_gen);
|
||||||
DESTROY_IF(rest_api);
|
DESTROY_IF(rest_api);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
|
Loading…
Reference in New Issue