void xccdf_rule_to_dom(struct xccdf_rule *rule, xmlNode *rule_node, xmlDoc *doc, xmlNode *parent) { const struct xccdf_version_info* version_info = xccdf_item_get_schema_version(XITEM(rule)); xmlNs *ns_xccdf = lookup_xccdf_ns(doc, parent, version_info); /* Handle Attributes */ const char *extends = xccdf_rule_get_extends(rule); if (extends) xmlNewProp(rule_node, BAD_CAST "extends", BAD_CAST extends); if (xccdf_rule_get_multiple(rule)) xmlNewProp(rule_node, BAD_CAST "multiple", BAD_CAST "true"); if (xccdf_rule_get_selected(rule)) xmlNewProp(rule_node, BAD_CAST "selected", BAD_CAST "true"); else xmlNewProp(rule_node, BAD_CAST "selected", BAD_CAST "false"); if (XITEM(rule)->item.defined_flags.weight) { char *weight_str = oscap_sprintf("%f", xccdf_rule_get_weight(rule)); xmlNewProp(rule_node, BAD_CAST "weight", BAD_CAST weight_str); free(weight_str); } xccdf_role_t role = xccdf_rule_get_role(rule); if (role != 0) xmlNewProp(rule_node, BAD_CAST "role", BAD_CAST XCCDF_ROLE_MAP[role - 1].string); xccdf_level_t severity = xccdf_rule_get_severity(rule); if (severity != XCCDF_LEVEL_NOT_DEFINED) xmlNewProp(rule_node, BAD_CAST "severity", BAD_CAST XCCDF_LEVEL_MAP[severity - 1].string); /* Handle Child Nodes */ xccdf_texts_to_dom(xccdf_rule_get_rationale(rule), rule_node, "rationale"); struct oscap_string_iterator *platforms = xccdf_rule_get_platforms(rule); while (oscap_string_iterator_has_more(platforms)) { const char *platform = oscap_string_iterator_next(platforms); xmlNode * child = xmlNewTextChild(rule_node, ns_xccdf, BAD_CAST "platform", BAD_CAST NULL); xmlNewProp(child, BAD_CAST "idref", BAD_CAST platform); } oscap_string_iterator_free(platforms); struct oscap_stringlist_iterator *lists = xccdf_rule_get_requires(rule); while (oscap_stringlist_iterator_has_more(lists)) { struct oscap_stringlist *list = oscap_stringlist_iterator_next(lists); struct oscap_string_iterator *strings = oscap_stringlist_get_strings(list); while (oscap_string_iterator_has_more(strings)) { const char *requires = oscap_string_iterator_next(strings); xmlNode * child = xmlNewTextChild(rule_node, ns_xccdf, BAD_CAST "requires", BAD_CAST NULL); xmlNewProp(child, BAD_CAST "idref", BAD_CAST requires); } oscap_string_iterator_free(strings); } oscap_stringlist_iterator_free(lists); struct oscap_string_iterator *conflicts = xccdf_rule_get_conflicts(rule); while (oscap_string_iterator_has_more(conflicts)) { const char *conflict = oscap_string_iterator_next(conflicts); xmlNode * child = xmlNewTextChild(rule_node, ns_xccdf, BAD_CAST "conflicts", BAD_CAST NULL); xmlNewProp(child, BAD_CAST "idref", BAD_CAST conflict); } oscap_string_iterator_free(conflicts); struct xccdf_ident_iterator *idents = xccdf_rule_get_idents(rule); while (xccdf_ident_iterator_has_more(idents)) { struct xccdf_ident *ident = xccdf_ident_iterator_next(idents); xccdf_ident_to_dom(ident, doc, rule_node, version_info); } xccdf_ident_iterator_free(idents); struct xccdf_profile_note_iterator *notes = xccdf_rule_get_profile_notes(rule); while (xccdf_profile_note_iterator_has_more(notes)) { struct xccdf_profile_note *note = xccdf_profile_note_iterator_next(notes); xccdf_profile_note_to_dom(note, doc, rule_node); } xccdf_profile_note_iterator_free(notes); struct xccdf_fixtext_iterator *fixtexts = xccdf_rule_get_fixtexts(rule); while (xccdf_fixtext_iterator_has_more(fixtexts)) { struct xccdf_fixtext *fixtext = xccdf_fixtext_iterator_next(fixtexts); xccdf_fixtext_to_dom(fixtext, doc, rule_node); } xccdf_fixtext_iterator_free(fixtexts); struct xccdf_fix_iterator *fixes = xccdf_rule_get_fixes(rule); while (xccdf_fix_iterator_has_more(fixes)) { struct xccdf_fix *fix = xccdf_fix_iterator_next(fixes); xccdf_fix_to_dom(fix, doc, rule_node, version_info); } xccdf_fix_iterator_free(fixes); struct xccdf_check_iterator *checks = xccdf_rule_get_checks(rule); while (xccdf_check_iterator_has_more(checks)) { struct xccdf_check *check = xccdf_check_iterator_next(checks); xccdf_check_to_dom(check, doc, rule_node, version_info); } xccdf_check_iterator_free(checks); }
void xccdf_group_to_dom(struct xccdf_group *group, xmlNode *group_node, xmlDoc *doc, xmlNode *parent) { const struct xccdf_version_info* version_info = xccdf_item_get_schema_version(XITEM(group)); xmlNs *ns_xccdf = lookup_xccdf_ns(doc, parent, version_info); /* Handle Attributes */ const char *extends = xccdf_group_get_extends(group); if (extends) xmlNewProp(group_node, BAD_CAST "extends", BAD_CAST extends); if (XITEM(group)->item.defined_flags.selected) { if (xccdf_group_get_selected(group)) xmlNewProp(group_node, BAD_CAST "selected", BAD_CAST "true"); else xmlNewProp(group_node, BAD_CAST "selected", BAD_CAST "false"); } if (XITEM(group)->item.defined_flags.weight) { float weight = xccdf_group_get_weight(group); char *weight_str = oscap_sprintf("%f", weight); xmlNewProp(group_node, BAD_CAST "weight", BAD_CAST weight_str); free(weight_str); } /* Handle Child Nodes */ xccdf_texts_to_dom(xccdf_group_get_rationale(group), group_node, "rationale"); struct oscap_string_iterator *platforms = xccdf_group_get_platforms(group); while (oscap_string_iterator_has_more(platforms)) { const char *platform = oscap_string_iterator_next(platforms); xmlNode * child = xmlNewTextChild(group_node, ns_xccdf, BAD_CAST "platform", BAD_CAST NULL); xmlNewProp(child, BAD_CAST "idref", BAD_CAST platform); } oscap_string_iterator_free(platforms); struct oscap_stringlist_iterator *lists = xccdf_group_get_requires(group); while (oscap_stringlist_iterator_has_more(lists)) { struct oscap_stringlist *list = oscap_stringlist_iterator_next(lists); struct oscap_string_iterator *strings = oscap_stringlist_get_strings(list); while (oscap_string_iterator_has_more(strings)) { const char *requires = oscap_string_iterator_next(strings); xmlNode * child = xmlNewTextChild(group_node, ns_xccdf, BAD_CAST "requires", BAD_CAST NULL); xmlNewProp(child, BAD_CAST "idref", BAD_CAST requires); } oscap_string_iterator_free(strings); } oscap_stringlist_iterator_free(lists); struct oscap_string_iterator *conflicts = xccdf_group_get_conflicts(group); while (oscap_string_iterator_has_more(conflicts)) { const char *conflict = oscap_string_iterator_next(conflicts); xmlNode * child = xmlNewTextChild(group_node, ns_xccdf, BAD_CAST "conflicts", BAD_CAST NULL); xmlNewProp(child, BAD_CAST "idref", BAD_CAST conflict); } oscap_string_iterator_free(conflicts); struct xccdf_value_iterator *values = xccdf_group_get_values(group); while (xccdf_value_iterator_has_more(values)) { struct xccdf_value *value = xccdf_value_iterator_next(values); if (XGROUP(xccdf_value_get_parent(value)) == group) { xccdf_item_to_dom((struct xccdf_item *)value, doc, group_node, version_info); } } xccdf_value_iterator_free(values); struct xccdf_item_iterator *items = xccdf_group_get_content(group); while (xccdf_item_iterator_has_more(items)) { struct xccdf_item *item = xccdf_item_iterator_next(items); if (XGROUP(xccdf_item_get_parent(item)) == group) { xccdf_item_to_dom(item, doc, group_node, version_info); } } xccdf_item_iterator_free(items); }
xmlNode *xccdf_benchmark_to_dom(struct xccdf_benchmark *benchmark, xmlDocPtr doc, xmlNode *parent, void *user_args) { xmlNodePtr root_node = NULL; if (parent) { root_node = xccdf_item_to_dom(XITEM(benchmark), doc, parent); } else { root_node = xccdf_item_to_dom(XITEM(benchmark), doc, parent); xmlDocSetRootElement(doc, root_node); } // FIXME! //xmlNewProp(root_node, BAD_CAST "xsi:schemaLocation", BAD_CAST XCCDF_SCHEMA_LOCATION); xmlNs *ns_xccdf = xmlNewNs(root_node, (const xmlChar*)xccdf_version_info_get_namespace_uri(xccdf_benchmark_get_schema_version(benchmark)), NULL); xmlNs *ns_xsi = xmlNewNs(root_node, XCCDF_XSI_NAMESPACE, BAD_CAST "xsi"); xmlSetNs(root_node, ns_xsi); xmlSetNs(root_node, ns_xccdf); /* Handle attributes */ if (xccdf_benchmark_get_resolved(benchmark)) xmlNewProp(root_node, BAD_CAST "resolved", BAD_CAST "1"); else xmlNewProp(root_node, BAD_CAST "resolved", BAD_CAST "0"); const char *xmllang = xccdf_benchmark_get_lang(benchmark); if (xmllang) xmlNewProp(root_node, BAD_CAST "xml:lang", BAD_CAST xmllang); const char *style = xccdf_benchmark_get_style(benchmark); if (style) xmlNewProp(root_node, BAD_CAST "style", BAD_CAST style); const char *style_href = xccdf_benchmark_get_style_href(benchmark); if (style_href) xmlNewProp(root_node, BAD_CAST "style-href", BAD_CAST style_href); // Export plain-text elements struct xccdf_plain_text_iterator *plain_text_it = xccdf_benchmark_get_plain_texts(benchmark); while (xccdf_plain_text_iterator_has_more(plain_text_it)) { struct xccdf_plain_text *plain_text = xccdf_plain_text_iterator_next(plain_text_it); xccdf_plain_text_to_dom(plain_text, doc, root_node, xccdf_benchmark_get_schema_version(benchmark)); } xccdf_plain_text_iterator_free(plain_text_it); /* Handle children */ if (xccdf_benchmark_get_cpe_list(benchmark)) { // CPE API can only export via xmlTextWriter, we export via DOM // this is used to bridge both methods xmlTextWriterPtr writer = xmlNewTextWriterTree(doc, root_node, 0); cpe_dict_export(xccdf_benchmark_get_cpe_list(benchmark), writer); xmlFreeTextWriter(writer); } if (xccdf_benchmark_get_cpe_lang_model(benchmark)) { // CPE API can only export via xmlTextWriter, we export via DOM // this is used to bridge both methods xmlTextWriterPtr writer = xmlNewTextWriterTree(doc, root_node, 0); cpe_lang_export(xccdf_benchmark_get_cpe_lang_model(benchmark), writer); xmlFreeTextWriter(writer); } struct oscap_string_iterator *platforms = xccdf_benchmark_get_platforms(benchmark); while (oscap_string_iterator_has_more(platforms)) { xmlNode *platform_node = xmlNewTextChild(root_node, ns_xccdf, BAD_CAST "platform", NULL); const char *idref = oscap_string_iterator_next(platforms); if (idref) xmlNewProp(platform_node, BAD_CAST "idref", BAD_CAST idref); } oscap_string_iterator_free(platforms); const char *version = xccdf_benchmark_get_version(benchmark); if (version) xmlNewTextChild(root_node, ns_xccdf, BAD_CAST "version", BAD_CAST version); struct oscap_string_iterator* metadata = xccdf_item_get_metadata(XITEM(benchmark)); while (oscap_string_iterator_has_more(metadata)) { const char* meta = oscap_string_iterator_next(metadata); oscap_xmlstr_to_dom(root_node, "metadata", meta); } oscap_string_iterator_free(metadata); OSCAP_FOR(xccdf_model, model, xccdf_benchmark_get_models(benchmark)) { xmlNode *model_node = xmlNewTextChild(root_node, ns_xccdf, BAD_CAST "model", NULL); xmlNewProp(model_node, BAD_CAST "system", BAD_CAST xccdf_model_get_system(model)); }
xmlNodePtr xccdf_tailoring_to_dom(struct xccdf_tailoring *tailoring, xmlDocPtr doc, xmlNodePtr parent, const struct xccdf_version_info *version_info) { xmlNs *ns_xccdf = xmlSearchNsByHref(doc, parent, BAD_CAST xccdf_version_info_get_namespace_uri(version_info)); xmlNs *ns_tailoring = NULL; xmlNode *tailoring_node = xmlNewNode(ns_xccdf, BAD_CAST "Tailoring"); const char *xccdf_version = xccdf_version_info_get_version(version_info); #ifdef __USE_GNU if (strverscmp(xccdf_version, "1.1") >= 0 && strverscmp(xccdf_version, "1.2") < 0) { #else if (strcmp(xccdf_version, "1.1") >= 0 && strcmp(xccdf_version, "1.2") < 0) { #endif // XCCDF 1.1 does not support Tailoring! // However we will allow Tailoring export if it is done to an external // file. The namespace will be our custom xccdf-1.1-tailoring extension // namespace. if (parent != NULL) { oscap_seterr(OSCAP_EFAMILY_XML, "XCCDF 1.1 does not support embedded Tailoring elements!"); xmlFreeNode(tailoring_node); return NULL; } ns_tailoring = xmlNewNs(tailoring_node, BAD_CAST "http://open-scap.org/page/Xccdf-1.1-tailoring", BAD_CAST "cdf-11-tailoring" ); } #ifdef __USE_GNU else if (strverscmp(xccdf_version, "1.1") < 0) { #else else if (strcmp(xccdf_version, "1.1") < 0) { #endif oscap_seterr(OSCAP_EFAMILY_XML, "XCCDF Tailoring isn't supported in XCCDF version '%s'," "nor does openscap have a custom extension for this scenario. " "XCCDF Tailoring requires XCCDF 1.1 and higher, 1.2 is recommended."); xmlFreeNode(tailoring_node); return NULL; } if (!ns_xccdf) { // In cases where tailoring ends up being the root node we have to create // a namespace at the node itself. ns_xccdf = xmlNewNs(tailoring_node, BAD_CAST xccdf_version_info_get_namespace_uri(version_info), BAD_CAST "xccdf"); } if (!ns_tailoring) ns_tailoring = ns_xccdf; // We intentionally set the wrong namespace here since children of tailoring // will reuse it and we want them to have the xccdf namespace, the namespace // is set to the proper namespace before returning the tailoring. xmlSetNs(tailoring_node, ns_xccdf); if (parent) xmlAddChild(parent, tailoring_node); else xmlDocSetRootElement(doc, tailoring_node); if (tailoring->id) { xmlNewProp(tailoring_node, BAD_CAST "id", BAD_CAST tailoring->id); } if (tailoring->benchmark_ref || tailoring->benchmark_ref_version) { xmlNodePtr benchmark_ref_node = xmlNewChild(tailoring_node, ns_tailoring, BAD_CAST "benchmark", NULL); if (tailoring->benchmark_ref) xmlNewProp(benchmark_ref_node, BAD_CAST "href", BAD_CAST tailoring->benchmark_ref); if (tailoring->benchmark_ref_version) xmlNewProp(benchmark_ref_node, BAD_CAST "version", BAD_CAST tailoring->benchmark_ref_version); } struct xccdf_status_iterator *statuses = xccdf_tailoring_get_statuses(tailoring); while (xccdf_status_iterator_has_more(statuses)) { struct xccdf_status *status = xccdf_status_iterator_next(statuses); xccdf_status_to_dom(status, doc, tailoring_node, version_info); } xccdf_status_iterator_free(statuses); struct oscap_reference_iterator *dc_statuses = xccdf_tailoring_get_dc_statuses(tailoring); while (oscap_reference_iterator_has_more(dc_statuses)) { struct oscap_reference *ref = oscap_reference_iterator_next(dc_statuses); oscap_reference_to_dom(ref, tailoring_node, doc, "dc-status"); } oscap_reference_iterator_free(dc_statuses); /* version and attributes */ const char *version = xccdf_tailoring_get_version(tailoring); if (version) { xmlNode* version_node = xmlNewTextChild(tailoring_node, ns_tailoring, BAD_CAST "version", BAD_CAST version); const char *version_update = xccdf_tailoring_get_version_update(tailoring); if (version_update) xmlNewProp(version_node, BAD_CAST "update", BAD_CAST version_update); const char *version_time = xccdf_tailoring_get_version_time(tailoring); if (version_time) xmlNewProp(version_node, BAD_CAST "time", BAD_CAST version_time); } struct oscap_string_iterator* metadata = xccdf_tailoring_get_metadata(tailoring); while (oscap_string_iterator_has_more(metadata)) { const char* meta = oscap_string_iterator_next(metadata); oscap_xmlstr_to_dom(tailoring_node, "metadata", meta); } oscap_string_iterator_free(metadata); struct xccdf_profile_iterator *profiles = xccdf_tailoring_get_profiles(tailoring); while (xccdf_profile_iterator_has_more(profiles)) { struct xccdf_profile *profile = xccdf_profile_iterator_next(profiles); xccdf_item_to_dom(XITEM(profile), doc, tailoring_node); } xccdf_profile_iterator_free(profiles); xmlSetNs(tailoring_node, ns_tailoring); return tailoring_node; } int xccdf_tailoring_export(struct xccdf_tailoring *tailoring, const char *file, const struct xccdf_version_info *version_info) { __attribute__nonnull__(file); LIBXML_TEST_VERSION; xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0"); if (doc == NULL) { oscap_setxmlerr(xmlGetLastError()); return -1; } xccdf_tailoring_to_dom(tailoring, doc, NULL, version_info); return oscap_xml_save_filename(file, doc); } const char *xccdf_tailoring_get_id(const struct xccdf_tailoring *tailoring) { return tailoring->id; } const char *xccdf_tailoring_get_version(const struct xccdf_tailoring *tailoring) { return tailoring->version; } const char *xccdf_tailoring_get_version_update(const struct xccdf_tailoring *tailoring) { return tailoring->version_update; } const char *xccdf_tailoring_get_version_time(const struct xccdf_tailoring *tailoring) { return tailoring->version_time; } const char *xccdf_tailoring_get_benchmark_ref(const struct xccdf_tailoring *tailoring) { return tailoring->benchmark_ref; } const char *xccdf_tailoring_get_benchmark_ref_version(const struct xccdf_tailoring *tailoring) { return tailoring->benchmark_ref_version; } bool xccdf_tailoring_set_id(struct xccdf_tailoring *tailoring, const char* newval) { if (tailoring->id) oscap_free(tailoring->id); tailoring->id = oscap_strdup(newval); return true; } bool xccdf_tailoring_set_version(struct xccdf_tailoring *tailoring, const char *newval) { if (tailoring->version) oscap_free(tailoring->version); tailoring->version = oscap_strdup(newval); return true; } bool xccdf_tailoring_set_version_update(struct xccdf_tailoring *tailoring, const char *newval) { if (tailoring->version_update) oscap_free(tailoring->version_update); tailoring->version_update = oscap_strdup(newval); return true; } bool xccdf_tailoring_set_version_time(struct xccdf_tailoring *tailoring, const char *newval) { if (tailoring->version_time) oscap_free(tailoring->version_time); tailoring->version_time = oscap_strdup(newval); return true; } bool xccdf_tailoring_set_benchmark_ref(struct xccdf_tailoring *tailoring, const char *newval) { if (tailoring->benchmark_ref) oscap_free(tailoring->benchmark_ref); tailoring->benchmark_ref = oscap_strdup(newval); return true; } bool xccdf_tailoring_set_benchmark_ref_version(struct xccdf_tailoring *tailoring, const char *newval) { if (tailoring->benchmark_ref_version) oscap_free(tailoring->benchmark_ref_version); tailoring->benchmark_ref_version = oscap_strdup(newval); return true; } struct oscap_string_iterator *xccdf_tailoring_get_metadata(const struct xccdf_tailoring *tailoring) { return (struct oscap_string_iterator*) oscap_iterator_new(tailoring->metadata); } struct xccdf_profile_iterator *xccdf_tailoring_get_profiles(const struct xccdf_tailoring *tailoring) { return (struct xccdf_profile_iterator*) oscap_iterator_new(tailoring->profiles); } struct xccdf_status_iterator *xccdf_tailoring_get_statuses(const struct xccdf_tailoring *tailoring) { return (struct xccdf_status_iterator*) oscap_iterator_new(tailoring->statuses); } struct oscap_reference_iterator *xccdf_tailoring_get_dc_statuses(const struct xccdf_tailoring *tailoring) { return (struct oscap_reference_iterator*) oscap_iterator_new(tailoring->dc_statuses); } struct xccdf_profile * xccdf_tailoring_get_profile_by_id(const struct xccdf_tailoring *tailoring, const char *profile_id) { struct xccdf_profile_iterator *profit = xccdf_tailoring_get_profiles(tailoring); while (xccdf_profile_iterator_has_more(profit)) { struct xccdf_profile *profile = xccdf_profile_iterator_next(profit); if (profile == NULL) { assert(profile != NULL); continue; } if (oscap_streq(xccdf_profile_get_id(profile), profile_id)) { xccdf_profile_iterator_free(profit); return profile; } } xccdf_profile_iterator_free(profit); return NULL; }
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; }