struct xccdf_check *xccdf_check_parse(xmlTextReaderPtr reader) { xccdf_element_t el = xccdf_element_get(reader); if (el != XCCDFE_CHECK && el != XCCDFE_COMPLEX_CHECK) return NULL; struct xccdf_check *check = xccdf_check_new(); check->id = xccdf_attribute_copy(reader, XCCDFA_ID); check->system = xccdf_attribute_copy(reader, XCCDFA_SYSTEM); check->selector = xccdf_attribute_copy(reader, XCCDFA_SELECTOR); check->oper = oscap_string_to_enum(XCCDF_BOOLOP_MAP, xccdf_attribute_get(reader, XCCDFA_OPERATOR)); if (xccdf_attribute_has(reader, XCCDFA_MULTICHECK) && el != XCCDFE_COMPLEX_CHECK) { check->flags.def_multicheck = true; check->flags.multicheck = xccdf_attribute_get_bool(reader, XCCDFA_MULTICHECK); } check->flags.def_negate = xccdf_attribute_has(reader, XCCDFA_NEGATE); check->flags.negate = xccdf_attribute_get_bool(reader, XCCDFA_NEGATE); int depth = oscap_element_depth(reader) + 1; while (oscap_to_start_element(reader, depth)) { switch (xccdf_element_get(reader)) { case XCCDFE_CHECK: case XCCDFE_COMPLEX_CHECK: if (check->oper == 0) break; oscap_list_add(check->children, xccdf_check_parse(reader)); break; case XCCDFE_CHECK_CONTENT_REF:{ const char *href = xccdf_attribute_get(reader, XCCDFA_HREF); if (href == NULL) break; struct xccdf_check_content_ref *ref = xccdf_check_content_ref_new(); ref->name = xccdf_attribute_copy(reader, XCCDFA_NAME); ref->href = strdup(href); oscap_list_add(check->content_refs, ref); break; } case XCCDFE_CHECK_CONTENT: if (check->content == NULL) check->content = oscap_get_xml(reader); break; case XCCDFE_CHECK_IMPORT:{ const char *name = xccdf_attribute_get(reader, XCCDFA_IMPORT_NAME); const char *xpath = xccdf_attribute_get(reader, XCCDFA_IMPORT_XPATH); if (name == NULL) // @import-name is a required attribute break; struct xccdf_check_import *imp = xccdf_check_import_new(); imp->name = strdup(name); if (xpath) // @import-xpath is just optional imp->xpath = strdup(xpath); imp->content = oscap_element_string_copy(reader); oscap_list_add(check->imports, imp); break; } case XCCDFE_CHECK_EXPORT:{ const char *name = xccdf_attribute_get(reader, XCCDFA_EXPORT_NAME); if (name == NULL) break; struct xccdf_check_export *exp = xccdf_check_export_new(); exp->name = strdup(name); exp->value = xccdf_attribute_copy(reader, XCCDFA_VALUE_ID); oscap_list_add(check->exports, exp); break; } default: break; } xmlTextReaderRead(reader); } return check; }
struct xccdf_tailoring *xccdf_tailoring_parse(xmlTextReaderPtr reader, struct xccdf_item *benchmark) { XCCDF_ASSERT_ELEMENT(reader, XCCDFE_TAILORING); struct xccdf_tailoring *tailoring = xccdf_tailoring_new(); const char *id = xccdf_attribute_get(reader, XCCDFA_ID); xccdf_tailoring_set_id(tailoring, id); int depth = oscap_element_depth(reader) + 1; // Read to the inside of Tailoring. xmlTextReaderRead(reader); while (oscap_to_start_element(reader, depth)) { switch (xccdf_element_get(reader)) { case XCCDFE_BENCHMARK_REF: { oscap_free(tailoring->benchmark_ref); tailoring->benchmark_ref = 0; oscap_free(tailoring->benchmark_ref_version); tailoring->benchmark_ref_version = 0; const char *ref = xccdf_attribute_get(reader, XCCDFA_HREF); if (ref) tailoring->benchmark_ref = oscap_strdup(ref); const char *ref_version = xccdf_attribute_get(reader, XCCDFA_VERSION); if (ref_version) tailoring->benchmark_ref_version = oscap_strdup(ref_version); break; } case XCCDFE_STATUS: { const char *date = xccdf_attribute_get(reader, XCCDFA_DATE); char *str = oscap_element_string_copy(reader); struct xccdf_status *status = xccdf_status_new_fill(str, date); oscap_free(str); oscap_list_add(tailoring->statuses, status); break; } case XCCDFE_DC_STATUS: oscap_list_add(tailoring->dc_statuses, oscap_reference_new_parse(reader)); break; case XCCDFE_VERSION: { xmlNode *ver = xmlTextReaderExpand(reader); /* optional attributes */ tailoring->version_time = (char*) xmlGetProp(ver, BAD_CAST "time"); tailoring->version_update = (char*) xmlGetProp(ver, BAD_CAST "update"); /* content */ tailoring->version = (char *) xmlNodeGetContent(ver); if (oscap_streq(tailoring->version, "")) { oscap_free(tailoring->version); tailoring->version = NULL; } break; } case XCCDFE_METADATA: { char* xml = oscap_get_xml(reader); oscap_list_add(tailoring->metadata, oscap_strdup(xml)); oscap_free(xml); break; } case XCCDFE_PROFILE: { struct xccdf_item *item = xccdf_profile_parse(reader, benchmark); if (!xccdf_tailoring_add_profile(tailoring, XPROFILE(item))) { dW("Failed to add profile to tailoring while parsing!"); } break; } default: dW("Encountered an unknown element '%s' while parsing XCCDF Tailoring element.", xmlTextReaderConstLocalName(reader)); } xmlTextReaderRead(reader); } return tailoring; }