struct xccdf_fixtext *xccdf_fixtext_parse(xmlTextReaderPtr reader) { struct xccdf_fixtext *fix = xccdf_fixtext_new(); fix->fixref = xccdf_attribute_copy(reader, XCCDFA_FIXREF); fix->text = oscap_text_new_parse(XCCDF_TEXT_HTMLSUB, reader); fix->reboot = xccdf_attribute_get_bool(reader, XCCDFA_REBOOT); fix->strategy = oscap_string_to_enum(XCCDF_STRATEGY_MAP, xccdf_attribute_get(reader, XCCDFA_STRATEGY)); fix->disruption = oscap_string_to_enum(XCCDF_LEVEL_MAP, xccdf_attribute_get(reader, XCCDFA_DISRUPTION)); fix->complexity = oscap_string_to_enum(XCCDF_LEVEL_MAP, xccdf_attribute_get(reader, XCCDFA_COMPLEXITY)); return fix; }
struct cpe_platform *cpe_platform_parse(xmlTextReaderPtr reader) { struct cpe_platform *ret; __attribute__nonnull__(reader); // allocate platform structure here ret = cpe_platform_new(); if (ret == NULL) return NULL; // parse platform attributes here ret->id = (char *)xmlTextReaderGetAttribute(reader, ATTR_ID_STR); if (ret->id == NULL) { cpe_platform_free(ret); return NULL; // if there is no "id" in platform element, return NULL } // skip from <platform> node to next one xmlTextReaderNextNode(reader); // while we have element that is not "platform", it is inside this element, otherwise it's ended // element </platform> and we should end. If there is no one from "if" statement cases, we are parsing // attribute or text ,.. and we can continue to next node. while (xmlStrcmp(xmlTextReaderConstLocalName(reader), TAG_PLATFORM_STR) != 0) { if (!xmlStrcmp(xmlTextReaderConstLocalName(reader), ATTR_TITLE_STR) && xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) { oscap_list_add(ret->titles, oscap_text_new_parse(OSCAP_TEXT_TRAITS_PLAIN, reader)); } else if (!xmlStrcmp(xmlTextReaderConstLocalName(reader), TAG_REMARK_STR) && xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) { ret->remark = parse_text_element(reader, (char *)TAG_REMARK_STR); // TODO: 0-n remarks ! } else if (!xmlStrcmp(xmlTextReaderConstLocalName(reader), TAG_LOGICAL_TEST_STR) && xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) { /* Maybe we shall not allocate this in constructor? */ cpe_testexpr_free(ret->expr); ret->expr = cpe_testexpr_parse(reader); } else if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) oscap_seterr(OSCAP_EFAMILY_OSCAP, "Unknown XML element in platform"); // get the next node xmlTextReaderNextNode(reader); } return ret; }
struct xccdf_item *xccdf_rule_parse(xmlTextReaderPtr reader, struct xccdf_item *parent) { XCCDF_ASSERT_ELEMENT(reader, XCCDFE_RULE); struct xccdf_item *rule = xccdf_rule_new_internal(parent); if (!xccdf_item_process_attributes(rule, reader)) { xccdf_rule_free(rule); return NULL; } if (xccdf_attribute_has(reader, XCCDFA_ROLE)) { rule->sub.rule.role = oscap_string_to_enum(XCCDF_ROLE_MAP, xccdf_attribute_get(reader, XCCDFA_ROLE)); rule->item.defined_flags.role = true; } if (xccdf_attribute_has(reader, XCCDFA_SEVERITY)) { rule->sub.rule.severity = oscap_string_to_enum(XCCDF_LEVEL_MAP, xccdf_attribute_get(reader, XCCDFA_SEVERITY)); rule->item.defined_flags.severity = true; } int depth = oscap_element_depth(reader) + 1; while (oscap_to_start_element(reader, depth)) { switch (xccdf_element_get(reader)) { case XCCDFE_REQUIRES: case XCCDFE_CONFLICTS: xccdf_item_parse_deps(reader, rule); break; case XCCDFE_PROFILE_NOTE:{ const char *tag = xccdf_attribute_get(reader, XCCDFA_TAG); if (tag == NULL) break; struct xccdf_profile_note *note = xccdf_profile_note_new(); note->reftag = strdup(tag); note->text = oscap_text_new_parse(XCCDF_TEXT_PROFNOTE, reader); oscap_list_add(rule->sub.rule.profile_notes, note); break; } case XCCDFE_COMPLEX_CHECK: case XCCDFE_CHECK:{ struct xccdf_check *check = xccdf_check_parse(reader); if (check == NULL) break; oscap_list_add(rule->sub.rule.checks, check); break; } case XCCDFE_FIX: oscap_list_add(rule->sub.rule.fixes, xccdf_fix_parse(reader)); break; case XCCDFE_FIXTEXT: oscap_list_add(rule->sub.rule.fixtexts, xccdf_fixtext_parse(reader)); break; case XCCDFE_IDENT: oscap_list_add(rule->sub.rule.idents, xccdf_ident_parse(reader)); break; default: if (!xccdf_item_process_element(rule, reader)) dW("Encountered an unknown element '%s' while parsing XCCDF group.", xmlTextReaderConstLocalName(reader)); } xmlTextReaderRead(reader); } return rule; }
bool xccdf_benchmark_parse(struct xccdf_item * benchmark, xmlTextReaderPtr reader) { XCCDF_ASSERT_ELEMENT(reader, XCCDFE_BENCHMARK); assert(benchmark != NULL); if (benchmark->type != XCCDF_BENCHMARK) return false; xccdf_benchmark_set_schema_version(XBENCHMARK(benchmark), xccdf_detect_version_parser(reader)); if (!xccdf_item_process_attributes(benchmark, reader)) { xccdf_benchmark_free(XBENCHMARK(benchmark)); return false; } benchmark->sub.benchmark.style = xccdf_attribute_copy(reader, XCCDFA_STYLE); benchmark->sub.benchmark.style_href = xccdf_attribute_copy(reader, XCCDFA_STYLE_HREF); benchmark->sub.benchmark.lang = (char *) xmlTextReaderXmlLang(reader); if (xccdf_attribute_has(reader, XCCDFA_RESOLVED)) benchmark->item.flags.resolved = xccdf_attribute_get_bool(reader, XCCDFA_RESOLVED); int depth = oscap_element_depth(reader) + 1; while (oscap_to_start_element(reader, depth)) { struct xccdf_model *parsed_model; switch (xccdf_element_get(reader)) { case XCCDFE_NOTICE: oscap_list_add(benchmark->sub.benchmark.notices, xccdf_notice_new_parse(reader)); break; case XCCDFE_FRONT_MATTER: oscap_list_add(benchmark->sub.benchmark.front_matter, oscap_text_new_parse(XCCDF_TEXT_HTMLSUB, reader)); break; case XCCDFE_REAR_MATTER: oscap_list_add(benchmark->sub.benchmark.rear_matter, oscap_text_new_parse(XCCDF_TEXT_HTMLSUB, reader)); break; case XCCDFE_PLATFORM: oscap_list_add(benchmark->item.platforms, xccdf_attribute_copy(reader, XCCDFA_IDREF)); break; case XCCDFE_MODEL: parsed_model = xccdf_model_new_xml(reader); // we won't add the implied default scoring model, it is already in the benchmark if (strcmp(xccdf_model_get_system(parsed_model), "urn:xccdf:scoring:default") != 0) assume_ex(xccdf_benchmark_add_model(XBENCHMARK(benchmark), parsed_model), false); else xccdf_model_free(parsed_model); break; case XCCDFE_PLAIN_TEXT:{ const char *id = xccdf_attribute_get(reader, XCCDFA_ID); const char *data = oscap_element_string_get(reader); if (id) oscap_list_add(benchmark->sub.benchmark.plain_texts, xccdf_plain_text_new_fill(id, data == NULL ? "" : data)); break; } case XCCDFE_CPE_LIST:{ struct cpe_parser_ctx *ctx = cpe_parser_ctx_from_reader(reader); xccdf_benchmark_set_cpe_list(XBENCHMARK(benchmark), cpe_dict_model_parse(ctx)); cpe_parser_ctx_free(ctx); break; } case XCCDFE_CPE2_PLATFORMSPEC: xccdf_benchmark_set_cpe_lang_model(XBENCHMARK(benchmark), cpe_lang_model_parse(reader)); break; case XCCDFE_PROFILE: oscap_list_add(benchmark->sub.benchmark.profiles, xccdf_profile_parse(reader, benchmark)); break; case XCCDFE_GROUP: case XCCDFE_RULE: xccdf_content_parse(reader, benchmark); break; case XCCDFE_VALUE: oscap_list_add(benchmark->sub.benchmark.values, xccdf_value_parse(reader, benchmark)); break; case XCCDFE_TESTRESULT: assume_ex(xccdf_benchmark_add_result(XBENCHMARK(benchmark), xccdf_result_new_parse(reader)), false); break; default: if (!xccdf_item_process_element(benchmark, reader)) dW("Encountered an unknown element '%s' while parsing XCCDF benchmark.", xmlTextReaderConstLocalName(reader)); } xmlTextReaderRead(reader); } return true; }