Exemple #1
0
int ds_sds_session_register_component_with_dependencies(struct ds_sds_session *session, const char *container_name, const char *component_id, const char *target_filename)
{
	xmlNode *datastream = ds_sds_session_get_selected_datastream(session);
	if (!datastream) {
		return -1;
	}

	xmlNodePtr container = node_get_child_element(datastream, container_name);
	if (!container) {
		if (ds_sds_session_get_datastream_id(session) == NULL)
			oscap_seterr(OSCAP_EFAMILY_XML, "No '%s' container element found in file '%s' in the first datastream.",
					container_name, oscap_source_readable_origin(session->source));
		else
			oscap_seterr(OSCAP_EFAMILY_XML, "No '%s' container element found in file '%s' in datastream of id '%s'.",
					container_name, oscap_source_readable_origin(session->source), ds_sds_session_get_datastream_id(session));
		return -1;
	}

	int res = -1;
	xmlNode *component_ref = containter_get_component_ref_by_id(container, component_id);
	if (component_ref != NULL) {
		if (target_filename == NULL) {
			res = ds_sds_dump_component_ref(component_ref, session);
		} else {
			res = ds_sds_dump_component_ref_as(component_ref, session, "." , target_filename);
		}
	}
	else {
		oscap_seterr(OSCAP_EFAMILY_XML, "No '%s' component ref found in file '%s' in datastream of id '%s'.",
				component_id, oscap_source_readable_origin(session->source), ds_sds_session_get_datastream_id(session));
		return -1;
	}

	return res;
}
Exemple #2
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;
}
Exemple #3
0
const char *ds_sds_session_get_readable_origin(const struct ds_sds_session *session)
{
	if (session->source == NULL)
		return NULL;

	return oscap_source_readable_origin(session->source);
}
int ds_rds_session_register_component_source(struct ds_rds_session *session, const char *content_id, struct oscap_source *component)
{
	if (!oscap_htable_add(session->component_sources, content_id, component)) {
		oscap_seterr(OSCAP_EFAMILY_OSCAP, "Content '%s' has already been register with Result DataStream session: %s",
				content_id, oscap_source_readable_origin(session->source));
		return -1;
	}
	return 0;
}
Exemple #5
0
int ds_sds_session_register_component_source(struct ds_sds_session *session, const char *relative_filepath, struct oscap_source *component)
{
	if (!oscap_htable_add(session->component_sources, relative_filepath, component)) {
		oscap_seterr(OSCAP_EFAMILY_OSCAP, "File %s has already been register with Source DataStream session: %s",
			relative_filepath, oscap_source_readable_origin(session->source));
		return -1;
	}
	return 0;
}
Exemple #6
0
int ds_dump_component_sources(struct oscap_htable *component_sources, const char *target_dir)
{
	struct oscap_htable_iterator *hit = oscap_htable_iterator_new(component_sources);
	while (oscap_htable_iterator_has_more(hit)) {
		struct oscap_source *s = oscap_htable_iterator_next_value(hit);
		char *filename = target_dir == NULL ? oscap_strdup(oscap_source_readable_origin(s))
				: oscap_sprintf("%s/%s", target_dir, oscap_source_readable_origin(s));
		int ret = oscap_acquire_ensure_parent_dir(filename);
		if (ret != 0) {
			oscap_htable_iterator_free(hit);
			return ret;
		}
		ret = oscap_source_save_as(s, filename);
		free(filename);
		if (ret != 0) {
			oscap_htable_iterator_free(hit);
			return ret;
		}
	}
	oscap_htable_iterator_free(hit);
	return 0;
}
Exemple #7
0
struct cpe_lang_model *cpe_lang_model_import_source(struct oscap_source *source)
{
	xmlTextReaderPtr reader = oscap_source_get_xmlTextReader(source);
	struct cpe_lang_model *ret = NULL;

