Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
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
}
Ejemplo n.º 5
0
/**
 * 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);
}
Ejemplo n.º 6
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);
}
Ejemplo n.º 7
0
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);
}
Ejemplo n.º 8
0
int rbt_rlock(rbt_t *rbt)
{
        assume_d (rbt != NULL, -1);

        if (pthread_rwlock_rdlock(&rbt->lock) != 0)
                return (-1);
        else
                return (0);
}
Ejemplo n.º 9
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);
}
Ejemplo n.º 10
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);
}
Ejemplo n.º 11
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);
}
Ejemplo n.º 12
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);
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
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);
}
Ejemplo n.º 15
0
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);
}
Ejemplo n.º 16
0
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);
}
Ejemplo n.º 17
0
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);
}
Ejemplo n.º 18
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);
}
Ejemplo n.º 19
0
int SEXP_datatypeTbl_init (SEXP_datatypeTbl_t *t)
{
        assume_d(t != NULL, -1);
        t->tree = rbt_str_new();
        return(0);
}
Ejemplo n.º 20
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);
}
Ejemplo n.º 21
0
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;
}
Ejemplo n.º 22
0
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;
}