Ejemplo n.º 1
0
static struct xccdf_profile *_xccdf_tailoring_profile_get_real_parent(struct xccdf_tailoring *tailoring, struct xccdf_profile *profile)
{
	const char *extends = xccdf_profile_get_extends(profile);
	struct xccdf_profile *parent_from_tailoring = xccdf_tailoring_get_profile_by_id(tailoring, extends);
	if (parent_from_tailoring != NULL && parent_from_tailoring != profile) {
		return parent_from_tailoring;
	}
	else {
		return XPROFILE(xccdf_benchmark_get_member(xccdf_profile_get_benchmark(profile), XCCDF_PROFILE, extends));
	}
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
0
struct xccdf_tailoring *xccdf_tailoring_parse(xmlTextReaderPtr reader, struct xccdf_item *benchmark)
{
	XCCDF_ASSERT_ELEMENT(reader, XCCDFE_TAILORING);

	struct xccdf_tailoring *tailoring = xccdf_tailoring_new();

	const char *id = xccdf_attribute_get(reader, XCCDFA_ID);
	xccdf_tailoring_set_id(tailoring, id);

	int depth = oscap_element_depth(reader) + 1;

	// Read to the inside of Tailoring.
	xmlTextReaderRead(reader);

	while (oscap_to_start_element(reader, depth)) {
		switch (xccdf_element_get(reader)) {
		case XCCDFE_BENCHMARK_REF: {
			oscap_free(tailoring->benchmark_ref);
			tailoring->benchmark_ref = 0;

			oscap_free(tailoring->benchmark_ref_version);
			tailoring->benchmark_ref_version = 0;

			const char *ref = xccdf_attribute_get(reader, XCCDFA_HREF);
			if (ref)
				tailoring->benchmark_ref = oscap_strdup(ref);

			const char *ref_version = xccdf_attribute_get(reader, XCCDFA_VERSION);
			if (ref_version)
				tailoring->benchmark_ref_version = oscap_strdup(ref_version);

			break;
		}
		case XCCDFE_STATUS: {
			const char *date = xccdf_attribute_get(reader, XCCDFA_DATE);
			char *str = oscap_element_string_copy(reader);
			struct xccdf_status *status = xccdf_status_new_fill(str, date);
			oscap_free(str);
			oscap_list_add(tailoring->statuses, status);
			break;
		}
		case XCCDFE_DC_STATUS:
			oscap_list_add(tailoring->dc_statuses, oscap_reference_new_parse(reader));
			break;
		case XCCDFE_VERSION: {
			xmlNode *ver = xmlTextReaderExpand(reader);
			/* optional attributes */
			tailoring->version_time = (char*) xmlGetProp(ver, BAD_CAST "time");
			tailoring->version_update = (char*) xmlGetProp(ver, BAD_CAST "update");
			/* content */
			tailoring->version = (char *) xmlNodeGetContent(ver);
			if (oscap_streq(tailoring->version, "")) {
				oscap_free(tailoring->version);
				tailoring->version = NULL;
			}
			break;
		}
		case XCCDFE_METADATA: {
			char* xml = oscap_get_xml(reader);
			oscap_list_add(tailoring->metadata, oscap_strdup(xml));
			oscap_free(xml);
			break;
		}
		case XCCDFE_PROFILE: {
			struct xccdf_item *item = xccdf_profile_parse(reader, benchmark);
			if (!xccdf_tailoring_add_profile(tailoring, XPROFILE(item))) {
				dW("Failed to add profile to tailoring while parsing!");
			}
			break;
		}
		default:
			dW("Encountered an unknown element '%s' while parsing XCCDF Tailoring element.",
				xmlTextReaderConstLocalName(reader));
		}
		xmlTextReaderRead(reader);
	}

	return tailoring;
}