summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorroot <[email protected]>2024-10-12 07:28:26 +0000
committerroot <[email protected]>2024-10-12 07:28:26 +0000
commit586f1c11b20524066a3b4025cd4a59a14565ad32 (patch)
treec1c650c1398cfefefe71df96ee0138fb99f1e2bd /src
parent02a2acf051d10440bb1e6628a1b646cab9c0bf9e (diff)
1.support and_conditions and or_conditions in rule
2.all test case success except MaatCmd.* in maat_framework_gtest
Diffstat (limited to 'src')
-rw-r--r--src/maat_config_monitor.c145
-rw-r--r--src/maat_rule.c203
2 files changed, 200 insertions, 148 deletions
diff --git a/src/maat_config_monitor.c b/src/maat_config_monitor.c
index 27831af..0ebc24e 100644
--- a/src/maat_config_monitor.c
+++ b/src/maat_config_monitor.c
@@ -214,6 +214,72 @@ static void object_info_free(struct object_info *object_name_map)
}
}
+static void convert_condition(struct object_info *object_name_map, cJSON *condition, cJSON *top_items, int *object_gen_id, int *item_gen_id)
+{
+ cJSON *object_uuid_array = cJSON_CreateArray();
+ cJSON *object_name = cJSON_GetObjectItem(condition, "object_name");
+ cJSON *object_uuid = cJSON_GetObjectItem(condition, "object_uuid");
+
+ if (object_name && object_uuid) {
+ object_info_add(object_name_map, object_name->valuestring, object_uuid->valuestring);
+ }
+
+ if (object_uuid) {
+ cJSON_AddItemToArray(object_uuid_array, cJSON_CreateString(object_uuid->valuestring));
+ } else if (object_name) {
+ struct object_info *object_info = object_info_find(object_name_map, object_name->valuestring);
+ if (object_info) {
+ cJSON_AddItemToArray(object_uuid_array, cJSON_CreateString(object_info->object_uuid));
+ }
+ }
+
+ cJSON *object_array = cJSON_GetObjectItem(condition, "objects");
+ cJSON *tmp_object = NULL;
+ cJSON_ArrayForEach(tmp_object, object_array) {//convert objects in condition
+ //find items, generate item_id and object_id
+ cJSON *object_id_obj = cJSON_GetObjectItem(tmp_object, "uuid");
+ cJSON *object_name_obj = cJSON_GetObjectItem(tmp_object, "object_name");
+ cJSON *items = cJSON_GetObjectItem(tmp_object, "items");
+ cJSON *item = NULL;
+ char obj_uuid_str[UUID_STR_LEN];
+ memset(obj_uuid_str, 0, sizeof(obj_uuid_str));
+ if (object_id_obj != NULL) {
+ snprintf(obj_uuid_str, sizeof(obj_uuid_str), "%s", object_id_obj->valuestring);
+ } else {
+ snprintf(obj_uuid_str, sizeof(obj_uuid_str), "00000000-0000-0000-0000-00000000%d", (*object_gen_id)++);
+ }
+
+ if (object_name_obj) {
+ object_info_add(object_name_map, object_name_obj->valuestring, obj_uuid_str);
+ }
+
+ cJSON_ArrayForEach(item, items) {
+ cJSON *table_name = cJSON_GetObjectItem(item, "table_name");
+ cJSON *tmp_item = cJSON_CreateObject();
+ cJSON_AddItemToObject(tmp_item, "table_name", cJSON_CreateString(table_name->valuestring));
+
+ cJSON *dup = cJSON_Duplicate(cJSON_GetObjectItem(item, "table_content"), 1);
+
+ if (cJSON_GetObjectItem(dup, "uuid") == NULL) {
+ char uuid_str[UUID_STR_LEN];
+ snprintf(uuid_str, sizeof(uuid_str), "00000000-0000-0000-0000-00000000%d", (*item_gen_id)++);
+ cJSON_AddStringToObject(dup, "uuid", uuid_str);
+ }
+ cJSON_AddStringToObject(dup, "object_uuid", obj_uuid_str);
+
+ cJSON_AddItemToObject(tmp_item, "table_content", dup);
+ cJSON_AddItemToArray(top_items, tmp_item);
+ }
+
+ cJSON_AddItemToArray(object_uuid_array, cJSON_CreateString(obj_uuid_str));
+ }
+ //replace object content with object_id
+ cJSON_DeleteItemFromObject(condition, "objects");
+ cJSON_AddItemToObject(condition, "object_uuids", object_uuid_array);
+
+ return;
+}
+
void convert_maat_json_rule(cJSON **json_root, unsigned char *json_buff)
{
*json_root = cJSON_Parse((const char *)json_buff);
@@ -307,74 +373,29 @@ void convert_maat_json_rule(cJSON **json_root, unsigned char *json_buff)
*/
cJSON *tmp_rule = NULL;
cJSON_ArrayForEach(tmp_rule, rules) {
- cJSON *tmp_condition = NULL;
- cJSON *condition_array = cJSON_GetObjectItem(tmp_rule, "conditions");
- cJSON_ArrayForEach(tmp_condition, condition_array) {
- cJSON *tmp_object = NULL;
- cJSON *object_uuid_array = cJSON_CreateArray();
+ cJSON *tmp_and_condition = NULL;
+ cJSON *condition_array = cJSON_GetObjectItem(tmp_rule, "and_conditions");
+ cJSON_ArrayForEach(tmp_and_condition, condition_array) {
- cJSON *negate_option = cJSON_GetObjectItem(tmp_condition, "negate_option");
+ cJSON *negate_option = cJSON_GetObjectItem(tmp_and_condition, "negate_option");
if (negate_option == NULL) {
- cJSON_AddBoolToObject(tmp_condition, "negate_option", 0);
- }
-
- cJSON *object_name = cJSON_GetObjectItem(tmp_condition, "object_name");
- cJSON *object_uuid = cJSON_GetObjectItem(tmp_condition, "object_uuid");
- if (object_name && object_uuid) {
- object_info_add(object_name_map, object_name->valuestring, object_uuid->valuestring);
- }
-
- if (object_uuid) {
- cJSON_AddItemToArray(object_uuid_array, cJSON_CreateString(object_uuid->valuestring));
- } else if (object_name) {
- struct object_info *object_info = object_info_find(object_name_map, object_name->valuestring);
- if (object_info) {
- cJSON_AddItemToArray(object_uuid_array, cJSON_CreateString(object_info->object_uuid));
- }
+ cJSON_AddBoolToObject(tmp_and_condition, "negate_option", 0);
}
-
- cJSON *object_array = cJSON_GetObjectItem(tmp_condition, "objects");
- cJSON_ArrayForEach(tmp_object, object_array) {//convert objects in rule
- //find items, generate item_id and object_id
- cJSON *object_id_obj = cJSON_GetObjectItem(tmp_object, "uuid");
- cJSON *object_name_obj = cJSON_GetObjectItem(tmp_object, "object_name");
- cJSON *items = cJSON_GetObjectItem(tmp_object, "items");
- cJSON *item = NULL;
- char obj_uuid_str[UUID_STR_LEN];
- memset(obj_uuid_str, 0, sizeof(obj_uuid_str));
- if (object_id_obj != NULL) {
- snprintf(obj_uuid_str, sizeof(obj_uuid_str), "%s", object_id_obj->valuestring);
- } else {
- snprintf(obj_uuid_str, sizeof(obj_uuid_str), "00000000-0000-0000-0000-00000000%d", object_gen_id++);
- }
- if (object_name_obj) {
- object_info_add(object_name_map, object_name_obj->valuestring, obj_uuid_str);
+ cJSON *or_conditions = cJSON_GetObjectItem(tmp_and_condition, "or_conditions");
+ if (or_conditions) {
+ cJSON *tmp_or_condition = NULL;
+ cJSON_ArrayForEach(tmp_or_condition, or_conditions) {
+ convert_condition(object_name_map, tmp_or_condition, top_items, &object_gen_id, &item_gen_id);
}
-
- cJSON_ArrayForEach(item, items) {
- cJSON *table_name = cJSON_GetObjectItem(item, "table_name");
- cJSON *tmp_item = cJSON_CreateObject();
- cJSON_AddItemToObject(tmp_item, "table_name", cJSON_CreateString(table_name->valuestring));
-
- cJSON *dup = cJSON_Duplicate(cJSON_GetObjectItem(item, "table_content"), 1);
-
- if (cJSON_GetObjectItem(dup, "uuid") == NULL) {
- char uuid_str[UUID_STR_LEN];
- snprintf(uuid_str, sizeof(uuid_str), "00000000-0000-0000-0000-00000000%d", item_gen_id++);
- cJSON_AddStringToObject(dup, "uuid", uuid_str);
- }
- cJSON_AddStringToObject(dup, "object_uuid", obj_uuid_str);
-
- cJSON_AddItemToObject(tmp_item, "table_content", dup);
- cJSON_AddItemToArray(top_items, tmp_item);
- }
-
- cJSON_AddItemToArray(object_uuid_array, cJSON_CreateString(obj_uuid_str));
+ } else {
+ cJSON *tmp_or_condition = cJSON_Duplicate(tmp_and_condition, 1);
+ convert_condition(object_name_map, tmp_or_condition, top_items, &object_gen_id, &item_gen_id);
+
+ or_conditions = cJSON_CreateArray();
+ cJSON_AddItemToArray(or_conditions, tmp_or_condition);
+ cJSON_AddItemToObject(tmp_and_condition, "or_conditions", or_conditions);
}
- //replace object content with object_id
- cJSON_DeleteItemFromObject(tmp_condition, "objects");
- cJSON_AddItemToObject(tmp_condition, "object_uuids", object_uuid_array);
}
}
diff --git a/src/maat_rule.c b/src/maat_rule.c
index 92d6597..1108b1e 100644
--- a/src/maat_rule.c
+++ b/src/maat_rule.c
@@ -99,9 +99,7 @@ struct condition_literal {
struct rule_condition {
long long condition_id;
- uuid_t object_uuids[MAX_OBJECT_CNT];
- int object_cnt;
- char attribute_name[MAX_ATTR_NAME_LEN];
+ UT_array *literals;
char negate_option; // 1 byte
char in_use; // 1 byte
char pad[6]; // for 8 bytes alignment
@@ -153,6 +151,7 @@ struct rule_compile_state {
};
UT_icd ut_condition_id_icd = {sizeof(long long), NULL, NULL, NULL};
+UT_icd ut_condition_literal_icd = {sizeof(struct condition_literal), NULL, NULL, NULL};
UT_icd ut_rule_object_uuid_icd = {sizeof(uuid_t), NULL, NULL, NULL};
UT_icd ut_maat_hit_object_icd = {sizeof(struct maat_hit_object), NULL, NULL, NULL};
UT_icd ut_hit_path_icd = {sizeof(struct internal_hit_path), NULL, NULL, NULL};
@@ -181,6 +180,11 @@ static void maat_rule_free(struct maat_rule *rule)
for (int i = 0; i < MAX_ITEMS_PER_BOOL_EXPR; i++) {
condition = rule->conditions + i;
+ if (condition->literals != NULL) {
+ utarray_free(condition->literals);
+ condition->literals = NULL;
+ }
+
condition->in_use = 0;
condition->condition_id = 0;
}
@@ -231,7 +235,7 @@ static struct maat_rule *maat_rule_new(struct rule_runtime *rule_rt, struct rule
struct maat_rule *rule = ALLOC(struct maat_rule, 1);
struct log_handle *logger = rule_rt->logger;
cJSON *tmp_obj = NULL;
- cJSON *conditions = NULL;
+ cJSON *conditions_obj = NULL;
cJSON *table_json = cJSON_Parse(table_line);
int table_id = table_manager_get_table_id(schema->ref_tbl_mgr, table_name);
@@ -247,19 +251,20 @@ static struct maat_rule *maat_rule_new(struct rule_runtime *rule_rt, struct rule
uuid_copy(rule->rule_uuid, rule_uuid);
for(int i = 0; i < MAX_ITEMS_PER_BOOL_EXPR; i++) {
+ utarray_new(rule->conditions[i].literals, &ut_condition_literal_icd);
rule->conditions[i].in_use = 0;
rule->conditions[i].condition_id = 0;
}
- conditions = cJSON_GetObjectItem(table_json, "conditions");
- if (conditions == NULL || conditions->type != cJSON_Array) {
+ conditions_obj = cJSON_GetObjectItem(table_json, "and_conditions");
+ if (conditions_obj == NULL || conditions_obj->type != cJSON_Array) {
log_fatal(logger, MODULE_RULE,
- "[%s:%d] table: <%s> has no conditions or not array format",
+ "[%s:%d] table: <%s> has no and_conditions or not array format",
__FUNCTION__, __LINE__, table_name);
goto error;
}
- rule->condition_num = cJSON_GetArraySize(conditions);
+ rule->condition_num = cJSON_GetArraySize(conditions_obj);
if (rule->condition_num > MAX_ITEMS_PER_BOOL_EXPR) {
log_fatal(logger, MODULE_RULE,
"[%s:%d] table: <%s> condition_num:%d exceed maximum:%d",
@@ -268,25 +273,9 @@ static struct maat_rule *maat_rule_new(struct rule_runtime *rule_rt, struct rule
}
for (int i = 0; i < rule->condition_num; i++) {
- cJSON *condition_obj = cJSON_GetArrayItem(conditions, i);
+ cJSON *condition_obj = cJSON_GetArrayItem(conditions_obj, i);
struct rule_condition *condition = rule->conditions + i;
- tmp_obj = cJSON_GetObjectItem(condition_obj, "attribute_name");
- if (tmp_obj == NULL || tmp_obj->type != cJSON_String) {
- log_fatal(rule_rt->logger, MODULE_RULE,
- "[%s:%d] table: <%s> has no attribute_name or not string format",
- __FUNCTION__, __LINE__, table_name);
- goto error;
- }
-
- if (strlen(tmp_obj->valuestring) >= sizeof(condition->attribute_name)) {
- log_fatal(logger, MODULE_RULE,
- "[%s:%d] table: <%s> attribute_name:%s length exceed maximum:%d",
- __FUNCTION__, __LINE__, table_name, tmp_obj->valuestring, sizeof(condition->attribute_name));
- goto error;
- }
- snprintf(condition->attribute_name, sizeof(condition->attribute_name), "%s", tmp_obj->valuestring);
-
tmp_obj = cJSON_GetObjectItem(condition_obj, "negate_option");
if (tmp_obj) {
if (tmp_obj->type == cJSON_True) {
@@ -299,30 +288,55 @@ static struct maat_rule *maat_rule_new(struct rule_runtime *rule_rt, struct rule
__FUNCTION__, __LINE__, table_name, tmp_obj->valuestring);
goto error;
}
- }
+ }
- if (condition->negate_option == CONDITION_NEGATE_OPTION_SET) {
- int ret = validate_table_not_condition(rule_rt, schema->ref_tbl_mgr, condition->attribute_name, MAAT_OP_ADD, logger);
- if (ret < 0) {
+ cJSON *or_conditions_obj = cJSON_GetObjectItem(condition_obj, "or_conditions");
+ cJSON *literal_obj = NULL;
+ cJSON_ArrayForEach(literal_obj, or_conditions_obj) {
+ struct condition_literal tmp_literal;
+ memset(&tmp_literal, 0, sizeof(tmp_literal));
+
+ tmp_obj = cJSON_GetObjectItem(literal_obj, "attribute_name");
+ if (tmp_obj == NULL || tmp_obj->type != cJSON_String) {
+ log_fatal(rule_rt->logger, MODULE_RULE,
+ "[%s:%d] table: <%s> has no attribute_name or not string format",
+ __FUNCTION__, __LINE__, table_name);
+ goto error;
+ }
+
+ if (strlen(tmp_obj->valuestring) >= sizeof(tmp_literal.attribute_name)) {
log_fatal(logger, MODULE_RULE,
- "[%s:%d] table: <%s> validate negate_option failed, line: %s",
- __FUNCTION__, __LINE__, table_name, table_line);
+ "[%s:%d] table: <%s> attribute_name:%s length exceed maximum:%d",
+ __FUNCTION__, __LINE__, table_name, tmp_obj->valuestring, sizeof(tmp_literal.attribute_name));
goto error;
}
- }
+ snprintf(tmp_literal.attribute_name, sizeof(tmp_literal.attribute_name), "%s", tmp_obj->valuestring);
+
+ if (condition->negate_option == CONDITION_NEGATE_OPTION_SET) {
+ int ret = validate_table_not_condition(rule_rt, schema->ref_tbl_mgr, tmp_literal.attribute_name, MAAT_OP_ADD, logger);
+ if (ret < 0) {
+ log_fatal(logger, MODULE_RULE,
+ "[%s:%d] table: <%s> validate negate_option failed, line: %s",
+ __FUNCTION__, __LINE__, table_name, table_line);
+ goto error;
+ }
+ }
- tmp_obj = cJSON_GetObjectItem(condition_obj, "object_uuids");
- if (tmp_obj && tmp_obj->type == cJSON_Array) {
- int n_object_ids = cJSON_GetArraySize(tmp_obj);
+ tmp_obj = cJSON_GetObjectItem(literal_obj, "object_uuids");
+ if (tmp_obj && tmp_obj->type == cJSON_Array) {
+ int n_object_ids = cJSON_GetArraySize(tmp_obj);
- condition->object_cnt = n_object_ids;
+ tmp_literal.object_cnt = n_object_ids;
- for (int j = 0; j < n_object_ids; j++) {
- cJSON *object_id_obj = cJSON_GetArrayItem(tmp_obj, j);
- if (object_id_obj && object_id_obj->type == cJSON_String) {
- uuid_parse(object_id_obj->valuestring, condition->object_uuids[j]);
+ for (int j = 0; j < n_object_ids; j++) {
+ cJSON *object_id_obj = cJSON_GetArrayItem(tmp_obj, j);
+ if (object_id_obj && object_id_obj->type == cJSON_String) {
+ uuid_parse(object_id_obj->valuestring, tmp_literal.object_uuids[j]);
+ }
}
}
+
+ utarray_push_back(condition->literals, &tmp_literal);
}
condition->in_use = 1;
@@ -676,32 +690,37 @@ build_condition_id_kv_hash(struct rule_runtime *rule_rt, int negate_option)
}
}
- for (size_t k = 0; k < condition->object_cnt; k++) {
- struct condition_query_key key;
- struct condition_id_kv *condition_id_kv = NULL;
-
- memset(&key, 0, sizeof(key));
-
- memcpy(key.attribute_name, condition->attribute_name, sizeof(key.attribute_name));
- key.negate_option = condition->negate_option;
- uuid_copy(key.object_uuid, condition->object_uuids[k]);
-
- HASH_FIND(hh, condition_id_kv_hash, &key, sizeof(struct condition_query_key),
- condition_id_kv);
- if (NULL == condition_id_kv) {
- condition_id_kv = ALLOC(struct condition_id_kv, 1);
- condition_id_kv->key = key;
- utarray_new(condition_id_kv->condition_ids, &ut_condition_id_icd);
- HASH_ADD_KEYPTR(hh, condition_id_kv_hash, &condition_id_kv->key,
- sizeof(condition_id_kv->key), condition_id_kv);
- }
-
- if (utarray_find(condition_id_kv->condition_ids, &(condition->condition_id),
- compare_condition_id)) {
- continue;
+ struct condition_literal *tmp_literal = NULL;
+ for (size_t j = 0; j < utarray_len(condition->literals); j++) {
+ tmp_literal = (struct condition_literal *)utarray_eltptr(condition->literals, j);
+
+ for (size_t k = 0; k < tmp_literal->object_cnt; k++) {
+ struct condition_query_key key;
+ struct condition_id_kv *condition_id_kv = NULL;
+
+ memset(&key, 0, sizeof(key));
+
+ memcpy(key.attribute_name, tmp_literal->attribute_name, sizeof(key.attribute_name));
+ key.negate_option = condition->negate_option;
+ uuid_copy(key.object_uuid, tmp_literal->object_uuids[k]);
+
+ HASH_FIND(hh, condition_id_kv_hash, &key, sizeof(struct condition_query_key),
+ condition_id_kv);
+ if (NULL == condition_id_kv) {
+ condition_id_kv = ALLOC(struct condition_id_kv, 1);
+ condition_id_kv->key = key;
+ utarray_new(condition_id_kv->condition_ids, &ut_condition_id_icd);
+ HASH_ADD_KEYPTR(hh, condition_id_kv_hash, &condition_id_kv->key,
+ sizeof(condition_id_kv->key), condition_id_kv);
+ }
+
+ if (utarray_find(condition_id_kv->condition_ids, &(condition->condition_id),
+ compare_condition_id)) {
+ continue;
+ }
+ utarray_push_back(condition_id_kv->condition_ids, &(condition->condition_id));
+ utarray_sort(condition_id_kv->condition_ids, compare_condition_id);
}
- utarray_push_back(condition_id_kv->condition_ids, &(condition->condition_id));
- utarray_sort(condition_id_kv->condition_ids, compare_condition_id);
}
}
}
@@ -1001,20 +1020,24 @@ static int maat_rule_has_condition_query_key(struct maat_rule *rule,
continue;
}
+ struct condition_literal *tmp_literal = NULL;
+ for (size_t j = 0; j < utarray_len(condition->literals); j++) {
+ tmp_literal = (struct condition_literal *)utarray_eltptr(condition->literals, j);
- if (strncmp(condition->attribute_name, key->attribute_name, sizeof(key->attribute_name)) != 0) {
- continue;
- }
+ if (strncmp(tmp_literal->attribute_name, key->attribute_name, sizeof(key->attribute_name)) != 0) {
+ continue;
+ }
- if (condition->negate_option != key->negate_option) {
- continue;
- }
+ if (condition->negate_option != key->negate_option) {
+ continue;
+ }
- uuid_t *tmp_object_uuid = bsearch(&(key->object_uuid), condition->object_uuids,
- condition->object_cnt, sizeof(uuid_t),
- compare_object_uuid);
- if (tmp_object_uuid != NULL) {
- return 1;
+ uuid_t *tmp_object_uuid = bsearch(&(key->object_uuid), tmp_literal->object_uuids,
+ tmp_literal->object_cnt, sizeof(uuid_t),
+ compare_object_uuid);
+ if (tmp_object_uuid != NULL) {
+ return 1;
+ }
}
}
@@ -1035,16 +1058,21 @@ maat_rule_get_hit_condition_index(struct maat_rule *rule,
continue;
}
+ struct condition_literal *tmp_literal = NULL;
+ for (size_t j = 0; j < utarray_len(tmp_condition->literals); j++) {
+ tmp_literal = (struct condition_literal *)utarray_eltptr(tmp_condition->literals, j);
+
+ if (strncmp(tmp_literal->attribute_name, attribute_name, sizeof(tmp_literal->attribute_name)) != 0) {
+ continue;
+ }
- if (strncmp(tmp_condition->attribute_name, attribute_name, sizeof(tmp_condition->attribute_name)) != 0) {
- continue;
- }
-
- uuid_t *tmp_object_uuid = bsearch(hit_object_uuid, tmp_condition->object_uuids,
- tmp_condition->object_cnt, sizeof(uuid_t),
- compare_object_uuid);
- if (tmp_object_uuid != NULL) {
- condition_idx_array[hit_condition_cnt++] = i;
+ uuid_t *tmp_object_uuid = bsearch(hit_object_uuid, tmp_literal->object_uuids,
+ tmp_literal->object_cnt, sizeof(uuid_t),
+ compare_object_uuid);
+ if (tmp_object_uuid != NULL) {
+ condition_idx_array[hit_condition_cnt++] = i;
+ break;
+ }
}
}
@@ -1457,7 +1485,10 @@ static void rule_runtime_del_rule(struct rule_runtime *rule_rt,
for (int i = 0; i < rule->condition_num; i++) {
struct rule_condition *condition = rule->conditions + i;
if (condition->in_use && condition->negate_option == CONDITION_NEGATE_OPTION_SET) {
- validate_table_not_condition(rule_rt, schema->ref_tbl_mgr, condition->attribute_name, MAAT_OP_DEL, logger);
+ for (size_t j = 0; j < utarray_len(condition->literals); j++) {
+ struct condition_literal *literal = (struct condition_literal *)utarray_eltptr(condition->literals, j);
+ validate_table_not_condition(rule_rt, schema->ref_tbl_mgr, literal->attribute_name, MAAT_OP_DEL, logger);
+ }
}
}