Blame SOURCES/openscap-1.3.6-PR-1769-local-ds-components.patch

909fca
From 35ae94cd84b7b99845f0d2306924946e66da6d50 Mon Sep 17 00:00:00 2001
909fca
From: =?UTF-8?q?Jan=20=C4=8Cern=C3=BD?= <jcerny@redhat.com>
909fca
Date: Tue, 15 Jun 2021 10:09:44 +0200
909fca
Subject: [PATCH 01/10] Allow providing pre-downloaded components
909fca
909fca
OpenSCAP can download remote SCAP source data stream components from the
909fca
internet if the --fetch-remote-resources option is set. When this
909fca
command line option isn't set, it is possible to download the remote
909fca
component separately, save it as file to the filesystem which name is
909fca
equal to the name of the remote component and OpenSCAP would use this
909fca
local file instead of just skipping the checks. It currently works by
909fca
accident, it wasn't intended to work this way or at least I haven't
909fca
heard it before, but somobody found out that it works and documented it
909fca
as a KSC: https://access.redhat.com/solutions/5185891. However, it
909fca
produces warning messages if the approach used in the KSC is used.
909fca
909fca
This patch promotes the workaround to a feature. And it changes the
909fca
logic so that it won't print the warnings.
909fca
909fca
The main difference is that it won't work automatically, but only
909fca
on user's demand by providing --use-local-file which is the new
909fca
command line option introduced by this commit.
909fca
909fca
Fixes: rhbz#1970527
909fca
---
909fca
 src/DS/ds_sds_session.c                       | 14 ++-
909fca
 src/DS/ds_sds_session_priv.h                  |  1 +
909fca
 src/DS/public/ds_sds_session.h                | 15 ++-
909fca
 src/DS/sds.c                                  | 22 +++++
909fca
 src/OVAL/oval_session.c                       | 11 ++-
909fca
 src/OVAL/public/oval_session.h                | 15 ++-
909fca
 src/XCCDF/public/xccdf_session.h              | 15 ++-
909fca
 src/XCCDF/xccdf_session.c                     | 36 ++++---
909fca
 tests/DS/CMakeLists.txt                       |  1 +
909fca
 .../remote.oval.xml                           | 58 +++++++++++
909fca
 .../remote_content_1.3.ds.xml                 | 96 +++++++++++++++++++
909fca
 .../DS/test_ds_use_local_remote_resources.sh  | 57 +++++++++++
909fca
 utils/oscap-ds.c                              |  6 +-
909fca
 utils/oscap-info.c                            |  4 +-
909fca
 utils/oscap-oval.c                            |  6 +-
909fca
 utils/oscap-tool.h                            |  1 +
909fca
 utils/oscap-xccdf.c                           | 14 ++-
909fca
 utils/oscap.8                                 | 26 +++++
909fca
 18 files changed, 369 insertions(+), 29 deletions(-)
909fca
 create mode 100644 tests/DS/ds_use_local_remote_resources/remote.oval.xml
909fca
 create mode 100644 tests/DS/ds_use_local_remote_resources/remote_content_1.3.ds.xml
909fca
 create mode 100755 tests/DS/test_ds_use_local_remote_resources.sh
909fca
909fca
diff --git a/src/DS/ds_sds_session.c b/src/DS/ds_sds_session.c
909fca
index 8c0072bae0..9d9a9c8b52 100644
909fca
--- a/src/DS/ds_sds_session.c
909fca
+++ b/src/DS/ds_sds_session.c
909fca
@@ -55,6 +55,7 @@ struct ds_sds_session {
909fca
 	struct oscap_htable *component_uris;    ///< maps component refs to component URIs
909fca
 	bool fetch_remote_resources;            ///< Allows loading of external components;
909fca
 	download_progress_calllback_t progress;	///< Callback to report progress of download.
909fca
+	bool use_local_file;                    ///< Use a locally downloaded copy of a remote resource if it exists
909fca
 };
909fca
 
909fca
 /**
909fca
@@ -337,12 +338,23 @@ int ds_sds_session_register_component_with_dependencies(struct ds_sds_session *s
909fca
 	return res;
909fca
 }
909fca
 
909fca
-void ds_sds_session_set_remote_resources(struct ds_sds_session *session, bool allowed, download_progress_calllback_t callback)
909fca
+void ds_sds_session_configure_remote_resources(struct ds_sds_session *session, bool allowed, bool use_local_file, download_progress_calllback_t callback)
909fca
 {
909fca
 	session->fetch_remote_resources = allowed;
909fca
+	session->use_local_file = use_local_file;
909fca
 	session->progress = (callback != NULL) ? callback : download_progress_empty_calllback;
909fca
 }
909fca
 
909fca
+void ds_sds_session_set_remote_resources(struct ds_sds_session *session, bool allowed, download_progress_calllback_t callback)
909fca
+{
909fca
+	ds_sds_session_configure_remote_resources(session, allowed, false, callback);
909fca
+}
909fca
+
909fca
+bool ds_sds_session_can_use_local_file(struct ds_sds_session *session)
909fca
+{
909fca
+	return session->use_local_file;
909fca
+}
909fca
+
909fca
 int ds_sds_session_dump_component_files(struct ds_sds_session *session)
909fca
 {
909fca
 	return ds_dump_component_sources(session->component_sources, ds_sds_session_get_target_dir(session));
909fca
diff --git a/src/DS/ds_sds_session_priv.h b/src/DS/ds_sds_session_priv.h
909fca
index f58231dc48..018cd053ec 100644
909fca
--- a/src/DS/ds_sds_session_priv.h
909fca
+++ b/src/DS/ds_sds_session_priv.h
909fca
@@ -40,6 +40,7 @@ struct oscap_htable *ds_sds_session_get_component_sources(struct ds_sds_session
909fca
 struct oscap_htable *ds_sds_session_get_component_uris(struct ds_sds_session *session);
909fca
 const char *ds_sds_session_get_readable_origin(const struct ds_sds_session *session);
909fca
 bool ds_sds_session_fetch_remote_resources(struct ds_sds_session *session);
909fca
+bool ds_sds_session_can_use_local_file(struct ds_sds_session *session);
909fca
 download_progress_calllback_t ds_sds_session_remote_resources_progress(struct ds_sds_session *session);
909fca
 
909fca
 void download_progress_empty_calllback(bool warning, const char * format, ...);
909fca
diff --git a/src/DS/public/ds_sds_session.h b/src/DS/public/ds_sds_session.h
909fca
index 20a85146cc..695a0df215 100644
909fca
--- a/src/DS/public/ds_sds_session.h
909fca
+++ b/src/DS/public/ds_sds_session.h
909fca
@@ -200,7 +200,20 @@ OSCAP_API void ds_sds_session_reset(struct ds_sds_session *session);
909fca
  * @param callback used to notify user about download proceeds. This might be safely set
909fca
  * to NULL -- ignoring user notification.
909fca
  */
909fca
-OSCAP_API void ds_sds_session_set_remote_resources(struct ds_sds_session *session, bool allowed, download_progress_calllback_t callback);
909fca
+OSCAP_API OSCAP_DEPRECATED(void ds_sds_session_set_remote_resources(struct ds_sds_session *session, bool allowed, download_progress_calllback_t callback));
909fca
+
909fca
+/**
909fca
+ * Set property of remote content.
909fca
+ * @memberof ds_sds_session
909fca
+ * @param session The source data stream session
909fca
+ * @param allowed Whether is download of remote resources allowed in this
909fca
+ * session (defaults to false)
909fca
+ * @param use_local_file Allows to use a locally downloaded copy of the remote
909fca
+ * resource if it exists (defaults to false)
909fca
+ * @param callback used to notify user about download proceeds. This might be
909fca
+ * safely set to NULL -- ignoring user notification.
909fca
+ */
909fca
+OSCAP_API void ds_sds_session_configure_remote_resources(struct ds_sds_session *session, bool allowed, bool use_local_file, download_progress_calllback_t callback);
909fca
 
909fca
 /**
909fca
  * Returns HTML representation of selected checklist in form of OpenSCAP guide.
909fca
diff --git a/src/DS/sds.c b/src/DS/sds.c
909fca
index 0f19a81982..b1737aa57f 100644
909fca
--- a/src/DS/sds.c
909fca
+++ b/src/DS/sds.c
909fca
@@ -413,6 +413,28 @@ static int ds_sds_dump_component_by_href(struct ds_sds_session *session, char* x
909fca
 		}
909fca
 
909fca
 		if (!ds_sds_session_fetch_remote_resources(session)) {
909fca
+			/*
909fca
+			 * If fetching remote resources isn't allowed by the user let's take
909fca
+			 * a look whether there exists a file whose file name is equal to
909fca
+			 * @name attribute of the uri element within the catalog of the
909fca
+			 * previously processed component-ref which pointed us to the
909fca
+			 * currently processed component-ref. Note that the @name attribute
909fca
+			 * value has been passed as relative_filepath in the recursive call
909fca
+			 * of ds_sds_dump_component_ref_as. If such file exists, we will
909fca
+			 * assume that it's a local copy of the remote component located at
909fca
+			 * the URL defined in @xlink:href. This way people can provide the
909fca
+			 * previously downloaded component which might be useful on systems
909fca
+			 * with limited internet access. This behavior is allowed only when
909fca
+			 * --use-local-file is used on the command line.
909fca
+			 * See: https://bugzilla.redhat.com/show_bug.cgi?id=1970527
909fca
+			 * See: https://access.redhat.com/solutions/5185891
909fca
+			 */
909fca
+			struct stat sb;
909fca
+			if (ds_sds_session_can_use_local_file(session) && stat(relative_filepath, &sb) == 0) {
909fca
+				dI("Using local file '%s' instead of '%s'", relative_filepath, xlink_href);
909fca
+				return ds_sds_dump_file_component(relative_filepath, *component_id, session, target_filename_dirname, relative_filepath);
909fca
+			}
909fca
+
909fca
 			static bool fetch_remote_resources_suggested = false;
909fca
 
