static int __probe_icache_add_nolock(probe_icache_t *cache, SEXP_t *cobj, SEXP_t *item, pthread_cond_t *cond) { assume_d((cond == NULL) ^ (item == NULL), -1); retry: if (cache->queue_cnt < cache->queue_max) { cache->queue[cache->queue_end].cobj = cobj; if (item != NULL) { assume_d(cobj != NULL, -1); cache->queue[cache->queue_end].p.item = item; } else { assume_d(item == NULL && cobj == NULL, -1); cache->queue[cache->queue_end].p.cond = cond; } ++cache->queue_cnt; ++cache->queue_end; if (cache->queue_end == cache->queue_max) cache->queue_end = 0; } else { /* * The queue is full, we have to wait */ if (pthread_cond_wait(&cache->queue_notfull, &cache->queue_mutex) == 0) goto retry; else { dE("An error ocured while waiting for the `notfull' queue condition: %u, %s", errno, strerror(errno)); return (-1); } } return (0); }
SEXP_datatypePtr_t *SEXP_datatype_get (SEXP_datatypeTbl_t *t, const char *k) { struct rbt_str_node *n = NULL; SEXP_datatype_t *d; assume_d(t != NULL, NULL); assume_d(k != NULL, NULL); SEXP_datatype_once(); if (rbt_str_getnode(t->tree, k, &n) != 0) return(NULL); d = (SEXP_datatype_t *)(n->data); if (d != NULL) { if (d->dt_flg & SEXP_DTFLG_LOCALDATA) { struct SEXP_datatype_extptr *eptr = NULL; /* See comment in SEXP_datatype_add */ if (posix_memalign((void **)(void *)(&eptr), SEXP_DATATYPEPTR_ALIGN, sizeof(struct SEXP_datatype_extptr)) != 0) { return(NULL); } eptr->n = n; eptr->l = NULL; return(SEXP_datatypePtr_t *)((uintptr_t)(eptr)|1); } } return((SEXP_datatypePtr_t *)n); }
static SEXP_t *oval_probe_cmd_obj_eval(SEXP_t *sexp, void *arg) { char *id_str; struct oval_definition_model *defs; struct oval_object *obj; struct oval_syschar *res; oval_pext_t *pext = (oval_pext_t *) arg; SEXP_t *ret, *ret_code; int r; assume_d (sexp != NULL, NULL); assume_d (arg != NULL, NULL); if (!SEXP_stringp(sexp)) { oscap_dlprintf(DBG_E, "Invalid argument: type=%s.\n", SEXP_strtype(sexp)); return (NULL); } id_str = SEXP_string_cstr(sexp); defs = oval_syschar_model_get_definition_model(*(pext->model)); obj = oval_definition_model_get_object(defs, id_str); ret = SEXP_list_new (sexp, NULL); oscap_dlprintf(DBG_I, "Get_object: %s.\n", id_str); if (obj == NULL) { oscap_dlprintf(DBG_E, "Can't find obj: id=%s.\n", id_str); oscap_free(id_str); SEXP_free(ret); return (NULL); } oscap_clearerr(); r = oval_probe_query_object(pext->sess_ptr, obj, OVAL_PDFLAG_NOREPLY|OVAL_PDFLAG_SLAVE, &res); if (r < 0) ret_code = SEXP_number_newu((unsigned int) SYSCHAR_FLAG_COMPLETE); else ret_code = SEXP_number_newu((unsigned int) oval_syschar_get_flag(res)); SEXP_list_add(ret, ret_code); SEXP_free(ret_code); if (oscap_err()) { oscap_dlprintf(DBG_E, "Failed: id: %s, err: %d, %s.\n", id_str, oscap_err_family(), oscap_err_desc()); oscap_clearerr(); oscap_free(id_str); SEXP_free(ret); return (NULL); } oscap_free(id_str); return (ret); }
int oval_agent_abort_session(oval_agent_session_t *ag_sess) { assume_d(ag_sess != NULL, -1); #if defined(OVAL_PROBES_ENABLED) assume_d(ag_sess->psess != NULL, -1); return oval_probe_session_abort(ag_sess->psess); #else /* TODO */ return 0; #endif }
/** * Collect an item * This function adds an item the collected object assosiated * with the given probe context. * * Returns: * 0 ... the item was succesfully added to the collected object * 1 ... the item was filtered out * 2 ... the item was not added because of memory constraints * and the collected object was flagged as incomplete *-1 ... unexpected/internal error * * The caller must not free the item, it's freed automatically * by this function or by the icache worker thread. */ int probe_item_collect(struct probe_ctx *ctx, SEXP_t *item) { SEXP_t *cobj_content; size_t cobj_itemcnt; assume_d(ctx != NULL, -1); assume_d(ctx->probe_out != NULL, -1); assume_d(item != NULL, -1); cobj_content = SEXP_listref_nth(ctx->probe_out, 3); cobj_itemcnt = SEXP_list_length(cobj_content); SEXP_free(cobj_content); if (probe_cobj_memcheck(cobj_itemcnt) != 0) { /* * Don't set the message again if the collected object is * already flagged as incomplete. */ if (probe_cobj_get_flag(ctx->probe_out) != SYSCHAR_FLAG_INCOMPLETE) { SEXP_t *msg; /* * Sync with the icache thread before modifying the * collected object. */ if (probe_icache_nop(ctx->icache) != 0) return -1; msg = probe_msg_creat(OVAL_MESSAGE_LEVEL_WARNING, "Object is incomplete due to memory constraints."); probe_cobj_add_msg(ctx->probe_out, msg); probe_cobj_set_flag(ctx->probe_out, SYSCHAR_FLAG_INCOMPLETE); SEXP_free(msg); } return 2; } if (ctx->filters != NULL && probe_item_filtered(item, ctx->filters)) { SEXP_free(item); return (1); } if (probe_icache_add(ctx->icache, ctx->probe_out, item) != 0) { dE("Can't add item (%p) to the item cache (%p)", item, ctx->icache); SEXP_free(item); return (-1); } return (0); }
void *oval_string_map_get_value(struct oval_string_map *map, const char *key) { void *val = NULL; assume_d(map != NULL, NULL); assume_d(key != NULL, NULL); if (rbt_str_get((rbt_t *)map, key, &val) != 0) return (NULL); else return (val); }
static SEXP_t *oval_probe_cmd_ste_fetch(SEXP_t *sexp, void *arg) { SEXP_t *id, *ste_list, *ste_sexp; char *id_str; struct oval_state *ste; struct oval_definition_model *definition_model; oval_pext_t *pext = (oval_pext_t *)arg; int ret; assume_d (sexp != NULL, NULL); assume_d (arg != NULL, NULL); ste_list = SEXP_list_new(NULL); SEXP_list_foreach(id, sexp) { if (SEXP_stringp(id)) { id_str = SEXP_string_cstr(id); definition_model = oval_syschar_model_get_definition_model(*(pext->model)); ste = oval_definition_model_get_state(definition_model, id_str); if (ste == NULL) { oscap_dlprintf(DBG_E, "Can't find ste: id: %s.\n", id_str); SEXP_list_free(ste_list); oscap_free(id_str); SEXP_free(id); return (NULL); } ret = oval_state_to_sexp(pext->sess_ptr, ste, &ste_sexp); if (ret !=0) { oscap_dlprintf(DBG_E, "Failed to convert OVAL state to SEXP, id: %s.\n", id_str); SEXP_list_free(ste_list); oscap_free(id_str); SEXP_free(id); return (NULL); } SEXP_list_add(ste_list, ste_sexp); SEXP_free(ste_sexp); oscap_free(id_str); } } return (ste_list); }
int rbt_rlock(rbt_t *rbt) { assume_d (rbt != NULL, -1); if (pthread_rwlock_rdlock(&rbt->lock) != 0) return (-1); else return (0); }
int probe_rcache_sexp_add(probe_rcache_t *cache, const SEXP_t *id, SEXP_t *item) { SEXP_t *r; char *k; assume_d(cache != NULL, -1); assume_d(id != NULL, -1); assume_d(item != NULL, -1); k = SEXP_string_cstr(id); r = SEXP_ref(item); if (rbt_str_add(cache->tree, k, (void *)r) != 0) { SEXP_free(r); free(k); return (-1); } return (0); }
static int oval_pdtbl_add(oval_pdtbl_t *tbl, oval_subtype_t type, int sd, const char *uri) { oval_pd_t *pd; assume_d (tbl != NULL, -1); assume_d (uri != NULL, -1); pd = oscap_talloc(oval_pd_t); pd->subtype = type; pd->sd = sd; pd->uri = strdup(uri); tbl->memb = oscap_realloc(tbl->memb, sizeof(oval_pd_t *) * (++tbl->count)); assume_d(tbl->memb != NULL, -1); tbl->memb[tbl->count - 1] = pd; qsort(tbl->memb, tbl->count, sizeof(oval_pd_t *), (int (*)(const void *, const void *))oval_pdtbl_pdcmp); return (0); }
static int oval_probe_cmd_init(oval_pext_t *pext) { assume_d (pext != NULL, -1); if (SEAP_cmd_register(pext->pdtbl->ctx, PROBECMD_OBJ_EVAL, SEAP_CMDREG_USEARG, &oval_probe_cmd_obj_eval, (void *)pext) != 0) { oscap_dlprintf(DBG_E, "Can't register command: %s: errno=%u, %s.\n", "obj_eval", errno, strerror(errno)); return (-1); } if (SEAP_cmd_register(pext->pdtbl->ctx, PROBECMD_STE_FETCH, SEAP_CMDREG_USEARG, &oval_probe_cmd_ste_fetch, (void *)pext) != 0) { oscap_dlprintf(DBG_E, "Can't register command: %s: errno=%u, %s.\n", "ste_fetch", errno, strerror(errno)); /* FIXME: unregister the first command */ return (-1); } return (0); }
static int oval_pdtbl_pdcmp(const oval_pd_t **a, const oval_pd_t **b) { assume_d(*a != NULL, -1); assume_d(*b != NULL, -1); return ((*a)->subtype - (*b)->subtype); }
int probe_main(probe_ctx *ctx, void *arg) { SEXP_t *path_ent, *file_ent, *inst_ent, *bh_ent, *patt_ent, *filepath_ent, *probe_in; SEXP_t *r0; /* char *i_val, *m_val, *s_val; */ bool val; struct pfdata pfd; int ret = 0; int errorffset = -1; const char *error; OVAL_FTS *ofts; OVAL_FTSENT *ofts_ent; char path_with_root[PATH_MAX + 1]; unsigned int root_len = 0; (void)arg; memset(&pfd, 0, sizeof(pfd)); probe_in = probe_ctx_getobject(ctx); over = probe_obj_get_platform_schema_version(probe_in); path_ent = probe_obj_getent(probe_in, "path", 1); file_ent = probe_obj_getent(probe_in, "filename", 1); inst_ent = probe_obj_getent(probe_in, "instance", 1); patt_ent = probe_obj_getent(probe_in, "pattern", 1); filepath_ent = probe_obj_getent(probe_in, "filepath", 1); bh_ent = probe_obj_getent(probe_in, "behaviors", 1); /* we want (path+filename or filepath) + instance + pattern*/ if ( ((path_ent == NULL || file_ent == NULL) && filepath_ent==NULL) || inst_ent==NULL || patt_ent==NULL) { SEXP_free (patt_ent); ret = PROBE_ENOELM; goto cleanup; } /* get pattern from SEXP */ SEXP_t *ent_val; ent_val = probe_ent_getval(patt_ent); pfd.pattern = SEXP_string_cstr(ent_val); assume_d(pfd.pattern != NULL, -1); SEXP_free(patt_ent); SEXP_free(ent_val); /* wtf? i_val = s_val = "0"; m_val = "1"; */ /* reset filebehavior attributes if 'filepath' entity is used */ if (filepath_ent != NULL && bh_ent != NULL) { SEXP_t *r1, *r2, *r3; r1 = r2 = r3 = NULL; if (probe_ent_attrexists(bh_ent, "ignore_case")) { r1 = probe_ent_getattrval(bh_ent, "ignore_case"); } if (probe_ent_attrexists(bh_ent, "multiline")) { r2 = probe_ent_getattrval(bh_ent, "multiline"); } if (probe_ent_attrexists(bh_ent, "singleline")) { r3 = probe_ent_getattrval(bh_ent, "singleline"); } r0 = SEXP_list_new(NULL); SEXP_free(bh_ent); bh_ent = probe_ent_creat1("behaviors", r0, NULL); SEXP_free(r0); if (r1) { probe_ent_attr_add(bh_ent, "ignore_case", r1); SEXP_free(r1); } if (r2) { probe_ent_attr_add(bh_ent, "multiline", r2); SEXP_free(r2); } if (r3) { probe_ent_attr_add(bh_ent, "singleline", r3); SEXP_free(r3); } } probe_tfc54behaviors_canonicalize(&bh_ent); pfd.instance_ent = inst_ent; pfd.ctx = ctx; pfd.re_opts = PCRE_UTF8; r0 = probe_ent_getattrval(bh_ent, "ignore_case"); if (r0) { val = SEXP_string_getb(r0); SEXP_free(r0); if (val) pfd.re_opts |= PCRE_CASELESS; } r0 = probe_ent_getattrval(bh_ent, "multiline"); if (r0) { val = SEXP_string_getb(r0); SEXP_free(r0); if (val) pfd.re_opts |= PCRE_MULTILINE; } r0 = probe_ent_getattrval(bh_ent, "singleline"); if (r0) { val = SEXP_string_getb(r0); SEXP_free(r0); if (val) pfd.re_opts |= PCRE_DOTALL; } pfd.compiled_regex = pcre_compile(pfd.pattern, pfd.re_opts, &error, &errorffset, NULL); if (pfd.compiled_regex == NULL) { SEXP_t *msg; msg = probe_msg_creatf(OVAL_MESSAGE_LEVEL_ERROR, "pcre_compile() '%s' %s.", pfd.pattern, error); probe_cobj_add_msg(probe_ctx_getresult(pfd.ctx), msg); SEXP_free(msg); probe_cobj_set_flag(probe_ctx_getresult(pfd.ctx), SYSCHAR_FLAG_ERROR); goto cleanup; } path_with_root[PATH_MAX] = '\0'; if (OSCAP_GSYM(offline_mode) & PROBE_OFFLINE_OWN) { strncpy(path_with_root, getenv("OSCAP_PROBE_ROOT"), PATH_MAX); root_len = strlen(path_with_root); if (path_with_root[root_len - 1] == FILE_SEPARATOR) --root_len; } if ((ofts = oval_fts_open(path_ent, file_ent, filepath_ent, bh_ent, probe_ctx_getresult(ctx))) != NULL) { while ((ofts_ent = oval_fts_read(ofts)) != NULL) { if (ofts_ent->fts_info == FTS_F || ofts_ent->fts_info == FTS_SL) { strncpy(path_with_root + root_len, ofts_ent->path, PATH_MAX - root_len); // todo: handle return code process_file(path_with_root, ofts_ent->file, &pfd); } oval_ftsent_free(ofts_ent); } oval_fts_close(ofts); } cleanup: SEXP_free(file_ent); SEXP_free(path_ent); SEXP_free(inst_ent); SEXP_free(bh_ent); SEXP_free(filepath_ent); if (pfd.pattern != NULL) free(pfd.pattern); if (pfd.compiled_regex != NULL) pcre_free(pfd.compiled_regex); return ret; }
static void *probe_icache_worker(void *arg) { probe_icache_t *cache = (probe_icache_t *)(arg); probe_iqpair_t *pair, pair_mem; SEXP_ID_t item_ID; assume_d(cache != NULL, NULL); pthread_setname_np(pthread_self(), "icache_worker"); if (pthread_mutex_lock(&cache->queue_mutex) != 0) { dE("An error ocured while locking the queue mutex: %u, %s", errno, strerror(errno)); return (NULL); } pair = &pair_mem; dD("icache worker ready"); switch (errno = pthread_barrier_wait(&OSCAP_GSYM(th_barrier))) { case 0: case PTHREAD_BARRIER_SERIAL_THREAD: break; default: dE("pthread_barrier_wait: %d, %s.", errno, strerror(errno)); pthread_mutex_unlock(&cache->queue_mutex); return (NULL); } while(pthread_cond_wait(&cache->queue_notempty, &cache->queue_mutex) == 0) { assume_d(cache->queue_cnt > 0, NULL); next: dD("Extracting item from the cache queue: cnt=%"PRIu16", beg=%"PRIu16"", cache->queue_cnt, cache->queue_beg); /* * Extract an item from the queue and update queue beg, end & cnt */ pair_mem = cache->queue[cache->queue_beg]; #ifndef NDEBUG memset(cache->queue + cache->queue_beg, 0, sizeof(probe_iqpair_t)); #endif --cache->queue_cnt; ++cache->queue_beg; if (cache->queue_beg == cache->queue_max) cache->queue_beg = 0; assume_d(cache->queue_cnt == 0 ? cache->queue_end == cache->queue_beg : cache->queue_end != cache->queue_beg, NULL); /* * Release the mutex */ if (pthread_mutex_unlock(&cache->queue_mutex) != 0) { dE("An error ocured while unlocking the queue mutex: %u, %s", errno, strerror(errno)); abort(); } dD("Signaling `notfull'"); if (pthread_cond_signal(&cache->queue_notfull) != 0) { dE("An error ocured while signaling the `notfull' condition: %u, %s", errno, strerror(errno)); abort(); } if (pair->cobj == NULL) { /* * Handle NOP case (synchronization) */ assume_d(pair->p.cond != NULL, NULL); dD("Handling NOP"); if (pthread_cond_signal(pair->p.cond) != 0) { dE("An error ocured while signaling NOP condition: %u, %s", errno, strerror(errno)); abort(); } } else { probe_citem_t *cached = NULL; dD("Handling cache request"); /* * Compute item ID */ item_ID = SEXP_ID_v(pair->p.item); dD("item ID=%"PRIu64"", item_ID); /* * Perform cache lookup */ if (rbt_i64_get(cache->tree, (int64_t)item_ID, (void *)&cached) == 0) { register uint16_t i; SEXP_t rest1, rest2; /* * Maybe a cache HIT */ dD("cache HIT #1"); for (i = 0; i < cached->count; ++i) { if (SEXP_deepcmp(SEXP_list_rest_r(&rest1, pair->p.item), SEXP_list_rest_r(&rest2, cached->item[i]))) { SEXP_free_r(&rest1); SEXP_free_r(&rest2); break; } SEXP_free_r(&rest1); SEXP_free_r(&rest2); } if (i == cached->count) { /* * Cache MISS */ dD("cache MISS"); cached->item = oscap_realloc(cached->item, sizeof(SEXP_t *) * ++cached->count); cached->item[cached->count - 1] = pair->p.item; /* Assign an unique item ID */ probe_icache_item_setID(pair->p.item, item_ID); } else { /* * Cache HIT */ dD("cache HIT #2 -> real HIT"); SEXP_free(pair->p.item); pair->p.item = cached->item[i]; } } else { /* * Cache MISS */ dD("cache MISS"); cached = oscap_talloc(probe_citem_t); cached->item = oscap_talloc(SEXP_t *); cached->item[0] = pair->p.item; cached->count = 1; /* Assign an unique item ID */ probe_icache_item_setID(pair->p.item, item_ID); if (rbt_i64_add(cache->tree, (int64_t)item_ID, (void *)cached, NULL) != 0) { dE("Can't add item (k=%"PRIi64" to the cache (%p)", (int64_t)item_ID, cache->tree); oscap_free(cached->item); oscap_free(cached); /* now what? */ abort(); } } if (probe_cobj_add_item(pair->cobj, pair->p.item) != 0) { dW("An error ocured while adding the item to the collected object"); } } if (pthread_mutex_lock(&cache->queue_mutex) != 0) { dE("An error ocured while re-locking the queue mutex: %u, %s", errno, strerror(errno)); abort(); } if (cache->queue_cnt > 0) goto next; } return (NULL); }
static int oval_probe_variable_eval(oval_probe_session_t *sess, struct oval_syschar *syschar) { struct oval_value_iterator *vit; struct oval_variable *var; struct oval_object *obj; oval_syschar_collection_flag_t flag = SYSCHAR_FLAG_ERROR; int ret = 0; obj = oval_syschar_get_object(syschar); var = oval_probe_variable_objgetvar(obj); if (var == NULL) { oval_syschar_set_flag(syschar, SYSCHAR_FLAG_ERROR); return(-1); } if (oval_probe_query_variable(sess, var) != 0) { oval_syschar_set_flag(syschar, SYSCHAR_FLAG_ERROR); return(-1); } flag = oval_variable_get_collection_flag(var); switch (flag) { case SYSCHAR_FLAG_COMPLETE: case SYSCHAR_FLAG_INCOMPLETE: break; default: { char msg[100]; snprintf(msg, sizeof(msg), "There was a problem processing referenced variable (%s).", oval_variable_get_id(var)); dW("%s\n", msg); oval_syschar_add_new_message(syschar, msg, OVAL_MESSAGE_LEVEL_WARNING); oval_syschar_set_flag(syschar, SYSCHAR_FLAG_ERROR); return(1); } } vit = oval_variable_get_values(var); if (vit == NULL) { flag = SYSCHAR_FLAG_ERROR; oval_syschar_set_flag(syschar, SYSCHAR_FLAG_ERROR); return(1); } else { SEXP_t *r0, *item, *cobj, *vrent, *val_sexp, *valent; char *var_ref; cobj = probe_cobj_new(SYSCHAR_FLAG_UNKNOWN, NULL, NULL); /* Create shared entity */ var_ref = oval_variable_get_id(var); vrent = probe_ent_creat1("var_ref", NULL, r0 = SEXP_string_new(var_ref, strlen(var_ref))); SEXP_free(r0); while (oval_value_iterator_has_more(vit)) { oval_datatype_t dtype; struct oval_value *val; val = oval_value_iterator_next(vit); oval_value_cast(val, OVAL_DATATYPE_STRING); dtype = oval_value_get_datatype(val); val_sexp = oval_value_to_sexp(val, dtype); assume_d(val_sexp != NULL, -1); valent = probe_ent_creat1("value", NULL, val_sexp); item = probe_item_creat("variable_item", NULL, NULL); /* temporary workaround to generate ids */ _gen_item_id(item); /* Add shared var_ref entity */ SEXP_list_add(item, vrent); /* Add value entity */ SEXP_list_add(item, valent); /* Add item to the item list */ probe_cobj_add_item(cobj, item); SEXP_vfree(item, valent, val_sexp, NULL); } oval_value_iterator_free(vit); probe_cobj_compute_flag(cobj); ret = oval_sexp2sysch(cobj, syschar); SEXP_vfree(cobj, vrent, NULL); } return(ret); }
static int rpmverify_collect(probe_ctx *ctx, const char *name, oval_operation_t name_op, const char *file, oval_operation_t file_op, SEXP_t *name_ent, SEXP_t *filepath_ent, uint64_t flags, void (*callback)(probe_ctx *, struct rpmverify_res *)) { rpmdbMatchIterator match; rpmVerifyAttrs omit = (rpmVerifyAttrs)(flags & RPMVERIFY_RPMATTRMASK); Header pkgh; pcre *re = NULL; int ret = -1; /* pre-compile regex if needed */ if (file_op == OVAL_OPERATION_PATTERN_MATCH) { const char *errmsg; int erroff; re = pcre_compile(file, PCRE_UTF8, &errmsg, &erroff, NULL); if (re == NULL) { /* TODO */ return (-1); } } RPMVERIFY_LOCK; switch (name_op) { case OVAL_OPERATION_EQUALS: match = rpmtsInitIterator (g_rpm.rpmts, RPMTAG_NAME, (const void *)name, 0); if (match == NULL) { ret = 0; goto ret; } ret = rpmdbGetIteratorCount (match); break; case OVAL_OPERATION_NOT_EQUAL: match = rpmtsInitIterator (g_rpm.rpmts, RPMDBI_PACKAGES, NULL, 0); if (match == NULL) { ret = 0; goto ret; } if (rpmdbSetIteratorRE (match, RPMTAG_NAME, RPMMIRE_GLOB, "*") != 0) { ret = -1; goto ret; } break; case OVAL_OPERATION_PATTERN_MATCH: match = rpmtsInitIterator (g_rpm.rpmts, RPMDBI_PACKAGES, NULL, 0); if (match == NULL) { ret = 0; goto ret; } if (rpmdbSetIteratorRE (match, RPMTAG_NAME, RPMMIRE_REGEX, (const char *)name) != 0) { ret = -1; goto ret; } break; default: /* not supported */ dE("package name: operation not supported"); ret = -1; goto ret; } assume_d(RPMTAG_BASENAMES != 0, -1); assume_d(RPMTAG_DIRNAMES != 0, -1); while ((pkgh = rpmdbNextIterator (match)) != NULL) { rpmfi fi; rpmTag tag[2] = { RPMTAG_BASENAMES, RPMTAG_DIRNAMES }; struct rpmverify_res res; errmsg_t rpmerr; int i; SEXP_t *name_sexp; res.name = headerFormat(pkgh, "%{NAME}", &rpmerr); name_sexp = SEXP_string_newf("%s", res.name); if (probe_entobj_cmp(name_ent, name_sexp) != OVAL_RESULT_TRUE) { SEXP_free(name_sexp); continue; } SEXP_free(name_sexp); /* * Inspect package files & directories */ for (i = 0; i < 2; ++i) { fi = rpmfiNew(g_rpm.rpmts, pkgh, tag[i], 1); while (rpmfiNext(fi) != -1) { SEXP_t *filepath_sexp; res.fflags = rpmfiFFlags(fi); res.oflags = omit; if (((res.fflags & RPMFILE_CONFIG) && (flags & RPMVERIFY_SKIP_CONFIG)) || ((res.fflags & RPMFILE_GHOST) && (flags & RPMVERIFY_SKIP_GHOST))) continue; res.file = strdup(rpmfiFN(fi)); filepath_sexp = SEXP_string_newf("%s", res.file); if (probe_entobj_cmp(filepath_ent, filepath_sexp) != OVAL_RESULT_TRUE) { SEXP_free(filepath_sexp); free(res.file); continue; } SEXP_free(filepath_sexp); if (rpmVerifyFile(g_rpm.rpmts, fi, &res.vflags, omit) != 0) res.vflags = RPMVERIFY_FAILURES; callback(ctx, &res); free(res.file); } rpmfiFree(fi); } } match = rpmdbFreeIterator (match); ret = 0; ret: if (re != NULL) pcre_free(re); RPMVERIFY_UNLOCK; return (ret); }
int probe_main(probe_ctx *ctx, void *mutex) { LDAP *ldp; LDAPMessage *ldpres, *entry; SEXP_t *se_ldap_behaviors = NULL, *se_relative_dn = NULL; SEXP_t *se_suffix = NULL, *se_attribute = NULL; SEXP_t *sa_scope, *sv_op; SEXP_t *item; SEXP_t *probe_in; char *relative_dn = NULL; char *suffix = NULL, *xattribute = NULL; char *uri_list, *uri, *uri_save, *attr; int scope; char base[2048]; char *attrs[3]; bool a_pattern_match = false, rdn_pattern_match = false; /* runtime */ #if defined(PROBE_LDAP_MUTEX) assume_r(mutex != NULL, PROBE_EINIT); #endif probe_in = probe_ctx_getobject(ctx); se_ldap_behaviors = probe_obj_getent(probe_in, "behaviors", 1); if (se_ldap_behaviors != NULL) { sa_scope = probe_ent_getattrval(se_ldap_behaviors, "scope"); SEXP_free(se_ldap_behaviors); if (sa_scope == NULL) { dE("Atrribute `scope' is missing!"); return (PROBE_ENOATTR); } if (!SEXP_stringp(sa_scope)) { dE("Invalid value type of the `scope' attribute."); SEXP_free(sa_scope); return (PROBE_EINVAL); } if (SEXP_strcmp(sa_scope, "ONE") == 0) scope = LDAP_SCOPE_ONELEVEL; else if (SEXP_strcmp(sa_scope, "BASE") == 0) scope = LDAP_SCOPE_BASE; else if (SEXP_strcmp(sa_scope, "SUBTREE") == 0) scope = LDAP_SCOPE_SUBTREE; else { dE("Invalid value of the `scope' attribute."); SEXP_free(sa_scope); return (PROBE_EINVAL); } SEXP_free(sa_scope); } else scope = LDAP_SCOPE_BASE; #define get_string(dst, se_dst, obj, ent_name) \ do { \ SEXP_t *__sval; \ \ __sval = probe_obj_getentval (obj, ent_name, 1); \ \ if (__sval != NULL) { \ (dst) = SEXP_string_cstr (__sval); \ \ if ((dst) == NULL) { \ SEXP_free(__sval); \ return (PROBE_EINVAL); \ } \ \ (se_dst) = __sval; \ } else { \ return (PROBE_ENOATTR); \ } \ } while (0) get_string(suffix, se_suffix, probe_in, "suffix"); get_string(relative_dn, se_relative_dn, probe_in, "relative_dn"); get_string(xattribute, se_attribute, probe_in, "attribute"); if ((sv_op = probe_ent_getattrval(se_relative_dn, "operation")) != NULL) { if (SEXP_number_geti_32(sv_op) == OVAL_OPERATION_PATTERN_MATCH) rdn_pattern_match = true; SEXP_free(sv_op); } if ((sv_op = probe_ent_getattrval(se_attribute, "operation")) != NULL) { if (SEXP_number_geti_32(sv_op) == OVAL_OPERATION_PATTERN_MATCH) a_pattern_match = true; SEXP_free(sv_op); } /* * Construct the attribute array for ldap_search_* * * nil -> "1.1" * .* -> "*" * "foo" -> "foo" */ attrs[0] = "objectClass"; if (xattribute == NULL) attrs[1] = strdup("1.1"); /* no attibutes */ else if (a_pattern_match) attrs[1] = strdup("*"); /* collect all, we'll filter them afterwards */ else attrs[1] = xattribute; /* no pattern match, use the string directly */ attrs[2] = NULL; /* * Construct `base' */ assume_r(((relative_dn ? strlen(relative_dn) : 0) + ( suffix ? strlen(suffix) : 0) + 2) < (sizeof base/sizeof(char)), PROBE_ERANGE); if (relative_dn != NULL) { strcpy(base, relative_dn); strcat(base, ","); strcat(base, suffix); } else strcpy(base, suffix); /* * Get URIs */ if (ldap_get_option(NULL, LDAP_OPT_URI, &uri_list) != LDAP_OPT_SUCCESS) { item = probe_item_creat("ldap57_item", NULL, NULL); probe_item_setstatus(item, SYSCHAR_STATUS_ERROR); probe_item_collect(ctx, item); dE("ldap_get_option failed"); goto fail0; } /* * Query each URI */ for (;;) { char *entry_dn = NULL; if ((uri = strtok_r(uri_list, " ,", &uri_save)) == NULL) break; ldp = NULL; if (ldap_initialize(&ldp, uri) != LDAP_SUCCESS) continue; if (ldap_search_ext_s(ldp, base, scope, NULL, attrs, 0, NULL /* serverctrls */, NULL /* clientctrls */, NULL /* timeout */, 0, &ldpres) != LDAP_SUCCESS) { item = probe_item_creat("ldap57_item", NULL, NULL); probe_item_setstatus(item, SYSCHAR_STATUS_ERROR); probe_item_collect(ctx, item); dE("ldap_search_ext_s failed"); goto fail0; } entry = ldap_first_entry(ldp, ldpres); entry_dn = ldap_get_dn(ldp, entry); while (entry != NULL) { BerElement *berelm = NULL; attr = ldap_first_attribute(ldp, entry, &berelm); /* XXX: pattern match filter */ while (attr != NULL) { SEXP_t *se_value = NULL; ber_tag_t bertag = LBER_DEFAULT; ber_len_t berlen = 0; Sockbuf *berbuf = NULL; SEXP_t se_tmp_mem; berbuf = ber_sockbuf_alloc(); /* * Prepare the value (record) entity. Collect only * primitive (i.e. simple) types. */ se_value = probe_ent_creat1("value", NULL, NULL); probe_ent_setdatatype(se_value, OVAL_DATATYPE_RECORD); /* * XXX: does ber_get_next() return LBER_ERROR after the last value? */ while ((bertag = ber_get_next(berbuf, &berlen, berelm)) != LBER_ERROR) { SEXP_t *field = NULL; oval_datatype_t field_type = OVAL_DATATYPE_UNKNOWN; switch(bertag & LBER_ENCODING_MASK) { case LBER_PRIMITIVE: dI("Found primitive value, bertag = %u", bertag); break; case LBER_CONSTRUCTED: dW("Don't know how to handle LBER_CONSTRUCTED values"); /* FALLTHROUGH */ default: dW("Skipping attribute value, bertag = %u", bertag); continue; } assume_d(bertag & LBER_PRIMITIVE, NULL); switch(bertag & LBER_BIG_TAG_MASK) { case LBER_BOOLEAN: { /* LDAPTYPE_BOOLEAN */ ber_int_t val = -1; if (ber_get_boolean(berelm, &val) == LBER_ERROR) { dW("ber_get_boolean: LBER_ERROR"); /* XXX: set error status on field */ continue; } assume_d(val != -1, NULL); field = probe_ent_creat1("field", NULL, SEXP_number_newb_r(&se_tmp_mem, (bool)val)); field_type = OVAL_DATATYPE_BOOLEAN; SEXP_free_r(&se_tmp_mem); } break; case LBER_INTEGER: { /* LDAPTYPE_INTEGER */ ber_int_t val = -1; if (ber_get_int(berelm, &val) == LBER_ERROR) { dW("ber_get_int: LBER_ERROR"); /* XXX: set error status on field */ continue; } field = probe_ent_creat1("field", NULL, SEXP_number_newi_r(&se_tmp_mem, (int)val)); field_type = OVAL_DATATYPE_INTEGER; SEXP_free_r(&se_tmp_mem); } break; case LBER_BITSTRING: /* LDAPTYPE_BIT_STRING */ dW("LBER_BITSTRING: not implemented"); continue; case LBER_OCTETSTRING: { /* * LDAPTYPE_PRINTABLE_STRING * LDAPTYPE_NUMERIC_STRING * LDAPTYPE_DN_STRING * LDAPTYPE_BINARY (?) */ char *val = NULL; if (ber_get_stringa(berelm, &val) == LBER_ERROR) { dW("ber_get_stringa: LBER_ERROR"); /* XXX: set error status on field */ continue; } assume_d(val != NULL, NULL); field = probe_ent_creat1("field", NULL, SEXP_string_new_r(&se_tmp_mem, val, strlen(val))); field_type = OVAL_DATATYPE_STRING; SEXP_free_r(&se_tmp_mem); ber_memfree(val); } break; case LBER_NULL: /* XXX: no equivalent LDAPTYPE_? or empty */ dI("LBER_NULL: skipped"); continue; case LBER_ENUMERATED: /* XXX: no equivalent LDAPTYPE_? */ dW("Don't know how to handle LBER_ENUMERATED type"); continue; default: dW("Unknown attribute value type, bertag = %u", bertag); continue; } if (field != NULL) { assume_d(field_type != OVAL_DATATYPE_UNKNOWN, NULL); probe_ent_setdatatype(field, field_type); probe_ent_attr_add(field, "name", SEXP_string_new_r(&se_tmp_mem, attr, strlen(attr))); SEXP_list_add(se_value, field); SEXP_free_r(&se_tmp_mem); SEXP_free(field); } } ber_sockbuf_free(berbuf); /* * Create the item */ item = probe_item_create(OVAL_INDEPENDENT_LDAP57, NULL, "suffix", OVAL_DATATYPE_STRING, suffix, "relative_dn", OVAL_DATATYPE_STRING, relative_dn, /* XXX: pattern match */ "attribute", OVAL_DATATYPE_STRING, attr, "object_class", OVAL_DATATYPE_STRING, "", "ldaptype", OVAL_DATATYPE_STRING, "", NULL); SEXP_list_add(item, se_value); SEXP_free(se_value); probe_item_collect(ctx, item); attr = ldap_next_attribute(ldp, entry, berelm); } ber_free(berelm, 0); ldap_memfree(entry_dn); entry = ldap_next_entry(ldp, entry); entry_dn = ldap_get_dn(ldp, entry); } /* * Close the LDAP connection and free resources */ ldap_unbind_ext_s(ldp, NULL, NULL); } ldap_memfree(uri_list); fail0: SEXP_free(se_suffix); SEXP_free(se_relative_dn); SEXP_free(se_attribute); free(suffix); free(relative_dn); free(attrs[1]); /* attribute */ return (0); }
SEXP_datatypePtr_t *SEXP_datatype_add(SEXP_datatypeTbl_t *t, char *n, SEXP_datatype_t *d, void *l) { void *r; struct rbt_str_node *node = NULL; assume_d(t != NULL, NULL); assume_d(n != NULL, NULL); SEXP_datatype_once(); /* * Check whether flags & passed values are meaningful */ if (l != NULL && (d->dt_flg & SEXP_DTFLG_LOCALDATA) == 0) { errno = EINVAL; return(NULL); } if (rbt_str_add(t->tree, n, d) != 0) return(NULL); /* * XXX: consider adding a version of rbt_str_add that returns * the node pointer, so that we don't have perform the * following search operation. */ if (rbt_str_getnode(t->tree, n, &node) != 0) return(NULL); if (d != NULL) { /* * If DTFLG_LOCALDATA is set, allocate a new extended pointer * and return it with `l' set as the local data pointer. */ if (d->dt_flg & SEXP_DTFLG_LOCALDATA) { struct SEXP_datatype_extptr *eptr = NULL; /* * Ensure that we can use the lowest bit for the extended * pointer flag. In the case we are returning the "normal" * pointer, the memory is already aligned because it's a * pointer into a red-black tree node + 2*sizeof(void *) * offset. The red-black tree implmentation allocates nodes * aligned to sizeof(void *) bytes. */ if (posix_memalign((void **)(void *)(&eptr), SEXP_DATATYPEPTR_ALIGN, sizeof(struct SEXP_datatype_extptr)) != 0) { return(NULL); } eptr->n = node; eptr->l = l; r = (void *)((uintptr_t)(eptr)|1); } else r = node; } else r = node; return((SEXP_datatypePtr_t *)r); }
int SEXP_datatypeTbl_init (SEXP_datatypeTbl_t *t) { assume_d(t != NULL, -1); t->tree = rbt_str_new(); return(0); }
static int oval_pdtbl_typecmp(oval_subtype_t *a, oval_pd_t **b) { assume_d(a != NULL, -1); assume_d(*b != NULL, -1); return (*a - (*b)->subtype); }
int probe_main(probe_ctx *ctx, void *arg) { SEXP_t *path_ent, *file_ent, *inst_ent, *bh_ent, *patt_ent, *filepath_ent, *probe_in; SEXP_t *r0; /* char *i_val, *m_val, *s_val; */ bool val; struct pfdata pfd; int ret = 0; #if defined USE_REGEX_PCRE int errorffset = -1; const char *error; #elif defined USE_REGEX_POSIX regex_t _re; pfd.compiled_regex = &_re; int err; #endif OVAL_FTS *ofts; OVAL_FTSENT *ofts_ent; (void)arg; memset(&pfd, 0, sizeof(pfd)); probe_in = probe_ctx_getobject(ctx); over = probe_obj_get_platform_schema_version(probe_in); path_ent = probe_obj_getent(probe_in, "path", 1); file_ent = probe_obj_getent(probe_in, "filename", 1); inst_ent = probe_obj_getent(probe_in, "instance", 1); patt_ent = probe_obj_getent(probe_in, "pattern", 1); filepath_ent = probe_obj_getent(probe_in, "filepath", 1); bh_ent = probe_obj_getent(probe_in, "behaviors", 1); /* we want (path+filename or filepath) + instance + pattern*/ if ( ((path_ent == NULL || file_ent == NULL) && filepath_ent==NULL) || inst_ent==NULL || patt_ent==NULL) { SEXP_free (patt_ent); ret = PROBE_ENOELM; goto cleanup; } /* get pattern from SEXP */ SEXP_t *ent_val; ent_val = probe_ent_getval(patt_ent); pfd.pattern = SEXP_string_cstr(ent_val); assume_d(pfd.pattern != NULL, -1); SEXP_free(patt_ent); SEXP_free(ent_val); /* wtf? i_val = s_val = "0"; m_val = "1"; */ /* reset filebehavior attributes if 'filepath' entity is used */ if (filepath_ent != NULL && bh_ent != NULL) { SEXP_t *r1, *r2, *r3; r1 = probe_ent_getattrval(bh_ent, "ignore_case"); r2 = probe_ent_getattrval(bh_ent, "multiline"); r3 = probe_ent_getattrval(bh_ent, "singleline"); r0 = probe_attr_creat("ignore_case", r1, "multiline", r2, "singleline", r3, NULL); SEXP_free(bh_ent); bh_ent = probe_ent_creat1("behaviors", r0, NULL); SEXP_vfree(r0, r1, r2, r3, NULL); } probe_tfc54behaviors_canonicalize(&bh_ent); pfd.instance_ent = inst_ent; pfd.ctx = ctx; #if defined USE_REGEX_PCRE pfd.re_opts = PCRE_UTF8; r0 = probe_ent_getattrval(bh_ent, "ignore_case"); if (r0) { val = SEXP_string_getb(r0); SEXP_free(r0); if (val) pfd.re_opts |= PCRE_CASELESS; } r0 = probe_ent_getattrval(bh_ent, "multiline"); if (r0) { val = SEXP_string_getb(r0); SEXP_free(r0); if (val) pfd.re_opts |= PCRE_MULTILINE; } r0 = probe_ent_getattrval(bh_ent, "singleline"); if (r0) { val = SEXP_string_getb(r0); SEXP_free(r0); if (val) pfd.re_opts |= PCRE_DOTALL; } pfd.compiled_regex = pcre_compile(pfd.pattern, pfd.re_opts, &error, &errorffset, NULL); if (pfd.compiled_regex == NULL) { SEXP_t *msg; msg = probe_msg_creatf(OVAL_MESSAGE_LEVEL_ERROR, "pcre_compile() '%s' %s.", pfd.pattern, error); probe_cobj_add_msg(probe_ctx_getresult(pfd.ctx), msg); SEXP_free(msg); probe_cobj_set_flag(probe_ctx_getresult(pfd.ctx), SYSCHAR_FLAG_ERROR); goto cleanup; } #elif defined USE_REGEX_POSIX pfd.re_opts = REG_EXTENDED | REG_NEWLINE; r0 = probe_ent_getattrval(bh_ent, "ignore_case"); if (r0) { val = SEXP_string_getb(r0); SEXP_free(r0); if (val) pfd.re_opts |= REG_ICASE; } if ((err = regcomp(pfd.compiled_regex, pfd.pattern, pfd.re_opts)) != 0) { SEXP_t *msg; msg = probe_msg_creatf(OVAL_MESSAGE_LEVEL_ERROR, "regcomp() '%s' returned %d.", pfd.pattern, err); probe_cobj_add_msg(probe_ctx_getresult(pfd.ctx), msg); SEXP_free(msg); probe_cobj_set_flag(probe_ctx_getresult(pfd.ctx), SYSCHAR_FLAG_ERROR); goto cleanup; } #endif if ((ofts = oval_fts_open(path_ent, file_ent, filepath_ent, bh_ent)) != NULL) { while ((ofts_ent = oval_fts_read(ofts)) != NULL) { if (ofts_ent->fts_info == FTS_F || ofts_ent->fts_info == FTS_SL) { // todo: handle return code process_file(ofts_ent->path, ofts_ent->file, &pfd); } oval_ftsent_free(ofts_ent); } oval_fts_close(ofts); } cleanup: SEXP_free(file_ent); SEXP_free(path_ent); SEXP_free(inst_ent); SEXP_free(bh_ent); SEXP_free(filepath_ent); if (pfd.pattern != NULL) oscap_free(pfd.pattern); #if defined USE_REGEX_PCRE if (pfd.compiled_regex != NULL) pcre_free(pfd.compiled_regex); #elif defined USE_REGEX_POSIX regfree(&_re); #endif return ret; }
int probe_main(probe_ctx *ctx, void *arg) { SEXP_t *path_ent, *filename_ent, *line_ent, *behaviors_ent, *filepath_ent, *probe_in; char *pattern; OVAL_FTS *ofts; OVAL_FTSENT *ofts_ent; (void)arg; probe_in = probe_ctx_getobject(ctx); over = probe_obj_get_platform_schema_version(probe_in); path_ent = probe_obj_getent(probe_in, "path", 1); filename_ent = probe_obj_getent(probe_in, "filename", 1); line_ent = probe_obj_getent(probe_in, "line", 1); filepath_ent = probe_obj_getent(probe_in, "filepath", 1); behaviors_ent = probe_obj_getent(probe_in, "behaviors", 1); if ( ((path_ent == NULL || filename_ent == NULL) && filepath_ent==NULL) || line_ent==NULL ) { SEXP_free (path_ent); SEXP_free (filename_ent); SEXP_free (line_ent); SEXP_free (filepath_ent); SEXP_free (behaviors_ent); return PROBE_ENOELM; } /* get pattern from SEXP */ SEXP_t *ent_val; ent_val = probe_ent_getval(line_ent); pattern = SEXP_string_cstr(ent_val); assume_d(pattern != NULL, -1); SEXP_vfree(line_ent, ent_val, NULL); /* behaviours are not important if filepath is used */ if(filepath_ent != NULL && behaviors_ent != NULL) { SEXP_free (behaviors_ent); behaviors_ent = NULL; } probe_filebehaviors_canonicalize(&behaviors_ent); struct pfdata pfd; pfd.pattern = pattern; pfd.filename_ent = filename_ent; pfd.ctx = ctx; if ((ofts = oval_fts_open(path_ent, filename_ent, filepath_ent, behaviors_ent, probe_ctx_getresult(ctx))) != NULL) { while ((ofts_ent = oval_fts_read(ofts)) != NULL) { if (ofts_ent->fts_info == FTS_F || ofts_ent->fts_info == FTS_SL) { // todo: handle return code process_file(ofts_ent->path, ofts_ent->file, &pfd); } oval_ftsent_free(ofts_ent); } oval_fts_close(ofts); } SEXP_free(path_ent); SEXP_free(filename_ent); SEXP_free(behaviors_ent); SEXP_free(filepath_ent); oscap_free(pattern); return 0; }