int oval_probe_query_sysinfo(oval_probe_session_t *sess, struct oval_sysinfo **out_sysinfo) { struct oval_sysinfo *sysinf; oval_ph_t *ph; int ret; dI("Querying system information."); ph = oval_probe_handler_get(sess->ph, OVAL_INDEPENDENT_SYSCHAR_SUBTYPE); if (ph == NULL) { oscap_seterr (OSCAP_EFAMILY_OVAL, "OVAL object not supported"); return(-1); } if (ph->func == NULL) { oscap_seterr (OSCAP_EFAMILY_OVAL, "OVAL object not correctly defined"); return(-1); } sysinf = NULL; ret = oval_probe_sys_handler(OVAL_INDEPENDENT_SYSCHAR_SUBTYPE, ph->uptr, PROBE_HANDLER_ACT_EVAL, NULL, &sysinf, 0); if (ret != 0) return(ret); *out_sysinfo = sysinf; return(0); }
static bool _recursive_delete_directory(WCHAR *directory) { if (directory == NULL) { return false; } WCHAR find_pattern[MAX_PATH]; wcsncpy(find_pattern, directory, MAX_PATH); wcsncat(find_pattern, L"\\*", MAX_PATH); WCHAR dir_path[MAX_PATH]; wcsncpy(dir_path, directory, MAX_PATH); wcsncat(dir_path, L"\\", MAX_PATH); WCHAR file_path[MAX_PATH]; wcsncpy(file_path, dir_path, MAX_PATH); DWORD err; WIN32_FIND_DATAW find_data; HANDLE find_handle = FindFirstFileW(find_pattern, &find_data); if (find_handle == INVALID_HANDLE_VALUE) { err = GetLastError(); char *error_message = oscap_windows_error_message(err); oscap_seterr(OSCAP_EFAMILY_WINDOWS, "FindFirstFileW error: %s", error_message); free(error_message); return false; } do { if (wcscmp(find_data.cFileName, L".") != 0 && wcscmp(find_data.cFileName, L"..") != 0) { wcsncat(file_path, find_data.cFileName, MAX_PATH); if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (!_recursive_delete_directory(file_path)) { FindClose(find_handle); return false; } } else { if (!DeleteFileW(file_path)) { err = GetLastError(); char *error_message = oscap_windows_error_message(err); oscap_seterr(OSCAP_EFAMILY_WINDOWS, "DeleteFileW Error: %s", error_message); free(error_message); FindClose(find_handle); return false; } } wcsncpy(file_path, dir_path, MAX_PATH); } } while (FindNextFileW(find_handle, &find_data) != 0); FindClose(find_handle); if (!RemoveDirectoryW(dir_path)) { err = GetLastError(); char *error_message = oscap_windows_error_message(err); oscap_seterr(OSCAP_EFAMILY_WINDOWS, "RemoveDirectoryW error: %s", error_message); free(error_message); return false; } return true; }
char *oscap_acquire_temp_dir() { WCHAR temp_path[PATH_MAX]; WCHAR temp_dir[PATH_MAX]; DWORD ret = GetTempPathW(PATH_MAX, temp_path); if (ret > PATH_MAX || ret == 0) { oscap_seterr(OSCAP_EFAMILY_WINDOWS, "Could not retrieve the path of the directory for temporary files."); return NULL; } unsigned int unique; rand_s(&unique); ret = GetTempFileNameW(temp_path, L"oscap", unique, temp_dir); if (ret == 0) { oscap_seterr(OSCAP_EFAMILY_WINDOWS, "Could not get a name for new temporary directory."); return NULL; } char *temp_dir_str = oscap_windows_wstr_to_str(temp_dir); WCHAR *path_prefix = temp_dir; do { /* Use wide characters with L modifier because we work with a wide string. */ WCHAR *delimiter = wcschr(path_prefix, L'\\'); if (delimiter == NULL) { break; } *delimiter = L'\0'; if (!CreateDirectoryW(temp_dir, NULL)) { ret = GetLastError(); if (ret != ERROR_ALREADY_EXISTS) { char *error_message = oscap_windows_error_message(ret); oscap_seterr(OSCAP_EFAMILY_WINDOWS, "Could not create temp directory '%s': %s.", temp_dir_str, error_message); free(error_message); free(temp_dir_str); return NULL; } } *delimiter = L'\\'; path_prefix = ++delimiter; } while (*path_prefix != L'\0'); if (!CreateDirectoryW(temp_dir, NULL)) { ret = GetLastError(); char *error_message = oscap_windows_error_message(ret); oscap_seterr(OSCAP_EFAMILY_WINDOWS, "Could not create temp directory '%s': %s.", temp_dir_str, error_message); free(error_message); free(temp_dir_str); return NULL; } return temp_dir_str; }
struct oscap_source *ds_sds_session_select_tailoring(struct ds_sds_session *session, const char *component_id) { if (ds_sds_session_register_component_with_dependencies(session, "checklists", component_id, "tailoring.xml") != 0) { oscap_seterr(OSCAP_EFAMILY_OSCAP, "Could not extract %s with all dependencies from datastream.", component_id); return NULL; } struct oscap_source *tailoring = oscap_htable_get(session->component_sources, "tailoring.xml"); if (tailoring == NULL) { oscap_seterr(OSCAP_EFAMILY_OSCAP, "Internal error: Could not acquire handle to tailoring.xml source."); } return tailoring; }
//typedef void (*oval_entity_consumer)(struct oval_entity_node*, void*); int oval_entity_parse_tag(xmlTextReaderPtr reader, struct oval_parser_context *context, oscap_consumer_func consumer, void *user) { __attribute__nonnull__(context); struct oval_entity *entity = oval_entity_new(context->definition_model); int return_code = 0; oval_datatype_t datatype = oval_datatype_parse(reader, "datatype", OVAL_DATATYPE_STRING); oval_operation_t operation = oval_operation_parse(reader, "operation", OVAL_OPERATION_EQUALS); int mask = oval_parser_boolean_attribute(reader, "mask", 0); char *nil_attr = (char *) xmlTextReaderGetAttributeNs(reader, BAD_CAST "nil", OSCAP_XMLNS_XSI); int xsi_nil = oscap_streq(nil_attr, "true") != 0; xmlFree(nil_attr); oval_entity_type_t type = OVAL_ENTITY_TYPE_UNKNOWN; //The value of the type field vs. the complexity of extracting type is arguable char *varref = (char *)xmlTextReaderGetAttribute(reader, BAD_CAST "var_ref"); struct oval_value *value = NULL; struct oval_variable *variable; char *name = (char *)xmlTextReaderLocalName(reader); oval_entity_varref_type_t varref_type; if (strcmp(name, "var_ref") == 0) { //special case for <var_ref> if (varref == NULL) { struct oval_definition_model *model = context->definition_model; varref_type = OVAL_ENTITY_VARREF_ELEMENT; struct oval_consume_varref_context ctx = {.model = model, .variable = &variable, .value = &value}; return_code = oscap_parser_text_value(reader, &oval_consume_varref, &ctx); } else { varref_type = OVAL_ENTITY_VARREF_ATTRIBUTE; struct oval_definition_model *model = context->definition_model; oval_schema_version_t version = oval_definition_model_get_core_schema_version(model); if (oval_schema_version_cmp(version, OVAL_SCHEMA_VERSION(5.6)) > 0) { oscap_seterr(OSCAP_EFAMILY_OVAL, "The var_ref attribute for the var_ref entity " "of a variable_object is prohibited since OVAL 5.6. Use plain " "var_ref instead."); } variable = oval_definition_model_get_variable(model, varref); if (variable == NULL) { oscap_seterr(OSCAP_EFAMILY_OVAL, "Could not found variable '%s' referenced by var_ref element.", varref); return_code = 1; } else { oscap_free(varref); varref = NULL; value = NULL; } } } else if (varref == NULL) {
struct xccdf_benchmark *xccdf_benchmark_import_source(struct oscap_source *source) { xmlTextReader *reader = oscap_source_get_xmlTextReader(source); while (xmlTextReaderRead(reader) == 1 && xmlTextReaderNodeType(reader) != XML_READER_TYPE_ELEMENT) ; struct xccdf_benchmark *benchmark = xccdf_benchmark_new(); const bool parse_result = xccdf_benchmark_parse(XITEM(benchmark), reader); xmlFreeTextReader(reader); if (!parse_result) { // parsing fatal error oscap_seterr(OSCAP_EFAMILY_XML, "Failed to import XCCDF content from '%s'.", oscap_source_readable_origin(source)); xccdf_benchmark_free(benchmark); return NULL; } // This is sadly the only place where we can pass origin file information // to the CPE1 embedded dictionary (if any). It is necessary to figure out // proper paths to OVAL files referenced from CPE1 dictionaries. // FIXME: Refactor and move this somewhere else struct cpe_dict_model* embedded_dict = xccdf_benchmark_get_cpe_list(benchmark); if (embedded_dict != NULL) { cpe_dict_model_set_origin_file(embedded_dict, oscap_source_readable_origin(source)); } // same situation with embedded CPE2 lang model // FIXME: Refactor and move this somewhere else struct cpe_lang_model* embedded_lang_model = xccdf_benchmark_get_cpe_lang_model(benchmark); if (embedded_lang_model != NULL) { cpe_lang_model_set_origin_file(embedded_lang_model, oscap_source_readable_origin(source)); } return benchmark; }
static inline void _xccdf_policy_add_xccdf_refine_rule_internal(struct xccdf_policy* policy, struct xccdf_benchmark* benchmark, const struct xccdf_refine_rule* refine_rule) { const char* rr_item_id = xccdf_refine_rule_get_item(refine_rule); struct xccdf_item* item = xccdf_benchmark_get_member(benchmark, XCCDF_ITEM, rr_item_id); if (item != NULL) { // get item by id _add_refine_rule(policy->refine_rules_internal, refine_rule, rr_item_id); return; } // try to get items by cluster-id struct oscap_htable_iterator* hit = xccdf_benchmark_get_cluster_items(benchmark, rr_item_id); if (hit == NULL) { oscap_seterr(OSCAP_EFAMILY_XCCDF, "Selector ID(%s) does not exist in Benchmark.", rr_item_id); return; } while (oscap_htable_iterator_has_more(hit)) { // iterate through every item in cluster const char* item_id = oscap_htable_iterator_next_key(hit); if (item_id == NULL) { assert(item_id != NULL); continue; } _add_refine_rule(policy->refine_rules_internal,refine_rule, item_id); } oscap_htable_iterator_free(hit); }
char * xccdf_detect_version(const char* file) { const struct xccdf_version_info *ver_info; char *doc_version; xmlTextReaderPtr reader = xmlReaderForFile(file, NULL, 0); if (!reader) { oscap_seterr(OSCAP_EFAMILY_GLIBC, "Unable to open file: '%s'", file); return NULL; } xmlTextReaderSetErrorHandler(reader, &libxml_error_handler, NULL); while (xmlTextReaderRead(reader) == 1 && xmlTextReaderNodeType(reader) != XML_READER_TYPE_ELEMENT); ver_info = xccdf_detect_version_parser(reader); if(!ver_info) { xmlFreeTextReader(reader); return NULL; } doc_version = strdup(xccdf_version_info_get_version(ver_info)); xmlFreeTextReader(reader); return doc_version; }
// xmlInputReadCallback static int bz2_mem_read(struct bz2_mem *bzmem, char *buffer, int len) { if (len < 1) { // ensure that at least one byte of output space is available at each BZ2_bzDecompress call. return 0; } if (bzmem->eof) { // If we run BZ2_bzDecompress on processed buffer we will get -1 (SEQUENCE_ERROR) return 0; } // next_out should point to a buffer in which the uncompressed output is to be placed bzmem->stream->next_out = buffer; // with avail_out indicating how much output space is available. bzmem->stream->avail_out = len; int bzerror = BZ2_bzDecompress(bzmem->stream); if (bzerror == BZ_STREAM_END) { bzmem->eof = true; } if (bzerror == BZ_OK || bzerror == BZ_STREAM_END) return (len - bzmem->stream->avail_out); else { oscap_seterr(OSCAP_EFAMILY_OSCAP, "Could not read from bz_stream: BZ2_bzDecompress returns %d", bzerror); return -1; } }
bool xccdf_tailoring_remove_profile(struct xccdf_tailoring *tailoring, struct xccdf_profile *profile) { assert(xccdf_profile_get_tailoring(profile)); // We have to make sure there is no other profile in tailoring that inherits // the profile we are about to remove. const char *profile_id = xccdf_profile_get_id(profile); struct xccdf_profile_iterator* it = xccdf_tailoring_get_profiles(tailoring); while (xccdf_profile_iterator_has_more(it)) { struct xccdf_profile* prof = xccdf_profile_iterator_next(it); if (prof == profile) continue; const char *extends = xccdf_profile_get_extends(prof); if (oscap_strcmp(profile_id, extends) == 0) { oscap_seterr(OSCAP_EFAMILY_XML, "Can't remove given profile '%s' from tailoring. Other profiles are inheriting from it!", profile_id); return false; xccdf_profile_iterator_free(it); } } xccdf_profile_iterator_free(it); return oscap_list_remove(tailoring->profiles, XITEM(profile), (oscap_cmp_func)_list_ptreq_cmp, NULL); }
int ores_add_res(struct oresults *ores, oval_result_t res) { switch (res) { case OVAL_RESULT_TRUE: ores->true_cnt++; break; case OVAL_RESULT_FALSE: ores->false_cnt++; break; case OVAL_RESULT_UNKNOWN: ores->unknown_cnt++; break; case OVAL_RESULT_ERROR: ores->error_cnt++; break; case OVAL_RESULT_NOT_EVALUATED: ores->noteval_cnt++; break; case OVAL_RESULT_NOT_APPLICABLE: ores->notappl_cnt++; break; default: oscap_seterr(OSCAP_EFAMILY_OSCAP, "Invalid oval result type: %d.", res); return 1; } return 0; }
int oval_definition_model_merge(struct oval_definition_model *model, const char *file) { __attribute__nonnull__(model); int ret; xmlTextReader *reader = xmlNewTextReaderFilename(file); if (reader == NULL) { oscap_seterr(OSCAP_EFAMILY_GLIBC, "%s '%s'", strerror(errno), file); return -1; } /* setup context */ struct oval_parser_context context; context.reader = reader; context.definition_model = model; context.user_data = NULL; xmlTextReaderSetErrorHandler(reader, &libxml_error_handler, &context); /* jump into oval_definitions */ while (xmlTextReaderRead(reader) == 1 && xmlTextReaderNodeType(reader) != XML_READER_TYPE_ELEMENT) ; /* start parsing */ ret = oval_definition_model_parse(reader, &context); xmlFreeTextReader(reader); return ret; }
static char *parse_text_element(xmlTextReaderPtr reader, char *name) { char *string = NULL; __attribute__nonnull__(reader); __attribute__nonnull__(name); // parse string element attributes here (like xml:lang) while (xmlTextReaderNextNode(reader)) { if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT && !xmlStrcmp(xmlTextReaderConstLocalName(reader), BAD_CAST name)) { return string; } switch (xmlTextReaderNodeType(reader)) { case XML_READER_TYPE_TEXT: string = (char *)xmlTextReaderValue(reader); break; default: oscap_seterr(OSCAP_EFAMILY_OSCAP, "Unknown XML element in platform"); break; } } return string; }
int ds_common_mkdir_p(const char* path) { // NOTE: This assumes a UNIX VFS path, C:\\folder\\folder would break it! if (strlen(path) > MAXPATHLEN) { return -1; } else { char temp[MAXPATHLEN + 1]; // +1 for \0 unsigned int i; for (i = 0; i <= strlen(path); i++) { if (path[i] == '/' || path[i] == '\0') { strncpy(temp, path, i); temp[i] = '\0'; // skip leading '/', we will never be creating the root anyway if (strlen(temp) == 0) continue; if (mkdir(temp, S_IRWXU) != 0 && errno != EEXIST) { oscap_seterr(OSCAP_EFAMILY_GLIBC, "Error making directory '%s', while doing recursive mkdir for '%s', error was '%s'.", temp, path, strerror(errno)); return -1; } } } return 0; } }
static inline oval_result_t _evaluate_sysent_with_variable(struct oval_syschar_model *syschar_model, struct oval_entity *state_entity, struct oval_sysent *item_entity, oval_operation_t state_entity_operation, struct oval_state_content *content) { oval_syschar_collection_flag_t flag; oval_result_t ent_val_res; struct oval_variable *state_entity_var; if ((state_entity_var = oval_entity_get_variable(state_entity)) == NULL) { oscap_seterr(OSCAP_EFAMILY_OVAL, "OVAL internal error: found NULL variable"); return -1; } if (0 != oval_syschar_model_compute_variable(syschar_model, state_entity_var)) { return -1; } flag = oval_variable_get_collection_flag(state_entity_var); switch (flag) { case SYSCHAR_FLAG_COMPLETE: case SYSCHAR_FLAG_INCOMPLETE:{ struct oresults var_ores; struct oval_value_iterator *val_itr; ores_clear(&var_ores); val_itr = oval_variable_get_values(state_entity_var); while (oval_value_iterator_has_more(val_itr)) { struct oval_value *var_val; char *state_entity_val_text = NULL; oval_result_t var_val_res; var_val = oval_value_iterator_next(val_itr); state_entity_val_text = oval_value_get_text(var_val); if (state_entity_val_text == NULL) { dE("Found NULL variable value text.\n"); ores_add_res(&var_ores, OVAL_RESULT_ERROR); break; } oval_datatype_t state_entity_val_datatype = oval_value_get_datatype(var_val); var_val_res = oval_ent_cmp_str(state_entity_val_text, state_entity_val_datatype, item_entity, state_entity_operation); ores_add_res(&var_ores, var_val_res); } oval_value_iterator_free(val_itr); oval_check_t var_check = oval_state_content_get_var_check(content); ent_val_res = ores_get_result_bychk(&var_ores, var_check); } break; case SYSCHAR_FLAG_ERROR: case SYSCHAR_FLAG_DOES_NOT_EXIST: case SYSCHAR_FLAG_NOT_COLLECTED: case SYSCHAR_FLAG_NOT_APPLICABLE: ent_val_res = OVAL_RESULT_ERROR; break; default: ent_val_res = -1; } return ent_val_res; }
// xmlInputCloseCallback static int bz2_mem_close(void *bzmem) { int bzerror = BZ2_bzDecompressEnd(((struct bz2_mem *)bzmem)->stream); bz2_mem_free(bzmem); if (bzerror != BZ_OK) { oscap_seterr(OSCAP_EFAMILY_OSCAP, "Could not close bz_stream: BZ2_bzDecompressEnd returns %d", bzerror); } return bzerror == BZ_OK ? 0 : -1; }
static struct cpe_ext_deprecation *cpe_ext_deprecation_parse(xmlTextReaderPtr reader) { __attribute__nonnull__(reader); if (xmlStrcmp(xmlTextReaderConstLocalName(reader), BAD_CAST TAG_CPE_EXT_DEPRECATION_STR) != 0 || xmlTextReaderNodeType(reader) != 1) { oscap_seterr(OSCAP_EFAMILY_OSCAP, "Found '%s' node when expecting: '%s'!", xmlTextReaderConstLocalName(reader), TAG_CPE_EXT_DEPRECATION_STR); } const xmlChar* nsuri = xmlTextReaderConstNamespaceUri(reader); if (nsuri && xmlStrcmp(nsuri, BAD_CAST XMLNS_CPE2D3_EXTENSION) != 0) { oscap_seterr(OSCAP_EFAMILY_OSCAP, "Found '%s' namespace when expecting: '%s'!", nsuri, XMLNS_CPE2D3_EXTENSION); return NULL; } struct cpe_ext_deprecation *deprecation = cpe_ext_deprecation_new(); deprecation->date = (char *) xmlTextReaderGetAttribute(reader, BAD_CAST ATTR_DATE_STR); if (xmlTextReaderIsEmptyElement(reader) == 0) { // the element contains child nodes xmlTextReaderNextNode(reader); while (xmlStrcmp(xmlTextReaderConstLocalName(reader), BAD_CAST TAG_CPE_EXT_DEPRECATION_STR) != 0) { if (xmlTextReaderNodeType(reader) != XML_READER_TYPE_ELEMENT) { xmlTextReaderNextNode(reader); continue; } if (xmlStrcmp(xmlTextReaderConstLocalName(reader), BAD_CAST TAG_CPE_EXT_DEPRECATEDBY_STR) == 0) { struct cpe_ext_deprecatedby *deprecatedby = cpe_ext_deprecatedby_parse(reader); if (deprecatedby == NULL) { cpe_ext_deprecation_free(deprecation); return NULL; } oscap_list_add(deprecation->deprecatedbys, deprecatedby); } else { oscap_seterr(OSCAP_EFAMILY_OSCAP, "Unexpected element within deprecation element: '%s'", xmlTextReaderConstLocalName(reader)); cpe_ext_deprecation_free(deprecation); return NULL; } xmlTextReaderNextNode(reader); } } return deprecation; }
int ds_sds_session_register_component_source(struct ds_sds_session *session, const char *relative_filepath, struct oscap_source *component) { if (!oscap_htable_add(session->component_sources, relative_filepath, component)) { oscap_seterr(OSCAP_EFAMILY_OSCAP, "File %s has already been register with Source DataStream session: %s", relative_filepath, oscap_source_readable_origin(session->source)); return -1; } return 0; }
int oscap_source_validate_priv(struct oscap_source *source, oscap_document_type_t doc_type, const char *version, xml_reporter reporter, void *user) { if (version == NULL) { oscap_seterr(OSCAP_EFAMILY_OSCAP, "Could not determine version for file: %s", oscap_source_readable_origin(source)); return -1; } /* find a right schema file */ for (struct oscap_schema_table_entry *entry = OSCAP_SCHEMAS_TABLE; entry->doc_type != 0; ++entry) { if (entry->doc_type != doc_type || strcmp(entry->schema_version, version)) continue; return oscap_validate_xml(source, entry->schema_path, reporter, user); } oscap_seterr(OSCAP_EFAMILY_OSCAP, "Schema file not found when trying to validate '%s'", oscap_source_readable_origin(source)); return -1; }
static int __unlink_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) { int rv = remove(fpath); if (rv) oscap_seterr(OSCAP_EFAMILY_GLIBC, "Could not remove %s. %s", fpath, strerror(errno)); return rv; }
int ds_rds_session_register_component_source(struct ds_rds_session *session, const char *content_id, struct oscap_source *component) { if (!oscap_htable_add(session->component_sources, content_id, component)) { oscap_seterr(OSCAP_EFAMILY_OSCAP, "Content '%s' has already been register with Result DataStream session: %s", content_id, oscap_source_readable_origin(session->source)); return -1; } return 0; }
bool oscap_set_verbose(const char *verbosity_level, const char *filename, bool is_probe) { if (verbosity_level == NULL) { return true; } __debuglog_level = oscap_verbosity_level_from_cstr(verbosity_level); if (__debuglog_level == DBG_UNKNOWN) { return false; } if (!is_probe) { setenv("OSCAP_PROBE_VERBOSITY_LEVEL", verbosity_level, 1); } if (filename == NULL) { __debuglog_fp = stderr; return true; } int fd; if (is_probe) { fd = open(filename, O_APPEND | O_WRONLY); } else { setenv("OSCAP_PROBE_VERBOSE_LOG_FILE", filename, 1); /* Open a file. If the file doesn't exist, create it. * If the file exists, erase its content. * File is opened in "append" mode. * Append mode is necessary when more processes write to same file. * Every process using the log file must open it in append mode, * because otherwise some data may be missing on output. */ fd = open(filename, O_APPEND | O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); } if (fd == -1) { oscap_seterr(OSCAP_EFAMILY_OSCAP, "Failed to open file %s: %s.", filename, strerror(errno)); return false; } __debuglog_fp = fdopen(fd, "a"); if (__debuglog_fp == NULL) { oscap_seterr(OSCAP_EFAMILY_OSCAP, "Failed to associate stream with file %s: %s.", filename, strerror(errno)); return false; } setbuf(__debuglog_fp, NULL); atexit(&__oscap_debuglog_close); return true; }
static int ds_sds_dump_component(const char* component_id, struct ds_sds_session *session, const char *target_filename_dirname, const char *relative_filepath) { xmlDoc *doc = ds_sds_session_get_xmlDoc(session); xmlNodePtr component = _lookup_component_in_collection(doc, component_id); if (component == NULL) { oscap_seterr(OSCAP_EFAMILY_XML, "Component of given id '%s' was not found in the document.", component_id); return -1; } xmlNodePtr inner_root = node_get_child_element(component, NULL); if (inner_root == NULL) { oscap_seterr(OSCAP_EFAMILY_XML, "Found component (id='%s') but it has no element contents, nothing to dump, skipping...", component_id); return -1; } // If the inner root is script, we have to treat it in a special way if (strcmp((const char*)inner_root->name, "script") == 0) { // the cast is safe to do because we are using the GNU basename, it doesn't // modify the string const char* file_basename = basename((char*)relative_filepath); const char* sce_filename = oscap_sprintf("%s/%s/%s",ds_sds_session_get_target_dir(session), target_filename_dirname, file_basename); int ret = ds_sds_dump_component_sce(inner_root->children, component_id, sce_filename); oscap_free(sce_filename); if (ret != 0) { return ret; } } // Otherwise we create a new XML doc we will dump the contents to. // We can't just dump node "innerXML" because namespaces have to be // handled. else { xmlDoc *new_doc = ds_doc_from_foreign_node(inner_root, doc); if (new_doc == NULL) { return -1; } struct oscap_source *source = oscap_source_new_from_xmlDoc(new_doc, relative_filepath); ds_sds_session_register_component_source(session, relative_filepath, source); } return 0; }
static int ds_sds_compose_has_component_ref(xmlDocPtr doc, xmlNodePtr datastream, const char* filepath, const char* cref_id) { xmlXPathContextPtr xpathCtx = xmlXPathNewContext(doc); if (xpathCtx == NULL) { oscap_seterr(OSCAP_EFAMILY_XML, "Error: unable to create new XPath context."); return -1; } xmlXPathRegisterNs(xpathCtx, BAD_CAST "ds", BAD_CAST datastream_ns_uri); xmlXPathRegisterNs(xpathCtx, BAD_CAST "xlink", BAD_CAST xlink_ns_uri); // limit xpath execution to just the datastream node // this is done for performance reasons xpathCtx->node = datastream; const char* expression = oscap_sprintf("*/ds:component-ref[@xlink:href = '#%s' and @id = '%s']", filepath, cref_id); xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression( BAD_CAST expression, xpathCtx); oscap_free(expression); if (xpathObj == NULL) { oscap_seterr(OSCAP_EFAMILY_XML, "Error: Unable to evalute XPath expression."); xmlXPathFreeContext(xpathCtx); return -1; } int result = 1; xmlNodeSetPtr nodeset = xpathObj->nodesetval; if (nodeset != NULL) result = nodeset->nodeNr > 0 ? 0 : 1; xmlXPathFreeObject(xpathObj); xmlXPathFreeContext(xpathCtx); return result; }
int ds_rds_dump_arf_content(struct ds_rds_session *session, const char *container_name, const char *component_name, const char *content_id) { xmlDoc *doc = ds_rds_session_get_xmlDoc(session); xmlNodePtr parent_node = ds_rds_lookup_component(doc, container_name, component_name, content_id); if (!parent_node) { oscap_seterr(OSCAP_EFAMILY_OSCAP, "Could not find any %s of id '%s'", component_name, content_id); return -1; } xmlNodePtr content_node = ds_rds_get_inner_content(NULL, parent_node); if (!content_node) return -1; xmlNodePtr candidate = content_node->children; xmlNodePtr inner_root = NULL; for (; candidate != NULL; candidate = candidate->next) { if (candidate->type != XML_ELEMENT_NODE) continue; if (inner_root) { oscap_seterr(OSCAP_EFAMILY_XML, "There are multiple nodes inside an 'arf:content' node. " "Only the last one will be used!"); } inner_root = candidate; } if (inner_root == NULL) { oscap_seterr(OSCAP_EFAMILY_XML, "Could not found any child inside 'arf:content' node when looking for %s.", content_id); return -1; } // We assume that arf:content is XML. This is reasonable because both // reports and report requests are XML documents. xmlDoc *new_doc = ds_doc_from_foreign_node(inner_root, ds_rds_session_get_xmlDoc(session)); char *target_file = oscap_sprintf("%s/%s.xml", ds_rds_session_get_target_dir(session), component_name); struct oscap_source *source = oscap_source_new_from_xmlDoc(new_doc, target_file); oscap_free(target_file); return ds_rds_session_register_component_source(session, content_id, source); }
char *oscap_acquire_temp_dir() { char *temp_dir = oscap_strdup(TEMP_DIR_TEMPLATE); if (mkdtemp(temp_dir) == NULL) { free(temp_dir); oscap_seterr(OSCAP_EFAMILY_GLIBC, "Could not create temp directory " TEMP_DIR_TEMPLATE ". %s", strerror(errno)); return NULL; } return temp_dir; }
static int ds_sds_compose_catalog_has_uri(xmlDocPtr doc, xmlNodePtr catalog, const char* uri) { xmlXPathContextPtr xpathCtx = xmlXPathNewContext(doc); if (xpathCtx == NULL) { oscap_seterr(OSCAP_EFAMILY_XML, "Error: unable to create a new XPath context."); return -1; } xmlXPathRegisterNs(xpathCtx, BAD_CAST "cat", BAD_CAST cat_ns_uri); xmlXPathRegisterNs(xpathCtx, BAD_CAST "xlink", BAD_CAST xlink_ns_uri); // limit xpath execution to just the catalog node // this is done for performance reasons xpathCtx->node = catalog; const char* expression = oscap_sprintf("cat:uri[@uri = '%s']", uri); xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression( BAD_CAST expression, xpathCtx); oscap_free(expression); if (xpathObj == NULL) { oscap_seterr(OSCAP_EFAMILY_XML, "Error: Unable to evalute XPath expression."); xmlXPathFreeContext(xpathCtx); return -1; } int result = 0; xmlNodeSetPtr nodeset = xpathObj->nodesetval; if (nodeset != NULL) result = nodeset->nodeNr > 0 ? 0 : 1; xmlXPathFreeObject(xpathObj); xmlXPathFreeContext(xpathCtx); return result; }
int oval_test_parse_tag(xmlTextReaderPtr reader, struct oval_parser_context *context, void *usr) { int ret = 0; char *comm = NULL; char *version = NULL; struct oval_definition_model *model = context->definition_model; char *id = (char *)xmlTextReaderGetAttribute(reader, BAD_CAST "id"); struct oval_test *test = oval_definition_model_get_new_test(model, id); oval_subtype_t subtype = oval_subtype_parse(reader); if ( subtype == OVAL_SUBTYPE_UNKNOWN) { oscap_seterr(OSCAP_EFAMILY_OVAL, "Unknown test type %s.", id); ret = -1; goto cleanup; } oval_test_set_subtype(test, subtype); oval_operator_t ste_operator = oval_operator_parse(reader, "state_operator", OVAL_OPERATOR_AND); oval_test_set_state_operator(test, ste_operator); oval_check_t check = oval_check_parse(reader, "check", OVAL_CHECK_UNKNOWN); if (check == OVAL_CHECK_NONE_EXIST) { dW("The 'none exist' CheckEnumeration value has been deprecated. " "Converted to check='none satisfy' and check_existence='none exist'.\n"); oval_test_set_check(test, OVAL_CHECK_NONE_SATISFY); oval_test_set_existence(test, OVAL_NONE_EXIST); } else { oval_existence_t existence; oval_test_set_check(test, check); existence = oval_existence_parse(reader, "check_existence", OVAL_AT_LEAST_ONE_EXISTS); oval_test_set_existence(test, existence); } comm = (char *)xmlTextReaderGetAttribute(reader, BAD_CAST "comment"); if (comm != NULL) { oval_test_set_comment(test, comm); } int deprecated = oval_parser_boolean_attribute(reader, "deprecated", 0); oval_test_set_deprecated(test, deprecated); version = (char *)xmlTextReaderGetAttribute(reader, BAD_CAST "version"); oval_test_set_version(test, atoi(version)); ret = oval_parser_parse_tag(reader, context, &_oval_test_parse_tag, test); cleanup: oscap_free(version); oscap_free(comm); oscap_free(id); return ret; }
SEXP_t *oval_value_to_sexp(struct oval_value *val, oval_datatype_t dtype) { SEXP_t *val_sexp = NULL; char *val_rptr = NULL; switch (dtype) { case OVAL_DATATYPE_EVR_STRING: case OVAL_DATATYPE_DEBIAN_EVR_STRING: case OVAL_DATATYPE_IPV4ADDR: case OVAL_DATATYPE_IPV6ADDR: case OVAL_DATATYPE_STRING: case OVAL_DATATYPE_VERSION: val_rptr = oval_value_get_text (val); if (val_rptr != NULL) { val_sexp = SEXP_string_newf("%s", val_rptr); } break; case OVAL_DATATYPE_FLOAT: val_sexp = SEXP_number_newf(oval_value_get_float(val)); break; case OVAL_DATATYPE_INTEGER: val_sexp = SEXP_number_newi_64(oval_value_get_integer(val)); break; case OVAL_DATATYPE_BOOLEAN: val_sexp = SEXP_number_newb(oval_value_get_boolean(val)); break; case OVAL_DATATYPE_BINARY: case OVAL_DATATYPE_FILESET_REVISION: case OVAL_DATATYPE_IOS_VERSION: // todo: oscap_seterr(OSCAP_EFAMILY_OVAL, "Unsupported datatype: %s.", dtype); val_sexp = NULL; break; default: oscap_seterr(OSCAP_EFAMILY_OVAL, "Unknown datatype: %s.", dtype); val_sexp = NULL; break; } return val_sexp; }
static int ds_sds_dump_component_sce(const xmlNode *script_node, const char *component_id, const char *filename) { if (script_node) { if (oscap_acquire_ensure_parent_dir(filename) < 0) { oscap_seterr(OSCAP_EFAMILY_XML, "Error while creating script parent directory for file '%s' of (id='%s')", filename, component_id); return -1; } // TODO: should we check whether the component is extended? int fd; xmlChar* text_contents = xmlNodeGetContent(script_node); if ((fd = open(filename, O_CREAT | O_TRUNC | O_NOFOLLOW | O_WRONLY, 0700)) < 0) { oscap_seterr(OSCAP_EFAMILY_XML, "Error while creating script component (id='%s') to file '%s'.", component_id, filename); xmlFree(text_contents); return -1; } FILE* output_file = fdopen(fd, "w"); if (output_file == NULL) { oscap_seterr(OSCAP_EFAMILY_XML, "Error while dumping script component (id='%s') to file '%s'.", component_id, filename); xmlFree(text_contents); close(fd); return -1; } // TODO: error checking, fprintf should return strlen((const char*)text_contents) fprintf(output_file, "%s", text_contents ? (char*)text_contents : ""); #ifndef _WIN32 // NB: This code is for SCE scripts if (fchmod(fd, 0700) != 0) { oscap_seterr(OSCAP_EFAMILY_XML, "Failed to set executable permission on script (id='%s') that was split to '%s'.", component_id, filename); } #endif dD("Successfully dumped script component (id='%s') to file '%s'.", component_id, filename); fclose(output_file); xmlFree(text_contents); return 0; } else { oscap_seterr(OSCAP_EFAMILY_XML, "Error while dumping script component (id='%s') to file '%s'. " "The script element was empty!", component_id, filename); return -1; } }