summaryrefslogtreecommitdiff
path: root/src/tsg_rule.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tsg_rule.cpp')
-rw-r--r--src/tsg_rule.cpp449
1 files changed, 377 insertions, 72 deletions
diff --git a/src/tsg_rule.cpp b/src/tsg_rule.cpp
index 821e078..0ecf975 100644
--- a/src/tsg_rule.cpp
+++ b/src/tsg_rule.cpp
@@ -37,7 +37,8 @@ const struct _str2index method2index[TSG_METHOD_TYPE_MAX]={ {TSG_METHOD_TYPE_UNK
{TSG_METHOD_TYPE_REDIRECTION, 8, (char *)"redirect"},
{TSG_METHOD_TYPE_BLOCK, 5, (char *)"block"},
{TSG_METHOD_TYPE_RESET, 3, (char *)"rst"},
- {TSG_METHOD_TYPE_ALERT, 5, (char *)"alert"}
+ {TSG_METHOD_TYPE_ALERT, 5, (char *)"alert"},
+ {TSG_METHOD_TYPE_ALERT, 10, (char *)"rate_limit"}
};
static char* str_unescape(char* s)
@@ -556,76 +557,171 @@ void app_id_dict_free_data(int table_id, MAAT_PLUGIN_EX_DATA* ad, long argl, voi
return;
}
-void security_compile_new(int idx, const struct Maat_rule_t* rule, const char* srv_def_large, MAAT_RULE_EX_DATA* ad, long argl, void *argp)
-{
+static int get_string_from_json(cJSON *object, const char *key, char **value)
+{
+ if(object==NULL || key==NULL)
+ {
+ return 0;
+ }
int len=0;
- cJSON *object=NULL, *item=NULL;
- struct compile_user_region *user_region=NULL;
-
- if(rule!=NULL)
+ cJSON *item=cJSON_GetObjectItem(object, key);
+ if(item!=NULL)
{
- if(srv_def_large!=NULL && strlen(srv_def_large)>2)
- {
- object=cJSON_Parse(srv_def_large);
- if(object!=NULL)
- {
- user_region=(struct compile_user_region *)calloc(1, sizeof(struct compile_user_region));
- atomic_inc(&user_region->ref_cnt);
+ len=strlen(item->valuestring);
+ (*value)=(char *)malloc(len+1);
+ memcpy((*value), item->valuestring, len);
+ (*value)[len]='\0';
- item=cJSON_GetObjectItem(object, "method");
- if(item!=NULL)
- {
- len=MIN(strlen(item->valuestring), sizeof(user_region->method)-1);
- memcpy(user_region->method, item->valuestring, len);
- }
+ return 1;
+ }
- item=cJSON_GetObjectItem(object, "protocol");
- if(item!=NULL)
- {
- len=MIN(strlen(item->valuestring), sizeof(user_region->protocol)-1);
- memcpy(user_region->protocol, item->valuestring, len);
- }
+ return 0;
+}
- item=cJSON_GetObjectItem(object, "message");
- if(item!=NULL)
- {
- len=strlen(item->valuestring)+1;
- user_region->message=(char *)calloc(1, len);
- memcpy(user_region->message, item->valuestring, len-1);
- }
+static int get_integer_from_json(cJSON *object, const char *key, int *value)
+{
+ if(object==NULL || key==NULL || (value)==NULL)
+ {
+ return 0;
+ }
+
+ cJSON *item=cJSON_GetObjectItem(object, key);
+ if(item!=NULL)
+ {
+ (*value)=item->valueint;
+ return 1;
+ }
- item=cJSON_GetObjectItem(object, "code");
- if(item!=NULL)
- {
- user_region->code=item->valueint;
- }
+ return 0;
+}
- item=cJSON_GetObjectItem(object, "html_profile");
- if(item!=NULL)
- {
- user_region->html_profile=item->valueint;
- }
+static struct compile_user_region *parse_monitor_user_region(cJSON *object)
+{
+ cJSON *mirror_item=NULL;
+ struct compile_user_region *user_region=(struct compile_user_region *)calloc(1, sizeof(struct compile_user_region));
+ mirror_item=cJSON_GetObjectItem(object, "packet_mirror");
+ if(mirror_item)
+ {
+ user_region->mirror=(struct monitor_user_region *)calloc(1, sizeof(struct monitor_user_region));
+ get_integer_from_json(mirror_item, "enable", &(user_region->mirror->enabled));
+ get_integer_from_json(mirror_item, "mirror_vlan", &(user_region->mirror->mirror_vlan_id));
+ }
- cJSON_Delete(object);
- object=NULL;
- }
- }
+ return user_region;
+}
- if(g_tsg_para.default_compile_switch==1 && g_tsg_para.default_compile_id==rule->config_id)
- {
- if(user_region==NULL)
+static struct compile_user_region *parse_deny_user_region(cJSON *object)
+{
+ int ret=0;
+ cJSON *item=NULL;
+ struct compile_user_region *user_region=(struct compile_user_region *)calloc(1, sizeof(struct compile_user_region));
+
+ item=cJSON_GetObjectItem(object, "method");
+ if(item!=NULL)
+ {
+ user_region->method_type=(TSG_METHOD_TYPE)tsg_get_method_id(item->valuestring);
+ }
+
+ switch(user_region->method_type)
+ {
+ case TSG_METHOD_TYPE_ALERT:
+ case TSG_METHOD_TYPE_BLOCK:
+ user_region->deny=(struct deny_user_region *)calloc(1, sizeof(struct deny_user_region));
+ get_integer_from_json(object, "code", &(user_region->deny->code));
+ ret=get_integer_from_json(object, "html_profile", &(user_region->deny->profile_id));
+ if(ret==1)
+ {
+ user_region->deny->type=TSG_DENY_TYPE_PROFILE;
+ break;
+ }
+
+ ret=get_string_from_json(object, "message", &(user_region->deny->message));
+ if(ret==1)
{
- user_region=(struct compile_user_region *)calloc(1, sizeof(struct compile_user_region));
- atomic_inc(&user_region->ref_cnt);
+ user_region->deny->type=TSG_DENY_TYPE_MESSAGE;
+ break;
}
- user_region->result=(struct Maat_rule_t *)calloc(1, sizeof(struct Maat_rule_t));
- memcpy(user_region->result, rule, sizeof(struct Maat_rule_t));
+ user_region->deny->type=TSG_DENY_TYPE_MAX;
+ break;
+ case TSG_METHOD_TYPE_REDIRECTION:
+ user_region->deny=(struct deny_user_region *)calloc(1, sizeof(struct deny_user_region));
+ get_integer_from_json(object, "code", &(user_region->deny->code));
+ ret=get_string_from_json(object, "redirect_url", &(user_region->deny->redirect_url_to));
+ if(ret==1)
+ {
+ user_region->deny->type=TSG_DENY_TYPE_REDIRECT_TO;
+ break;
+ }
+ ret=get_string_from_json(object, "to", &(user_region->deny->redirect_url_to));
+ if(ret==1)
+ {
+ user_region->deny->type=TSG_DENY_TYPE_REDIRECT_TO;
+ break;
+ }
+ break;
+ case TSG_METHOD_TYPE_RATE_LINIT:
+ user_region->deny=(struct deny_user_region *)calloc(1, sizeof(struct deny_user_region));
+ get_integer_from_json(object, "bytes_per_sec", &(user_region->deny->bytes_per_sec));
+ break;
+ case TSG_METHOD_TYPE_DROP:
+ case TSG_METHOD_TYPE_RESET:
+ break;
+ default:
+ break;
+ }
+
+ return user_region;
+}
+
+void security_compile_new(int idx, const struct Maat_rule_t* rule, const char* srv_def_large, MAAT_RULE_EX_DATA* ad, long argl, void *argp)
+{
+ cJSON *object=NULL;
+ struct compile_user_region *user_region=NULL;
+
+ if(rule==NULL)
+ {
+ return ;
+ }
+
+ if(srv_def_large!=NULL && strlen(srv_def_large)>2)
+ {
+ object=cJSON_Parse(srv_def_large);
+ if(object!=NULL)
+ {
+ switch(rule->action)
+ {
+ case TSG_ACTION_DENY:
+ user_region=parse_deny_user_region(object);
+ atomic_inc(&user_region->ref_cnt);
+ break;
+ case TSG_ACTION_MONITOR:
+ user_region=parse_monitor_user_region(object);
+ atomic_inc(&user_region->ref_cnt);
+ break;
+ default:
+ break;
+ }
+
+ cJSON_Delete(object);
+ object=NULL;
}
+ }
- *ad=(MAAT_RULE_EX_DATA)user_region;
+ if(g_tsg_para.default_compile_switch==1 && g_tsg_para.default_compile_id==rule->config_id)
+ {
+ if(user_region==NULL)
+ {
+ user_region=(struct compile_user_region *)calloc(1, sizeof(struct compile_user_region));
+ atomic_inc(&user_region->ref_cnt);
+ }
+
+ user_region->result=(struct Maat_rule_t *)calloc(1, sizeof(struct Maat_rule_t));
+ memcpy(user_region->result, rule, sizeof(struct Maat_rule_t));
}
+ *ad=(MAAT_RULE_EX_DATA)user_region;
+
return ;
}
@@ -639,32 +735,183 @@ void security_compile_dup(int idx, MAAT_RULE_EX_DATA *to, MAAT_RULE_EX_DATA *fro
}
}
-void security_compile_free(int idx, const struct Maat_rule_t* rule, const char* srv_def_large, MAAT_RULE_EX_DATA* ad, long argl, void *argp)
+static void free_deny_user_region(struct deny_user_region *deny)
{
- struct compile_user_region *user_region=(struct compile_user_region *)(*ad);
- if(user_region!=NULL)
+ if(deny==NULL)
{
- atomic_dec(&user_region->ref_cnt);
- if(user_region->ref_cnt<=0)
- {
- if(user_region->message!=NULL)
- {
- free(user_region->message);
- user_region->message=NULL;
- }
+ return ;
+ }
- if(user_region->result!=NULL)
+ switch(deny->type)
+ {
+ case TSG_DENY_TYPE_MESSAGE:
+ case TSG_DENY_TYPE_REDIRECT_TO:
+ if(deny->para)
{
- free(user_region->result);
- user_region->result=NULL;
+ free(deny->para);
+ deny->para=NULL;
}
-
- free(*ad);
- *ad=NULL;
+ break;
+ default:
+ break;
+ }
+
+}
+
+void security_compile_free(int idx, const struct Maat_rule_t* rule, const char* srv_def_large, MAAT_RULE_EX_DATA* ad, long argl, void *argp)
+{
+ struct compile_user_region *user_region=(struct compile_user_region *)(*ad);
+ if(user_region==NULL)
+ {
+ return ;
+ }
+
+ atomic_dec(&user_region->ref_cnt);
+ if(user_region->ref_cnt>0)
+ {
+ return ;
+ }
+
+ switch(user_region->method_type)
+ {
+ case TSG_METHOD_TYPE_ALERT:
+ case TSG_METHOD_TYPE_BLOCK:
+ case TSG_METHOD_TYPE_RATE_LINIT:
+ case TSG_METHOD_TYPE_REDIRECTION:
+ free_deny_user_region(user_region->deny);
+ break;
+ default:
+ break;
+ }
+
+ if(user_region->user_region_para!=NULL)
+ {
+ free(user_region->user_region_para);
+ user_region->user_region_para=NULL;
+ }
+
+ free(*ad);
+ *ad=NULL;
+
+}
+
+static char *get_pages_content(const char *filename, int *filelen)
+{
+ FILE *file = NULL;
+ long length = 0;
+ char *content = NULL;
+ size_t read_chars = 0;
+ file = fopen(filename, "rb");
+ if(file == NULL)
+ {
+ goto cleanup;
+ }
+ if(fseek(file, 0, SEEK_END) != 0)
+ {
+ goto cleanup;
+ }
+ length = ftell(file);
+ if(length < 0)
+ {
+ goto cleanup;
+ }
+ if(fseek(file, 0, SEEK_SET) != 0)
+ {
+ goto cleanup;
+ }
+ content = (char*)malloc((size_t)length + sizeof(""));
+ if(content == NULL)
+ {
+ goto cleanup;
+ }
+ read_chars = fread(content, sizeof(char), (size_t)length, file);
+ if ((long)read_chars != length)
+ {
+ free(content);
+ content = NULL;
+ goto cleanup;
+ }
+ *filelen = read_chars;
+ content[read_chars] = '\0';
+cleanup:
+ if (file != NULL)
+ {
+ fclose(file);
+ }
+
+ return content;
+}
+
+
+void http_response_pages_dup(int table_id, MAAT_PLUGIN_EX_DATA *to, MAAT_PLUGIN_EX_DATA *from, long argl, void* argp)
+{
+ struct http_response_pages *res_pages=(struct http_response_pages *)*from;
+
+ if(*from!=NULL)
+ {
+ *to=*from;
+ atomic_inc(&res_pages->ref_cnt);
+ }
+}
+
+void http_response_pages_new(int table_id, const char* key, const char* table_line, MAAT_PLUGIN_EX_DATA* ad, long argl, void* argp)
+{
+ int ret=0;
+ void *logger=argp;
+ int is_valid;
+ char format[256]={0};
+ char path[1024]={0};
+ char profile_name[256]={0};
+ struct http_response_pages *res_pages=NULL;
+
+ res_pages=(struct http_response_pages *)calloc(1, sizeof(struct http_response_pages));
+
+ ret=sscanf(table_line, "%d\t%s\t%s\t%s\t%d", &res_pages->profile_id, profile_name, format, path, &is_valid);
+ if(ret!=5)
+ {
+ free(res_pages);
+ res_pages=NULL;
+ if(logger!=NULL)
+ {
+ MESA_handle_runtime_log(logger,
+ RLOG_LV_FATAL,
+ "RESPONSE_PAGES",
+ "Parse response pages failed, ret: %d table_id: %d key: %s table_line: %s",
+ ret,
+ table_id,
+ key,
+ table_line
+ );
}
+ return;
}
+
+ if((strncasecmp(format, "template", strlen(format)))==0)
+ {
+ res_pages->format=HTTP_RESPONSE_FORMAT_TEMPLATE;
+ }
+ else
+ {
+ res_pages->format=HTTP_RESPONSE_FORMAT_HTML;
+ }
+
+ atomic_inc(&res_pages->ref_cnt);
+ res_pages->content=get_pages_content(path, &res_pages->content_len);
+ *ad=(MAAT_PLUGIN_EX_DATA)res_pages;
}
+void http_response_pages_free(int table_id, MAAT_PLUGIN_EX_DATA* ad, long argl, void* argp)
+{
+ struct http_response_pages *res_pages=(struct http_response_pages *)*ad;
+
+ atomic_dec(&res_pages->ref_cnt);
+ if(res_pages->ref_cnt<=0)
+ {
+ free(res_pages->content);
+ free(*ad);
+ *ad=NULL;
+ }
+}
static int get_fqdn_category_id(Maat_feather_t maat_feather, int table_id, char *fqdn, unsigned int *category_id, int category_id_num, void *logger, int thread_seq)
{
@@ -858,6 +1105,8 @@ int tsg_rule_init(const char* conffile, void *logger)
MESA_load_profile_string_def(conffile, "MAAT", "GTP_APN", g_tsg_para.table_name[TABLE_GTP_APN], _MAX_TABLE_NAME_LEN, "TSG_FILED_GTP_APN");
MESA_load_profile_string_def(conffile, "MAAT", "GTP_IMSI", g_tsg_para.table_name[TABLE_GTP_IMSI], _MAX_TABLE_NAME_LEN, "TSG_FILED_GTP_IMSI");
MESA_load_profile_string_def(conffile, "MAAT", "GTP_PHONE_NUMBER", g_tsg_para.table_name[TABLE_GTP_PHONE_NUMBER], _MAX_TABLE_NAME_LEN, "TSG_FILED_GTP_PHONE_NUMBER");
+ MESA_load_profile_string_def(conffile, "MAAT", "GTP_PHONE_NUMBER", g_tsg_para.table_name[TABLE_GTP_PHONE_NUMBER], _MAX_TABLE_NAME_LEN, "TSG_FILED_GTP_PHONE_NUMBER");
+ MESA_load_profile_string_def(conffile, "MAAT", "RESPONSE_PAGES_TABLE", g_tsg_para.table_name[TABLE_RESPONSE_PAGES], _MAX_TABLE_NAME_LEN, "TSG_PROFILE_RESPONSE_PAGES");
//init static maat feather
g_tsg_maat_feather=init_maat_feather(maat_conffile, (char *)"TSG_STATIC", (char *)"STATIC", logger);
@@ -980,6 +1229,25 @@ int tsg_rule_init(const char* conffile, void *logger)
);
return -1;
}
+
+ ret=Maat_plugin_EX_register(g_tsg_maat_feather,
+ g_tsg_para.table_id[TABLE_RESPONSE_PAGES],
+ http_response_pages_new,
+ http_response_pages_free,
+ http_response_pages_dup,
+ NULL,
+ 0,
+ logger);
+ if(ret<0)
+ {
+ MESA_handle_runtime_log(logger,
+ RLOG_LV_FATAL,
+ "RESPONSE_PAGES",
+ "Maat_plugin_EX_register failed, table_name: %s table_id: %d",
+ g_tsg_para.table_name[TABLE_RESPONSE_PAGES],
+ g_tsg_para.table_id[TABLE_RESPONSE_PAGES]);
+ return -1;
+ }
//init dynamic maat feather
g_tsg_dynamic_maat_feather=init_maat_feather(maat_conffile, (char *)"TSG_DYNAMIC", (char *)"DYNAMIC", logger);
@@ -1778,3 +2046,40 @@ int tsg_app_id2name(int app_id, char *app_name, int app_name_len, int is_joint_p
return offset;
}
+
+int tsg_free_compile_user_region(const struct Maat_rule_t *rule, struct compile_user_region *user_region)
+{
+ security_compile_free(0, rule, NULL , (MAAT_RULE_EX_DATA *)&user_region, 0, NULL);
+
+ return 0;
+}
+
+struct compile_user_region *tsg_get_compile_user_region(const Maat_feather_t maat_feather, struct Maat_rule_t *result)
+{
+ return ((struct compile_user_region *)Maat_rule_get_ex_data(g_tsg_maat_feather, result, g_tsg_para.table_id[TABLE_SECURITY_COMPILE]));
+}
+
+int tsg_get_vlan_id_by_monitor_rule(Maat_feather_t maat_feather, struct Maat_rule_t *result, int result_num, int *vlan_id, int vlan_id_num)
+{
+ int i=0,count=0;
+ struct compile_user_region *user_region=NULL;
+
+ for(i=0; i<result_num && count<vlan_id_num; i++)
+ {
+ if(result[i].action!=TSG_ACTION_MONITOR)
+ {
+ continue;
+ }
+
+ user_region=tsg_get_compile_user_region(maat_feather, &(result[i]));
+ if(user_region!=NULL)
+ {
+ vlan_id[count++]=user_region->mirror->mirror_vlan_id;
+ tsg_free_compile_user_region(&(result[i]), user_region);
+ user_region=NULL;
+ }
+ }
+
+ return count;
+}
+