@@ -502,127 +502,160 @@ static struct xccdf_benchmark *_resolve_benchmark_for_tailoring(
502502 return bench ;
503503}
504504
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+
525+ static int _handle_xccdf_benchmark_profile (
526+ struct xccdf_benchmark * bench ,
527+ const struct oscap_action * action ,
528+ const char * profile_suffix ,
529+ const char * filename ,
530+ bool * profile_found )
531+ {
532+ const char * profile_id = benchmark_get_profile_or_report_multiple_ids (bench , profile_suffix , filename );
533+ if (profile_id == NULL ) {
534+ xccdf_benchmark_free (bench );
535+ return OSCAP_OK ;
536+ }
537+ if (action -> list_rules || action -> list_vars ) {
538+ struct xccdf_policy_model * policy_model = xccdf_policy_model_new (bench );
539+ if (action -> list_rules ) {
540+ _print_rules_for_profile (policy_model , profile_id );
541+ } else {
542+ _print_vars_for_profile (policy_model , profile_id );
543+ }
544+ xccdf_policy_model_free (policy_model );
545+ } else {
546+ _print_single_benchmark_one_profile (bench , profile_id );
547+ xccdf_benchmark_free (bench );
548+ }
549+ * profile_found = true;
550+ return OSCAP_OK ;
551+ }
552+
553+ static int _handle_xccdf_tailoring_profile (
554+ struct xccdf_tailoring * tailoring ,
555+ const struct oscap_action * action ,
556+ const char * profile_suffix ,
557+ const char * filename ,
558+ struct ds_sds_session * session ,
559+ struct ds_stream_index * stream ,
560+ const char * checklist_id ,
561+ bool * profile_found )
562+ {
563+ const char * profile_id = tailoring_get_profile_or_report_multiple_ids (tailoring , profile_suffix , filename );
564+ if (profile_id == NULL ) {
565+ xccdf_tailoring_free (tailoring );
566+ return OSCAP_OK ;
567+ }
568+ if (!(action -> list_rules || action -> list_vars )) {
569+ struct xccdf_profile * profile = xccdf_tailoring_get_profile_by_id (tailoring , profile_id );
570+ _print_xccdf_profile_with_id (profile , "" );
571+ xccdf_tailoring_free (tailoring );
572+ * profile_found = true;
573+ return OSCAP_OK ;
574+ }
575+ char * profile_id_dup = strdup (profile_id );
576+ xccdf_tailoring_free (tailoring );
577+
578+ /* Find the XCCDF benchmark component in the stream */
579+ ds_sds_session_reset (session );
580+ struct xccdf_benchmark * bench = _find_benchmark_in_stream (session , stream );
581+ if (bench == NULL ) {
582+ fprintf (stderr , "Could not find a benchmark in the datastream.\n" );
583+ free (profile_id_dup );
584+ return OSCAP_ERROR ;
585+ }
586+
587+ /* Re-select the tailoring component and import with benchmark */
588+ const char * stream_id = ds_stream_index_get_id (stream );
589+ ds_sds_session_reset (session );
590+ struct oscap_source * tail_source = ds_sds_session_select_checklist (session , stream_id , checklist_id , NULL );
591+ struct xccdf_tailoring * resolved_tailoring = xccdf_tailoring_import_source (tail_source , bench );
592+
593+ struct xccdf_policy_model * policy_model = xccdf_policy_model_new (bench );
594+ xccdf_policy_model_set_tailoring (policy_model , resolved_tailoring );
595+
596+ if (action -> list_rules ) {
597+ _print_rules_for_profile (policy_model , profile_id_dup );
598+ } else {
599+ _print_vars_for_profile (policy_model , profile_id_dup );
600+ }
601+ xccdf_policy_model_free (policy_model );
602+ free (profile_id_dup );
603+ * profile_found = true;
604+ return OSCAP_OK ;
605+ }
606+
505607static int app_info_single_ds_one_profile (struct ds_stream_index_iterator * sds_it , struct ds_sds_session * session , const struct oscap_action * action )
506608{
609+ int ret = OSCAP_OK ;
507610 const char * profile_suffix = action -> profile ;
508611 const char * filename = action -> file ;
509- const char * prefix = "" ;
510- struct ds_stream_index * stream = ds_stream_index_iterator_next (sds_it );
511- struct oscap_string_iterator * checklist_it = ds_stream_index_get_checklists (stream );
612+ struct ds_stream_index * stream = ds_stream_index_iterator_next (sds_it );
613+ struct oscap_string_iterator * checklist_it = ds_stream_index_get_checklists (stream );
512614
513615 if (!action -> list_rules && !action -> list_vars ) {
514616 printf ("\nStream: %s\n" , ds_stream_index_get_id (stream ));
515617 printf ("Generated: %s\n" , ds_stream_index_get_timestamp (stream ));
516618 printf ("Version: %s\n" , ds_stream_index_get_version (stream ));
517619 }
518- bool profile_not_found = true ;
620+ bool profile_found = false ;
519621
520- while (oscap_string_iterator_has_more (checklist_it ) && profile_not_found ) {
521- const char * id = oscap_string_iterator_next (checklist_it );
622+ while (oscap_string_iterator_has_more (checklist_it ) && ! profile_found ) {
623+ const char * id = oscap_string_iterator_next (checklist_it );
522624
523625 /* decompose */
524626 struct oscap_source * xccdf_source = ds_sds_session_select_checklist (session , ds_stream_index_get_id (stream ), id , NULL );
525627 if (xccdf_source == NULL ) {
526- oscap_string_iterator_free (checklist_it );
527- ds_stream_index_iterator_free (sds_it );
528- ds_sds_session_free (session );
529- return OSCAP_ERROR ;
628+ ret = OSCAP_ERROR ;
629+ goto cleanup ;
530630 }
531631
532632 if (oscap_source_get_scap_type (xccdf_source ) == OSCAP_DOCUMENT_XCCDF ) {
533633 struct xccdf_benchmark * bench = xccdf_benchmark_import_source (xccdf_source );
534- if (!bench ) {
535- oscap_string_iterator_free (checklist_it );
536- ds_stream_index_iterator_free (sds_it );
537- ds_sds_session_free (session );
538- return OSCAP_ERROR ;
539- }
540- const char * profile_id = benchmark_get_profile_or_report_multiple_ids (bench , profile_suffix , filename );
541- if (profile_id != NULL ) {
542- if (action -> list_rules ) {
543- struct xccdf_policy_model * policy_model = xccdf_policy_model_new (bench );
544- _print_rules_for_profile (policy_model , profile_id );
545- xccdf_policy_model_free (policy_model );
546- } else if (action -> list_vars ) {
547- struct xccdf_policy_model * policy_model = xccdf_policy_model_new (bench );
548- _print_vars_for_profile (policy_model , profile_id );
549- xccdf_policy_model_free (policy_model );
550- } else {
551- _print_single_benchmark_one_profile (bench , profile_id );
552- xccdf_benchmark_free (bench );
553- }
554- profile_not_found = false;
555- } else {
556- xccdf_benchmark_free (bench );
634+ if (!bench ) {
635+ ret = OSCAP_ERROR ;
636+ goto cleanup ;
557637 }
638+ ret = _handle_xccdf_benchmark_profile (bench , action , profile_suffix , filename , & profile_found );
558639 } else if (oscap_source_get_scap_type (xccdf_source ) == OSCAP_DOCUMENT_XCCDF_TAILORING ) {
559640 struct xccdf_tailoring * tailoring = xccdf_tailoring_import_source (xccdf_source , NULL );
560-
561- const char * profile_id = tailoring_get_profile_or_report_multiple_ids (tailoring , profile_suffix , filename );
562- if (profile_id != NULL ) {
563- if (action -> list_rules || action -> list_vars ) {
564- char * profile_id_dup = strdup (profile_id );
565- xccdf_tailoring_free (tailoring );
566- tailoring = NULL ;
567-
568- const char * stream_id = ds_stream_index_get_id (stream );
569-
570- /* Find the XCCDF benchmark component in the stream */
571- ds_sds_session_reset (session );
572- struct oscap_string_iterator * bench_it = ds_stream_index_get_checklists (stream );
573- struct xccdf_benchmark * bench = NULL ;
574- while (oscap_string_iterator_has_more (bench_it )) {
575- const char * cl_id = oscap_string_iterator_next (bench_it );
576- struct oscap_source * src = ds_sds_session_select_checklist (session , stream_id , cl_id , NULL );
577- if (src != NULL && oscap_source_get_scap_type (src ) == OSCAP_DOCUMENT_XCCDF ) {
578- bench = xccdf_benchmark_import_source (src );
579- break ;
580- }
581- ds_sds_session_reset (session );
582- }
583- oscap_string_iterator_free (bench_it );
584-
585- if (bench == NULL ) {
586- fprintf (stderr , "Could not find a benchmark in the datastream.\n" );
587- free (profile_id_dup );
588- oscap_string_iterator_free (checklist_it );
589- ds_stream_index_iterator_free (sds_it );
590- ds_sds_session_free (session );
591- return OSCAP_ERROR ;
592- }
593-
594- /* Re-select the tailoring component and import with benchmark */
595- ds_sds_session_reset (session );
596- struct oscap_source * tail_source = ds_sds_session_select_checklist (session , stream_id , id , NULL );
597- struct xccdf_tailoring * resolved_tailoring = xccdf_tailoring_import_source (tail_source , bench );
598-
599- struct xccdf_policy_model * policy_model = xccdf_policy_model_new (bench );
600- xccdf_policy_model_set_tailoring (policy_model , resolved_tailoring );
601-
602- if (action -> list_rules ) {
603- _print_rules_for_profile (policy_model , profile_id_dup );
604- } else {
605- _print_vars_for_profile (policy_model , profile_id_dup );
606- }
607- xccdf_policy_model_free (policy_model );
608- free (profile_id_dup );
609- } else {
610- struct xccdf_profile * profile = xccdf_tailoring_get_profile_by_id (tailoring , profile_id );
611- _print_xccdf_profile_with_id (profile , prefix );
612- xccdf_tailoring_free (tailoring );
613- }
614- profile_not_found = false;
615- } else {
616- xccdf_tailoring_free (tailoring );
617- }
641+ ret = _handle_xccdf_tailoring_profile (tailoring , action , profile_suffix , filename , session , stream , id , & profile_found );
642+ }
643+ if (ret != OSCAP_OK ) {
644+ goto cleanup ;
618645 }
619646 ds_sds_session_reset (session );
620647 }
621- oscap_string_iterator_free (checklist_it );
622- if (profile_not_found ) {
648+ if (!profile_found ) {
623649 report_missing_profile (profile_suffix , filename );
624650 }
625- return OSCAP_OK ;
651+
652+ cleanup :
653+ oscap_string_iterator_free (checklist_it );
654+ if (ret != OSCAP_OK ) {
655+ ds_stream_index_iterator_free (sds_it );
656+ ds_sds_session_free (session );
657+ }
658+ return ret ;
626659}
627660
628661static int app_info_single_ds_all (struct ds_stream_index_iterator * sds_it , struct ds_sds_session * session , const struct oscap_action * action )
0 commit comments