|
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 |
}
|