Blame src/OVAL/results/oval_cmp_basic.c

Packit 517ee8
/*
Packit 517ee8
 * Copyright 2009--2014 Red Hat Inc., Durham, North Carolina.
Packit 517ee8
 * All Rights Reserved.
Packit 517ee8
 *
Packit 517ee8
 * This library is free software; you can redistribute it and/or
Packit 517ee8
 * modify it under the terms of the GNU Lesser General Public
Packit 517ee8
 * License as published by the Free Software Foundation; either
Packit 517ee8
 * version 2.1 of the License, or (at your option) any later version.
Packit 517ee8
 *
Packit 517ee8
 * This library is distributed in the hope that it will be useful,
Packit 517ee8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 517ee8
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 517ee8
 * Lesser General Public License for more details.
Packit 517ee8
 *
Packit 517ee8
 * You should have received a copy of the GNU Lesser General Public
Packit 517ee8
 * License along with this library; if not, write to the Free Software
Packit 517ee8
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Packit 517ee8
 *
Packit 517ee8
 * Authors:
Packit 517ee8
 *     Tomas Heinrich <theinric@redhat.com>
Packit 517ee8
 *     Šimon Lukašík
Packit 517ee8
 */
Packit 517ee8
Packit 517ee8
#ifdef HAVE_CONFIG_H
Packit 517ee8
#include <config.h>
Packit 517ee8
#endif
Packit 517ee8
Packit 517ee8
#include <math.h>
Packit 517ee8
#include <string.h>
Packit 517ee8
#include <pcre.h>
Packit 517ee8
Packit 517ee8
#include "oval_types.h"
Packit 517ee8
#include "common/_error.h"
Packit 517ee8
#include "common/debug_priv.h"
Packit 517ee8
#include "oval_cmp_basic_impl.h"
Packit 517ee8
Packit 517ee8
oval_result_t oval_boolean_cmp(const bool state, const bool syschar, oval_operation_t operation)
Packit 517ee8
{
Packit 517ee8
	switch (operation) {
Packit 517ee8
	case OVAL_OPERATION_EQUALS:
Packit 517ee8
		return state == syschar ? OVAL_RESULT_TRUE : OVAL_RESULT_FALSE;
Packit 517ee8
	case OVAL_OPERATION_NOT_EQUAL:
Packit 517ee8
		return state != syschar ? OVAL_RESULT_TRUE : OVAL_RESULT_FALSE;
Packit 517ee8
	default:
Packit 517ee8
		oscap_seterr(OSCAP_EFAMILY_OVAL, "Invalid type of operation in boolean evaluation: %d.", operation);
Packit 517ee8
	}
Packit 517ee8
	return OVAL_RESULT_ERROR;
Packit 517ee8
}
Packit 517ee8
Packit 517ee8
oval_result_t oval_int_cmp(const intmax_t state, const intmax_t syschar, oval_operation_t operation)
Packit 517ee8
{
Packit 517ee8
	switch (operation) {
Packit 517ee8
	case OVAL_OPERATION_EQUALS:
Packit 517ee8
		return state == syschar ? OVAL_RESULT_TRUE : OVAL_RESULT_FALSE;
Packit 517ee8
	case OVAL_OPERATION_NOT_EQUAL:
Packit 517ee8
		return state != syschar ? OVAL_RESULT_TRUE : OVAL_RESULT_FALSE;
Packit 517ee8
	case OVAL_OPERATION_GREATER_THAN:
Packit 517ee8
		return syschar > state ? OVAL_RESULT_TRUE : OVAL_RESULT_FALSE;
Packit 517ee8
	case OVAL_OPERATION_GREATER_THAN_OR_EQUAL:
Packit 517ee8
		return syschar >= state ? OVAL_RESULT_TRUE : OVAL_RESULT_FALSE;
Packit 517ee8
	case OVAL_OPERATION_LESS_THAN:
Packit 517ee8
		return syschar < state ? OVAL_RESULT_TRUE : OVAL_RESULT_FALSE;
Packit 517ee8
	case OVAL_OPERATION_LESS_THAN_OR_EQUAL:
Packit 517ee8
		return syschar <= state ? OVAL_RESULT_TRUE : OVAL_RESULT_FALSE;
Packit 517ee8
	case OVAL_OPERATION_BITWISE_AND:
Packit 517ee8
		return (syschar & state) == state ? OVAL_RESULT_TRUE : OVAL_RESULT_FALSE;
Packit 517ee8
	case OVAL_OPERATION_BITWISE_OR:
Packit 517ee8
		return (syschar | state) == state ? OVAL_RESULT_TRUE : OVAL_RESULT_FALSE;
Packit 517ee8
	default:
Packit 517ee8
		oscap_seterr(OSCAP_EFAMILY_OVAL, "Invalid type of operation in integer evaluation: %d.", operation);
Packit 517ee8
	}
Packit 517ee8
	return OVAL_RESULT_ERROR;
Packit 517ee8
}
Packit 517ee8
Packit 517ee8
static inline int cmp_float(double a, double b)
Packit 517ee8
{
Packit 517ee8
	double relative_err;
Packit 517ee8
	int r;
Packit 517ee8
Packit 517ee8
	if (a == b)
Packit 517ee8
		return 0;
Packit 517ee8
	r = (a > b) ? 1 : -1;
Packit 517ee8
	if (fabs(a) > fabs(b)) {
Packit 517ee8
		relative_err = fabs((a - b) / a);
Packit 517ee8
	} else {
Packit 517ee8
		relative_err = fabs((a - b) / b);
Packit 517ee8
	}
Packit 517ee8
	if (relative_err <= 0.000000001)
Packit 517ee8
		return 0;
Packit 517ee8
Packit 517ee8
	return r;
Packit 517ee8
}
Packit 517ee8
Packit 517ee8
oval_result_t oval_float_cmp(const double state_val, const double sys_val, oval_operation_t operation)
Packit 517ee8
{
Packit 517ee8
	if (operation == OVAL_OPERATION_EQUALS) {
Packit 517ee8
		return ((cmp_float(sys_val, state_val) == 0) ? OVAL_RESULT_TRUE : OVAL_RESULT_FALSE);
Packit 517ee8
	} else if (operation == OVAL_OPERATION_NOT_EQUAL) {
Packit 517ee8
		return ((cmp_float(sys_val, state_val) != 0) ? OVAL_RESULT_TRUE : OVAL_RESULT_FALSE);
Packit 517ee8
	} else if (operation == OVAL_OPERATION_GREATER_THAN) {
Packit 517ee8
		return ((cmp_float(sys_val, state_val) == 1) ? OVAL_RESULT_TRUE : OVAL_RESULT_FALSE);
Packit 517ee8
	} else if (operation == OVAL_OPERATION_GREATER_THAN_OR_EQUAL) {
Packit 517ee8
		return ((cmp_float(sys_val, state_val) >= 0) ? OVAL_RESULT_TRUE : OVAL_RESULT_FALSE);
Packit 517ee8
	} else if (operation == OVAL_OPERATION_LESS_THAN) {
Packit 517ee8
		return ((cmp_float(sys_val, state_val) == -1) ? OVAL_RESULT_TRUE : OVAL_RESULT_FALSE);
Packit 517ee8
	} else if (operation == OVAL_OPERATION_LESS_THAN_OR_EQUAL) {
Packit 517ee8
		return ((cmp_float(sys_val, state_val) <= 0) ? OVAL_RESULT_TRUE : OVAL_RESULT_FALSE);
Packit 517ee8
	} else {
Packit 517ee8
		oscap_seterr(OSCAP_EFAMILY_OVAL, "Invalid type of operation in float evaluation: %s.", oval_operation_get_text(operation));
Packit 517ee8
		return OVAL_RESULT_ERROR;
Packit 517ee8
	}
Packit 517ee8
}
Packit 517ee8
Packit 517ee8
static int istrcmp(const char *st1, const char *st2)
Packit 517ee8
{
Packit 517ee8
	if (st1 == NULL)
Packit 517ee8
		st1 = "";
Packit 517ee8
	if (st2 == NULL)
Packit 517ee8
		st2 = "";
Packit 517ee8
	return oscap_strcasecmp(st1, st2);
Packit 517ee8
}
Packit 517ee8
Packit 517ee8
static oval_result_t strregcomp(const char *pattern, const char *test_str)
Packit 517ee8
{
Packit 517ee8
	int ret;
Packit 517ee8
	oval_result_t result = OVAL_RESULT_ERROR;
Packit 517ee8
	pcre *re;
Packit 517ee8
	const char *err;
Packit 517ee8
	int errofs;
Packit 517ee8
Packit 517ee8
	re = pcre_compile(pattern, PCRE_UTF8, &err, &errofs, NULL);
Packit 517ee8
	if (re == NULL) {
Packit 517ee8
		dE("Unable to compile regex pattern '%s', "
Packit 517ee8
				"pcre_compile() returned error (offset: %d): '%s'.\n", pattern, errofs, err);
Packit 517ee8
		return OVAL_RESULT_ERROR;
Packit 517ee8
	}
Packit 517ee8
Packit 517ee8
	ret = pcre_exec(re, NULL, test_str, strlen(test_str), 0, 0, NULL, 0);
Packit 517ee8
	if (ret > -1 ) {
Packit 517ee8
		result = OVAL_RESULT_TRUE;
Packit 517ee8
	} else if (ret == -1) {
Packit 517ee8
		result = OVAL_RESULT_FALSE;
Packit 517ee8
	} else {
Packit 517ee8
		dE("Unable to match regex pattern '%s' on string '%s', "
Packit 517ee8
				"pcre_exec() returned error: %d.\n", pattern, test_str, ret);
Packit 517ee8
		result = OVAL_RESULT_ERROR;
Packit 517ee8
	}
Packit 517ee8
Packit 517ee8
	pcre_free(re);
Packit 517ee8
	return result;
Packit 517ee8
}
Packit 517ee8
Packit 517ee8
oval_result_t oval_string_cmp(const char *state, const char *syschar, oval_operation_t operation)
Packit 517ee8
{
Packit 517ee8
	syschar = syschar ? syschar : "";
Packit 517ee8
	switch (operation) {
Packit 517ee8
	case OVAL_OPERATION_EQUALS:
Packit 517ee8
		return oscap_strcmp(state, syschar) ? OVAL_RESULT_FALSE : OVAL_RESULT_TRUE;
Packit 517ee8
	case OVAL_OPERATION_CASE_INSENSITIVE_EQUALS:
Packit 517ee8
		return istrcmp(state, syschar) ? OVAL_RESULT_FALSE : OVAL_RESULT_TRUE;
Packit 517ee8
	case OVAL_OPERATION_NOT_EQUAL:
Packit 517ee8
		return oscap_strcmp(state, syschar) ? OVAL_RESULT_TRUE : OVAL_RESULT_FALSE;
Packit 517ee8
	case OVAL_OPERATION_CASE_INSENSITIVE_NOT_EQUAL:
Packit 517ee8
		return istrcmp(state, syschar) ? OVAL_RESULT_TRUE : OVAL_RESULT_FALSE;
Packit 517ee8
	case OVAL_OPERATION_PATTERN_MATCH:
Packit 517ee8
		return strregcomp(state, syschar);
Packit 517ee8
	default:
Packit 517ee8
		oscap_seterr(OSCAP_EFAMILY_OVAL, "Invalid type of operation in string evaluation: %d.", operation);
Packit 517ee8
	}
Packit 517ee8
	return OVAL_RESULT_ERROR;
Packit 517ee8
}
Packit 517ee8
Packit 517ee8
oval_result_t oval_binary_cmp(const char *state, const char *syschar, oval_operation_t operation)
Packit 517ee8
{
Packit 517ee8
	// I'm going to use case insensitive compare here - don't know if it's necessary
Packit 517ee8
	switch (operation) {
Packit 517ee8
	case OVAL_OPERATION_EQUALS:
Packit 517ee8
		return istrcmp(state, syschar) == 0 ? OVAL_RESULT_TRUE : OVAL_RESULT_FALSE;
Packit 517ee8
	case OVAL_OPERATION_NOT_EQUAL:
Packit 517ee8
		return istrcmp(state, syschar) != 0 ? OVAL_RESULT_TRUE : OVAL_RESULT_FALSE;
Packit 517ee8
	default:
Packit 517ee8
		oscap_seterr(OSCAP_EFAMILY_OVAL, "Invalid type of operation in binary evalu?ation: %d.", operation);
Packit 517ee8
	}
Packit 517ee8
	return OVAL_RESULT_ERROR;
Packit 517ee8
}