292 lines
6.0 KiB
C
292 lines
6.0 KiB
C
/*
|
|
* 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;
|
|
}
|