Beispiel #1
0
static struct oscap_list *xccdf_benchmark_resolve_dependencies(void *itemptr, void *userdata)
{
	struct xccdf_item *item = XITEM(itemptr);
	struct oscap_list *ret = oscap_list_new();
	struct xccdf_value_iterator *val_it = NULL;

	const char *extends = xccdf_item_get_extends(item);
	if (extends) oscap_list_add(ret, xccdf_benchmark_get_member(xccdf_item_get_benchmark(item), xccdf_item_get_type(item), extends));

	switch (xccdf_item_get_type(item)) {
		case XCCDF_BENCHMARK: {
			OSCAP_FOR(xccdf_profile, profile, xccdf_benchmark_get_profiles(xccdf_item_to_benchmark(item)))
				oscap_list_add(ret, profile);
			val_it = xccdf_benchmark_get_values(xccdf_item_to_benchmark(item));
			break;
		}
		case XCCDF_GROUP:
			val_it = xccdf_group_get_values(xccdf_item_to_group(item));
		default: break; /* no-op */
	}

	OSCAP_FOR(xccdf_item, child, xccdf_item_get_content(item))
		oscap_list_add(ret, child);

	OSCAP_FOR(xccdf_value, val, val_it)
		oscap_list_add(ret, val);


	return ret;
}
Beispiel #2
0
bool xccdf_tailoring_remove_profile(struct xccdf_tailoring *tailoring, struct xccdf_profile *profile)
{
	assert(xccdf_profile_get_tailoring(profile));

	// We have to make sure there is no other profile in tailoring that inherits
	// the profile we are about to remove.

	const char *profile_id = xccdf_profile_get_id(profile);

	struct xccdf_profile_iterator* it = xccdf_tailoring_get_profiles(tailoring);
	while (xccdf_profile_iterator_has_more(it)) {
		struct xccdf_profile* prof = xccdf_profile_iterator_next(it);

		if (prof == profile)
			continue;

		const char *extends = xccdf_profile_get_extends(prof);
		if (oscap_strcmp(profile_id, extends) == 0) {
			oscap_seterr(OSCAP_EFAMILY_XML,
				"Can't remove given profile '%s' from tailoring. Other profiles are inheriting from it!",
				profile_id);

			return false;
			xccdf_profile_iterator_free(it);
		}
	}
	xccdf_profile_iterator_free(it);

	return oscap_list_remove(tailoring->profiles, XITEM(profile), (oscap_cmp_func)_list_ptreq_cmp, NULL);
}
Beispiel #3
0
struct xccdf_benchmark *xccdf_benchmark_import_source(struct oscap_source *source)
{
	xmlTextReader *reader = oscap_source_get_xmlTextReader(source);

	while (xmlTextReaderRead(reader) == 1 && xmlTextReaderNodeType(reader) != XML_READER_TYPE_ELEMENT) ;
	struct xccdf_benchmark *benchmark = xccdf_benchmark_new();
	const bool parse_result = xccdf_benchmark_parse(XITEM(benchmark), reader);
	xmlFreeTextReader(reader);

	if (!parse_result) { // parsing fatal error
		oscap_seterr(OSCAP_EFAMILY_XML, "Failed to import XCCDF content from '%s'.", oscap_source_readable_origin(source));
		xccdf_benchmark_free(benchmark);
		return NULL;
	}

	// This is sadly the only place where we can pass origin file information
	// to the CPE1 embedded dictionary (if any). It is necessary to figure out
	// proper paths to OVAL files referenced from CPE1 dictionaries.

	// FIXME: Refactor and move this somewhere else
	struct cpe_dict_model* embedded_dict = xccdf_benchmark_get_cpe_list(benchmark);
	if (embedded_dict != NULL) {
		cpe_dict_model_set_origin_file(embedded_dict, oscap_source_readable_origin(source));
	}

