Mod aaa-12 修改nat模块配置保存恢复及正则检查

RCA:
SOL:
修改人:sunguosong
检视人:

Signed-off-by: sunguosong <sunguosong@cmhi.chinamobile.com>
This commit is contained in:
sunguosong 2019-10-12 09:22:04 +08:00
parent e43238ff4c
commit f9457a2cab
4 changed files with 119 additions and 13 deletions

View File

@ -210,7 +210,7 @@
{\ {\
NAT4_CONFIG, \ NAT4_CONFIG, \
CONFIG_FROM_WEB, \ CONFIG_FROM_WEB, \
FALSE, \ TRUE, \
nat_config_chk, \ nat_config_chk, \
nat_config_proc, \ nat_config_proc, \
nat_config_get, \ nat_config_get, \

View File

@ -157,6 +157,15 @@ static const char *__json = "{ \"config_type\":3, \"content\":[ \
} \ } \
} while (0) } while (0)
// 宏: 字段正则检查
#define _REG_CHK(reg, E) do { \
int status = __regex_match(reg, conf->E); \
if(status != 0) { \
__error_report(msg, current_id, "\"%s: %s\" is not vaild!", #E, conf->E); \
return FAIL; \
} \
} while (0)
// 宏: int拼接到字符串并防止拼接越界 // 宏: int拼接到字符串并防止拼接越界
#define strcat_int_free_count(des, src) do { \ #define strcat_int_free_count(des, src) do { \
char s[21]; \ char s[21]; \
@ -224,6 +233,23 @@ static int free_space = MAX_ERR_MSG;
// 当前执行的命令id // 当前执行的命令id
static int current_id = -1; static int current_id = -1;
static char *_ip_regex = "^(((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})\
(\\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}(/([0-9]|\\.){1,15}){0,1}){0,1}$";
static char *_id_regex = "^([0-9]{0,5})$";
static char *_port_regex = "^([0-9]{0,5})$";
static char *_prot_regex = "^([0-9a-zA-Z]|-){0,15}$";
static char *_device_regex = "^([0-9a-zA-Z]|-){0,15}$";
static char *_addr_regex = "^((((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})\
(\\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3})(-\
(((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})\
(\\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3})){0,1}\
(:[0-9]{0,5}(-[0-9]{0,5}){0,1}){0,1}){0,1}$";
static char *_match_regex = "^(mark){0,1}$";
static char *_match_info_regex = "^[0-9]{0,4}$";
typedef void *(*jsonfunc)(cJSON *json_arr, int *output_len, ret_code *ret, char **msg); typedef void *(*jsonfunc)(cJSON *json_arr, int *output_len, ret_code *ret, char **msg);
// iptables 命令参数拼接前缀 // iptables 命令参数拼接前缀
@ -316,6 +342,8 @@ ret_code __nf_conntrack_parse(const char *conn, nf_conntrack *conf);
char *__error_report(char** msg, int id, char *fmt, ...) char *__error_report(char** msg, int id, char *fmt, ...)
__attribute__((format(printf, 3, 4))); __attribute__((format(printf, 3, 4)));
int __regex_match(char* pattern, char* buf);
// 字符串指针char**)释放函数 // 字符串指针char**)释放函数
void __free_dptr_char(char ***ptr, int len); void __free_dptr_char(char ***ptr, int len);
@ -352,12 +380,27 @@ char* __error_report (char **msg, int id, char *fmt, ...) {
} }
strcat_str_free_count(*msg, _msg_head); strcat_str_free_count(*msg, _msg_head);
printf("%s\n", *msg); //printf("%s\n", *msg);
err: err:
return NULL; return NULL;
} }
int __regex_match(char* pattern, char* buf) {
int status,i;
regmatch_t pmatch[1];
const size_t nmatch=1;
regex_t reg;
//编译正则模式
regcomp(&reg, pattern, REG_EXTENDED|REG_NEWLINE);
//执行正则表达式和缓存的比较
status=regexec(&reg, buf, nmatch, pmatch, 0);
regfree(&reg);
return status;
}
/* /*
* int整数转化成char* * int整数转化成char*
@ -602,10 +645,10 @@ char **split(const char * const targetString, const char * const delimiter,
*length = 0; *length = 0;
char ** resultString = NULL; char ** resultString = NULL;
char inputString[strlen(targetString)]; char inputString[strlen(targetString) + 1];
strcpy(inputString,targetString); strcpy(inputString,targetString);
char inputDelimiter[strlen(delimiter)]; char inputDelimiter[strlen(delimiter) + 1];
strcpy(inputDelimiter,delimiter); strcpy(inputDelimiter,delimiter);
char * splitedString = strtok(inputString, inputDelimiter); char * splitedString = strtok(inputString, inputDelimiter);
@ -700,6 +743,10 @@ ret_code __ipt_conf_parse(const iptables_rule rule, const struct ipt_config *con
while(option = __extract_parm(&_optind, _argc, _argv)) { while(option = __extract_parm(&_optind, _argc, _argv)) {
if (_optind >= _argc) break; if (_optind >= _argc) break;
switch(option) { switch(option) {
case '!':
// to do
break;
case 'A': case 'A':
CMP_IPT_OPTION(chain); CMP_IPT_OPTION(chain);
FILL_IPT_OPTION(chain, MAX_CHAIN); FILL_IPT_OPTION(chain, MAX_CHAIN);
@ -1073,11 +1120,27 @@ boolean __iptconfig_chk(struct ipt_config *conf, char **msg) {
switch (option = __parse_action(conf)) { switch (option = __parse_action(conf)) {
case DELETE: case DELETE:
if (!isempty_str(conf->id)) {
_REG_CHK(_id_regex, id);
}
else {
goto setmode;
}
break; break;
case SET: case SET:
_REG_CHK(_id_regex, id);
setmode:
_REG_CHK(_ip_regex, source);
_REG_CHK(_ip_regex, destination);
_REG_CHK(_port_regex, sport);
_REG_CHK(_port_regex, dport);
_REG_CHK(_prot_regex, prot);
_REG_CHK(_device_regex, i_device);
_REG_CHK(_device_regex, o_device);
_REG_CHK(_match_regex, match);
_REG_CHK(_match_info_regex, match_info);
_REG_CHK(_addr_regex, to);
break; break;
case SAVE: case SAVE:
@ -1107,7 +1170,7 @@ ret_code set_iptables_config(const char *json, char **msg) {
struct ipt_config *conf = NULL, *conf_start = NULL; struct ipt_config *conf = NULL, *conf_start = NULL;
free_space = MAX_ERR_MSG; free_space = MAX_ERR_MSG;
__chk_malloc((*msg), char*, sizeof(char) * free_space, ret, msg); __chk_malloc((*msg), char*, sizeof(char) * free_space, ret, NULL);
memset(*msg, 0, sizeof(char) * free_space); memset(*msg, 0, sizeof(char) * free_space);
conf = (struct ipt_config*)__jsontxt_to_struct(json, &len, conf = (struct ipt_config*)__jsontxt_to_struct(json, &len,
@ -1140,6 +1203,8 @@ ret_code set_iptables_config(const char *json, char **msg) {
} }
} }
ret = run_command("sudo iptables-save -t nat > ./iptables-conf.txt 2>&1", msg);
MEMerr: MEMerr:
err: err:
xfree(rule); xfree(rule);
@ -1201,7 +1266,7 @@ ret_code get_iptables_config(const char *json, const char * __restrict__ __filen
boolean match = FAIL; boolean match = FAIL;
ret_code ret = RET_OK; ret_code ret = RET_OK;
__chk_malloc((*msg), char*, sizeof(char) * free_space, ret, msg); __chk_malloc((*msg), char*, sizeof(char) * free_space, ret, NULL);
memset(*msg, 0, sizeof(char)*free_space); memset(*msg, 0, sizeof(char)*free_space);
ret = run_command("sudo iptables-save -t nat > ./iptables-conf.txt 2>&1", msg); ret = run_command("sudo iptables-save -t nat > ./iptables-conf.txt 2>&1", msg);
@ -1220,6 +1285,8 @@ ret_code get_iptables_config(const char *json, const char * __restrict__ __filen
rules = __read_iptables_conf(__filename, &len, 0, -1, &ret, msg); rules = __read_iptables_conf(__filename, &len, 0, -1, &ret, msg);
rules_start = rules; rules_start = rules;
if (!__iptconfig_chk(&(rwconf->conf), msg)) goto err; if (!__iptconfig_chk(&(rwconf->conf), msg)) goto err;
rwconf->begin -= 1;
if (rwconf->begin < 0) rwconf->begin = 0; if (rwconf->begin < 0) rwconf->begin = 0;
if (rwconf->offset < 0) rwconf->offset = len; if (rwconf->offset < 0) rwconf->offset = len;
@ -1275,6 +1342,24 @@ MEMerr:
return ret; return ret;
} }
ret_code nat_config_recovery(char **msg) {
FILE *fp = NULL;
free_space = MAX_ERR_MSG;
ret_code ret = RET_OK;
__chk_malloc((*msg), char*, sizeof(char) * free_space, ret, NULL);
memset(*msg, 0, sizeof(char) * free_space);
fp = fopen("./iptables-conf.txt", "r");
if (fp != NULL) {
fclose(fp);
ret = run_command("sudo iptables-restore ./iptables-conf.txt 2>&1", msg);
}
MEMerr:
return ret;
}
/* /*
* ,,使 * ,,使
*/ */

