Skip to content

Commit 421c4d9

Browse files
committed
Fix ARF generation with tailoring to use extended-component
Created in part by Claude Code. Fixes #2260
1 parent 0cdf676 commit 421c4d9

File tree

2 files changed

+46
-10
lines changed

2 files changed

+46
-10
lines changed

src/DS/rds.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ static int _ds_rds_create_from_dom(xmlDocPtr *ret, xmlDocPtr sds_doc,
710710

711711
if (tailoring_doc && strcmp(tailoring_filepath, "NONEXISTENT")) {
712712
char *mangled_tailoring_filepath = ds_sds_mangle_filepath(tailoring_filepath);
713-
char *tailoring_component_id = oscap_sprintf("scap_org.open-scap_comp_%s_tailoring", mangled_tailoring_filepath);
713+
char *tailoring_component_id = oscap_sprintf("scap_org.open-scap_ecomp_%s_tailoring", mangled_tailoring_filepath);
714714
char *tailoring_component_ref_id = oscap_sprintf("scap_org.open-scap_cref_%s_tailoring", mangled_tailoring_filepath);
715715

716716
// Need unique id (ref_id) - if generated already exists, then create new one
@@ -733,7 +733,7 @@ static int _ds_rds_create_from_dom(xmlDocPtr *ret, xmlDocPtr sds_doc,
733733
xmlDOMWrapCloneNode(tailoring_wrap_ctxt, tailoring_doc, xmlDocGetRootElement(tailoring_doc),
734734
&tailoring_res_node, doc, NULL, 1, 0);
735735
xmlNsPtr sds_ns = sds_res_node->ns;
736-
xmlNodePtr tailoring_component = xmlNewNode(sds_ns, BAD_CAST "component");
736+
xmlNodePtr tailoring_component = xmlNewNode(sds_ns, BAD_CAST "extended-component");
737737
xmlSetProp(tailoring_component, BAD_CAST "id", BAD_CAST tailoring_component_id);
738738
xmlSetProp(tailoring_component, BAD_CAST "timestamp", BAD_CAST tailoring_doc_timestamp);
739739
xmlAddChild(tailoring_component, tailoring_res_node);

tests/API/XCCDF/tailoring/all.sh

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ function test_api_xccdf_tailoring_simple_include_in_arf {
9494
return 1
9595
fi
9696

97-
assert_exists 1 '/arf:asset-report-collection/arf:report-requests/arf:report-request/arf:content/ds:data-stream-collection/ds:component/Tailoring'
97+
assert_exists 1 '/arf:asset-report-collection/arf:report-requests/arf:report-request/arf:content/ds:data-stream-collection/ds:extended-component/Tailoring'
9898
rm -f $result
9999
}
100100

@@ -112,7 +112,7 @@ function test_api_xccdf_tailoring_simple_include_in_arf_xlink_namespace {
112112
fi
113113

114114
[ ! -s "$stderr" ]
115-
assert_exists 1 '/arf:asset-report-collection/arf:report-requests/arf:report-request/arf:content/ds:data-stream-collection/ds:component/Tailoring'
115+
assert_exists 1 '/arf:asset-report-collection/arf:report-requests/arf:report-request/arf:content/ds:data-stream-collection/ds:extended-component/Tailoring'
116116

117117
rm -f "$result"
118118
rm -f "$stderr"
@@ -127,12 +127,15 @@ function test_api_xccdf_tailoring_profile_include_in_arf {
127127
$OSCAP xccdf eval --tailoring-file $TAILORING --profile "xccdf_com.example.www_profile_customized" --results-arf $result $INPUT || [ "$?" == "2" ]
128128

129129
component_xpath='/arf:asset-report-collection/arf:report-requests/arf:report-request/arf:content/ds:data-stream-collection/ds:component'
130-
assert_exists 3 $component_xpath
131-
assert_exists 3 $component_xpath'/@timestamp'
132-
assert_exists 1 $component_xpath'/xccdf:Tailoring'
133-
assert_exists 1 $component_xpath'/xccdf:Tailoring/xccdf:Profile'
134-
assert_exists 1 $component_xpath'/xccdf:Tailoring/xccdf:Profile[@id="xccdf_com.example.www_profile_customized"]'
135-
assert_exists 1 $component_xpath'/xccdf:Tailoring/xccdf:Profile[@extends="xccdf_com.example.www_profile_baseline1"]'
130+
extended_component_xpath='/arf:asset-report-collection/arf:report-requests/arf:report-request/arf:content/ds:data-stream-collection/ds:extended-component'
131+
# 2 regular components (XCCDF and OVAL) + 1 extended component (Tailoring)
132+
assert_exists 2 $component_xpath
133+
assert_exists 1 $extended_component_xpath
134+
assert_exists 1 $extended_component_xpath'/@timestamp'
135+
assert_exists 1 $extended_component_xpath'/xccdf:Tailoring'
136+
assert_exists 1 $extended_component_xpath'/xccdf:Tailoring/xccdf:Profile'
137+
assert_exists 1 $extended_component_xpath'/xccdf:Tailoring/xccdf:Profile[@id="xccdf_com.example.www_profile_customized"]'
138+
assert_exists 1 $extended_component_xpath'/xccdf:Tailoring/xccdf:Profile[@extends="xccdf_com.example.www_profile_baseline1"]'
136139
rm -f $result
137140
}
138141

@@ -169,6 +172,38 @@ function test_api_xccdf_tailoring_profile_generate_guide {
169172
rm -f $guide
170173
}
171174

175+
function test_api_xccdf_tailoring_arf_validation {
176+
# Regression test for https://github.com/OpenSCAP/openscap/issues/2260 where tailoring was stored in <ds:component>
177+
# instead of <ds:extended-component>, and ID used '_comp_' instead of '_ecomp_'
178+
# This caused ARF validation failures and generate fix errors.
179+
180+
local INPUT=$srcdir/$1
181+
local TAILORING=$srcdir/$2
182+
183+
result=`mktemp`
184+
stderr=`mktemp`
185+
186+
# Generate ARF with tailoring
187+
$OSCAP xccdf eval --tailoring-file $TAILORING --profile "xccdf_com.example.www_profile_customized" --results-arf $result $INPUT 2>$stderr || [ "$?" == "2" ]
188+
189+
# Check that the extended-component ID contains 'ecomp' (not just 'comp')
190+
grep -q 'extended-component.*id="scap_org.open-scap_ecomp_.*tailoring"' $result
191+
local ret1=$?
192+
193+
# Validate the ARF against schema (most important - this was failing before the fix)
194+
$OSCAP ds rds-validate $result 2>$stderr
195+
local ret2=$?
196+
197+
rm -f $result $stderr
198+
199+
if [ $ret1 -ne 0 ]; then
200+
return 1
201+
fi
202+
if [ $ret2 -ne 0 ]; then
203+
return 1
204+
fi
205+
}
206+
172207
# Testing.
173208

174209
test_init "test_api_xccdf_tailoring.log"
@@ -191,6 +226,7 @@ test_run "test_api_xccdf_tailoring_simple_include_in_arf_xlink_namespace" test_a
191226
test_run "test_api_xccdf_tailoring_profile_include_in_arf" test_api_xccdf_tailoring_profile_include_in_arf baseline.xccdf.xml baseline.tailoring.xml
192227
test_run "test_api_xccdf_tailoring_profile_generate_fix" test_api_xccdf_tailoring_profile_generate_fix baseline.xccdf.xml baseline.tailoring.xml
193228
test_run "test_api_xccdf_tailoring_profile_generate_guide" test_api_xccdf_tailoring_profile_generate_guide baseline.xccdf.xml baseline.tailoring.xml
229+
test_run "test_api_xccdf_tailoring_arf_validation" test_api_xccdf_tailoring_arf_validation baseline.xccdf.xml baseline.tailoring.xml
194230

195231

196232
test_exit

0 commit comments

Comments
 (0)