|
|
8b65ee |
From 9b40767967e533bdb340ca4c91f2fd1192694820 Mon Sep 17 00:00:00 2001
|
|
|
8b65ee |
From: =?UTF-8?q?Jan=20=C4=8Cern=C3=BD?= <jcerny@redhat.com>
|
|
|
8b65ee |
Date: Wed, 2 Dec 2020 16:45:42 +0100
|
|
|
8b65ee |
Subject: [PATCH] Fix TestResult/benchmark/@href attribute
|
|
|
8b65ee |
|
|
|
8b65ee |
Make the href attribute an URI according to SCAP specification Section
|
|
|
8b65ee |
4.5. This should fix SCAPVAL error RES-253-2 which occured when
|
|
|
8b65ee |
validating ARFs by SCAPVAL. See #1629 for the problem description.
|
|
|
8b65ee |
|
|
|
8b65ee |
Also, it fixes a problem that xccdf_benchmark_item_clone didn't create
|
|
|
8b65ee |
the clusters_dict hash table.
|
|
|
8b65ee |
|
|
|
8b65ee |
The existing tests are extended to test this property, the
|
|
|
8b65ee |
function test_sds_external_xccdf has been splitted into 2 functions.
|
|
|
8b65ee |
|
|
|
8b65ee |
Fixes: #1629
|
|
|
8b65ee |
---
|
|
|
8b65ee |
src/DS/ds_sds_session.c | 18 ++++++++++++++++++
|
|
|
8b65ee |
src/DS/ds_sds_session_priv.h | 1 +
|
|
|
8b65ee |
src/DS/public/ds_sds_session.h | 8 ++++++++
|
|
|
8b65ee |
src/DS/sds.c | 3 +++
|
|
|
8b65ee |
src/XCCDF/item.c | 1 +
|
|
|
8b65ee |
src/XCCDF/xccdf_session.c | 25 ++++++++++++++++++++-----
|
|
|
8b65ee |
tests/DS/test_ds_misc.sh | 30 +++++++++++++++++++++++-------
|
|
|
8b65ee |
7 files changed, 74 insertions(+), 12 deletions(-)
|
|
|
8b65ee |
|
|
|
8b65ee |
diff --git a/src/DS/ds_sds_session.c b/src/DS/ds_sds_session.c
|
|
|
8b65ee |
index c03d3d593e..9120ee3243 100644
|
|
|
8b65ee |
--- a/src/DS/ds_sds_session.c
|
|
|
8b65ee |
+++ b/src/DS/ds_sds_session.c
|
|
|
8b65ee |
@@ -50,7 +50,9 @@ struct ds_sds_session {
|
|
|
8b65ee |
const char *target_dir; ///< Target directory for current split
|
|
|
8b65ee |
const char *datastream_id; ///< ID of selected datastream
|
|
|
8b65ee |
const char *checklist_id; ///< ID of selected checklist
|
|
|
8b65ee |
+ const char *checklist_uri; ///< URI of selected checklist
|
|
|
8b65ee |
struct oscap_htable *component_sources; ///< oscap_source for parsed components
|
|
|
8b65ee |
+ struct oscap_htable *component_uris; ///< maps component refs to component URIs
|
|
|
8b65ee |
bool fetch_remote_resources; ///< Allows loading of external components;
|
|
|
8b65ee |
download_progress_calllback_t progress; ///< Callback to report progress of download.
|
|
|
8b65ee |
};
|
|
|
8b65ee |
@@ -72,6 +74,7 @@ struct ds_sds_session *ds_sds_session_new_from_source(struct oscap_source *sourc
|
|
|
8b65ee |
struct ds_sds_session *sds_session = (struct ds_sds_session *) calloc(1, sizeof(struct ds_sds_session));
|
|
|
8b65ee |
sds_session->source = source;
|
|
|
8b65ee |
sds_session->component_sources = oscap_htable_new();
|
|
|
8b65ee |
+ sds_session->component_uris = oscap_htable_new();
|
|
|
8b65ee |
sds_session->progress = download_progress_empty_calllback;
|
|
|
8b65ee |
return sds_session;
|
|
|
8b65ee |
}
|
|
|
8b65ee |
@@ -84,6 +87,7 @@ void ds_sds_session_free(struct ds_sds_session *sds_session)
|
|
|
8b65ee |
oscap_acquire_cleanup_dir(&(sds_session->temp_dir));
|
|
|
8b65ee |
}
|
|
|
8b65ee |
oscap_htable_free(sds_session->component_sources, (oscap_destruct_func) oscap_source_free);
|
|
|
8b65ee |
+ oscap_htable_free(sds_session->component_uris, (oscap_destruct_func) free);
|
|
|
8b65ee |
free(sds_session);
|
|
|
8b65ee |
}
|
|
|
8b65ee |
}
|
|
|
8b65ee |
@@ -91,10 +95,13 @@ void ds_sds_session_free(struct ds_sds_session *sds_session)
|
|
|
8b65ee |
void ds_sds_session_reset(struct ds_sds_session *session)
|
|
|
8b65ee |
{
|
|
|
8b65ee |
session->checklist_id = NULL;
|
|
|
8b65ee |
+ session->checklist_uri = NULL;
|
|
|
8b65ee |
session->datastream_id = NULL;
|
|
|
8b65ee |
session->target_dir = NULL;
|
|
|
8b65ee |
oscap_htable_free(session->component_sources, (oscap_destruct_func) oscap_source_free);
|
|
|
8b65ee |
session->component_sources = oscap_htable_new();
|
|
|
8b65ee |
+ oscap_htable_free(session->component_uris, (oscap_destruct_func) free);
|
|
|
8b65ee |
+ session->component_uris = oscap_htable_new();
|
|
|
8b65ee |
}
|
|
|
8b65ee |
|
|
|
8b65ee |
struct ds_sds_index *ds_sds_session_get_sds_idx(struct ds_sds_session *session)
|
|
|
8b65ee |
@@ -163,11 +170,21 @@ const char *ds_sds_session_get_checklist_id(const struct ds_sds_session *session
|
|
|
8b65ee |
return session->checklist_id;
|
|
|
8b65ee |
}
|
|
|
8b65ee |
|
|
|
8b65ee |
+const char *ds_sds_session_get_checklist_uri(const struct ds_sds_session *session)
|
|
|
8b65ee |
+{
|
|
|
8b65ee |
+ return session->checklist_uri;
|
|
|
8b65ee |
+}
|
|
|
8b65ee |
+
|
|
|
8b65ee |
struct oscap_htable *ds_sds_session_get_component_sources(struct ds_sds_session *session)
|
|
|
8b65ee |
{
|
|
|
8b65ee |
return session->component_sources;
|
|
|
8b65ee |
}
|
|
|
8b65ee |
|
|
|
8b65ee |
+struct oscap_htable *ds_sds_session_get_component_uris(struct ds_sds_session *session)
|
|
|
8b65ee |
+{
|
|
|
8b65ee |
+ return session->component_uris;
|
|
|
8b65ee |
+}
|
|
|
8b65ee |
+
|
|
|
8b65ee |
const char *ds_sds_session_get_readable_origin(const struct ds_sds_session *session)
|
|
|
8b65ee |
{
|
|
|
8b65ee |
if (session->source == NULL)
|
|
|
8b65ee |
@@ -210,6 +227,7 @@ struct oscap_source *ds_sds_session_select_checklist(struct ds_sds_session *sess
|
|
|
8b65ee |
oscap_seterr(OSCAP_EFAMILY_OSCAP, "Could not extract %s with all dependencies from datastream.", session->checklist_id);
|
|
|
8b65ee |
return NULL;
|
|
|
8b65ee |
}
|
|
|
8b65ee |
+ session->checklist_uri = oscap_htable_get(session->component_uris, session->checklist_id);
|
|
|
8b65ee |
struct oscap_source *xccdf = oscap_htable_get(session->component_sources, session->checklist_id);
|
|
|
8b65ee |
if (xccdf == NULL) {
|
|
|
8b65ee |
oscap_seterr(OSCAP_EFAMILY_OSCAP, "Internal error: Could not acquire handle to '%s' source.", session->checklist_id);
|
|
|
8b65ee |
diff --git a/src/DS/ds_sds_session_priv.h b/src/DS/ds_sds_session_priv.h
|
|
|
8b65ee |
index 4aa559ebb4..f58231dc48 100644
|
|
|
8b65ee |
--- a/src/DS/ds_sds_session_priv.h
|
|
|
8b65ee |
+++ b/src/DS/ds_sds_session_priv.h
|
|
|
8b65ee |
@@ -37,6 +37,7 @@ xmlDoc *ds_sds_session_get_xmlDoc(struct ds_sds_session *session);
|
|
|
8b65ee |
int ds_sds_session_register_component_source(struct ds_sds_session *session, const char *relative_filepath, struct oscap_source *component);
|
|
|
8b65ee |
const char *ds_sds_session_get_target_dir(struct ds_sds_session *session);
|
|
|
8b65ee |
struct oscap_htable *ds_sds_session_get_component_sources(struct ds_sds_session *session);
|
|
|
8b65ee |
+struct oscap_htable *ds_sds_session_get_component_uris(struct ds_sds_session *session);
|
|
|
8b65ee |
const char *ds_sds_session_get_readable_origin(const struct ds_sds_session *session);
|
|
|
8b65ee |
bool ds_sds_session_fetch_remote_resources(struct ds_sds_session *session);
|
|
|
8b65ee |
download_progress_calllback_t ds_sds_session_remote_resources_progress(struct ds_sds_session *session);
|
|
|
8b65ee |
diff --git a/src/DS/public/ds_sds_session.h b/src/DS/public/ds_sds_session.h
|
|
|
8b65ee |
index 1ce692ce21..20a85146cc 100644
|
|
|
8b65ee |
--- a/src/DS/public/ds_sds_session.h
|
|
|
8b65ee |
+++ b/src/DS/public/ds_sds_session.h
|
|
|
8b65ee |
@@ -119,6 +119,14 @@ const char *ds_sds_session_get_datastream_id(const struct ds_sds_sessi
|
|
|
8b65ee |
*/
|
|
|
8b65ee |
const char *ds_sds_session_get_checklist_id(const struct ds_sds_session *session);
|
|
|
8b65ee |
|
|
|
8b65ee |
+/**
|
|
|
8b65ee |
+ * Return URI of currently selected component representing XCCDF within the DataStream
|
|
|
8b65ee |
+ * @memberof ds_sds_session
|
|
|
8b65ee |
+ * @param session The Source DataStream session
|
|
|
8b65ee |
+ * @returns URI of selected component or NULL
|
|
|
8b65ee |
+ */
|
|
|
8b65ee |
+const char *ds_sds_session_get_checklist_uri(const struct ds_sds_session *session);
|
|
|
8b65ee |
+
|
|
|
8b65ee |
/**
|
|
|
8b65ee |
* Get component from Source DataStream by its href. This assumes that the component
|
|
|
8b65ee |
* has been already cached by the session. You can cache component or its dependencies
|
|
|
8b65ee |
diff --git a/src/DS/sds.c b/src/DS/sds.c
|
|
|
8b65ee |
index b546ed3e65..20c683a7aa 100644
|
|
|
8b65ee |
--- a/src/DS/sds.c
|
|
|
8b65ee |
+++ b/src/DS/sds.c
|
|
|
8b65ee |
@@ -450,7 +450,10 @@ int ds_sds_dump_component_ref_as(const xmlNodePtr component_ref, struct ds_sds_s
|
|
|
8b65ee |
|
|
|
8b65ee |
char* component_id = NULL;
|
|
|
8b65ee |
|
|
|
8b65ee |
+ // make a copy of xlink_href because ds_sds_dump_component_by_href modifies its second argument
|
|
|
8b65ee |
+ char *xlink_href_copy = oscap_strdup(xlink_href);
|
|
|
8b65ee |
int ret = ds_sds_dump_component_by_href(session, xlink_href, target_filename_dirname, relative_filepath, cref_id, &component_id);
|
|
|
8b65ee |
+ oscap_htable_add(ds_sds_session_get_component_uris(session), cref_id, xlink_href_copy);
|
|
|
8b65ee |
|
|
|
8b65ee |
xmlFree(xlink_href);
|
|
|
8b65ee |
xmlFree(cref_id);
|
|
|
8b65ee |
diff --git a/src/XCCDF/item.c b/src/XCCDF/item.c
|
|
|
8b65ee |
index 3657fb461a..295e4a7f00 100644
|
|
|
8b65ee |
--- a/src/XCCDF/item.c
|
|
|
8b65ee |
+++ b/src/XCCDF/item.c
|
|
|
8b65ee |
@@ -1155,6 +1155,7 @@ struct xccdf_benchmark_item * xccdf_benchmark_item_clone(struct xccdf_item *pare
|
|
|
8b65ee |
clone->items_dict = oscap_htable_new();
|
|
|
8b65ee |
clone->profiles_dict = oscap_htable_new();
|
|
|
8b65ee |
clone->results_dict = oscap_htable_new();
|
|
|
8b65ee |
+ clone->clusters_dict = oscap_htable_new();
|
|
|
8b65ee |
clone->notices = oscap_list_clone(item->notices, (oscap_clone_func) xccdf_notice_clone);
|
|
|
8b65ee |
clone->plain_texts = oscap_list_clone(item->plain_texts, (oscap_clone_func) xccdf_plain_text_clone);
|
|
|
8b65ee |
|
|
|
8b65ee |
diff --git a/src/XCCDF/xccdf_session.c b/src/XCCDF/xccdf_session.c
|
|
|
8b65ee |
index f1b8379591..c88d90be05 100644
|
|
|
8b65ee |
--- a/src/XCCDF/xccdf_session.c
|
|
|
8b65ee |
+++ b/src/XCCDF/xccdf_session.c
|
|
|
8b65ee |
@@ -1374,21 +1374,28 @@ static int _build_xccdf_result_source(struct xccdf_session *session)
|
|
|
8b65ee |
oscap_seterr(OSCAP_EFAMILY_OSCAP, "No XCCDF results to export.");
|
|
|
8b65ee |
return 1;
|
|
|
8b65ee |
}
|
|
|
8b65ee |
- struct xccdf_result* cloned_result = xccdf_result_clone(session->xccdf.result);
|
|
|
8b65ee |
- xccdf_benchmark_add_result(benchmark, cloned_result);
|
|
|
8b65ee |
- session->xccdf.result_source = xccdf_benchmark_export_source(benchmark, session->export.xccdf_file);
|
|
|
8b65ee |
|
|
|
8b65ee |
if (session->export.xccdf_file != NULL) {
|
|
|
8b65ee |
+ struct xccdf_benchmark *cloned_benchmark = xccdf_benchmark_clone(benchmark);
|
|
|
8b65ee |
+ struct xccdf_result *cloned_result = xccdf_result_clone(session->xccdf.result);
|
|
|
8b65ee |
+ xccdf_benchmark_add_result(cloned_benchmark, cloned_result);
|
|
|
8b65ee |
+ struct oscap_source *xccdf_result_source = xccdf_benchmark_export_source(cloned_benchmark, session->export.xccdf_file);
|
|
|
8b65ee |
+ // cloned_result is freed during xccdf_benchmark_free
|
|
|
8b65ee |
+ xccdf_benchmark_free(cloned_benchmark);
|
|
|
8b65ee |
// Export XCCDF result file only when explicitly requested
|
|
|
8b65ee |
- if (oscap_source_save_as(session->xccdf.result_source, NULL) != 0) {
|
|
|
8b65ee |
+ if (oscap_source_save_as(xccdf_result_source, NULL) != 0) {
|
|
|
8b65ee |
oscap_seterr(OSCAP_EFAMILY_OSCAP, "Could not save file: %s",
|
|
|
8b65ee |
- oscap_source_readable_origin(session->xccdf.result_source));
|
|
|
8b65ee |
+ oscap_source_readable_origin(xccdf_result_source));
|
|
|
8b65ee |
+ oscap_source_free(xccdf_result_source);
|
|
|
8b65ee |
return -1;
|
|
|
8b65ee |
}
|
|
|
8b65ee |
+ oscap_source_free(xccdf_result_source);
|
|
|
8b65ee |
}
|
|
|
8b65ee |
|
|
|
8b65ee |
if (session->export.xccdf_stig_viewer_file != NULL) {
|
|
|
8b65ee |
+ struct xccdf_result *cloned_result = xccdf_result_clone(session->xccdf.result);
|
|
|
8b65ee |
struct oscap_source * stig_result = xccdf_result_stig_viewer_export_source(cloned_result, session->export.xccdf_stig_viewer_file);
|
|
|
8b65ee |
+ xccdf_result_free(cloned_result);
|
|
|
8b65ee |
if (oscap_source_save_as(stig_result, NULL) != 0) {
|
|
|
8b65ee |
oscap_seterr(OSCAP_EFAMILY_OSCAP, "Could not save file: %s",
|
|
|
8b65ee |
oscap_source_readable_origin(stig_result));
|
|
|
8b65ee |
@@ -1398,6 +1405,14 @@ static int _build_xccdf_result_source(struct xccdf_session *session)
|
|
|
8b65ee |
oscap_source_free(stig_result);
|
|
|
8b65ee |
}
|
|
|
8b65ee |
|
|
|
8b65ee |
+ struct xccdf_result *cloned_result = xccdf_result_clone(session->xccdf.result);
|
|
|
8b65ee |
+ if (xccdf_session_is_sds(session)) {
|
|
|
8b65ee |
+ struct ds_sds_session *sds_session = xccdf_session_get_ds_sds_session(session);
|
|
|
8b65ee |
+ const char *benchmark_uri = ds_sds_session_get_checklist_uri(sds_session);
|
|
|
8b65ee |
+ xccdf_result_set_benchmark_uri(cloned_result, benchmark_uri);
|
|
|
8b65ee |
+ }
|
|
|
8b65ee |
+ xccdf_benchmark_add_result(benchmark, cloned_result);
|
|
|
8b65ee |
+ session->xccdf.result_source = xccdf_benchmark_export_source(benchmark, session->export.xccdf_file);
|
|
|
8b65ee |
/* validate XCCDF Results */
|
|
|
8b65ee |
if (session->validate && session->full_validation) {
|
|
|
8b65ee |
if (oscap_source_validate(session->xccdf.result_source, _reporter, NULL)) {
|