Exemplo n.º 1
0
static int ds_dsd_dump_remote_component(const char* url, const char* component_id, struct ds_sds_session *session, const char *target_filename_dirname, const char *relative_filepath)
{
	int ret = 0;
	size_t memory_size = 0;

	ds_sds_session_remote_resources_progress(session)(false, "Downloading: %s ... ", url);

	char* mem = oscap_acquire_url_download(url, &memory_size);
	if (mem == NULL) {
		ds_sds_session_remote_resources_progress(session)(false, "error\n", url);
		return -1;
	}

	ds_sds_session_remote_resources_progress(session)(false, "ok\n", url);

	struct oscap_source *source_file = oscap_source_new_take_memory(mem, memory_size, url);
	xmlDoc *doc = oscap_source_get_xmlDoc(source_file);

	if (doc == NULL) {
		ret = -1;
		goto cleanup;
	}

	xmlNodePtr inner_root = ds_sds_get_component_root_by_id(doc, component_id);

	if (ds_sds_register_component(session, doc, inner_root, component_id, target_filename_dirname, relative_filepath) != 0) {
		ret = -1;
		goto cleanup;
	}

	cleanup:
		oscap_source_free(source_file);
		return ret;
}
Exemplo n.º 2
0
int ds_rds_session_replace_report_with_source(struct ds_rds_session *session, struct oscap_source *source)
{
	xmlDoc *doc = oscap_source_get_xmlDoc(session->source);
	xmlNode *reports_node = ds_rds_lookup_container(doc, "reports");
	xmlNode *report_node = ds_rds_lookup_component(doc, "reports", "report", session->report_id);
	xmlDOMWrapCtxtPtr wrap_ctxt = xmlDOMWrapNewCtxt();
	if (xmlDOMWrapRemoveNode(wrap_ctxt, doc, report_node, 0) != 0) {
		oscap_seterr(OSCAP_EFAMILY_OSCAP, "Could not remove arf:report[@id='%s'] from result DataStream", session->report_id);
		return 1;
	}
	struct oscap_source *prev_source = oscap_htable_detach(session->component_sources, session->report_id);
	oscap_source_free(prev_source);
	if (ds_rds_session_register_component_source(session, session->report_id, source) != 0) {
		return 1;
	}
	return ds_rds_create_report(doc, reports_node, oscap_source_get_xmlDoc(source), session->report_id) == NULL;
}
Exemplo n.º 3
0
struct oscap_source *ds_rds_create_source(struct oscap_source *sds_source, struct oscap_source *xccdf_result_source, struct oscap_htable *oval_result_sources, const char *target_file)
{
	xmlDoc *sds_doc = oscap_source_get_xmlDoc(sds_source);
	if (sds_doc == NULL) {
		return NULL;
	}
	xmlDoc *result_file_doc = oscap_source_get_xmlDoc(xccdf_result_source);
	if (result_file_doc == NULL) {
		return NULL;
	}