	if (reader != NULL) {
		xmlTextReaderNextNode(reader);
		ret = cpe_lang_model_parse(reader);
		if (ret != NULL) {
			cpe_lang_model_set_origin_file(ret, oscap_source_readable_origin(source));
		}
	}
	xmlFreeTextReader(reader);
	return ret;
}
Exemple #8
0
int oscap_source_validate_priv(struct oscap_source *source, oscap_document_type_t doc_type, const char *version, xml_reporter reporter, void *user)
{
	if (version == NULL) {
		oscap_seterr(OSCAP_EFAMILY_OSCAP, "Could not determine version for file: %s", oscap_source_readable_origin(source));
		return -1;
	}

	/* find a right schema file */
	for (struct oscap_schema_table_entry *entry = OSCAP_SCHEMAS_TABLE; entry->doc_type != 0; ++entry) {
		if (entry->doc_type != doc_type || strcmp(entry->schema_version, version))
			continue;

		return oscap_validate_xml(source, entry->schema_path, reporter, user);
	}

	oscap_seterr(OSCAP_EFAMILY_OSCAP, "Schema file not found when trying to validate '%s'", oscap_source_readable_origin(source));
	return -1;
}
Exemple #9
0
static inline int oscap_validate_xml(struct oscap_source *source, const char *schemafile, xml_reporter reporter, void *arg)
{
	int result = -1;
	xmlSchemaParserCtxtPtr parser_ctxt = NULL;
	xmlSchemaPtr schema = NULL;
	xmlSchemaValidCtxtPtr ctxt = NULL;
	xmlDocPtr doc = NULL;

	struct ctxt context = { reporter, arg, (void*) oscap_source_readable_origin(source)};

	if (schemafile == NULL) {
		oscap_seterr(OSCAP_EFAMILY_OSCAP, "'schemafile' == NULL");
		return -1;
	}

	char * schemapath = oscap_sprintf("%s%s%s", oscap_path_to_schemas(), "/", schemafile);
	if (access(schemapath, R_OK)) {
		oscap_seterr(OSCAP_EFAMILY_OSCAP, "Schema file '%s' not found in path '%s' when trying to validate '%s'",
				schemafile, oscap_path_to_schemas(), oscap_source_readable_origin(source));
		goto cleanup;
	}

	parser_ctxt = xmlSchemaNewParserCtxt(schemapath);
	if (parser_ctxt == NULL) {
		oscap_seterr(OSCAP_EFAMILY_XML, "Could not create parser context for validation");
		goto cleanup;
	}

	xmlSchemaSetParserStructuredErrors(parser_ctxt, oscap_xml_validity_handler, &context);

	schema = xmlSchemaParse(parser_ctxt);
	if (schema == NULL) {
		oscap_seterr(OSCAP_EFAMILY_XML, "Could not parse XML schema");
		goto cleanup;
	}

	ctxt = xmlSchemaNewValidCtxt(schema);
	if (ctxt == NULL) {
		oscap_seterr(OSCAP_EFAMILY_XML, "Could not create validation context");
		goto cleanup;
	}

	xmlSchemaSetValidStructuredErrors(ctxt, oscap_xml_validity_handler, &context);

	doc = oscap_source_get_xmlDoc(source);
	if (!doc)
		goto cleanup;

	result = xmlSchemaValidateDoc(ctxt, doc);

	/*
	 * xmlSchemaValidateFile() returns "-1" if document is not well formed
	 * thefore we ignore libxml internal errors here and map return code to
	 * either pass or fail.
	 */
	if (result != 0)
		result = 1;
	/* This would be nicer
	 * if (result ==  -1)
	 *	oscap_setxmlerr(xmlGetLastError());
	*/

cleanup:
	if (ctxt)
		xmlSchemaFreeValidCtxt(ctxt);
	if (schema)
		xmlSchemaFree(schema);
	if (parser_ctxt)
		xmlSchemaFreeParserCtxt(parser_ctxt);
	oscap_free(schemapath);

	return result;
}
Exemple #10
0
static int ds_sds_compose_add_component_dependencies(xmlDocPtr doc, xmlNodePtr datastream, struct oscap_source *component_source, xmlNodePtr catalog, int component_type)
{
	xmlDocPtr component_doc = oscap_source_get_xmlDoc(component_source);
	if (component_doc == NULL)
	{
		return -1;
	}

	xmlXPathContextPtr xpathCtx = xmlXPathNewContext(component_doc);
	if (xpathCtx == NULL)
	{
		oscap_seterr(OSCAP_EFAMILY_XML, "Error: unable to create new XPath context.");
		return -1;
	}

	xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression(
			// we want robustness and support for future versions, this expression
			// retrieves check-content-refs from any namespace
			BAD_CAST _get_dep_xpath_for_type(component_type),
			xpathCtx);
	if (xpathObj == NULL)
	{
		oscap_seterr(OSCAP_EFAMILY_XML, "Error: Unable to evalute XPath expression.");
		xmlXPathFreeContext(xpathCtx);

		return -1;
	}

	xmlNsPtr cat_ns = xmlSearchNsByHref(doc, datastream, BAD_CAST cat_ns_uri);

	xmlNodeSetPtr nodeset = xpathObj->nodesetval;
	if (nodeset != NULL)
	{
		struct oscap_htable *exported = oscap_htable_new();
		char* filepath_cpy = oscap_strdup(oscap_source_readable_origin(component_source));
		const char* dir = dirname(filepath_cpy);

		for (int i = 0; i < nodeset->nodeNr; i++)
		{
			xmlNodePtr node = nodeset->nodeTab[i];

			if (node->type != XML_ELEMENT_NODE)
				continue;

			if (xmlHasProp(node, BAD_CAST "href"))
			{
				char* href = (char*)xmlGetProp(node, BAD_CAST "href");
				if (oscap_htable_get(exported, href) != NULL) {
					// This path has been already exported. Do not export duplicate.
					xmlFree(href);
					continue;
				}
				oscap_htable_add(exported, href, "");

				if (oscap_acquire_url_is_supported(href)) {
					/* If the referenced component is remote one, do not include
					 * it within the DataStream. Such component shall only be
					 * downloaded once the scan is run. */
					xmlFree(href);
					continue;
				}

				char* real_path = (strcmp(dir, "") == 0 || strcmp(dir, ".") == 0) ?
					oscap_strdup(href) : oscap_sprintf("%s/%s", dir, href);

				char* mangled_path = ds_sds_mangle_filepath(real_path);
				char* cref_id = oscap_sprintf("scap_org.open-scap_cref_%s", mangled_path);

				int counter = 0;
				while (ds_sds_find_component_ref(datastream, cref_id) != NULL) {
					// While the given component ID already exists in the document.
					oscap_free(cref_id);
					cref_id = oscap_sprintf("scap_org.open-scap_cref_%s%03d", mangled_path, counter++);
				}
				oscap_free(mangled_path);

				char* uri = oscap_sprintf("#%s", cref_id);

				// we don't want duplicated uri elements in the catalog
				if (ds_sds_compose_catalog_has_uri(doc, catalog, uri) == 0)
				{
					oscap_free(uri);
					oscap_free(cref_id);
					oscap_free(real_path);
					xmlFree(href);
					continue;
				}

				int ret = ds_sds_compose_add_component_with_ref(doc, datastream, real_path, cref_id);
				if (ret == 0) {
					xmlNodePtr catalog_uri = xmlNewNode(cat_ns, BAD_CAST "uri");
					xmlSetProp(catalog_uri, BAD_CAST "name", BAD_CAST href);
					xmlSetProp(catalog_uri, BAD_CAST "uri", BAD_CAST uri);
					xmlAddChild(catalog, catalog_uri);
				}

				oscap_free(cref_id);
				oscap_free(uri);
				oscap_free(real_path);
				xmlFree(href);

				if (ret < 0) {
					// oscap_seterr has already been called
					oscap_htable_free0(exported);
					return -1;
				}

			}
		}

		oscap_htable_free0(exported);
		oscap_free(filepath_cpy);
	}

	xmlXPathFreeObject(xpathObj);
	xmlXPathFreeContext(xpathCtx);

	return 0;
}