Skip to content

Commit dff5eeb

Browse files
committed
Fix tailoring processing
This commit fixes processing of tailoring files in oscap info module options `--list-rules` and `--list-vars`. It fixes these situations: 1. tailoring points to a file using an URI with `file://` prefix 2. tailoring points to a SCAP source data stream
1 parent 698dece commit dff5eeb

File tree

5 files changed

+145
-24
lines changed

5 files changed

+145
-24
lines changed

tests/oscap_info_profiles/test_list_rules.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,34 @@ grep -q "xccdf_com.example.www_rule_R2" $stdout
5151
[[ "$(wc -l < $stdout)" -eq 2 ]]
5252
:> $stdout
5353

54+
# Test 5: --list-rules with tailoring referencing SDS via file: prefix + cref
55+
temp_dir="$(mktemp -d)"
56+
cp "$srcdir/test_reference_ds.xml" $temp_dir
57+
tailoring_sds="test_tailoring_file_sds_cref.xml"
58+
sed "s;TEMP_DIRECTORY_PLACEHOLDER;$temp_dir;" "$srcdir/$tailoring_sds" > "$temp_dir/$tailoring_sds"
59+
$OSCAP info --profile $tp --list-rules "$temp_dir/$tailoring_sds" > $stdout 2> $stderr
60+
[[ -f $stderr ]]; [[ ! -s $stderr ]]; :> $stderr
61+
grep -q "xccdf_com.example.www_rule_R1" $stdout
62+
grep -q "xccdf_com.example.www_rule_R2" $stdout
63+
! grep -q "xccdf_com.example.www_rule_R3" $stdout
64+
! grep -q "xccdf_com.example.www_rule_R4" $stdout
65+
[[ "$(wc -l < $stdout)" -eq 2 ]]
66+
:> $stdout
67+
rm -rf "$temp_dir"
68+
69+
# Test 6: --list-rules with tailoring referencing SDS via file: prefix, no cref
70+
temp_dir="$(mktemp -d)"
71+
cp "$srcdir/test_reference_ds.xml" $temp_dir
72+
tailoring_sds_nf="test_tailoring_file_sds.xml"
73+
sed "s;TEMP_DIRECTORY_PLACEHOLDER;$temp_dir;" "$srcdir/$tailoring_sds_nf" > "$temp_dir/$tailoring_sds_nf"
74+
$OSCAP info --profile $tp --list-rules "$temp_dir/$tailoring_sds_nf" > $stdout 2> $stderr
75+
[[ -f $stderr ]]; [[ ! -s $stderr ]]; :> $stderr
76+
grep -q "xccdf_com.example.www_rule_R1" $stdout
77+
grep -q "xccdf_com.example.www_rule_R2" $stdout
78+
! grep -q "xccdf_com.example.www_rule_R3" $stdout
79+
! grep -q "xccdf_com.example.www_rule_R4" $stdout
80+
[[ "$(wc -l < $stdout)" -eq 2 ]]
81+
:> $stdout
82+
rm -rf "$temp_dir"
83+
5484
rm -f $stdout $stderr

tests/oscap_info_profiles/test_list_vars.sh

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,30 @@ grep -q "xccdf_com.example.www_value_V2 custom_val" $stdout
5151
[[ "$(wc -l < $stdout)" -eq 2 ]]
5252
:> $stdout
5353

