Beispiel #1
0
static oval_result_t
_oval_result_test_evaluate_items(struct oval_test *test, struct oval_syschar *syschar_object, void **args)
{
	struct oval_sysitem_iterator *collected_items_itr;
	oval_result_t result;
	int exists_cnt, error_cnt;
	bool hasstate;
	oval_check_t test_check;
	oval_existence_t test_check_existence;
	struct oval_state_iterator *ste_itr;

	exists_cnt = error_cnt = 0;
	collected_items_itr = oval_syschar_get_sysitem(syschar_object);
	while (oval_sysitem_iterator_has_more(collected_items_itr)) {
		struct oval_sysitem *item;
		char *item_id;
		oval_syschar_status_t item_status;
		struct oval_result_item *ritem;

		item = oval_sysitem_iterator_next(collected_items_itr);
		if (item == NULL) {
			oscap_seterr(OSCAP_EFAMILY_OVAL, "Iterator returned null.");
			oval_sysitem_iterator_free(collected_items_itr);
			return OVAL_RESULT_ERROR;
		}

		item_status = oval_sysitem_get_status(item);
		if (item_status == SYSCHAR_STATUS_EXISTS)
			exists_cnt++;
		if (item_status == SYSCHAR_STATUS_ERROR)
			error_cnt++;

		item_id = oval_sysitem_get_id(item);
		ritem = oval_result_item_new(SYSTEM, item_id);
		oval_result_item_set_result(ritem, OVAL_RESULT_NOT_EVALUATED);
		_oval_test_item_consumer(ritem, args);
	}
	oval_sysitem_iterator_free(collected_items_itr);

	test_check = oval_test_get_check(test);
	test_check_existence = oval_test_get_existence(test);
	ste_itr = oval_test_get_states(test);
	hasstate = oval_state_iterator_has_more(ste_itr);
	oval_state_iterator_free(ste_itr);

	switch (oval_syschar_get_flag(syschar_object)) {
	case SYSCHAR_FLAG_ERROR:
		if (test_check_existence == OVAL_ANY_EXIST
		    && !hasstate) {
			result = OVAL_RESULT_TRUE;
		} else {
			result = OVAL_RESULT_ERROR;
		}
		break;
	case SYSCHAR_FLAG_NOT_COLLECTED:
		if (test_check_existence == OVAL_ANY_EXIST
		    && !hasstate) {
			result = OVAL_RESULT_TRUE;
		} else {
			result = OVAL_RESULT_UNKNOWN;
		}
		break;
	case SYSCHAR_FLAG_NOT_APPLICABLE:
		if (test_check_existence == OVAL_ANY_EXIST
		    && !hasstate) {
			result = OVAL_RESULT_TRUE;
		} else {
			result = OVAL_RESULT_NOT_APPLICABLE;
		}
		break;
	case SYSCHAR_FLAG_DOES_NOT_EXIST:
		if (test_check_existence == OVAL_NONE_EXIST
		    || test_check_existence == OVAL_ANY_EXIST) {
			result = OVAL_RESULT_TRUE;
		} else {
			result = OVAL_RESULT_FALSE;
		}
		break;
	case SYSCHAR_FLAG_COMPLETE:
		result = eval_check_existence(test_check_existence, exists_cnt, error_cnt);
		if (result == OVAL_RESULT_TRUE
		    && hasstate) {
			result = eval_check_state(test, args);
		}
		break;
	case SYSCHAR_FLAG_INCOMPLETE:
		if (test_check_existence == OVAL_ANY_EXIST) {
			result = OVAL_RESULT_TRUE;
		} else if (test_check_existence == OVAL_AT_LEAST_ONE_EXISTS
			   && exists_cnt > 0) {
			result = OVAL_RESULT_TRUE;
		} else if (test_check_existence == OVAL_NONE_EXIST
			   && exists_cnt > 0) {
			result = OVAL_RESULT_FALSE;
		} else if (test_check_existence == OVAL_ONLY_ONE_EXISTS
			   && exists_cnt > 1) {
			result = OVAL_RESULT_FALSE;
		} else {
			result = OVAL_RESULT_UNKNOWN;
		}

		if (result == OVAL_RESULT_TRUE
		    && hasstate) {
			result = eval_check_state(test, args);
			if (result == OVAL_RESULT_TRUE) {
				if (test_check != OVAL_CHECK_AT_LEAST_ONE) {
					result = OVAL_RESULT_UNKNOWN;
				}
			} else if (result != OVAL_RESULT_FALSE) {
				result = OVAL_RESULT_UNKNOWN;
			}
		}
		break;
	default: {
		const char *object_id = oval_syschar_get_object(syschar_object) ? oval_object_get_id(oval_syschar_get_object(syschar_object)) : "<UNKNOWN>";
		oscap_seterr(OSCAP_EFAMILY_OVAL, "Unknown syschar flag: '%d' when evaluating object: '%s' from test: '%s' ",
				oval_syschar_get_flag(syschar_object), object_id, oval_test_get_id(test));
		return OVAL_RESULT_ERROR;
		}
	}

	return result;
}
Beispiel #2
0
int oval_object_to_sexp(void *sess, const char *typestr, struct oval_syschar *syschar, SEXP_t **out_sexp)
{
	unsigned int ent_cnt, varref_cnt;
	int ret;
	SEXP_t *obj_sexp, *elm, *varrefs, *ent_lst, *lst, *stmp;
	SEXP_t *r0, *r1, *r2, *obj_attr, sm0, sm1;

	struct oval_object *object;
	struct oval_object_content_iterator *cit;
	struct oval_behavior_iterator *bit;
	struct oval_object_content *content;
	struct oval_entity *entity;

	char obj_name[128];
	const char *obj_id;

	object = oval_syschar_get_object(syschar);

	/*
	 * Object name & attributes (id)
	 */
	ret = snprintf(obj_name, sizeof obj_name, "%s_object", typestr);
	if (ret<0 || (unsigned int) ret > sizeof obj_name) {
		dE("obj_name length too short");
		return -1;
	}

	// even though it returns const char* it has to be freed :-(
	char *obj_over = (char*)oval_schema_version_to_cstr(oval_object_get_platform_schema_version(object));
	obj_id   = oval_object_get_id(object);
	obj_attr = probe_attr_creat("id", SEXP_string_new_r(&sm0, obj_id, strlen(obj_id)),
	                            "oval_version", SEXP_string_new_r(&sm1, obj_over, strlen(obj_over)),
	                            NULL);
	free(obj_over);

	obj_sexp = probe_obj_new(obj_name, obj_attr);

	SEXP_free_r(&sm0);
	SEXP_free_r(&sm1);
	SEXP_free(obj_attr);

	/*
	 * Object content
	 */

	ent_lst = SEXP_list_new(NULL);
	varrefs = NULL;
	ent_cnt = varref_cnt = 0;

	cit = oval_object_get_object_contents(object);
	while (oval_object_content_iterator_has_more(cit)) {
		oval_check_t ochk;
		oval_entity_varref_type_t vr_type;

		content = oval_object_content_iterator_next(cit);
		elm = NULL;
		lst = ent_lst;

		switch (oval_object_content_get_type(content)) {
		case OVAL_OBJECTCONTENT_ENTITY:
			entity = oval_object_content_get_entity(content);
			elm = oval_entity_to_sexp(entity);
			if (elm == NULL)
				break;

			ochk = oval_object_content_get_varCheck(content);
			if (ochk != OVAL_CHECK_UNKNOWN) {
				probe_ent_attr_add(elm, "var_check",
						   r0 = SEXP_number_newu_32(ochk));
				SEXP_free(r0);
			}
			ret = 0;
			vr_type = oval_entity_get_varref_type(entity);
			if (vr_type == OVAL_ENTITY_VARREF_ATTRIBUTE) {
				const char *var_id = oval_variable_get_id(oval_entity_get_variable(entity));
				const char *field_name = oval_object_content_get_field_name(content);
				dI("Object '%s' references variable '%s' in '%s' field.", obj_id, var_id, field_name);
				ret = oval_varref_attr_to_sexp(sess, entity, syschar, &stmp);

				if (ret == 0) {
					if (varrefs == NULL)
						varrefs = SEXP_list_new(NULL);

					SEXP_list_add(varrefs, stmp);
					SEXP_free(stmp);
					// todo: don't add duplicates
					++varref_cnt;

					lst = obj_sexp;
					++ent_cnt;
				}
			} else if (vr_type == OVAL_ENTITY_VARREF_ELEMENT) {
				SEXP_t *val_lst;
				struct oval_variable *var;
				oval_datatype_t dt;

				var = oval_entity_get_variable(entity);
				dt = oval_entity_get_datatype(entity);
				ret = oval_varref_elm_to_sexp(sess, var, dt, &val_lst, syschar);

				if (ret == 0) {
					SEXP_list_add(elm, val_lst);
					SEXP_free(val_lst);
				}
			}

			if (ret != 0) {
				SEXP_t s_flag;
				SEXP_number_newi_32_r(&s_flag, SYSCHAR_FLAG_DOES_NOT_EXIST);
				probe_item_attr_add(obj_sexp, "skip_eval", &s_flag);
				SEXP_free_r(&s_flag);

				SEXP_free(elm);
				SEXP_free(ent_lst);
				if (varrefs != NULL)
					SEXP_free(varrefs);
				oval_object_content_iterator_free(cit);

				*out_sexp = obj_sexp;

				return (0);
			}

			break;

		case OVAL_OBJECTCONTENT_SET:
			elm = oval_set_to_sexp(oval_object_content_get_setobject(content));
			break;

		case OVAL_OBJECTCONTENT_FILTER: {
			struct oval_filter *filter = oval_object_content_get_filter(content);
			struct oval_state *ste = oval_filter_get_state(filter);
			const char *ste_id = oval_state_get_id(ste);
			oval_filter_action_t action = oval_filter_get_filter_action(filter);
			const char *action_text = oval_filter_action_get_text(action);
			dI("Object '%s' has a filter that %ss items conforming to state '%s'.",
					obj_id, action_text, ste_id);
			elm = oval_filter_to_sexp(filter);
			}
			break;

		case OVAL_OBJECTCONTENT_UNKNOWN:
			break;
		}

		if (elm == NULL) {
			SEXP_free(obj_sexp);
			SEXP_free(ent_lst);
			if (varrefs != NULL)
				SEXP_free(varrefs);
			oval_object_content_iterator_free(cit);

			return -1;
		}

		SEXP_list_add(lst, elm);
		SEXP_free(elm);
	}

	if (varrefs != NULL) {
		// todo: SEXP_list_push()
		stmp = SEXP_list_new(r0 = SEXP_string_new("varrefs", 7),
				     r1 = SEXP_number_newu(varref_cnt), r2 = SEXP_number_newu(ent_cnt), NULL);
		SEXP_vfree(r0, r1, r2, NULL);

		r0 = SEXP_list_join(stmp, varrefs);
		SEXP_list_add(obj_sexp, r0);
		SEXP_vfree(stmp, varrefs, r0, NULL);
	}

	stmp = SEXP_list_join(obj_sexp, ent_lst);
	SEXP_free(obj_sexp);
	SEXP_free(ent_lst);
	obj_sexp = stmp;

	oval_object_content_iterator_free(cit);

	/*
	 * Object behaviors
	 */

	bit = oval_object_get_behaviors(object);
	if (oval_behavior_iterator_has_more(bit)) {
		elm = oval_behaviors_to_sexp(bit);
		SEXP_list_add(obj_sexp, elm);
		SEXP_free(elm);
	}
	oval_behavior_iterator_free(bit);

	*out_sexp = obj_sexp;

	return (0);
}
Beispiel #3
0
static oval_result_t
_oval_result_test_evaluate_items(struct oval_test *test, struct oval_syschar *syschar_object, void **args)
{
	struct oval_sysitem_iterator *collected_items_itr;
	oval_result_t result;
	int exists_cnt, error_cnt;
	bool hasstate;
	const char *test_id, *object_id, *flag_text;
	oval_check_t test_check;
	oval_existence_t test_check_existence;
	struct oval_state_iterator *ste_itr;
	oval_syschar_collection_flag_t flag;
	struct oval_object *object;

	exists_cnt = error_cnt = 0;
	test_id = oval_test_get_id(test);
	collected_items_itr = oval_syschar_get_sysitem(syschar_object);
	while (oval_sysitem_iterator_has_more(collected_items_itr)) {
		struct oval_sysitem *item;
		char *item_id;
		oval_syschar_status_t item_status;
		struct oval_result_item *ritem;

		item = oval_sysitem_iterator_next(collected_items_itr);
		if (item == NULL) {
			oscap_seterr(OSCAP_EFAMILY_OVAL, "Iterator returned null.");
			oval_sysitem_iterator_free(collected_items_itr);
			return OVAL_RESULT_ERROR;
		}

		item_status = oval_sysitem_get_status(item);
		if (item_status == SYSCHAR_STATUS_EXISTS)
			exists_cnt++;
		if (item_status == SYSCHAR_STATUS_ERROR)
			error_cnt++;

		item_id = oval_sysitem_get_id(item);
		ritem = oval_result_item_new(SYSTEM, item_id);
		oval_result_item_set_result(ritem, OVAL_RESULT_NOT_EVALUATED);
		_oval_test_item_consumer(ritem, args);
	}
	oval_sysitem_iterator_free(collected_items_itr);

	test_check = oval_test_get_check(test);
	test_check_existence = oval_test_get_existence(test);
	ste_itr = oval_test_get_states(test);
	hasstate = oval_state_iterator_has_more(ste_itr);
	oval_state_iterator_free(ste_itr);
	object = oval_syschar_get_object(syschar_object);
	object_id = object ? oval_object_get_id(object) : "<UNKNOWN>";

	switch (test_check_existence) {
	case OVAL_ALL_EXIST:
		dI("Test '%s' requires that every object defined by '%s' exists on the system.", test_id, object_id);
		break;
	case OVAL_ANY_EXIST:
		dI("Test '%s' requires that zero or more objects defined by '%s' exist on the system.", test_id, object_id);
		break;
	case OVAL_AT_LEAST_ONE_EXISTS:
		dI("Test '%s' requires that at least one object defined by '%s' exists on the system.", test_id, object_id);
		break;
	case OVAL_NONE_EXIST:
		dI("Test '%s' requires that none of the objects defined by '%s' exist on the system.", test_id, object_id);
		break;
	case OVAL_ONLY_ONE_EXISTS:
		dI("Test '%s' requires that only one object defined by '%s' exists on the system.", test_id, object_id);
		break;
	default:
		oscap_seterr(OSCAP_EFAMILY_OVAL, "Check_existence parameter of test '%s' is unknown. This may indicate a bug in OpenSCAP.", test_id);
	}

	dI("%d objects defined by '%s' exist on the system.", exists_cnt, object_id);
	if (!hasstate) {
		dI("Test '%s' does not contain any state to compare object with.", test_id);
	}
	flag = oval_syschar_get_flag(syschar_object);
	flag_text = oval_syschar_collection_flag_get_text(flag);

	switch (flag) {
	case SYSCHAR_FLAG_ERROR:
		dI("An error occured while collecting items matching object '%s'. (flag=%s)", object_id, flag_text);
		if (test_check_existence == OVAL_ANY_EXIST
		    && !hasstate) {
			result = OVAL_RESULT_TRUE;
		} else {
			result = OVAL_RESULT_ERROR;
		}
		break;
	case SYSCHAR_FLAG_NOT_COLLECTED:
		dI("No attempt was made to collect items matching object '%s'. (flag=%s)", object_id, flag_text);
		if (test_check_existence == OVAL_ANY_EXIST
		    && !hasstate) {
			result = OVAL_RESULT_TRUE;
		} else {
			result = OVAL_RESULT_UNKNOWN;
		}
		break;
	case SYSCHAR_FLAG_NOT_APPLICABLE:
		dI("Object '%s' is not applicable to the system. (flag=%s)", object_id, flag_text);
		if (test_check_existence == OVAL_ANY_EXIST
		    && !hasstate) {
			result = OVAL_RESULT_TRUE;
		} else {
			result = OVAL_RESULT_NOT_APPLICABLE;
		}
		break;
	case SYSCHAR_FLAG_DOES_NOT_EXIST:
		dI("No item matching object '%s' was found on the system. (flag=%s)", object_id, flag_text);
		if (test_check_existence == OVAL_NONE_EXIST
		    || test_check_existence == OVAL_ANY_EXIST) {
			result = OVAL_RESULT_TRUE;
		} else {
			result = OVAL_RESULT_FALSE;
		}
		break;
	case SYSCHAR_FLAG_COMPLETE:
		dI("All items matching object '%s' were collected. (flag=%s)", object_id, flag_text);
		result = eval_check_existence(test_check_existence, exists_cnt, error_cnt);
		if (result == OVAL_RESULT_TRUE
		    && hasstate) {
			result = eval_check_state(test, args);
		}
		break;
	case SYSCHAR_FLAG_INCOMPLETE:
		dI("Only some of items matching object '%s' have been collected from the system. It is unknown if other matching items also exist. (flag=%s)", object_id, flag_text);
		if (test_check_existence == OVAL_ANY_EXIST) {
			result = OVAL_RESULT_TRUE;
		} else if (test_check_existence == OVAL_AT_LEAST_ONE_EXISTS
			   && exists_cnt > 0) {
			result = OVAL_RESULT_TRUE;
		} else if (test_check_existence == OVAL_NONE_EXIST
			   && exists_cnt > 0) {
			result = OVAL_RESULT_FALSE;
		} else if (test_check_existence == OVAL_ONLY_ONE_EXISTS
			   && exists_cnt > 1) {
			result = OVAL_RESULT_FALSE;
		} else {
			result = OVAL_RESULT_UNKNOWN;
		}

		if (result == OVAL_RESULT_TRUE
		    && hasstate) {
			result = eval_check_state(test, args);
			if (result == OVAL_RESULT_TRUE) {
				if (test_check != OVAL_CHECK_AT_LEAST_ONE) {
					result = OVAL_RESULT_UNKNOWN;
				}
			} else if (result != OVAL_RESULT_FALSE) {
				result = OVAL_RESULT_UNKNOWN;
			}
		}
		break;
	default: {
		oscap_seterr(OSCAP_EFAMILY_OVAL, "Item corresponding to object '%s' from test '%s' has an unknown flag. This may indicate a bug in OpenSCAP.",
				object_id, test_id);
		return OVAL_RESULT_ERROR;
		}
	}

	return result;
}
Beispiel #4
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);
}