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); }
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); }
static void xccdf_resolve_item(struct xccdf_item *item, struct xccdf_tailoring *tailoring) { assert(item != NULL); if (xccdf_item_get_type(item) == XCCDF_BENCHMARK) { xccdf_benchmark_set_resolved(xccdf_item_to_benchmark(item), true); return; // benchmark has no extends } assert(!xccdf_item_get_extends(item) || xccdf_item_get_type(item) & (XCCDF_PROFILE | XCCDF_ITEM)); struct xccdf_item *parent = NULL; if (xccdf_item_get_type(item) == XCCDF_PROFILE && tailoring != NULL) { parent = XITEM(_xccdf_tailoring_profile_get_real_parent(tailoring, XPROFILE(item))); } else { parent = xccdf_benchmark_get_member(xccdf_item_get_benchmark(item), xccdf_item_get_type(item), xccdf_item_get_extends(item)); } if (parent == NULL) return; if (xccdf_item_get_type(item) != xccdf_item_get_type(parent)) return; if (xccdf_item_get_type(item) == XCCDF_GROUP && xccdf_version_cmp(xccdf_item_get_schema_version(item), "1.2") >= 0) return; // Group/@extends= has been obsoleted in XCCDF 1.2 // resolve flags XCCDF_RESOLVE_FLAG(item, parent, selected); XCCDF_RESOLVE_FLAG(item, parent, hidden); XCCDF_RESOLVE_FLAG(item, parent, prohibit_changes); XCCDF_RESOLVE_FLAG(item, parent, interactive); XCCDF_RESOLVE_FLAG(item, parent, multiple); // resolve weight & version if (!item->item.defined_flags.weight) xccdf_item_set_weight(item, xccdf_item_get_weight(parent)); if (xccdf_item_get_version(item) == NULL) { xccdf_item_set_version(item, xccdf_item_get_version(parent)); xccdf_item_set_version_update(item, xccdf_item_get_version_update(parent)); xccdf_item_set_version_time(item, xccdf_item_get_version_time(parent)); } // resolve textual elements xccdf_resolve_textlist(item->item.title, parent->item.title, NULL); xccdf_resolve_textlist(item->item.description, parent->item.description, NULL); xccdf_resolve_textlist(item->item.question, parent->item.question, NULL); xccdf_resolve_textlist(item->item.rationale, parent->item.rationale, NULL); xccdf_resolve_textlist(item->item.warnings, parent->item.warnings, xccdf_resolve_warning); xccdf_resolve_textlist(item->item.references, parent->item.references, NULL); // resolve platforms OSCAP_FOR_STR(platform, xccdf_item_get_platforms(parent)) xccdf_item_add_platform(item, platform); // resolve properties specific to particular item type switch (xccdf_item_get_type(item)) { case XCCDF_PROFILE: xccdf_resolve_profile(item, parent); break; case XCCDF_GROUP: xccdf_resolve_group(item, parent); break; case XCCDF_RULE: xccdf_resolve_rule(item, parent); break; case XCCDF_VALUE: xccdf_resolve_value(item, parent); break; default: assert(false); } // item resolved -> it no longer has a parent xccdf_item_set_extends(item, NULL); }