TSG-14628 TFE适配TCP Option Profile库表的变更
This commit is contained in:
@@ -36,6 +36,7 @@ option(ENABLE_PLUGIN_DOH "Enable Doh business" TRUE)
|
|||||||
option(ENABLE_PLUGIN_PANGU_HTTP "Enable Pangu-HTTP business" TRUE)
|
option(ENABLE_PLUGIN_PANGU_HTTP "Enable Pangu-HTTP business" TRUE)
|
||||||
option(ENABLE_PLUGIN_HTTP2 "Enable HTTP2 business" TRUE)
|
option(ENABLE_PLUGIN_HTTP2 "Enable HTTP2 business" TRUE)
|
||||||
option(ENABLE_PLUGIN_SSL_POLICY "Enable SSL policy support" TRUE)
|
option(ENABLE_PLUGIN_SSL_POLICY "Enable SSL policy support" TRUE)
|
||||||
|
option(ENABLE_PLUGIN_TCP_POLICY "Enable TCP policy support" TRUE)
|
||||||
|
|
||||||
if(ENABLE_PIC)
|
if(ENABLE_PIC)
|
||||||
set(CMAKE_POSITION_INDEPENDENT_CODE 1)
|
set(CMAKE_POSITION_INDEPENDENT_CODE 1)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ extern "C"
|
|||||||
struct raw_socket
|
struct raw_socket
|
||||||
{
|
{
|
||||||
int sockfd;
|
int sockfd;
|
||||||
char interface[64];
|
char interface[16];
|
||||||
struct ether_addr mac_addr;
|
struct ether_addr mac_addr;
|
||||||
struct sockaddr_ll sockaddr;
|
struct sockaddr_ll sockaddr;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ typedef enum ssl_stream_action ssl_stream_new_hook(struct ssl_stream *upstream,
|
|||||||
|
|
||||||
enum SSL_STREAM_OPT
|
enum SSL_STREAM_OPT
|
||||||
{
|
{
|
||||||
SSL_STREAM_OPT_INTERCEPT_POLICY_ID,
|
|
||||||
SSL_STREAM_OPT_IS_EV_CERT, //0:FALSE, 1:TRUE.
|
SSL_STREAM_OPT_IS_EV_CERT, //0:FALSE, 1:TRUE.
|
||||||
SSL_STREAM_OPT_IS_CT_CERT, //0:FALSE, 1:TRUE.
|
SSL_STREAM_OPT_IS_CT_CERT, //0:FALSE, 1:TRUE.
|
||||||
SSL_STREAM_OPT_IS_MUTUAL_AUTH, //0:FALSE, 1:TRUE.
|
SSL_STREAM_OPT_IS_MUTUAL_AUTH, //0:FALSE, 1:TRUE.
|
||||||
@@ -47,6 +46,7 @@ int ssl_stream_get_integer_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT
|
|||||||
int ssl_stream_get_string_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT opt_type, char* in_buff, size_t sz);
|
int ssl_stream_get_string_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT opt_type, char* in_buff, size_t sz);
|
||||||
|
|
||||||
void ssl_stream_set_cmsg_string(struct ssl_stream *stream, enum tfe_cmsg_tlv_type type, const char *value_str);
|
void ssl_stream_set_cmsg_string(struct ssl_stream *stream, enum tfe_cmsg_tlv_type type, const char *value_str);
|
||||||
|
uint64_t ssl_stream_get_policy_id(struct ssl_stream *upstream);
|
||||||
|
|
||||||
unsigned int is_ssl_debug();
|
unsigned int is_ssl_debug();
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
struct tfe_cmsg;
|
struct tfe_cmsg;
|
||||||
struct tfe_cmsg_serialize_header;
|
struct tfe_cmsg_serialize_header;
|
||||||
@@ -33,7 +34,7 @@ enum tfe_cmsg_tlv_type
|
|||||||
TFE_CMSG_TCP_RESTORE_TS_CLIENT_VAL = 0xe,
|
TFE_CMSG_TCP_RESTORE_TS_CLIENT_VAL = 0xe,
|
||||||
TFE_CMSG_TCP_RESTORE_TS_SERVER_VAL = 0xf,
|
TFE_CMSG_TCP_RESTORE_TS_SERVER_VAL = 0xf,
|
||||||
|
|
||||||
TFE_CMSG_POLICY_ID = 0x10,
|
TFE_CMSG_POLICY_ID = 0x10, // size uint64_t
|
||||||
TFE_CMSG_STREAM_TRACE_ID = 0x11,
|
TFE_CMSG_STREAM_TRACE_ID = 0x11,
|
||||||
|
|
||||||
TFE_CMSG_SSL_INTERCEPT_STATE, //size uint64_t, 0-passthrough, 1-intercept, 2-shutdown, referer from enum ssl_stream_action
|
TFE_CMSG_SSL_INTERCEPT_STATE, //size uint64_t, 0-passthrough, 1-intercept, 2-shutdown, referer from enum ssl_stream_action
|
||||||
@@ -50,6 +51,8 @@ enum tfe_cmsg_tlv_type
|
|||||||
TFE_CMSG_DST_MAC,
|
TFE_CMSG_DST_MAC,
|
||||||
|
|
||||||
/* TCP option information */
|
/* TCP option information */
|
||||||
|
TFE_CMSG_DOWNSTREAM_TCP_MSS_ENABLE,
|
||||||
|
TFE_CMSG_DOWNSTREAM_TCP_MSS_VALUE,
|
||||||
TFE_CMSG_DOWNSTREAM_TCP_NODELAY,
|
TFE_CMSG_DOWNSTREAM_TCP_NODELAY,
|
||||||
TFE_CMSG_DOWNSTREAM_TCP_TTL,
|
TFE_CMSG_DOWNSTREAM_TCP_TTL,
|
||||||
TFE_CMSG_DOWNSTREAM_TCP_KEEPALIVE,
|
TFE_CMSG_DOWNSTREAM_TCP_KEEPALIVE,
|
||||||
@@ -58,6 +61,8 @@ enum tfe_cmsg_tlv_type
|
|||||||
TFE_CMSG_DOWNSTREAM_TCP_KEEPINTVL,
|
TFE_CMSG_DOWNSTREAM_TCP_KEEPINTVL,
|
||||||
TFE_CMSG_DOWNSTREAM_TCP_USER_TIMEOUT,
|
TFE_CMSG_DOWNSTREAM_TCP_USER_TIMEOUT,
|
||||||
|
|
||||||
|
TFE_CMSG_UPSTREAM_TCP_MSS_ENABLE,
|
||||||
|
TFE_CMSG_UPSTREAM_TCP_MSS_VALUE,
|
||||||
TFE_CMSG_UPSTREAM_TCP_NODELAY,
|
TFE_CMSG_UPSTREAM_TCP_NODELAY,
|
||||||
TFE_CMSG_UPSTREAM_TCP_TTL,
|
TFE_CMSG_UPSTREAM_TCP_TTL,
|
||||||
TFE_CMSG_UPSTREAM_TCP_KEEPALIVE,
|
TFE_CMSG_UPSTREAM_TCP_KEEPALIVE,
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ int tfe_scan_ip_location(const struct tfe_stream *stream, long long *result, str
|
|||||||
int hit_cnt_ip = 0;
|
int hit_cnt_ip = 0;
|
||||||
size_t n_hit_result = 0;
|
size_t n_hit_result = 0;
|
||||||
uint16_t opt_out_size;
|
uint16_t opt_out_size;
|
||||||
char buff[TFE_STRING_MAX] = {0};
|
char buff[TFE_STRING_MAX * 5] = {0};
|
||||||
char src_city[TFE_STRING_MAX] = {0};
|
char src_city[TFE_STRING_MAX] = {0};
|
||||||
char dst_city[TFE_STRING_MAX] = {0};
|
char dst_city[TFE_STRING_MAX] = {0};
|
||||||
char src_provine[TFE_STRING_MAX] = {0};
|
char src_provine[TFE_STRING_MAX] = {0};
|
||||||
@@ -255,7 +255,7 @@ int tfe_scan_ip_asn(const struct tfe_stream *stream, long long *result, struct m
|
|||||||
int hit_cnt_ip = 0;
|
int hit_cnt_ip = 0;
|
||||||
size_t n_hit_result = 0;
|
size_t n_hit_result = 0;
|
||||||
uint16_t opt_out_size;
|
uint16_t opt_out_size;
|
||||||
char buff[TFE_STRING_MAX] = {0};
|
char buff[TFE_STRING_MAX * 5] = {0};
|
||||||
char src_asn[TFE_STRING_MAX] = {0};
|
char src_asn[TFE_STRING_MAX] = {0};
|
||||||
char dst_asn[TFE_STRING_MAX] = {0};
|
char dst_asn[TFE_STRING_MAX] = {0};
|
||||||
char src_org[TFE_STRING_MAX] = {0};
|
char src_org[TFE_STRING_MAX] = {0};
|
||||||
|
|||||||
@@ -48,6 +48,10 @@ if(ENABLE_PLUGIN_SSL_POLICY)
|
|||||||
target_link_libraries(tfe -Wl,--whole-archive ssl-policy -Wl,--no-whole-archive)
|
target_link_libraries(tfe -Wl,--whole-archive ssl-policy -Wl,--no-whole-archive)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(ENABLE_PLUGIN_TCP_POLICY)
|
||||||
|
target_link_libraries(tfe -Wl,--whole-archive tcp-policy -Wl,--no-whole-archive)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(ENABLE_PLUGIN_TRAFFIC_MIRROR)
|
if(ENABLE_PLUGIN_TRAFFIC_MIRROR)
|
||||||
target_link_libraries(tfe -Wl,--whole-archive traffic-mirror -Wl,--no-whole-archive)
|
target_link_libraries(tfe -Wl,--whole-archive traffic-mirror -Wl,--no-whole-archive)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -130,7 +130,8 @@ struct tfe_proxy
|
|||||||
struct tfe_plugin * modules;
|
struct tfe_plugin * modules;
|
||||||
|
|
||||||
struct ssl_mgr * ssl_mgr_handler;
|
struct ssl_mgr * ssl_mgr_handler;
|
||||||
struct ssl_policy_enforcer* ssl_ply_enforcer;
|
struct tcp_policy_enforcer *tcp_ply_enforcer;
|
||||||
|
struct ssl_policy_enforcer *ssl_ply_enforcer;
|
||||||
struct key_keeper * key_keeper_handler;
|
struct key_keeper * key_keeper_handler;
|
||||||
|
|
||||||
unsigned int en_kni_v1_acceptor;
|
unsigned int en_kni_v1_acceptor;
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
#define TCP_RESTORE_TCPOPT_KIND 88
|
#define TCP_RESTORE_TCPOPT_KIND 88
|
||||||
|
|
||||||
|
extern void tcp_policy_enforce(struct tcp_policy_enforcer *enforcer, struct tfe_cmsg *cmsg, uint64_t rule_id);
|
||||||
|
|
||||||
struct acceptor_kni_v3
|
struct acceptor_kni_v3
|
||||||
{
|
{
|
||||||
struct tfe_proxy *proxy;
|
struct tfe_proxy *proxy;
|
||||||
@@ -529,6 +531,51 @@ static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int overwrite_tcp_mss(struct tfe_cmsg *cmsg, struct tcp_restore_info *restore)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
uint16_t size = 0;
|
||||||
|
int server_side_mss_enable = 0;
|
||||||
|
int server_side_mss_value = 0;
|
||||||
|
int client_side_mss_enable = 0;
|
||||||
|
int client_side_mss_value = 0;
|
||||||
|
|
||||||
|
ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_DOWNSTREAM_TCP_MSS_ENABLE, (unsigned char *)&client_side_mss_enable, sizeof(client_side_mss_enable), &size);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
TFE_LOG_ERROR(g_default_logger, "failed at fetch client side tcp mss from cmsg: %s", strerror(-ret));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_DOWNSTREAM_TCP_MSS_VALUE, (unsigned char *)&client_side_mss_value, sizeof(client_side_mss_value), &size);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
TFE_LOG_ERROR(g_default_logger, "failed at fetch client side tcp mss value from cmsg: %s", strerror(-ret));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_UPSTREAM_TCP_MSS_ENABLE, (unsigned char *)&server_side_mss_enable, sizeof(server_side_mss_enable), &size);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
TFE_LOG_ERROR(g_default_logger, "failed at fetch server side tcp mss from cmsg: %s", strerror(-ret));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_UPSTREAM_TCP_MSS_VALUE, (unsigned char *)&server_side_mss_value, sizeof(server_side_mss_value), &size);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
TFE_LOG_ERROR(g_default_logger, "failed at fetch server side tcp mss value from cmsg: %s", strerror(-ret));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (client_side_mss_enable)
|
||||||
|
{
|
||||||
|
restore->client.mss = client_side_mss_value;
|
||||||
|
}
|
||||||
|
if (server_side_mss_enable)
|
||||||
|
{
|
||||||
|
restore->server.mss = server_side_mss_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nfmsg : message objetc that contains the packet
|
* nfmsg : message objetc that contains the packet
|
||||||
* nfad : Netlink packet data handle
|
* nfad : Netlink packet data handle
|
||||||
@@ -555,6 +602,7 @@ static int payload_handler_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, s
|
|||||||
struct tcp_restore_info restore_info;
|
struct tcp_restore_info restore_info;
|
||||||
uint8_t stream_protocol_in_char = 0;
|
uint8_t stream_protocol_in_char = 0;
|
||||||
uint16_t size = 0;
|
uint16_t size = 0;
|
||||||
|
uint64_t rule_id = 0;
|
||||||
struct acceptor_kni_v3 *__ctx = (struct acceptor_kni_v3 *)data;
|
struct acceptor_kni_v3 *__ctx = (struct acceptor_kni_v3 *)data;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &(__ctx->start));
|
clock_gettime(CLOCK_MONOTONIC, &(__ctx->start));
|
||||||
memset(&pktinfo, 0, sizeof(pktinfo));
|
memset(&pktinfo, 0, sizeof(pktinfo));
|
||||||
@@ -659,6 +707,25 @@ static int payload_handler_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, s
|
|||||||
pktinfo.tcphdr->check = tfe_pkt_checksum_tcp_v6((void*)pktinfo.tcphdr, pktinfo.ip_totlen - pktinfo.iphdr_len, pktinfo.iphdr.v6->ip6_src, pktinfo.iphdr.v6->ip6_dst);
|
pktinfo.tcphdr->check = tfe_pkt_checksum_tcp_v6((void*)pktinfo.tcphdr, pktinfo.ip_totlen - pktinfo.iphdr_len, pktinfo.iphdr.v6->ip6_src, pktinfo.iphdr.v6->ip6_dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tfe_cmsg_deserialize((const unsigned char *)restore_info.cmsg, restore_info.cmsg_len, &cmsg) < 0)
|
||||||
|
{
|
||||||
|
TFE_LOG_ERROR(g_default_logger, "failed at tfe_cmsg_deserialize()");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_POLICY_ID, (unsigned char *)&rule_id, sizeof(rule_id), &size);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
TFE_LOG_ERROR(g_default_logger, "failed at fetch rule_id from cmsg: %s", strerror(-ret));
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
tcp_policy_enforce(__ctx->proxy->tcp_ply_enforcer, cmsg, rule_id);
|
||||||
|
|
||||||
|
if (overwrite_tcp_mss(cmsg, &restore_info))
|
||||||
|
{
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
tfe_tcp_restore_info_dump(&restore_info);
|
tfe_tcp_restore_info_dump(&restore_info);
|
||||||
|
|
||||||
// tcp repair C2S
|
// tcp repair C2S
|
||||||
@@ -677,12 +744,6 @@ static int payload_handler_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, s
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tfe_cmsg_deserialize((const unsigned char *)restore_info.cmsg, restore_info.cmsg_len, &cmsg) < 0)
|
|
||||||
{
|
|
||||||
TFE_LOG_ERROR(g_default_logger, "Failed at tfe_cmsg_deserialize()");
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_PROTOCOL, (unsigned char *)&stream_protocol_in_char, sizeof(stream_protocol_in_char), &size);
|
tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_PROTOCOL, (unsigned char *)&stream_protocol_in_char, sizeof(stream_protocol_in_char), &size);
|
||||||
if (steering_device_is_available() && (
|
if (steering_device_is_available() && (
|
||||||
(STREAM_PROTO_PLAIN == (enum tfe_stream_proto)stream_protocol_in_char && __ctx->proxy->traffic_steering_options.enable_steering_http) ||
|
(STREAM_PROTO_PLAIN == (enum tfe_stream_proto)stream_protocol_in_char && __ctx->proxy->traffic_steering_options.enable_steering_http) ||
|
||||||
|
|||||||
@@ -61,6 +61,7 @@
|
|||||||
extern struct ssl_policy_enforcer* ssl_policy_enforcer_create(void* logger);
|
extern struct ssl_policy_enforcer* ssl_policy_enforcer_create(void* logger);
|
||||||
extern enum ssl_stream_action ssl_policy_enforce(struct ssl_stream *upstream, void* u_para);
|
extern enum ssl_stream_action ssl_policy_enforce(struct ssl_stream *upstream, void* u_para);
|
||||||
|
|
||||||
|
extern struct tcp_policy_enforcer *tcp_policy_enforcer_create(void *logger);
|
||||||
static int signals[] = {SIGHUP, SIGPIPE, SIGUSR1, SIGUSR2};
|
static int signals[] = {SIGHUP, SIGPIPE, SIGUSR1, SIGUSR2};
|
||||||
|
|
||||||
/* Global Resource */
|
/* Global Resource */
|
||||||
@@ -165,17 +166,16 @@ int tfe_proxy_fds_accept(struct tfe_proxy *ctx, int fd_downstream, int fd_upstre
|
|||||||
uint8_t stream_protocol_in_char = 0;
|
uint8_t stream_protocol_in_char = 0;
|
||||||
int tcp_passthrough = -1;
|
int tcp_passthrough = -1;
|
||||||
uint16_t size = 0;
|
uint16_t size = 0;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
int result = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_PROTOCOL, (unsigned char *)&stream_protocol_in_char,
|
result = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_PROTOCOL, (unsigned char *)&stream_protocol_in_char, sizeof(stream_protocol_in_char), &size);
|
||||||
sizeof(stream_protocol_in_char), &size);
|
|
||||||
|
|
||||||
if (unlikely(result < 0))
|
if (unlikely(result < 0))
|
||||||
{
|
{
|
||||||
TFE_LOG_ERROR(ctx->logger, "failed at fetch connection's protocol from cmsg: %s", strerror(-result));
|
TFE_LOG_ERROR(ctx->logger, "failed at fetch connection's protocol from cmsg: %s", strerror(-result));
|
||||||
goto __errout;
|
goto __errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream_protocol = (enum tfe_stream_proto)stream_protocol_in_char;
|
stream_protocol = (enum tfe_stream_proto)stream_protocol_in_char;
|
||||||
tfe_stream_option_set(stream, TFE_STREAM_OPT_SESSION_TYPE, &stream_protocol, sizeof(stream_protocol));
|
tfe_stream_option_set(stream, TFE_STREAM_OPT_SESSION_TYPE, &stream_protocol, sizeof(stream_protocol));
|
||||||
tfe_stream_cmsg_setup(stream, cmsg);
|
tfe_stream_cmsg_setup(stream, cmsg);
|
||||||
|
|
||||||
@@ -697,7 +697,12 @@ int main(int argc, char * argv[])
|
|||||||
TFE_LOG_INFO(g_default_logger, "Plugin %s initialized. ", plugin_iter->symbol);
|
TFE_LOG_INFO(g_default_logger, "Plugin %s initialized. ", plugin_iter->symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_default_proxy->ssl_ply_enforcer=ssl_policy_enforcer_create(g_default_logger);
|
g_default_proxy->tcp_ply_enforcer = tcp_policy_enforcer_create(g_default_logger);
|
||||||
|
CHECK_OR_EXIT(g_default_proxy->tcp_ply_enforcer == NULL, "Failed at creating tcp policy enforcer. Exit.");
|
||||||
|
|
||||||
|
g_default_proxy->ssl_ply_enforcer = ssl_policy_enforcer_create(g_default_logger);
|
||||||
|
CHECK_OR_EXIT(g_default_proxy->ssl_ply_enforcer == NULL, "Failed at creating ssl policy enforcer. Exit.");
|
||||||
|
|
||||||
ssl_manager_set_new_upstream_cb(g_default_proxy->ssl_mgr_handler, ssl_policy_enforce, g_default_proxy->ssl_ply_enforcer);
|
ssl_manager_set_new_upstream_cb(g_default_proxy->ssl_mgr_handler, ssl_policy_enforce, g_default_proxy->ssl_ply_enforcer);
|
||||||
ret = tfe_proxy_work_thread_run(g_default_proxy);
|
ret = tfe_proxy_work_thread_run(g_default_proxy);
|
||||||
CHECK_OR_EXIT(ret == 0, "Failed at creating thread. Exit.");
|
CHECK_OR_EXIT(ret == 0, "Failed at creating thread. Exit.");
|
||||||
|
|||||||
@@ -2180,9 +2180,7 @@ int ssl_stream_set_integer_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT
|
|||||||
int ssl_stream_get_integer_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT opt_type, int *opt_val)
|
int ssl_stream_get_integer_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT opt_type, int *opt_val)
|
||||||
{
|
{
|
||||||
struct ssl_service_status* svc=&upstream->up_parts.svc_status;
|
struct ssl_service_status* svc=&upstream->up_parts.svc_status;
|
||||||
struct tfe_cmsg *cmsg=NULL;
|
|
||||||
UNUSED int ret=0;
|
UNUSED int ret=0;
|
||||||
uint16_t out_size=0;
|
|
||||||
switch(opt_type)
|
switch(opt_type)
|
||||||
{
|
{
|
||||||
case SSL_STREAM_OPT_IS_EV_CERT:
|
case SSL_STREAM_OPT_IS_EV_CERT:
|
||||||
@@ -2203,18 +2201,24 @@ int ssl_stream_get_integer_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT
|
|||||||
case SSL_STREAM_OPT_HAS_PROTOCOL_ERRORS:
|
case SSL_STREAM_OPT_HAS_PROTOCOL_ERRORS:
|
||||||
*opt_val=svc->has_protocol_errors;
|
*opt_val=svc->has_protocol_errors;
|
||||||
break;
|
break;
|
||||||
case SSL_STREAM_OPT_INTERCEPT_POLICY_ID:
|
|
||||||
cmsg=tfe_stream_get0_cmsg(upstream->tcp_stream);
|
|
||||||
ret=tfe_cmsg_get_value(cmsg, TFE_CMSG_POLICY_ID, (unsigned char*)opt_val, sizeof(*opt_val), &out_size);
|
|
||||||
assert(ret==0);
|
|
||||||
assert(out_size==sizeof(*opt_val));
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t ssl_stream_get_policy_id(struct ssl_stream *upstream)
|
||||||
|
{
|
||||||
|
uint16_t out_size;
|
||||||
|
uint64_t policy_id = 0;
|
||||||
|
struct tfe_cmsg *cmsg = tfe_stream_get0_cmsg(upstream->tcp_stream);
|
||||||
|
int ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_POLICY_ID, (unsigned char *)policy_id, sizeof(policy_id), &out_size);
|
||||||
|
assert(ret == 0);
|
||||||
|
|
||||||
|
return policy_id;
|
||||||
|
}
|
||||||
|
|
||||||
int ssl_stream_get_string_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT opt_type, char* in_buff, size_t sz)
|
int ssl_stream_get_string_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT opt_type, char* in_buff, size_t sz)
|
||||||
{
|
{
|
||||||
const char* sni=upstream->up_parts.client_hello->sni?upstream->up_parts.client_hello->sni:"null";
|
const char* sni=upstream->up_parts.client_hello->sni?upstream->up_parts.client_hello->sni:"null";
|
||||||
|
|||||||
@@ -2,3 +2,4 @@ add_subdirectory(traffic-mirror)
|
|||||||
add_subdirectory(doh)
|
add_subdirectory(doh)
|
||||||
add_subdirectory(tsg-http)
|
add_subdirectory(tsg-http)
|
||||||
add_subdirectory(ssl-policy)
|
add_subdirectory(ssl-policy)
|
||||||
|
add_subdirectory(tcp-policy)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ struct ssl_policy_enforcer
|
|||||||
};
|
};
|
||||||
struct intercept_param
|
struct intercept_param
|
||||||
{
|
{
|
||||||
int policy_id;
|
uint64_t policy_id;
|
||||||
int ref_cnt;
|
int ref_cnt;
|
||||||
int keyring_for_trusted;
|
int keyring_for_trusted;
|
||||||
int keyring_for_untrusted;
|
int keyring_for_untrusted;
|
||||||
@@ -94,7 +94,7 @@ void intercept_param_new_cb(const char *table_name, int table_id, const char* ke
|
|||||||
}
|
}
|
||||||
|
|
||||||
param=ALLOC(struct intercept_param, 1);
|
param=ALLOC(struct intercept_param, 1);
|
||||||
param->policy_id=atoi(key);
|
param->policy_id=atoll(key);
|
||||||
param->ref_cnt=1;
|
param->ref_cnt=1;
|
||||||
/*
|
/*
|
||||||
param->bypass_mutual_auth=1;
|
param->bypass_mutual_auth=1;
|
||||||
@@ -118,7 +118,7 @@ void intercept_param_new_cb(const char *table_name, int table_id, const char* ke
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TFE_LOG_ERROR(enforcer->logger, "Invalid intercept parameter: %d invalid keyring_for_trusted format", param->policy_id);
|
TFE_LOG_ERROR(enforcer->logger, "Invalid intercept parameter: %lu invalid keyring_for_trusted format", param->policy_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@ void intercept_param_new_cb(const char *table_name, int table_id, const char* ke
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TFE_LOG_ERROR(enforcer->logger, "Invalid intercept parameter: %d invalid keyring_for_untrusted format", param->policy_id);
|
TFE_LOG_ERROR(enforcer->logger, "Invalid intercept parameter: %lu invalid keyring_for_untrusted format", param->policy_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,11 +152,11 @@ void intercept_param_new_cb(const char *table_name, int table_id, const char* ke
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TFE_LOG_ERROR(enforcer->logger, "Invalid intercept parameter:%d invalid decryption format", param->policy_id);
|
TFE_LOG_ERROR(enforcer->logger, "Invalid intercept parameter: %lu invalid decryption format", param->policy_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*ad=param;
|
*ad=param;
|
||||||
TFE_LOG_INFO(enforcer->logger, "Add intercept policy: %d", param->policy_id);
|
TFE_LOG_INFO(enforcer->logger, "Add intercept policy: %lu", param->policy_id);
|
||||||
error_out:
|
error_out:
|
||||||
cJSON_Delete(json);
|
cJSON_Delete(json);
|
||||||
free(json_str);
|
free(json_str);
|
||||||
@@ -173,7 +173,7 @@ void intercept_param_free_cb(int table_id, void **ad, long argl, void* argp)
|
|||||||
|
|
||||||
if ((__sync_sub_and_fetch(¶m->ref_cnt, 1) == 0))
|
if ((__sync_sub_and_fetch(¶m->ref_cnt, 1) == 0))
|
||||||
{
|
{
|
||||||
TFE_LOG_INFO(enforcer->logger, "Del intercept policy %d", param->policy_id);\
|
TFE_LOG_INFO(enforcer->logger, "Del intercept policy %lu", param->policy_id);
|
||||||
free(param);
|
free(param);
|
||||||
*ad=NULL;
|
*ad=NULL;
|
||||||
}
|
}
|
||||||
@@ -351,17 +351,16 @@ enum ssl_stream_action ssl_policy_enforce(struct ssl_stream *upstream, void* u_p
|
|||||||
struct decryption_param *profile_param=NULL;
|
struct decryption_param *profile_param=NULL;
|
||||||
enum ssl_stream_action action=SSL_ACTION_PASSTHROUGH;
|
enum ssl_stream_action action=SSL_ACTION_PASSTHROUGH;
|
||||||
UNUSED int ret=0;
|
UNUSED int ret=0;
|
||||||
int policy_id=0;
|
uint64_t policy_id=0;
|
||||||
char policy_id_str[16]={0};
|
char policy_id_str[16]={0};
|
||||||
char profile_id_str[16]={0};
|
char profile_id_str[16]={0};
|
||||||
char sni[512], addr_string[512];
|
char sni[512], addr_string[512];
|
||||||
ret=ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_INTERCEPT_POLICY_ID, &policy_id);
|
policy_id = ssl_stream_get_policy_id(upstream);
|
||||||
assert(ret==0);
|
snprintf(policy_id_str, sizeof(policy_id_str), "%lu", policy_id);
|
||||||
snprintf(policy_id_str, sizeof(policy_id_str), "%d", policy_id);
|
|
||||||
policy_param=(struct intercept_param *)maat_plugin_table_get_ex_data(enforcer->maat, enforcer->policy_table_id, policy_id_str);
|
policy_param=(struct intercept_param *)maat_plugin_table_get_ex_data(enforcer->maat, enforcer->policy_table_id, policy_id_str);
|
||||||
if(policy_param==NULL)
|
if(policy_param==NULL)
|
||||||
{
|
{
|
||||||
TFE_LOG_INFO(enforcer->logger, "Failed to get intercept parameter of policy %d.", policy_id);
|
TFE_LOG_INFO(enforcer->logger, "Failed to get intercept parameter of policy %lu.", policy_id);
|
||||||
ssl_stream_set_cmsg_string(upstream, TFE_CMSG_SSL_PASSTHROUGH_REASON, "Invalid Intercept Param");
|
ssl_stream_set_cmsg_string(upstream, TFE_CMSG_SSL_PASSTHROUGH_REASON, "Invalid Intercept Param");
|
||||||
return SSL_ACTION_PASSTHROUGH;
|
return SSL_ACTION_PASSTHROUGH;
|
||||||
}
|
}
|
||||||
@@ -369,7 +368,7 @@ enum ssl_stream_action ssl_policy_enforce(struct ssl_stream *upstream, void* u_p
|
|||||||
{
|
{
|
||||||
ssl_stream_get_string_opt(upstream, SSL_STREAM_OPT_SNI, sni, sizeof(sni));
|
ssl_stream_get_string_opt(upstream, SSL_STREAM_OPT_SNI, sni, sizeof(sni));
|
||||||
ssl_stream_get_string_opt(upstream, SSL_STREAM_OPT_ADDR, addr_string, sizeof(addr_string));
|
ssl_stream_get_string_opt(upstream, SSL_STREAM_OPT_ADDR, addr_string, sizeof(addr_string));
|
||||||
TFE_LOG_DEBUG(enforcer->logger, "%s %s enforce policy %d", addr_string, sni, policy_id);
|
TFE_LOG_DEBUG(enforcer->logger, "%s %s enforce policy %lu", addr_string, sni, policy_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(profile_id_str, sizeof(profile_id_str), "%u", policy_param->decryption_profile_id);
|
snprintf(profile_id_str, sizeof(profile_id_str), "%u", policy_param->decryption_profile_id);
|
||||||
@@ -416,37 +415,37 @@ enum ssl_stream_action ssl_policy_enforce(struct ssl_stream *upstream, void* u_p
|
|||||||
{
|
{
|
||||||
action = SSL_ACTION_PASSTHROUGH;
|
action = SSL_ACTION_PASSTHROUGH;
|
||||||
ssl_stream_set_cmsg_string(upstream, TFE_CMSG_SSL_PASSTHROUGH_REASON, "Certificate Not Installed");
|
ssl_stream_set_cmsg_string(upstream, TFE_CMSG_SSL_PASSTHROUGH_REASON, "Certificate Not Installed");
|
||||||
TFE_LOG_DEBUG(enforcer->logger, "%s %s enforce policy_id %d, action PASSTHROUGH due to Certificate Not Installed", addr_string, sni, policy_param->policy_id);
|
TFE_LOG_DEBUG(enforcer->logger, "%s %s enforce policy_id %lu, action PASSTHROUGH due to Certificate Not Installed", addr_string, sni, policy_param->policy_id);
|
||||||
}
|
}
|
||||||
else if ((pinning_staus == 1 || ja3_pinning_status == JA3_PINNING_STATUS_IS_PINNING) && ja3_pinning_status != JA3_PINNING_STATUS_NOT_PINNING && profile_param->bypass_pinning)
|
else if ((pinning_staus == 1 || ja3_pinning_status == JA3_PINNING_STATUS_IS_PINNING) && ja3_pinning_status != JA3_PINNING_STATUS_NOT_PINNING && profile_param->bypass_pinning)
|
||||||
{
|
{
|
||||||
action = SSL_ACTION_PASSTHROUGH;
|
action = SSL_ACTION_PASSTHROUGH;
|
||||||
ssl_stream_set_cmsg_string(upstream, TFE_CMSG_SSL_PASSTHROUGH_REASON, "Certificate Pinning");
|
ssl_stream_set_cmsg_string(upstream, TFE_CMSG_SSL_PASSTHROUGH_REASON, "Certificate Pinning");
|
||||||
TFE_LOG_DEBUG(enforcer->logger, "%s %s enforce policy_id %d, action PASSTHROUGH due to Certificate Pinning", addr_string, sni, policy_param->policy_id);
|
TFE_LOG_DEBUG(enforcer->logger, "%s %s enforce policy_id %lu, action PASSTHROUGH due to Certificate Pinning", addr_string, sni, policy_param->policy_id);
|
||||||
}
|
}
|
||||||
else if (is_mauth && profile_param->bypass_mutual_auth)
|
else if (is_mauth && profile_param->bypass_mutual_auth)
|
||||||
{
|
{
|
||||||
action = SSL_ACTION_PASSTHROUGH;
|
action = SSL_ACTION_PASSTHROUGH;
|
||||||
ssl_stream_set_cmsg_string(upstream, TFE_CMSG_SSL_PASSTHROUGH_REASON, "Mutual Authentication");
|
ssl_stream_set_cmsg_string(upstream, TFE_CMSG_SSL_PASSTHROUGH_REASON, "Mutual Authentication");
|
||||||
TFE_LOG_DEBUG(enforcer->logger, "%s %s enforce policy_id %d, action PASSTHROUGH due to Mutual Authentication", addr_string, sni, policy_param->policy_id);
|
TFE_LOG_DEBUG(enforcer->logger, "%s %s enforce policy_id %lu, action PASSTHROUGH due to Mutual Authentication", addr_string, sni, policy_param->policy_id);
|
||||||
}
|
}
|
||||||
else if (is_ev && profile_param->bypass_ev_cert)
|
else if (is_ev && profile_param->bypass_ev_cert)
|
||||||
{
|
{
|
||||||
action = SSL_ACTION_PASSTHROUGH;
|
action = SSL_ACTION_PASSTHROUGH;
|
||||||
ssl_stream_set_cmsg_string(upstream, TFE_CMSG_SSL_PASSTHROUGH_REASON, "EV Certificate");
|
ssl_stream_set_cmsg_string(upstream, TFE_CMSG_SSL_PASSTHROUGH_REASON, "EV Certificate");
|
||||||
TFE_LOG_DEBUG(enforcer->logger, "%s %s enforce policy_id %d, action PASSTHROUGH due to EV Certificate", addr_string, sni, policy_param->policy_id);
|
TFE_LOG_DEBUG(enforcer->logger, "%s %s enforce policy_id %lu, action PASSTHROUGH due to EV Certificate", addr_string, sni, policy_param->policy_id);
|
||||||
}
|
}
|
||||||
else if (is_ct && profile_param->bypass_ct_cert)
|
else if (is_ct && profile_param->bypass_ct_cert)
|
||||||
{
|
{
|
||||||
action = SSL_ACTION_PASSTHROUGH;
|
action = SSL_ACTION_PASSTHROUGH;
|
||||||
ssl_stream_set_cmsg_string(upstream, TFE_CMSG_SSL_PASSTHROUGH_REASON, "Certificate Transparency");
|
ssl_stream_set_cmsg_string(upstream, TFE_CMSG_SSL_PASSTHROUGH_REASON, "Certificate Transparency");
|
||||||
TFE_LOG_DEBUG(enforcer->logger, "%s %s enforce policy_id %d, action PASSTHROUGH due to Certificate Transparency", addr_string, sni, policy_param->policy_id);
|
TFE_LOG_DEBUG(enforcer->logger, "%s %s enforce policy_id %lu, action PASSTHROUGH due to Certificate Transparency", addr_string, sni, policy_param->policy_id);
|
||||||
}
|
}
|
||||||
else if (has_error && profile_param->bypass_protocol_errors)
|
else if (has_error && profile_param->bypass_protocol_errors)
|
||||||
{
|
{
|
||||||
action = SSL_ACTION_PASSTHROUGH;
|
action = SSL_ACTION_PASSTHROUGH;
|
||||||
ssl_stream_set_cmsg_string(upstream, TFE_CMSG_SSL_PASSTHROUGH_REASON, "Protocol Errors");
|
ssl_stream_set_cmsg_string(upstream, TFE_CMSG_SSL_PASSTHROUGH_REASON, "Protocol Errors");
|
||||||
TFE_LOG_DEBUG(enforcer->logger, "%s %s enforce policy_id %d, action PASSTHROUGH due to Protocol Errors", addr_string, sni, policy_param->policy_id);
|
TFE_LOG_DEBUG(enforcer->logger, "%s %s enforce policy_id %lu, action PASSTHROUGH due to Protocol Errors", addr_string, sni, policy_param->policy_id);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
4
plugin/business/tcp-policy/CMakeLists.txt
Normal file
4
plugin/business/tcp-policy/CMakeLists.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
add_library(tcp-policy src/tcp_policy.cpp)
|
||||||
|
target_link_libraries(tcp-policy PUBLIC common)
|
||||||
|
target_link_libraries(tcp-policy PUBLIC cjson)
|
||||||
|
target_link_libraries(tcp-policy PUBLIC maatframe)
|
||||||
400
plugin/business/tcp-policy/src/tcp_policy.cpp
Normal file
400
plugin/business/tcp-policy/src/tcp_policy.cpp
Normal file
@@ -0,0 +1,400 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <tfe_cmsg.h>
|
||||||
|
#include <tfe_utils.h>
|
||||||
|
#include <tfe_stream.h>
|
||||||
|
#include <tfe_resource.h>
|
||||||
|
#include <cjson/cJSON.h>
|
||||||
|
#include <MESA/maat.h>
|
||||||
|
|
||||||
|
#include "tcp_policy.h"
|
||||||
|
|
||||||
|
struct tcp_policy_enforcer
|
||||||
|
{
|
||||||
|
struct maat *maat;
|
||||||
|
int policy_table_id;
|
||||||
|
int profile_table_id;
|
||||||
|
void *logger;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct side_conn_param
|
||||||
|
{
|
||||||
|
int maxseg_enable;
|
||||||
|
int maxseg_vaule;
|
||||||
|
int nodelay;
|
||||||
|
int keepalive;
|
||||||
|
int keepcnt;
|
||||||
|
int keepidle;
|
||||||
|
int keepintvl;
|
||||||
|
int ttl;
|
||||||
|
int user_timeout;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tcp_profile_param
|
||||||
|
{
|
||||||
|
int ref_cnt;
|
||||||
|
int tcp_passthrough;
|
||||||
|
int bypass_duplicated_packet; // TODO no use, need delete from CM
|
||||||
|
|
||||||
|
struct side_conn_param client_side;
|
||||||
|
struct side_conn_param server_side;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct intercept_param
|
||||||
|
{
|
||||||
|
uint64_t rule_id;
|
||||||
|
int ref_cnt;
|
||||||
|
int tcp_option_profile;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void intercept_param_new_cb(const char *table_name, int table_id, const char *key, const char *table_line, void **ad, long argl, void *argp)
|
||||||
|
{
|
||||||
|
size_t offset = 0;
|
||||||
|
size_t len = 0;
|
||||||
|
char *json_str = NULL;
|
||||||
|
cJSON *json = NULL;
|
||||||
|
cJSON *item = NULL;
|
||||||
|
struct intercept_param *policy_param = NULL;
|
||||||
|
struct tcp_policy_enforcer *enforcer = (struct tcp_policy_enforcer *)argp;
|
||||||
|
|
||||||
|
if (maat_helper_read_column(table_line, 7, &offset, &len) < 0)
|
||||||
|
{
|
||||||
|
TFE_LOG_ERROR(enforcer->logger, "Invalid intercept user region: %s", table_line);
|
||||||
|
goto error_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
json_str = ALLOC(char, len + 1);
|
||||||
|
memcpy(json_str, table_line + offset, len);
|
||||||
|
json = cJSON_Parse(json_str);
|
||||||
|
if (json == NULL)
|
||||||
|
{
|
||||||
|
TFE_LOG_ERROR(enforcer->logger, "Invalid intercept parameter: id = %s", key);
|
||||||
|
goto error_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
item = cJSON_GetObjectItem(json, "tcp_option_profile");
|
||||||
|
if (item == NULL || item->type != cJSON_Number)
|
||||||
|
{
|
||||||
|
TFE_LOG_ERROR(enforcer->logger, "Invalid intercept parameter: %s invalid tcp_option_profile format", key);
|
||||||
|
goto error_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
policy_param = ALLOC(struct intercept_param, 1);
|
||||||
|
policy_param->rule_id = atoll(key);
|
||||||
|
policy_param->ref_cnt = 1;
|
||||||
|
policy_param->tcp_option_profile = item->valueint;
|
||||||
|
|
||||||
|
*ad = policy_param;
|
||||||
|
TFE_LOG_INFO(enforcer->logger, "Add intercept policy: %lu", policy_param->rule_id);
|
||||||
|
|
||||||
|
error_out:
|
||||||
|
if (json)
|
||||||
|
{
|
||||||
|
cJSON_Delete(json);
|
||||||
|
}
|
||||||
|
if (json_str)
|
||||||
|
{
|
||||||
|
free(json_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void intercept_param_free_cb(int table_id, void **ad, long argl, void *argp)
|
||||||
|
{
|
||||||
|
struct tcp_policy_enforcer *enforcer = (struct tcp_policy_enforcer *)argp;
|
||||||
|
struct intercept_param *policy_param = (struct intercept_param *)*ad;
|
||||||
|
if (policy_param == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((__sync_sub_and_fetch(&policy_param->ref_cnt, 1) == 0))
|
||||||
|
{
|
||||||
|
TFE_LOG_INFO(enforcer->logger, "Del intercept policy %lu", policy_param->rule_id);
|
||||||
|
free(policy_param);
|
||||||
|
*ad = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void intercept_param_free(struct intercept_param *policy_param)
|
||||||
|
{
|
||||||
|
intercept_param_free_cb(0, (void **)&policy_param, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void intercept_param_dup_cb(int table_id, void **to, void **from, long argl, void *argp)
|
||||||
|
{
|
||||||
|
struct intercept_param *policy_param = (struct intercept_param *)*from;
|
||||||
|
if (policy_param)
|
||||||
|
{
|
||||||
|
__sync_add_and_fetch(&(policy_param->ref_cnt), 1);
|
||||||
|
*to = policy_param;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*to = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parser_side_conn_param(const char *json_str, struct side_conn_param *out_val, void *logger)
|
||||||
|
{
|
||||||
|
cJSON *json = NULL;
|
||||||
|
cJSON *object = NULL;
|
||||||
|
cJSON *item = NULL;
|
||||||
|
|
||||||
|
json = cJSON_Parse(json_str);
|
||||||
|
if (json == NULL)
|
||||||
|
{
|
||||||
|
TFE_LOG_ERROR(logger, "Invalid tcp option param %s", json_str);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
object = cJSON_GetObjectItem(json, "tcp_maxseg");
|
||||||
|
if (object)
|
||||||
|
{
|
||||||
|
item = cJSON_GetObjectItem(object, "enable");
|
||||||
|
if (item && item->type == cJSON_Number)
|
||||||
|
{
|
||||||
|
out_val->maxseg_enable = item->valueint;
|
||||||
|
}
|
||||||
|
item = cJSON_GetObjectItem(object, "maxseg");
|
||||||
|
if (item && item->type == cJSON_Number)
|
||||||
|
{
|
||||||
|
out_val->maxseg_vaule = item->valueint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item = cJSON_GetObjectItem(json, "nodelay");
|
||||||
|
if (item && item->type == cJSON_Number)
|
||||||
|
{
|
||||||
|
out_val->nodelay = item->valueint;
|
||||||
|
}
|
||||||
|
|
||||||
|
object = cJSON_GetObjectItem(json, "keep_alive");
|
||||||
|
if (object)
|
||||||
|
{
|
||||||
|
item = cJSON_GetObjectItem(object, "enable");
|
||||||
|
if (item && item->type == cJSON_Number)
|
||||||
|
{
|
||||||
|
out_val->keepalive = item->valueint;
|
||||||
|
}
|
||||||
|
item = cJSON_GetObjectItem(object, "tcp_keepcnt");
|
||||||
|
if (item && item->type == cJSON_Number)
|
||||||
|
{
|
||||||
|
out_val->keepcnt = item->valueint;
|
||||||
|
}
|
||||||
|
item = cJSON_GetObjectItem(object, "tcp_keepidle");
|
||||||
|
if (item && item->type == cJSON_Number)
|
||||||
|
{
|
||||||
|
out_val->keepidle = item->valueint;
|
||||||
|
}
|
||||||
|
item = cJSON_GetObjectItem(object, "tcp_keepintvl");
|
||||||
|
if (item && item->type == cJSON_Number)
|
||||||
|
{
|
||||||
|
out_val->keepintvl = item->valueint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item = cJSON_GetObjectItem(json, "ttl");
|
||||||
|
if (item && item->type == cJSON_Number)
|
||||||
|
{
|
||||||
|
out_val->ttl = item->valueint;
|
||||||
|
}
|
||||||
|
|
||||||
|
item = cJSON_GetObjectItem(json, "user_timeout");
|
||||||
|
if (item && item->type == cJSON_Number)
|
||||||
|
{
|
||||||
|
out_val->user_timeout = item->valueint;
|
||||||
|
}
|
||||||
|
cJSON_Delete(json);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void profile_param_new_cb(const char *table_name, int table_id, const char *key, const char *table_line, void **ad, long argl, void *argp)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
int profile_id = 0;
|
||||||
|
int tcp_passthrough = 0;
|
||||||
|
int bypass_duplicated_packet = 0;
|
||||||
|
char client_side_conn_param[512] = {0};
|
||||||
|
char server_side_conn_param[512] = {0};
|
||||||
|
int is_valid = 0;
|
||||||
|
struct tcp_profile_param *profile_param = NULL;
|
||||||
|
struct tcp_policy_enforcer *enforcer = (struct tcp_policy_enforcer *)argp;
|
||||||
|
|
||||||
|
ret = sscanf(table_line, "%d\t%d\t%d\t%s\t%s\t%d", &profile_id, &tcp_passthrough, &bypass_duplicated_packet, client_side_conn_param, server_side_conn_param, &is_valid);
|
||||||
|
if (ret != 6)
|
||||||
|
{
|
||||||
|
TFE_LOG_ERROR(enforcer->logger, "Invalid tcp option profile: %s", table_line);
|
||||||
|
goto error_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
profile_param = ALLOC(struct tcp_profile_param, 1);
|
||||||
|
profile_param->ref_cnt = 1;
|
||||||
|
profile_param->tcp_passthrough = tcp_passthrough;
|
||||||
|
profile_param->bypass_duplicated_packet = bypass_duplicated_packet;
|
||||||
|
|
||||||
|
if (parser_side_conn_param(client_side_conn_param, &profile_param->client_side, enforcer->logger) == -1)
|
||||||
|
{
|
||||||
|
goto error_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parser_side_conn_param(server_side_conn_param, &profile_param->server_side, enforcer->logger) == -1)
|
||||||
|
{
|
||||||
|
goto error_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ad = profile_param;
|
||||||
|
TFE_LOG_INFO(enforcer->logger, "Add tcp option profile: %s", key);
|
||||||
|
return;
|
||||||
|
|
||||||
|
error_out:
|
||||||
|
if (profile_param)
|
||||||
|
{
|
||||||
|
free(profile_param);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void profile_param_free_cb(int table_id, void **ad, long argl, void *argp)
|
||||||
|
{
|
||||||
|
struct tcp_profile_param *profile_param = (struct tcp_profile_param *)*ad;
|
||||||
|
if (profile_param == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((__sync_sub_and_fetch(&profile_param->ref_cnt, 1) == 0))
|
||||||
|
{
|
||||||
|
free(profile_param);
|
||||||
|
*ad = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void profile_param_free(struct tcp_profile_param *profile_param)
|
||||||
|
{
|
||||||
|
profile_param_free_cb(0, (void **)&profile_param, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void profile_param_dup_cb(int table_id, void **to, void **from, long argl, void *argp)
|
||||||
|
{
|
||||||
|
struct tcp_profile_param *profile_param = (struct tcp_profile_param *)*from;
|
||||||
|
if (profile_param)
|
||||||
|
{
|
||||||
|
__sync_add_and_fetch(&(profile_param->ref_cnt), 1);
|
||||||
|
*to = profile_param;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*to = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct tcp_policy_enforcer *tcp_policy_enforcer_create(void *logger)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
struct tcp_policy_enforcer *enforcer = ALLOC(struct tcp_policy_enforcer, 1);
|
||||||
|
enforcer->maat = (struct maat *)tfe_bussiness_resouce_get(STATIC_MAAT);
|
||||||
|
enforcer->logger = logger;
|
||||||
|
enforcer->policy_table_id = maat_get_table_id(enforcer->maat, "TSG_SECURITY_COMPILE");
|
||||||
|
if (enforcer->policy_table_id < 0)
|
||||||
|
{
|
||||||
|
TFE_LOG_ERROR(enforcer->logger, "failed at register table of TSG_SECURITY_COMPILE, ret = %d", enforcer->policy_table_id);
|
||||||
|
goto error_out;
|
||||||
|
}
|
||||||
|
enforcer->profile_table_id = maat_get_table_id(enforcer->maat, "PXY_PROFILE_TCP_OPTION");
|
||||||
|
if (enforcer->profile_table_id < 0)
|
||||||
|
{
|
||||||
|
TFE_LOG_ERROR(enforcer->logger, "failed at register table of PXY_PROFILE_TCP_OPTION, ret = %d", enforcer->profile_table_id);
|
||||||
|
goto error_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = maat_plugin_table_ex_schema_register(enforcer->maat, "TSG_SECURITY_COMPILE",
|
||||||
|
intercept_param_new_cb,
|
||||||
|
intercept_param_free_cb,
|
||||||
|
intercept_param_dup_cb,
|
||||||
|
0, enforcer);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
TFE_LOG_ERROR(enforcer->logger, "failed at register callback of TSG_SECURITY_COMPILE, ret = %d", ret);
|
||||||
|
goto error_out;
|
||||||
|
}
|
||||||
|
ret = maat_plugin_table_ex_schema_register(enforcer->maat, "PXY_PROFILE_TCP_OPTION",
|
||||||
|
profile_param_new_cb,
|
||||||
|
profile_param_free_cb,
|
||||||
|
profile_param_dup_cb,
|
||||||
|
0, enforcer);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
TFE_LOG_ERROR(enforcer->logger, "failed at register callback of PXY_PROFILE_TCP_OPTION, ret = %d", ret);
|
||||||
|
goto error_out;
|
||||||
|
}
|
||||||
|
return enforcer;
|
||||||
|
|
||||||
|
error_out:
|
||||||
|
tcp_policy_enforcer_destory(enforcer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tcp_policy_enforcer_destory(struct tcp_policy_enforcer *enforcer)
|
||||||
|
{
|
||||||
|
if (enforcer)
|
||||||
|
{
|
||||||
|
free(enforcer);
|
||||||
|
enforcer = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tcp_policy_enforce(struct tcp_policy_enforcer *enforcer, struct tfe_cmsg *cmsg, uint64_t rule_id)
|
||||||
|
{
|
||||||
|
char rule_id_str[16] = {0};
|
||||||
|
char profile_id_str[16] = {0};
|
||||||
|
|
||||||
|
snprintf(rule_id_str, sizeof(rule_id_str), "%lu", rule_id);
|
||||||
|
struct intercept_param *policy_param = (struct intercept_param *)maat_plugin_table_get_ex_data(enforcer->maat, enforcer->policy_table_id, rule_id_str);
|
||||||
|
if (policy_param == NULL)
|
||||||
|
{
|
||||||
|
TFE_LOG_INFO(enforcer->logger, "Failed to get intercept parameter of policy %lu.", rule_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(profile_id_str, sizeof(profile_id_str), "%d", policy_param->tcp_option_profile);
|
||||||
|
struct tcp_profile_param *profile_param = (struct tcp_profile_param *)maat_plugin_table_get_ex_data(enforcer->maat, enforcer->profile_table_id, profile_id_str);
|
||||||
|
if (profile_param == NULL)
|
||||||
|
{
|
||||||
|
TFE_LOG_INFO(enforcer->logger, "Failed to get tcp option parameter of profile %lu.", rule_id);
|
||||||
|
intercept_param_free(policy_param);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tfe_cmsg_set(cmsg, TFE_CMSG_TCP_PASSTHROUGH, (unsigned char *)&profile_param->tcp_passthrough, sizeof(profile_param->tcp_passthrough));
|
||||||
|
|
||||||
|
struct side_conn_param *client_side = &profile_param->client_side;
|
||||||
|
tfe_cmsg_set(cmsg, TFE_CMSG_DOWNSTREAM_TCP_MSS_ENABLE, (unsigned char *)&client_side->maxseg_enable, sizeof(client_side->maxseg_enable));
|
||||||
|
tfe_cmsg_set(cmsg, TFE_CMSG_DOWNSTREAM_TCP_MSS_VALUE, (unsigned char *)&client_side->maxseg_vaule, sizeof(client_side->maxseg_vaule));
|
||||||
|
tfe_cmsg_set(cmsg, TFE_CMSG_DOWNSTREAM_TCP_NODELAY, (unsigned char *)&client_side->nodelay, sizeof(client_side->nodelay));
|
||||||
|
tfe_cmsg_set(cmsg, TFE_CMSG_DOWNSTREAM_TCP_TTL, (unsigned char *)&client_side->ttl, sizeof(client_side->ttl));
|
||||||
|
tfe_cmsg_set(cmsg, TFE_CMSG_DOWNSTREAM_TCP_KEEPALIVE, (unsigned char *)&client_side->keepalive, sizeof(client_side->keepalive));
|
||||||
|
tfe_cmsg_set(cmsg, TFE_CMSG_DOWNSTREAM_TCP_KEEPCNT, (unsigned char *)&client_side->keepcnt, sizeof(client_side->keepcnt));
|
||||||
|
tfe_cmsg_set(cmsg, TFE_CMSG_DOWNSTREAM_TCP_KEEPIDLE, (unsigned char *)&client_side->keepidle, sizeof(client_side->keepidle));
|
||||||
|
tfe_cmsg_set(cmsg, TFE_CMSG_DOWNSTREAM_TCP_KEEPINTVL, (unsigned char *)&client_side->keepidle, sizeof(client_side->keepintvl));
|
||||||
|
tfe_cmsg_set(cmsg, TFE_CMSG_DOWNSTREAM_TCP_USER_TIMEOUT, (unsigned char *)&client_side->user_timeout, sizeof(client_side->user_timeout));
|
||||||
|
|
||||||
|
struct side_conn_param *server_side = &profile_param->server_side;
|
||||||
|
tfe_cmsg_set(cmsg, TFE_CMSG_UPSTREAM_TCP_MSS_ENABLE, (unsigned char *)&server_side->maxseg_enable, sizeof(server_side->maxseg_enable));
|
||||||
|
tfe_cmsg_set(cmsg, TFE_CMSG_UPSTREAM_TCP_MSS_VALUE, (unsigned char *)&server_side->maxseg_vaule, sizeof(server_side->maxseg_vaule));
|
||||||
|
tfe_cmsg_set(cmsg, TFE_CMSG_UPSTREAM_TCP_NODELAY, (unsigned char *)&server_side->nodelay, sizeof(server_side->nodelay));
|
||||||
|
tfe_cmsg_set(cmsg, TFE_CMSG_UPSTREAM_TCP_TTL, (unsigned char *)&server_side->ttl, sizeof(server_side->ttl));
|
||||||
|
tfe_cmsg_set(cmsg, TFE_CMSG_UPSTREAM_TCP_KEEPALIVE, (unsigned char *)&server_side->keepalive, sizeof(server_side->keepalive));
|
||||||
|
tfe_cmsg_set(cmsg, TFE_CMSG_UPSTREAM_TCP_KEEPCNT, (unsigned char *)&server_side->keepcnt, sizeof(server_side->keepcnt));
|
||||||
|
tfe_cmsg_set(cmsg, TFE_CMSG_UPSTREAM_TCP_KEEPIDLE, (unsigned char *)&server_side->keepidle, sizeof(server_side->keepidle));
|
||||||
|
tfe_cmsg_set(cmsg, TFE_CMSG_UPSTREAM_TCP_KEEPINTVL, (unsigned char *)&server_side->keepintvl, sizeof(server_side->keepintvl));
|
||||||
|
tfe_cmsg_set(cmsg, TFE_CMSG_UPSTREAM_TCP_USER_TIMEOUT, (unsigned char *)&server_side->user_timeout, sizeof(server_side->user_timeout));
|
||||||
|
|
||||||
|
TFE_LOG_INFO(enforcer->logger, "hit rule_id %lu tcp_option_profile %d tcp_passthrough %d "
|
||||||
|
"client_side={maxseg_enable:%d, maxseg_vaule:%d, nodelay:%d, ttl:%d, keepalive:%d, keepcnt:%d, keepidle:%d, keepintvl:%d, user_timeout:%d} "
|
||||||
|
"server_side={maxseg_enable:%d, maxseg_vaule:%d, nodelay:%d, ttl:%d, keepalive:%d, keepcnt:%d, keepidle:%d, keepintvl:%d, user_timeout:%d} ",
|
||||||
|
rule_id, policy_param->tcp_option_profile, profile_param->tcp_passthrough,
|
||||||
|
client_side->maxseg_enable, client_side->maxseg_vaule, client_side->nodelay, client_side->ttl, client_side->keepalive, client_side->keepcnt, client_side->keepidle, client_side->keepidle, client_side->user_timeout,
|
||||||
|
server_side->maxseg_enable, server_side->maxseg_vaule, server_side->nodelay, server_side->ttl, server_side->keepalive, server_side->keepcnt, server_side->keepidle, server_side->keepidle, server_side->user_timeout);
|
||||||
|
profile_param_free(profile_param);
|
||||||
|
intercept_param_free(policy_param);
|
||||||
|
}
|
||||||
8
plugin/business/tcp-policy/src/tcp_policy.h
Normal file
8
plugin/business/tcp-policy/src/tcp_policy.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <tfe_cmsg.h>
|
||||||
|
#include <MESA/maat.h>
|
||||||
|
|
||||||
|
struct tcp_policy_enforcer;
|
||||||
|
struct tcp_policy_enforcer *tcp_policy_enforcer_create(void *logger);
|
||||||
|
void tcp_policy_enforcer_destory(struct tcp_policy_enforcer *enforcer);
|
||||||
|
void tcp_policy_enforce(struct tcp_policy_enforcer *enforcer, struct tfe_cmsg *cmsg, uint64_t rule_id);
|
||||||
@@ -540,7 +540,7 @@ int traffic_mirror_on_open_cb(const struct tfe_stream * stream, unsigned int thr
|
|||||||
char str_policy_id[TFE_SYMBOL_MAX] = {0};
|
char str_policy_id[TFE_SYMBOL_MAX] = {0};
|
||||||
char str_profile_id[TFE_SYMBOL_MAX] = {0};
|
char str_profile_id[TFE_SYMBOL_MAX] = {0};
|
||||||
|
|
||||||
unsigned int opt_val;
|
uint64_t rule_id;
|
||||||
uint16_t opt_out_size;
|
uint16_t opt_out_size;
|
||||||
|
|
||||||
struct policy_table_ex_data * policy_ex_data = NULL;
|
struct policy_table_ex_data * policy_ex_data = NULL;
|
||||||
@@ -549,14 +549,14 @@ int traffic_mirror_on_open_cb(const struct tfe_stream * stream, unsigned int thr
|
|||||||
struct ether_addr c_ether_addr = {};
|
struct ether_addr c_ether_addr = {};
|
||||||
struct ether_addr s_ether_addr = {};
|
struct ether_addr s_ether_addr = {};
|
||||||
|
|
||||||
int ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_POLICY_ID, (unsigned char *) &opt_val, sizeof(opt_val), &opt_out_size);
|
int ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_POLICY_ID, (unsigned char *)&rule_id, sizeof(rule_id), &opt_out_size);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
TFE_LOG_ERROR(instance->logger, "failed at getting policy id from cmsg, detach the stream.");
|
TFE_LOG_ERROR(instance->logger, "failed at getting policy id from cmsg, detach the stream.");
|
||||||
goto detach;
|
goto detach;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(str_policy_id, sizeof(str_policy_id), "%u", opt_val);
|
snprintf(str_policy_id, sizeof(str_policy_id), "%lu", rule_id);
|
||||||
policy_ex_data = (struct policy_table_ex_data *)maat_plugin_table_get_ex_data(instance->maat_feather, instance->policy_table_id, str_policy_id);
|
policy_ex_data = (struct policy_table_ex_data *)maat_plugin_table_get_ex_data(instance->maat_feather, instance->policy_table_id, str_policy_id);
|
||||||
if (!policy_ex_data || !policy_ex_data->enable)
|
if (!policy_ex_data || !policy_ex_data->enable)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -444,5 +444,15 @@
|
|||||||
"key_type":"pointer",
|
"key_type":"pointer",
|
||||||
"foreign": [2]
|
"foreign": [2]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"table_id":43,
|
||||||
|
"table_name":"PXY_PROFILE_TCP_OPTION",
|
||||||
|
"table_type":"plugin",
|
||||||
|
"valid_column":6,
|
||||||
|
"custom": {
|
||||||
|
"key":1,
|
||||||
|
"key_type":"pointer"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
Reference in New Issue
Block a user