コード例 #1
0
ファイル: sds.c プロジェクト: 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;
}
コード例 #2
0
ファイル: sds.c プロジェクト: nevion/openscap
static int ds_sds_dump_component_by_href(struct ds_sds_session *session, char* xlink_href, char *target_filename_dirname, const char* relative_filepath, char* cref_id, char **component_id)
{
	if (!xlink_href || strlen(xlink_href) < 2)
	{
		oscap_seterr(OSCAP_EFAMILY_XML, "No or invalid xlink:href attribute on given component-ref.");
		return -1;
	}

	if (xlink_href[0] == '#')
	{
		*component_id = xlink_href + 1;

		return ds_sds_dump_local_component(*component_id, session, target_filename_dirname, relative_filepath);

	} else if (oscap_str_startswith(xlink_href, "file:")){

		char* sep = strchr(xlink_href, '#');

		const char *filename = xlink_href + strlen("file:");

		if (sep == NULL) {
			*component_id = NULL;
		} else {
			*sep = '\0';
			*component_id = sep + 1;
		}

		return ds_sds_dump_file_component(filename, *component_id, session, target_filename_dirname, relative_filepath);

	} else if (oscap_acquire_url_is_supported(xlink_href)){
		char *sep = strchr(xlink_href, '#');

		char* url = xlink_href;

		if (sep == NULL) {
			*component_id = NULL;
		} else {
			*sep = '\0';
			*component_id = sep + 1;
		}

		if (!ds_sds_session_fetch_remote_resources(session)) {
			static bool fetch_remote_resources_suggested = false;

			if (!fetch_remote_resources_suggested) {
				fetch_remote_resources_suggested = true;
				ds_sds_session_remote_resources_progress(session)(true, "WARNING: Datastream component '%s' points out to the remote '%s'. "
									"Use '--fetch-remote-resources' option to download it.\n", cref_id, url);
			}

			ds_sds_session_remote_resources_progress(session)(true, "WARNING: Skipping '%s' file which is referenced from datastream\n", url);
			return -2;
		}

		return ds_dsd_dump_remote_component(url, *component_id, session, target_filename_dirname, relative_filepath);
	} else {
		oscap_seterr(OSCAP_EFAMILY_XML, "Unsupported type of xlink:href attribute on given component-ref - '%s'.", xlink_href);
		return -1;
	}
	return 0;
}