static bool valid_inputs(const struct oscap_action *action) { bool result = true; /* validate SDS or OVAL Definitions & Variables & Syschars, depending on the data */ struct oscap_source *definitions_source = oscap_source_new_from_file(action->f_oval); if (oscap_source_get_scap_type(definitions_source) != OSCAP_DOCUMENT_OVAL_DEFINITIONS && oscap_source_get_scap_type(definitions_source) != OSCAP_DOCUMENT_SDS) { fprintf(stderr, "Type mismatch: %s. Expecting OVAL Definition or Source DataStream, but found %s.\n", action->f_oval, oscap_document_type_to_string(oscap_source_get_scap_type(definitions_source))); result = false; } if (oscap_source_validate(definitions_source, reporter, (void *) action)) { result = false; } oscap_source_free(definitions_source); if (action->f_variables) { struct oscap_source *variables_source = oscap_source_new_from_file(action->f_variables); if (oscap_source_get_scap_type(variables_source) != OSCAP_DOCUMENT_OVAL_VARIABLES) { fprintf(stderr, "Type mismatch: %s. Expecting OVAL Variables, but found %s.\n", action->f_variables, oscap_document_type_to_string(oscap_source_get_scap_type(variables_source))); result = false; } if (oscap_source_validate(variables_source, reporter, (void *) action)) { result = false; } oscap_source_free(variables_source); } if (action->f_directives) { struct oscap_source *directives_source = oscap_source_new_from_file(action->f_directives); if (oscap_source_get_scap_type(directives_source) != OSCAP_DOCUMENT_OVAL_DIRECTIVES) { fprintf(stderr, "Type mismatch: %s. Expecting OVAL Directives, but found %s.\n", action->f_directives, oscap_document_type_to_string(oscap_source_get_scap_type(directives_source))); result = false; } if (oscap_source_validate(directives_source, reporter, (void *) action)) { result = false; } oscap_source_free(directives_source); } if (action->module == &OVAL_ANALYSE && action->f_syschar) { struct oscap_source *syschar_source = oscap_source_new_from_file(action->f_syschar); if (oscap_source_get_scap_type(syschar_source) != OSCAP_DOCUMENT_OVAL_SYSCHAR) { fprintf(stderr, "Type mismatch: %s. Expecting OVAL System Characteristic, but found %s.\n", action->f_syschar, oscap_document_type_to_string(oscap_source_get_scap_type(syschar_source))); result = false; } if (oscap_source_validate(syschar_source, reporter, (void *) action)) { result = false; } oscap_source_free(syschar_source); } return result; }
static int app_oval_validate(const struct oscap_action *action) { int ret; int result = OSCAP_ERROR; struct oscap_source *source = oscap_source_new_from_file(action->f_oval); ret = oscap_source_validate(source, reporter, (void *) action); if (ret == -1) { result = OSCAP_ERROR; goto cleanup; } else { result = ret == 1 ? OSCAP_FAIL : OSCAP_OK; } /* schematron-based validation requested We can only do schematron validation if the file isn't a source datastream */ if (action->schematron && oscap_source_get_scap_type(source) != OSCAP_DOCUMENT_SDS) { ret = oscap_source_validate_schematron(source, NULL); if (ret==-1) { result=OSCAP_ERROR; } else if (ret>0) { result=OSCAP_FAIL; } } cleanup: oscap_source_free(source); if (oscap_err()) fprintf(stderr, "%s %s\n", OSCAP_ERR_MSG, oscap_err_desc()); return result; }
struct ds_rds_session *ds_rds_session_new_from_source(struct oscap_source *source) { if (oscap_source_get_scap_type(source) != OSCAP_DOCUMENT_ARF) { oscap_seterr(OSCAP_EFAMILY_OSCAP, "Could not create Result DataStream " "session: File is not Result DataStream."); return NULL; } struct ds_rds_session *rds_session = (struct ds_rds_session *) oscap_calloc(1, sizeof(struct ds_rds_session)); rds_session->source = source; rds_session->component_sources = oscap_htable_new(); return rds_session; }
struct ds_sds_session *ds_sds_session_new_from_source(struct oscap_source *source) { if (oscap_source_get_scap_type(source) != OSCAP_DOCUMENT_SDS) { oscap_seterr(OSCAP_EFAMILY_OSCAP, "Could not create Source DataStream " "session: File is not Source DataStream."); return NULL; } struct ds_sds_session *sds_session = (struct ds_sds_session *) oscap_calloc(1, sizeof(struct ds_sds_session)); sds_session->source = source; sds_session->component_sources = oscap_htable_new(); sds_session->progress = download_progress_empty_calllback; return sds_session; }
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 ds_sds_compose_add_component_with_ref(xmlDocPtr doc, xmlNodePtr datastream, const char* filepath, const char* cref_id) { xmlNsPtr ds_ns = xmlSearchNsByHref(doc, datastream, BAD_CAST datastream_ns_uri); xmlNsPtr xlink_ns = xmlSearchNsByHref(doc, datastream, BAD_CAST xlink_ns_uri); xmlNsPtr cat_ns = xmlSearchNsByHref(doc, datastream, BAD_CAST cat_ns_uri); // In case we already have this component we just return, no need to add // it twice. We will typically have many references to OVAL files, adding // component for each reference would create unnecessarily huge datastreams int result = ds_sds_compose_has_component_ref(doc, datastream, filepath, cref_id); if (result == 0) { return 0; } if (result == -1) { // no need to free anything // oscap_seterr has already been called return -1; } xmlNodePtr cref_catalog = xmlNewNode(cat_ns, BAD_CAST "catalog"); xmlNodePtr cref_parent; bool extended_component = false; struct oscap_source *component_source = oscap_source_new_from_file(filepath); oscap_document_type_t doc_type = oscap_source_get_scap_type(component_source); if (doc_type == OSCAP_DOCUMENT_XCCDF) { cref_parent = node_get_child_element(datastream, "checklists"); if (ds_sds_compose_add_component_dependencies(doc, datastream, component_source, cref_catalog, doc_type) != 0) { // oscap_seterr has already been called oscap_source_free(component_source); return -1; } } else if (doc_type == OSCAP_DOCUMENT_CPE_DICTIONARY || doc_type == OSCAP_DOCUMENT_CPE_LANGUAGE) { cref_parent = node_get_child_element(datastream, "dictionaries"); if (cref_parent == NULL) { cref_parent = xmlNewNode(ds_ns, BAD_CAST "dictionaries"); // The <ds:dictionaries element must as the first child of the datastream xmlNodePtr first_child = datastream->xmlChildrenNode; xmlNodePtr new_node = (first_child == NULL) ? xmlAddChild(datastream, cref_parent) : xmlAddPrevSibling(first_child, cref_parent); if (new_node == NULL) { oscap_seterr(OSCAP_EFAMILY_XML, "Failed to add dictionaries element to the DataStream."); xmlFreeNode(cref_parent); cref_parent = NULL; } } if (ds_sds_compose_add_component_dependencies(doc, datastream, component_source, cref_catalog, doc_type) != 0) { oscap_source_free(component_source); return -1; } } else if (doc_type == OSCAP_DOCUMENT_OVAL_DEFINITIONS || doc_type == OSCAP_DOCUMENT_OCIL) { cref_parent = node_get_child_element(datastream, "checks"); } else { // not an XCCDF file, not an OVAL file, not a dict/lang, assume it goes into extended components extended_component = true; cref_parent = node_get_child_element(datastream, "extended-components"); } oscap_source_free(component_source); char* mangled_filepath = ds_sds_mangle_filepath(filepath); // extended components (sadly :-/) use a different ID scheme and have // a different element name than "normal" components char* comp_id = oscap_sprintf("scap_org.open-scap_%scomp_%s", extended_component ? "e" : "", mangled_filepath); int counter = 0; while (_lookup_component_in_collection(doc, comp_id) != NULL) { // While a component of the given ID already exists, generate a new one oscap_free(comp_id); comp_id = oscap_sprintf("scap_org.open-scap_%scomp_%s%03d", extended_component ? "e" : "", mangled_filepath, counter++); } oscap_free(mangled_filepath); result = ds_sds_compose_add_component_internal(doc, datastream, filepath, comp_id, extended_component); if (result == 0) { xmlNodePtr cref = xmlNewNode(ds_ns, BAD_CAST "component-ref"); xmlAddChild(cref, cref_catalog); xmlSetProp(cref, BAD_CAST "id", BAD_CAST cref_id); const char* xlink_href = oscap_sprintf("#%s", comp_id); xmlSetNsProp(cref, xlink_ns, BAD_CAST "href", BAD_CAST xlink_href); oscap_free(xlink_href); if (xmlAddChild(cref_parent, cref) == NULL) { oscap_seterr(OSCAP_EFAMILY_XML, "Failed to add component-ref/@id='%s' to the DataStream.", cref_id); result = 1; } } oscap_free(comp_id); // the source data stream XSD requires either no catalog or a non-empty one if (cref_catalog->children == NULL) { xmlUnlinkNode(cref_catalog); xmlFreeNode(cref_catalog); } return result; }