From ff5d42dc9164c71d36bb7a3b21d961773d3e22d6 Mon Sep 17 00:00:00 2001
From: Martin Preisler <mpreisle@redhat.com>
Date: Mon, 17 Sep 2018 08:09:45 -0400
Subject: [PATCH 1/4] Introduce a "virtual" "(all)" profile that will select
all groups and all rules
This is useful for testing and debugging. It will use default values but
will select everything in the benchmark.
---
src/XCCDF_POLICY/xccdf_policy.c | 6 ++--
src/XCCDF_POLICY/xccdf_policy_model.c | 52 +++++++++++++++++++++++++--
2 files changed, 53 insertions(+), 5 deletions(-)
diff --git a/src/XCCDF_POLICY/xccdf_policy.c b/src/XCCDF_POLICY/xccdf_policy.c
index b984d0273..c35fa8dfd 100644
--- a/src/XCCDF_POLICY/xccdf_policy.c
+++ b/src/XCCDF_POLICY/xccdf_policy.c
@@ -2283,8 +2283,10 @@ void xccdf_policy_free(struct xccdf_policy * policy) {
/* A policy which is set to use default profile has its profile member set to NULL,
* check it so we don't try to get the ID from a NULL profile.
* */
- if (policy->profile && xccdf_profile_get_id(policy->profile) == NULL)
- /* If ID of policy's profile is NULL then this
+ if (policy->profile && (
+ (xccdf_profile_get_id(policy->profile) == NULL) ||
+ (strcmp(xccdf_profile_get_id(policy->profile), "(all)") == 0)))
+ /* If ID of policy's profile is NULL or "(all)" then this
* profile is created by Policy layer and need
* to be freed
*/
diff --git a/src/XCCDF_POLICY/xccdf_policy_model.c b/src/XCCDF_POLICY/xccdf_policy_model.c
index 2ec913bbd..37187bc92 100644
--- a/src/XCCDF_POLICY/xccdf_policy_model.c
+++ b/src/XCCDF_POLICY/xccdf_policy_model.c
@@ -31,6 +31,7 @@
#include "xccdf_policy_model_priv.h"
#include "xccdf_policy_priv.h"
#include "XCCDF/item.h"
+#include "XCCDF/helpers.h"
struct xccdf_policy *xccdf_policy_model_get_existing_policy_by_id(struct xccdf_policy_model *policy_model, const char *profile_id)
{
@@ -46,6 +47,38 @@ struct xccdf_policy *xccdf_policy_model_get_existing_policy_by_id(struct xccdf_p
return NULL;
}
+static inline void _add_selectors_for_all_items(struct xccdf_profile *profile, struct xccdf_item *item)
+{
+ struct xccdf_item_iterator *children = NULL;
+ if (xccdf_item_get_type(item) == XCCDF_BENCHMARK) {
+ children = xccdf_benchmark_get_content(XBENCHMARK(item));
+ }
+ else if (xccdf_item_get_type(item) == XCCDF_GROUP) {
+ children = xccdf_group_get_content(XGROUP(item));
+
+ struct xccdf_select *select = xccdf_select_new();
+ xccdf_select_set_item(select, xccdf_item_get_id(item));
+ xccdf_select_set_selected(select, true);
+ xccdf_profile_add_select(profile, select);
+ printf("g: %s\n", xccdf_item_get_id(item));
+ }
+ else if (xccdf_item_get_type(item) == XCCDF_RULE) {
+ struct xccdf_select *select = xccdf_select_new();
+ xccdf_select_set_item(select, xccdf_item_get_id(item));
+ xccdf_select_set_selected(select, true);
+ xccdf_profile_add_select(profile, select);
+ printf("r: %s\n", xccdf_item_get_id(item));
+ }
+
+ if (children) {
+ while (xccdf_item_iterator_has_more(children)) {
+ struct xccdf_item *current = xccdf_item_iterator_next(children);
+ _add_selectors_for_all_items(profile, current);
+ }
+ xccdf_item_iterator_free(children);
+ }
+}
+
struct xccdf_policy *xccdf_policy_model_create_policy_by_id(struct xccdf_policy_model *policy_model, const char *id)
{
struct xccdf_profile *profile = NULL;
@@ -71,9 +104,22 @@ struct xccdf_policy *xccdf_policy_model_create_policy_by_id(struct xccdf_policy_
assert(benchmark != NULL);
return NULL;
}
- profile = xccdf_benchmark_get_profile_by_id(benchmark, id);
- if (profile == NULL)
- return NULL;
+
+ if (strcmp(id, "(all)") == 0) {
+ profile = xccdf_profile_new();
+ xccdf_profile_set_id(profile, "(all)");
+ struct oscap_text *title = oscap_text_new();
+ oscap_text_set_text(title, "(all) profile (all rules selected)");
+ oscap_text_set_lang(title, "en");
+ xccdf_profile_add_title(profile, title);
+
+ _add_selectors_for_all_items(profile, XITEM(benchmark));
+ }
+ else {
+ profile = xccdf_benchmark_get_profile_by_id(benchmark, id);
+ if (profile == NULL)
+ return NULL;
+ }
}
}
From 884e8558dac6f8442e81a081f261cbd114931c31 Mon Sep 17 00:00:00 2001
From: Martin Preisler <mpreisle@redhat.com>
Date: Mon, 17 Sep 2018 09:11:37 -0400
Subject: [PATCH 2/4] Comments, refactoring of the (all) profile feature
---
src/XCCDF_POLICY/xccdf_policy_model.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/src/XCCDF_POLICY/xccdf_policy_model.c b/src/XCCDF_POLICY/xccdf_policy_model.c
index 37187bc92..552229947 100644
--- a/src/XCCDF_POLICY/xccdf_policy_model.c
+++ b/src/XCCDF_POLICY/xccdf_policy_model.c
@@ -47,7 +47,7 @@ struct xccdf_policy *xccdf_policy_model_get_existing_policy_by_id(struct xccdf_p
return NULL;
}
-static inline void _add_selectors_for_all_items(struct xccdf_profile *profile, struct xccdf_item *item)
+static void _add_selectors_for_all_xccdf_items(struct xccdf_profile *profile, struct xccdf_item *item)
{
struct xccdf_item_iterator *children = NULL;
if (xccdf_item_get_type(item) == XCCDF_BENCHMARK) {
@@ -55,25 +55,21 @@ static inline void _add_selectors_for_all_items(struct xccdf_profile *profile, s
}
else if (xccdf_item_get_type(item) == XCCDF_GROUP) {
children = xccdf_group_get_content(XGROUP(item));
-
- struct xccdf_select *select = xccdf_select_new();
- xccdf_select_set_item(select, xccdf_item_get_id(item));
- xccdf_select_set_selected(select, true);
- xccdf_profile_add_select(profile, select);
- printf("g: %s\n", xccdf_item_get_id(item));
}
- else if (xccdf_item_get_type(item) == XCCDF_RULE) {
+
+ if (xccdf_item_get_type(item) == XCCDF_RULE ||
+ xccdf_item_get_type(item) == XCCDF_GROUP)
+ {
struct xccdf_select *select = xccdf_select_new();
xccdf_select_set_item(select, xccdf_item_get_id(item));
xccdf_select_set_selected(select, true);
xccdf_profile_add_select(profile, select);
- printf("r: %s\n", xccdf_item_get_id(item));
}
if (children) {
while (xccdf_item_iterator_has_more(children)) {
struct xccdf_item *current = xccdf_item_iterator_next(children);
- _add_selectors_for_all_items(profile, current);
+ _add_selectors_for_all_xccdf_items(profile, current);
}
xccdf_item_iterator_free(children);
}
@@ -89,6 +85,9 @@ struct xccdf_policy *xccdf_policy_model_create_policy_by_id(struct xccdf_policy_
profile = xccdf_tailoring_get_profile_by_id(tailoring, id);
}
+ // The (default) and (all) profiles are de-facto owned by the xccdf_policy
+ // and will be freed by it when it's freed. See xccdf_policy_free.
+
if (!profile) {
if (id == NULL) {
profile = xccdf_profile_new();
@@ -113,7 +112,7 @@ struct xccdf_policy *xccdf_policy_model_create_policy_by_id(struct xccdf_policy_
oscap_text_set_lang(title, "en");
xccdf_profile_add_title(profile, title);
- _add_selectors_for_all_items(profile, XITEM(benchmark));
+ _add_selectors_for_all_xccdf_items(profile, XITEM(benchmark));
}
else {
profile = xccdf_benchmark_get_profile_by_id(benchmark, id);
From 6496649d6aaf8ccea3c5560f2492f294645378eb Mon Sep 17 00:00:00 2001
From: Martin Preisler <mpreisle@redhat.com>
Date: Mon, 17 Sep 2018 09:13:24 -0400
Subject: [PATCH 3/4] Mention (all) profile in the man page
---
utils/oscap.8 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/utils/oscap.8 b/utils/oscap.8
index 5af83ec3b..25724155c 100644
--- a/utils/oscap.8
+++ b/utils/oscap.8
@@ -83,7 +83,7 @@ You may specify OVAL Definition files as the last parameter, XCCDF evaluation wi
.TP
\fB\-\-profile PROFILE\fR
.RS
-Select a particular profile from XCCDF document.
+Select a particular profile from XCCDF document. If "(all)" is given a virtual profile that selects all groups and rules will be used.
.RE
.TP
\fB\-\-rule RULE\fR
From a7e1395ca912b375c4702250dfde6026e1c54d6c Mon Sep 17 00:00:00 2001
From: Martin Preisler <mpreisle@redhat.com>
Date: Tue, 18 Sep 2018 07:58:08 -0400
Subject: [PATCH 4/4] Fixed coding style issues
---
src/XCCDF_POLICY/xccdf_policy_model.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/src/XCCDF_POLICY/xccdf_policy_model.c b/src/XCCDF_POLICY/xccdf_policy_model.c
index 552229947..55f09fb03 100644
--- a/src/XCCDF_POLICY/xccdf_policy_model.c
+++ b/src/XCCDF_POLICY/xccdf_policy_model.c
@@ -52,8 +52,7 @@ static void _add_selectors_for_all_xccdf_items(struct xccdf_profile *profile, st
struct xccdf_item_iterator *children = NULL;
if (xccdf_item_get_type(item) == XCCDF_BENCHMARK) {
children = xccdf_benchmark_get_content(XBENCHMARK(item));
- }
- else if (xccdf_item_get_type(item) == XCCDF_GROUP) {
+ } else if (xccdf_item_get_type(item) == XCCDF_GROUP) {
children = xccdf_group_get_content(XGROUP(item));
}
@@ -96,8 +95,7 @@ struct xccdf_policy *xccdf_policy_model_create_policy_by_id(struct xccdf_policy_
oscap_text_set_text(title, "No profile (default benchmark)");
oscap_text_set_lang(title, "en");
xccdf_profile_add_title(profile, title);
- }
- else {
+ } else {
struct xccdf_benchmark *benchmark = xccdf_policy_model_get_benchmark(policy_model);
if (benchmark == NULL) {
assert(benchmark != NULL);
@@ -113,8 +111,7 @@ struct xccdf_policy *xccdf_policy_model_create_policy_by_id(struct xccdf_policy_
xccdf_profile_add_title(profile, title);
_add_selectors_for_all_xccdf_items(profile, XITEM(benchmark));
- }
- else {
+ } else {
profile = xccdf_benchmark_get_profile_by_id(benchmark, id);
if (profile == NULL)
return NULL;