Skip to content

Commit 2701281

Browse files
committed
Reduce cognitive complexity of app_info_single_ds_one_profile
1 parent aa01af1 commit 2701281

1 file changed

Lines changed: 127 additions & 94 deletions

File tree

utils/oscap-info.c

Lines changed: 127 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
505607
static 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

628661
static 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

Comments
 (0)