	// same situation with embedded CPE2 lang model
	// FIXME: Refactor and move this somewhere else
	struct cpe_lang_model* embedded_lang_model = xccdf_benchmark_get_cpe_lang_model(benchmark);
	if (embedded_lang_model != NULL) {
		cpe_lang_model_set_origin_file(embedded_lang_model, oscap_source_readable_origin(source));
	}
	return benchmark;
}
Beispiel #4
0
struct xccdf_group * xccdf_group_clone(const struct xccdf_group * group)
{
	struct xccdf_item *new_group = calloc(1, sizeof(struct xccdf_item) + sizeof(struct xccdf_group_item));
	struct xccdf_item *old = XITEM(group);
    xccdf_item_base_clone(&new_group->item, &(old->item));
	new_group->type = old->type;
    xccdf_group_item_clone(new_group, &(old->sub.group));
	return XGROUP(new_group);
}
Beispiel #5
0
struct xccdf_rule *xccdf_rule_clone(const struct xccdf_rule * rule)
{
	struct xccdf_item *new_rule = calloc(1, sizeof(struct xccdf_item) + sizeof(struct xccdf_rule_item));
	struct xccdf_item *old = XITEM(rule);
    xccdf_item_base_clone(&new_rule->item, &(old->item));
	new_rule->type = old->type;
    xccdf_rule_item_clone(&new_rule->sub.rule, &old->sub.rule);
	return XRULE(new_rule);
}
Beispiel #6
0
struct xccdf_benchmark *xccdf_benchmark_clone(const struct xccdf_benchmark *old_benchmark)
{
	struct xccdf_item *new_benchmark = oscap_calloc(1, sizeof(struct xccdf_item) + sizeof(struct xccdf_benchmark_item));
	struct xccdf_item *old = XITEM(old_benchmark);
    xccdf_item_base_clone(&new_benchmark->item, &old->item);
	new_benchmark->type = old->type;
	//second argument is a pointer to the benchmark being created which will be the parent of all of its sub elements.
    xccdf_benchmark_item_clone(new_benchmark, old_benchmark);
	return XBENCHMARK(new_benchmark);
}
Beispiel #7
0
bool xccdf_benchmark_resolve(struct xccdf_benchmark *benchmark)
{
	struct oscap_list *resolve_order = NULL, *root_nodes = oscap_list_new();
	oscap_list_add(root_nodes, benchmark);
	bool ret = false;
	
	if (oscap_tsort(root_nodes, &resolve_order, xccdf_benchmark_resolve_dependencies, NULL, NULL)) {
		OSCAP_FOR(xccdf_item, item, oscap_iterator_new(resolve_order))
			xccdf_resolve_item(item, NULL);
		ret = true;
	}

	oscap_list_free(root_nodes, NULL);
	oscap_list_free(resolve_order, NULL);

    xccdf_resolve_cleanup(XITEM(benchmark));

	return ret;
}
Beispiel #8
0
struct xccdf_benchmark *xccdf_benchmark_import(const char *file)
{
	xmlTextReaderPtr reader = xmlReaderForFile(file, NULL, 0);
	if (!reader) {
		oscap_seterr(OSCAP_EFAMILY_GLIBC, "Unable to open file: '%s'", file);
		return NULL;
	}

	xmlTextReaderSetErrorHandler(reader, &libxml_error_handler, NULL);

	while (xmlTextReaderRead(reader) == 1 && xmlTextReaderNodeType(reader) != XML_READER_TYPE_ELEMENT) ;
	struct xccdf_benchmark *benchmark = xccdf_benchmark_new();
	const bool parse_result = xccdf_benchmark_parse(XITEM(benchmark), reader);
	xmlFreeTextReader(reader);

	if (!parse_result) { // parsing fatal error
		oscap_seterr(OSCAP_EFAMILY_XML, "Failed to parse '%s'.", file);
		xccdf_benchmark_free(benchmark);
		return NULL;
	}

	// This is sadly the only place where we can pass origin file information
	// to the CPE1 embedded dictionary (if any). It is necessary to figure out
	// proper paths to OVAL files referenced from CPE1 dictionaries.

	// FIXME: Refactor and move this somewhere else
	struct cpe_dict_model* embedded_dict = xccdf_benchmark_get_cpe_list(benchmark);
	if (embedded_dict != NULL) {
		cpe_dict_model_set_origin_file(embedded_dict, file);
	}

	// same situation with embedded CPE2 lang model
	// FIXME: Refactor and move this somewhere else
	struct cpe_lang_model* embedded_lang_model = xccdf_benchmark_get_cpe_lang_model(benchmark);
	if (embedded_lang_model != NULL) {
		cpe_lang_model_set_origin_file(embedded_lang_model, file);
	}

	return benchmark;
}
Beispiel #9
0
struct xccdf_tailoring *xccdf_tailoring_import(const char *file, struct xccdf_benchmark *benchmark)
{
	xmlTextReaderPtr reader = xmlReaderForFile(file, NULL, 0);
	if (!reader) {
		oscap_seterr(OSCAP_EFAMILY_GLIBC, "Unable to open file: '%s'", file);
		return NULL;
	}

	xmlTextReaderSetErrorHandler(reader, &libxml_error_handler, NULL);

	while (xmlTextReaderRead(reader) == 1 && xmlTextReaderNodeType(reader) != XML_READER_TYPE_ELEMENT) ;
	struct xccdf_tailoring *tailoring = xccdf_tailoring_parse(reader, XITEM(benchmark));
	xmlFreeTextReader(reader);

	if (!tailoring) { // parsing fatal error
		oscap_seterr(OSCAP_EFAMILY_XML, "Failed to parse '%s'.", file);
		xccdf_tailoring_free(tailoring);
		return NULL;
	}

