int ds_sds_compose_from_xccdf(const char* xccdf_file, const char* target_datastream) { xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0"); xmlNodePtr root = xmlNewNode(NULL, BAD_CAST "data-stream-collection"); xmlDocSetRootElement(doc, root); xmlNsPtr ds_ns = xmlNewNs(root, BAD_CAST datastream_ns_uri, BAD_CAST "ds"); xmlSetNs(root, ds_ns); // we will need this namespace later when creating xlink:href attr in // component-ref xmlNewNs(root, BAD_CAST xlink_ns_uri, BAD_CAST "xlink"); char* mangled_xccdf_file = ds_sds_mangle_filepath(xccdf_file); char* collection_id = oscap_sprintf("scap_org.open-scap_collection_from_xccdf_%s", mangled_xccdf_file); xmlSetProp(root, BAD_CAST "id", BAD_CAST collection_id); oscap_free(collection_id); xmlSetProp(root, BAD_CAST "schematron-version", BAD_CAST "1.2"); // we will need this namespace later when creating component-ref // dependency catalog xmlNewNs(root, BAD_CAST cat_ns_uri, BAD_CAST "cat"); xmlNodePtr datastream = xmlNewNode(ds_ns, BAD_CAST "data-stream"); xmlAddChild(root, datastream); char* datastream_id = oscap_sprintf("scap_org.open-scap_datastream_from_xccdf_%s", mangled_xccdf_file); xmlSetProp(datastream, BAD_CAST "id", BAD_CAST datastream_id); oscap_free(datastream_id); xmlSetProp(datastream, BAD_CAST "scap-version", BAD_CAST "1.2"); xmlSetProp(datastream, BAD_CAST "use-case", BAD_CAST "OTHER"); xmlNodePtr dictionaries = xmlNewNode(ds_ns, BAD_CAST "dictionaries"); xmlAddChild(datastream, dictionaries); xmlNodePtr checklists = xmlNewNode(ds_ns, BAD_CAST "checklists"); xmlAddChild(datastream, checklists); xmlNodePtr checks = xmlNewNode(ds_ns, BAD_CAST "checks"); xmlAddChild(datastream, checks); xmlNodePtr extended_components = xmlNewNode(ds_ns, BAD_CAST "extended-components"); xmlAddChild(datastream, extended_components); char* cref_id = oscap_sprintf("scap_org.open-scap_cref_%s", mangled_xccdf_file); if (ds_sds_compose_add_component_with_ref(doc, datastream, xccdf_file, cref_id) != 0) { // oscap_seterr already called oscap_free(cref_id); oscap_free(mangled_xccdf_file); return -1; } oscap_free(cref_id); // the XSD of source data stream enforces that the collection elements are // not empty if they are there, we will therefore now removes collections // where nothing has been added if (dictionaries->children == NULL) { xmlUnlinkNode(dictionaries); xmlFreeNode(dictionaries); } if (checklists->children == NULL) { xmlUnlinkNode(checklists); xmlFreeNode(checklists); } if (checks->children == NULL) { xmlUnlinkNode(checks); xmlFreeNode(checks); } if (extended_components->children == NULL) { xmlUnlinkNode(extended_components); xmlFreeNode(extended_components); } oscap_free(mangled_xccdf_file); if (xmlSaveFileEnc(target_datastream, doc, "utf-8") == -1) { oscap_seterr(OSCAP_EFAMILY_GLIBC, "Error saving source datastream to '%s'.", target_datastream); xmlFreeDoc(doc); return -1; } xmlFreeDoc(doc); return 0; }
static int ds_sds_compose_add_component_dependencies(xmlDocPtr doc, xmlNodePtr datastream, struct oscap_source *component_source, xmlNodePtr catalog, int component_type) { xmlDocPtr component_doc = oscap_source_get_xmlDoc(component_source); if (component_doc == NULL) { return -1; } xmlXPathContextPtr xpathCtx = xmlXPathNewContext(component_doc); if (xpathCtx == NULL) { oscap_seterr(OSCAP_EFAMILY_XML, "Error: unable to create new XPath context."); return -1; } xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression( // we want robustness and support for future versions, this expression // retrieves check-content-refs from any namespace BAD_CAST _get_dep_xpath_for_type(component_type), xpathCtx); if (xpathObj == NULL) { oscap_seterr(OSCAP_EFAMILY_XML, "Error: Unable to evalute XPath expression."); xmlXPathFreeContext(xpathCtx); return -1; } xmlNsPtr cat_ns = xmlSearchNsByHref(doc, datastream, BAD_CAST cat_ns_uri); xmlNodeSetPtr nodeset = xpathObj->nodesetval; if (nodeset != NULL) { struct oscap_htable *exported = oscap_htable_new(); char* filepath_cpy = oscap_strdup(oscap_source_readable_origin(component_source)); const char* dir = dirname(filepath_cpy); for (int i = 0; i < nodeset->nodeNr; i++) { xmlNodePtr node = nodeset->nodeTab[i]; if (node->type != XML_ELEMENT_NODE) continue; if (xmlHasProp(node, BAD_CAST "href")) { char* href = (char*)xmlGetProp(node, BAD_CAST "href"); if (oscap_htable_get(exported, href) != NULL) { // This path has been already exported. Do not export duplicate. xmlFree(href); continue; } oscap_htable_add(exported, href, ""); if (oscap_acquire_url_is_supported(href)) { /* If the referenced component is remote one, do not include * it within the DataStream. Such component shall only be * downloaded once the scan is run. */ xmlFree(href); continue; } // skip over file:// if it's used in the file href const char *altered_href = oscap_str_startswith(href, "file://") ? href + 7 : href; char* real_path = (strcmp(dir, "") == 0 || strcmp(dir, ".") == 0 || altered_href[0] == '/') ? oscap_strdup(altered_href) : oscap_sprintf("%s/%s", dir, altered_href); char* mangled_path = ds_sds_mangle_filepath(real_path); char* cref_id = oscap_sprintf("scap_org.open-scap_cref_%s", mangled_path); int counter = 0; while (ds_sds_find_component_ref(datastream, cref_id) != NULL) { // While the given component ID already exists in the document. oscap_free(cref_id); cref_id = oscap_sprintf("scap_org.open-scap_cref_%s%03d", mangled_path, counter++); } oscap_free(mangled_path); char* uri = oscap_sprintf("#%s", cref_id); // we don't want duplicated uri elements in the catalog if (ds_sds_compose_catalog_has_uri(doc, catalog, uri) == 0) { oscap_free(uri); oscap_free(cref_id); oscap_free(real_path); xmlFree(href); continue; } int ret = ds_sds_compose_add_component_with_ref(doc, datastream, real_path, cref_id); if (ret == 0) { xmlNodePtr catalog_uri = xmlNewNode(cat_ns, BAD_CAST "uri"); xmlSetProp(catalog_uri, BAD_CAST "name", BAD_CAST href); xmlSetProp(catalog_uri, BAD_CAST "uri", BAD_CAST uri); xmlAddChild(catalog, catalog_uri); } oscap_free(cref_id); oscap_free(uri); oscap_free(real_path); xmlFree(href); if (ret < 0) { // oscap_seterr has already been called oscap_htable_free0(exported); return -1; } } } oscap_htable_free0(exported); oscap_free(filepath_cpy); } xmlXPathFreeObject(xpathObj); xmlXPathFreeContext(xpathCtx); return 0; }
static int read_process(SEXP_t *cmd_ent, probe_ctx *ctx) { int err = 1; DIR *d; struct dirent *ent; d = opendir("/proc"); if (d == NULL) return err; psinfo_t *psinfo; // Scan the directories while (( ent = readdir(d) )) { int fd, len; char buf[336]; int pid; unsigned sched_policy; SEXP_t *cmd_sexp; // Skip non-process58 dir entries if(*ent->d_name<'0' || *ent->d_name>'9') continue; errno = 0; pid = strtol(ent->d_name, NULL, 10); if (errno || pid == 2) // skip err & kthreads continue; // Parse up the stat file for the proc snprintf(buf, 32, "/proc/%d/psinfo", pid); fd = open(buf, O_RDONLY, 0); if (fd < 0) continue; len = read(fd, buf, sizeof buf); close(fd); if (len < 336) continue; // The psinfo file contains a psinfo struct; this typecast gets us the struct directly psinfo = (psinfo_t *) buf; err = 0; // If we get this far, no permission problems dI("Have command: %s\n", psinfo->pr_fname); cmd_sexp = SEXP_string_newf("%s", psinfo->pr_fname); if (probe_entobj_cmp(cmd_ent, cmd_sexp) == OVAL_RESULT_TRUE) { struct result_info r; char tbuf[32], sbuf[32]; int tday,tyear; time_t s_time; struct tm *proc, *now; const char *fmt; int fixfmt_year; r.scheduling_class = malloc(PRCLSZ); strncpy(r.scheduling_class, (psinfo->pr_lwp).pr_clname, sizeof(r.scheduling_class)); // Get the start time s_time = time(NULL); now = localtime(&s_time); tyear = now->tm_year; tday = now->tm_yday; // Get current time s_time = psinfo->pr_start.tv_sec; proc = localtime(&s_time); // Select format based on how long we've been running // // FROM THE SPEC: // "This is the time of day the process started formatted in HH:MM:SS if // the same day the process started or formatted as MMM_DD (Ex.: Feb_5) // if process started the previous day or further in the past." // if (tday != proc->tm_yday || tyear != proc->tm_year) fmt = "%b_%d"; else fmt = "%H:%M:%S"; strftime(sbuf, sizeof(sbuf), fmt, proc); r.command_line = psinfo->pr_fname; r.exec_time = convert_time(psinfo->pr_time.tv_sec, tbuf, sizeof(tbuf)); r.pid = psinfo->pr_pid; r.ppid = psinfo->pr_ppid; r.priority = (psinfo->pr_lwp).pr_pri; r.ruid = psinfo->pr_uid; r.start_time = sbuf; r.tty = oscap_sprintf("%s", psinfo->pr_ttydev); r.user_id = psinfo->pr_euid; report_finding(&r, ctx); } SEXP_free(cmd_sexp); } closedir(d); return err; }