diff --git a/docs/manual/manual.adoc b/docs/manual/manual.adoc index ab069a3708..a461482268 100644 --- a/docs/manual/manual.adoc +++ b/docs/manual/manual.adoc @@ -696,6 +696,34 @@ STIG by DISA. When evaluating a STIG provided by DISA using `oscap`, use the `scap-security-guide` content in STIG Viewer and evaluating `scap-security-guide` by oscap, use `--results` instead of `--stig-viewer`. +=== Checking for compliance with a particular requirement coverage + +A common theme is to check system status based on requirements of a particular policy. +OpenSCAP can select rules that are related to a specific requirement based on the references in the rules. + +1) List references that are supported in your scap content using the `oscap info --references` command. +This will list of available reference names and their URIs. +For example: + +---- +$ oscap info --references /usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml +... snip ... + References: + anssi: http://www.ssi.gouv.fr/administration/bonnes-pratiques/ + cis: https://www.cisecurity.org/benchmark/red_hat_linux/ + disa: https://public.cyber.mil/stigs/cci/ +... snip ... +---- + +2) Run the evaluation with the `--reference` option, using the name obtained in the previous step and the requirement ID, separated by a colon. +That will filter the list of rules so that only rules that have the given reference ID assigned would be evaluated. +For example: + +---- +$ oscap xccdf eval --profile cis --reference cis:3.3.2 /usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml +---- + +NOTE: If the `oscap info --references` command doesn't list any reference names in the `References` section of its output, it means that the provided SCAP content doesn't support this feature. == Remediating system diff --git a/src/XCCDF/public/xccdf_session.h b/src/XCCDF/public/xccdf_session.h index 8efa1d16d7..fbadeccd2e 100644 --- a/src/XCCDF/public/xccdf_session.h +++ b/src/XCCDF/public/xccdf_session.h @@ -644,6 +644,13 @@ OSCAP_API int xccdf_session_generate_guide(struct xccdf_session *session, const */ OSCAP_API int xccdf_session_export_all(struct xccdf_session *session); +/** + * Set reference filter to the XCCDF session. If this filter is set, + * the XCCDF session will evaluate only rules that conform to the filter. + * @param session XCCDF session + * @param reference_filter a string in a form "key:identifier" + */ +OSCAP_API void xccdf_session_set_reference_filter(struct xccdf_session *session, const char *reference_filter); /// @} /// @} #endif diff --git a/src/XCCDF/xccdf_session.c b/src/XCCDF/xccdf_session.c index c5bc6d6947..5ec127be68 100644 --- a/src/XCCDF/xccdf_session.c +++ b/src/XCCDF/xccdf_session.c @@ -70,6 +70,7 @@ struct xccdf_session { const char *filename; ///< File name of SCAP (SDS or XCCDF) file for this session. struct oscap_list *rules; struct oscap_list *skip_rules; + const char *reference_parameter; struct oscap_source *source; ///< Main source assigned with the main file (SDS or XCCDF) char *temp_dir; ///< Temp directory used for decomposed component files. struct { @@ -1384,6 +1385,9 @@ int xccdf_session_evaluate(struct xccdf_session *session) } oscap_iterator_free(sit); + if (session->reference_parameter) { + xccdf_policy_set_reference_filter(policy, session->reference_parameter); + } session->xccdf.result = xccdf_policy_evaluate(policy); if (session->xccdf.result == NULL) return 1; @@ -2059,3 +2063,8 @@ int xccdf_session_export_all(struct xccdf_session *session) oscap_source_free(arf_source); return ret; } + +void xccdf_session_set_reference_filter(struct xccdf_session *session, const char *reference_filter) +{ + session->reference_parameter = reference_filter; +} diff --git a/src/XCCDF_POLICY/xccdf_policy.c b/src/XCCDF_POLICY/xccdf_policy.c index c37be64b17..f12b046baf 100644 --- a/src/XCCDF_POLICY/xccdf_policy.c +++ b/src/XCCDF_POLICY/xccdf_policy.c @@ -36,6 +36,7 @@ #include "xccdf_policy_engine_priv.h" #include "reporter_priv.h" #include "public/xccdf_policy.h" +#include "public/xccdf_session.h" #include "public/xccdf_benchmark.h" #include "public/oscap_text.h" @@ -1031,6 +1032,25 @@ static void _warn_about_required_rules(const struct xccdf_policy *policy, const oscap_stringlist_iterator_free(requires_it); } +static bool _matches_references(struct xccdf_policy *policy, const struct xccdf_rule *rule) +{ + if (!policy->reference_filter.active) { + return true; + } + bool matched = false; + struct oscap_reference_iterator *references = xccdf_item_get_references((struct xccdf_item *)rule); + while (oscap_reference_iterator_has_more(references) && !matched) { + struct oscap_reference *ref = oscap_reference_iterator_next(references); + const char *href = oscap_reference_get_href(ref); + const char *title = oscap_reference_get_title(ref); + if (!strcmp(href, policy->reference_filter.href) && !strcmp(title, policy->reference_filter.title)) { + matched = true; + } + } + oscap_reference_iterator_free(references); + return matched; +} + /** * Evaluate given check which is immediate child of the rule. * A possibe child checks will be evaluated by xccdf_policy_check_evaluate. @@ -1074,6 +1094,10 @@ _xccdf_policy_rule_evaluate(struct xccdf_policy * policy, const struct xccdf_rul } } + if (!_matches_references(policy, rule)) { + return _xccdf_policy_report_rule_result(policy, result, rule, NULL, XCCDF_RESULT_NOT_SELECTED, NULL); + } + /* Otherwise start reporting */ report = xccdf_policy_report_cb(policy, XCCDF_POLICY_OUTCB_START, (void *) rule); if (report) @@ -1882,6 +1906,10 @@ struct xccdf_policy * xccdf_policy_new(struct xccdf_policy_model * model, struct policy->refine_rules_internal = oscap_htable_new(); policy->model = model; + policy->reference_filter.active = false; + policy->reference_filter.href = NULL; + policy->reference_filter.title = NULL; + benchmark = xccdf_policy_model_get_benchmark(model); if (profile) { @@ -2253,6 +2281,48 @@ void xccdf_policy_model_free(struct xccdf_policy_model * model) { free(model); } +static const char *_find_reference_uri_by_key(struct xccdf_benchmark *benchmark, const char *key) +{ + const char *uri = NULL; + struct oscap_reference_iterator *benchmark_references = xccdf_item_get_references((struct xccdf_item *)benchmark); + while (oscap_reference_iterator_has_more(benchmark_references)) { + struct oscap_reference *ref = oscap_reference_iterator_next(benchmark_references); + const char *title = oscap_reference_get_title(ref); + if (!strcmp(key, title)) { + uri = oscap_reference_get_href(ref); + break; + } + } + oscap_reference_iterator_free(benchmark_references); + return uri; +} + +void xccdf_policy_set_reference_filter(struct xccdf_policy *policy, const char *reference_parameter) +{ + if (!reference_parameter) { + return; + } + char *reference_parameter_dup = strdup(reference_parameter); + char **split = oscap_split(reference_parameter_dup, ":"); + struct xccdf_benchmark *benchmark = policy->model->benchmark; + char *key = split[0]; + const char *uri = _find_reference_uri_by_key(benchmark, key); + if (!uri) { + oscap_seterr(OSCAP_EFAMILY_OSCAP, "Reference type '%s' isn't available in this benchmark", key); + goto cleanup; + } + char *title = split[1]; + if (!title) { + oscap_seterr(OSCAP_EFAMILY_OSCAP, "Reference identifier hasn't been provided"); + goto cleanup; + } + policy->reference_filter.active = true; + policy->reference_filter.href = strdup(uri); + policy->reference_filter.title = strdup(title); +cleanup: + free(split); + free(reference_parameter_dup); +} void xccdf_policy_free(struct xccdf_policy * policy) { @@ -2278,6 +2348,8 @@ void xccdf_policy_free(struct xccdf_policy * policy) { oscap_htable_free0(policy->selected_internal); oscap_htable_free0(policy->selected_final); oscap_htable_free(policy->refine_rules_internal, (oscap_destruct_func) xccdf_refine_rule_internal_free); + free(policy->reference_filter.href); + free(policy->reference_filter.title); free(policy); } diff --git a/src/XCCDF_POLICY/xccdf_policy_priv.h b/src/XCCDF_POLICY/xccdf_policy_priv.h index e5eb9ebd12..edfbe0c68f 100644 --- a/src/XCCDF_POLICY/xccdf_policy_priv.h +++ b/src/XCCDF_POLICY/xccdf_policy_priv.h @@ -72,6 +72,11 @@ struct xccdf_policy { struct oscap_htable *selected_final; /* The hash-table contains the latest refine-rule for specified item-id. */ struct oscap_htable *refine_rules_internal; + struct { + bool active; + char *href; + char *title; + } reference_filter; }; @@ -136,5 +141,6 @@ int xccdf_policy_report_cb(struct xccdf_policy *policy, const char *sysname, voi */ struct xccdf_benchmark *xccdf_policy_get_benchmark(const struct xccdf_policy *policy); +void xccdf_policy_set_reference_filter(struct xccdf_policy *policy, const char *reference_parameter); #endif diff --git a/tests/API/XCCDF/unittests/CMakeLists.txt b/tests/API/XCCDF/unittests/CMakeLists.txt index 95441b40e1..7a9b3b452c 100644 --- a/tests/API/XCCDF/unittests/CMakeLists.txt +++ b/tests/API/XCCDF/unittests/CMakeLists.txt @@ -109,3 +109,4 @@ add_oscap_test("test_results_hostname.sh") add_oscap_test("test_skip_rule.sh") add_oscap_test("test_no_newline_between_select_elements.sh") add_oscap_test("test_single_line_tailoring.sh") +add_oscap_test("test_reference.sh") diff --git a/tests/API/XCCDF/unittests/test_reference.sh b/tests/API/XCCDF/unittests/test_reference.sh new file mode 100755 index 0000000000..4c5a76ea03 --- /dev/null +++ b/tests/API/XCCDF/unittests/test_reference.sh @@ -0,0 +1,104 @@ +#!/usr/bin/env bash +. $builddir/tests/test_common.sh + +set -e +set -o pipefail + +result=$(mktemp -t ${name}.out.XXXXXX) +stderr=$(mktemp -t ${name}.out.XXXXXX) +stdout=$(mktemp -t ${name}.out.XXXXXX) + +ds="$srcdir/test_reference_ds.xml" +p1="xccdf_com.example.www_profile_P1" +r1="xccdf_com.example.www_rule_R1" +r2="xccdf_com.example.www_rule_R2" +r3="xccdf_com.example.www_rule_R3" +r4="xccdf_com.example.www_rule_R4" + +# Tests if references are correctly shown in oscap info output +$OSCAP info --references $ds > $stdout 2> $stderr +[ -f $stderr ]; [ ! -s $stderr ]; :> $stderr +grep -q "References:" $stdout +grep -q "animals: https://www.animals.com" $stdout +grep -q "fruit: https://www.fruit.com" $stdout +:> $stdout + +# Tests that all rules from profile P1 (profile contains only 4 rules) are +# evaluated when '--reference' option is not specified. +$OSCAP xccdf eval --results $result --profile $p1 $ds > $stdout 2> $stderr + +[ -f $stderr ]; [ ! -s $stderr ]; :> $stderr +assert_exists 1 "//rule-result[@idref=\"$r1\"]/result[text()=\"pass\"]" +assert_exists 1 "//rule-result[@idref=\"$r2\"]/result[text()=\"pass\"]" +assert_exists 1 "//rule-result[@idref=\"$r3\"]/result[text()=\"pass\"]" +assert_exists 1 "//rule-result[@idref=\"$r4\"]/result[text()=\"pass\"]" +:> $stdout +:> $result + +# Tests that rule R1 from profile P1 is evaluated when '--reference' option +# matches the rule R1. +$OSCAP xccdf eval --results $result --profile $p1 --reference "animals:3.14" $ds > $stdout 2> $stderr + +[ -f $stderr ]; [ ! -s $stderr ]; :> $stderr +assert_exists 1 "//rule-result[@idref=\"$r1\"]/result[text()=\"pass\"]" +assert_exists 1 "//rule-result[@idref=\"$r2\"]/result[text()=\"notselected\"]" +assert_exists 1 "//rule-result[@idref=\"$r3\"]/result[text()=\"notselected\"]" +assert_exists 1 "//rule-result[@idref=\"$r4\"]/result[text()=\"notselected\"]" +:> $stdout +:> $result + +# Tests that rule R1 from profile P1 is evaluated when '--reference' option +# matches the rule R1. This test uses a different reference key than the +# previous test. +$OSCAP xccdf eval --results $result --profile $p1 --reference "fruit:42.42" $ds > $stdout 2> $stderr + +[ -f $stderr ]; [ ! -s $stderr ]; :> $stderr +assert_exists 1 "//rule-result[@idref=\"$r1\"]/result[text()=\"pass\"]" +assert_exists 1 "//rule-result[@idref=\"$r2\"]/result[text()=\"notselected\"]" +assert_exists 1 "//rule-result[@idref=\"$r3\"]/result[text()=\"notselected\"]" +assert_exists 1 "//rule-result[@idref=\"$r4\"]/result[text()=\"notselected\"]" +:> $stdout +:> $result + +# Tests that only rules R2 and R3 from profile P1 are evaluated when +# '--reference' option matches the rule R2 and R3, both rules have +# the same reference item. +$OSCAP xccdf eval --results $result --profile $p1 --reference "animals:17.71.777" $ds > $stdout 2> $stderr + +[ -f $stderr ]; [ ! -s $stderr ]; :> $stderr +assert_exists 1 "//rule-result[@idref=\"$r1\"]/result[text()=\"notselected\"]" +assert_exists 1 "//rule-result[@idref=\"$r2\"]/result[text()=\"pass\"]" +assert_exists 1 "//rule-result[@idref=\"$r3\"]/result[text()=\"pass\"]" +assert_exists 1 "//rule-result[@idref=\"$r4\"]/result[text()=\"notselected\"]" +:> $stdout +:> $result + +# Tests that no rule from profile P1 is evaluated when '--reference' option +# doesn't match any reference in any rule. +$OSCAP xccdf eval --results $result --profile $p1 --reference "animals:99.66.33" $ds > $stdout 2> $stderr + +[ -f $stderr ]; [ ! -s $stderr ]; :> $stderr +assert_exists 1 "//rule-result[@idref=\"$r1\"]/result[text()=\"notselected\"]" +assert_exists 1 "//rule-result[@idref=\"$r2\"]/result[text()=\"notselected\"]" +assert_exists 1 "//rule-result[@idref=\"$r3\"]/result[text()=\"notselected\"]" +assert_exists 1 "//rule-result[@idref=\"$r4\"]/result[text()=\"notselected\"]" +:> $stdout +:> $result + +# Tests that when a wrong '--reference' option is provided OpenSCAP ignores it, +# evaluates all rules and prints a nice error messsage. +$OSCAP xccdf eval --results $result --profile $p1 --reference "aliens:XXX" $ds > $stdout 2> $stderr +grep -q "OpenSCAP Error: Reference type 'aliens' isn't available in this benchmark" $stderr +assert_exists 1 "//rule-result[@idref=\"$r1\"]/result[text()=\"pass\"]" +assert_exists 1 "//rule-result[@idref=\"$r2\"]/result[text()=\"pass\"]" +assert_exists 1 "//rule-result[@idref=\"$r3\"]/result[text()=\"pass\"]" +assert_exists 1 "//rule-result[@idref=\"$r4\"]/result[text()=\"pass\"]" +:> $stdout +:> $result + +# Tests that when a wrong '--reference' option with a valid name but missing +# identifier is provided OpenSCAP prints an errror message. +$OSCAP xccdf eval --results $result --profile $p1 --reference "animals" $ds > $stdout 2> $stderr || [[ $? -eq 1 ]] +grep -q "The --reference argument needs to be in form NAME:IDENTIFIER, using a colon as a separator." $stderr +:> $stdout +:> $result diff --git a/tests/API/XCCDF/unittests/test_reference_ds.xml b/tests/API/XCCDF/unittests/test_reference_ds.xml new file mode 100644 index 0000000000..c2bacf0704 --- /dev/null +++ b/tests/API/XCCDF/unittests/test_reference_ds.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + 5.11.2 + 2021-02-01T08:07:06+01:00 + + + + + PASS + pass + + + + + + + + + + + + + + oval:x:var:1 + + + + + 100 + + + + + + + accepted + Test Benchmark + Description + animals + fruit + 1.0 + + OpenSCAP + OpenSCAP + OpenSCAP + http://scap.nist.gov + + + xccdf_test_profile + This profile is for testing. + + + + + Rule R1 + Description + 3.14 + 42.42 + + + + + + Rule R2 + Description + 17.71.777 + 88888888 + + + + + + Rule R3 + Description + 17.71.777 + 666 + + + + + + Rule R4 + Description + + + + + + + diff --git a/utils/oscap-info.c b/utils/oscap-info.c index d47c816369..0f2f158766 100644 --- a/utils/oscap-info.c +++ b/utils/oscap-info.c @@ -65,7 +65,8 @@ struct oscap_module OSCAP_INFO_MODULE = { " --fetch-remote-resources - Download remote content referenced by data stream.\n" " --local-files - Use locally downloaded copies of remote resources stored in the given directory.\n" " --profile - Show info of the profile with the given ID.\n" - " --profiles - Show profiles from the input file in the : format, one line per profile.\n", + " --profiles - Show profiles from the input file in the <id>:<title> format, one line per profile.\n" + " --references - Show references available in the input benchmark", .opt_parser = getopt_info, .func = app_info }; @@ -255,14 +256,33 @@ static inline void _print_xccdf_testresults(struct xccdf_benchmark *bench, const xccdf_result_iterator_free(res_it); } -static inline void _print_xccdf_benchmark(struct xccdf_benchmark *bench, const char *prefix, void (*print_one_profile)(const struct xccdf_profile *, const char *)) +static void _print_references(struct xccdf_benchmark *bench, const char *prefix) +{ + struct oscap_reference_iterator *it = xccdf_item_get_references((struct xccdf_item *)bench); + printf("%sReferences:\n", prefix); + if (!oscap_reference_iterator_has_more(it)) { + printf("%s\tNone\n", prefix); + } + while (oscap_reference_iterator_has_more(it)) { + struct oscap_reference *ref = oscap_reference_iterator_next(it); + const char *title = oscap_reference_get_title(ref); + const char *href = oscap_reference_get_href(ref); + printf("%s\t%s: %s\n", prefix, title, href); + } + oscap_reference_iterator_free(it); +} + +static inline void _print_xccdf_benchmark(struct xccdf_benchmark *bench, const char *prefix, bool print_references) { _print_xccdf_status(xccdf_benchmark_get_status_current(bench), prefix); printf("%sResolved: %s\n", prefix, xccdf_benchmark_get_resolved(bench) ? "true" : "false"); struct xccdf_profile_iterator *prof_it = xccdf_benchmark_get_profiles(bench); - _print_xccdf_profiles(prof_it, prefix, print_one_profile); + _print_xccdf_profiles(prof_it, prefix, NULL); xccdf_profile_iterator_free(prof_it); + if (print_references) { + _print_references(bench, prefix); + } struct xccdf_policy_model *policy_model = xccdf_policy_model_new(bench); _print_xccdf_referenced_files(policy_model, prefix); @@ -308,7 +328,7 @@ static void _print_single_benchmark_one_profile(struct xccdf_benchmark *bench, c static void _print_single_benchmark_all(struct xccdf_benchmark *bench, const char *prefix) { - _print_xccdf_benchmark(bench, prefix, 0); + _print_xccdf_benchmark(bench, prefix, false); // bench is freed as a side-effect of the function above } @@ -462,7 +482,7 @@ static int app_info_single_ds_all(struct ds_stream_index_iterator* sds_it, struc ds_sds_session_free(session); return OSCAP_ERROR; } - _print_xccdf_benchmark(bench, prefix, 0); + _print_xccdf_benchmark(bench, prefix, action->references); // bench is freed as a side-effect of the function above } else if (oscap_source_get_scap_type(xccdf_source) == OSCAP_DOCUMENT_XCCDF_TAILORING) { _print_xccdf_tailoring(xccdf_source, prefix, 0); @@ -772,6 +792,7 @@ bool getopt_info(int argc, char **argv, struct oscap_action *action) {"local-files", required_argument, NULL, 'l'}, {"profile", required_argument, 0, 'p'}, {"profiles", no_argument, 0, 'n'}, + {"references", no_argument, 0, 'r'}, // end {0, 0, 0, 0} }; @@ -790,6 +811,9 @@ bool getopt_info(int argc, char **argv, struct oscap_action *action) case 'l': action->local_files = optarg; break; + case 'r': + action->references = 1; + break; default: return oscap_module_usage(action->module, stderr, NULL); } } diff --git a/utils/oscap-tool.h b/utils/oscap-tool.h index c0f11e45d3..509fe2a15b 100644 --- a/utils/oscap-tool.h +++ b/utils/oscap-tool.h @@ -176,6 +176,8 @@ struct oscap_action { char *verbosity_level; char *fix_type; char *local_files; + char *reference; + int references; }; int app_xslt(const char *infile, const char *xsltfile, const char *outfile, const char **params); diff --git a/utils/oscap-xccdf.c b/utils/oscap-xccdf.c index 746a3dfbec..2bcdac2e1c 100644 --- a/utils/oscap-xccdf.c +++ b/utils/oscap-xccdf.c @@ -153,6 +153,7 @@ static struct oscap_module XCCDF_EVAL = { " --profile <name> - The name of Profile to be evaluated.\n" " --rule <name> - The name of a single rule to be evaluated.\n" " --skip-rule <name> - The name of the rule to be skipped.\n" + " --reference <NAME:ID> - Evaluate only rules that have the given reference.\n" " --tailoring-file <file> - Use given XCCDF Tailoring file.\n" " --tailoring-id <component-id> - Use given DS component as XCCDF Tailoring file.\n" " --cpe <name> - Use given CPE dictionary or language (autodetected)\n" @@ -637,6 +638,13 @@ int app_evaluate_xccdf(const struct oscap_action *action) xccdf_session_skip_rule(session, rid); } oscap_string_iterator_free(sit); + if (action->reference) { + if (strchr(action->reference, ':') == NULL) { + fprintf(stderr, "The --reference argument needs to be in form NAME:IDENTIFIER, using a colon as a separator.\n"); + goto cleanup; + } + xccdf_session_set_reference_filter(session, action->reference); + } if (xccdf_session_load(session) != 0) goto cleanup; @@ -1200,7 +1208,8 @@ enum oval_opt { XCCDF_OPT_OUTPUT = 'o', XCCDF_OPT_RESULT_ID = 'i', XCCDF_OPT_FIX_TYPE, - XCCDF_OPT_LOCAL_FILES + XCCDF_OPT_LOCAL_FILES, + XCCDF_OPT_REFERENCE }; bool getopt_xccdf(int argc, char **argv, struct oscap_action *action) @@ -1234,6 +1243,7 @@ bool getopt_xccdf(int argc, char **argv, struct oscap_action *action) {"sce-template", required_argument, NULL, XCCDF_OPT_SCE_TEMPLATE}, {"fix-type", required_argument, NULL, XCCDF_OPT_FIX_TYPE}, {"local-files", required_argument, NULL, XCCDF_OPT_LOCAL_FILES}, + {"reference", required_argument, NULL, XCCDF_OPT_REFERENCE}, // flags {"force", no_argument, &action->force, 1}, {"oval-results", no_argument, &action->oval_results, 1}, @@ -1297,6 +1307,9 @@ bool getopt_xccdf(int argc, char **argv, struct oscap_action *action) case XCCDF_OPT_LOCAL_FILES: action->local_files = optarg; break; + case XCCDF_OPT_REFERENCE: + action->reference = optarg; + break; case 0: break; default: return oscap_module_usage(action->module, stderr, NULL); } diff --git a/utils/oscap.8 b/utils/oscap.8 index 52b993f6bf..09da46d008 100644 --- a/utils/oscap.8 +++ b/utils/oscap.8 @@ -86,6 +86,11 @@ Show info of the profile with the given ID. .RS Show profiles from the input file in the <id>:<title> format, one line per profile. .RE +.TP +\fB\-\-references\fR +.RS +Show list of references available in each benchmark. +.RE .SH XCCDF OPERATIONS .TP @@ -116,6 +121,12 @@ Select a particular rule from XCCDF document. Only this rule will be evaluated. Skip a particular rule from XCCDF document. This option can be used multiple times to skip multiple rules at once. .RE .TP +\fB\-\-reference NAME:IDENTIFIER\fR +.RS +Evaluate rules matching the given reference. This option can be used to check for evaluating compliance with a particular policy requirement. Rules that match the reference will be evaluated, other rules will be skipped and a result of notselected will be returned. The argument needs to be provided in the form NAME:IDENTIFIER (colon is a separator), where NAME is the reference name used as a text of xccdf:reference elements that are child of xccdf:Benchmark element and IDENTIFIER is a text of xccdf:reference element that is child of a particular xccdf:Rule element which has the same @href value as the xccdf:reference element of the NAME value. This feature requires SCAP content to be formed in the aforementioned way. For example: --reference "cis:4.1.3.19", --reference "anssi:BP28(R29)" +List of references available in the given benchmark can be obtained by running the oscap info --references command. +.RE +.TP \fB\-\-tailoring-file TAILORING_FILE\fR .RS Use given file for XCCDF tailoring. Select profile from tailoring file to apply using --profile. If both --tailoring-file and --tailoring-id are specified, --tailoring-file takes priority.