From ff5d42dc9164c71d36bb7a3b21d961773d3e22d6 Mon Sep 17 00:00:00 2001 From: Martin Preisler 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 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 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 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;