View File

@ -13,6 +13,8 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#include <regex.h>
//#include <io.h>
#include <cjson/cJSON.h> #include <cjson/cJSON.h>
@ -40,7 +42,7 @@ typedef enum ret_code {
#define MAX_PROT 15 #define MAX_PROT 15
#define MAX_ADDR 45 #define MAX_ADDR 45
#define MAX_IP 33 #define MAX_IP 33
#define MAX_PORT 5 #define MAX_PORT 6
#define MAX_DEVICE 15 #define MAX_DEVICE 15
#define MAX_MATCH 6 #define MAX_MATCH 6
#define MAX_MATCH_INFO 10 #define MAX_MATCH_INFO 10
@ -111,4 +113,6 @@ ret_code set_iptables_config(const char *json, char **msg);
// linux系统命令执行函数, 返回shell信息 // linux系统命令执行函数, 返回shell信息
ret_code run_command(char *const cmd, char **msg); ret_code run_command(char *const cmd, char **msg);
ret_code nat_config_recovery(char **msg);
#endif /* config_h */ #endif /* config_h */

View File

@ -32,8 +32,17 @@ ret_code nat_config_chk(uint source,uint *config_type,
{ {
int config_len = sizeof(ip_config_t); int config_len = sizeof(ip_config_t);
int code = 0;
ret_code ret = RET_OK; ret_code ret = RET_OK;
if(source == CONFIG_FROM_RECOVER1) {
return RET_OK;
}
if(source == CONFIG_FROM_RECOVER2){
return RET_CHKERR;
}
get_config_type(input, config_type); get_config_type(input, config_type);
switch (*config_type) switch (*config_type)
{ {
@ -68,10 +77,17 @@ ret_code nat_config_proc(uint source, uint config_type,
{ {
char *errmsg; char *errmsg;
char *jsontxt = (char*)input; char *jsontxt = (char*)input;
int code = 0;
ret_code ret = RET_OK; ret_code ret = RET_OK;
if(source == CONFIG_FROM_RECOVER1 || source == CONFIG_FROM_RECOVER2) {
ret = nat_config_recovery(&errmsg);
goto pass;
}
ret = set_iptables_config(jsontxt, &errmsg); ret = set_iptables_config(jsontxt, &errmsg);
//rpc_log_info("NAT message: %s \n", errmsg); pass:
rpc_log_info("NAT message: %s \n", errmsg);
free(errmsg); free(errmsg);
RET_ERR_FORMART(ret, output, *output_len); RET_ERR_FORMART(ret, output, *output_len);
@ -87,10 +103,11 @@ ret_code nat_config_get(uint source,
{ {
char *errmsg; char *errmsg;
char *jsontxt = (char*)input; char *jsontxt = (char*)input;
int code = 0;
ret_code ret = RET_OK; ret_code ret = RET_OK;
ret = get_iptables_config(jsontxt, iptables_save_dir, output, output_len, &errmsg); ret = get_iptables_config(jsontxt, iptables_save_dir, output, output_len, &errmsg);
//rpc_log_info("NAT message:\n %s \n", errmsg); rpc_log_info("NAT message:\n %s \n", errmsg);
free(errmsg); free(errmsg);
RET_ERR_FORMART(ret, output, *output_len); RET_ERR_FORMART(ret, output, *output_len);