909fca
 			if (!fetch_remote_resources_suggested) {
909fca
diff --git a/src/OVAL/oval_session.c b/src/OVAL/oval_session.c
909fca
index ebc7e55f71..5adda43f66 100644
909fca
--- a/src/OVAL/oval_session.c
909fca
+++ b/src/OVAL/oval_session.c
909fca
@@ -84,6 +84,7 @@ struct oval_session {
909fca
 	bool full_validation;
909fca
 	bool fetch_remote_resources;
909fca
 	download_progress_calllback_t progress;
909fca
+	bool use_local_file;
909fca
 };
909fca
 
909fca
 struct oval_session *oval_session_new(const char *filename)
909fca
@@ -223,7 +224,7 @@ static int oval_session_load_definitions(struct oval_session *session)
909fca
 		if ((session->sds_session = ds_sds_session_new_from_source(session->source)) == NULL) {
909fca
 			return 1;
909fca
 		}
909fca
-		ds_sds_session_set_remote_resources(session->sds_session,session->fetch_remote_resources ,session->progress);
909fca
+		ds_sds_session_configure_remote_resources(session->sds_session, session->fetch_remote_resources, session->use_local_file, session->progress);
909fca
 		ds_sds_session_set_datastream_id(session->sds_session, session->datastream_id);
909fca
 		if (ds_sds_session_register_component_with_dependencies(session->sds_session,
909fca
 					"checks", session->component_id, "oval.xml") != 0) {
909fca
@@ -451,12 +452,18 @@ void oval_session_set_export_system_characteristics(struct oval_session *session
909fca
 	session->export_sys_chars = export;
909fca
 }
909fca
 
909fca
-void oval_session_set_remote_resources(struct oval_session *session, bool allowed, download_progress_calllback_t callback)
909fca
+void oval_session_configure_remote_resources(struct oval_session *session, bool allowed, bool use_local_file, download_progress_calllback_t callback)
909fca
 {
909fca
 	session->fetch_remote_resources = allowed;
909fca
+	session->use_local_file = use_local_file;
909fca
 	session->progress = callback;
909fca
 }
909fca
 
909fca
+void oval_session_set_remote_resources(struct oval_session *session, bool allowed, download_progress_calllback_t callback)
909fca
+{
909fca
+	oval_session_configure_remote_resources(session, allowed, false, callback);
909fca
+}
909fca
+
909fca
 void oval_session_free(struct oval_session *session)
909fca
 {
909fca
 	if (session == NULL)
909fca
diff --git a/src/OVAL/public/oval_session.h b/src/OVAL/public/oval_session.h
909fca
index ed97cb7768..d485676747 100644
909fca
--- a/src/OVAL/public/oval_session.h
909fca
+++ b/src/OVAL/public/oval_session.h
909fca
@@ -239,7 +239,20 @@ OSCAP_API void oval_session_set_export_system_characteristics(struct oval_sessio
909fca
  * @param callback used to notify user about download proceeds. This might be safely set
909fca
  * to NULL -- ignoring user notification.
909fca
  */
909fca
-OSCAP_API void oval_session_set_remote_resources(struct oval_session *session, bool allowed, download_progress_calllback_t callback);
909fca
+OSCAP_API OSCAP_DEPRECATED(void oval_session_set_remote_resources(struct oval_session *session, bool allowed, download_progress_calllback_t callback));
909fca
+
909fca
+/**
909fca
+ * Set property of remote content.
909fca
+ * @memberof oval_session
909fca
+ * @param session an \ref oval_session
909fca
+ * @param allowed Whether is download of remote resources allowed in this
909fca
+ * session (defaults to false)
909fca
+ * @param use_local_file Allows to use a locally downloaded copy of the remote
909fca
+ * resource if it exists (defaults to false)
909fca
+ * @param callback used to notify user about download proceeds. This might be
909fca
+ * safely set to NULL -- ignoring user notification.
909fca
+ */
909fca
+OSCAP_API void oval_session_configure_remote_resources(struct oval_session *session, bool allowed, bool use_local_file, download_progress_calllback_t callback);
909fca
 
909fca
 /**
909fca
  * Destructor of an \ref oval_session.
909fca
diff --git a/src/XCCDF/public/xccdf_session.h b/src/XCCDF/public/xccdf_session.h
909fca
index 70cfc677f3..2eb7128019 100644
909fca
--- a/src/XCCDF/public/xccdf_session.h
909fca
+++ b/src/XCCDF/public/xccdf_session.h
909fca
@@ -232,7 +232,20 @@ OSCAP_API void xccdf_session_set_user_tailoring_cid(struct xccdf_session *sessio
909fca
  * @param callback used to notify user about download proceeds. This might be safely set
909fca
  * to NULL -- ignoring user notification.
909fca
  */
909fca
-OSCAP_API void xccdf_session_set_remote_resources(struct xccdf_session *session, bool allowed, download_progress_calllback_t callback);
909fca
+OSCAP_API OSCAP_DEPRECATED(void xccdf_session_set_remote_resources(struct xccdf_session *session, bool allowed, download_progress_calllback_t callback));
909fca
+
909fca
+/**
909fca
+ * Set properties of remote content.
909fca
+ * @memberof xccdf_session
909fca
+ * @param session XCCDF Session
909fca
+ * @param allowed Whether is download od remote resources allowed in this
909fca
+ * session (defaults to false)
909fca
+ * @param use_local_file Allows to use a locally downloaded copy of the remote
909fca
+ * resource if it exists (defaults to false)
909fca
+ * @param callback used to notify user about download proceeds. This might be
909fca
+ * safely set to NULL -- ignoring user notification.
909fca
+ */
909fca
+OSCAP_API void xccdf_session_configure_remote_resources(struct xccdf_session *session, bool allowed, bool use_local_file, download_progress_calllback_t callback);
909fca
 
909fca
 /**
909fca
  * Disable or allow loading of depending content (OVAL, SCE, CPE)
909fca
diff --git a/src/XCCDF/xccdf_session.c b/src/XCCDF/xccdf_session.c
909fca
index 9d8f42c445..85fcc90d23 100644
909fca
--- a/src/XCCDF/xccdf_session.c
909fca
+++ b/src/XCCDF/xccdf_session.c
909fca
@@ -87,6 +87,7 @@ struct xccdf_session {
909fca
 	} ds;
909fca
 	struct {
909fca
 		bool fetch_remote_resources;		///< Allows download of remote resources (not applicable when user sets custom oval files)
909fca
+		bool use_local_file; ///< Use a locally downloaded copy of a remote resource if it exists
909fca
 		download_progress_calllback_t progress;	///< Callback to report progress of download.
909fca
 		struct oval_content_resource **custom_resources;///< OVAL files required by user
909fca
 		struct oval_content_resource **resources;///< OVAL files referenced from XCCDF
909fca
@@ -626,7 +627,8 @@ static struct ds_sds_session *xccdf_session_get_ds_sds_session(struct xccdf_sess
909fca
 	return session->ds.session;
909fca
 }
909fca
 
909fca
-void xccdf_session_set_remote_resources(struct xccdf_session *session, bool allowed, download_progress_calllback_t callback)
909fca
+
909fca
+void xccdf_session_configure_remote_resources(struct xccdf_session *session, bool allowed, bool use_local_file, download_progress_calllback_t callback)
909fca
 {
909fca
 	if (callback == NULL) {
909fca
 		// With empty cb we don't have to check for NULL
909fca
@@ -635,15 +637,21 @@ void xccdf_session_set_remote_resources(struct xccdf_session *session, bool allo
909fca
 	}
909fca
 
909fca
 	session->oval.fetch_remote_resources = allowed;
909fca
+	session->oval.use_local_file = use_local_file;
909fca
 	session->oval.progress = callback;
909fca
 
909fca
 	if (xccdf_session_is_sds(session)) {
909fca
 		// We have to propagate this option to allow loading
909fca
 		// of external datastream components
909fca
-		ds_sds_session_set_remote_resources(xccdf_session_get_ds_sds_session(session), allowed, callback);
909fca
+		ds_sds_session_configure_remote_resources(xccdf_session_get_ds_sds_session(session), allowed, use_local_file, callback);
909fca
 	}
909fca
 }
909fca
 
909fca
+void xccdf_session_set_remote_resources(struct xccdf_session *session, bool allowed, download_progress_calllback_t callback)
909fca
+{
909fca
+	xccdf_session_configure_remote_resources(session, allowed, false, callback);
909fca
+}
909fca
+
909fca
 void xccdf_session_set_loading_flags(struct xccdf_session *session, xccdf_session_loading_flags_t flags)
909fca
 {
909fca
 	session->loading_flags = flags;
909fca
@@ -993,6 +1001,7 @@ static int _xccdf_session_get_oval_from_model(struct xccdf_session *session)
909fca
 	while (oscap_file_entry_iterator_has_more(files_it)) {
909fca
 		struct oscap_file_entry *file_entry;
909fca
 		struct stat sb;
909fca
+		bool source_owned = false;
909fca
 
909fca
 		file_entry = (struct oscap_file_entry *) oscap_file_entry_iterator_next(files_it);
909fca
 
909fca
@@ -1002,9 +1011,6 @@ static int _xccdf_session_get_oval_from_model(struct xccdf_session *session)
909fca
 
909fca
 		const char *file_path = oscap_file_entry_get_file(file_entry);
909fca
 		struct oscap_source *source = NULL;
909fca
-		if (xccdf_session_get_ds_sds_session(session) != NULL) {
909fca
-			source = ds_sds_session_get_component_by_href(xccdf_session_get_ds_sds_session(session), file_path);
909fca
-		}
909fca
 
909fca
 		tmp_path = malloc(PATH_MAX * sizeof(char));
909fca
 		if (file_path[0] == '/') { // it's a simple absolute path
909fca
@@ -1017,16 +1023,20 @@ static int _xccdf_session_get_oval_from_model(struct xccdf_session *session)
909fca
 			snprintf(tmp_path, PATH_MAX, "%s/%s", dir_path, file_path);
909fca
 		}
909fca
 
909fca
-		if (source != NULL || stat(tmp_path, &sb) == 0) {
909fca
-			resources[idx] = malloc(sizeof(struct oval_content_resource));
909fca
-			resources[idx]->href = oscap_strdup(oscap_file_entry_get_file(file_entry));
909fca
-			if (source == NULL) {
909fca
+		if (xccdf_session_get_ds_sds_session(session) != NULL) {
909fca
+			source = ds_sds_session_get_component_by_href(xccdf_session_get_ds_sds_session(session), file_path);
909fca
+			source_owned = false;
909fca
+		} else {
909fca
+			if (stat(tmp_path, &sb) == 0) {
909fca
 				source = oscap_source_new_from_file(tmp_path);
909fca
-				resources[idx]->source_owned = true;
909fca
-			}
909fca
-			else {
909fca
-				resources[idx]->source_owned = false;
909fca
+				source_owned = true;
909fca
 			}
909fca
+		}
909fca
+
909fca
+		if (source != NULL) {
909fca
+			resources[idx] = malloc(sizeof(struct oval_content_resource));
909fca
+			resources[idx]->href = oscap_strdup(oscap_file_entry_get_file(file_entry));
909fca
+			resources[idx]->source_owned = source_owned;
909fca
 			resources[idx]->source = source;
909fca
 			idx++;
909fca
 			void *new_resources = realloc(resources, (idx + 1) * sizeof(struct oval_content_resource *));
909fca
diff --git a/tests/DS/CMakeLists.txt b/tests/DS/CMakeLists.txt
909fca
index f239586f8b..aac089cab5 100644
909fca
--- a/tests/DS/CMakeLists.txt
909fca
+++ b/tests/DS/CMakeLists.txt
909fca
@@ -4,6 +4,7 @@ add_oscap_test("test_sds_compose_split.sh")
909fca
 add_oscap_test("test_sds_eval.sh")
909fca
 add_oscap_test("test_sds_fix_from_results.sh")
909fca
 add_oscap_test("test_sds_fix_from_source.sh")
909fca
+add_oscap_test("test_ds_use_local_remote_resources.sh")
909fca
 
909fca
 add_subdirectory("ds_sds_index")
909fca
 add_subdirectory("schematron")
909fca
diff --git a/tests/DS/ds_use_local_remote_resources/remote.oval.xml b/tests/DS/ds_use_local_remote_resources/remote.oval.xml
909fca
new file mode 100644
909fca
index 0000000000..ed864a462d
909fca
--- /dev/null
909fca
+++ b/tests/DS/ds_use_local_remote_resources/remote.oval.xml
909fca
@@ -0,0 +1,58 @@
909fca
+
909fca
+<oval_definitions xmlns:oval-def="http://oval.mitre.org/XMLSchema/oval-definitions-5" xmlns:oval="http://oval.mitre.org/XMLSchema/oval-common-5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ind-def="http://oval.mitre.org/XMLSchema/oval-definitions-5#independent" xmlns:unix-def="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix" xmlns:lin-def="http://oval.mitre.org/XMLSchema/oval-definitions-5#linux" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5" xsi:schemaLocation="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix unix-definitions-schema.xsd http://oval.mitre.org/XMLSchema/oval-definitions-5#independent independent-definitions-schema.xsd http://oval.mitre.org/XMLSchema/oval-definitions-5#linux linux-definitions-schema.xsd http://oval.mitre.org/XMLSchema/oval-definitions-5 oval-definitions-schema.xsd http://oval.mitre.org/XMLSchema/oval-common-5 oval-common-schema.xsd">
909fca
+  <generator>
909fca
+    <oval:schema_version>5.10</oval:schema_version>
909fca
+    <oval:timestamp>0001-01-01T00:00:00+00:00</oval:timestamp>
909fca
+  </generator>
909fca
+
909fca
+  <definitions>
909fca
+    <definition class="compliance" version="1" id="oval:x:def:1">
909fca
+      <metadata>
909fca
+        <title>This definition will pass</title>
909fca
+        <description>x</description>
909fca
+        <affected family="unix">
909fca
+          <platform>x</platform>
909fca
+        </affected>
909fca
+      </metadata>
909fca
+      <criteria comment="x" operator="OR">
909fca
+        <criterion test_ref="oval:x:tst:1" comment="always pass"/>
909fca
+        <criterion test_ref="oval:x:tst:2" comment="always fail"/>
909fca
+      </criteria>
909fca
+    </definition>
909fca
+    <definition class="compliance" version="1" id="oval:x:def:2">
909fca
+      <metadata>
909fca
+        <title>This definition will fail</title>
909fca
+        <description>x</description>
909fca
+        <affected family="unix">
909fca
+          <platform>x</platform>
909fca
+        </affected>
909fca
+      </metadata>
909fca
+      <criteria comment="x" operator="AND">
909fca
+        <criterion test_ref="oval:x:tst:1" comment="always pass"/>
909fca
+        <criterion test_ref="oval:x:tst:2" comment="always fail"/>
909fca
+      </criteria>
909fca
+    </definition>
909fca
+  </definitions>
909fca
+
909fca
+  <tests>
909fca
+    <variable_test id="oval:x:tst:1" check="all" comment="always pass" version="1" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#independent">
909fca
+      <object object_ref="oval:x:obj:1"/>
909fca
+    </variable_test>
909fca
+
909fca
+    <variable_test id="oval:x:tst:2" check="all" check_existence="none_exist" comment="always fail" version="1" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#independent">
909fca
+      <object object_ref="oval:x:obj:1"/>
909fca
+    </variable_test>
909fca
+  </tests>
909fca
+
909fca
+  <objects>
909fca
+    <variable_object id="oval:x:obj:1" version="1" comment="x" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#independent">
909fca
+      <var_ref>oval:x:var:1</var_ref>
909fca
+    </variable_object>
909fca
+  </objects>
909fca
+
909fca
+  <variables>
909fca
+    <constant_variable id="oval:x:var:1" version="1" comment="x" datatype="string">
909fca
+      <value>x</value>
909fca
+    </constant_variable>
909fca
+  </variables>
909fca
+</oval_definitions>
909fca
diff --git a/tests/DS/ds_use_local_remote_resources/remote_content_1.3.ds.xml b/tests/DS/ds_use_local_remote_resources/remote_content_1.3.ds.xml
909fca
new file mode 100644
909fca
index 0000000000..ab1a0f1458
909fca
--- /dev/null
909fca
+++ b/tests/DS/ds_use_local_remote_resources/remote_content_1.3.ds.xml
909fca
@@ -0,0 +1,96 @@
909fca
+
909fca
+<ds:data-stream-collection xmlns:ds="http://scap.nist.gov/schema/scap/source/1.2" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:cat="urn:oasis:names:tc:entity:xmlns:xml:catalog" id="scap_org.open-scap_collection_from_xccdf_test_single_rule.xccdf.xml" schematron-version="1.3">
909fca
+<ds:data-stream id="scap_org.open-scap_datastream_from_xccdf_test_single_rule.xccdf.xml" scap-version="1.3" use-case="OTHER">
909fca
+  <ds:checklists>
909fca
+    <ds:component-ref id="scap_org.open-scap_cref_test_single_rule.xccdf.xml" xlink:href="#scap_org.open-scap_comp_test_single_rule.xccdf.xml">
909fca
+      <cat:catalog>
909fca
+        <cat:uri name="test_single_rule.oval.xml" uri="#scap_org.open-scap_cref_test_single_rule.oval.xml"/>
909fca
+        <cat:uri name="remote.oval.xml" uri="#scap_org.open-scap_cref_remote.oval.xml"/>
909fca
+      </cat:catalog>
909fca
+    </ds:component-ref>
909fca
+  </ds:checklists>
909fca
+  <ds:checks>
909fca
+    <ds:component-ref id="scap_org.open-scap_cref_test_single_rule.oval.xml" xlink:href="#scap_org.open-scap_comp_test_single_rule.oval.xml"/>
909fca
+    <ds:component-ref id="scap_org.open-scap_cref_remote.oval.xml" xlink:href="https://www.example.com/security/data/oval/remote.oval.xml"/>
909fca
+  </ds:checks>
909fca
+</ds:data-stream>
909fca
+
909fca
+<ds:component id="scap_org.open-scap_comp_test_single_rule.oval.xml" timestamp="2017-06-09T07:07:38">
909fca
+<oval_definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5" xmlns:ind-def="http://oval.mitre.org/XMLSchema/oval-definitions-5#independent" xmlns:oval-def="http://oval.mitre.org/XMLSchema/oval-definitions-5" xmlns:oval="http://oval.mitre.org/XMLSchema/oval-common-5" xmlns:win-def="http://oval.mitre.org/XMLSchema/oval-definitions-5#windows" xsi:schemaLocation="http://oval.mitre.org/XMLSchema/oval-definitions-5 oval-definitions-schema.xsd    http://oval.mitre.org/XMLSchema/oval-definitions-5#independent independent-definitions-schema.xsd   http://oval.mitre.org/XMLSchema/oval-definitions-5#windows windows-definitions-schema.xsd">
909fca
+  <generator>
909fca
+    <oval:schema_version>5.11</oval:schema_version>
909fca
+    <oval:timestamp>2009-01-12T10:41:00-05:00</oval:timestamp>
909fca
+  </generator>
909fca
+
909fca
+  <definitions>
909fca
+    <definition class="compliance" id="oval:test-pass:def:1" version="1">
909fca
+      <metadata>
909fca
+        <title>PASS</title>
909fca
+	<description>pass</description>
909fca
+      </metadata>
909fca
+      <criteria>
909fca
+        <criterion comment="PASS test" test_ref="oval:x:tst:1"/>
909fca
+      </criteria>
909fca
+    </definition>
909fca
+  </definitions>
909fca
+
909fca
+    <tests>
909fca
+    <variable_test xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#independent" id="oval:x:tst:1" check="all" comment="always pass" version="1">
909fca
+      <object object_ref="oval:x:obj:1"/>
909fca
+    </variable_test>
909fca
+    </tests>
909fca
+
909fca
+    <objects>
909fca
+    <variable_object xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5#independent" id="oval:x:obj:1" version="1" comment="x">
909fca
+      <var_ref>oval:x:var:1</var_ref>
909fca
+    </variable_object>
909fca
+    </objects>
909fca
+
909fca
+    <variables>
909fca
+      <constant_variable id="oval:x:var:1" version="1" comment="x" datatype="int">
909fca
+        <value>100</value>
909fca
+      </constant_variable>
909fca
+    </variables>
909fca
+
909fca
+</oval_definitions>
909fca
+</ds:component>
909fca
+
909fca
+<ds:component id="scap_org.open-scap_comp_test_single_rule.xccdf.xml" timestamp="2017-06-09T09:15:45">
909fca
+<Benchmark xmlns="http://checklists.nist.gov/xccdf/1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="xccdf_com.example.www_benchmark_dummy" xml:lang="en-US">
909fca
+  <status>accepted</status>
909fca
+  <version>1.0</version>
909fca
+
909fca
+  <Profile id="xccdf_com.example.www_profile_test_remote_res">
909fca
+    <title>xccdf_test_profile</title>
909fca
+    <description>This profile is for testing.</description>
909fca
+    <select idref="xccdf_com.example.www_rule_test-pass" selected="true"/>
909fca
+    <select idref="xccdf_com.example.www_rule_test-remote_res" selected="true"/>
909fca
+  </Profile>
909fca
+
909fca
+  <Value id="xccdf_com.example.www_value_val1" type="number" operator="equals" interactive="0">
909fca
+    <title>test value</title>
909fca
+    <description>foo</description>
909fca
+    <value selector="bar_1">50</value>
909fca
+    <value selector="bar_2">100</value>
909fca
+  </Value>
909fca
+  <Rule selected="true" id="xccdf_com.example.www_rule_test-pass">
909fca
+    <title>This rule always pass</title>
909fca
+    <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
909fca
+      <check-content-ref href="test_single_rule.oval.xml" name="oval:test-pass:def:1"/>
909fca
+    </check>
909fca
+  </Rule>
909fca
+  <Rule selected="true" id="xccdf_com.example.www_rule_test-remote_res">
909fca
+    <title>This rule checks remote resource</title>
909fca
+    <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5" multi-check="true">
909fca
+      <check-content-ref href="remote.oval.xml"/>
909fca
+    </check>
909fca
+  </Rule>
909fca
+  <Rule selected="true" id="xccdf_com.example.www_rule_test-pass2">
909fca
+    <title>This rule always pass</title>
909fca
+    <check system="http://oval.mitre.org/XMLSchema/oval-definitions-5">
909fca
+      <check-content-ref href="test_single_rule.oval.xml" name="oval:test-pass:def:1"/>
909fca
+    </check>
909fca
+  </Rule>
909fca
+</Benchmark>
909fca
+</ds:component>
909fca
+</ds:data-stream-collection>
909fca
diff --git a/tests/DS/test_ds_use_local_remote_resources.sh b/tests/DS/test_ds_use_local_remote_resources.sh
909fca
new file mode 100755
909fca
index 0000000000..706f38c2bc
909fca
--- /dev/null
909fca
+++ b/tests/DS/test_ds_use_local_remote_resources.sh
909fca
@@ -0,0 +1,57 @@
909fca
+#!/usr/bin/env bash
909fca
+
909fca
+# Author:
909fca
+#   Jan Černý <jcerny@redhat.com>
909fca
+
909fca
+set -e -o pipefail
909fca
+set -x
909fca
+
909fca
+. $builddir/tests/test_common.sh
909fca
+	
909fca
+PROFILE="xccdf_com.example.www_profile_test_remote_res"
909fca
+result=$(mktemp)
909fca
+stderr=$(mktemp)
909fca
+tmpdir=$(mktemp -d)
909fca
+cp "${srcdir}/ds_use_local_remote_resources/remote_content_1.3.ds.xml" "$tmpdir"
909fca
+cp "${srcdir}/ds_use_local_remote_resources/remote.oval.xml" "$tmpdir"
909fca
+pushd "$tmpdir"
909fca
+
909fca
+$OSCAP xccdf eval --use-local-file --profile "$PROFILE" --results "$result" "remote_content_1.3.ds.xml" 2>"$stderr" || ret=$?
909fca
+[ "$ret" = 2 ]
909fca
+
909fca
+grep -q "WARNING: Datastream component 'scap_org.open-scap_cref_remote.oval.xml' points out to the remote 'https://www.example.com/security/data/oval/remote.oval.xml'. Use '--fetch-remote-resources' option to download it." "$stderr" && false
909fca
+grep -q "WARNING: Skipping 'https://www.example.com/security/data/oval/remote.oval.xml' file which is referenced from datastream" "$stderr" && false
909fca
+
909fca
+assert_exists 1 '//rule-result[@idref="xccdf_com.example.www_rule_test-pass"]/result[text()="pass"]'
909fca
+# the remote_res rule is a multicheck with 2 oval definitions so it's twice here
909fca
+assert_exists 1 '//rule-result[@idref="xccdf_com.example.www_rule_test-remote_res"]/result[text()="pass"]'
909fca
+assert_exists 1 '//rule-result[@idref="xccdf_com.example.www_rule_test-remote_res"]/result[text()="fail"]'
909fca
+assert_exists 1 '//rule-result[@idref="xccdf_com.example.www_rule_test-pass2"]/result[text()="pass"]'
909fca
+
909fca
+popd
909fca
+rm -f "$result" "$stderr"
909fca
+rm -rf "$tmpdir"
909fca
+
909fca
+
909fca
+# test the same without --use-local-file to make sure the $tmpdir/remote.oval.xml isn't loaded by oscap
909fca
+
909fca
+result=$(mktemp)
909fca
+stderr=$(mktemp)
909fca
+tmpdir=$(mktemp -d)
909fca
+cp "${srcdir}/ds_use_local_remote_resources/remote_content_1.3.ds.xml" "$tmpdir"
909fca
+cp "${srcdir}/ds_use_local_remote_resources/remote.oval.xml" "$tmpdir"
909fca
+pushd "$tmpdir"
909fca
+
909fca
+$OSCAP xccdf eval --profile "$PROFILE" --results "$result" "remote_content_1.3.ds.xml" 2>"$stderr" || ret=$?
909fca
+[ "$ret" = 2 ]
909fca
+
909fca
+grep -q "WARNING: Datastream component 'scap_org.open-scap_cref_remote.oval.xml' points out to the remote 'https://www.example.com/security/data/oval/remote.oval.xml'. Use '--fetch-remote-resources' option to download it." "$stderr"
909fca
+grep -q "WARNING: Skipping 'https://www.example.com/security/data/oval/remote.oval.xml' file which is referenced from datastream" "$stderr"
909fca
+
909fca
+assert_exists 1 '//rule-result[@idref="xccdf_com.example.www_rule_test-pass"]/result[text()="pass"]'
909fca
+assert_exists 1 '//rule-result[@idref="xccdf_com.example.www_rule_test-remote_res"]/result[text()="notchecked"]'
909fca
+assert_exists 1 '//rule-result[@idref="xccdf_com.example.www_rule_test-pass2"]/result[text()="pass"]'
909fca
+
909fca
+popd
909fca
+rm -f "$result" "$stderr"
909fca
+rm -rf "$tmpdir"
909fca
\ No newline at end of file
909fca
diff --git a/utils/oscap-ds.c b/utils/oscap-ds.c
909fca
index 772c9c3283..6a42724597 100644
909fca
--- a/utils/oscap-ds.c
909fca
+++ b/utils/oscap-ds.c
909fca
@@ -82,7 +82,8 @@ static struct oscap_module DS_SDS_SPLIT_MODULE = {
909fca
 		"   --xccdf-id <id>               - ID of XCCDF in the data stream that should be evaluated.\n"
909fca
 		"   --skip-valid                  - Skips validating of given XCCDF.\n"
909fca
 		"   --skip-validation\n"
909fca
-		"   --fetch-remote-resources      - Download remote content referenced by data stream.\n",
909fca
+		"   --fetch-remote-resources      - Download remote content referenced by data stream.\n"
909fca
+		"   --use-local-file              - Use a locally downloaded copy of the remote resource if it exists.\n",
909fca
 	.opt_parser = getopt_ds,
909fca
 	.func = app_ds_sds_split
909fca
 };
909fca
@@ -186,6 +187,7 @@ bool getopt_ds(int argc, char **argv, struct oscap_action *action) {
909fca
 		{"xccdf-id",		required_argument, NULL, DS_OPT_XCCDF_ID},
909fca
 		{"report-id",		required_argument, NULL, DS_OPT_REPORT_ID},
909fca
 		{"fetch-remote-resources", no_argument, &action->remote_resources, 1},
909fca
+		{"use-local-file", no_argument, &action->use_local_file, 1},
909fca
 	// end
909fca
 		{0, 0, 0, 0}
909fca
 	};
909fca
@@ -308,7 +310,7 @@ int app_ds_sds_split(const struct oscap_action *action) {
909fca
 	}
909fca
 	ds_sds_session_set_datastream_id(session, f_datastream_id);
909fca
 
909fca
-	ds_sds_session_set_remote_resources(session, action->remote_resources, download_reporting_callback);
909fca
+	ds_sds_session_configure_remote_resources(session, action->remote_resources, action->use_local_file, download_reporting_callback);
909fca
 	ds_sds_session_set_target_dir(session, action->ds_action->target);
909fca
 	if (ds_sds_session_register_component_with_dependencies(session, "checklists", f_component_id, NULL) != 0) {
909fca
 		goto cleanup;
909fca
diff --git a/utils/oscap-info.c b/utils/oscap-info.c
909fca
index 46721eba05..01db5153b3 100644
909fca
--- a/utils/oscap-info.c
909fca
+++ b/utils/oscap-info.c
909fca
@@ -63,6 +63,7 @@ struct oscap_module OSCAP_INFO_MODULE = {
909fca
     .usage = "some-file.xml",
909fca
 	.help = "Options:\n"
909fca
 		"   --fetch-remote-resources      - Download remote content referenced by data stream.\n"
909fca
+		"   --use-local-file              - Use a locally downloaded copy of the remote resource if it exists.\n"
909fca
 		"   --profile <id>                - Show info of the profile with the given ID.\n"
909fca
 		"   --profiles                    - Show profiles from the input file in the <id>:<title> format, one line per profile.\n",
909fca
     .opt_parser = getopt_info,
909fca
@@ -531,7 +532,7 @@ static int app_info_sds(struct oscap_source *source, const struct oscap_action *
909fca
 		return OSCAP_ERROR;
909fca
 	}
909fca
 
909fca
-	ds_sds_session_set_remote_resources(session, action->remote_resources, download_reporting_callback);
909fca
+	ds_sds_session_configure_remote_resources(session, action->remote_resources, action->use_local_file, download_reporting_callback);
909fca
 
909fca
 	/* get collection */
909fca
 	struct ds_sds_index *sds = ds_sds_session_get_sds_idx(session);
909fca
@@ -762,6 +763,7 @@ bool getopt_info(int argc, char **argv, struct oscap_action *action)
909fca
 	/* Command-options */
909fca
 	const struct option long_options[] = {
909fca
 		{"fetch-remote-resources", no_argument, &action->remote_resources, 1},
909fca
+		{"use-local-file", no_argument, &action->use_local_file, 1},
909fca
 		{"profile", required_argument, 0, 'p'},
909fca
 		{"profiles", no_argument, 0, 'n'},
909fca
 		// end
909fca
diff --git a/utils/oscap-oval.c b/utils/oscap-oval.c
909fca
index 39bcb92edb..582a5695e3 100644
909fca
--- a/utils/oscap-oval.c
909fca
+++ b/utils/oscap-oval.c
909fca
@@ -115,7 +115,8 @@ static struct oscap_module OVAL_EVAL = {
909fca
 	"   --oval-id <id>                - ID of the OVAL component ref in the data stream to use.\n"
909fca
 	"                                   (only applicable for source data streams)\n"
909fca
 	"   --fetch-remote-resources      - Download remote content referenced by OVAL Definitions.\n"
909fca
-	"                                   (only applicable for source data streams)\n",
909fca
+	"                                   (only applicable for source data streams)\n"
909fca
+	"   --use-local-file              - Use a locally downloaded copy of the remote resource if it exists.\n",
909fca
     .opt_parser = getopt_oval_eval,
909fca
     .func = app_evaluate_oval
909fca
 };
909fca
@@ -344,7 +345,7 @@ int app_evaluate_oval(const struct oscap_action *action)
909fca
 	/* set OVAL Variables */
909fca
 	oval_session_set_variables(session, action->f_variables);
909fca
 
909fca
-	oval_session_set_remote_resources(session, action->remote_resources, download_reporting_callback);
909fca
+	oval_session_configure_remote_resources(session, action->remote_resources, action->use_local_file, download_reporting_callback);
909fca
 	/* load all necesary OVAL Definitions and bind OVAL Variables if provided */
909fca
 	if ((oval_session_load(session)) != 0)
909fca
 		goto cleanup;
909fca
@@ -520,6 +521,7 @@ bool getopt_oval_eval(int argc, char **argv, struct oscap_action *action)
909fca
 		{ "skip-valid",	no_argument, &action->validate, 0 },
909fca
 		{ "skip-validation",	no_argument, &action->validate, 0 },
909fca
 		{ "fetch-remote-resources", no_argument, &action->remote_resources, 1},
909fca
+		{ "use-local-file", no_argument, &action->use_local_file, 1},
909fca
 		{ 0, 0, 0, 0 }
909fca
 	};
909fca
 
909fca
diff --git a/utils/oscap-tool.h b/utils/oscap-tool.h
909fca
index 18cce0fbce..a3b8781b27 100644
909fca
--- a/utils/oscap-tool.h
909fca
+++ b/utils/oscap-tool.h
909fca
@@ -174,6 +174,7 @@ struct oscap_action {
909fca
         int list_dynamic;
909fca
 	char *verbosity_level;
909fca
 	char *fix_type;
909fca
+	int use_local_file;
909fca
 };
909fca
 
909fca
 int app_xslt(const char *infile, const char *xsltfile, const char *outfile, const char **params);
909fca
diff --git a/utils/oscap-xccdf.c b/utils/oscap-xccdf.c
909fca
index 801e54fa35..ef2768bdef 100644
909fca
--- a/utils/oscap-xccdf.c
909fca
+++ b/utils/oscap-xccdf.c
909fca
@@ -129,6 +129,7 @@ static struct oscap_module XCCDF_EXPORT_OVAL_VARIABLES = {
909fca
 		"   --skip-valid                  - Skip validation.\n"
909fca
 		"   --skip-validation\n"
909fca
 		"   --fetch-remote-resources      - Download remote content referenced by XCCDF.\n"
909fca
+		"   --use-local-file              - Use a locally downloaded copy of the remote resource if it exists.\n"
909fca
 		"   --datastream-id <id>          - ID of the data stream in the collection to use.\n"
909fca
 		"                                   (only applicable for source data streams)\n"
909fca
 		"   --xccdf-id <id>               - ID of component-ref with XCCDF in the data stream that should be evaluated.\n"
909fca
@@ -171,6 +172,7 @@ static struct oscap_module XCCDF_EVAL = {
909fca
 		"                                   (only applicable for source data streams)\n"
909fca
 		"   --enforce-signature           - Process only signed data streams.\n"
909fca
 		"   --fetch-remote-resources      - Download remote content referenced by XCCDF.\n"
909fca
+		"   --use-local-file              - Use a locally downloaded copy of the remote resource if it exists.\n"
909fca
 		"   --progress                    - Switch to sparse output suitable for progress reporting.\n"
909fca
 		"                                   Format is \"$rule_id:$result\\n\".\n"
909fca
 		"   --datastream-id <id>          - ID of the data stream in the collection to use.\n"
909fca
@@ -199,6 +201,7 @@ static struct oscap_module XCCDF_REMEDIATE = {
909fca
 		"   --cpe <name>                  - Use given CPE dictionary or language (autodetected)\n"
909fca
 		"                                   for applicability checks.\n"
909fca
 		"   --fetch-remote-resources      - Download remote content referenced by XCCDF.\n"
909fca
+		"   --use-local-file              - Use a locally downloaded copy of the remote resource if it exists.\n"
909fca
 		"   --results <file>              - Write XCCDF Results into file.\n"
909fca
 		"   --results-arf <file>          - Write ARF (result data stream) into file.\n"
909fca
 		"   --stig-viewer <file>          - Writes XCCDF results into FILE in a format readable by DISA STIG Viewer\n"
909fca
@@ -573,7 +576,7 @@ int app_evaluate_xccdf(const struct oscap_action *action)
909fca
 	if (action->tailoring_file != NULL)
909fca
 		xccdf_session_set_user_tailoring_file(session, action->tailoring_file);
909fca
 	xccdf_session_set_user_tailoring_cid(session, action->tailoring_id);
909fca
-	xccdf_session_set_remote_resources(session, action->remote_resources, download_reporting_callback);
909fca
+	xccdf_session_configure_remote_resources(session, action->remote_resources, action->use_local_file, download_reporting_callback);
909fca
 	xccdf_session_set_custom_oval_files(session, action->f_ovals);
909fca
 	xccdf_session_set_product_cpe(session, OSCAP_PRODUCTNAME);
909fca
 	xccdf_session_set_rule(session, action->rule);
909fca
@@ -678,7 +681,7 @@ static int app_xccdf_export_oval_variables(const struct oscap_action *action)
909fca
 		xccdf_session_set_benchmark_id(session, action->f_benchmark_id);
909fca
 	}
909fca
 	xccdf_session_set_user_cpe(session, action->cpe);
909fca
-	xccdf_session_set_remote_resources(session, action->remote_resources, download_reporting_callback);
909fca
+	xccdf_session_configure_remote_resources(session, action->remote_resources, action->use_local_file, download_reporting_callback);
909fca
 	xccdf_session_set_custom_oval_files(session, action->f_ovals);
909fca
 	xccdf_session_set_custom_oval_eval_fn(session, resolve_variables_wrapper);
909fca
 
909fca
@@ -721,7 +724,7 @@ int app_xccdf_remediate(const struct oscap_action *action)
909fca
 		goto cleanup;
909fca
 	xccdf_session_set_validation(session, action->validate, getenv("OSCAP_FULL_VALIDATION") != NULL);
909fca
 	xccdf_session_set_user_cpe(session, action->cpe);
909fca
-	xccdf_session_set_remote_resources(session, action->remote_resources, download_reporting_callback);
909fca
+	xccdf_session_configure_remote_resources(session, action->remote_resources, action->use_local_file, download_reporting_callback);
909fca
 	xccdf_session_set_custom_oval_files(session, action->f_ovals);
909fca
 
909fca
 	if (xccdf_session_load(session) != 0)
909fca
@@ -937,7 +940,7 @@ int app_generate_fix(const struct oscap_action *action)
909fca
 	xccdf_session_set_signature_validation(session, action->validate_signature);
909fca
 	xccdf_session_set_signature_enforcement(session, action->enforce_signature);
909fca
 	xccdf_session_set_user_cpe(session, action->cpe);
909fca
-	xccdf_session_set_remote_resources(session, action->remote_resources, download_reporting_callback);
909fca
+	xccdf_session_configure_remote_resources(session, action->remote_resources, action->use_local_file, download_reporting_callback);
909fca
 	xccdf_session_set_custom_oval_files(session, action->f_ovals);
909fca
 	xccdf_session_set_user_tailoring_file(session, action->tailoring_file);
909fca
 	xccdf_session_set_user_tailoring_cid(session, action->tailoring_id);
909fca
@@ -1012,7 +1015,7 @@ int app_generate_guide(const struct oscap_action *action)
909fca
 	xccdf_session_set_validation(session, action->validate, getenv("OSCAP_FULL_VALIDATION") != NULL);
909fca
 	xccdf_session_set_signature_validation(session, action->validate_signature);
909fca
 	xccdf_session_set_signature_enforcement(session, action->enforce_signature);
909fca
-	xccdf_session_set_remote_resources(session, action->remote_resources, download_reporting_callback);
909fca
+	xccdf_session_configure_remote_resources(session, action->remote_resources, action->use_local_file, download_reporting_callback);
909fca
 	xccdf_session_set_user_tailoring_file(session, action->tailoring_file);
909fca
 	xccdf_session_set_user_tailoring_cid(session, action->tailoring_id);
909fca
 	if (xccdf_session_is_sds(session)) {
909fca
@@ -1166,6 +1169,7 @@ bool getopt_xccdf(int argc, char **argv, struct oscap_action *action)
909fca
 		{"skip-signature-validation", no_argument, &action->validate_signature, 0},
909fca
 		{"enforce-signature", no_argument, &action->enforce_signature, 1},
909fca
 		{"fetch-remote-resources", no_argument, &action->remote_resources, 1},
909fca
+		{"use-local-file", no_argument, &action->use_local_file, 1},
909fca
 		{"progress", no_argument, &action->progress, 1},
909fca
 		{"remediate", no_argument, &action->remediate, 1},
909fca
 		{"hide-profile-info",	no_argument, &action->hide_profile_info, 1},
909fca
diff --git a/utils/oscap.8 b/utils/oscap.8
909fca
index 6cae0ffe8a..8dcb9ca330 100644
909fca
--- a/utils/oscap.8
909fca
+++ b/utils/oscap.8
909fca
@@ -72,6 +72,11 @@ For XCCDF or SCAP source data stream files, the info module prints out IDs of in
909fca
 Allow download of remote components referenced from data stream.
909fca
 .RE
909fca
 .TP
909fca
+\fB\-\-use-local-file\fR
909fca
+.RS
909fca
+Instead of downloading remote data stream components from the network, use a data stream component stored locally in a file. In place of the remote data stream component OpenSCAP will attempt to use a file whose file name is equal to @name attribute of the uri element within the catalog element within the component-ref element in the data stream if such file exists.
909fca
+.RE
909fca
+.TP
909fca
 \fB\-\-profile PROFILE\fR
909fca
 .RS
909fca
 Show info of the profile with the given ID.
909fca
@@ -201,6 +206,11 @@ Process only digitally signed SCAP source data streams. Data streams without a s
909fca
 Allow download of remote OVAL content referenced from XCCDF by check-content-ref/@href.
909fca
 .RE
909fca
 .TP
909fca
+\fB\-\-use-local-file\fR
909fca
+.RS
909fca
+Instead of downloading remote data stream components from the network, use a data stream component stored locally in a file. In place of the remote data stream component OpenSCAP will attempt to use a file whose file name is equal to @name attribute of the uri element within the catalog element within the component-ref element in the data stream if such file exists.
909fca
+.RE
909fca
+.TP
909fca
 \fB\-\-remediate\fR
909fca
 .RS
909fca
 Execute XCCDF remediation in the process of XCCDF evaluation. This option automatically executes content of XCCDF fix elements for failed rules, and thus this shall be avoided unless for trusted content. Use of this option is always at your own risk.
909fca
@@ -226,6 +236,11 @@ Do not validate input/output files.
909fca
 Allow download of remote OVAL content referenced from XCCDF by check-content-ref/@href.
909fca
 .RE
909fca
 .TP
909fca
+\fB\-\-use-local-file\fR
909fca
+.RS
909fca
+Instead of downloading remote data stream components from the network, use a data stream component stored locally in a file. In place of the remote data stream component OpenSCAP will attempt to use a file whose file name is equal to @name attribute of the uri element within the catalog element within the component-ref element in the data stream if such file exists.
909fca
+.RE
909fca
+.TP
909fca
 \fB\-\-cpe CPE_FILE\fR
909fca
 .RS
909fca
 Use given CPE dictionary or language (auto-detected) for applicability checks.
909fca
@@ -303,6 +318,11 @@ Select a particular profile from XCCDF document.
909fca
 Allow download of remote OVAL content referenced from XCCDF by check-content-ref/@href.
909fca
 .RE
909fca
 .TP
909fca
+\fB\-\-use-local-file\fR
909fca
+.RS
909fca
+Instead of downloading remote data stream components from the network, use a data stream component stored locally in a file. In place of the remote data stream component OpenSCAP will attempt to use a file whose file name is equal to @name attribute of the uri element within the catalog element within the component-ref element in the data stream if such file exists.
909fca
+.RE
909fca
+.TP
909fca
 \fB\-\-skip-valid\fR, \fB\-\-skip-validation\fR
909fca
 .RS
909fca
 Do not validate input/output files.
909fca
@@ -477,6 +497,9 @@ Do not validate input/output files.
909fca
 .TP
909fca
 \fB\-\-fetch-remote-resources\fR
909fca
 Allow download of remote components referenced from data stream.
909fca
+.TP
909fca
+\fB\-\-use-local-file\fR
909fca
+Instead of downloading remote data stream components from the network, use a data stream component stored locally in a file. In place of the remote data stream component OpenSCAP will attempt to use a file whose file name is equal to @name attribute of the uri element within the catalog element within the component-ref element in the data stream if such file exists.
909fca
 .RE
909fca
 
909fca
 .TP
909fca
@@ -638,6 +661,9 @@ Do not validate input/output files.
909fca
 .TP
909fca
 \fB\-\-fetch-remote-resources\fR
909fca
 Allow download of remote components referenced from data stream.
909fca
+.TP
909fca
+\fB\-\-use-local-file\fR
909fca
+Instead of downloading remote data stream components from the network, use a data stream component stored locally in a file. In place of the remote data stream component OpenSCAP will attempt to use a file whose file name is equal to @name attribute of the uri element within the catalog element within the component-ref element in the data stream if such file exists.
909fca
 .RE
909fca
 .TP
909fca
 .B \fBsds-validate\fR SOURCE_DS
909fca
909fca
From 0a24a755b7102b716da7237717aa78290f8efe9e Mon Sep 17 00:00:00 2001
909fca
From: =?UTF-8?q?Jan=20=C4=8Cern=C3=BD?= <jcerny@redhat.com>
909fca
Date: Tue, 13 Jul 2021 08:41:08 +0200
909fca
Subject: [PATCH 02/10] Describe using local files in user manual
909fca
909fca
To increase visiblity it's also added to the FAQs.
909fca
---
909fca
 docs/manual/manual.adoc | 27 +++++++++++++++++++++++++++
909fca
 1 file changed, 27 insertions(+)
909fca
909fca
diff --git a/docs/manual/manual.adoc b/docs/manual/manual.adoc
909fca
index 409d502a3b..8655f518f0 100644
909fca
--- a/docs/manual/manual.adoc
909fca
+++ b/docs/manual/manual.adoc
909fca
@@ -1636,6 +1636,25 @@ Rule    xccdf_org.ssgproject.content_rule_partition_for_var_log
909fca
 ...
909fca
 ----
909fca
 
909fca
+On systems that don't have a direct internet access or if the user doesn't want OpenSCAP to connect to the network it's possible to download the remote content using other tools and then pass it to OpenSCAP as a file.
909fca
+To do that, use `--use-local-file` instead of `--fetch-remote-resources` as argument of the `oscap` command.
909fca
+
909fca
+In place of the remote data stream component OpenSCAP  will attempt to use a file whose file name is equal to `name` attribute of the `uri` element within the `catalog` element within the `component-ref` element representing a checklist in the data stream if such file exists.
909fca
+
909fca
+In the following example, the `ssg-rhel8-ds.xml` is an SCAP source datastream.
909fca
+It needs some checks from a remote component. The remote component's `component-ref` ID is `scap_org.open-scap_cref_security-data-oval-com.redhat.rhsa-RHEL8.xml`  and the `component-ref` is pointing to `https://www.redhat.com/security/data/oval/com.redhat.rhsa-RHEL8.xml`.
909fca
+The checks from the remote component are used in the only checklist in the data stream.
909fca
+The `component-ref` of the checklist component contains a `catalog` where one of the `uri` elements maps the remote component's `component-ref` ID in the `uri` attribute to the actual name `security-data-oval-com.redhat.rhsa-RHEL8.xml` which is the value of the `name` attribute.
909fca
+Therefore, we can download the remote data from `https://www.redhat.com/security/data/oval/com.redhat.rhsa-RHEL8.xml` and save it as `security-data-oval-com.redhat.rhsa-RHEL8.xml`.
909fca
+Then, we can optionally copy the file to the computer which we want to scan.
909fca
+Then, we execute `oscap` with `--use-local-file` in that directory.
909fca
+It will pick the file and use it instead of the remote data and it won't connect to the network.
909fca
+
909fca
+----
909fca
+$ wget -O security-data-oval-com.redhat.rhsa-RHEL8.xml https://www.redhat.com/security/data/oval/com.redhat.rhsa-RHEL8.xml
909fca
+...
909fca
+$ oscap xccdf eval --use-local-file --profile ospp ssg-rhel8-ds.xml
909fca
+----
909fca
 
909fca
 == Practical Examples
909fca
 This section demonstrates practical usage of certain security content provided
909fca
@@ -2133,3 +2152,11 @@ The downloaded guidance contains rule descriptions, but it doesn't contain OVAL
909fca
 
909fca
 Make sure that you provide the ID of the customized profile in `--profile` option instead of the ID of the original profile.
909fca
 If you created the tailoring file using SCAP Workbench, you were prompted to choose the ID of the customized profile. You can display the ID of the customized profile by running `oscap info <your_tailoring_file>`. By default, the ID of the customized profile ends with `_customized` suffix.
909fca
+
909fca
+*My SCAP source data stream contains rule `security_patches_up_to_date` which needs to download some data from the internet to work.*
909fca
+*But I'm in an air gapped environment so it can't download it.*
909fca
+*Can I download it separately and pass it to oscap?*
909fca
+
909fca
+Yes, it's possible, you can download the file on other computer that is connected to the internet and then copy the file to the system where you run `oscap`.
909fca
+Instead of the `--fetch-remote-resources` option you will use the `--use-local-file` option.
909fca
+For more information, please refer to section <<_using_external_or_remote_resources,Using external or remote resources>>.
909fca
909fca
From 86ce263d26405d08abdf027e9b71bea69386e51f Mon Sep 17 00:00:00 2001
909fca
From: =?UTF-8?q?Jan=20=C4=8Cern=C3=BD?= <jcerny@redhat.com>
909fca
Date: Thu, 22 Jul 2021 16:19:36 +0200
909fca
Subject: [PATCH 03/10] Provide a directory path
909fca
909fca
This will allow users to pass a directory path where downloaded files
909fca
are stored.
909fca
909fca
Currently, when it attempts to open a file, the path is resolved
909fca
relatively to the data stream file. For example, that means if the data
909fca
stream file is located in /usr/share/xml/scap you need to copy the file
909fca
there and you can have permission problems. Instead, we will pass the
909fca
directory and store the downloaded file to the directory.
909fca
909fca
The interface and command line options are updated to accept the
909fca
directory path. Moreover, we have realized that there can be multiple
909fca
remote components in a single source data stream. Therefore, we have
909fca
found a more suitable name for the option which would more fit that the
909fca
option accepts an argument and there can be multiple files.
909fca
---
909fca
 docs/manual/manual.adoc                       | 16 +++++-----
909fca
 src/DS/ds_sds_session.c                       | 10 +++---
909fca
 src/DS/ds_sds_session_priv.h                  |  2 +-
909fca
 src/DS/public/ds_sds_session.h                |  7 +++--
909fca
 src/DS/sds.c                                  | 31 ++++++++++++++++---
909fca
 src/OVAL/oval_session.c                       | 10 +++---
909fca
 src/OVAL/public/oval_session.h                |  7 +++--
909fca
 src/XCCDF/public/xccdf_session.h              |  7 +++--
909fca
 src/XCCDF/xccdf_session.c                     | 12 +++----
909fca
 .../DS/test_ds_use_local_remote_resources.sh  | 19 ++++++------
909fca
 utils/oscap-ds.c                              | 10 ++++--
909fca
 utils/oscap-info.c                            |  9 ++++--
909fca
 utils/oscap-oval.c                            | 12 ++++---
909fca
 utils/oscap-tool.h                            |  2 +-
909fca
 utils/oscap-xccdf.c                           | 24 ++++++++------
909fca
 utils/oscap.8                                 | 18 +++++------
909fca
 16 files changed, 118 insertions(+), 78 deletions(-)
909fca
909fca
diff --git a/docs/manual/manual.adoc b/docs/manual/manual.adoc
909fca
index 8655f518f0..9f0fc38b75 100644
909fca
--- a/docs/manual/manual.adoc
909fca
+++ b/docs/manual/manual.adoc
909fca
@@ -1636,8 +1636,8 @@ Rule    xccdf_org.ssgproject.content_rule_partition_for_var_log
909fca
 ...
909fca
 ----
909fca
 
909fca
-On systems that don't have a direct internet access or if the user doesn't want OpenSCAP to connect to the network it's possible to download the remote content using other tools and then pass it to OpenSCAP as a file.
909fca
-To do that, use `--use-local-file` instead of `--fetch-remote-resources` as argument of the `oscap` command.
909fca
+On systems that don't have a direct internet access or if the user doesn't want OpenSCAP to connect to the network it's possible to download the remote content using other tools, save it to a directory and then pass it to OpenSCAP as a file.
909fca
+To do that, use `--local-files` instead of `--fetch-remote-resources` as argument of the `oscap` command.
909fca
 
909fca
 In place of the remote data stream component OpenSCAP  will attempt to use a file whose file name is equal to `name` attribute of the `uri` element within the `catalog` element within the `component-ref` element representing a checklist in the data stream if such file exists.
909fca
 
909fca
@@ -1645,15 +1645,15 @@ In the following example, the `ssg-rhel8-ds.xml` is an SCAP source datastream.
909fca
 It needs some checks from a remote component. The remote component's `component-ref` ID is `scap_org.open-scap_cref_security-data-oval-com.redhat.rhsa-RHEL8.xml`  and the `component-ref` is pointing to `https://www.redhat.com/security/data/oval/com.redhat.rhsa-RHEL8.xml`.
909fca
 The checks from the remote component are used in the only checklist in the data stream.
909fca
 The `component-ref` of the checklist component contains a `catalog` where one of the `uri` elements maps the remote component's `component-ref` ID in the `uri` attribute to the actual name `security-data-oval-com.redhat.rhsa-RHEL8.xml` which is the value of the `name` attribute.
909fca
-Therefore, we can download the remote data from `https://www.redhat.com/security/data/oval/com.redhat.rhsa-RHEL8.xml` and save it as `security-data-oval-com.redhat.rhsa-RHEL8.xml`.
909fca
-Then, we can optionally copy the file to the computer which we want to scan.
909fca
-Then, we execute `oscap` with `--use-local-file` in that directory.
909fca
+Therefore, we can download the remote data from `https://www.redhat.com/security/data/oval/com.redhat.rhsa-RHEL8.xml` and save it as `security-data-oval-com.redhat.rhsa-RHEL8.xml` to some directory.
909fca
+Then, we execute `oscap` with `--local-files` and provide a path to the directory where it's located.
909fca
 It will pick the file and use it instead of the remote data and it won't connect to the network.
909fca
 
909fca
 ----
909fca
-$ wget -O security-data-oval-com.redhat.rhsa-RHEL8.xml https://www.redhat.com/security/data/oval/com.redhat.rhsa-RHEL8.xml
909fca
+$ mkdir ~/scap-files
909fca
+$ wget -O ~/scap-files/security-data-oval-com.redhat.rhsa-RHEL8.xml https://www.redhat.com/security/data/oval/com.redhat.rhsa-RHEL8.xml
909fca
 ...
909fca
-$ oscap xccdf eval --use-local-file --profile ospp ssg-rhel8-ds.xml
909fca
+$ oscap xccdf eval --local-files ~/scap-files --profile ospp ssg-rhel8-ds.xml
909fca
 ----
909fca
 
909fca
 == Practical Examples
909fca
@@ -2158,5 +2158,5 @@ If you created the tailoring file using SCAP Workbench, you were prompted to cho
909fca
 *Can I download it separately and pass it to oscap?*
909fca
 
909fca
 Yes, it's possible, you can download the file on other computer that is connected to the internet and then copy the file to the system where you run `oscap`.
909fca
-Instead of the `--fetch-remote-resources` option you will use the `--use-local-file` option.
909fca
+Instead of the `--fetch-remote-resources` option you will use the `--local-files` option.
909fca
 For more information, please refer to section <<_using_external_or_remote_resources,Using external or remote resources>>.
909fca
diff --git a/src/DS/ds_sds_session.c b/src/DS/ds_sds_session.c
909fca
index 9d9a9c8b52..99f4bc20fd 100644
909fca
--- a/src/DS/ds_sds_session.c
909fca
+++ b/src/DS/ds_sds_session.c
909fca
@@ -55,7 +55,7 @@ struct ds_sds_session {
909fca
 	struct oscap_htable *component_uris;    ///< maps component refs to component URIs
909fca
 	bool fetch_remote_resources;            ///< Allows loading of external components;
909fca
 	download_progress_calllback_t progress;	///< Callback to report progress of download.
909fca
-	bool use_local_file;                    ///< Use a locally downloaded copy of a remote resource if it exists
909fca
+	const char *local_files;            ///< Path to the directory where local copies of remote components are located
909fca
 };
909fca
 
909fca
 /**
909fca
@@ -338,10 +338,10 @@ int ds_sds_session_register_component_with_dependencies(struct ds_sds_session *s
909fca
 	return res;
909fca
 }
909fca
 
909fca
-void ds_sds_session_configure_remote_resources(struct ds_sds_session *session, bool allowed, bool use_local_file, download_progress_calllback_t callback)
909fca
+void ds_sds_session_configure_remote_resources(struct ds_sds_session *session, bool allowed, const char *local_files, download_progress_calllback_t callback)
909fca
 {
909fca
 	session->fetch_remote_resources = allowed;
909fca
-	session->use_local_file = use_local_file;
909fca
+	session->local_files = local_files;
909fca
 	session->progress = (callback != NULL) ? callback : download_progress_empty_calllback;
909fca
 }
909fca
 
909fca
@@ -350,9 +350,9 @@ void ds_sds_session_set_remote_resources(struct ds_sds_session *session, bool al
909fca
 	ds_sds_session_configure_remote_resources(session, allowed, false, callback);
909fca
 }
909fca
 
909fca
-bool ds_sds_session_can_use_local_file(struct ds_sds_session *session)
909fca
+const char *ds_sds_session_local_files(struct ds_sds_session *session)
909fca
 {
909fca
-	return session->use_local_file;
909fca
+	return session->local_files;
909fca
 }
909fca
 
909fca
 int ds_sds_session_dump_component_files(struct ds_sds_session *session)
909fca
diff --git a/src/DS/ds_sds_session_priv.h b/src/DS/ds_sds_session_priv.h
909fca
index 018cd053ec..5e6dfc7672 100644
909fca
--- a/src/DS/ds_sds_session_priv.h
909fca
+++ b/src/DS/ds_sds_session_priv.h
909fca
@@ -40,7 +40,7 @@ struct oscap_htable *ds_sds_session_get_component_sources(struct ds_sds_session
909fca
 struct oscap_htable *ds_sds_session_get_component_uris(struct ds_sds_session *session);
909fca
 const char *ds_sds_session_get_readable_origin(const struct ds_sds_session *session);
909fca
 bool ds_sds_session_fetch_remote_resources(struct ds_sds_session *session);
909fca
-bool ds_sds_session_can_use_local_file(struct ds_sds_session *session);
909fca
+const char *ds_sds_session_local_files(struct ds_sds_session *session);
909fca
 download_progress_calllback_t ds_sds_session_remote_resources_progress(struct ds_sds_session *session);
909fca
 
909fca
 void download_progress_empty_calllback(bool warning, const char * format, ...);
909fca
diff --git a/src/DS/public/ds_sds_session.h b/src/DS/public/ds_sds_session.h
909fca
index 695a0df215..83e7feadba 100644
909fca
--- a/src/DS/public/ds_sds_session.h
909fca
+++ b/src/DS/public/ds_sds_session.h
909fca
@@ -208,12 +208,13 @@ OSCAP_API OSCAP_DEPRECATED(void ds_sds_session_set_remote_resources(struct ds_sd
909fca
  * @param session The source data stream session
909fca
  * @param allowed Whether is download of remote resources allowed in this
909fca
  * session (defaults to false)
909fca
- * @param use_local_file Allows to use a locally downloaded copy of the remote
909fca
- * resource if it exists (defaults to false)
909fca
+ * @param local_files Allows to use a locally downloaded copy of the remote
909fca
+ * resources. Contains a path to a directory where the files are stored
909fca
+ * (defaults to NULL).
909fca
  * @param callback used to notify user about download proceeds. This might be
909fca
  * safely set to NULL -- ignoring user notification.
909fca
  */
909fca
-OSCAP_API void ds_sds_session_configure_remote_resources(struct ds_sds_session *session, bool allowed, bool use_local_file, download_progress_calllback_t callback);
909fca
+OSCAP_API void ds_sds_session_configure_remote_resources(struct ds_sds_session *session, bool allowed, const char *local_files, download_progress_calllback_t callback);
909fca
 
909fca
 /**
909fca
  * Returns HTML representation of selected checklist in form of OpenSCAP guide.
909fca
diff --git a/src/DS/sds.c b/src/DS/sds.c
909fca
index b1737aa57f..365ae96987 100644
909fca
--- a/src/DS/sds.c
909fca
+++ b/src/DS/sds.c
909fca
@@ -425,14 +425,35 @@ static int ds_sds_dump_component_by_href(struct ds_sds_session *session, char* x
909fca
 			 * the URL defined in @xlink:href. This way people can provide the
909fca
 			 * previously downloaded component which might be useful on systems
909fca
 			 * with limited internet access. This behavior is allowed only when
909fca
-			 * --use-local-file is used on the command line.
909fca
+			 * --local-files is used on the command line.
909fca
 			 * See: https://bugzilla.redhat.com/show_bug.cgi?id=1970527
909fca
 			 * See: https://access.redhat.com/solutions/5185891
909fca
 			 */
909fca
-			struct stat sb;
909fca
-			if (ds_sds_session_can_use_local_file(session) && stat(relative_filepath, &sb) == 0) {
909fca
-				dI("Using local file '%s' instead of '%s'", relative_filepath, xlink_href);
909fca
-				return ds_sds_dump_file_component(relative_filepath, *component_id, session, target_filename_dirname, relative_filepath);
909fca
+			const char *local_files = ds_sds_session_local_files(session);
909fca
+			if (local_files != NULL) {
909fca
+				char *local_filepath = oscap_path_join(local_files, relative_filepath);
909fca
+				struct stat sb;
909fca
+				if (stat(local_filepath, &sb) == 0) {
909fca
+				//if (ds_sds_session_can_use_local_file(session)) {
909fca
+					dI("Using local file '%s' instead of '%s'", local_filepath, xlink_href);
909fca
+					struct oscap_source *source_file = oscap_source_new_from_file(local_filepath);
909fca
+					xmlDoc *doc = oscap_source_get_xmlDoc(source_file);
909fca
+					if (doc == NULL) {
909fca
+						free(local_filepath);
909fca
+						return -1;
909fca
+					}
909fca
+					xmlNodePtr inner_root = ds_sds_get_component_root_by_id(doc, *component_id);
909fca
+
909fca
+					if (ds_sds_register_component(session, doc, inner_root, *component_id, target_filename_dirname, relative_filepath) != 0) {
909fca
+						free(local_filepath);
909fca
+						return -1;
909fca
+					}
909fca
+					free(local_filepath);
909fca
+					return 0;
909fca
+				} else {
909fca
+					dW("Can't use local file '%s' instead of '%s'", local_filepath, xlink_href);
909fca
+				}
909fca
+				free(local_filepath);
909fca
 			}
909fca
 
909fca
 			static bool fetch_remote_resources_suggested = false;
909fca
diff --git a/src/OVAL/oval_session.c b/src/OVAL/oval_session.c
909fca
index 5adda43f66..bb73543ed8 100644
909fca
--- a/src/OVAL/oval_session.c
909fca
+++ b/src/OVAL/oval_session.c
909fca
@@ -84,7 +84,7 @@ struct oval_session {
909fca
 	bool full_validation;
909fca
 	bool fetch_remote_resources;
909fca
 	download_progress_calllback_t progress;
909fca
-	bool use_local_file;
909fca
+	const char *local_files;
909fca
 };
909fca
 
909fca
 struct oval_session *oval_session_new(const char *filename)
909fca
@@ -224,7 +224,7 @@ static int oval_session_load_definitions(struct oval_session *session)
909fca
 		if ((session->sds_session = ds_sds_session_new_from_source(session->source)) == NULL) {
909fca
 			return 1;
909fca
 		}
909fca
-		ds_sds_session_configure_remote_resources(session->sds_session, session->fetch_remote_resources, session->use_local_file, session->progress);
909fca
+		ds_sds_session_configure_remote_resources(session->sds_session, session->fetch_remote_resources, session->local_files, session->progress);
909fca
 		ds_sds_session_set_datastream_id(session->sds_session, session->datastream_id);
909fca
 		if (ds_sds_session_register_component_with_dependencies(session->sds_session,
909fca
 					"checks", session->component_id, "oval.xml") != 0) {
909fca
@@ -452,16 +452,16 @@ void oval_session_set_export_system_characteristics(struct oval_session *session
909fca
 	session->export_sys_chars = export;
909fca
 }
909fca
 
909fca
-void oval_session_configure_remote_resources(struct oval_session *session, bool allowed, bool use_local_file, download_progress_calllback_t callback)
909fca
+void oval_session_configure_remote_resources(struct oval_session *session, bool allowed, const char *local_files, download_progress_calllback_t callback)
909fca
 {
909fca
 	session->fetch_remote_resources = allowed;
909fca
-	session->use_local_file = use_local_file;
909fca
+	session->local_files = local_files;
909fca
 	session->progress = callback;
909fca
 }
909fca
 
909fca
 void oval_session_set_remote_resources(struct oval_session *session, bool allowed, download_progress_calllback_t callback)
909fca
 {
909fca
-	oval_session_configure_remote_resources(session, allowed, false, callback);
909fca
+	oval_session_configure_remote_resources(session, allowed, NULL, callback);
909fca
 }
909fca
 
909fca
 void oval_session_free(struct oval_session *session)
909fca
diff --git a/src/OVAL/public/oval_session.h b/src/OVAL/public/oval_session.h
909fca
index d485676747..378c77c490 100644
909fca
--- a/src/OVAL/public/oval_session.h
909fca
+++ b/src/OVAL/public/oval_session.h
909fca
@@ -247,12 +247,13 @@ OSCAP_API OSCAP_DEPRECATED(void oval_session_set_remote_resources(struct oval_se
909fca
  * @param session an \ref oval_session
909fca
  * @param allowed Whether is download of remote resources allowed in this
909fca
  * session (defaults to false)
909fca
- * @param use_local_file Allows to use a locally downloaded copy of the remote
909fca
- * resource if it exists (defaults to false)
909fca
+ * @param local_files Allows to use a locally downloaded copy of the remote
909fca
+ * resources. Contains a path to a directory where the files are stored
909fca
+ * (defaults to NULL).
909fca
  * @param callback used to notify user about download proceeds. This might be
909fca
  * safely set to NULL -- ignoring user notification.
909fca
  */
909fca
-OSCAP_API void oval_session_configure_remote_resources(struct oval_session *session, bool allowed, bool use_local_file, download_progress_calllback_t callback);
909fca
+OSCAP_API void oval_session_configure_remote_resources(struct oval_session *session, bool allowed, const char *local_files, download_progress_calllback_t callback);
909fca
 
909fca
 /**
909fca
  * Destructor of an \ref oval_session.
909fca
diff --git a/src/XCCDF/public/xccdf_session.h b/src/XCCDF/public/xccdf_session.h
909fca
index 2eb7128019..466ef2b9d4 100644
909fca
--- a/src/XCCDF/public/xccdf_session.h
909fca
+++ b/src/XCCDF/public/xccdf_session.h
909fca
@@ -240,12 +240,13 @@ OSCAP_API OSCAP_DEPRECATED(void xccdf_session_set_remote_resources(struct xccdf_
909fca
  * @param session XCCDF Session
909fca
  * @param allowed Whether is download od remote resources allowed in this
909fca
  * session (defaults to false)
909fca
- * @param use_local_file Allows to use a locally downloaded copy of the remote
909fca
- * resource if it exists (defaults to false)
909fca
+ * @param local_files Allows to use a locally downloaded copy of the remote
909fca
+ * resources. Contains a path to a directory where the files are stored
909fca
+ * (defaults to NULL).
909fca
  * @param callback used to notify user about download proceeds. This might be
909fca
  * safely set to NULL -- ignoring user notification.
909fca
  */
909fca
-OSCAP_API void xccdf_session_configure_remote_resources(struct xccdf_session *session, bool allowed, bool use_local_file, download_progress_calllback_t callback);
909fca
+OSCAP_API void xccdf_session_configure_remote_resources(struct xccdf_session *session, bool allowed, const char *local_files, download_progress_calllback_t callback);
909fca
 
909fca
 /**
909fca
  * Disable or allow loading of depending content (OVAL, SCE, CPE)
909fca
diff --git a/src/XCCDF/xccdf_session.c b/src/XCCDF/xccdf_session.c
909fca
index 85fcc90d23..990e40702b 100644
909fca
--- a/src/XCCDF/xccdf_session.c
909fca
+++ b/src/XCCDF/xccdf_session.c
909fca
@@ -87,7 +87,7 @@ struct xccdf_session {
909fca
 	} ds;
909fca
 	struct {
909fca
 		bool fetch_remote_resources;		///< Allows download of remote resources (not applicable when user sets custom oval files)
909fca
-		bool use_local_file; ///< Use a locally downloaded copy of a remote resource if it exists
909fca
+		const char *local_files; ///< Path to the directory where local copies of remote components are located
909fca
 		download_progress_calllback_t progress;	///< Callback to report progress of download.
909fca
 		struct oval_content_resource **custom_resources;///< OVAL files required by user
909fca
 		struct oval_content_resource **resources;///< OVAL files referenced from XCCDF
909fca
@@ -103,7 +103,7 @@ struct xccdf_session {
909fca
 		char *arf_file;				///< Path to ARF file to export
909fca
 		char *xccdf_file;			///< Path to XCCDF file to export
909fca
 		char *xccdf_stig_viewer_file;		///< Path to STIG Viewer XCCDF file to export
909fca
-		char *report_file;			///< Path to HTML file to eport
909fca
+		char *report_file;			///< Path to HTML file to export
909fca
 		bool oval_results;			///< Shall be the OVAL results files exported?
909fca
 		bool oval_variables;			///< Shall be the OVAL variable files exported?
909fca
 		bool check_engine_plugins_results;	///< Shall the check engine plugins results be exported?
909fca
@@ -628,7 +628,7 @@ static struct ds_sds_session *xccdf_session_get_ds_sds_session(struct xccdf_sess
909fca
 }
909fca
 
909fca
 
909fca
-void xccdf_session_configure_remote_resources(struct xccdf_session *session, bool allowed, bool use_local_file, download_progress_calllback_t callback)
909fca
+void xccdf_session_configure_remote_resources(struct xccdf_session *session, bool allowed, const char *local_files, download_progress_calllback_t callback)
909fca
 {
909fca
 	if (callback == NULL) {
909fca
 		// With empty cb we don't have to check for NULL
909fca
@@ -637,19 +637,19 @@ void xccdf_session_configure_remote_resources(struct xccdf_session *session, boo
909fca
 	}
909fca
 
909fca
 	session->oval.fetch_remote_resources = allowed;
909fca
-	session->oval.use_local_file = use_local_file;
909fca
+	session->oval.local_files = local_files;
909fca
 	session->oval.progress = callback;
909fca
 
909fca
 	if (xccdf_session_is_sds(session)) {
909fca
 		// We have to propagate this option to allow loading
909fca
 		// of external datastream components
909fca
-		ds_sds_session_configure_remote_resources(xccdf_session_get_ds_sds_session(session), allowed, use_local_file, callback);
909fca
+		ds_sds_session_configure_remote_resources(xccdf_session_get_ds_sds_session(session), allowed, local_files, callback);
909fca
 	}
909fca
 }
909fca
 
909fca
 void xccdf_session_set_remote_resources(struct xccdf_session *session, bool allowed, download_progress_calllback_t callback)
909fca
 {
909fca
-	xccdf_session_configure_remote_resources(session, allowed, false, callback);
909fca
+	xccdf_session_configure_remote_resources(session, allowed, NULL, callback);
909fca
 }
909fca
 
909fca
 void xccdf_session_set_loading_flags(struct xccdf_session *session, xccdf_session_loading_flags_t flags)
909fca
diff --git a/tests/DS/test_ds_use_local_remote_resources.sh b/tests/DS/test_ds_use_local_remote_resources.sh
909fca
index 706f38c2bc..e4a1f0eedd 100755
909fca
--- a/tests/DS/test_ds_use_local_remote_resources.sh
909fca
+++ b/tests/DS/test_ds_use_local_remote_resources.sh
909fca
@@ -11,12 +11,14 @@ set -x
909fca
 PROFILE="xccdf_com.example.www_profile_test_remote_res"
909fca
 result=$(mktemp)
909fca
 stderr=$(mktemp)
909fca
-tmpdir=$(mktemp -d)
909fca
-cp "${srcdir}/ds_use_local_remote_resources/remote_content_1.3.ds.xml" "$tmpdir"
909fca
-cp "${srcdir}/ds_use_local_remote_resources/remote.oval.xml" "$tmpdir"
909fca
-pushd "$tmpdir"
909fca
-
909fca
-$OSCAP xccdf eval --use-local-file --profile "$PROFILE" --results "$result" "remote_content_1.3.ds.xml" 2>"$stderr" || ret=$?
909fca
+tmpdir1=$(mktemp -d)
909fca
+tmpdir2=$(mktemp -d)
909fca
+tmpdir3=$(mktemp -d)
909fca
+cp "${srcdir}/ds_use_local_remote_resources/remote_content_1.3.ds.xml" "$tmpdir2"
909fca
+cp "${srcdir}/ds_use_local_remote_resources/remote.oval.xml" "$tmpdir3"
909fca
+pushd "$tmpdir1"
909fca
+
909fca
+$OSCAP xccdf eval --local-files "$tmpdir3" --profile "$PROFILE" --results "$result" "$tmpdir2/remote_content_1.3.ds.xml" 2>"$stderr" || ret=$?
909fca
 [ "$ret" = 2 ]
909fca
 
909fca
 grep -q "WARNING: Datastream component 'scap_org.open-scap_cref_remote.oval.xml' points out to the remote 'https://www.example.com/security/data/oval/remote.oval.xml'. Use '--fetch-remote-resources' option to download it." "$stderr" && false
909fca
@@ -30,10 +32,9 @@ assert_exists 1 '//rule-result[@idref="xccdf_com.example.www_rule_test-pass2"]/r
909fca
 
909fca
 popd
909fca
 rm -f "$result" "$stderr"
909fca
-rm -rf "$tmpdir"
909fca
-
909fca
+rm -rf "$tmpdir1" "$tmpdir2" "$tmpdir3"
909fca
 
909fca
-# test the same without --use-local-file to make sure the $tmpdir/remote.oval.xml isn't loaded by oscap
909fca
+# test the same without --local-files to make sure the $tmpdir/remote.oval.xml isn't loaded by oscap
909fca
 
909fca
 result=$(mktemp)
909fca
 stderr=$(mktemp)
909fca
diff --git a/utils/oscap-ds.c b/utils/oscap-ds.c
909fca
index 6a42724597..8207f097ec 100644
909fca
--- a/utils/oscap-ds.c
909fca
+++ b/utils/oscap-ds.c
909fca
@@ -172,7 +172,8 @@ static struct oscap_module* DS_SUBMODULES[DS_SUBMODULES_NUM] = {
909fca
 enum ds_opt {
909fca
 	DS_OPT_DATASTREAM_ID = 1,
909fca
 	DS_OPT_XCCDF_ID,
909fca
-	DS_OPT_REPORT_ID
909fca
+	DS_OPT_REPORT_ID,
909fca
+	DS_OPT_LOCAL_FILES
909fca
 };
909fca
 
909fca
 bool getopt_ds(int argc, char **argv, struct oscap_action *action) {
909fca
@@ -187,7 +188,7 @@ bool getopt_ds(int argc, char **argv, struct oscap_action *action) {
909fca
 		{"xccdf-id",		required_argument, NULL, DS_OPT_XCCDF_ID},
909fca
 		{"report-id",		required_argument, NULL, DS_OPT_REPORT_ID},
909fca
 		{"fetch-remote-resources", no_argument, &action->remote_resources, 1},
909fca
-		{"use-local-file", no_argument, &action->use_local_file, 1},
909fca
+		{"local-files", required_argument, NULL, DS_OPT_LOCAL_FILES},
909fca
 	// end
909fca
 		{0, 0, 0, 0}
909fca
 	};
909fca
@@ -199,6 +200,9 @@ bool getopt_ds(int argc, char **argv, struct oscap_action *action) {
909fca
 		case DS_OPT_DATASTREAM_ID:	action->f_datastream_id = optarg;	break;
909fca
 		case DS_OPT_XCCDF_ID:	action->f_xccdf_id = optarg; break;
909fca
 		case DS_OPT_REPORT_ID:	action->f_report_id = optarg; break;
909fca
+		case DS_OPT_LOCAL_FILES:
909fca
+			action->local_files = optarg;
909fca
+			break;
909fca
 		case 0: break;
909fca
 		default: return oscap_module_usage(action->module, stderr, NULL);
909fca
 		}
909fca
@@ -310,7 +314,7 @@ int app_ds_sds_split(const struct oscap_action *action) {
909fca
 	}
909fca
 	ds_sds_session_set_datastream_id(session, f_datastream_id);
909fca
 
909fca
-	ds_sds_session_configure_remote_resources(session, action->remote_resources, action->use_local_file, download_reporting_callback);
909fca
+	ds_sds_session_configure_remote_resources(session, action->remote_resources, action->local_files, download_reporting_callback);
909fca
 	ds_sds_session_set_target_dir(session, action->ds_action->target);
909fca
 	if (ds_sds_session_register_component_with_dependencies(session, "checklists", f_component_id, NULL) != 0) {
909fca
 		goto cleanup;
909fca
diff --git a/utils/oscap-info.c b/utils/oscap-info.c
909fca
index 01db5153b3..2e6f5003aa 100644
909fca
--- a/utils/oscap-info.c
909fca
+++ b/utils/oscap-info.c
909fca
@@ -63,7 +63,7 @@ struct oscap_module OSCAP_INFO_MODULE = {
909fca
     .usage = "some-file.xml",
909fca
 	.help = "Options:\n"
909fca
 		"   --fetch-remote-resources      - Download remote content referenced by data stream.\n"
909fca
-		"   --use-local-file              - Use a locally downloaded copy of the remote resource if it exists.\n"
909fca
+		"   --local-files <dir>       - Use locally downloaded copies of remote resources stored in the given directory.\n"
909fca
 		"   --profile <id>                - Show info of the profile with the given ID.\n"
909fca
 		"   --profiles                    - Show profiles from the input file in the <id>:<title> format, one line per profile.\n",
909fca
     .opt_parser = getopt_info,
909fca
@@ -532,7 +532,7 @@ static int app_info_sds(struct oscap_source *source, const struct oscap_action *
909fca
 		return OSCAP_ERROR;
909fca
 	}
909fca
 
909fca
-	ds_sds_session_configure_remote_resources(session, action->remote_resources, action->use_local_file, download_reporting_callback);
909fca
+	ds_sds_session_configure_remote_resources(session, action->remote_resources, action->local_files, download_reporting_callback);
909fca
 
909fca
 	/* get collection */
909fca
 	struct ds_sds_index *sds = ds_sds_session_get_sds_idx(session);
909fca
@@ -763,7 +763,7 @@ bool getopt_info(int argc, char **argv, struct oscap_action *action)
909fca
 	/* Command-options */
909fca
 	const struct option long_options[] = {
909fca
 		{"fetch-remote-resources", no_argument, &action->remote_resources, 1},
909fca
-		{"use-local-file", no_argument, &action->use_local_file, 1},
909fca
+		{"local-files", required_argument, NULL, 'l'},
909fca
 		{"profile", required_argument, 0, 'p'},
909fca
 		{"profiles", no_argument, 0, 'n'},
909fca
 		// end
909fca
@@ -781,6 +781,9 @@ bool getopt_info(int argc, char **argv, struct oscap_action *action)
909fca
 				action->show_profiles_only = 1;
909fca
 				action->provide_machine_readable_output = 1;
909fca
 				break;
909fca
+			case 'l':
909fca
+				action->local_files = optarg;
909fca
+				break;
909fca
 			default: return oscap_module_usage(action->module, stderr, NULL);
909fca
 		}
909fca
 	}
909fca
diff --git a/utils/oscap-oval.c b/utils/oscap-oval.c
909fca
index 582a5695e3..3a206bb3c4 100644
909fca
--- a/utils/oscap-oval.c
909fca
+++ b/utils/oscap-oval.c
909fca
@@ -116,7 +116,7 @@ static struct oscap_module OVAL_EVAL = {
909fca
 	"                                   (only applicable for source data streams)\n"
909fca
 	"   --fetch-remote-resources      - Download remote content referenced by OVAL Definitions.\n"
909fca
 	"                                   (only applicable for source data streams)\n"
909fca
-	"   --use-local-file              - Use a locally downloaded copy of the remote resource if it exists.\n",
909fca
+	"   --local-files <dir>       - Use locally downloaded copies of remote resources stored in the given directory.\n",
909fca
     .opt_parser = getopt_oval_eval,
909fca
     .func = app_evaluate_oval
909fca
 };
909fca
@@ -345,7 +345,7 @@ int app_evaluate_oval(const struct oscap_action *action)
909fca
 	/* set OVAL Variables */
909fca
 	oval_session_set_variables(session, action->f_variables);
909fca
 
909fca
-	oval_session_configure_remote_resources(session, action->remote_resources, action->use_local_file, download_reporting_callback);
909fca
+	oval_session_configure_remote_resources(session, action->remote_resources, action->local_files, download_reporting_callback);
909fca
 	/* load all necesary OVAL Definitions and bind OVAL Variables if provided */
909fca
 	if ((oval_session_load(session)) != 0)
909fca
 		goto cleanup;
909fca
@@ -500,7 +500,8 @@ enum oval_opt {
909fca
     OVAL_OPT_DIRECTIVES,
909fca
     OVAL_OPT_DATASTREAM_ID,
909fca
     OVAL_OPT_OVAL_ID,
909fca
-	OVAL_OPT_OUTPUT = 'o'
909fca
+	OVAL_OPT_OUTPUT = 'o',
909fca
+	OVAL_OPT_LOCAL_FILES
909fca
 };
909fca
 
909fca
 #if defined(OVAL_PROBES_ENABLED)
909fca
@@ -521,7 +522,7 @@ bool getopt_oval_eval(int argc, char **argv, struct oscap_action *action)
909fca
 		{ "skip-valid",	no_argument, &action->validate, 0 },
909fca
 		{ "skip-validation",	no_argument, &action->validate, 0 },
909fca
 		{ "fetch-remote-resources", no_argument, &action->remote_resources, 1},
909fca
-		{ "use-local-file", no_argument, &action->use_local_file, 1},
909fca
+		{ "local-files", required_argument, NULL, OVAL_OPT_LOCAL_FILES},
909fca
 		{ 0, 0, 0, 0 }
909fca
 	};
909fca
 
909fca
@@ -535,6 +536,9 @@ bool getopt_oval_eval(int argc, char **argv, struct oscap_action *action)
909fca
 		case OVAL_OPT_DIRECTIVES: action->f_directives = optarg; break;
909fca
 		case OVAL_OPT_DATASTREAM_ID: action->f_datastream_id = optarg;	break;
909fca
 		case OVAL_OPT_OVAL_ID: action->f_oval_id = optarg;	break;
909fca
+		case OVAL_OPT_LOCAL_FILES:
909fca
+			action->local_files = optarg;
909fca
+			break;
909fca
 		case 0: break;
909fca
 		default: return oscap_module_usage(action->module, stderr, NULL);
909fca
 		}
909fca
diff --git a/utils/oscap-tool.h b/utils/oscap-tool.h
909fca
index a3b8781b27..c0596f3e60 100644
909fca
--- a/utils/oscap-tool.h
909fca
+++ b/utils/oscap-tool.h
909fca
@@ -174,7 +174,7 @@ struct oscap_action {
909fca
         int list_dynamic;
909fca
 	char *verbosity_level;
909fca
 	char *fix_type;
909fca
-	int use_local_file;
909fca
+	char *local_files;
909fca
 };
909fca
 
909fca
 int app_xslt(const char *infile, const char *xsltfile, const char *outfile, const char **params);
909fca
diff --git a/utils/oscap-xccdf.c b/utils/oscap-xccdf.c
909fca
index ef2768bdef..54b8df5467 100644
909fca
--- a/utils/oscap-xccdf.c
909fca
+++ b/utils/oscap-xccdf.c
909fca
@@ -129,7 +129,7 @@ static struct oscap_module XCCDF_EXPORT_OVAL_VARIABLES = {
909fca
 		"   --skip-valid                  - Skip validation.\n"
909fca
 		"   --skip-validation\n"
909fca
 		"   --fetch-remote-resources      - Download remote content referenced by XCCDF.\n"
909fca
-		"   --use-local-file              - Use a locally downloaded copy of the remote resource if it exists.\n"
909fca
+		"   --local-files <dir>       - Use locally downloaded copies of remote resources stored in the given directory.\n"
909fca
 		"   --datastream-id <id>          - ID of the data stream in the collection to use.\n"
909fca
 		"                                   (only applicable for source data streams)\n"
909fca
 		"   --xccdf-id <id>               - ID of component-ref with XCCDF in the data stream that should be evaluated.\n"
909fca
@@ -172,7 +172,7 @@ static struct oscap_module XCCDF_EVAL = {
909fca
 		"                                   (only applicable for source data streams)\n"
909fca
 		"   --enforce-signature           - Process only signed data streams.\n"
909fca
 		"   --fetch-remote-resources      - Download remote content referenced by XCCDF.\n"
909fca
-		"   --use-local-file              - Use a locally downloaded copy of the remote resource if it exists.\n"
909fca
+		"   --local-files <dir>       - Use locally downloaded copies of remote resources stored in the given directory.\n"
909fca
 		"   --progress                    - Switch to sparse output suitable for progress reporting.\n"
909fca
 		"                                   Format is \"$rule_id:$result\\n\".\n"
909fca
 		"   --datastream-id <id>          - ID of the data stream in the collection to use.\n"
909fca
@@ -201,7 +201,7 @@ static struct oscap_module XCCDF_REMEDIATE = {
909fca
 		"   --cpe <name>                  - Use given CPE dictionary or language (autodetected)\n"
909fca
 		"                                   for applicability checks.\n"
909fca
 		"   --fetch-remote-resources      - Download remote content referenced by XCCDF.\n"
909fca
-		"   --use-local-file              - Use a locally downloaded copy of the remote resource if it exists.\n"
909fca
+		"   --local-files <dir>       - Use locally downloaded copies of remote resources stored in the given directory.\n"
909fca
 		"   --results <file>              - Write XCCDF Results into file.\n"
909fca
 		"   --results-arf <file>          - Write ARF (result data stream) into file.\n"
909fca
 		"   --stig-viewer <file>          - Writes XCCDF results into FILE in a format readable by DISA STIG Viewer\n"
909fca
@@ -576,7 +576,7 @@ int app_evaluate_xccdf(const struct oscap_action *action)
909fca
 	if (action->tailoring_file != NULL)
909fca
 		xccdf_session_set_user_tailoring_file(session, action->tailoring_file);
909fca
 	xccdf_session_set_user_tailoring_cid(session, action->tailoring_id);
909fca
-	xccdf_session_configure_remote_resources(session, action->remote_resources, action->use_local_file, download_reporting_callback);
909fca
+	xccdf_session_configure_remote_resources(session, action->remote_resources, action->local_files, download_reporting_callback);
909fca
 	xccdf_session_set_custom_oval_files(session, action->f_ovals);
909fca
 	xccdf_session_set_product_cpe(session, OSCAP_PRODUCTNAME);
909fca
 	xccdf_session_set_rule(session, action->rule);
909fca
@@ -681,7 +681,7 @@ static int app_xccdf_export_oval_variables(const struct oscap_action *action)
909fca
 		xccdf_session_set_benchmark_id(session, action->f_benchmark_id);
909fca
 	}
909fca
 	xccdf_session_set_user_cpe(session, action->cpe);
909fca
-	xccdf_session_configure_remote_resources(session, action->remote_resources, action->use_local_file, download_reporting_callback);
909fca
+	xccdf_session_configure_remote_resources(session, action->remote_resources, action->local_files, download_reporting_callback);
909fca
 	xccdf_session_set_custom_oval_files(session, action->f_ovals);
909fca
 	xccdf_session_set_custom_oval_eval_fn(session, resolve_variables_wrapper);
909fca
 
909fca
@@ -724,7 +724,7 @@ int app_xccdf_remediate(const struct oscap_action *action)
909fca
 		goto cleanup;
909fca
 	xccdf_session_set_validation(session, action->validate, getenv("OSCAP_FULL_VALIDATION") != NULL);
909fca
 	xccdf_session_set_user_cpe(session, action->cpe);
909fca
-	xccdf_session_configure_remote_resources(session, action->remote_resources, action->use_local_file, download_reporting_callback);
909fca
+	xccdf_session_configure_remote_resources(session, action->remote_resources, action->local_files, download_reporting_callback);
909fca
 	xccdf_session_set_custom_oval_files(session, action->f_ovals);
909fca
 
909fca
 	if (xccdf_session_load(session) != 0)
909fca
@@ -940,7 +940,7 @@ int app_generate_fix(const struct oscap_action *action)
909fca
 	xccdf_session_set_signature_validation(session, action->validate_signature);
909fca
 	xccdf_session_set_signature_enforcement(session, action->enforce_signature);
909fca
 	xccdf_session_set_user_cpe(session, action->cpe);
909fca
-	xccdf_session_configure_remote_resources(session, action->remote_resources, action->use_local_file, download_reporting_callback);
909fca
+	xccdf_session_configure_remote_resources(session, action->remote_resources, action->local_files, download_reporting_callback);
909fca
 	xccdf_session_set_custom_oval_files(session, action->f_ovals);
909fca
 	xccdf_session_set_user_tailoring_file(session, action->tailoring_file);
909fca
 	xccdf_session_set_user_tailoring_cid(session, action->tailoring_id);
909fca
@@ -1015,7 +1015,7 @@ int app_generate_guide(const struct oscap_action *action)
909fca
 	xccdf_session_set_validation(session, action->validate, getenv("OSCAP_FULL_VALIDATION") != NULL);
909fca
 	xccdf_session_set_signature_validation(session, action->validate_signature);
909fca
 	xccdf_session_set_signature_enforcement(session, action->enforce_signature);
909fca
-	xccdf_session_configure_remote_resources(session, action->remote_resources, action->use_local_file, download_reporting_callback);
909fca
+	xccdf_session_configure_remote_resources(session, action->remote_resources, action->local_files, download_reporting_callback);
909fca
 	xccdf_session_set_user_tailoring_file(session, action->tailoring_file);
909fca
 	xccdf_session_set_user_tailoring_cid(session, action->tailoring_id);
909fca
 	if (xccdf_session_is_sds(session)) {
909fca
@@ -1128,7 +1128,8 @@ enum oval_opt {
909fca
     XCCDF_OPT_CPE_DICT,
909fca
     XCCDF_OPT_OUTPUT = 'o',
909fca
     XCCDF_OPT_RESULT_ID = 'i',
909fca
-	XCCDF_OPT_FIX_TYPE
909fca
+	XCCDF_OPT_FIX_TYPE,
909fca
+	XCCDF_OPT_LOCAL_FILES
909fca
 };
909fca
 
909fca
 bool getopt_xccdf(int argc, char **argv, struct oscap_action *action)
909fca
@@ -1160,6 +1161,7 @@ bool getopt_xccdf(int argc, char **argv, struct oscap_action *action)
909fca
 		{"cpe-dict",	required_argument, NULL, XCCDF_OPT_CPE_DICT}, // DEPRECATED!
909fca
 		{"sce-template", 	required_argument, NULL, XCCDF_OPT_SCE_TEMPLATE},
909fca
 		{"fix-type", required_argument, NULL, XCCDF_OPT_FIX_TYPE},
909fca
+		{"local-files", required_argument, NULL, XCCDF_OPT_LOCAL_FILES},
909fca
 	// flags
909fca
 		{"force",		no_argument, &action->force, 1},
909fca
 		{"oval-results",	no_argument, &action->oval_results, 1},
909fca
@@ -1169,7 +1171,6 @@ bool getopt_xccdf(int argc, char **argv, struct oscap_action *action)
909fca
 		{"skip-signature-validation", no_argument, &action->validate_signature, 0},
909fca
 		{"enforce-signature", no_argument, &action->enforce_signature, 1},
909fca
 		{"fetch-remote-resources", no_argument, &action->remote_resources, 1},
909fca
-		{"use-local-file", no_argument, &action->use_local_file, 1},
909fca
 		{"progress", no_argument, &action->progress, 1},
909fca
 		{"remediate", no_argument, &action->remediate, 1},
909fca
 		{"hide-profile-info",	no_argument, &action->hide_profile_info, 1},
909fca
@@ -1215,6 +1216,9 @@ bool getopt_xccdf(int argc, char **argv, struct oscap_action *action)
909fca
 		case XCCDF_OPT_FIX_TYPE:
909fca
 			action->fix_type = optarg;
909fca
 			break;
909fca
+		case XCCDF_OPT_LOCAL_FILES:
909fca
+			action->local_files = optarg;
909fca
+			break;
909fca
 		case 0: break;
909fca
 		default: return oscap_module_usage(action->module, stderr, NULL);
909fca
 		}
909fca
diff --git a/utils/oscap.8 b/utils/oscap.8
909fca
index 8dcb9ca330..4f5f6259e3 100644
909fca
--- a/utils/oscap.8
909fca
+++ b/utils/oscap.8
909fca
@@ -72,9 +72,9 @@ For XCCDF or SCAP source data stream files, the info module prints out IDs of in
909fca
 Allow download of remote components referenced from data stream.
909fca
 .RE
909fca
 .TP
909fca
-\fB\-\-use-local-file\fR
909fca
+\fB\-\-local-files DIRECTORY\fR
909fca
 .RS
909fca
-Instead of downloading remote data stream components from the network, use a data stream component stored locally in a file. In place of the remote data stream component OpenSCAP will attempt to use a file whose file name is equal to @name attribute of the uri element within the catalog element within the component-ref element in the data stream if such file exists.
909fca
+Instead of downloading remote data stream components from the network, use data stream components stored locally as files in the given directory. In place of the remote data stream component OpenSCAP will attempt to use a file whose file name is equal to @name attribute of the uri element within the catalog element within the component-ref element in the data stream if such file exists.
909fca
 .RE
909fca
 .TP
909fca
 \fB\-\-profile PROFILE\fR
909fca
@@ -206,9 +206,9 @@ Process only digitally signed SCAP source data streams. Data streams without a s
909fca
 Allow download of remote OVAL content referenced from XCCDF by check-content-ref/@href.
909fca
 .RE
909fca
 .TP
909fca
-\fB\-\-use-local-file\fR
909fca
+\fB\-\-local-files DIRECTORY\fR
909fca
 .RS
909fca
-Instead of downloading remote data stream components from the network, use a data stream component stored locally in a file. In place of the remote data stream component OpenSCAP will attempt to use a file whose file name is equal to @name attribute of the uri element within the catalog element within the component-ref element in the data stream if such file exists.
909fca
+Instead of downloading remote data stream components from the network, use data stream components stored locally as files in the given directory. In place of the remote data stream component OpenSCAP will attempt to use a file whose file name is equal to @name attribute of the uri element within the catalog element within the component-ref element in the data stream if such file exists.
909fca
 .RE
909fca
 .TP
909fca
 \fB\-\-remediate\fR
909fca
@@ -236,9 +236,9 @@ Do not validate input/output files.
909fca
 Allow download of remote OVAL content referenced from XCCDF by check-content-ref/@href.
909fca
 .RE
909fca
 .TP
909fca
-\fB\-\-use-local-file\fR
909fca
+\fB\-\-local-files DIRECTORY\fR
909fca
 .RS
909fca
-Instead of downloading remote data stream components from the network, use a data stream component stored locally in a file. In place of the remote data stream component OpenSCAP will attempt to use a file whose file name is equal to @name attribute of the uri element within the catalog element within the component-ref element in the data stream if such file exists.
909fca
+Instead of downloading remote data stream components from the network, use data stream components stored locally as files in the given directory. In place of the remote data stream component OpenSCAP will attempt to use a file whose file name is equal to @name attribute of the uri element within the catalog element within the component-ref element in the data stream if such file exists.
909fca
 .RE
909fca
 .TP
909fca
 \fB\-\-cpe CPE_FILE\fR
909fca
@@ -318,7 +318,7 @@ Select a particular profile from XCCDF document.
909fca
 Allow download of remote OVAL content referenced from XCCDF by check-content-ref/@href.
909fca
 .RE
909fca
 .TP
909fca
-\fB\-\-use-local-file\fR
909fca
+\fB\-\-local-files DIRECTORY\fR
909fca
 .RS
909fca
 Instead of downloading remote data stream components from the network, use a data stream component stored locally in a file. In place of the remote data stream component OpenSCAP will attempt to use a file whose file name is equal to @name attribute of the uri element within the catalog element within the component-ref element in the data stream if such file exists.
909fca
 .RE
909fca
@@ -498,7 +498,7 @@ Do not validate input/output files.
909fca
 \fB\-\-fetch-remote-resources\fR
909fca
 Allow download of remote components referenced from data stream.
909fca
 .TP
909fca
-\fB\-\-use-local-file\fR
909fca
+\fB\-\-local-files DIRECTORY\fR
909fca
 Instead of downloading remote data stream components from the network, use a data stream component stored locally in a file. In place of the remote data stream component OpenSCAP will attempt to use a file whose file name is equal to @name attribute of the uri element within the catalog element within the component-ref element in the data stream if such file exists.
909fca
 .RE
909fca
 
909fca
@@ -662,7 +662,7 @@ Do not validate input/output files.
909fca
 \fB\-\-fetch-remote-resources\fR
909fca
 Allow download of remote components referenced from data stream.
909fca
 .TP
909fca
-\fB\-\-use-local-file\fR
909fca
+\fB\-\-local-files DIRECTORY\fR
909fca
 Instead of downloading remote data stream components from the network, use a data stream component stored locally in a file. In place of the remote data stream component OpenSCAP will attempt to use a file whose file name is equal to @name attribute of the uri element within the catalog element within the component-ref element in the data stream if such file exists.
909fca
 .RE
909fca
 .TP
909fca
909fca
From 6732eb94fb6f4606be388e27c347a882917dfb3f Mon Sep 17 00:00:00 2001
909fca
From: =?UTF-8?q?Jan=20=C4=8Cern=C3=BD?= <jcerny@redhat.com>
909fca
Date: Fri, 23 Jul 2021 12:58:33 +0200
909fca
Subject: [PATCH 04/10] Show a warning
909fca
909fca
When --local-files is used but the file which is expected to be
909fca
loaded instead of the remote data stream component doesn't exist
909fca
we will print a warning so that the user is informed and he would
909fca
know what file is expected.
909fca
909fca
Also added a simple test to test the aforementioned warning scenario.
909fca
---
909fca
 src/DS/sds.c                                  |  7 ++++-
909fca
 .../DS/test_ds_use_local_remote_resources.sh  | 26 ++++++++++++++++++-
909fca
 2 files changed, 31 insertions(+), 2 deletions(-)
909fca
909fca
diff --git a/src/DS/sds.c b/src/DS/sds.c
909fca
index 365ae96987..a6e7b27ac9 100644
909fca
--- a/src/DS/sds.c
909fca
+++ b/src/DS/sds.c
909fca
@@ -451,7 +451,12 @@ static int ds_sds_dump_component_by_href(struct ds_sds_session *session, char* x
909fca
 					free(local_filepath);
909fca
 					return 0;
909fca
 				} else {
909fca
-					dW("Can't use local file '%s' instead of '%s'", local_filepath, xlink_href);
909fca
+					ds_sds_session_remote_resources_progress(session)(true,
909fca
+						"WARNING: Data stream component '%s' points out to the remote '%s'. " \
909fca
+						"The option --local-files '%s' has been provided, but the file '%s' can't be used locally: %s.\n",
909fca
+						cref_id, url, local_files, local_filepath, strerror(errno));
909fca
+					free(local_filepath);
909fca
+					return -2;
909fca
 				}
909fca
 				free(local_filepath);
909fca
 			}
909fca
diff --git a/tests/DS/test_ds_use_local_remote_resources.sh b/tests/DS/test_ds_use_local_remote_resources.sh
909fca
index e4a1f0eedd..789dc8326c 100755
909fca
--- a/tests/DS/test_ds_use_local_remote_resources.sh
909fca
+++ b/tests/DS/test_ds_use_local_remote_resources.sh
909fca
@@ -9,6 +9,7 @@ set -x
909fca
 . $builddir/tests/test_common.sh
909fca
 	
909fca
 PROFILE="xccdf_com.example.www_profile_test_remote_res"
909fca
+
909fca
 result=$(mktemp)
909fca
 stderr=$(mktemp)
909fca
 tmpdir1=$(mktemp -d)
909fca
@@ -55,4 +56,27 @@ assert_exists 1 '//rule-result[@idref="xccdf_com.example.www_rule_test-pass2"]/r
909fca
 
909fca
 popd
909fca
 rm -f "$result" "$stderr"
909fca
-rm -rf "$tmpdir"
909fca
\ No newline at end of file
909fca
+rm -rf "$tmpdir"
909fca
+
909fca
+# test that a warning is shown when --local-files is provided but the file doesn't exist
909fca
+result=$(mktemp)
909fca
+stderr=$(mktemp)
909fca
+tmpdir1=$(mktemp -d)
909fca
+tmpdir2=$(mktemp -d)
909fca
+tmpdir3=$(mktemp -d)
909fca
+cp "${srcdir}/ds_use_local_remote_resources/remote_content_1.3.ds.xml" "$tmpdir2"
909fca
+pushd "$tmpdir1"
909fca
+
909fca
+# $tmpdir3 is empty, it doesn't contain any content
909fca
+$OSCAP xccdf eval --local-files "$tmpdir3" --profile "$PROFILE" --results "$result" "$tmpdir2/remote_content_1.3.ds.xml" 2>"$stderr" || ret=$?
909fca
+[ "$ret" = 2 ]
909fca
+
909fca
+grep -q "WARNING: Data stream component 'scap_org.open-scap_cref_remote.oval.xml' points out to the remote 'https://www.example.com/security/data/oval/remote.oval.xml'. The option --local-files '$tmpdir3' has been provided, but the file '$tmpdir3/remote.oval.xml' can't be used locally: No such file or directory." "$stderr"
909fca
+
909fca
+assert_exists 1 '//rule-result[@idref="xccdf_com.example.www_rule_test-pass"]/result[text()="pass"]'
909fca
+assert_exists 1 '//rule-result[@idref="xccdf_com.example.www_rule_test-remote_res"]/result[text()="notchecked"]'
909fca
+assert_exists 1 '//rule-result[@idref="xccdf_com.example.www_rule_test-pass2"]/result[text()="pass"]'
909fca
+
909fca
+popd
909fca
+rm -f "$result" "$stderr"
909fca
+rm -rf "$tmpdir1" "$tmpdir2" "$tmpdir3"
909fca
909fca
From 34ebf46a84a9bd4d9727739c514faaf0e41858ac Mon Sep 17 00:00:00 2001
909fca
From: =?UTF-8?q?Jan=20=C4=8Cern=C3=BD?= <jcerny@redhat.com>
909fca
Date: Fri, 23 Jul 2021 17:07:44 +0200
909fca
Subject: [PATCH 05/10] Update bash completion
909fca
909fca
with --local-files
909fca
---
909fca
 dist/bash_completion.d/oscap | 12 ++++++------
909fca
 1 file changed, 6 insertions(+), 6 deletions(-)
909fca
909fca
diff --git a/dist/bash_completion.d/oscap b/dist/bash_completion.d/oscap
909fca
index 030c250ebe..329f0736e3 100644
909fca
--- a/dist/bash_completion.d/oscap
909fca
+++ b/dist/bash_completion.d/oscap
909fca
@@ -27,14 +27,14 @@ function _oscap {
909fca
     local -A opts=()
909fca
 	opts[oscap]="--version --quiet --help -V -q -h"
909fca
     opts[oscap:oval:validate]="--version --definitions --variables --syschar --results --directives --skip-schematron"
909fca
-    opts[oscap:oval:eval]="--datastream-id --oval-id --id --variables --directives --without-syschar --results --report --skip-valid --skip-validation --fetch-remote-resources --verbose --verbose-log-file"
909fca
+    opts[oscap:oval:eval]="--datastream-id --oval-id --id --variables --directives --without-syschar --results --report --skip-valid --skip-validation --fetch-remote-resources --local-files --verbose --verbose-log-file"
909fca
     opts[oscap:oval:analyse]="--variables --directives --verbose --verbose-log-file --skip-valid --skip-validation"
909fca
     opts[oscap:oval:collect]="--id --syschar --skip-valid --skip-validation --variables --verbose --verbose-log-file"
909fca
     opts[oscap:oval:generate:report]="-o --output"
909fca
-    opts[oscap:xccdf:eval]="--benchmark-id --check-engine-results --cpe --datastream-id --enforce-signature --export-variables --fetch-remote-resources --oval-results --profile --progress --remediate --report --results --results-arf --rule --skip-valid --skip-validation --skip-signature-validation --stig-viewer --tailoring-file --tailoring-id --thin-results --verbose --verbose-log-file --without-syschar --xccdf-id"
909fca
+    opts[oscap:xccdf:eval]="--benchmark-id --check-engine-results --cpe --datastream-id --enforce-signature --export-variables --fetch-remote-resources --local-files --oval-results --profile --progress --remediate --report --results --results-arf --rule --skip-valid --skip-validation --skip-signature-validation --stig-viewer --tailoring-file --tailoring-id --thin-results --verbose --verbose-log-file --without-syschar --xccdf-id"
909fca
     opts[oscap:xccdf:validate]="--skip-schematron"
909fca
-    opts[oscap:xccdf:export-oval-variables]="--datastream-id --xccdf-id --profile --skip-valid --skip-validation --fetch-remote-resources --cpe"
909fca
-    opts[oscap:xccdf:remediate]="--result-id --skip-valid --skip-validation --fetch-remote-resources --results --results-arf --report --oval-results --export-variables --cpe --check-engine-results --progress"
909fca
+    opts[oscap:xccdf:export-oval-variables]="--datastream-id --xccdf-id --profile --skip-valid --skip-validation --fetch-remote-resources --local-files --cpe"
909fca
+    opts[oscap:xccdf:remediate]="--result-id --skip-valid --skip-validation --fetch-remote-resources --local-files --results --results-arf --report --oval-results --export-variables --cpe --check-engine-results --progress"
909fca
     opts[oscap:xccdf:resolve]="-o --output -f --force"
909fca
     opts[oscap:xccdf:generate]="--profile"
909fca
     opts[oscap:xccdf:generate:report]="-o --output --result-id --profile --oval-template --sce-template"
909fca
@@ -43,12 +43,12 @@ function _oscap {
909fca
     opts[oscap:xccdf:generate:custom]="-o --output --stylesheet"
909fca
     opts[oscap:ds:sds-add]="--datastream-id --skip-valid --skip-validation"
909fca
     opts[oscap:ds:sds-compose]="--skip-valid --skip-validation"
909fca
-    opts[oscap:ds:sds-split]="--datastream-id --xccdf-id --skip-valid --skip-validation --fetch-remote-resources"
909fca
+    opts[oscap:ds:sds-split]="--datastream-id --xccdf-id --skip-valid --skip-validation --fetch-remote-resources --local-files"
909fca
     opts[oscap:ds:rds-create]="--skip-valid --skip-validation"
909fca
     opts[oscap:ds:rds-split]="--report-id --skip-valid --skip-validation"
909fca
     opts[oscap:cvss:score]=""
909fca
     opts[oscap:cvss:describe]=""
909fca
-    opts[oscap:info]="--fetch-remote-resources --profile --profiles"
909fca
+    opts[oscap:info]="--fetch-remote-resources --local-files --profile --profiles"
909fca
 
909fca
     # local variables
909fca
 	local std cmd i prev
909fca
909fca
From 66ae271966405596b156bca13e6ca41dc118564b Mon Sep 17 00:00:00 2001
909fca
From: =?UTF-8?q?Jan=20=C4=8Cern=C3=BD?= <jcerny@redhat.com>
909fca
Date: Fri, 23 Jul 2021 17:08:17 +0200
909fca
Subject: [PATCH 06/10] Support local remote files in wrappers
909fca
909fca
This adds --local-files to oscap-chroot, oscap-ssh and oscap-vm.
909fca
909fca
In oscap-ssh we need to copy the files to the remote machine, which
909fca
is a similar thing that we do with tailoring and other files.
909fca
---
909fca
 utils/oscap-chroot   |  1 +
909fca
 utils/oscap-chroot.8 |  1 +
909fca
 utils/oscap-ssh      | 17 +++++++++++++++++
909fca
 utils/oscap-ssh.8    |  1 +
909fca
 utils/oscap-vm       |  1 +
909fca
 utils/oscap-vm.8     |  1 +
909fca
 6 files changed, 22 insertions(+)
909fca
909fca
diff --git a/utils/oscap-chroot b/utils/oscap-chroot
909fca
index c1e35aa652..57ec66c428 100755
909fca
--- a/utils/oscap-chroot
909fca
+++ b/utils/oscap-chroot
909fca
@@ -53,6 +53,7 @@ function usage()
909fca
     echo "  --skip-valid"
909fca
     echo "  --skip-validation"
909fca
     echo "  --fetch-remote-resources"
909fca
+    echo "  --local-files"
909fca
     echo "  --progress"
909fca
     echo "  --datastream-id"
909fca
     echo "  --xccdf-id"
909fca
diff --git a/utils/oscap-chroot.8 b/utils/oscap-chroot.8
909fca
index d0c75c68e3..e02dd8dbea 100644
909fca
--- a/utils/oscap-chroot.8
909fca
+++ b/utils/oscap-chroot.8
909fca
@@ -23,6 +23,7 @@ supported oscap xccdf eval options are:
909fca
   --skip-valid
909fca
   --skip-validation
909fca
   --fetch-remote-resources
909fca
+  --local-files
909fca
   --progress
909fca
   --datastream-id
909fca
   --xccdf-id
909fca
diff --git a/utils/oscap-ssh b/utils/oscap-ssh
909fca
index f428f99a8e..120d4ae8c6 100755
909fca
--- a/utils/oscap-ssh
909fca
+++ b/utils/oscap-ssh
909fca
@@ -54,6 +54,7 @@ function usage()
909fca
     echo "  --skip-valid"
909fca
     echo "  --skip-validation"
909fca
     echo "  --fetch-remote-resources"
909fca
+    echo "  --local-files"
909fca
     echo "  --progress"
909fca
     echo "  --datastream-id"
909fca
     echo "  --xccdf-id"
909fca
@@ -110,6 +111,12 @@ function scp_copy_to_temp_dir {
909fca
     scp -o ControlPath="$MASTER_SOCKET" -P "$SSH_PORT" $SSH_ADDITIONAL_OPTIONS "$1" "$SSH_HOST:$REMOTE_TEMP_DIR/$2"
909fca
 }
909fca
 
909fca
+# $1: Local directory name to copy
909fca
+# $2: Remote destination
909fca
+function scp_copy_dir_to_temp_dir {
909fca
+    scp -r -o ControlPath="$MASTER_SOCKET" -P "$SSH_PORT" $SSH_ADDITIONAL_OPTIONS "$1" "$SSH_HOST:$REMOTE_TEMP_DIR/$2"
909fca
+}
909fca
+
909fca
 # $1: Remote filename to get
909fca
 # $2: Local destination
909fca
 function scp_retreive_from_temp_dir {
909fca
@@ -196,6 +203,7 @@ oscap_args=("$@")
909fca
 
909fca
 LOCAL_CONTENT_PATH=""
909fca
 LOCAL_TAILORING_PATH=""
909fca
+LOCAL_LOCAL_FILES_PATH=""
909fca
 LOCAL_CPE_PATH=""
909fca
 LOCAL_VARIABLES_PATH=""
909fca
 LOCAL_DIRECTIVES_PATH=""
909fca
@@ -214,6 +222,10 @@ for i in $(seq 0 `expr $# - 1`); do
909fca
         LOCAL_TAILORING_PATH=${oscap_args[j]}
909fca
         oscap_args[j]="$REMOTE_TEMP_DIR/tailoring.xml"
909fca
       ;;
909fca
+    ("--local-files")
909fca
+        LOCAL_LOCAL_FILES_PATH=${oscap_args[j]}
909fca
+        oscap_args[j]="$REMOTE_TEMP_DIR/local_files"
909fca
+      ;;
909fca
     ("--cpe")
909fca
         LOCAL_CPE_PATH=${oscap_args[j]}
909fca
         oscap_args[j]="$REMOTE_TEMP_DIR/cpe.xml"
909fca
@@ -258,6 +270,7 @@ fi
909fca
 
909fca
 [ "$LOCAL_CONTENT_PATH" == "" ] || [ -f "$LOCAL_CONTENT_PATH" ] || die "Expected the last argument to be an input file, '$LOCAL_CONTENT_PATH' isn't a valid file path or the file doesn't exist!"
909fca
 [ "$LOCAL_TAILORING_PATH" == "" ] || [ -f "$LOCAL_TAILORING_PATH" ] || die "Tailoring file path '$LOCAL_TAILORING_PATH' isn't a valid file path or the file doesn't exist!"
909fca
+[ "$LOCAL_LOCAL_FILES_PATH" == "" ] || [ -d "$LOCAL_LOCAL_FILES_PATH" ] || die "Directory '$LOCAL_LOCAL_FILES_PATH' isn't a valid directory path or the directory doesn't exist!"
909fca
 [ "$LOCAL_CPE_PATH" == "" ] || [ -f "$LOCAL_CPE_PATH" ] || die "CPE file path '$LOCAL_CPE_PATH' isn't a valid file path or the file doesn't exist!"
909fca
 [ "$LOCAL_VARIABLES_PATH" == "" ] || [ -f "$LOCAL_VARIABLES_PATH" ] || die "OVAL variables file path '$LOCAL_VARIABLES_PATH' isn't a valid file path or the file doesn't exist!"
909fca
 [ "$LOCAL_DIRECTIVES_PATH" == "" ] || [ -f "$LOCAL_DIRECTIVES_PATH" ] || die "OVAL directives file path '$LOCAL_DIRECTIVES_PATH' isn't a valid file path or the file doesn't exist!"
909fca
@@ -270,6 +283,10 @@ if [ "$LOCAL_TAILORING_PATH" != "" ]; then
909fca
     echo "Copying tailoring file '$LOCAL_TAILORING_PATH' to remote working directory '$REMOTE_TEMP_DIR'..."
909fca
     scp_copy_to_temp_dir "$LOCAL_TAILORING_PATH" tailoring.xml || die "Failed to copy tailoring file to remote temporary directory!"
909fca
 fi
909fca
+if [ "$LOCAL_LOCAL_FILES_PATH" != "" ]; then
909fca
+    echo "Copying directory '$LOCAL_LOCAL_FILES_PATH' to remote working directory '$REMOTE_TEMP_DIR'..."
909fca
+    scp_copy_dir_to_temp_dir "$LOCAL_LOCAL_FILES_PATH" local_files || die "Failed to copy directory $LOCAL_LOCAL_FILES_PATH to remote temporary directory!"
909fca
+fi
909fca
 if [ "$LOCAL_CPE_PATH" != "" ]; then
909fca
     echo "Copying CPE file '$LOCAL_CPE_PATH' to remote working directory '$REMOTE_TEMP_DIR'..."
909fca
     scp_copy_to_temp_dir "$LOCAL_CPE_PATH" cpe.xml || die "Failed to copy CPE file to remote temporary directory!"
909fca
diff --git a/utils/oscap-ssh.8 b/utils/oscap-ssh.8
909fca
index f64855829a..416b1f3e58 100644
909fca
--- a/utils/oscap-ssh.8
909fca
+++ b/utils/oscap-ssh.8
909fca
@@ -29,6 +29,7 @@ Supported options are:
909fca
   --skip-valid
909fca
   --skip-validation
909fca
   --fetch-remote-resources
909fca
+  --local-files
909fca
   --progress
909fca
   --datastream-id
909fca
   --xccdf-id
909fca
diff --git a/utils/oscap-vm b/utils/oscap-vm
909fca
index 1a9d6b3bf6..e7ae6e2600 100755
909fca
--- a/utils/oscap-vm
909fca
+++ b/utils/oscap-vm
909fca
@@ -51,6 +51,7 @@ function usage()
909fca
     echo "  --skip-valid"
909fca
     echo "  --skip-validation"
909fca
     echo "  --fetch-remote-resources"
909fca
+    echo "  --local-files"
909fca
     echo "  --progress"
909fca
     echo "  --datastream-id"
909fca
     echo "  --xccdf-id"
909fca
diff --git a/utils/oscap-vm.8 b/utils/oscap-vm.8
909fca
index a335725e5e..b7276c1128 100644
909fca
--- a/utils/oscap-vm.8
909fca
+++ b/utils/oscap-vm.8
909fca
@@ -65,6 +65,7 @@ Supported oscap xccdf eval options are:
909fca
   \-\-skip-valid
909fca
   \-\-skip-validation
909fca
   \-\-fetch-remote-resources
909fca
+  \-\-local-files
909fca
   \-\-progress
909fca
   \-\-datastream-id <id>
909fca
   \-\-xccdf-id <id>
909fca
909fca
From cac289e1d15cd8f3bde64b94563ed1dcf34652bb Mon Sep 17 00:00:00 2001
909fca
From: =?UTF-8?q?Jan=20=C4=8Cern=C3=BD?= <jcerny@redhat.com>
909fca
Date: Fri, 23 Jul 2021 17:18:55 +0200
909fca
Subject: [PATCH 07/10] Fix the value to use a correct type
909fca
909fca
---
909fca
 src/DS/ds_sds_session.c | 2 +-
909fca
 1 file changed, 1 insertion(+), 1 deletion(-)
909fca
909fca
diff --git a/src/DS/ds_sds_session.c b/src/DS/ds_sds_session.c
909fca
index 99f4bc20fd..3a720e8131 100644
909fca
--- a/src/DS/ds_sds_session.c
909fca
+++ b/src/DS/ds_sds_session.c
909fca
@@ -347,7 +347,7 @@ void ds_sds_session_configure_remote_resources(struct ds_sds_session *session, b
909fca
 
909fca
 void ds_sds_session_set_remote_resources(struct ds_sds_session *session, bool allowed, download_progress_calllback_t callback)
909fca
 {
909fca
-	ds_sds_session_configure_remote_resources(session, allowed, false, callback);
909fca
+	ds_sds_session_configure_remote_resources(session, allowed, NULL, callback);
909fca
 }
909fca
 
909fca
 const char *ds_sds_session_local_files(struct ds_sds_session *session)
909fca
909fca
From e4e6732ffd23b408c0bf08eea91c406434bd4ec6 Mon Sep 17 00:00:00 2001
909fca
From: =?UTF-8?q?Jan=20=C4=8Cern=C3=BD?= <jcerny@redhat.com>
909fca
Date: Fri, 23 Jul 2021 17:36:36 +0200
909fca
Subject: [PATCH 08/10] Refactor: Extract function _handle_disabled_downloads
909fca
909fca
---
909fca
 src/DS/sds.c | 122 ++++++++++++++++++++++++++-------------------------
909fca
 1 file changed, 63 insertions(+), 59 deletions(-)
909fca
909fca
diff --git a/src/DS/sds.c b/src/DS/sds.c
909fca
index a6e7b27ac9..530e3ad9fa 100644
909fca
--- a/src/DS/sds.c
909fca
+++ b/src/DS/sds.c
909fca
@@ -371,6 +371,66 @@ static char *compose_target_filename_dirname(const char *relative_filepath, cons
909fca
 	return target_filename_dirname;
909fca
 }
909fca
 
909fca
+static int _handle_disabled_downloads(struct ds_sds_session *session, const char *relative_filepath, const char *xlink_href, const char *component_id, const char *target_filename_dirname, const char *cref_id, const char *url)
909fca
+{
909fca
+	/*
909fca
+	 * If fetching remote resources isn't allowed by the user let's take a look
909fca
+	 * whether there exists a file whose file name is equal to @name attribute
909fca
+	 * of the uri element within the catalog of the previously processed
909fca
+	 * component-ref which pointed us to the currently processed component-ref.
909fca
+	 * Note that the @name attribute value has been passed as relative_filepath
909fca
+	 * in the recursive call of ds_sds_dump_component_ref_as. If such file
909fca
+	 * exists, we will assume that it's a local copy of the remote component
909fca
+	 * located at the URL defined in @xlink:href. This way people can provide
909fca
+	 * the previously downloaded component which might be useful on systems with
909fca
+	 * limited internet access. This behavior is allowed only when --local-files
909fca
+	 * is used on the command line.
909fca
+	 * See: https://bugzilla.redhat.com/show_bug.cgi?id=1970527
909fca
+	 * See: https://access.redhat.com/solutions/5185891
909fca
+	 */
909fca
+	const char *local_files = ds_sds_session_local_files(session);
909fca
+	if (local_files == NULL) {
909fca
+		static bool fetch_remote_resources_suggested = false;
909fca
+		if (!fetch_remote_resources_suggested) {
909fca
+			fetch_remote_resources_suggested = true;
909fca
+			ds_sds_session_remote_resources_progress(session)(true,
909fca
+				"WARNING: Datastream component '%s' points out to the remote '%s'. Use '--fetch-remote-resources' option to download it.\n",
909fca
+				cref_id, url);
909fca
+		}
909fca
+
909fca
+		ds_sds_session_remote_resources_progress(session)(true,
909fca
+			"WARNING: Skipping '%s' file which is referenced from datastream\n",
909fca
+			url);
909fca
+		// -2 means that remote resources were not downloaded
909fca
+		return -2;
909fca
+	}
909fca
+	char *local_filepath = oscap_path_join(local_files, relative_filepath);
909fca
+	struct stat sb;
909fca
+	if (stat(local_filepath, &sb) == 0) {
909fca
+		dI("Using local file '%s' instead of '%s'", local_filepath, xlink_href);
909fca
+		struct oscap_source *source_file = oscap_source_new_from_file(local_filepath);
909fca
+		xmlDoc *doc = oscap_source_get_xmlDoc(source_file);
909fca
+		if (doc == NULL) {
909fca
+			free(local_filepath);
909fca
+			return -1;
909fca
+		}
909fca
+		xmlNodePtr inner_root = ds_sds_get_component_root_by_id(doc, component_id);
909fca
+
909fca
+		if (ds_sds_register_component(session, doc, inner_root, component_id, target_filename_dirname, relative_filepath) != 0) {
909fca
+			free(local_filepath);
909fca
+			return -1;
909fca
+		}
909fca
+		free(local_filepath);
909fca
+		return 0;
909fca
+	}
909fca
+	ds_sds_session_remote_resources_progress(session)(true,
909fca
+		"WARNING: Data stream component '%s' points out to the remote '%s'. " \
909fca
+		"The option --local-files '%s' has been provided, but the file '%s' can't be used locally: %s.\n",
909fca
+		cref_id, url, local_files, local_filepath, strerror(errno));
909fca
+	free(local_filepath);
909fca
+	return -2;
909fca
+}
909fca
+
909fca
 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)
909fca
 {
909fca
 	if (!xlink_href || strlen(xlink_href) < 2)
909fca
@@ -413,65 +473,9 @@ static int ds_sds_dump_component_by_href(struct ds_sds_session *session, char* x
909fca
 		}
909fca
 
909fca
 		if (!ds_sds_session_fetch_remote_resources(session)) {
909fca
-			/*
909fca
-			 * If fetching remote resources isn't allowed by the user let's take
909fca
-			 * a look whether there exists a file whose file name is equal to
909fca
-			 * @name attribute of the uri element within the catalog of the
909fca
-			 * previously processed component-ref which pointed us to the
909fca
-			 * currently processed component-ref. Note that the @name attribute
909fca
-			 * value has been passed as relative_filepath in the recursive call
909fca
-			 * of ds_sds_dump_component_ref_as. If such file exists, we will
909fca
-			 * assume that it's a local copy of the remote component located at
909fca
-			 * the URL defined in @xlink:href. This way people can provide the
909fca
-			 * previously downloaded component which might be useful on systems
909fca
-			 * with limited internet access. This behavior is allowed only when
909fca
-			 * --local-files is used on the command line.
909fca
-			 * See: https://bugzilla.redhat.com/show_bug.cgi?id=1970527
909fca
-			 * See: https://access.redhat.com/solutions/5185891
909fca
-			 */
909fca
-			const char *local_files = ds_sds_session_local_files(session);
909fca
-			if (local_files != NULL) {
909fca
-				char *local_filepath = oscap_path_join(local_files, relative_filepath);
909fca
-				struct stat sb;
909fca
-				if (stat(local_filepath, &sb) == 0) {
909fca
-				//if (ds_sds_session_can_use_local_file(session)) {
909fca
-					dI("Using local file '%s' instead of '%s'", local_filepath, xlink_href);
909fca
-					struct oscap_source *source_file = oscap_source_new_from_file(local_filepath);
909fca
-					xmlDoc *doc = oscap_source_get_xmlDoc(source_file);
909fca
-					if (doc == NULL) {
909fca
-						free(local_filepath);
909fca
-						return -1;
909fca
-					}
909fca
-					xmlNodePtr inner_root = ds_sds_get_component_root_by_id(doc, *component_id);
909fca
-
909fca
-					if (ds_sds_register_component(session, doc, inner_root, *component_id, target_filename_dirname, relative_filepath) != 0) {
909fca
-						free(local_filepath);
909fca
-						return -1;
909fca
-					}
909fca
-					free(local_filepath);
909fca
-					return 0;
909fca
-				} else {
909fca
-					ds_sds_session_remote_resources_progress(session)(true,
909fca
-						"WARNING: Data stream component '%s' points out to the remote '%s'. " \
909fca
-						"The option --local-files '%s' has been provided, but the file '%s' can't be used locally: %s.\n",
909fca
-						cref_id, url, local_files, local_filepath, strerror(errno));
909fca
-					free(local_filepath);
909fca
-					return -2;
909fca
-				}
909fca
-				free(local_filepath);
909fca
-			}
909fca
-
909fca
-			static bool fetch_remote_resources_suggested = false;
909fca
-
909fca
-			if (!fetch_remote_resources_suggested) {
909fca
-				fetch_remote_resources_suggested = true;
909fca
-				ds_sds_session_remote_resources_progress(session)(true, "WARNING: Datastream component '%s' points out to the remote '%s'. "
909fca
-									"Use '--fetch-remote-resources' option to download it.\n", cref_id, url);
909fca
-			}
909fca
-
909fca
-			ds_sds_session_remote_resources_progress(session)(true, "WARNING: Skipping '%s' file which is referenced from datastream\n", url);
909fca
-			// -2 means that remote resources were not downloaded
909fca
-			return -2;
909fca
+			return _handle_disabled_downloads(
909fca
+				session, relative_filepath, xlink_href, *component_id,
909fca
+				target_filename_dirname, cref_id, url);
909fca
 		}
909fca
 
909fca
 		return ds_dsd_dump_remote_component(url, *component_id, session, target_filename_dirname, relative_filepath);
909fca
909fca
From 9cb39894484e6bdccc235e4138af6447ffc5ee4b Mon Sep 17 00:00:00 2001
909fca
From: =?UTF-8?q?Jan=20=C4=8Cern=C3=BD?= <jcerny@redhat.com>
909fca
Date: Mon, 26 Jul 2021 16:03:18 +0200
909fca
Subject: [PATCH 09/10] Fix indentation and typos
909fca
909fca
---
909fca
 utils/oscap-ds.c    | 2 +-
909fca
 utils/oscap-info.c  | 2 +-
909fca
 utils/oscap-oval.c  | 2 +-
909fca
 utils/oscap-xccdf.c | 6 +++---
909fca
 4 files changed, 6 insertions(+), 6 deletions(-)
909fca
909fca
diff --git a/utils/oscap-ds.c b/utils/oscap-ds.c
909fca
index 8207f097ec..5f9863414b 100644
909fca
--- a/utils/oscap-ds.c
909fca
+++ b/utils/oscap-ds.c
909fca
@@ -83,7 +83,7 @@ static struct oscap_module DS_SDS_SPLIT_MODULE = {
909fca
 		"   --skip-valid                  - Skips validating of given XCCDF.\n"
909fca
 		"   --skip-validation\n"
909fca
 		"   --fetch-remote-resources      - Download remote content referenced by data stream.\n"
909fca
-		"   --use-local-file              - Use a locally downloaded copy of the remote resource if it exists.\n",
909fca
+		"   --local-files <dir>           - Use locally downloaded copies of remote resources stored in the given directory.\n",
909fca
 	.opt_parser = getopt_ds,
909fca
 	.func = app_ds_sds_split
909fca
 };
909fca
diff --git a/utils/oscap-info.c b/utils/oscap-info.c
909fca
index 2e6f5003aa..721596a528 100644
909fca
--- a/utils/oscap-info.c
909fca
+++ b/utils/oscap-info.c
909fca
@@ -63,7 +63,7 @@ struct oscap_module OSCAP_INFO_MODULE = {
909fca
     .usage = "some-file.xml",
909fca
 	.help = "Options:\n"
909fca
 		"   --fetch-remote-resources      - Download remote content referenced by data stream.\n"
909fca
-		"   --local-files <dir>       - Use locally downloaded copies of remote resources stored in the given directory.\n"
909fca
+		"   --local-files <dir>           - Use locally downloaded copies of remote resources stored in the given directory.\n"
909fca
 		"   --profile <id>                - Show info of the profile with the given ID.\n"
909fca
 		"   --profiles                    - Show profiles from the input file in the <id>:<title> format, one line per profile.\n",
909fca
     .opt_parser = getopt_info,
909fca
diff --git a/utils/oscap-oval.c b/utils/oscap-oval.c
909fca
index 3a206bb3c4..da1b1aad86 100644
909fca
--- a/utils/oscap-oval.c
909fca
+++ b/utils/oscap-oval.c
909fca
@@ -116,7 +116,7 @@ static struct oscap_module OVAL_EVAL = {
909fca
 	"                                   (only applicable for source data streams)\n"
909fca
 	"   --fetch-remote-resources      - Download remote content referenced by OVAL Definitions.\n"
909fca
 	"                                   (only applicable for source data streams)\n"
909fca
-	"   --local-files <dir>       - Use locally downloaded copies of remote resources stored in the given directory.\n",
909fca
+	"   --local-files <dir>           - Use locally downloaded copies of remote resources stored in the given directory.\n",
909fca
     .opt_parser = getopt_oval_eval,
909fca
     .func = app_evaluate_oval
909fca
 };
909fca
diff --git a/utils/oscap-xccdf.c b/utils/oscap-xccdf.c
909fca
index 54b8df5467..a7870c4281 100644
909fca
--- a/utils/oscap-xccdf.c
909fca
+++ b/utils/oscap-xccdf.c
909fca
@@ -129,7 +129,7 @@ static struct oscap_module XCCDF_EXPORT_OVAL_VARIABLES = {
909fca
 		"   --skip-valid                  - Skip validation.\n"
909fca
 		"   --skip-validation\n"
909fca
 		"   --fetch-remote-resources      - Download remote content referenced by XCCDF.\n"
909fca
-		"   --local-files <dir>       - Use locally downloaded copies of remote resources stored in the given directory.\n"
909fca
+		"   --local-files <dir>           - Use locally downloaded copies of remote resources stored in the given directory.\n"
909fca
 		"   --datastream-id <id>          - ID of the data stream in the collection to use.\n"
909fca
 		"                                   (only applicable for source data streams)\n"
909fca
 		"   --xccdf-id <id>               - ID of component-ref with XCCDF in the data stream that should be evaluated.\n"
909fca
@@ -172,7 +172,7 @@ static struct oscap_module XCCDF_EVAL = {
909fca
 		"                                   (only applicable for source data streams)\n"
909fca
 		"   --enforce-signature           - Process only signed data streams.\n"
909fca
 		"   --fetch-remote-resources      - Download remote content referenced by XCCDF.\n"
909fca
-		"   --local-files <dir>       - Use locally downloaded copies of remote resources stored in the given directory.\n"
909fca
+		"   --local-files <dir>           - Use locally downloaded copies of remote resources stored in the given directory.\n"
909fca
 		"   --progress                    - Switch to sparse output suitable for progress reporting.\n"
909fca
 		"                                   Format is \"$rule_id:$result\\n\".\n"
909fca
 		"   --datastream-id <id>          - ID of the data stream in the collection to use.\n"
909fca
@@ -201,7 +201,7 @@ static struct oscap_module XCCDF_REMEDIATE = {
909fca
 		"   --cpe <name>                  - Use given CPE dictionary or language (autodetected)\n"
909fca
 		"                                   for applicability checks.\n"
909fca
 		"   --fetch-remote-resources      - Download remote content referenced by XCCDF.\n"
909fca
-		"   --local-files <dir>       - Use locally downloaded copies of remote resources stored in the given directory.\n"
909fca
+		"   --local-files <dir>           - Use locally downloaded copies of remote resources stored in the given directory.\n"
909fca
 		"   --results <file>              - Write XCCDF Results into file.\n"
909fca
 		"   --results-arf <file>          - Write ARF (result data stream) into file.\n"
909fca
 		"   --stig-viewer <file>          - Writes XCCDF results into FILE in a format readable by DISA STIG Viewer\n"
909fca
909fca
From 7187e2a1e49927884d80702c2e3e6a796996277b Mon Sep 17 00:00:00 2001
909fca
From: =?UTF-8?q?Jan=20=C4=8Cern=C3=BD?= <jcerny@redhat.com>
909fca
Date: Mon, 26 Jul 2021 16:19:49 +0200
909fca
Subject: [PATCH 10/10] Update description in man page
909fca
909fca
---
909fca
 utils/oscap.8 | 6 +++---
909fca
 1 file changed, 3 insertions(+), 3 deletions(-)
909fca
909fca
diff --git a/utils/oscap.8 b/utils/oscap.8
909fca
index 4f5f6259e3..dcfa3d0c2f 100644
909fca
--- a/utils/oscap.8
909fca
+++ b/utils/oscap.8
909fca
@@ -320,7 +320,7 @@ Allow download of remote OVAL content referenced from XCCDF by check-content-ref
909fca
 .TP
909fca
 \fB\-\-local-files DIRECTORY\fR
909fca
 .RS
909fca
-Instead of downloading remote data stream components from the network, use a data stream component stored locally in a file. In place of the remote data stream component OpenSCAP will attempt to use a file whose file name is equal to @name attribute of the uri element within the catalog element within the component-ref element in the data stream if such file exists.
909fca
+Instead of downloading remote data stream components from the network, use data stream components stored locally as files in the given directory. In place of the remote data stream component OpenSCAP will attempt to use a file whose file name is equal to @name attribute of the uri element within the catalog element within the component-ref element in the data stream if such file exists.
909fca
 .RE
909fca
 .TP
909fca
 \fB\-\-skip-valid\fR, \fB\-\-skip-validation\fR
909fca
@@ -499,7 +499,7 @@ Do not validate input/output files.
909fca
 Allow download of remote components referenced from data stream.
909fca
 .TP
909fca
 \fB\-\-local-files DIRECTORY\fR
909fca
-Instead of downloading remote data stream components from the network, use a data stream component stored locally in a file. In place of the remote data stream component OpenSCAP will attempt to use a file whose file name is equal to @name attribute of the uri element within the catalog element within the component-ref element in the data stream if such file exists.
909fca
+Instead of downloading remote data stream components from the network, use data stream components stored locally as files in the given directory. In place of the remote data stream component OpenSCAP will attempt to use a file whose file name is equal to @name attribute of the uri element within the catalog element within the component-ref element in the data stream if such file exists.
909fca
 .RE
909fca
 
909fca
 .TP
909fca
@@ -663,7 +663,7 @@ Do not validate input/output files.
909fca
 Allow download of remote components referenced from data stream.
909fca
 .TP
909fca
 \fB\-\-local-files DIRECTORY\fR
909fca
-Instead of downloading remote data stream components from the network, use a data stream component stored locally in a file. In place of the remote data stream component OpenSCAP will attempt to use a file whose file name is equal to @name attribute of the uri element within the catalog element within the component-ref element in the data stream if such file exists.
909fca
+Instead of downloading remote data stream components from the network, use data stream components stored locally as files in the given directory. In place of the remote data stream component OpenSCAP will attempt to use a file whose file name is equal to @name attribute of the uri element within the catalog element within the component-ref element in the data stream if such file exists.
909fca
 .RE
909fca
 .TP
909fca
 .B \fBsds-validate\fR SOURCE_DS