54+
# Test 6: --list-vars with tailoring referencing SDS via file: prefix + cref
55+
temp_dir="$(mktemp -d)"
56+
cp "$srcdir/test_reference_ds.xml" $temp_dir
57+
tailoring_sds="test_tailoring_file_sds_cref.xml"
58+
sed "s;TEMP_DIRECTORY_PLACEHOLDER;$temp_dir;" "$srcdir/$tailoring_sds" > "$temp_dir/$tailoring_sds"
59+
$OSCAP info --profile $tp --list-vars "$temp_dir/$tailoring_sds" > $stdout 2> $stderr
60+
[[ -f $stderr ]]; [[ ! -s $stderr ]]; :> $stderr
61+
grep -q "xccdf_com.example.www_value_V1 99" $stdout
62+
grep -q "xccdf_com.example.www_value_V2 custom_val" $stdout
63+
[[ "$(wc -l < $stdout)" -eq 2 ]]
64+
:> $stdout
65+
rm -rf "$temp_dir"
66+
67+
# Test 7: --list-vars with tailoring referencing SDS via file: prefix, no cref
68+
temp_dir="$(mktemp -d)"
69+
cp "$srcdir/test_reference_ds.xml" $temp_dir
70+
tailoring_sds_nf="test_tailoring_file_sds.xml"
71+
sed "s;TEMP_DIRECTORY_PLACEHOLDER;$temp_dir;" "$srcdir/$tailoring_sds_nf" > "$temp_dir/$tailoring_sds_nf"
72+
$OSCAP info --profile $tp --list-vars "$temp_dir/$tailoring_sds_nf" > $stdout 2> $stderr
73+
[[ -f $stderr ]]; [[ ! -s $stderr ]]; :> $stderr
74+
grep -q "xccdf_com.example.www_value_V1 99" $stdout
75+
grep -q "xccdf_com.example.www_value_V2 custom_val" $stdout
76+
[[ "$(wc -l < $stdout)" -eq 2 ]]
77+
:> $stdout
78+
rm -rf "$temp_dir"
79+
5480
rm -f $stdout $stderr
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Tailoring xmlns="http://checklists.nist.gov/xccdf/1.2" id="xccdf_com.example.www_tailoring_test">
3+
<benchmark href="file://TEMP_DIRECTORY_PLACEHOLDER/test_reference_ds.xml"/>
4+
<version>1.0</version>
5+
<Profile id="xccdf_com.example.www_profile_P1_tailored" extends="xccdf_com.example.www_profile_P1">
6+
<title>Tailored P1</title>
7+
<select idref="xccdf_com.example.www_rule_R3" selected="false"/>
8+
<select idref="xccdf_com.example.www_rule_R4" selected="false"/>
9+
<set-value idref="xccdf_com.example.www_value_V1">99</set-value>
10+
</Profile>
11+
</Tailoring>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Tailoring xmlns="http://checklists.nist.gov/xccdf/1.2" id="xccdf_com.example.www_tailoring_test">
3+
<benchmark href="file://TEMP_DIRECTORY_PLACEHOLDER/test_reference_ds.xml#scap_org.open-scap_cref_test_single_rule.xccdf.xml"/>
4+
<version>1.0</version>
5+
<Profile id="xccdf_com.example.www_profile_P1_tailored" extends="xccdf_com.example.www_profile_P1">
6+
<title>Tailored P1</title>
7+
<select idref="xccdf_com.example.www_rule_R3" selected="false"/>
8+
<select idref="xccdf_com.example.www_rule_R4" selected="false"/>
9+
<set-value idref="xccdf_com.example.www_value_V1">99</set-value>
10+
</Profile>
11+
</Tailoring>

utils/oscap-info.c

Lines changed: 67 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,26 @@ static void _print_vars_for_profile(struct xccdf_policy_model *policy_model, con
457457
xccdf_refine_value_iterator_free(rv_it);
458458
}
459459

