@@ -64,6 +64,7 @@ struct oscap_module OSCAP_INFO_MODULE = {
6464 .help = "Options:\n"
6565 " --fetch-remote-resources - Download remote content referenced by data stream.\n"
6666 " --list-rules - Print selected rule IDs for the given profile (requires --profile).\n"
67+ " --list-vars - Print XCCDF Value IDs and their resolved values for the given profile (requires --profile).\n"
6768 " --local-files <dir> - Use locally downloaded copies of remote resources stored in the given directory.\n"
6869 " --profile <id> - Show info of the profile with the given ID.\n"
6970 " --profiles - Show profiles from the input file in the <id>:<title> format, one line per profile.\n"
@@ -418,6 +419,49 @@ static void _print_rules_for_profile(struct xccdf_benchmark *bench, const char *
418419 xccdf_policy_model_free (policy_model );
419420}
420421
422+ static void _print_vars_for_profile (struct xccdf_benchmark * bench , const char * profile_id )
423+ {
424+ struct xccdf_policy_model * policy_model = xccdf_policy_model_new (bench );
425+ struct xccdf_policy * policy = xccdf_policy_model_get_policy_by_id (policy_model , profile_id );
426+ if (policy == NULL ) {
427+ xccdf_policy_model_free (policy_model );
428+ return ;
429+ }
430+ struct xccdf_profile * profile = xccdf_policy_get_profile (policy );
431+ if (profile == NULL ) {
432+ xccdf_policy_model_free (policy_model );
433+ return ;
434+ }
435+
436+ struct xccdf_setvalue_iterator * sv_it = xccdf_profile_get_setvalues (profile );
437+ while (xccdf_setvalue_iterator_has_more (sv_it )) {
438+ struct xccdf_setvalue * sv = xccdf_setvalue_iterator_next (sv_it );
439+ const char * value_id = xccdf_setvalue_get_item (sv );
440+ struct xccdf_item * item = xccdf_benchmark_get_item (bench , value_id );
441+ if (item != NULL ) {
442+ const char * resolved = xccdf_policy_get_value_of_item (policy , item );
443+ if (resolved != NULL )
444+ printf ("%s\t%s\n" , value_id , resolved );
445+ }
446+ }
447+ xccdf_setvalue_iterator_free (sv_it );
448+
449+ struct xccdf_refine_value_iterator * rv_it = xccdf_profile_get_refine_values (profile );
450+ while (xccdf_refine_value_iterator_has_more (rv_it )) {
451+ struct xccdf_refine_value * rv = xccdf_refine_value_iterator_next (rv_it );
452+ const char * value_id = xccdf_refine_value_get_item (rv );
453+ struct xccdf_item * item = xccdf_benchmark_get_item (bench , value_id );
454+ if (item != NULL ) {
455+ const char * resolved = xccdf_policy_get_value_of_item (policy , item );
456+ if (resolved != NULL )
457+ printf ("%s\t%s\n" , value_id , resolved );
458+ }
459+ }
460+ xccdf_refine_value_iterator_free (rv_it );
461+
462+ xccdf_policy_model_free (policy_model );
463+ }
464+
421465static int app_info_single_ds_one_profile (struct ds_stream_index_iterator * sds_it , struct ds_sds_session * session , const struct oscap_action * action )
422466{
423467 const char * profile_suffix = action -> profile ;
@@ -426,7 +470,7 @@ static int app_info_single_ds_one_profile(struct ds_stream_index_iterator* sds_i
426470 struct ds_stream_index * stream = ds_stream_index_iterator_next (sds_it );
427471 struct oscap_string_iterator * checklist_it = ds_stream_index_get_checklists (stream );
428472
429- if (!action -> list_rules ) {
473+ if (!action -> list_rules && ! action -> list_vars ) {
430474 printf ("\nStream: %s\n" , ds_stream_index_get_id (stream ));
431475 printf ("Generated: %s\n" , ds_stream_index_get_timestamp (stream ));
432476 printf ("Version: %s\n" , ds_stream_index_get_version (stream ));
@@ -458,6 +502,9 @@ static int app_info_single_ds_one_profile(struct ds_stream_index_iterator* sds_i
458502 if (action -> list_rules ) {
459503 _print_rules_for_profile (bench , profile_id );
460504 // bench is freed by policy_model inside _print_rules_for_profile
505+ } else if (action -> list_vars ) {
506+ _print_vars_for_profile (bench , profile_id );
507+ // bench is freed by policy_model inside _print_vars_for_profile
461508 } else {
462509 _print_single_benchmark_one_profile (bench , profile_id );
463510 xccdf_benchmark_free (bench );
@@ -541,6 +588,9 @@ static void app_info_single_benchmark(struct xccdf_benchmark *bench, const struc
541588 if (action -> list_rules ) {
542589 _print_rules_for_profile (bench , profile_id );
543590 // bench is freed by policy_model inside _print_rules_for_profile
591+ } else if (action -> list_vars ) {
592+ _print_vars_for_profile (bench , profile_id );
593+ // bench is freed by policy_model inside _print_vars_for_profile
544594 } else {
545595 _print_single_benchmark_one_profile (bench , profile_id );
546596 xccdf_benchmark_free (bench );
@@ -805,6 +855,7 @@ bool getopt_info(int argc, char **argv, struct oscap_action *action)
805855 enum oscap_info_opts {
806856 OSCAP_INFO_OPT_REMOTE_RESOURCES ,
807857 OSCAP_INFO_OPT_LIST_RULES ,
858+ OSCAP_INFO_OPT_LIST_VARS ,
808859 OSCAP_INFO_OPT_LOCAL_FILES ,
809860 OSCAP_INFO_OPT_PROFILE ,
810861 OSCAP_INFO_OPT_PROFILES ,
@@ -816,6 +867,7 @@ bool getopt_info(int argc, char **argv, struct oscap_action *action)
816867 const struct option long_options [] = {
817868 {"fetch-remote-resources" , no_argument , & action -> remote_resources , 1 },
818869 {"list-rules" , no_argument , 0 , OSCAP_INFO_OPT_LIST_RULES },
870+ {"list-vars" , no_argument , 0 , OSCAP_INFO_OPT_LIST_VARS },
819871 {"local-files" , required_argument , NULL , OSCAP_INFO_OPT_LOCAL_FILES },
820872 {"profile" , required_argument , 0 , OSCAP_INFO_OPT_PROFILE },
821873 {"profiles" , no_argument , 0 , OSCAP_INFO_OPT_PROFILES },
@@ -834,6 +886,10 @@ bool getopt_info(int argc, char **argv, struct oscap_action *action)
834886 action -> list_rules = 1 ;
835887 action -> provide_machine_readable_output = 1 ;
836888 break ;
889+ case OSCAP_INFO_OPT_LIST_VARS :
890+ action -> list_vars = 1 ;
891+ action -> provide_machine_readable_output = 1 ;
892+ break ;
837893 case OSCAP_INFO_OPT_PROFILE :
838894 action -> profile = optarg ;
839895 break ;
@@ -862,6 +918,11 @@ bool getopt_info(int argc, char **argv, struct oscap_action *action)
862918 return false;
863919 }
864920
921+ if (action -> list_vars && action -> profile == NULL ) {
922+ oscap_module_usage (action -> module , stderr , "The --list-vars option requires --profile.\n" );
923+ return false;
924+ }
925+
865926 if (optind >= argc ) {
866927 oscap_module_usage (action -> module , stderr , "SCAP file needs to be specified!\n" );
867928 return false;
0 commit comments