/* Private exporting functions cpe_*<structure>*_export( xmlTextWriterPtr ) * More info in representive header file. * returns the type of <structure> */ void cpe_lang_model_export_xml(const struct cpe_lang_model *spec, const char *file) { __attribute__nonnull__(spec); __attribute__nonnull__(file); // TODO: ad macro to check return value from xmlTextWriter* functions xmlTextWriterPtr writer; writer = xmlNewTextWriterFilename(file, 0); if (writer == NULL) { oscap_setxmlerr(xmlGetLastError()); return; } // Set properties of writer TODO: make public function to edit this ?? xmlTextWriterSetIndent(writer, 1); xmlTextWriterSetIndentString(writer, BAD_CAST " "); xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL); cpe_lang_export(spec, writer); xmlTextWriterEndDocument(writer); xmlFreeTextWriter(writer); if (xmlGetLastError() != NULL) oscap_setxmlerr(xmlGetLastError()); }
struct oscap_source *xccdf_benchmark_export_source(struct xccdf_benchmark *benchmark, const char *filename) { xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0"); if (doc == NULL) { oscap_setxmlerr(xmlGetLastError()); return NULL; } xccdf_benchmark_to_dom(benchmark, doc, NULL, NULL); return oscap_source_new_from_xmlDoc(doc, filename); }
const struct xccdf_version_info* xccdf_detect_version_parser(xmlTextReaderPtr reader) { const struct xccdf_version_info *mapptr; const char* namespace_uri = (const char*)xmlTextReaderConstNamespaceUri(reader); if (!namespace_uri) { oscap_setxmlerr(xmlGetLastError()); return NULL; } mapptr = _namespace_get_xccdf_version_info(namespace_uri); if (mapptr == NULL) oscap_seterr(OSCAP_EFAMILY_XML, "This is not known XCCDF namespace: %s.", namespace_uri); return mapptr; }
int oscap_xml_save_filename(const char *filename, xmlDocPtr doc) { xmlOutputBufferPtr buff; int xmlCode; if (strcmp(filename, "-") == 0) { xmlCode = xmlSaveFormatFileEnc(filename, doc, "UTF-8", 1); } else { int fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); if (fd < 0) { oscap_seterr(OSCAP_EFAMILY_GLIBC, "%s '%s'", strerror(errno), filename); xmlFreeDoc(doc); return -1; } buff = xmlOutputBufferCreateFd(fd, NULL); if (buff == NULL) { close(fd); oscap_setxmlerr(xmlGetLastError()); oscap_dlprintf(DBG_W, "xmlOutputBufferCreateFile() failed.\n"); xmlFreeDoc(doc); return -1; } xmlCode = xmlSaveFormatFileTo(buff, doc, "UTF-8", 1); close(fd); } if (xmlCode <= 0) { oscap_setxmlerr(xmlGetLastError()); oscap_dlprintf(DBG_W, "No bytes exported: xmlCode: %d.\n", xmlCode); } return (xmlCode >= 1) ? 1 : -1; }
int oval_definition_model_export(struct oval_definition_model *model, const char *file) { __attribute__nonnull__(model); LIBXML_TEST_VERSION; xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0"); if (doc == NULL) { oscap_setxmlerr(xmlGetLastError()); return -1; } oval_definition_model_to_dom(model, doc, NULL); return oscap_xml_save_filename_free(file, doc); }
int xccdf_benchmark_export(struct xccdf_benchmark *benchmark, const char *file) { __attribute__nonnull__(file); LIBXML_TEST_VERSION; xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0"); if (doc == NULL) { oscap_setxmlerr(xmlGetLastError()); return -1; } xccdf_benchmark_to_dom(benchmark, doc, NULL, NULL); return oscap_xml_save_filename(file, doc); }
static int cpe_ext_deprecatedby_export(const struct cpe_ext_deprecatedby *deprecatedby, xmlTextWriterPtr writer) { __attribute__nonnull__(writer); __attribute__nonnull__(deprecatedby); xmlTextWriterStartElementNS(writer, NULL, BAD_CAST TAG_CPE_EXT_DEPRECATEDBY_STR, BAD_CAST XMLNS_CPE2D3_EXTENSION); if (deprecatedby->name != NULL) { xmlTextWriterWriteAttribute(writer, BAD_CAST ATTR_NAME_STR, BAD_CAST deprecatedby->name); } if (deprecatedby->type != 0) { xmlTextWriterWriteAttribute(writer, BAD_CAST ATTR_TYPE_STR, BAD_CAST oscap_enum_to_string(CPE_EXT_DEPRECATION_MAP, deprecatedby->type)); } xmlTextWriterEndElement(writer); if (xmlGetLastError() != NULL) oscap_setxmlerr(xmlGetLastError()); return 0; }
int oscap_determine_document_type_reader(xmlTextReader *reader, oscap_document_type_t *doc_type) { const char* elm_name = NULL; *doc_type = 0; /* find root element */ while (xmlTextReaderRead(reader) == 1 && xmlTextReaderNodeType(reader) != XML_READER_TYPE_ELEMENT); /* identify document type */ elm_name = (const char *) xmlTextReaderConstLocalName(reader); if (!elm_name) { oscap_setxmlerr(xmlGetLastError()); return -1; } else if (!strcmp("oval_definitions", elm_name)) { *doc_type = OSCAP_DOCUMENT_OVAL_DEFINITIONS; } else if (!strcmp("oval_directives", elm_name)) { *doc_type = OSCAP_DOCUMENT_OVAL_DIRECTIVES; } else if (!strcmp("oval_results", elm_name)) { *doc_type = OSCAP_DOCUMENT_OVAL_RESULTS; } else if (!strcmp("oval_system_characteristics", elm_name)) { *doc_type = OSCAP_DOCUMENT_OVAL_SYSCHAR; } else if (!strcmp("oval_variables", elm_name)) { *doc_type = OSCAP_DOCUMENT_OVAL_VARIABLES; } else if (oscap_streq("Benchmark", elm_name) || oscap_streq("TestResult", elm_name)) { *doc_type = OSCAP_DOCUMENT_XCCDF; } else if (!strcmp("Tailoring", elm_name)) { *doc_type = OSCAP_DOCUMENT_XCCDF_TAILORING; } else if (!strcmp("cpe-list", elm_name)) { *doc_type = OSCAP_DOCUMENT_CPE_DICTIONARY; } else if (!strcmp("platform-specification", elm_name)) { *doc_type = OSCAP_DOCUMENT_CPE_LANGUAGE; } else if (!strcmp("nvd", elm_name)) { *doc_type = OSCAP_DOCUMENT_CVE_FEED; } else if (!strcmp("data-stream-collection", elm_name)) { *doc_type = OSCAP_DOCUMENT_SDS; } else if (!strcmp("asset-report-collection", elm_name)) { *doc_type = OSCAP_DOCUMENT_ARF; } else if (!strcmp("sce_results", elm_name)) { *doc_type = OSCAP_DOCUMENT_SCE_RESULT; } else if (!strcmp("ocil", elm_name)) { *doc_type = OSCAP_DOCUMENT_OCIL; } else { return -1; } dI("Identified document type: %s", elm_name); return 0; }
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; }