	xmlDocPtr rds_doc = NULL;
	if (ds_rds_create_from_dom(&rds_doc, sds_doc, result_file_doc, oval_result_sources) != 0) {
		return NULL;
	}
	return oscap_source_new_from_xmlDoc(rds_doc, target_file);
}
Exemplo n.º 4
0
xmlNode *ds_sds_session_get_selected_datastream(struct ds_sds_session *session)
{
	xmlDoc *doc = oscap_source_get_xmlDoc(session->source);
	xmlNode *datastream = ds_sds_lookup_datastream_in_collection(doc, session->datastream_id);
	if (datastream == NULL) {
		const char* error = session->datastream_id ?
			oscap_sprintf("Could not find any datastream of id '%s'", session->datastream_id) :
			oscap_sprintf("Could not find any datastream inside the file");
		oscap_seterr(OSCAP_EFAMILY_XML, error);
		oscap_free(error);
	}
	return datastream;
}
Exemplo n.º 5
0
Arquivo: sds.c Projeto: radzy/openscap
int ds_sds_compose_add_component(const char *target_datastream, const char *datastream_id, const char *new_component, bool extended)
{
	struct oscap_source *sds_source = oscap_source_new_from_file(target_datastream);
	xmlDoc *doc = oscap_source_get_xmlDoc(sds_source);
	if (doc == NULL) {
		oscap_source_free(sds_source);
		return 1;
	}
	xmlNodePtr datastream = ds_sds_lookup_datastream_in_collection(doc, datastream_id);
	if (datastream == NULL) {
		const char* error = datastream_id ?
			oscap_sprintf("Could not find any datastream of id '%s'", datastream_id) :
			oscap_sprintf("Could not find any datastream inside the file");

		oscap_seterr(OSCAP_EFAMILY_XML, error);
		oscap_free(error);
		oscap_source_free(sds_source);
		return 1;
	}

	char* mangled_path = ds_sds_mangle_filepath(new_component);

	char* cref_id = oscap_sprintf("scap_org.open-scap_cref_%s", mangled_path);
	oscap_free(mangled_path);
	if (ds_sds_compose_add_component_with_ref(doc, datastream, new_component, cref_id) != 0) {
		oscap_free(cref_id);
		oscap_source_free(sds_source);
		return 1;
	}
	oscap_free(cref_id);

	if (oscap_source_save_as(sds_source, NULL) != 0) {
		oscap_seterr(OSCAP_EFAMILY_GLIBC, "Error saving source datastream to '%s'.", target_datastream);
		oscap_source_free(sds_source);
		return 1;
	}
	oscap_source_free(sds_source);
	return 0;
}
Exemplo n.º 6
0
static int ds_sds_dump_file_component(const char* external_file, const char* component_id, struct ds_sds_session *session, const char *target_filename_dirname, const char *relative_filepath)
{
	int ret = 0;

	struct oscap_source *source_file = load_referenced_source(session, external_file);
	xmlDoc *doc = oscap_source_get_xmlDoc(source_file);

	if (doc == NULL) {
		ret = -1;
		goto cleanup;
	}

	xmlNodePtr inner_root = ds_sds_get_component_root_by_id(doc, component_id);

	if (ds_sds_register_component(session, doc, inner_root, component_id, target_filename_dirname, relative_filepath) != 0) {
		ret = -1;
		goto cleanup;
	}

	cleanup:
		oscap_source_free(source_file);
		return ret;
}
Exemplo n.º 7
0
int ds_rds_create(const char* sds_file, const char* xccdf_result_file, const char** oval_result_files, const char* target_file)
{
	struct oscap_source *sds_source = oscap_source_new_from_file(sds_file);
	struct oscap_source *xccdf_result_source = oscap_source_new_from_file(xccdf_result_file);
	struct oscap_htable *oval_result_sources = oscap_htable_new();

	int result = 0;
	// this check is there to allow passing NULL instead of having to allocate
	// an empty array
	if (oval_result_files != NULL)
	{
		while (*oval_result_files != NULL)
		{
			struct oscap_source *oval_source = oscap_source_new_from_file(*oval_result_files);
			if (oscap_source_get_xmlDoc(oval_source) == NULL) {
				result = -1;
				oscap_source_free(oval_source);
			} else {
				oscap_htable_add(oval_result_sources, *oval_result_files, oval_source);
			}
			oval_result_files++;
		}
	}
	if (result == 0) {
		struct oscap_source *target_rds = ds_rds_create_source(sds_source, xccdf_result_source, oval_result_sources, target_file);
		result = target_rds == NULL;
		if (result == 0) {
			result = oscap_source_save_as(target_rds, NULL);
		}
		oscap_source_free(target_rds);
	}
	oscap_htable_free(oval_result_sources, (oscap_destruct_func) oscap_source_free);
	oscap_source_free(sds_source);
	oscap_source_free(xccdf_result_source);

	return result;
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
0
xmlDoc *ds_rds_session_get_xmlDoc(struct ds_rds_session *session)
{
	return oscap_source_get_xmlDoc(session->source);
}
Exemplo n.º 10
0
static int ds_rds_create_from_dom(xmlDocPtr* ret, xmlDocPtr sds_doc, xmlDocPtr xccdf_result_file_doc, struct oscap_htable* oval_result_sources)
{
	*ret = NULL;

	xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
	xmlNodePtr root = xmlNewNode(NULL, BAD_CAST "asset-report-collection");
	xmlDocSetRootElement(doc, root);

	xmlNsPtr arf_ns = xmlNewNs(root, BAD_CAST arf_ns_uri, BAD_CAST "arf");
	xmlSetNs(root, arf_ns);

	xmlNsPtr core_ns = xmlNewNs(root, BAD_CAST core_ns_uri, BAD_CAST "core");
	xmlNewNs(root, BAD_CAST ai_ns_uri, BAD_CAST "ai");

	xmlNodePtr relationships = xmlNewNode(core_ns, BAD_CAST "relationships");
	xmlNewNs(relationships, BAD_CAST arfvocab_ns_uri, BAD_CAST "arfvocab");
	xmlNewNs(relationships, BAD_CAST arfrel_ns_uri, BAD_CAST "arfrel");
	xmlAddChild(root, relationships);

	xmlNodePtr report_requests = xmlNewNode(arf_ns, BAD_CAST "report-requests");
	xmlAddChild(root, report_requests);

	xmlNodePtr assets = xmlNewNode(arf_ns, BAD_CAST "assets");
	xmlAddChild(root, assets);

	xmlNodePtr report_request = xmlNewNode(arf_ns, BAD_CAST "report-request");
	xmlSetProp(report_request, BAD_CAST "id", BAD_CAST "collection1");

	xmlNodePtr arf_content = xmlNewNode(arf_ns, BAD_CAST "content");

	xmlDOMWrapCtxtPtr sds_wrap_ctxt = xmlDOMWrapNewCtxt();
	xmlNodePtr sds_res_node = NULL;
	xmlDOMWrapCloneNode(sds_wrap_ctxt, sds_doc, xmlDocGetRootElement(sds_doc),
			&sds_res_node, doc, NULL, 1, 0);
	xmlAddChild(arf_content, sds_res_node);
	xmlDOMWrapReconcileNamespaces(sds_wrap_ctxt, sds_res_node, 0);
	xmlDOMWrapFreeCtxt(sds_wrap_ctxt);

	xmlAddChild(report_request, arf_content);

	xmlAddChild(report_requests, report_request);

	xmlNodePtr reports = xmlNewNode(arf_ns, BAD_CAST "reports");

	ds_rds_add_xccdf_test_results(doc, reports, xccdf_result_file_doc,
			relationships, assets, "collection1");

	unsigned int oval_report_suffix = 2;
	struct oscap_htable_iterator *hit = oscap_htable_iterator_new(oval_result_sources);
	while (oscap_htable_iterator_has_more(hit)) {
		struct oscap_source *oval_source = oscap_htable_iterator_next_value(hit);
		xmlDoc *oval_result_doc = oscap_source_get_xmlDoc(oval_source);

		char* report_id = oscap_sprintf("oval%i", oval_report_suffix++);
		ds_rds_create_report(doc, reports, oval_result_doc, report_id);
		oscap_free(report_id);
	}
	oscap_htable_iterator_free(hit);

	xmlAddChild(root, reports);

	*ret = doc;
	return 0;
}
Exemplo n.º 11
0
Arquivo: sds.c Projeto: radzy/openscap
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;
}
Exemplo n.º 12
0
Arquivo: sds.c Projeto: radzy/openscap
static int ds_sds_compose_add_component_internal(xmlDocPtr doc, xmlNodePtr datastream, const char* filepath, const char* comp_id, bool extended)
{
	xmlNsPtr ds_ns = xmlSearchNsByHref(doc, datastream, BAD_CAST datastream_ns_uri);
	if (!ds_ns)
	{
		oscap_seterr(OSCAP_EFAMILY_GLIBC,
				"Unable to find namespace '%s' in the XML DOM tree when create "
				"source datastream. This is most likely an internal error!",
				datastream_ns_uri);
		return -1;
	}

	char file_timestamp[32];
	strcpy(file_timestamp, "0000-00-00T00:00:00");

	struct stat file_stat;
	if (stat(filepath, &file_stat) == 0)
		strftime(file_timestamp, 32, "%Y-%m-%dT%H:%M:%S", localtime(&file_stat.st_mtime));
	else {
		oscap_seterr(OSCAP_EFAMILY_GLIBC, "Could not find file %s: %s.", filepath, strerror(errno));
		// Return positive number, indicating less severe problem.
		// Rationale: When an OVAL file is missing during a scan it it not considered
		// to be deal breaker (it shall have 'notchecked' result), thus we shall allow
		// DataStreams with missing OVAL.
		return 1;
	}

	xmlNodePtr component = xmlNewNode(ds_ns, BAD_CAST (extended ? "extended-component" : "component"));
	xmlSetProp(component, BAD_CAST "id", BAD_CAST comp_id);
	xmlSetProp(component, BAD_CAST "timestamp", BAD_CAST file_timestamp);

	xmlNodePtr doc_root = xmlDocGetRootElement(doc);

	if (extended) {
		if (ds_sds_compose_component_add_script_content(component, filepath) == -1) {
			xmlFreeNode(component);
			return -1;
		}
		// extended components always go at the end
		xmlAddChild(doc_root, component);
	} else {
		struct oscap_source *component_source = oscap_source_new_from_file(filepath);
		xmlDoc *component_doc = oscap_source_get_xmlDoc(component_source);
		if (!component_doc) {
			oscap_seterr(OSCAP_EFAMILY_XML, "Could not read/parse XML of given input file at path '%s'.", filepath);
			xmlFreeNode(component);
			oscap_source_free(component_source);
			return -1;
		}

		xmlNodePtr component_root = xmlDocGetRootElement(component_doc);

		xmlDOMWrapCtxtPtr wrap_ctxt = xmlDOMWrapNewCtxt();

		xmlNodePtr res_component_root = NULL;
		if (xmlDOMWrapCloneNode(wrap_ctxt, component_doc, component_root, &res_component_root, doc, NULL, 1, 0) != 0)
		{
			oscap_seterr(OSCAP_EFAMILY_XML,
					"Cannot clone node when adding component from file '%s' with id '%s' while "
					"creating source datastream.", filepath, comp_id);

			xmlDOMWrapFreeCtxt(wrap_ctxt);
			oscap_source_free(component_source);
			xmlFreeNode(component);

			return -1;
		}
		if (xmlDOMWrapReconcileNamespaces(wrap_ctxt, res_component_root, 0) != 0)
		{
			oscap_seterr(OSCAP_EFAMILY_XML,
					"Cannot reconcile namespaces when adding component from file '%s' with id '%s' while "
					"creating source datastream.", filepath, comp_id);

			xmlDOMWrapFreeCtxt(wrap_ctxt);
			oscap_source_free(component_source);
			xmlFreeNode(component);

			return -1;
		}

		xmlAddChild(component, res_component_root);

		xmlDOMWrapFreeCtxt(wrap_ctxt);

		// this component is not extended, we have to figure out if there
		// already is an extended-component and if so, add it right before
		// that component

		xmlNodePtr first_extended_component = node_get_child_element(doc_root, "extended-component");
		if (first_extended_component == NULL)
		{
			// no extended component yet, add to the end
			xmlAddChild(doc_root, component);
		}
		else
		{
			xmlAddPrevSibling(first_extended_component, component);
		}
		oscap_source_free(component_source);
	}

	return 0;
}