460+
static struct xccdf_benchmark *_find_benchmark_in_stream(
461+
struct ds_sds_session *session,
462+
struct ds_stream_index *stream)
463+
{
464+
const char *stream_id = ds_stream_index_get_id(stream);
465+
struct oscap_string_iterator *bench_it = ds_stream_index_get_checklists(stream);
466+
struct xccdf_benchmark *bench = NULL;
467+
while (oscap_string_iterator_has_more(bench_it)) {
468+
const char *cl_id = oscap_string_iterator_next(bench_it);
469+
struct oscap_source *src = ds_sds_session_select_checklist(session, stream_id, cl_id, NULL);
470+
if (src != NULL && oscap_source_get_scap_type(src) == OSCAP_DOCUMENT_XCCDF) {
471+
bench = xccdf_benchmark_import_source(src);
472+
break;
473+
}
474+
ds_sds_session_reset(session);
475+
}
476+
oscap_string_iterator_free(bench_it);
477+
return bench;
478+
}
479+
460480
static struct xccdf_benchmark *_resolve_benchmark_for_tailoring(
461481
struct oscap_source *tailoring_source,
462482
const char *tailoring_filepath,
@@ -478,21 +498,64 @@ static struct xccdf_benchmark *_resolve_benchmark_for_tailoring(
478498
return NULL;
479499
}
480500

501+
// Extract #component_ref fragment from benchmark_ref, if present
502+
const char *component_ref = NULL;
503+
char *sep = strchr(benchmark_ref, '#');
504+
if (sep != NULL) {
505+
component_ref = sep + 1;
506+
*sep = '\0';
507+
}
508+
509+
// Strip file:// prefix
510+
const char *path_start = benchmark_ref;
511+
if (strncmp(benchmark_ref, "file://", 7) == 0) {
512+
path_start = benchmark_ref + 7;
513+
}
514+
481515
char *filepath_cpy = strdup(tailoring_filepath);
482516
char *dir = oscap_dirname(filepath_cpy);
483-
char *benchmark_path = benchmark_ref[0] == '/' ?
484-
strdup(benchmark_ref) : oscap_sprintf("%s/%s", dir, benchmark_ref);
517+
char *benchmark_path = path_start[0] == '/' ?
518+
strdup(path_start) : oscap_sprintf("%s/%s", dir, path_start);
485519
free(dir);
486520
free(filepath_cpy);
487-
free(benchmark_ref);
488521

489522
struct oscap_source *bench_source = oscap_source_new_from_file(benchmark_path);
490523
free(benchmark_path);
491524
if (bench_source == NULL) {
525+
free(benchmark_ref);
492526
return NULL;
493527
}
494528

495-
struct xccdf_benchmark *bench = xccdf_benchmark_import_source(bench_source);
529+
struct xccdf_benchmark *bench = NULL;
530+
oscap_document_type_t doc_type = oscap_source_get_scap_type(bench_source);
531+
if (doc_type == OSCAP_DOCUMENT_SDS) {
532+
struct ds_sds_session *sds_session = ds_sds_session_new_from_source(bench_source);
533+
if (sds_session == NULL) {
534+
oscap_source_free(bench_source);
535+
free(benchmark_ref);
536+
return NULL;
537+
}
538+
if (component_ref != NULL) {
539+
struct oscap_source *xccdf_source = ds_sds_session_select_checklist(sds_session, NULL, component_ref, NULL);
540+
if (xccdf_source != NULL) {
541+
bench = xccdf_benchmark_import_source(xccdf_source);
542+
}
543+
} else {
544+
struct ds_sds_index *sds_index = ds_sds_session_get_sds_idx(sds_session);
545+
struct ds_stream_index_iterator *streams = ds_sds_index_get_streams(sds_index);
546+
if (ds_stream_index_iterator_has_more(streams)) {
547+
struct ds_stream_index *stream = ds_stream_index_iterator_next(streams);
548+
bench = _find_benchmark_in_stream(sds_session, stream);
549+
}
550+
ds_stream_index_iterator_free(streams);
551+
}
552+
ds_sds_session_free(sds_session);
553+
} else {
554+
bench = xccdf_benchmark_import_source(bench_source);
555+
}
556+
557+
free(benchmark_ref);
558+
496559
if (bench == NULL) {
497560
oscap_source_free(bench_source);
498561
return NULL;
@@ -502,26 +565,6 @@ static struct xccdf_benchmark *_resolve_benchmark_for_tailoring(
502565
return bench;
503566
}
504567

505-
static struct xccdf_benchmark *_find_benchmark_in_stream(
506-
struct ds_sds_session *session,
507-
struct ds_stream_index *stream)
508-
{
509-
const char *stream_id = ds_stream_index_get_id(stream);
510-
struct oscap_string_iterator *bench_it = ds_stream_index_get_checklists(stream);
511-
struct xccdf_benchmark *bench = NULL;
512-
while (oscap_string_iterator_has_more(bench_it)) {
513-
const char *cl_id = oscap_string_iterator_next(bench_it);
514-
struct oscap_source *src = ds_sds_session_select_checklist(session, stream_id, cl_id, NULL);
515-
if (src != NULL && oscap_source_get_scap_type(src) == OSCAP_DOCUMENT_XCCDF) {
516-
bench = xccdf_benchmark_import_source(src);
517-
break;
518-
}
519-
ds_sds_session_reset(session);
520-
}
521-
oscap_string_iterator_free(bench_it);
522-
return bench;
523-
}
524-
525568
static int _handle_xccdf_benchmark_profile(
526569
struct xccdf_benchmark *bench,
527570
const struct oscap_action *action,

0 commit comments

Comments
 (0)