int app_evaluate_oval(const struct oscap_action *action) { struct oval_session *session = NULL; oval_result_t eval_result; int ret = OSCAP_ERROR; /* Turn on verbosity */ if (!oscap_set_verbose(action->verbosity_level, action->f_verbose_log, false)) { goto cleanup; } /* create a new OVAL session */ if ((session = oval_session_new(action->f_oval)) == NULL) { oscap_print_error(); return ret; } /* set validation level */ oval_session_set_validation(session, action->validate, getenv("OSCAP_FULL_VALIDATION")); /* set source DS related IDs */ oval_session_set_datastream_id(session, action->f_datastream_id); oval_session_set_component_id(session, action->f_oval_id); /* set reporter function for XML validation of inputs and outputs */ oval_session_set_xml_reporter(session, reporter); /* set OVAL Variables */ oval_session_set_variables(session, action->f_variables); /* load all necesary OVAL Definitions and bind OVAL Variables if provided */ if ((oval_session_load(session)) != 0) goto cleanup; /* evaluation */ if (action->id) { if ((oval_session_evaluate_id(session, action->probe_root, action->id, &eval_result)) != 0) goto cleanup; printf("Definition %s: %s\n", action->id, oval_result_get_text(eval_result)); } else { if ((oval_session_evaluate(session, action->probe_root, app_oval_callback, NULL)) != 0) goto cleanup; } printf("Evaluation done.\n"); oval_session_set_directives(session, action->f_directives); oval_session_set_results_export(session, action->f_results); oval_session_set_report_export(session, action->f_report); if (oval_session_export(session) != 0) goto cleanup; ret = OSCAP_OK; cleanup: oscap_print_error(); oval_session_free(session); return ret; }
int app_xccdf_validate(const struct oscap_action *action) { int ret; int result; struct oscap_source *source = oscap_source_new_from_file(action->f_xccdf); ret = oscap_source_validate(source, reporter, (void *) action); if (ret==-1) { result=OSCAP_ERROR; goto cleanup; } else if (ret==1) { result=OSCAP_FAIL; } else result=OSCAP_OK; if (action->schematron) { ret = oscap_source_validate_schematron(source, NULL); if (ret == -1) { result = OSCAP_ERROR; } else if (ret > 0) { result = OSCAP_FAIL; } } oscap_source_free(source); cleanup: oscap_print_error(); return result; }
int app_ds_rds_split(const struct oscap_action *action) { int ret = OSCAP_ERROR; struct ds_rds_session *session = NULL; struct oscap_source *source = oscap_source_new_from_file(action->ds_action->file); if (action->validate) { if (oscap_source_validate(source, reporter, (void *) action) != 0) { goto cleanup; } } session = ds_rds_session_new_from_source(source); if (session == NULL || ds_rds_session_set_target_dir(session, action->ds_action->target) != 0 || ds_rds_session_select_report(session, action->f_report_id) == NULL || ds_rds_session_select_report_request(session, NULL) == NULL || ds_rds_session_dump_component_files(session) != 0) { fprintf(stdout, "Failed to split given result datastream '%s'.\n", action->ds_action->file); goto cleanup; } ret = OSCAP_OK; cleanup: oscap_print_error(); ds_rds_session_free(session); free(action->ds_action); oscap_source_free(source); return ret; }
static int app_xccdf_export_oval_variables(const struct oscap_action *action) { struct xccdf_policy *policy = NULL; struct xccdf_result *xres; int result = OSCAP_ERROR; struct xccdf_session *session = NULL; session = xccdf_session_new(action->f_xccdf); if (session == NULL) goto cleanup; xccdf_session_set_validation(session, action->validate, getenv("OSCAP_FULL_VALIDATION") != NULL); if (xccdf_session_is_sds(session)) { xccdf_session_set_datastream_id(session, action->f_datastream_id); xccdf_session_set_component_id(session, action->f_xccdf_id); xccdf_session_set_benchmark_id(session, action->f_benchmark_id); } xccdf_session_set_user_cpe(session, action->cpe); xccdf_session_set_remote_resources(session, action->remote_resources, _download_reporting_callback); xccdf_session_set_custom_oval_files(session, action->f_ovals); xccdf_session_set_custom_oval_eval_fn(session, resolve_variables_wrapper); if (xccdf_session_load(session) != 0) goto cleanup; /* select a profile */ policy = xccdf_policy_model_get_policy_by_id(xccdf_session_get_policy_model(session), action->profile); if (policy == NULL) { if (action->profile != NULL) report_missing_profile(action); else fprintf(stderr, "No Policy was found for default profile.\n"); goto cleanup; } /* perform evaluation */ xres = xccdf_policy_evaluate(policy); if (xres == NULL) goto cleanup; xccdf_session_set_oval_variables_export(session, true); if (xccdf_session_export_oval(session) == 0) result = OSCAP_OK; cleanup: oscap_print_error(); if (session != NULL) xccdf_session_free(session); return result; }
int app_ds_sds_compose(const struct oscap_action *action) { int ret = OSCAP_ERROR; // The API will correctly deal with the file parameter having directory // references in it. However this will create a hard to navigate mangled // component IDs in the resulting datastream. // // To fix this we will chdir to parent dir of the given XCCDF and chdir // back after we are done. char *previous_cwd = _gcwd(); if (previous_cwd == NULL) { goto cleanup; } char target_abs_path[PATH_MAX + 1]; // if the path is already absolute we just use it as it is if (*action->ds_action->target == '/') snprintf(target_abs_path, PATH_MAX, "%s", action->ds_action->target); else snprintf(target_abs_path, PATH_MAX, "%s/%s", previous_cwd, action->ds_action->target); char* temp_cwd = strdup(action->ds_action->file); chdir(dirname(temp_cwd)); free(temp_cwd); char* source_xccdf = strdup(action->ds_action->file); ds_sds_compose_from_xccdf(basename(source_xccdf), target_abs_path); free(source_xccdf); chdir(previous_cwd); free(previous_cwd); if (action->validate) { struct oscap_source *source = oscap_source_new_from_file(target_abs_path); if (oscap_source_validate(source, reporter, (void *) action) != 0) { oscap_source_free(source); goto cleanup; } oscap_source_free(source); } ret = OSCAP_OK; cleanup: oscap_print_error(); free(action->ds_action); return ret; }
int app_ds_sds_split(const struct oscap_action *action) { int ret = OSCAP_ERROR; const char* f_datastream_id = action->f_datastream_id; const char* f_component_id = action->f_xccdf_id; struct ds_sds_session *session = NULL; struct oscap_source *source = oscap_source_new_from_file(action->ds_action->file); /* Validate */ if (action->validate) { if (oscap_source_validate(source, reporter, (void *) action) != 0) { goto cleanup; } } session = ds_sds_session_new_from_source(source); if (session == NULL) { goto cleanup; } if (ds_sds_index_select_checklist(ds_sds_session_get_sds_idx(session), &f_datastream_id, &f_component_id) != 0) { fprintf(stdout, "Failed to locate a datastream with ID matching '%s' ID " "and checklist inside matching '%s' ID.\n", action->f_datastream_id == NULL ? "<any>" : action->f_datastream_id, action->f_xccdf_id == NULL ? "<any>" : action->f_xccdf_id); goto cleanup; } ds_sds_session_set_datastream_id(session, f_datastream_id); ds_sds_session_set_remote_resources(session, action->remote_resources, download_reporting_callback); ds_sds_session_set_target_dir(session, action->ds_action->target); if (ds_sds_session_register_component_with_dependencies(session, "checklists", f_component_id, NULL) != 0) { goto cleanup; } if (ds_sds_session_dump_component_files(session) != 0) { goto cleanup; } ret = OSCAP_OK; cleanup: oscap_print_error(); ds_sds_session_free(session); oscap_source_free(source); free(action->ds_action); return ret; }
int app_ds_sds_validate(const struct oscap_action *action) { int ret = OSCAP_ERROR; struct oscap_source *source = oscap_source_new_from_file(action->ds_action->file); if (oscap_source_validate(source, reporter, (void*) action) != 0) { goto cleanup; } ret = OSCAP_OK; cleanup: oscap_print_error(); free(action->ds_action); oscap_source_free(source); return ret; }
int app_xccdf_remediate(const struct oscap_action *action) { struct xccdf_session *session = NULL; int result = OSCAP_ERROR; session = xccdf_session_new(action->f_xccdf); if (session == NULL) goto cleanup; xccdf_session_set_validation(session, action->validate, getenv("OSCAP_FULL_VALIDATION") != NULL); xccdf_session_set_user_cpe(session, action->cpe); xccdf_session_set_remote_resources(session, action->remote_resources, _download_reporting_callback); xccdf_session_set_custom_oval_files(session, action->f_ovals); if (xccdf_session_load(session) != 0) goto cleanup; if (xccdf_session_build_policy_from_testresult(session, action->id) != 0) goto cleanup; _register_progress_callback(session, action->progress); xccdf_session_remediate(session); xccdf_session_set_oval_results_export(session, action->oval_results); xccdf_session_set_oval_variables_export(session, action->export_variables); xccdf_session_set_arf_export(session, action->f_results_arf); xccdf_session_set_xccdf_export(session, action->f_results); xccdf_session_set_report_export(session, action->f_report); if (xccdf_session_export_oval(session) != 0) goto cleanup; xccdf_session_set_check_engine_plugins_results_export(session, action->check_engine_results); if (xccdf_session_export_check_engine_plugins(session) != 0) goto cleanup; if (xccdf_session_export_xccdf(session) != 0) goto cleanup; if (xccdf_session_export_arf(session) != 0) goto cleanup; /* Get the result from TestResult model and decide if end with error or with correct return code */ result = xccdf_session_contains_fail_result(session) ? OSCAP_FAIL : OSCAP_OK; cleanup: oscap_print_error(); xccdf_session_free(session); return result; }
static int app_cvrf_validate(const struct oscap_action *action) { int result; struct oscap_source *source = oscap_source_new_from_file(action->cvrf_action->f_cvrf); int ret = oscap_source_validate(source, reporter, (void *) action); if (ret==-1) { result=OSCAP_ERROR; } else if (ret==1) { result=OSCAP_FAIL; } else { result=OSCAP_OK; } oscap_source_free(source); oscap_print_error(); return result; }
int app_ds_sds_add(const struct oscap_action *action) { int ret = OSCAP_ERROR; // TODO: chdir to the directory of the component (same as when composing new sds) ret = ds_sds_compose_add_component(action->ds_action->target, action->f_datastream_id, action->ds_action->file, false); if (action->validate) { struct oscap_source *source = oscap_source_new_from_file(action->ds_action->file); if (oscap_source_validate(source, reporter, (void *) action) != 0) { ret = OSCAP_ERROR; } oscap_source_free(source); } oscap_print_error(); free(action->ds_action); return ret; }
int app_xccdf_validate(const struct oscap_action *action) { int ret; char *doc_version; int result; doc_version = xccdf_detect_version(action->f_xccdf); if (!doc_version) { result = OSCAP_ERROR; goto cleanup; } ret=oscap_validate_document(action->f_xccdf, action->doctype, doc_version, reporter, (void*)action); if (ret==-1) { result=OSCAP_ERROR; goto cleanup; } else if (ret==1) { result=OSCAP_FAIL; } else result=OSCAP_OK; if (action->schematron) { ret = oscap_schematron_validate_document(action->f_xccdf, action->doctype, doc_version, NULL); if (ret == -1) { result = OSCAP_ERROR; } else if (ret > 0) { result = OSCAP_FAIL; } } if (result==OSCAP_FAIL) validation_failed(action->f_xccdf, OSCAP_DOCUMENT_XCCDF, doc_version); cleanup: oscap_print_error(); if (doc_version) free(doc_version); return result; }
static int app_info(const struct oscap_action *action) { int result = OSCAP_ERROR; struct oscap_source *source = oscap_source_new_from_file(action->file); switch (oscap_source_get_scap_type(source)) { case OSCAP_DOCUMENT_OVAL_DEFINITIONS: { printf("Document type: OVAL Definitions\n"); struct oval_definition_model *def_model = oval_definition_model_import_source(source); if(!def_model) goto cleanup; struct oval_generator *gen = oval_definition_model_get_generator(def_model); printf("OVAL version: %s\n", oval_generator_get_core_schema_version(gen)); printf("Generated: %s\n", oval_generator_get_timestamp(gen)); print_time(action->file); oval_definition_model_free(def_model); } break; case OSCAP_DOCUMENT_OVAL_VARIABLES: { printf("Document type: OVAL Variables\n"); struct oval_variable_model *var_model = oval_variable_model_import_source(source); if(!var_model) goto cleanup; struct oval_generator *gen = oval_variable_model_get_generator(var_model); printf("OVAL version: %s\n", oval_generator_get_core_schema_version(gen)); printf("Generated: %s\n", oval_generator_get_timestamp(gen)); print_time(action->file); oval_variable_model_free(var_model); } break; case OSCAP_DOCUMENT_OVAL_DIRECTIVES: { printf("Document type: OVAL Directives\n"); struct oval_directives_model *dir_model = oval_directives_model_new(); int ret = oval_directives_model_import_source(dir_model, source); if(ret) goto cleanup; struct oval_generator *gen = oval_directives_model_get_generator(dir_model); printf("OVAL version: %s\n", oval_generator_get_core_schema_version(gen)); printf("Generated: %s\n", oval_generator_get_timestamp(gen)); print_time(action->file); oval_directives_model_free(dir_model); } break; case OSCAP_DOCUMENT_OVAL_SYSCHAR: { printf("Document type: OVAL System Characteristics\n"); struct oval_definition_model * def_model = oval_definition_model_new(); struct oval_syschar_model * sys_model = oval_syschar_model_new(def_model); int ret = oval_syschar_model_import_source(sys_model, source); if(ret) goto cleanup; struct oval_generator *gen = oval_syschar_model_get_generator(sys_model); printf("OVAL version: %s\n", oval_generator_get_core_schema_version(gen)); printf("Generated: %s\n", oval_generator_get_timestamp(gen)); print_time(action->file); oval_syschar_model_free(sys_model); oval_definition_model_free(def_model); } break; case OSCAP_DOCUMENT_OVAL_RESULTS: { printf("Document type: OVAL Results\n"); struct oval_definition_model * def_model=oval_definition_model_new(); struct oval_results_model * res_model = oval_results_model_new(def_model,NULL); int ret = oval_results_model_import_source(res_model, source); if(ret) goto cleanup; struct oval_generator *gen = oval_results_model_get_generator(res_model); printf("OVAL version: %s\n", oval_generator_get_core_schema_version(gen)); printf("Generated: %s\n", oval_generator_get_timestamp(gen)); print_time(action->file); oval_results_model_free(res_model); oval_definition_model_free(def_model); } break; case OSCAP_DOCUMENT_XCCDF: { printf("Document type: XCCDF Checklist\n"); struct xccdf_benchmark* bench = xccdf_benchmark_import_source(source); if(!bench) goto cleanup; printf("Checklist version: %s\n", oscap_source_get_schema_version(source)); print_time(action->file); _print_xccdf_benchmark(bench, ""); } break; case OSCAP_DOCUMENT_CPE_LANGUAGE: { printf("Document type: CPE Language\n"); print_time(action->file); } break; case OSCAP_DOCUMENT_CPE_DICTIONARY: { printf("Document type: CPE Dictionary\n"); struct cpe_dict_model *dict_model = cpe_dict_model_import_source(source); if (!dict_model) goto cleanup; struct cpe_generator *gen = cpe_dict_model_get_generator(dict_model); if (gen != NULL) { printf("CPE version: %s\n", cpe_generator_get_schema_version(gen)); printf("Generated: %s\n", cpe_generator_get_timestamp(gen)); } print_time(action->file); cpe_dict_model_free(dict_model); } break; case OSCAP_DOCUMENT_SDS: { printf("Document type: Source Data Stream\n"); print_time(action->file); struct ds_sds_session *session = ds_sds_session_new_from_source(source); if (session == NULL) { goto cleanup; } /* get collection */ struct ds_sds_index *sds = ds_sds_session_get_sds_idx(session); if (!sds) { ds_sds_session_free(session); goto cleanup; } /* iterate over streams */ struct ds_stream_index_iterator* sds_it = ds_sds_index_get_streams(sds); while (ds_stream_index_iterator_has_more(sds_it)) { struct ds_stream_index * stream = ds_stream_index_iterator_next(sds_it); printf("\nStream: %s\n", ds_stream_index_get_id(stream)); printf("Generated: %s\n", ds_stream_index_get_timestamp(stream)); printf("Version: %s\n", ds_stream_index_get_version(stream)); printf("Checklists:\n"); struct oscap_string_iterator* checklist_it = ds_stream_index_get_checklists(stream); while (oscap_string_iterator_has_more(checklist_it)) { const char * id = oscap_string_iterator_next(checklist_it); printf("\tRef-Id: %s\n", id); /* decompose */ struct oscap_source *xccdf_source = ds_sds_session_select_checklist(session, ds_stream_index_get_id(stream), id, NULL); if (xccdf_source == NULL) { oscap_string_iterator_free(checklist_it); ds_stream_index_iterator_free(sds_it); ds_sds_session_free(session); goto cleanup; } const char *prefix = "\t\t"; if (oscap_source_get_scap_type(xccdf_source) == OSCAP_DOCUMENT_XCCDF) { struct xccdf_benchmark* bench = xccdf_benchmark_import_source(xccdf_source); if(!bench) { oscap_string_iterator_free(checklist_it); ds_stream_index_iterator_free(sds_it); ds_sds_session_free(session); goto cleanup; } _print_xccdf_benchmark(bench, prefix); } else if (oscap_source_get_scap_type(xccdf_source) == OSCAP_DOCUMENT_XCCDF_TAILORING) { _print_xccdf_tailoring(xccdf_source, prefix); } ds_sds_session_reset(session); } oscap_string_iterator_free(checklist_it); printf("Checks:\n"); struct oscap_string_iterator* checks_it = ds_stream_index_get_checks(stream); while (oscap_string_iterator_has_more(checks_it)) { const char * id = oscap_string_iterator_next(checks_it); printf("\tRef-Id: %s\n", id); } oscap_string_iterator_free(checks_it); struct oscap_string_iterator* dict_it = ds_stream_index_get_dictionaries(stream); if (oscap_string_iterator_has_more(dict_it)) printf("Dictionaries:\n"); else printf("No dictionaries.\n"); while (oscap_string_iterator_has_more(dict_it)) { const char * id = oscap_string_iterator_next(dict_it); printf("\tRef-Id: %s\n", id); } oscap_string_iterator_free(dict_it); } ds_stream_index_iterator_free(sds_it); ds_sds_session_free(session); } break; case OSCAP_DOCUMENT_ARF: { printf("Document type: Result Data Stream\n"); struct ds_rds_session *session = ds_rds_session_new_from_source(source); if (session == NULL) { goto cleanup; } struct rds_index *rds = ds_rds_session_get_rds_idx(session); if (!rds) { ds_rds_session_free(session); goto cleanup; } struct rds_asset_index_iterator* asset_it = rds_index_get_assets(rds); while (rds_asset_index_iterator_has_more(asset_it)) { struct rds_asset_index* asset = rds_asset_index_iterator_next(asset_it); printf("\nAsset: %s\n", rds_asset_index_get_id(asset)); struct rds_report_index_iterator* report_it = rds_asset_index_get_reports(asset); while (rds_report_index_iterator_has_more(report_it)) { struct rds_report_index* report = rds_report_index_iterator_next(report_it); struct rds_report_request_index* request = rds_report_index_get_request(report); printf(" - %s -> %s\n", rds_report_request_index_get_id(request), rds_report_index_get_id(report)); } rds_report_index_iterator_free(report_it); } rds_asset_index_iterator_free(asset_it); ds_rds_session_free(session); } break; case OSCAP_DOCUMENT_XCCDF_TAILORING: printf("Document type: XCCDF Tailoring\n"); print_time(action->file); _print_xccdf_tailoring(source, ""); break; case OSCAP_DOCUMENT_CVE_FEED: printf("Document type: CVE Feed\n"); // TODO: Provide more info about CVE feeds break; case OSCAP_DOCUMENT_SCE_RESULT: printf("Document type: SCE Result File\n"); // Currently, we do not have any SCE result file parsing capabilities. break; default: printf("Could not determine document type\n"); goto cleanup; break; } result=OSCAP_OK; cleanup: oscap_source_free(source); oscap_print_error(); return result; }
int app_generate_fix(const struct oscap_action *action) { if (action->id != NULL) { /* Listen very carefully -- I shall say this only once. This is temporaly * fallback mode. Which may be dropped from future OpenSCAP releases. * * Previously, the OpenSCAP used XSLT to generate fixes from XCCDF files. * That is no longer viable as XSLT cannot support Text substitution, CPE * processing, DataStreams, or Tailoring. * * The XSLT used to print out <fix> elements from TestResult (if supplied) * or from a profile (otherwise). We keep the former untouched (XSLT) and * later was rewritten using C. * * When scanning OpenSCAP used to copy all the <fix> elements from Profile * to the TestResult. That was not of much value. Now OpenSCAP includes in * TestResult only those <fix> elements which were executed on a given * system. * * Thus, this mode is usefull to review which fixes has been executed as a part * of given scan (TestResult) * * TODO: Once this legacy is dropped, we need to document --cpe and --datastream * support in man pages. */ fprintf(stderr, "#Warning: OpenSCAP will now use fallback mode (XSLT) to generate fixes. " "Some of the functionality might be missing (Text substitution, CPE processing, DataStream support, and tailoring). " "Please ommit --result-id option to trigger advanced processing.\n"); return app_xccdf_xslt(action); } /* Otherwise, we better use internal solver instead of XSLT * Mainly because of Text Substitution */ int ret = OSCAP_ERROR; struct xccdf_session *session = xccdf_session_new(action->f_xccdf); if (session == NULL) goto cleanup; if (xccdf_session_is_sds(session)) { xccdf_session_set_datastream_id(session, action->f_datastream_id); xccdf_session_set_component_id(session, action->f_xccdf_id); xccdf_session_set_benchmark_id(session, action->f_benchmark_id); } xccdf_session_set_user_cpe(session, action->cpe); xccdf_session_set_user_tailoring_file(session, action->tailoring_file); xccdf_session_set_user_tailoring_cid(session, action->tailoring_id); if (xccdf_session_load_xccdf(session) != 0) goto cleanup; if (xccdf_session_load_cpe(session) != 0) goto cleanup; if (xccdf_session_load_tailoring(session) != 0) goto cleanup; if (!xccdf_session_set_profile_id(session, action->profile)) { report_missing_profile(action); goto cleanup; } struct xccdf_policy *policy = xccdf_session_get_xccdf_policy(session); int output_fd = STDOUT_FILENO; if (action->f_results != NULL) { if ((output_fd = open(action->f_results, O_CREAT|O_TRUNC|O_NOFOLLOW|O_WRONLY, 0700)) < 0) { fprintf(stderr, "Could not open %s: %s", action->f_results, strerror(errno)); goto cleanup; } } if (xccdf_policy_generate_fix(policy, NULL, action->tmpl, output_fd) == 0) ret = OSCAP_OK; if (output_fd != STDOUT_FILENO) close(output_fd); cleanup: oscap_print_error(); xccdf_session_free(session); return ret; }
int app_xccdf_resolve(const struct oscap_action *action) { int ret = OSCAP_ERROR; struct xccdf_benchmark *bench = NULL; if (!action->f_xccdf) { fprintf(stderr, "No input document specified!\n"); return OSCAP_ERROR; } if (!action->f_results) { fprintf(stderr, "No output document filename specified!\n"); return OSCAP_ERROR; } struct oscap_source *source = oscap_source_new_from_file(action->f_xccdf); /* validate input */ if (action->validate) { if (oscap_source_validate(source, reporter, (void *) action) != 0) { oscap_source_free(source); goto cleanup; } } bench = xccdf_benchmark_import_source(source); oscap_source_free(source); if (!bench) goto cleanup; if (action->force) xccdf_benchmark_set_resolved(bench, false); if (xccdf_benchmark_get_resolved(bench)) fprintf(stderr, "Benchmark is already resolved!\n"); else { if (!xccdf_benchmark_resolve(bench)) fprintf(stderr, "Benchmark resolving failure (probably a dependency loop)!\n"); else { if (xccdf_benchmark_export(bench, action->f_results) == 0) { ret = OSCAP_OK; /* validate exported results */ const char* full_validation = getenv("OSCAP_FULL_VALIDATION"); if (action->validate && full_validation) { struct oscap_source *result_source = oscap_source_new_from_file(action->f_results); if (oscap_source_validate(result_source, reporter, (void *) action) != 0) { ret = OSCAP_ERROR; } else fprintf(stdout, "Resolved XCCDF has been exported correctly.\n"); oscap_source_free(result_source); } } } } cleanup: oscap_print_error(); if (bench) xccdf_benchmark_free(bench); return ret; }
/** * XCCDF Processing fucntion * @param action OSCAP Action structure * @param sess OVAL Agent Session */ int app_evaluate_xccdf(const struct oscap_action *action) { struct xccdf_session *session = NULL; int result = OSCAP_ERROR; int priority = LOG_NOTICE; /* syslog message */ syslog(priority, "Evaluation started. Content: %s, Profile: %s.", action->f_xccdf, action->profile); session = xccdf_session_new(action->f_xccdf); if (session == NULL) goto cleanup; xccdf_session_set_validation(session, action->validate, getenv("OSCAP_FULL_VALIDATION") != NULL); if (xccdf_session_is_sds(session)) { xccdf_session_set_datastream_id(session, action->f_datastream_id); xccdf_session_set_component_id(session, action->f_xccdf_id); xccdf_session_set_benchmark_id(session, action->f_benchmark_id); } xccdf_session_set_user_cpe(session, action->cpe); // The tailoring_file may be NULL but the tailoring file may have been // autonegotiated from the input file, we don't want to lose that. if (action->tailoring_file != NULL) xccdf_session_set_user_tailoring_file(session, action->tailoring_file); xccdf_session_set_user_tailoring_cid(session, action->tailoring_id); xccdf_session_set_remote_resources(session, action->remote_resources, _download_reporting_callback); xccdf_session_set_custom_oval_files(session, action->f_ovals); xccdf_session_set_product_cpe(session, OSCAP_PRODUCTNAME); if (xccdf_session_load(session) != 0) goto cleanup; /* Select profile */ if (!xccdf_session_set_profile_id(session, action->profile)) { if (action->profile != NULL) report_missing_profile(action); else fprintf(stderr, "No Policy was found for default profile.\n"); goto cleanup; } _register_progress_callback(session, action->progress); /* Perform evaluation */ if (xccdf_session_evaluate(session) != 0) goto cleanup; xccdf_session_set_oval_results_export(session, action->oval_results); xccdf_session_set_oval_variables_export(session, action->export_variables); xccdf_session_set_arf_export(session, action->f_results_arf); if (xccdf_session_export_oval(session) != 0) goto cleanup; else if (action->validate && getenv("OSCAP_FULL_VALIDATION") != NULL && (action->oval_results == true || action->f_results_arf)) fprintf(stdout, "OVAL Results are exported correctly.\n"); xccdf_session_set_check_engine_plugins_results_export(session, action->check_engine_results); if (xccdf_session_export_check_engine_plugins(session) != 0) goto cleanup; if (action->remediate) { if (!action->progress) printf("\n --- Starting Remediation ---\n"); xccdf_session_remediate(session); } xccdf_session_set_xccdf_export(session, action->f_results); xccdf_session_set_report_export(session, action->f_report); if (xccdf_session_export_xccdf(session) != 0) goto cleanup; else if (action->validate && getenv("OSCAP_FULL_VALIDATION") != NULL && (action->f_results || action->f_report || action->f_results_arf)) fprintf(stdout, "XCCDF Results are exported correctly.\n"); if (xccdf_session_export_arf(session) != 0) goto cleanup; else if (action->f_results_arf && getenv("OSCAP_FULL_VALIDATION") != NULL) fprintf(stdout, "Result DataStream exported correctly.\n"); /* Get the result from TestResult model and decide if end with error or with correct return code */ result = xccdf_session_contains_fail_result(session) ? OSCAP_FAIL : OSCAP_OK; cleanup: oscap_print_error(); /* syslog message */ syslog(priority, "Evaluation finished. Return code: %d, Base score %f.", result, session == NULL ? 0 : xccdf_session_get_base_score(session)); if (session != NULL) xccdf_session_free(session); return result; }
int app_xccdf_resolve(const struct oscap_action *action) { char *doc_version = NULL; int ret = OSCAP_ERROR; struct xccdf_benchmark *bench = NULL; if (!action->f_xccdf) { fprintf(stderr, "No input document specified!\n"); return OSCAP_ERROR; } if (!action->f_results) { fprintf(stderr, "No output document filename specified!\n"); return OSCAP_ERROR; } /* validate input */ if (action->validate) { doc_version = xccdf_detect_version(action->f_xccdf); if (!doc_version) { return OSCAP_ERROR; } if (oscap_validate_document(action->f_xccdf, OSCAP_DOCUMENT_XCCDF, doc_version, reporter, (void*) action) != 0) { validation_failed(action->f_xccdf, OSCAP_DOCUMENT_XCCDF, doc_version); goto cleanup; } } bench = xccdf_benchmark_import(action->f_xccdf); if (!bench) goto cleanup; if (action->force) xccdf_benchmark_set_resolved(bench, false); if (xccdf_benchmark_get_resolved(bench)) fprintf(stderr, "Benchmark is already resolved!\n"); else { if (!xccdf_benchmark_resolve(bench)) fprintf(stderr, "Benchmark resolving failure (probably a dependency loop)!\n"); else { if (xccdf_benchmark_export(bench, action->f_results)) { ret = OSCAP_OK; /* validate exported results */ const char* full_validation = getenv("OSCAP_FULL_VALIDATION"); if (action->validate && full_validation) { /* reuse doc_version from unresolved document it should be same in resolved one */ if (oscap_validate_document(action->f_results, OSCAP_DOCUMENT_XCCDF, doc_version, reporter, (void*)action)) { validation_failed(action->f_results, OSCAP_DOCUMENT_XCCDF, doc_version); ret = OSCAP_ERROR; } else fprintf(stdout, "Resolved XCCDF has been exported correctly.\n"); } } } } cleanup: oscap_print_error(); if (bench) xccdf_benchmark_free(bench); if (doc_version) free(doc_version); return ret; }
int app_ds_rds_create(const struct oscap_action *action) { int ret = OSCAP_ERROR; if (action->validate) { struct oscap_source *sds = oscap_source_new_from_file(action->ds_action->file); if (oscap_source_validate(sds, reporter, (void *) action) != 0) { oscap_source_free(sds); goto cleanup; } oscap_source_free(sds); struct oscap_source *result = oscap_source_new_from_file(action->ds_action->xccdf_result); if (oscap_source_validate(result, reporter, (void *) action) != 0) { ret = OSCAP_ERROR; oscap_source_free(result); goto cleanup; } oscap_source_free(result); } char** oval_result_files = malloc(sizeof(char*) * (action->ds_action->oval_result_count + 1)); size_t i; for (i = 0; i < action->ds_action->oval_result_count; ++i) { oval_result_files[i] = action->ds_action->oval_results[i]; if (action->validate) { struct oscap_source *source = oscap_source_new_from_file(oval_result_files[i]); if (oscap_source_validate(source, reporter, (void *) action) != 0) { ret = OSCAP_ERROR; oscap_source_free(source); free(oval_result_files); goto cleanup; } oscap_source_free(source); } } oval_result_files[i] = NULL; ret = ds_rds_create(action->ds_action->file, action->ds_action->xccdf_result, (const char**)oval_result_files, action->ds_action->target); free(oval_result_files); if (ret != 0) { fprintf(stdout, "Failed to create result datastream in ARF."); ret = OSCAP_ERROR; goto cleanup; } const char* full_validation = getenv("OSCAP_FULL_VALIDATION"); if (action->validate && full_validation) { struct oscap_source *rds = oscap_source_new_from_file(action->ds_action->target); if (oscap_source_validate(rds, reporter, (void *) action) != 0) { oscap_source_free(rds); goto cleanup; } oscap_source_free(rds); } ret = OSCAP_OK; cleanup: oscap_print_error(); free(action->ds_action); return ret; }