	return tailoring;
}
Beispiel #10
0
bool xccdf_rule_add_conflicts(struct xccdf_rule* rule, const char* conflicts)
{
    oscap_stringlist_add_string((struct oscap_stringlist*)(XITEM(rule)->sub.rule.conflicts), conflicts);
    return true;
}
Beispiel #11
0
bool xccdf_group_add_requires(struct xccdf_group* group, struct oscap_stringlist* requires)
{
    oscap_list_add(XITEM(group)->sub.group.requires, requires);
    return true;
}
Beispiel #12
0
bool xccdf_rule_add_requires(struct xccdf_rule* rule, struct oscap_stringlist* requires)
{
    oscap_list_add(XITEM(rule)->sub.rule.requires, requires);
    return true;
}
Beispiel #13
0
struct oscap_stringlist_iterator *xccdf_group_get_requires(const struct xccdf_group* group)
{
	return oscap_iterator_new(XITEM(group)->sub.group.requires);
}
Beispiel #14
0
struct oscap_stringlist_iterator *xccdf_rule_get_requires(const struct xccdf_rule* rule)
{
	return oscap_iterator_new(XITEM(rule)->sub.rule.requires);
}
Beispiel #15
0
struct oscap_string_iterator *xccdf_group_get_conflicts(const struct xccdf_group* group)
{
	return oscap_iterator_new(XITEM(group)->sub.group.conflicts);
}
Beispiel #16
0
struct oscap_string_iterator *xccdf_rule_get_conflicts(const struct xccdf_rule* rule)
{
	return oscap_iterator_new(XITEM(rule)->sub.rule.conflicts);
}
Beispiel #17
0
xmlNode *xccdf_benchmark_to_dom(struct xccdf_benchmark *benchmark, xmlDocPtr doc,
				xmlNode *parent, void *user_args)
{
	xmlNodePtr root_node = NULL;

	if (parent) {
		root_node = xccdf_item_to_dom(XITEM(benchmark), doc, parent);
	} else {
		root_node = xccdf_item_to_dom(XITEM(benchmark), doc, parent);
		xmlDocSetRootElement(doc, root_node);
	}

	// FIXME!
	//xmlNewProp(root_node, BAD_CAST "xsi:schemaLocation", BAD_CAST XCCDF_SCHEMA_LOCATION);

	xmlNs *ns_xccdf = xmlNewNs(root_node,
			(const xmlChar*)xccdf_version_info_get_namespace_uri(xccdf_benchmark_get_schema_version(benchmark)),
			NULL);

	xmlNs *ns_xsi = xmlNewNs(root_node, XCCDF_XSI_NAMESPACE, BAD_CAST "xsi");

	xmlSetNs(root_node, ns_xsi);
	xmlSetNs(root_node, ns_xccdf);

	/* Handle attributes */
	if (xccdf_benchmark_get_resolved(benchmark))
		xmlNewProp(root_node, BAD_CAST "resolved", BAD_CAST "1");
	else
		xmlNewProp(root_node, BAD_CAST "resolved", BAD_CAST "0");

    const char *xmllang = xccdf_benchmark_get_lang(benchmark);
	if (xmllang)
		xmlNewProp(root_node, BAD_CAST "xml:lang", BAD_CAST xmllang);

	const char *style = xccdf_benchmark_get_style(benchmark);
	if (style)
		xmlNewProp(root_node, BAD_CAST "style", BAD_CAST style);

	const char *style_href = xccdf_benchmark_get_style_href(benchmark);
	if (style_href)
		xmlNewProp(root_node, BAD_CAST "style-href", BAD_CAST style_href);

	// Export plain-text elements
	struct xccdf_plain_text_iterator *plain_text_it = xccdf_benchmark_get_plain_texts(benchmark);
	while (xccdf_plain_text_iterator_has_more(plain_text_it)) {
		struct xccdf_plain_text *plain_text = xccdf_plain_text_iterator_next(plain_text_it);
		xccdf_plain_text_to_dom(plain_text, doc, root_node, xccdf_benchmark_get_schema_version(benchmark));
	}
	xccdf_plain_text_iterator_free(plain_text_it);

	/* Handle children */
	if (xccdf_benchmark_get_cpe_list(benchmark)) {
		// CPE API can only export via xmlTextWriter, we export via DOM
		// this is used to bridge both methods
		xmlTextWriterPtr writer = xmlNewTextWriterTree(doc, root_node, 0);
		cpe_dict_export(xccdf_benchmark_get_cpe_list(benchmark), writer);
		xmlFreeTextWriter(writer);
	}
	if (xccdf_benchmark_get_cpe_lang_model(benchmark)) {
		// CPE API can only export via xmlTextWriter, we export via DOM
		// this is used to bridge both methods
		xmlTextWriterPtr writer = xmlNewTextWriterTree(doc, root_node, 0);
		cpe_lang_export(xccdf_benchmark_get_cpe_lang_model(benchmark), writer);
		xmlFreeTextWriter(writer);
	}

	struct oscap_string_iterator *platforms = xccdf_benchmark_get_platforms(benchmark);
	while (oscap_string_iterator_has_more(platforms)) {
		xmlNode *platform_node = xmlNewTextChild(root_node, ns_xccdf, BAD_CAST "platform", NULL);

		const char *idref = oscap_string_iterator_next(platforms);
		if (idref)
			xmlNewProp(platform_node, BAD_CAST "idref", BAD_CAST idref);
	}
	oscap_string_iterator_free(platforms);

	const char *version = xccdf_benchmark_get_version(benchmark);
	if (version)
		xmlNewTextChild(root_node, ns_xccdf, BAD_CAST "version", BAD_CAST version);

	struct oscap_string_iterator* metadata = xccdf_item_get_metadata(XITEM(benchmark));
	while (oscap_string_iterator_has_more(metadata))
	{
		const char* meta = oscap_string_iterator_next(metadata);
		oscap_xmlstr_to_dom(root_node, "metadata", meta);
	}
	oscap_string_iterator_free(metadata);

	OSCAP_FOR(xccdf_model, model, xccdf_benchmark_get_models(benchmark)) {
		xmlNode *model_node = xmlNewTextChild(root_node, ns_xccdf, BAD_CAST "model", NULL);
		xmlNewProp(model_node, BAD_CAST "system", BAD_CAST xccdf_model_get_system(model));
	}
Beispiel #18
0
bool xccdf_group_add_conflicts(struct xccdf_group* group, const char* conflicts)
{
    oscap_stringlist_add_string((struct oscap_stringlist*)(XITEM(group)->sub.group.conflicts), conflicts);
    return true;
}
Beispiel #19
0
xmlNodePtr xccdf_tailoring_to_dom(struct xccdf_tailoring *tailoring, xmlDocPtr doc, xmlNodePtr parent, const struct xccdf_version_info *version_info)
{
	xmlNs *ns_xccdf = xmlSearchNsByHref(doc, parent,
				BAD_CAST xccdf_version_info_get_namespace_uri(version_info));

	xmlNs *ns_tailoring = NULL;

	xmlNode *tailoring_node = xmlNewNode(ns_xccdf, BAD_CAST "Tailoring");

	const char *xccdf_version = xccdf_version_info_get_version(version_info);
#ifdef __USE_GNU
	if (strverscmp(xccdf_version, "1.1") >= 0 && strverscmp(xccdf_version, "1.2") < 0) {
#else
	if (strcmp(xccdf_version, "1.1") >= 0 && strcmp(xccdf_version, "1.2") < 0) {
#endif
		// XCCDF 1.1 does not support Tailoring!
		// However we will allow Tailoring export if it is done to an external
		// file. The namespace will be our custom xccdf-1.1-tailoring extension
		// namespace.

		if (parent != NULL) {
			oscap_seterr(OSCAP_EFAMILY_XML, "XCCDF 1.1 does not support embedded Tailoring elements!");
			xmlFreeNode(tailoring_node);
			return NULL;
		}

		ns_tailoring = xmlNewNs(tailoring_node,
			BAD_CAST "http://open-scap.org/page/Xccdf-1.1-tailoring",
			BAD_CAST "cdf-11-tailoring"
		);
	}
#ifdef __USE_GNU
	else if (strverscmp(xccdf_version, "1.1") < 0) {
#else
	else if (strcmp(xccdf_version, "1.1") < 0) {
#endif
		oscap_seterr(OSCAP_EFAMILY_XML, "XCCDF Tailoring isn't supported in XCCDF version '%s',"
			"nor does openscap have a custom extension for this scenario. "
			"XCCDF Tailoring requires XCCDF 1.1 and higher, 1.2 is recommended.");

		xmlFreeNode(tailoring_node);
		return NULL;
	}

	if (!ns_xccdf) {
		// In cases where tailoring ends up being the root node we have to create
		// a namespace at the node itself.
		ns_xccdf = xmlNewNs(tailoring_node,
			BAD_CAST xccdf_version_info_get_namespace_uri(version_info),
			BAD_CAST "xccdf");
	}

	if (!ns_tailoring)
		ns_tailoring = ns_xccdf;

	// We intentionally set the wrong namespace here since children of tailoring
	// will reuse it and we want them to have the xccdf namespace, the namespace
	// is set to the proper namespace before returning the tailoring.
	xmlSetNs(tailoring_node, ns_xccdf);

	if (parent)
		xmlAddChild(parent, tailoring_node);
	else
		xmlDocSetRootElement(doc, tailoring_node);

	if (tailoring->id) {
		xmlNewProp(tailoring_node, BAD_CAST "id", BAD_CAST tailoring->id);
	}

	if (tailoring->benchmark_ref || tailoring->benchmark_ref_version) {
		xmlNodePtr benchmark_ref_node = xmlNewChild(tailoring_node, ns_tailoring, BAD_CAST "benchmark", NULL);

		if (tailoring->benchmark_ref)
			xmlNewProp(benchmark_ref_node, BAD_CAST "href", BAD_CAST tailoring->benchmark_ref);

		if (tailoring->benchmark_ref_version)
			xmlNewProp(benchmark_ref_node, BAD_CAST "version", BAD_CAST tailoring->benchmark_ref_version);
	}

	struct xccdf_status_iterator *statuses = xccdf_tailoring_get_statuses(tailoring);
	while (xccdf_status_iterator_has_more(statuses)) {
		struct xccdf_status *status = xccdf_status_iterator_next(statuses);
		xccdf_status_to_dom(status, doc, tailoring_node, version_info);
	}
	xccdf_status_iterator_free(statuses);

	struct oscap_reference_iterator *dc_statuses = xccdf_tailoring_get_dc_statuses(tailoring);
	while (oscap_reference_iterator_has_more(dc_statuses)) {
		struct oscap_reference *ref = oscap_reference_iterator_next(dc_statuses);
		oscap_reference_to_dom(ref, tailoring_node, doc, "dc-status");
	}
	oscap_reference_iterator_free(dc_statuses);

	/* version and attributes */
	const char *version = xccdf_tailoring_get_version(tailoring);
	if (version) {
		xmlNode* version_node = xmlNewTextChild(tailoring_node, ns_tailoring, BAD_CAST "version", BAD_CAST version);

		const char *version_update = xccdf_tailoring_get_version_update(tailoring);
		if (version_update)
			xmlNewProp(version_node, BAD_CAST "update", BAD_CAST version_update);

		const char *version_time = xccdf_tailoring_get_version_time(tailoring);
		if (version_time)
			xmlNewProp(version_node, BAD_CAST "time", BAD_CAST version_time);
	}

	struct oscap_string_iterator* metadata = xccdf_tailoring_get_metadata(tailoring);
	while (oscap_string_iterator_has_more(metadata))
	{
		const char* meta = oscap_string_iterator_next(metadata);
		oscap_xmlstr_to_dom(tailoring_node, "metadata", meta);
	}
	oscap_string_iterator_free(metadata);

	struct xccdf_profile_iterator *profiles = xccdf_tailoring_get_profiles(tailoring);
	while (xccdf_profile_iterator_has_more(profiles)) {
		struct xccdf_profile *profile = xccdf_profile_iterator_next(profiles);
		xccdf_item_to_dom(XITEM(profile), doc, tailoring_node);
	}
	xccdf_profile_iterator_free(profiles);

	xmlSetNs(tailoring_node, ns_tailoring);

	return tailoring_node;
}

int xccdf_tailoring_export(struct xccdf_tailoring *tailoring, const char *file, const struct xccdf_version_info *version_info)
{
	__attribute__nonnull__(file);

	LIBXML_TEST_VERSION;

	xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
	if (doc == NULL) {
		oscap_setxmlerr(xmlGetLastError());
		return -1;
	}

	xccdf_tailoring_to_dom(tailoring, doc, NULL, version_info);

	return oscap_xml_save_filename(file, doc);
}

const char *xccdf_tailoring_get_id(const struct xccdf_tailoring *tailoring)
{
	return tailoring->id;
}

const char *xccdf_tailoring_get_version(const struct xccdf_tailoring *tailoring)
{
	return tailoring->version;
}

const char *xccdf_tailoring_get_version_update(const struct xccdf_tailoring *tailoring)
{
	return tailoring->version_update;
}

const char *xccdf_tailoring_get_version_time(const struct xccdf_tailoring *tailoring)
{
	return tailoring->version_time;
}

const char *xccdf_tailoring_get_benchmark_ref(const struct xccdf_tailoring *tailoring)
{
	return tailoring->benchmark_ref;
}

const char *xccdf_tailoring_get_benchmark_ref_version(const struct xccdf_tailoring *tailoring)
{
	return tailoring->benchmark_ref_version;
}

bool xccdf_tailoring_set_id(struct xccdf_tailoring *tailoring, const char* newval)
{
	if (tailoring->id)
		oscap_free(tailoring->id);

	tailoring->id = oscap_strdup(newval);
	return true;
}

bool xccdf_tailoring_set_version(struct xccdf_tailoring *tailoring, const char *newval)
{
	if (tailoring->version)
		oscap_free(tailoring->version);

	tailoring->version = oscap_strdup(newval);
	return true;
}

bool xccdf_tailoring_set_version_update(struct xccdf_tailoring *tailoring, const char *newval)
{
	if (tailoring->version_update)
		oscap_free(tailoring->version_update);

	tailoring->version_update = oscap_strdup(newval);
	return true;
}

bool xccdf_tailoring_set_version_time(struct xccdf_tailoring *tailoring, const char *newval)
{
	if (tailoring->version_time)
		oscap_free(tailoring->version_time);

	tailoring->version_time = oscap_strdup(newval);
	return true;
}

bool xccdf_tailoring_set_benchmark_ref(struct xccdf_tailoring *tailoring, const char *newval)
{
	if (tailoring->benchmark_ref)
		oscap_free(tailoring->benchmark_ref);

	tailoring->benchmark_ref = oscap_strdup(newval);
	return true;
}

bool xccdf_tailoring_set_benchmark_ref_version(struct xccdf_tailoring *tailoring, const char *newval)
{
	if (tailoring->benchmark_ref_version)
		oscap_free(tailoring->benchmark_ref_version);

	tailoring->benchmark_ref_version = oscap_strdup(newval);
	return true;
}

struct oscap_string_iterator *xccdf_tailoring_get_metadata(const struct xccdf_tailoring *tailoring)
{
	return (struct oscap_string_iterator*) oscap_iterator_new(tailoring->metadata);
}

struct xccdf_profile_iterator *xccdf_tailoring_get_profiles(const struct xccdf_tailoring *tailoring)
{
	return (struct xccdf_profile_iterator*) oscap_iterator_new(tailoring->profiles);
}

struct xccdf_status_iterator *xccdf_tailoring_get_statuses(const struct xccdf_tailoring *tailoring)
{
	return (struct xccdf_status_iterator*) oscap_iterator_new(tailoring->statuses);
}

struct oscap_reference_iterator *xccdf_tailoring_get_dc_statuses(const struct xccdf_tailoring *tailoring)
{
	return (struct oscap_reference_iterator*) oscap_iterator_new(tailoring->dc_statuses);
}

struct xccdf_profile *
xccdf_tailoring_get_profile_by_id(const struct xccdf_tailoring *tailoring, const char *profile_id)
{
	struct xccdf_profile_iterator *profit = xccdf_tailoring_get_profiles(tailoring);
	while (xccdf_profile_iterator_has_more(profit)) {
		struct xccdf_profile *profile = xccdf_profile_iterator_next(profit);
		if (profile == NULL) {
			assert(profile != NULL);
			continue;
		}
		if (oscap_streq(xccdf_profile_get_id(profile), profile_id)) {
			xccdf_profile_iterator_free(profit);
			return profile;
		}
	}
	xccdf_profile_iterator_free(profit);
	return NULL;
}
Beispiel #20
0
static void xccdf_resolve_item(struct xccdf_item *item, struct xccdf_tailoring *tailoring)
{
	assert(item != NULL);

	if (xccdf_item_get_type(item) == XCCDF_BENCHMARK) {
		xccdf_benchmark_set_resolved(xccdf_item_to_benchmark(item), true);
		return; // benchmark has no extends
	}

	assert(!xccdf_item_get_extends(item) || xccdf_item_get_type(item) & (XCCDF_PROFILE | XCCDF_ITEM));
	struct xccdf_item *parent = NULL;
	if (xccdf_item_get_type(item) == XCCDF_PROFILE && tailoring != NULL) {
		parent = XITEM(_xccdf_tailoring_profile_get_real_parent(tailoring, XPROFILE(item)));
	}
	else {
		parent = xccdf_benchmark_get_member(xccdf_item_get_benchmark(item), xccdf_item_get_type(item), xccdf_item_get_extends(item));
	}
	if (parent == NULL) return;
	if (xccdf_item_get_type(item) != xccdf_item_get_type(parent)) return;
	if (xccdf_item_get_type(item) == XCCDF_GROUP && xccdf_version_cmp(xccdf_item_get_schema_version(item), "1.2") >= 0)
		return;	// Group/@extends= has been obsoleted in XCCDF 1.2

	// resolve flags
	XCCDF_RESOLVE_FLAG(item, parent, selected);
	XCCDF_RESOLVE_FLAG(item, parent, hidden);
	XCCDF_RESOLVE_FLAG(item, parent, prohibit_changes);
	XCCDF_RESOLVE_FLAG(item, parent, interactive);
	XCCDF_RESOLVE_FLAG(item, parent, multiple);

	// resolve weight & version
	if (!item->item.defined_flags.weight)
		xccdf_item_set_weight(item, xccdf_item_get_weight(parent));

	if (xccdf_item_get_version(item) == NULL) {
		xccdf_item_set_version(item, xccdf_item_get_version(parent));
		xccdf_item_set_version_update(item, xccdf_item_get_version_update(parent));
		xccdf_item_set_version_time(item, xccdf_item_get_version_time(parent));
	}

	// resolve textual elements
	xccdf_resolve_textlist(item->item.title,       parent->item.title,       NULL);
	xccdf_resolve_textlist(item->item.description, parent->item.description, NULL);
	xccdf_resolve_textlist(item->item.question,    parent->item.question,    NULL);
	xccdf_resolve_textlist(item->item.rationale,   parent->item.rationale,   NULL);
	xccdf_resolve_textlist(item->item.warnings,    parent->item.warnings,    xccdf_resolve_warning);
	xccdf_resolve_textlist(item->item.references,  parent->item.references,  NULL);

	// resolve platforms
	OSCAP_FOR_STR(platform, xccdf_item_get_platforms(parent))
		xccdf_item_add_platform(item, platform);

	// resolve properties specific to particular item type
	switch (xccdf_item_get_type(item)) {
		case XCCDF_PROFILE:   xccdf_resolve_profile(item, parent); break;
		case XCCDF_GROUP:     xccdf_resolve_group(item, parent);   break;
		case XCCDF_RULE:      xccdf_resolve_rule(item, parent);    break;
		case XCCDF_VALUE:     xccdf_resolve_value(item, parent);   break;
		default: assert(false);
	}

	// item resolved -> it no longer has a parent
	xccdf_item_set_extends(item, NULL);
}
Beispiel #21
0
bool xccdf_tailoring_add_profile(struct xccdf_tailoring *tailoring, struct xccdf_profile *profile)
{
	xccdf_profile_set_tailoring(profile, true);
	return oscap_list_add(tailoring->profiles, XITEM(profile));
}
Beispiel #22
0
void xccdf_rule_to_dom(struct xccdf_rule *rule, xmlNode *rule_node, xmlDoc *doc, xmlNode *parent)
{
	const struct xccdf_version_info* version_info = xccdf_item_get_schema_version(XITEM(rule));
	xmlNs *ns_xccdf = lookup_xccdf_ns(doc, parent, version_info);

	/* Handle Attributes */
	const char *extends = xccdf_rule_get_extends(rule);
	if (extends)
		xmlNewProp(rule_node, BAD_CAST "extends", BAD_CAST extends);

	if (xccdf_rule_get_multiple(rule))
		xmlNewProp(rule_node, BAD_CAST "multiple", BAD_CAST "true");

	if (xccdf_rule_get_selected(rule))
		xmlNewProp(rule_node, BAD_CAST "selected", BAD_CAST "true");
	else
		xmlNewProp(rule_node, BAD_CAST "selected", BAD_CAST "false");

	if (XITEM(rule)->item.defined_flags.weight) {
		char *weight_str = oscap_sprintf("%f", xccdf_rule_get_weight(rule));
		xmlNewProp(rule_node, BAD_CAST "weight", BAD_CAST weight_str);
		free(weight_str);
	}

	xccdf_role_t role = xccdf_rule_get_role(rule);
	if (role != 0)
		xmlNewProp(rule_node, BAD_CAST "role", BAD_CAST XCCDF_ROLE_MAP[role - 1].string);

	xccdf_level_t severity = xccdf_rule_get_severity(rule);
	if (severity != XCCDF_LEVEL_NOT_DEFINED)
		xmlNewProp(rule_node, BAD_CAST "severity", BAD_CAST XCCDF_LEVEL_MAP[severity - 1].string);

	/* Handle Child Nodes */
	xccdf_texts_to_dom(xccdf_rule_get_rationale(rule), rule_node, "rationale");

	struct oscap_string_iterator *platforms = xccdf_rule_get_platforms(rule);
	while (oscap_string_iterator_has_more(platforms)) {
		const char *platform = oscap_string_iterator_next(platforms);
		xmlNode * child = xmlNewTextChild(rule_node, ns_xccdf, BAD_CAST "platform", BAD_CAST NULL);
                xmlNewProp(child, BAD_CAST "idref", BAD_CAST platform);
	}
	oscap_string_iterator_free(platforms);

	struct oscap_stringlist_iterator *lists = xccdf_rule_get_requires(rule);
	while (oscap_stringlist_iterator_has_more(lists)) {
		struct oscap_stringlist *list = oscap_stringlist_iterator_next(lists);
		struct oscap_string_iterator *strings = oscap_stringlist_get_strings(list);
		while (oscap_string_iterator_has_more(strings)) {
			const char *requires = oscap_string_iterator_next(strings);
			xmlNode * child = xmlNewTextChild(rule_node, ns_xccdf, BAD_CAST "requires", BAD_CAST NULL);
                        xmlNewProp(child, BAD_CAST "idref", BAD_CAST requires);
		}
		oscap_string_iterator_free(strings);
	}
	oscap_stringlist_iterator_free(lists);

	struct oscap_string_iterator *conflicts = xccdf_rule_get_conflicts(rule);
	while (oscap_string_iterator_has_more(conflicts)) {
		const char *conflict = oscap_string_iterator_next(conflicts);
		xmlNode * child = xmlNewTextChild(rule_node, ns_xccdf, BAD_CAST "conflicts", BAD_CAST NULL);
                xmlNewProp(child, BAD_CAST "idref", BAD_CAST conflict);
	}
	oscap_string_iterator_free(conflicts);

	struct xccdf_ident_iterator *idents = xccdf_rule_get_idents(rule);
	while (xccdf_ident_iterator_has_more(idents)) {
		struct xccdf_ident *ident = xccdf_ident_iterator_next(idents);
		xccdf_ident_to_dom(ident, doc, rule_node, version_info);
	}
	xccdf_ident_iterator_free(idents);

	struct xccdf_profile_note_iterator *notes = xccdf_rule_get_profile_notes(rule);
	while (xccdf_profile_note_iterator_has_more(notes)) {
		struct xccdf_profile_note *note = xccdf_profile_note_iterator_next(notes);
		xccdf_profile_note_to_dom(note, doc, rule_node);
	}
	xccdf_profile_note_iterator_free(notes);

	struct xccdf_fixtext_iterator *fixtexts = xccdf_rule_get_fixtexts(rule);
	while (xccdf_fixtext_iterator_has_more(fixtexts)) {
		struct xccdf_fixtext *fixtext = xccdf_fixtext_iterator_next(fixtexts);
		xccdf_fixtext_to_dom(fixtext, doc, rule_node);
	}
	xccdf_fixtext_iterator_free(fixtexts);

	struct xccdf_fix_iterator *fixes = xccdf_rule_get_fixes(rule);
	while (xccdf_fix_iterator_has_more(fixes)) {
		struct xccdf_fix *fix = xccdf_fix_iterator_next(fixes);
		xccdf_fix_to_dom(fix, doc, rule_node, version_info);
	}
	xccdf_fix_iterator_free(fixes);

	struct xccdf_check_iterator *checks = xccdf_rule_get_checks(rule);
	while (xccdf_check_iterator_has_more(checks)) {
		struct xccdf_check *check = xccdf_check_iterator_next(checks);
		xccdf_check_to_dom(check, doc, rule_node, version_info);
	}
	xccdf_check_iterator_free(checks);
}
Beispiel #23
0
void xccdf_group_to_dom(struct xccdf_group *group, xmlNode *group_node, xmlDoc *doc, xmlNode *parent)
{
	const struct xccdf_version_info* version_info = xccdf_item_get_schema_version(XITEM(group));
	xmlNs *ns_xccdf = lookup_xccdf_ns(doc, parent, version_info);

	/* Handle Attributes */
	const char *extends = xccdf_group_get_extends(group);
	if (extends)
		xmlNewProp(group_node, BAD_CAST "extends", BAD_CAST extends);

	if (XITEM(group)->item.defined_flags.selected) {
		if (xccdf_group_get_selected(group))
			xmlNewProp(group_node, BAD_CAST "selected", BAD_CAST "true");
		else
			xmlNewProp(group_node, BAD_CAST "selected", BAD_CAST "false");
	}

	if (XITEM(group)->item.defined_flags.weight) {
		float weight = xccdf_group_get_weight(group);
		char *weight_str = oscap_sprintf("%f", weight);
		xmlNewProp(group_node, BAD_CAST "weight", BAD_CAST weight_str);
        free(weight_str);
	}

	/* Handle Child Nodes */
	xccdf_texts_to_dom(xccdf_group_get_rationale(group), group_node, "rationale");

	struct oscap_string_iterator *platforms = xccdf_group_get_platforms(group);
	while (oscap_string_iterator_has_more(platforms)) {
		const char *platform = oscap_string_iterator_next(platforms);
		xmlNode * child = xmlNewTextChild(group_node, ns_xccdf, BAD_CAST "platform", BAD_CAST NULL);
                xmlNewProp(child, BAD_CAST "idref", BAD_CAST platform);
	}
	oscap_string_iterator_free(platforms);

	struct oscap_stringlist_iterator *lists = xccdf_group_get_requires(group);
	while (oscap_stringlist_iterator_has_more(lists)) {
		struct oscap_stringlist *list = oscap_stringlist_iterator_next(lists);
		struct oscap_string_iterator *strings = oscap_stringlist_get_strings(list);
		while (oscap_string_iterator_has_more(strings)) {
			const char *requires = oscap_string_iterator_next(strings);
			xmlNode * child = xmlNewTextChild(group_node, ns_xccdf, BAD_CAST "requires", BAD_CAST NULL);
                        xmlNewProp(child, BAD_CAST "idref", BAD_CAST requires);
		}
		oscap_string_iterator_free(strings);
	}
	oscap_stringlist_iterator_free(lists);

	struct oscap_string_iterator *conflicts = xccdf_group_get_conflicts(group);
	while (oscap_string_iterator_has_more(conflicts)) {
		const char *conflict = oscap_string_iterator_next(conflicts);
		xmlNode * child = xmlNewTextChild(group_node, ns_xccdf, BAD_CAST "conflicts", BAD_CAST NULL);
                xmlNewProp(child, BAD_CAST "idref", BAD_CAST conflict);
	}
	oscap_string_iterator_free(conflicts);

        struct xccdf_value_iterator *values = xccdf_group_get_values(group);
	while (xccdf_value_iterator_has_more(values)) {
		struct xccdf_value *value = xccdf_value_iterator_next(values);
		if (XGROUP(xccdf_value_get_parent(value)) == group) {
			xccdf_item_to_dom((struct xccdf_item *)value, doc, group_node, version_info);
		}
	}
	xccdf_value_iterator_free(values);

	struct xccdf_item_iterator *items = xccdf_group_get_content(group);
	while (xccdf_item_iterator_has_more(items)) {
		struct xccdf_item *item = xccdf_item_iterator_next(items);
		if (XGROUP(xccdf_item_get_parent(item)) == group) {
			xccdf_item_to_dom(item, doc, group_node, version_info);
		}
	}
	xccdf_item_iterator_free(items);

}