diff --git a/inc/Maat_rule.h b/inc/Maat_rule.h index 3a93a6e..a68e699 100644 --- a/inc/Maat_rule.h +++ b/inc/Maat_rule.h @@ -259,6 +259,12 @@ int Maat_rule_get_ex_new_index(Maat_feather_t feather, const char* compile_table //returned data is duplicated by dup_func of Maat_rule_get_ex_new_index, caller is responsible to free the data. MAAT_RULE_EX_DATA Maat_rule_get_ex_data(Maat_feather_t feather, const struct Maat_rule_t* rule, int idx); +//Sort rule by execute sequence. +//rule_array will be modified with sorted rule. +//Return sortted rule number, maybe less than n_rule if some rules are invalid. +size_t Maat_rule_sort_by_exec_seq(Maat_feather_t feather, struct Maat_rule_t* rule_array, size_t n_rule); + + //Helper function for parsing space or tab seperated line. //Nth_column: the Nth column is numberd from 1. //Return 0 if success. diff --git a/src/entry/Maat_api.cpp b/src/entry/Maat_api.cpp index 7f0a637..f638446 100644 --- a/src/entry/Maat_api.cpp +++ b/src/entry/Maat_api.cpp @@ -116,22 +116,94 @@ size_t pickup_hit_region_from_compile(struct bool_expr *compile_hit, void fill_maat_rule(struct Maat_rule_t *rule, const struct Maat_rule_head* rule_head, const char* srv_def, int srv_def_len) { memcpy(rule, rule_head, sizeof(struct Maat_rule_head)); - memcpy(rule->service_defined, srv_def, MIN(srv_def_len,MAX_SERVICE_DEFINE_LEN)); + memcpy(rule->service_defined, srv_def, MIN(srv_def_len, MAX_SERVICE_DEFINE_LEN)); return; } +struct compile_sort_para +{ + double exec_seq; + int group_cnt; + int compile_id; + void* user; +}; +static void compile_sort_para_set(struct compile_sort_para* para, const struct Maat_compile_group_relation* compile_relation, void* user) +{ + para->compile_id=compile_relation->compile_id; + para->exec_seq=compile_relation->compile->exec_seq; + para->group_cnt=compile_relation->group_cnt; + para->user=user; + return; +} +static int compile_sort_para_compare(const struct compile_sort_para* a, const struct compile_sort_para* b) +{ + //If both of compile rule's execute sequences are specified, compile rule with lower execute sequence is priority. + if(a->exec_seq!=0 && b->exec_seq!=0) + { + if(a->exec_seq - b->exec_seq <0) + { + return -1; + } + else if(a->exec_seq - b->exec_seq >0) + { + return 1; + } + } + //If compile rule's execute sequences are not specified or equal. + if(a->group_cnt!=b->group_cnt) + { + return (a->group_cnt-b->group_cnt); + } + else + { + return (b->compile_id-a->compile_id); + } + +} static int compare_compile_inner(const void *a, const void *b) { const struct Maat_compile_group_relation *ra=*(const struct Maat_compile_group_relation **)a; const struct Maat_compile_group_relation *rb=*(const struct Maat_compile_group_relation **)b; + + struct compile_sort_para sa, sb; + compile_sort_para_set(&sa, ra, NULL); + compile_sort_para_set(&sb, rb, NULL); - if(ra->group_cnt!=rb->group_cnt) + return compile_sort_para_compare(&sa, &sb); +} +static int compile_sort_para_compare_no_type(const void* a, const void* b) +{ + return compile_sort_para_compare((const struct compile_sort_para*) a, (const struct compile_sort_para*) b); + +} +size_t Maat_rule_sort_by_exec_seq(Maat_feather_t feather, struct Maat_rule_t* rule_array, size_t n_rule) +{ + struct _Maat_feather_t *_feather=(struct _Maat_feather_t *)feather; + struct compile_sort_para sort_para[n_rule]; + struct Maat_rule_t copy_rule_array[n_rule]; + + memcpy(copy_rule_array, rule_array, sizeof(struct Maat_rule_t)*n_rule); + + struct Maat_compile_group_relation *p=NULL; + + size_t i=0, j=0; + for(i=0; igroup_cnt-rb->group_cnt); + p=(struct Maat_compile_group_relation *)HASH_fetch_by_id(_feather->scanner->compile_hash, rule_array[i].config_id); + if(p && 0==pthread_rwlock_tryrdlock(&(p->rwlock)))//rule maybe already deleted. + { + compile_sort_para_set(sort_para+i, p, copy_rule_array+i); + j++; + pthread_rwlock_unlock(&(p->rwlock)); + } } - else + qsort(sort_para, j, sizeof(struct compile_sort_para), + compile_sort_para_compare_no_type); + for(i=0; icompile_id-ra->compile_id); + memcpy(rule_array+i, sort_para[i].user, sizeof(struct Maat_rule_t)); } + return j; + } struct scan_region_hit_wraper { @@ -221,7 +293,7 @@ int region_compile(_Maat_feather_t*feather, struct _INNER_scan_status_t *_mid, c } if(scan_ret>1) { - qsort(relation_array, scan_ret, sizeof(struct Maat_compile_group_relation**), + qsort(relation_array, scan_ret, sizeof(struct Maat_compile_group_relation*), compare_compile_inner); } for(i=0; i<(unsigned int)scan_ret&&result_cnthead.serv_def_len=strlen(service_define)+1; p->service_defined=ALLOC(char, p->head.serv_def_len); memcpy(p->service_defined, service_define, p->head.serv_def_len); + p->exec_seq=exec_seq; for(i=0; icompile.ex_data_num; i++) { @@ -2833,7 +2834,8 @@ void update_compile_rule(struct Maat_table_desc* table,const char* table_line ,s char tag_str[MAX_TABLE_LINE_SIZE]={0}; int ret=0; int is_valid=0, declared_grp_num=0; - ret=sscanf(table_line,"%d\t%d\t%hhd\t%hhd\t%hhd\t%s\t%s\t%d\t%d",&(m_rule_tmp.config_id), + double exec_seq=0.0; + ret=sscanf(table_line,"%d\t%d\t%hhd\t%hhd\t%hhd\t%s\t%s\t%d\t%d\t%lf",&(m_rule_tmp.config_id), &(m_rule_tmp.service_id), &(m_rule_tmp.action), &(m_rule_tmp.do_blacklist), @@ -2841,8 +2843,9 @@ void update_compile_rule(struct Maat_table_desc* table,const char* table_line ,s tag_str, service_define, &is_valid, - &declared_grp_num); - if((ret!=8&&ret!=9)||declared_grp_num>MAAT_MAX_EXPR_ITEM_NUM) + &declared_grp_num, + &exec_seq); + if((ret!=8&&ret!=9&&ret!=10)||declared_grp_num>MAAT_MAX_EXPR_ITEM_NUM) { MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module , "update error, invalid format of compile table %s:%s" @@ -2885,7 +2888,7 @@ void update_compile_rule(struct Maat_table_desc* table,const char* table_line ,s } else { - p_compile=create_compile_rule(&m_rule_tmp, service_define, declared_grp_num, table); + p_compile=create_compile_rule(&m_rule_tmp, service_define, declared_grp_num, exec_seq, table); ret=add_compile_rule(table, p_compile, scanner, logger); if(ret<0) { diff --git a/src/entry/json2iris.cpp b/src/entry/json2iris.cpp index 31943f3..ed71dbc 100644 --- a/src/entry/json2iris.cpp +++ b/src/entry/json2iris.cpp @@ -796,7 +796,10 @@ int write_compile_line(cJSON *compile, struct iris_description_t *p_iris, void * int compile_id=-1,cmd_cnt=0,ret=-1; cJSON* item=NULL; struct iris_table_t* table_info=NULL; - + cJSON* g_rules=cJSON_GetObjectItem(compile, "groups"); + int group_cnt=cJSON_GetArraySize(g_rules); + cJSON_AddNumberToObject(compile, "group_num", group_cnt); + struct traslate_command_t compile_cmd[MAX_COLUMN_NUM]; memset(compile_cmd,0,sizeof(compile_cmd)); @@ -836,6 +839,17 @@ int write_compile_line(cJSON *compile, struct iris_description_t *p_iris, void * compile_cmd[cmd_cnt].json_type=cJSON_String; compile_cmd[cmd_cnt].str2int_flag=1; cmd_cnt++; + + compile_cmd[cmd_cnt].json_string="group_num"; + compile_cmd[cmd_cnt].json_type=cJSON_Number; + cmd_cnt++; + + compile_cmd[cmd_cnt].json_string="exec_seq"; + compile_cmd[cmd_cnt].json_type=cJSON_String; + compile_cmd[cmd_cnt].empty_allowed=1; + compile_cmd[cmd_cnt].default_string="0.0"; + cmd_cnt++; + item=cJSON_GetObjectItem(compile,"table_name"); if(item==NULL||item->type!=cJSON_String) @@ -847,7 +861,7 @@ int write_compile_line(cJSON *compile, struct iris_description_t *p_iris, void * table_info=query_table_info(p_iris, item->valuestring, TABLE_TYPE_COMPILE); } - ret=direct_write_rule(compile, p_iris->str2int_map,compile_cmd,cmd_cnt, table_info, logger); + ret=direct_write_rule(compile, p_iris->str2int_map, compile_cmd, cmd_cnt, table_info, logger); if(ret<0) { return -1; diff --git a/src/inc_internal/Maat_rule_internal.h b/src/inc_internal/Maat_rule_internal.h index 3aed79e..325daa2 100644 --- a/src/inc_internal/Maat_rule_internal.h +++ b/src/inc_internal/Maat_rule_internal.h @@ -93,6 +93,7 @@ struct Maat_compile_rule char* service_defined; int is_valid; int declared_grp_num; + double exec_seq; const struct Maat_table_desc* ref_table; MAAT_RULE_EX_DATA* ads; }; diff --git a/test/maat_json.json b/test/maat_json.json index 1c690f9..f28a2d2 100644 --- a/test/maat_json.json +++ b/test/maat_json.json @@ -1301,6 +1301,102 @@ ] } ] + }, + { + "compile_id": 165, + "service": 1, + "action": 1, + "do_blacklist": 1, + "do_log": 1, + "user_region": "ExecuteSequence", + "is_valid": "yes", + "exec_seq":"2.111", + "groups": [ + { + "group_name": "Untitled", + "regions": [ + { + "table_name": "HTTP_URL", + "table_type": "string", + "table_content": { + "keywords": "cavemancircus.com/", + "expr_type": "none", + "match_method": "sub", + "format": "uncase plain" + } + } + ] + }, + { + "regions": [ + { + "table_type": "ip_plus", + "table_name": "IP_PLUS_CONFIG", + "table_content": { + "addr_type": "ipv4", + "saddr_format": "CIDR", + "src_ip1": "192.168.23.1", + "src_ip2": "24" + } + } + ], + "not_flag" : 0 + } + ] + }, + { + "compile_id": 166, + "service": 1, + "action": 1, + "do_blacklist": 1, + "do_log": 1, + "user_region": "ExecuteSequence", + "is_valid": "yes", + "exec_seq":"100.233", + "groups": [ + { + "group_name": "Untitled", + "regions": [ + { + "table_name": "HTTP_URL", + "table_type": "string", + "table_content": { + "keywords": "2019/12/27/pretty-girls-6", + "expr_type": "none", + "match_method": "sub", + "format": "uncase plain" + } + } + ] + } + ] + }, + { + "compile_id": 167, + "service": 1, + "action": 1, + "do_blacklist": 1, + "do_log": 1, + "user_region": "ExecuteSequence", + "is_valid": "yes", + "exec_seq":"300.999", + "groups": [ + { + "group_name": "Untitled", + "regions": [ + { + "table_name": "HTTP_URL", + "table_type": "string", + "table_content": { + "keywords": "2019/12/27", + "expr_type": "none", + "match_method": "sub", + "format": "uncase plain" + } + } + ] + } + ] } ], "plugin_table": [ diff --git a/test/test_maatframe.cpp b/test/test_maatframe.cpp index b027377..6a4561f 100644 --- a/test/test_maatframe.cpp +++ b/test/test_maatframe.cpp @@ -1349,7 +1349,7 @@ TEST(Policy, CompileEXData) const char* url="i.ytimg.com/vi/OtCNcustg_I/hqdefault.jpg?sqp=-oaymwEZCNACELwBSFXyq4qpAwsIARUAAIhCGAFwAQ==&rs=AOn4CLDOp_5fHMaCA9XZuJdCRv4DNDorMg"; const char* table_name="HTTP_URL"; const char* expect_name="I have a name"; - table_id=Maat_table_register(g_feather,table_name); + table_id=Maat_table_register(g_feather, table_name); ASSERT_GT(table_id, 0); int ex_param_idx=Maat_rule_get_ex_new_index(g_feather, "COMPILE_ALIAS", @@ -1409,6 +1409,52 @@ TEST(Policy, SubGroup) return; } +TEST(Policy, ExecuteSequence) +{ +#define TestExecuteSequence + int ret=0, table_id=0; + size_t i=0; + const char* url="cavemancircus.com/2019/12/27/pretty-girls-6/"; + struct Maat_rule_t result[4]; + memset(result, 0, sizeof(result)); + scan_status_t mid=NULL; + + table_id=Maat_table_register(g_feather, "HTTP_URL"); + ASSERT_GT(table_id, 0); + + ret=Maat_full_scan_string(g_feather, table_id, CHARSET_GBK, url, strlen(url), + result+i, NULL, 4-i, + &mid, 0); + EXPECT_EQ(ret, 2); + EXPECT_EQ(result[i].config_id, 166); + i+=ret; + + struct ipaddr ipv4_addr; + struct stream_tuple4_v4 v4_addr; + ipv4_addr.addrtype=ADDR_TYPE_IPV4; + inet_pton(AF_INET,"192.168.23.23",&(v4_addr.saddr)); + v4_addr.source=htons(50001); + inet_pton(AF_INET,"172.0.6.233",&(v4_addr.daddr)); + v4_addr.dest=htons(80); + ipv4_addr.v4=&v4_addr; + + table_id=Maat_table_register(g_feather, "IP_PLUS_CONFIG"); + ASSERT_GT(table_id, 0); + + ret=Maat_scan_proto_addr(g_feather, table_id, &ipv4_addr, 6, result+i, 4-i, &mid,0); + + EXPECT_EQ(ret, 1); + EXPECT_EQ(result[i].config_id, 165); + i+=ret; + + ret=Maat_rule_sort_by_exec_seq(g_feather, result, i); + EXPECT_EQ(ret, i); + EXPECT_EQ(result[0].config_id, 165); + EXPECT_EQ(result[1].config_id, 166); + EXPECT_EQ(result[2].config_id, 167); + Maat_clean_status(&mid); + +} TEST(StreamFuzzyHash, Pure) { @@ -2797,7 +2843,7 @@ int main(int argc, char ** argv) g_feather=Maat_feather(g_iThreadNum, table_info_path, g_logger); Maat_set_feather_opt(g_feather, MAAT_OPT_INSTANCE_NAME, "demo", strlen("demo")+1); - Maat_set_feather_opt(g_feather, MAAT_OPT_DECRYPT_KEY, decrypt_key, strlen(decrypt_key)+1); +// Maat_set_feather_opt(g_feather, MAAT_OPT_DECRYPT_KEY, decrypt_key, strlen(decrypt_key)+1); ret=Maat_set_feather_opt(g_feather, MAAT_OPT_JSON_FILE_PATH, json_path, strlen(json_path)+1); assert(ret==0); Maat_set_feather_opt(g_feather, MAAT_OPT_SCANDIR_INTERVAL_MS, &scan_interval_ms, sizeof(scan_interval_ms));