secgateway/Platform/user/configm/config-server/web_config/authfree.c

733 lines
21 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <unistd.h>
#include <arpa/inet.h>
#include "../include/parsefile.h"
#include "../include/configm.h"
#include "../../../netlink_uapi/libnetlinku.h"
#include "rpc.h"
#include "authfree.h"
#include "auth_parameters.h"
#include <cjson/cJSON.h>
#include "s2j/s2j.h"
#include "commuapinl.h"
#include "../Platform/common/database/database.h"
#include "include/user_authfree.h"
#include "config_manager.h"
/*定义结构体数组 存在免认证规则 */
freeauth_configure_t freeauth_array[RULE_MAX_NUM] = {0};
#define UNAMESIZE (127 + 1)
#define SPECHAR(element) (strpbrk((element), "~!@#$%^&*()_+{}|:\"<>?\\,./;\'[]-=`")) //校验特殊字符
#ifdef FREEAUTH_ACK_COOKIES
#define CFG_FREEAUTH_ACK_COOKIES
#endif
/* 判断IPv4格式是否正确*/
int isIpV4Addr(const char *ipAddr)
{
unsigned char buf[sizeof(struct sockaddr_in)];
if((NULL == ipAddr) || (0 == strlen(ipAddr))) {
return -1;
}
if(inet_pton(AF_INET, ipAddr, buf) == 1) {
return 0;
}
return -1;
}
/*下发配置到内核态 */
int set_freeauthcfg_waitack(freeauth_configure_t *struct_freeauth)
{
int freeauth_len = 0;
struct nlmsghdr *ack = NULL;
struct {
struct nlmsghdr n;
char buf[1024];
} req = {
.n.nlmsg_len = NLMSG_LENGTH(0),
#ifdef CFG_FREEAUTH_ACK_COOKIES
.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK, /*set NLM_F_ACKuse kernel auto ack*/
#else
.n.nlmsg_flags = NLM_F_REQUEST, /*not use kernel auto ack */
#endif
.n.nlmsg_type = FREEAUTH_CFG,
.n.nlmsg_pid = getpid(),
};
/*判断要发送的数据是否为NULL,不为NULL,打印出来 */
if(struct_freeauth == NULL) {
printf("set_freeauthcfg_waitack is error: input struct_freeauth is NULL.\r\n");
return -1;
} else {
unsigned char str[INET_ADDRSTRLEN];
unsigned char dtr[INET_ADDRSTRLEN];
memset(str, 0, INET_ADDRSTRLEN);
inet_ntop(AF_INET, (void *)&struct_freeauth->sip, str, INET_ADDRSTRLEN);
memset(dtr, 0, INET_ADDRSTRLEN);
inet_ntop(AF_INET, (void *)&struct_freeauth->dip, dtr, INET_ADDRSTRLEN);
printf("set_freeauthcfg_waitack :name %s sip %s dip %s dport %d\n",
struct_freeauth->name, str, dtr,
struct_freeauth->dport);
}
/*计算需要发送的数据的长度 */
freeauth_len = sizeof(freeauth_configure_t);
/*可选属性 */
commnl_addattr_l(&req.n, sizeof(req), 1, struct_freeauth, freeauth_len);
/*发送组装好的netlink消息 */
if(pdeliv_talk(1, &req.n, &ack) < 0) {
printf("set_user_freeauth_waitack rcv ack msg faild.\r\n");
return -2;
} else {
printf("set_user_freeauth_waitack rcv ack msg success.\r\n");
}
if(ack != NULL) {
printf("set_user_freeauth_waitack rcv answer.\r\n");
} else {
printf("set_user_freeauth_waitack rcv answer error.\r\n");
return -3;
}
#ifdef CFG_FREEAUTH_ACK_COOKIES
/*recv answer*/
if(ack->nlmsg_type == NLMSG_ERROR) {
nl_debugfs_extack(ack);
}
#else
/*recv answer*/
if(ack->nlmsg_type == FREEAUTH_CFG) {
nl_debugfs(ack);
}
#endif
if(ack) {
free(ack);
}
return 0;
}
/*获取json串类型*/
ret_code freeauth_config_json_type(pointer input, uint *conf_type)
{
const char *pString = (char *)input;
cJSON *cjson, *type;
if(!pString) {
return RET_INPUTERR;
}
printf("json:[%s]\n", pString);
/*JSON字符串到JSON格式 */
cjson = cJSON_Parse(input);
if(!cjson) {
return RET_INPUTERR;
}
/*获取操作类型 add、mod、del */
type = cJSON_GetObjectItem(cjson, "type");
if(!type) {
cJSON_Delete(cjson);
return RET_INPUTERR;
}
if(conf_type) {
*conf_type = type->valueint;
}
cJSON_Delete(cjson);
return RET_OK;
}
/*json字符串转为结构体*/
/*iuput格式{"type": 0, "data": {"rule_priority": 1, "name": "armink","sip": 1027824,"dip": 103427824,"dport": 24, "flag":0}}*/
ret_code freeauth_config_json_parse(pointer input, uint *conf_type, freeauth_configure_t *freeauth_buff)
{
const char *pString = (char *)input;
cJSON *cjson, *type, *data;
if(!pString) {
return RET_INPUTERR;
}
printf("json:[%s]\n", pString);
/*JSON字符串到JSON格式 */
cjson = cJSON_Parse(pString);
if(!cjson) {
return RET_INPUTERR;
}
/*获取操作类型 add、mod、del */
type = cJSON_GetObjectItem(cjson, "type");
if(!type) {
cJSON_Delete(cjson);
return RET_INPUTERR;
}
if(conf_type) {
*conf_type = type->valueint;
}
/*获取免认证规则的data部分 */
data = cJSON_GetObjectItem(cjson, "data");
if(!data) {
cJSON_Delete(cjson);
return RET_INPUTERR;
}
/*创建freeauth_configure_t结构体对象 */
s2j_create_struct_obj(struct_freeauth, freeauth_configure_t);
if(struct_freeauth == NULL) {
cJSON_Delete(cjson);
return RET_NOMEM;
}
/*反序列化数据到freeauth_configure_t结构体对象 */
s2j_struct_get_basic_element(struct_freeauth, data, int, rule_priority);
s2j_struct_get_basic_element(struct_freeauth, data, string, name);
s2j_struct_get_basic_element(struct_freeauth, data, int, sip);
s2j_struct_get_basic_element(struct_freeauth, data, int, dip);
s2j_struct_get_basic_element(struct_freeauth, data, int, dport);
s2j_struct_get_basic_element(struct_freeauth, data, int, flag);
if(freeauth_buff) {
memset(freeauth_buff, 0, sizeof(freeauth_configure_t));
freeauth_buff->rule_priority = struct_freeauth->rule_priority;
strncpy(freeauth_buff->name, struct_freeauth->name, 31);
freeauth_buff->sip = struct_freeauth->sip;
freeauth_buff->dip = struct_freeauth->dip;
freeauth_buff->dport = struct_freeauth->dport;
freeauth_buff->flag = struct_freeauth->flag;
}
cJSON_Delete(cjson);
s2j_delete_struct_obj(struct_freeauth);
return RET_OK;
}
/*iuput格式
{
"type": 0,
"data": [
{"rule_priority": 1,"name": "cary","sip": 2323790,"dip": 13546465478,"dport": 120, "flag":0},
{"rule_priority": 2,"name": "nicole","sip": 2323790,"dip": 13546465478,"dport": 130, "flag":0},
{"rule_priority": 3,"name": "arwrgmink","sip": 2323790,"dip": 13546465478,"dport": 90, "flag":0}
]
}
*/
ret_code authpara_config_json_parse_array(pointer input, uint *conf_type, freeauth_configure_t **fb, int *cnt)
{
cJSON *cjson, *data, *rule_priority, *name, *sip, *dip, *dport, *flag;
freeauth_configure_t *freeauth_buff = *fb;
int iCount = 0, i = 0;
*fb = NULL;
/*JSON字符串到JSON格式 */
cjson = cJSON_Parse(input);
if(!cjson) {
return RET_INPUTERR;
}
rpc_log_info("json input:%s \n", cJSON_Print(cjson));
/*获取免认证规则的data部分 */
data = cJSON_GetObjectItem(cjson, "data");
if(!data) {
cJSON_Delete(cjson);
return RET_INPUTERR;
}
/*获取数组长度*/
iCount = cJSON_GetArraySize(data);
printf("iCount=[%d]\n", iCount);
freeauth_buff = (freeauth_configure_t *)malloc(sizeof(freeauth_configure_t) * iCount);
if(!freeauth_buff) {
cJSON_Delete(cjson);
return RET_NOMEM;
}
memset(freeauth_buff, 0, sizeof(freeauth_configure_t) * iCount);
for(i = 0; i < iCount; i++) {
cJSON *pArrayItem = cJSON_GetArrayItem(data, i);
if(pArrayItem) {
/*获取未认证权限优先级键值对*/
rule_priority = cJSON_GetObjectItem(pArrayItem, "rule_priority");
if(rule_priority) {
freeauth_buff->rule_priority = rule_priority->valueint;
}
/*未认证权限名称*/
name = cJSON_GetObjectItem(pArrayItem, "name");
if(name) {
strncpy(freeauth_buff->name, name->valuestring, 31);
}
/*源IP地址*/
sip = cJSON_GetObjectItem(pArrayItem, "sip");
if(sip) {
freeauth_buff->sip = sip->valueint;
}
/*目的IP地址*/
dip = cJSON_GetObjectItem(pArrayItem, "dip");
if(dip) {
freeauth_buff->dip = dip->valueint;
}
/*目的端口号*/
dport = cJSON_GetObjectItem(pArrayItem, "dport");
if(dport) {
freeauth_buff->dport = dport->valueint;
}
/*状态标志位*/
flag = cJSON_GetObjectItem(pArrayItem, "flag");
if(flag) {
freeauth_buff->flag = flag->valueint;
}
#if 0
printf("freeauth_buff->name = %p\n", &freeauth_buff->name);
for (int j = 0; j < iCount; j++)
{
printf("[%d %s %d %d %d %d]\n",pbuf[j].rule_priority, pbuf[j].name, pbuf[j].sip,
pbuf[j].dip, pbuf[j].dport, pbuf[j].flag);
}
#endif
freeauth_buff++;
}
}
if(cnt) {
*cnt = iCount;
}
cJSON_Delete(cjson);
*fb = freeauth_buff;
return RET_OK;
}
ret_code authpara_config_json_parse_del_array(pointer input, uint *conf_type, freeauth_configure_t **fb, int *cnt)
{
return authpara_config_json_parse_array(input, conf_type, fb, cnt);
}
/*chk data格式 */
ret_code freeauth_config_chk(uint source, uint *config_type,
pointer input, int *input_len,
pointer output, int *output_len)
{
ret_code ret = RET_OK;
return ret;
}
/*增加未认证权限规则*/
ret_code freeauth_config_add_proc(uint source, uint config_type,
pointer input, int input_len,
pointer output, int *output_len)
{
int i;
cJSON *res;
freeauth_configure_t *freeauth_configure;
uint conf_type = FREEAUTH_CONFIG_GET;
char *ret_char = NULL;
unsigned int ret_int = 0;
authfree_result_t authfree_result;
freeauth_configure = (freeauth_configure_t *)malloc(sizeof(freeauth_configure_t));
if(freeauth_configure == NULL) {
return RET_NOMEM;
}
freeauth_config_json_parse(input, &conf_type, freeauth_configure);
/*校验用户名长度*/
if(input_len != sizeof(freeauth_configure_t) || NULL == freeauth_configure->name ||
(UNAMESIZE) < strlen(freeauth_configure->name) || 0 == strlen(freeauth_configure->name)) {
free(freeauth_configure);
return RET_INPUTERR;
}
/* 校验用户名中不含特殊字符 */
if(SPECHAR(freeauth_configure->name)) {
free(freeauth_configure);
return RET_INPUTERR;
}
if((freeauth_configure->dport < DPORT_MIN_NUM) || (freeauth_configure->dport > DPORT_MAX_NUM)) {
free(freeauth_configure);
return RET_IPINVALID;
}
/*查找要增加的未认证权限是否重名 该名字已存在 则退出程序 */
for(i = 0; i < RULE_MAX_NUM; i++) {
/*两个字符串相等 strcmp值为0*/
if(0 == strcmp(freeauth_array[i].name, freeauth_configure->name)) {
printf("%s(%d) freeauth_array[%d] = %p\n", __FUNCTION__, __LINE__, i, &freeauth_array[i]);
free(freeauth_configure);
return RET_EXIST;
}
}
/*数据库修改 存入全局变量*/
add_authfree(freeauth_configure->rule_priority, freeauth_configure->name, freeauth_configure->sip, freeauth_configure->dip,
freeauth_configure->dport, freeauth_configure->flag, &authfree_result);
#if 0
/*用户态下发到内核态auth_hook */
int r = -1;
printf("cfgchannel main begin:\r\n");
/*创建通道 */
r = commcfgnl_open();
if(r < 0) {
printf(" pdlivnl_open fail, exit.\r\n");
return RET_ERR;
}
/*下发配置到内核态 */
r = set_freeauthcfg_waitack(freeauth_configure);
if(r < 0) {
printf("set_cfg_debug_waitack failed.\r\n");
return RET_ERR;
}
/*关闭netlink通道 */
commcfgnl_close();
printf("cfgchannel main exit!\r\n");
#endif
/*创建json对象 */
res = cJSON_CreateObject();
if(!res) {
free(freeauth_configure);
return RET_ERR;
}
/*将json对象转换成json字符串 返回处理结果*/
cJSON_AddNumberToObject(res, "resultcode", authfree_result.resultcode);
cJSON_AddStringToObject(res, "message", authfree_result.message);
ret_char = cJSON_PrintUnformatted(res);
ret_int = strlen(ret_char);
if(output_len) {
*output_len = ret_int;
}
/*超出2k的内存报错 */
if(ret_int >= 1024 * 2) {
free(ret_char);
free(freeauth_configure);
cJSON_Delete(res);
return RET_NOMEM;
}
memcpy(output, ret_char, ret_int + 1);
free(ret_char);
cJSON_Delete(res);
free(freeauth_configure);
return RET_OK;
}
ret_code freeauth_config_mod_proc(uint source, uint config_type,
pointer input, int input_len,
pointer output, int *output_len)
{
int i;
int cnt;
cJSON *res;
authfree_result_t authfree_result;
freeauth_configure_t *freeauth_configure = NULL;
uint conf_type = FREEAUTH_CONFIG_GET;
char *ret_char = NULL;
unsigned int ret_int = 0;
authpara_config_json_parse_array(input, &conf_type, &freeauth_configure, &cnt);
if(input_len != sizeof(freeauth_configure_t)) {
return RET_INPUTERR;
}
/*查找要修改的免认证规则名字,不存在则退出程序 */
for(i = 0; i < RULE_MAX_NUM; i++) {
/*两个字符串相等 strcmp值为0*/
for(int j = 0; j < cnt; j++) {
if(0 == strcmp(freeauth_array[i].name, freeauth_configure[j].name)) {
printf("%s %d\n", freeauth_array[i].name, i);
printf("%s %d\n", freeauth_configure[j].name, j);
printf("%s(%d) freeauth_array[%d] = %p\n", __FUNCTION__, __LINE__, i, &freeauth_array[j]);
/*数据库修改 存入全局变量*/
mod_authfree(freeauth_configure[j].rule_priority, freeauth_configure[j].name, freeauth_configure[j].sip, freeauth_configure[j].dip,
freeauth_configure[j].dport, freeauth_configure[j].flag, &authfree_result);
#if 0
/*用户态下发到内核态auth_hook */
int r = -1;
printf("cfgchannel main begin:\r\n");
/*创建通道 */
r = commcfgnl_open();
if(r < 0) {
printf(" pdlivnl_open fail, exit.\r\n");
return RET_ERR;
}
/*下发配置到内核态 */
r = set_freeauthcfg_waitack(freeauth_configure);
if(r < 0) {
printf("set_cfg_debug_waitack failed.\r\n");
return RET_ERR;
}
/*关闭netlink通道 */
commcfgnl_close();
printf("cfgchannel main exit!\r\n");
#endif
/*创建json对象 */
res = cJSON_CreateObject();
if(!res) {
return RET_ERR;
}
/*将json对象转换成json字符串 返回处理结果*/
cJSON_AddNumberToObject(res, "resultcode", authfree_result.resultcode);
cJSON_AddStringToObject(res, "message", authfree_result.message);
ret_char = cJSON_PrintUnformatted(res);
ret_int = strlen(ret_char);
if(output_len) {
*output_len = ret_int;
}
/*超出2k的内存报错 */
if(ret_int >= 1024 * 2) {
free(ret_char);
cJSON_Delete(res);
return RET_NOMEM;
}
memcpy(output, ret_char, ret_int + 1);
free(ret_char);
cJSON_Delete(res);
}
}
}
if(freeauth_configure) {
free(freeauth_configure);
}
return RET_OK;
}
ret_code freeauth_config_del_proc(uint source, uint config_type,
pointer input, int input_len,
pointer output, int *output_len)
{
int i;
int cnt;
cJSON *res;
authfree_result_t authfree_result;
freeauth_configure_t *freeauth_configure = NULL;
uint conf_type = FREEAUTH_CONFIG_GET;
char *ret_char = NULL;
unsigned int ret_int = 0;
#if 0
freeauth_configure = (freeauth_configure_t *)malloc(sizeof(freeauth_configure_t));
if(freeauth_configure == NULL) {
return RET_NAMEINVAL;
}
#endif
authpara_config_json_parse_del_array(input, &conf_type, &freeauth_configure, &cnt);
if(input_len != sizeof(freeauth_configure_t)) {
return RET_INPUTERR;
}
/*查找要修改的免认证规则名字,不存在则退出程序 */
for(i = 0; i < RULE_MAX_NUM; i++) {
/*两个字符串相等 strcmp值为0*/
for(int j = 0; j < cnt; j++) {
if(0 == strcmp(freeauth_array[i].name, freeauth_configure[j].name)) {
printf("%s %d\n", freeauth_array[i].name, i);
printf("%s %d\n", freeauth_configure[j].name, j);
printf("%s(%d) freeauth_array[%d] = %p\n", __FUNCTION__, __LINE__, i, &freeauth_array[j]);
/*数据库修改 存入全局变量*/
del_authfree(freeauth_configure[j].name, &authfree_result);
#if 0
/*用户态下发到内核态auth_hook */
int r = -1;
printf("cfgchannel main begin:\r\n");
/*创建通道 */
r = commcfgnl_open();
if(r < 0) {
printf(" pdlivnl_open fail, exit.\r\n");
return RET_ERR;
}
/*下发配置到内核态 */
r = set_freeauthcfg_waitack(freeauth_configure);
if(r < 0) {
printf("set_cfg_debug_waitack failed.\r\n");
return RET_ERR;
}
/*关闭netlink通道 */
commcfgnl_close();
printf("cfgchannel main exit!\r\n");
#endif
/*创建json对象 */
res = cJSON_CreateObject();
if(!res) {
return RET_ERR;
}
/*将json对象转换成json字符串 返回处理结果*/
cJSON_AddNumberToObject(res, "resultcode", authfree_result.resultcode);
cJSON_AddStringToObject(res, "message", authfree_result.message);
ret_char = cJSON_PrintUnformatted(res);
ret_int = strlen(ret_char);
if(output_len) {
*output_len = ret_int;
}
/*超出2k的内存报错 */
if(ret_int >= 1024 * 2) {
free(ret_char);
cJSON_Delete(res);
return RET_NOMEM;
}
memcpy(output, ret_char, ret_int + 1);
free(ret_char);
cJSON_Delete(res);
}
}
}
if(freeauth_configure) {
free(freeauth_configure);
}
return RET_OK;
}
ret_code freeauth_config_proc(uint source, uint config_type,
pointer input, int input_len,
pointer output, int *output_len)
{
ret_code ret = RET_OK;
freeauth_configure_t freeauth_configure = {0};
int config_len = sizeof(freeauth_configure_t);
uint conf_type = FREEAUTH_CONFIG_GET;
char *ret_char = NULL;
unsigned int ret_int = 0;
int r = -1;
cJSON *res;
int code = 0;
freeauth_config_json_type(input, &conf_type);
rpc_log_info("config type is %d\n", conf_type);
switch(conf_type) {
case FREEAUTH_CONFIG_ADD:
ret = freeauth_config_add_proc(source, conf_type,
input, input_len,
output, output_len);
break;
case FREEAUTH_CONFIG_MOD:
ret = freeauth_config_mod_proc(source, conf_type,
input, input_len,
output, output_len);
break;
case FREEAUTH_CONFIG_DEL:
ret = freeauth_config_del_proc(source, conf_type,
input, input_len,
output, output_len);
break;
default:
ret = RET_NOTSUPPORT;
}
return RET_OK;
}