38
38
#include "ds_rds_session.h"
39
39
#include "ds_rds_session_priv.h"
40
40
#include "rds_priv.h"
41
+ #include "sds_priv.h"
41
42
#include "source/public/oscap_source.h"
42
43
#include "source/oscap_source_priv.h"
43
44
@@ -55,6 +56,8 @@ static const char* arf_ns_uri = "http://scap.nist.gov/schema/asset-reporting-for
55
56
static const char * core_ns_uri = "http://scap.nist.gov/schema/reporting-core/1.1" ;
56
57
static const char * arfvocab_ns_uri = "http://scap.nist.gov/specifications/arf/vocabulary/relationships/1.0#" ;
57
58
static const char * ai_ns_uri = "http://scap.nist.gov/schema/asset-identification/1.1" ;
59
+ static const char * xlink_ns_uri = "http://www.w3.org/1999/xlink" ;
60
+
58
61
59
62
xmlNode * ds_rds_lookup_container (xmlDocPtr doc , const char * container_name )
60
63
{
@@ -693,7 +696,7 @@ static void ds_rds_add_xccdf_test_results(xmlDocPtr doc, xmlNodePtr reports,
693
696
}
694
697
}
695
698
696
- static int ds_rds_create_from_dom (xmlDocPtr * ret , xmlDocPtr sds_doc , xmlDocPtr xccdf_result_file_doc , struct oscap_htable * oval_result_sources , struct oscap_htable * oval_result_mapping , struct oscap_htable * arf_report_mapping )
699
+ static int ds_rds_create_from_dom (xmlDocPtr * ret , xmlDocPtr sds_doc , xmlDocPtr tailoring_doc , const char * tailoring_filepath , char * tailoring_doc_timestamp , xmlDocPtr xccdf_result_file_doc , struct oscap_htable * oval_result_sources , struct oscap_htable * oval_result_mapping , struct oscap_htable * arf_report_mapping )
697
700
{
698
701
* ret = NULL ;
699
702
@@ -730,6 +733,68 @@ static int ds_rds_create_from_dom(xmlDocPtr* ret, xmlDocPtr sds_doc, xmlDocPtr x
730
733
xmlDOMWrapReconcileNamespaces (sds_wrap_ctxt , sds_res_node , 0 );
731
734
xmlDOMWrapFreeCtxt (sds_wrap_ctxt );
732
735
736
+ if (tailoring_doc && strcmp (tailoring_filepath , "NONEXISTENT" )) {
737
+ char * mangled_tailoring_filepath = ds_sds_mangle_filepath (tailoring_filepath );
738
+ char * tailoring_component_id = oscap_sprintf ("scap_org.open-scap_comp_%s_tailoring" , mangled_tailoring_filepath );
739
+ char * tailoring_component_ref_id = oscap_sprintf ("scap_org.open-scap_cref_%s_tailoring" , mangled_tailoring_filepath );
740
+
741
+ // Need unique id (ref_id) - if generated already exists, then create new one
742
+ int counter = 0 ;
743
+ while (lookup_component_in_collection (sds_doc , tailoring_component_id ) != NULL ) {
744
+ free (tailoring_component_id );
745
+ tailoring_component_id = oscap_sprintf ("scap_org.open-scap_comp_%s_tailoring%03d" , mangled_tailoring_filepath , counter ++ );
746
+ }
747
+
748
+ counter = 0 ;
749
+ while (ds_sds_find_component_ref (xmlDocGetRootElement (sds_res_node )-> children , tailoring_component_ref_id ) != NULL ) {
750
+ free (tailoring_component_ref_id );
751
+ tailoring_component_ref_id = oscap_sprintf ("scap_org.open-scap_cref_%s_tailoring%03d" , mangled_tailoring_filepath , counter ++ );
752
+ }
753
+
754
+ free (mangled_tailoring_filepath );
755
+
756
+ xmlDOMWrapCtxtPtr tailoring_wrap_ctxt = xmlDOMWrapNewCtxt ();
757
+ xmlNodePtr tailoring_res_node = NULL ;
758
+ xmlDOMWrapCloneNode (tailoring_wrap_ctxt , tailoring_doc , xmlDocGetRootElement (tailoring_doc ),
759
+ & tailoring_res_node , doc , NULL , 1 , 0 );
760
+ xmlNsPtr sds_ns = sds_res_node -> ns ;
761
+ xmlNodePtr tailoring_component = xmlNewNode (sds_ns , BAD_CAST "component" );
762
+ xmlSetProp (tailoring_component , BAD_CAST "id" , BAD_CAST tailoring_component_id );
763
+ xmlSetProp (tailoring_component , BAD_CAST "timestamp" , BAD_CAST tailoring_doc_timestamp );
764
+ xmlAddChild (tailoring_component , tailoring_res_node );
765
+ xmlAddChild (sds_res_node , tailoring_component );
766
+
767
+ xmlNodePtr checklists_element = NULL ;
768
+ xmlNodePtr datastream_element = node_get_child_element (sds_res_node , "data-stream" );
769
+ if (datastream_element == NULL ) {
770
+ datastream_element = xmlNewNode (sds_ns , "data-stream" );
771
+ xmlAddChild (sds_res_node , datastream_element );
772
+ checklists_element = xmlNewNode (sds_ns , "checklists" );
773
+ xmlAddChild (datastream_element , checklists_element );
774
+ }
775
+ else {
776
+ checklists_element = node_get_child_element (datastream_element , "checklists" );
777
+ }
778
+
779
+ xmlNodePtr tailoring_component_ref = xmlNewNode (sds_ns , BAD_CAST "component-ref" );
780
+ xmlSetProp (tailoring_component_ref , BAD_CAST "id" , BAD_CAST tailoring_component_ref_id );
781
+ char * tailoring_cref_href = oscap_sprintf ("#%s" , tailoring_component_id );
782
+ xmlNsPtr xlink_ns = xmlSearchNsByHref (doc , sds_res_node , BAD_CAST xlink_ns_uri );
783
+ if (!xlink_ns ) {
784
+ oscap_seterr (OSCAP_EFAMILY_XML ,
785
+ "Unable to find namespace '%s' in the XML DOM tree. "
786
+ "This is most likely an internal error!." ,
787
+ xlink_ns_uri );
788
+ return -1 ;
789
+ }
790
+ xmlSetNsProp (tailoring_component_ref , xlink_ns , BAD_CAST "href" , BAD_CAST tailoring_cref_href );
791
+ free (tailoring_cref_href );
792
+ xmlAddChild (checklists_element , tailoring_component_ref );
793
+
794
+ xmlDOMWrapReconcileNamespaces (tailoring_wrap_ctxt , tailoring_res_node , 0 );
795
+ xmlDOMWrapFreeCtxt (tailoring_wrap_ctxt );
796
+ }
797
+
733
798
xmlAddChild (report_request , arf_content );
734
799
735
800
xmlAddChild (report_requests , report_request );
@@ -758,22 +823,43 @@ static int ds_rds_create_from_dom(xmlDocPtr* ret, xmlDocPtr sds_doc, xmlDocPtr x
758
823
return 0 ;
759
824
}
760
825
761
- struct oscap_source * ds_rds_create_source (struct oscap_source * sds_source , struct oscap_source * xccdf_result_source , struct oscap_htable * oval_result_sources , struct oscap_htable * oval_result_mapping , struct oscap_htable * arf_report_mapping , const char * target_file )
826
+ struct oscap_source * ds_rds_create_source (struct oscap_source * sds_source , struct oscap_source * tailoring_source , struct oscap_source * xccdf_result_source , struct oscap_htable * oval_result_sources , struct oscap_htable * oval_result_mapping , struct oscap_htable * arf_report_mapping , const char * target_file )
762
827
{
763
828
xmlDoc * sds_doc = oscap_source_get_xmlDoc (sds_source );
764
829
if (sds_doc == NULL ) {
765
830
return NULL ;
766
831
}
832
+
767
833
xmlDoc * result_file_doc = oscap_source_get_xmlDoc (xccdf_result_source );
768
834
if (result_file_doc == NULL ) {
769
835
return NULL ;
770
836
}
771
837
838
+ xmlDoc * tailoring_doc = NULL ;
839
+ char * tailoring_doc_timestamp = NULL ;
840
+ char * tailoring_filepath = NULL ;
841
+ if (tailoring_source ) {
842
+ tailoring_doc = oscap_source_get_xmlDoc (tailoring_source );
843
+ if (tailoring_doc == NULL ) {
844
+ return NULL ;
845
+ }
846
+ tailoring_filepath = oscap_source_get_filepath (tailoring_source );
847
+ struct stat file_stat ;
848
+ if (stat (tailoring_filepath , & file_stat ) == 0 ) {
849
+ const size_t max_timestamp_len = 32 ;
850
+ tailoring_doc_timestamp = malloc (max_timestamp_len );
851
+ strftime (tailoring_doc_timestamp , max_timestamp_len , "%Y-%m-%dT%H:%M:%S" , localtime (& file_stat .st_mtime ));
852
+ }
853
+ }
854
+
772
855
xmlDocPtr rds_doc = NULL ;
773
- if (ds_rds_create_from_dom (& rds_doc , sds_doc , result_file_doc ,
856
+
857
+ if (ds_rds_create_from_dom (& rds_doc , sds_doc , tailoring_doc , tailoring_filepath , tailoring_doc_timestamp , result_file_doc ,
774
858
oval_result_sources , oval_result_mapping , arf_report_mapping ) != 0 ) {
859
+ free (tailoring_doc_timestamp );
775
860
return NULL ;
776
861
}
862
+ free (tailoring_doc_timestamp );
777
863
return oscap_source_new_from_xmlDoc (rds_doc , target_file );
778
864
}
779
865
@@ -803,7 +889,7 @@ int ds_rds_create(const char* sds_file, const char* xccdf_result_file, const cha
803
889
}
804
890
}
805
891
if (result == 0 ) {
806
- struct oscap_source * target_rds = ds_rds_create_source (sds_source , xccdf_result_source , oval_result_sources , oval_result_mapping , arf_report_mapping , target_file );
892
+ struct oscap_source * target_rds = ds_rds_create_source (sds_source , NULL , xccdf_result_source , oval_result_sources , oval_result_mapping , arf_report_mapping , target_file );
807
893
result = target_rds == NULL ;
808
894
if (result == 0 ) {
809
895
result = oscap_source_save_as (target_rds , NULL );
0 commit comments