TFE适配MAAT4,编译表只注册一次

This commit is contained in:
luwenpeng
2023-04-23 16:35:42 +08:00
parent 97a4386bc4
commit 2138d7f13e
12 changed files with 411 additions and 368 deletions

View File

@@ -2,7 +2,7 @@
common src/tfe_utils.cpp src/tfe_types.cpp src/tfe_future.cpp src/tfe_http.cpp src/tfe_plugin.cpp common src/tfe_utils.cpp src/tfe_types.cpp src/tfe_future.cpp src/tfe_http.cpp src/tfe_plugin.cpp
src/tfe_rpc.cpp src/tfe_cmsg.cpp src/tfe_kafka_logger.cpp src/tfe_resource.cpp src/tfe_scan.cpp src/tfe_rpc.cpp src/tfe_cmsg.cpp src/tfe_kafka_logger.cpp src/tfe_resource.cpp src/tfe_scan.cpp
src/tfe_pkt_util.cpp src/tfe_tcp_restore.cpp src/raw_socket.cpp src/packet_construct.cpp src/tfe_pkt_util.cpp src/tfe_tcp_restore.cpp src/raw_socket.cpp src/packet_construct.cpp
src/tap.cpp src/io_uring.cpp) src/tap.cpp src/io_uring.cpp src/intercept_policy.cpp)
target_include_directories(common PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include) target_include_directories(common PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
target_link_libraries(common PUBLIC libevent-static libevent-static-openssl libevent-static-pthreads rdkafka) target_link_libraries(common PUBLIC libevent-static libevent-static-openssl libevent-static-pthreads rdkafka)
target_link_libraries(common PUBLIC MESA_handle_logger cjson) target_link_libraries(common PUBLIC MESA_handle_logger cjson)

View File

@@ -0,0 +1,9 @@
#pragma once
#include <tfe_cmsg.h>
struct intercept_policy_enforcer;
struct intercept_policy_enforcer *intercept_policy_enforcer_create(void *logger);
void intercept_policy_enforce_destory(struct intercept_policy_enforcer *enforcer);
// return 0 : success
// return -1 : error (need passthrough)
int intercept_policy_enforce(struct intercept_policy_enforcer *enforcer, struct tfe_cmsg *cmsg);

View File

@@ -46,7 +46,11 @@ 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); uint64_t ssl_stream_get_policy_id(struct ssl_stream *upstream);
int ssl_stream_get_decrypted_profile_id(struct ssl_stream *upstream);
int ssl_stream_get_trusted_keyring_profile_id(struct ssl_stream *upstream);
int ssl_stream_get_untrusted_keyring_profile_id(struct ssl_stream *upstream);
unsigned int is_ssl_debug(); unsigned int is_ssl_debug();

View File

@@ -36,6 +36,10 @@ enum tfe_cmsg_tlv_type
TFE_CMSG_POLICY_ID = 0x10, // size uint64_t TFE_CMSG_POLICY_ID = 0x10, // size uint64_t
TFE_CMSG_STREAM_TRACE_ID = 0x11, TFE_CMSG_STREAM_TRACE_ID = 0x11,
TFE_CMSG_TCP_OPTION_PROFILE_ID, // size int
TFE_CMSG_DECRYPTION_PROFILE_ID, // size int
TFE_CMSG_KEYRING_FOR_TRUSTED_ID, // size int
TFE_CMSG_KEYRING_FOR_UNTRUSTED, // size int
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
TFE_CMSG_SSL_SERVER_SIDE_LATENCY, //size uint64_t, milisecond TFE_CMSG_SSL_SERVER_SIDE_LATENCY, //size uint64_t, milisecond

View File

@@ -0,0 +1,271 @@
#include <tfe_utils.h>
#include <MESA/maat.h>
#include <cjson/cJSON.h>
#include <tfe_resource.h>
#include <intercept_policy.h>
struct intercept_param
{
uint64_t rule_id;
int ref_cnt;
int keyring_for_trusted;
int keyring_for_untrusted;
int decryption_profile;
int tcp_option_profile;
};
struct intercept_policy_enforcer
{
struct maat *maat;
int table_id;
void *logger;
};
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 len = 0;
size_t offset = 0;
char *json_str = NULL;
cJSON *json = NULL;
cJSON *item = NULL;
struct intercept_param *param = NULL;
struct intercept_policy_enforcer *enforcer = (struct intercept_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, "protocol");
if (unlikely(!item || !cJSON_IsString(item)))
{
TFE_LOG_ERROR(enforcer->logger, "Invalid intercept parameter: %s invalid protocol format", key);
goto error_out;
}
if (0 != strcasecmp(item->valuestring, "SSL") && 0 != strcasecmp(item->valuestring, "HTTP"))
{
goto error_out;
}
param = ALLOC(struct intercept_param, 1);
param->rule_id = atoll(key);
param->ref_cnt = 1;
param->keyring_for_trusted = 1;
param->keyring_for_untrusted = 0;
param->decryption_profile = 0;
param->tcp_option_profile = 0;
item = cJSON_GetObjectItem(json, "keyring_for_trusted");
if (item)
{
if (item->type == cJSON_Number)
{
param->keyring_for_trusted = item->valueint;
}
else if (item->type == cJSON_String)
{
param->keyring_for_trusted = atoi(item->valuestring);
}
else
{
TFE_LOG_ERROR(enforcer->logger, "Invalid intercept parameter: %lu invalid keyring_for_trusted format", param->rule_id);
}
}
item = cJSON_GetObjectItem(json, "keyring_for_untrusted");
if (item)
{
if (item->type == cJSON_Number)
{
param->keyring_for_untrusted = item->valueint;
}
else if (item->type == cJSON_String)
{
param->keyring_for_untrusted = atoi(item->valuestring);
}
else
{
TFE_LOG_ERROR(enforcer->logger, "Invalid intercept parameter: %lu invalid keyring_for_untrusted format", param->rule_id);
}
}
item = cJSON_GetObjectItem(json, "decryption");
if (item)
{
if (item->type == cJSON_Number)
{
param->decryption_profile = item->valueint;
}
else if (item->type == cJSON_String)
{
param->decryption_profile = atoi(item->valuestring);
}
else
{
TFE_LOG_ERROR(enforcer->logger, "Invalid intercept parameter: %lu invalid decryption_profile format", param->rule_id);
}
}
item = cJSON_GetObjectItem(json, "tcp_option_profile");
if (item)
{
if (item->type == cJSON_Number)
{
param->tcp_option_profile = item->valueint;
}
else if (item->type == cJSON_String)
{
param->tcp_option_profile = atoi(item->valuestring);
}
else
{
TFE_LOG_ERROR(enforcer->logger, "Invalid intercept parameter: %lu invalid tcp_option_profile format", param->rule_id);
}
}
*ad = param;
TFE_LOG_INFO(enforcer->logger, "Add intercept policy: %lu", 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 intercept_policy_enforcer *enforcer = (struct intercept_policy_enforcer *)argp;
struct intercept_param *param = (struct intercept_param *)*ad;
if (param == NULL)
{
return;
}
if ((__sync_sub_and_fetch(&param->ref_cnt, 1) == 0))
{
TFE_LOG_INFO(enforcer->logger, "Del intercept policy %lu", param->rule_id);
free(param);
*ad = NULL;
}
}
static void intercept_param_dup_cb(int table_id, void **to, void **from, long argl, void *argp)
{
struct intercept_param *param = (struct intercept_param *)*from;
if (param)
{
__sync_add_and_fetch(&(param->ref_cnt), 1);
*to = param;
}
else
{
*to = NULL;
}
}
static void intercept_param_free(struct intercept_param *param)
{
intercept_param_free_cb(0, (void **)&param, 0, NULL);
}
struct intercept_policy_enforcer *intercept_policy_enforcer_create(void *logger)
{
int ret = 0;
struct intercept_policy_enforcer *enforcer = ALLOC(struct intercept_policy_enforcer, 1);
enforcer->maat = (struct maat *)tfe_bussiness_resouce_get(STATIC_MAAT);
enforcer->logger = logger;
enforcer->table_id = maat_get_table_id(enforcer->maat, "TSG_SECURITY_COMPILE");
if (enforcer->table_id < 0)
{
TFE_LOG_ERROR(enforcer->logger, "failed at register table of TSG_SECURITY_COMPILE, ret = %d", enforcer->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;
}
return enforcer;
error_out:
intercept_policy_enforce_destory(enforcer);
return NULL;
}
void intercept_policy_enforce_destory(struct intercept_policy_enforcer *enforcer)
{
if (enforcer)
{
free(enforcer);
enforcer = NULL;
}
}
// return 0 : success
// return -1 : error (need passthrough)
int intercept_policy_enforce(struct intercept_policy_enforcer *enforcer, struct tfe_cmsg *cmsg)
{
int ret = 0;
uint16_t size = 0;
uint64_t rule_id = 0;
char buff[16] = {0};
struct intercept_param *param = NULL;
int passthrough = 1;
char reason[] = "Invalid Intercept Param";
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 intercept rule_id from cmsg: %s", strerror(-ret));
goto error_passthrough;
}
snprintf(buff, sizeof(buff), "%lu", rule_id);
param = (struct intercept_param *)maat_plugin_table_get_ex_data(enforcer->maat, enforcer->table_id, buff);
if (param == NULL)
{
TFE_LOG_INFO(enforcer->logger, "Failed to get intercept parameter of policy %lu.", rule_id);
goto error_passthrough;
}
tfe_cmsg_set(cmsg, TFE_CMSG_TCP_OPTION_PROFILE_ID, (const unsigned char *)&(param->tcp_option_profile), sizeof(param->tcp_option_profile));
tfe_cmsg_set(cmsg, TFE_CMSG_DECRYPTION_PROFILE_ID, (const unsigned char *)&(param->decryption_profile), sizeof(param->decryption_profile));
tfe_cmsg_set(cmsg, TFE_CMSG_KEYRING_FOR_TRUSTED_ID, (const unsigned char *)&(param->keyring_for_trusted), sizeof(param->keyring_for_trusted));
tfe_cmsg_set(cmsg, TFE_CMSG_KEYRING_FOR_UNTRUSTED, (const unsigned char *)&(param->keyring_for_untrusted), sizeof(param->keyring_for_untrusted));
intercept_param_free(param);
return 0;
error_passthrough:
tfe_cmsg_set(cmsg, TFE_CMSG_TCP_PASSTHROUGH, (const unsigned char *)&passthrough, sizeof(passthrough));
tfe_cmsg_set(cmsg, TFE_CMSG_SSL_PASSTHROUGH_REASON, (const unsigned char *)&reason, strlen(reason));
return -1;
}

View File

@@ -5,6 +5,7 @@
#include <sender_scm.h> #include <sender_scm.h>
#include <ssl_stream_core.h> #include <ssl_stream_core.h>
#include <net/if.h> #include <net/if.h>
#include <intercept_policy.h>
struct ssl_mgr; struct ssl_mgr;
struct key_keeper; struct key_keeper;
@@ -130,6 +131,7 @@ struct tfe_proxy
struct tfe_plugin * modules; struct tfe_plugin * modules;
struct ssl_mgr * ssl_mgr_handler; struct ssl_mgr * ssl_mgr_handler;
struct intercept_policy_enforcer *int_ply_enforcer;
struct tcp_policy_enforcer *tcp_ply_enforcer; struct tcp_policy_enforcer *tcp_ply_enforcer;
struct ssl_policy_enforcer *ssl_ply_enforcer; struct ssl_policy_enforcer *ssl_ply_enforcer;
struct chaining_policy_enforcer *chain_ply_enforcer; struct chaining_policy_enforcer *chain_ply_enforcer;

View File

@@ -15,10 +15,11 @@
#include <watchdog_3rd_device.h> #include <watchdog_3rd_device.h>
#include <raw_socket.h> #include <raw_socket.h>
#include <packet_construct.h> #include <packet_construct.h>
#include <intercept_policy.h>
#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); extern int tcp_policy_enforce(struct tcp_policy_enforcer *tcp_enforcer, struct tfe_cmsg *cmsg);
extern void chaining_policy_enforce(struct chaining_policy_enforcer *enforcer, struct tfe_cmsg *cmsg, uint64_t rule_id); extern void chaining_policy_enforce(struct chaining_policy_enforcer *enforcer, struct tfe_cmsg *cmsg, uint64_t rule_id);
struct acceptor_kni_v3 struct acceptor_kni_v3
@@ -604,7 +605,6 @@ static int payload_handler_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, s
uint8_t stream_protocol_in_char = 0; uint8_t stream_protocol_in_char = 0;
uint8_t enalbe_decrypted_traffic_steering = 0; uint8_t enalbe_decrypted_traffic_steering = 0;
uint16_t size = 0; uint16_t size = 0;
uint64_t rule_id = 0;
uint64_t chaining_rule_id = 0; // only use for acceptv4 uint64_t chaining_rule_id = 0; // only use for acceptv4
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));
@@ -716,13 +716,8 @@ static int payload_handler_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, s
goto end; goto end;
} }
ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_POLICY_ID, (unsigned char *)&rule_id, sizeof(rule_id), &size); intercept_policy_enforce(__ctx->proxy->int_ply_enforcer, cmsg);
if (ret < 0) tcp_policy_enforce(__ctx->proxy->tcp_ply_enforcer, cmsg);
{
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);
chaining_policy_enforce(__ctx->proxy->chain_ply_enforcer, cmsg, chaining_rule_id); chaining_policy_enforce(__ctx->proxy->chain_ply_enforcer, cmsg, chaining_rule_id);
if (overwrite_tcp_mss(cmsg, &restore_info)) if (overwrite_tcp_mss(cmsg, &restore_info))

View File

@@ -698,6 +698,9 @@ 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->int_ply_enforcer = intercept_policy_enforcer_create(g_default_logger);
CHECK_OR_EXIT(g_default_proxy->int_ply_enforcer != NULL, "Failed at creating intercept policy enforcer. Exit.");
g_default_proxy->tcp_ply_enforcer = tcp_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."); CHECK_OR_EXIT(g_default_proxy->tcp_ply_enforcer != NULL, "Failed at creating tcp policy enforcer. Exit.");

View File

@@ -2219,6 +2219,39 @@ uint64_t ssl_stream_get_policy_id(struct ssl_stream *upstream)
return policy_id; return policy_id;
} }
int ssl_stream_get_decrypted_profile_id(struct ssl_stream *upstream)
{
uint16_t out_size;
int profile_id = 0;
struct tfe_cmsg *cmsg = tfe_stream_get0_cmsg(upstream->tcp_stream);
int ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_DECRYPTION_PROFILE_ID, (unsigned char *)profile_id, sizeof(profile_id), &out_size);
assert(ret == 0);
return profile_id;
}
int ssl_stream_get_trusted_keyring_profile_id(struct ssl_stream *upstream)
{
uint16_t out_size;
int keyring_id = 0;
struct tfe_cmsg *cmsg = tfe_stream_get0_cmsg(upstream->tcp_stream);
int ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_KEYRING_FOR_TRUSTED_ID, (unsigned char *)keyring_id, sizeof(keyring_id), &out_size);
assert(ret == 0);
return keyring_id;
}
int ssl_stream_get_untrusted_keyring_profile_id(struct ssl_stream *upstream)
{
uint16_t out_size;
int keyring_id = 0;
struct tfe_cmsg *cmsg = tfe_stream_get0_cmsg(upstream->tcp_stream);
int ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_KEYRING_FOR_UNTRUSTED, (unsigned char *)keyring_id, sizeof(keyring_id), &out_size);
assert(ret == 0);
return keyring_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";

View File

@@ -10,18 +10,9 @@
struct ssl_policy_enforcer struct ssl_policy_enforcer
{ {
struct maat *maat; struct maat *maat;
int policy_table_id;
int profile_table_id; int profile_table_id;
void* logger; void* logger;
}; };
struct intercept_param
{
uint64_t policy_id;
int ref_cnt;
int keyring_for_trusted;
int keyring_for_untrusted;
int decryption_profile_id;
};
struct decryption_param struct decryption_param
{ {
@@ -43,147 +34,6 @@ struct decryption_param
int mirror_client_version; int mirror_client_version;
}; };
void intercept_param_dup_cb(int table_id, void **to, void **from, long argl, void* argp)
{
struct intercept_param* param= (struct intercept_param*) *from;
if(param)
{
__sync_add_and_fetch(&(param->ref_cnt), 1);
*to = param;
}
else
{
*to=NULL;
}
return;
}
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)
{
int ret=0;
size_t intercept_user_region_offset=0, len=0;
char* json_str=NULL;
cJSON *json=NULL, *item=NULL;
struct intercept_param* param=NULL;
struct ssl_policy_enforcer* enforcer=(struct ssl_policy_enforcer*)argp;
ret=maat_helper_read_column(table_line, 7, &intercept_user_region_offset, &len);
if(ret<0)
{
TFE_LOG_ERROR(enforcer->logger, "Get intercept user region: %s", table_line);
return;
}
json_str=ALLOC(char, len+1);
memcpy(json_str, table_line+intercept_user_region_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, "protocol");
if(unlikely(!item || !cJSON_IsString(item)))
{
TFE_LOG_ERROR(enforcer->logger, "Invalid intercept parameter: %s invalid protocol format", key);
goto error_out;
}
if(0!=strcasecmp(item->valuestring, "SSL")&& 0!=strcasecmp(item->valuestring, "HTTP"))
{
goto error_out;
}
param=ALLOC(struct intercept_param, 1);
param->policy_id=atoll(key);
param->ref_cnt=1;
/*
param->bypass_mutual_auth=1;
param->bypass_pinning=1;
param->mirror_client_version=1;
*/
param->keyring_for_trusted=1;
param->keyring_for_untrusted=0;
param->decryption_profile_id=0;
item=cJSON_GetObjectItem(json, "keyring_for_trusted");
if(item)
{
if(item->type==cJSON_Number)
{
param->keyring_for_trusted=item->valueint;
}
else if(item->type==cJSON_String)
{
param->keyring_for_trusted=atoi(item->valuestring);
}
else
{
TFE_LOG_ERROR(enforcer->logger, "Invalid intercept parameter: %lu invalid keyring_for_trusted format", param->policy_id);
}
}
item=cJSON_GetObjectItem(json, "keyring_for_untrusted");
if(item)
{
if(item->type==cJSON_Number)
{
param->keyring_for_untrusted=item->valueint;
}
else if(item->type==cJSON_String)
{
param->keyring_for_untrusted=atoi(item->valuestring);
}
else
{
TFE_LOG_ERROR(enforcer->logger, "Invalid intercept parameter: %lu invalid keyring_for_untrusted format", param->policy_id);
}
}
item=cJSON_GetObjectItem(json, "decryption");
if(item)
{
if(item->type==cJSON_Number)
{
param->decryption_profile_id=item->valueint;
}
else if(item->type==cJSON_String)
{
param->decryption_profile_id=atoi(item->valuestring);
}
else
{
TFE_LOG_ERROR(enforcer->logger, "Invalid intercept parameter: %lu invalid decryption format", param->policy_id);
}
}
*ad=param;
TFE_LOG_INFO(enforcer->logger, "Add intercept policy: %lu", param->policy_id);
error_out:
cJSON_Delete(json);
free(json_str);
return;
}
void intercept_param_free_cb(int table_id, void **ad, long argl, void* argp)
{
struct ssl_policy_enforcer* enforcer=(struct ssl_policy_enforcer*)argp;
struct intercept_param* param= (struct intercept_param*) *ad;
if(param==NULL)
{
return;
}
if ((__sync_sub_and_fetch(&param->ref_cnt, 1) == 0))
{
TFE_LOG_INFO(enforcer->logger, "Del intercept policy %lu", param->policy_id);
free(param);
*ad=NULL;
}
}
void intercept_param_free(struct intercept_param* param)
{
intercept_param_free_cb(0, (void**)&param, 0, NULL);
return;
}
void profile_param_dup_cb(int table_id, void **to, void **from, long argl, void* argp) void profile_param_dup_cb(int table_id, void **to, void **from, long argl, void* argp)
{ {
struct decryption_param* param= (struct decryption_param*) *from; struct decryption_param* param= (struct decryption_param*) *from;
@@ -319,21 +169,12 @@ error_out:
} }
struct ssl_policy_enforcer* ssl_policy_enforcer_create(void* logger) struct ssl_policy_enforcer* ssl_policy_enforcer_create(void* logger)
{ {
UNUSED int ret=0;
struct ssl_policy_enforcer* enforcer=ALLOC(struct ssl_policy_enforcer, 1); struct ssl_policy_enforcer* enforcer=ALLOC(struct ssl_policy_enforcer, 1);
enforcer->maat=(struct maat*)tfe_bussiness_resouce_get(STATIC_MAAT);; enforcer->maat=(struct maat*)tfe_bussiness_resouce_get(STATIC_MAAT);;
enforcer->logger=logger; enforcer->logger=logger;
enforcer->policy_table_id=maat_get_table_id(enforcer->maat, "TSG_SECURITY_COMPILE");
assert(enforcer->policy_table_id >= 0);
enforcer->profile_table_id=maat_get_table_id(enforcer->maat, "PXY_PROFILE_DECRYPTION"); enforcer->profile_table_id=maat_get_table_id(enforcer->maat, "PXY_PROFILE_DECRYPTION");
assert(enforcer->profile_table_id >= 0); assert(enforcer->profile_table_id >= 0);
UNUSED int 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);
assert(ret==0);
ret=maat_plugin_table_ex_schema_register(enforcer->maat, ret=maat_plugin_table_ex_schema_register(enforcer->maat,
"PXY_PROFILE_DECRYPTION", "PXY_PROFILE_DECRYPTION",
profile_param_new_cb, profile_param_new_cb,
@@ -347,32 +188,24 @@ struct ssl_policy_enforcer* ssl_policy_enforcer_create(void* logger)
enum ssl_stream_action ssl_policy_enforce(struct ssl_stream *upstream, void* u_para) enum ssl_stream_action ssl_policy_enforce(struct ssl_stream *upstream, void* u_para)
{ {
UNUSED struct ssl_policy_enforcer* enforcer=(struct ssl_policy_enforcer*)u_para; UNUSED struct ssl_policy_enforcer* enforcer=(struct ssl_policy_enforcer*)u_para;
struct intercept_param *policy_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;
uint64_t policy_id=0; char sni[512];
char policy_id_str[16]={0}; char addr_string[512];
char profile_id_str[16]={0}; char profile_id_str[16]={0};
char sni[512], addr_string[512];
policy_id = ssl_stream_get_policy_id(upstream); uint64_t policy_id = ssl_stream_get_policy_id(upstream);
snprintf(policy_id_str, sizeof(policy_id_str), "%lu", policy_id); int decryption_profile_id = ssl_stream_get_decrypted_profile_id(upstream);
policy_param=(struct intercept_param *)maat_plugin_table_get_ex_data(enforcer->maat, enforcer->policy_table_id, policy_id_str); int keyring_for_trusted = ssl_stream_get_trusted_keyring_profile_id(upstream);
if(policy_param==NULL) int keyring_for_untrusted = ssl_stream_get_untrusted_keyring_profile_id(upstream);
{
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");
return SSL_ACTION_PASSTHROUGH;
}
else
{
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 %lu", 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", decryption_profile_id);
profile_param=(struct decryption_param *)maat_plugin_table_get_ex_data(enforcer->maat, enforcer->profile_table_id, profile_id_str); struct decryption_param *profile_param=(struct decryption_param *)maat_plugin_table_get_ex_data(enforcer->maat, enforcer->profile_table_id, profile_id_str);
if (profile_param==NULL) if (profile_param==NULL)
{ {
TFE_LOG_INFO(enforcer->logger, "Failed to get decryption parameter of profile %s.", profile_id_str); TFE_LOG_INFO(enforcer->logger, "Failed to get decryption parameter of profile %s.", profile_id_str);
@@ -397,8 +230,8 @@ enum ssl_stream_action ssl_policy_enforce(struct ssl_stream *upstream, void* u_p
{ {
ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_BLOCK_FAKE_CERT, 1); ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_BLOCK_FAKE_CERT, 1);
} }
ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_KEYRING_FOR_TRUSTED, policy_param->keyring_for_trusted); ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_KEYRING_FOR_TRUSTED, keyring_for_trusted);
ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_KEYRING_FOR_UNTRUSTED, policy_param->keyring_for_untrusted); ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_KEYRING_FOR_UNTRUSTED, keyring_for_untrusted);
ret=ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_PINNING_STATUS, &pinning_staus); ret=ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_PINNING_STATUS, &pinning_staus);
assert(ret==0); assert(ret==0);
@@ -415,46 +248,44 @@ 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 %lu, 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_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 %lu, 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_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 %lu, 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_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 %lu, 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_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 %lu, 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_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 %lu, 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_id);
} }
else else
{ {
action = SSL_ACTION_INTERCEPT; action = SSL_ACTION_INTERCEPT;
} }
intercept_param_free(policy_param);
profile_param_free(profile_param); profile_param_free(profile_param);
policy_param=NULL;
profile_param=NULL; profile_param=NULL;
return action; return action;
} }

View File

@@ -1,7 +1,6 @@
#include <assert.h> #include <assert.h>
#include <tfe_cmsg.h> #include <tfe_cmsg.h>
#include <tfe_utils.h> #include <tfe_utils.h>
#include <tfe_stream.h>
#include <tfe_resource.h> #include <tfe_resource.h>
#include <cjson/cJSON.h> #include <cjson/cJSON.h>
#include <MESA/maat.h> #include <MESA/maat.h>
@@ -11,8 +10,7 @@
struct tcp_policy_enforcer struct tcp_policy_enforcer
{ {
struct maat *maat; struct maat *maat;
int policy_table_id; int table_id;
int profile_table_id;
void *logger; void *logger;
}; };
@@ -39,100 +37,6 @@ struct tcp_profile_param
struct side_conn_param server_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) static int parser_side_conn_param(const char *json_str, struct side_conn_param *out_val, void *logger)
{ {
cJSON *json = NULL; cJSON *json = NULL;
@@ -217,7 +121,7 @@ static void profile_param_new_cb(const char *table_name, int table_id, const cha
char client_side_conn_param[512] = {0}; char client_side_conn_param[512] = {0};
char server_side_conn_param[512] = {0}; char server_side_conn_param[512] = {0};
int is_valid = 0; int is_valid = 0;
struct tcp_profile_param *profile_param = NULL; struct tcp_profile_param *param = NULL;
struct tcp_policy_enforcer *enforcer = (struct tcp_policy_enforcer *)argp; 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); 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);
@@ -227,60 +131,54 @@ static void profile_param_new_cb(const char *table_name, int table_id, const cha
goto error_out; goto error_out;
} }
profile_param = ALLOC(struct tcp_profile_param, 1); param = ALLOC(struct tcp_profile_param, 1);
profile_param->ref_cnt = 1; param->ref_cnt = 1;
profile_param->tcp_passthrough = tcp_passthrough; param->tcp_passthrough = tcp_passthrough;
profile_param->bypass_duplicated_packet = bypass_duplicated_packet; param->bypass_duplicated_packet = bypass_duplicated_packet;
if (parser_side_conn_param(client_side_conn_param, &profile_param->client_side, enforcer->logger) == -1) if (parser_side_conn_param(client_side_conn_param, &param->client_side, enforcer->logger) == -1)
{ {
goto error_out; goto error_out;
} }
if (parser_side_conn_param(server_side_conn_param, &profile_param->server_side, enforcer->logger) == -1) if (parser_side_conn_param(server_side_conn_param, &param->server_side, enforcer->logger) == -1)
{ {
goto error_out; goto error_out;
} }
*ad = profile_param; *ad = param;
TFE_LOG_INFO(enforcer->logger, "Add tcp option profile: %s", key); TFE_LOG_INFO(enforcer->logger, "Add tcp option profile: %s", key);
return; return;
error_out: error_out:
if (profile_param) if (param)
{ {
free(profile_param); free(param);
} }
return;
} }
static void profile_param_free_cb(int table_id, void **ad, long argl, void *argp) 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; struct tcp_profile_param *param = (struct tcp_profile_param *)*ad;
if (profile_param == NULL) if (param == NULL)
{ {
return; return;
} }
if ((__sync_sub_and_fetch(&profile_param->ref_cnt, 1) == 0)) if ((__sync_sub_and_fetch(&param->ref_cnt, 1) == 0))
{ {
free(profile_param); free(param);
*ad = NULL; *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) 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; struct tcp_profile_param *param = (struct tcp_profile_param *)*from;
if (profile_param) if (param)
{ {
__sync_add_and_fetch(&(profile_param->ref_cnt), 1); __sync_add_and_fetch(&(param->ref_cnt), 1);
*to = profile_param; *to = param;
} }
else else
{ {
@@ -288,35 +186,24 @@ static void profile_param_dup_cb(int table_id, void **to, void **from, long argl
} }
} }
static void profile_param_free(struct tcp_profile_param *param)
{
profile_param_free_cb(0, (void **)&param, 0, NULL);
}
struct tcp_policy_enforcer *tcp_policy_enforcer_create(void *logger) struct tcp_policy_enforcer *tcp_policy_enforcer_create(void *logger)
{ {
int ret = 0; int ret = 0;
struct tcp_policy_enforcer *enforcer = ALLOC(struct tcp_policy_enforcer, 1); struct tcp_policy_enforcer *enforcer = ALLOC(struct tcp_policy_enforcer, 1);
enforcer->maat = (struct maat *)tfe_bussiness_resouce_get(STATIC_MAAT); enforcer->maat = (struct maat *)tfe_bussiness_resouce_get(STATIC_MAAT);
enforcer->logger = logger; enforcer->logger = logger;
enforcer->policy_table_id = maat_get_table_id(enforcer->maat, "TSG_SECURITY_COMPILE"); enforcer->table_id = maat_get_table_id(enforcer->maat, "PXY_PROFILE_TCP_OPTION");
if (enforcer->policy_table_id < 0) if (enforcer->table_id < 0)
{ {
TFE_LOG_ERROR(enforcer->logger, "failed at register table of TSG_SECURITY_COMPILE, ret = %d", enforcer->policy_table_id); TFE_LOG_ERROR(enforcer->logger, "failed at register table of PXY_PROFILE_TCP_OPTION, ret = %d", enforcer->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; 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", ret = maat_plugin_table_ex_schema_register(enforcer->maat, "PXY_PROFILE_TCP_OPTION",
profile_param_new_cb, profile_param_new_cb,
profile_param_free_cb, profile_param_free_cb,
@@ -343,31 +230,33 @@ 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) // return 0 : success
// return -1 : error (need passthrough)
int tcp_policy_enforce(struct tcp_policy_enforcer *tcp_enforcer, struct tfe_cmsg *cmsg)
{ {
char rule_id_str[16] = {0}; int ret = 0;
char profile_id_str[16] = {0}; int profile_id = 0;
uint16_t size = 0;
char buffer[16] = {0};
snprintf(rule_id_str, sizeof(rule_id_str), "%lu", rule_id); ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_OPTION_PROFILE_ID, (unsigned char *)&profile_id, sizeof(profile_id), &size);
struct intercept_param *policy_param = (struct intercept_param *)maat_plugin_table_get_ex_data(enforcer->maat, enforcer->policy_table_id, rule_id_str); if (ret < 0)
if (policy_param == NULL)
{ {
TFE_LOG_INFO(enforcer->logger, "Failed to get intercept parameter of policy %lu.", rule_id); TFE_LOG_ERROR(g_default_logger, "Failed at fetch tcp_option_profile from cmsg: %s", strerror(-ret));
return; return -1;
} }
snprintf(profile_id_str, sizeof(profile_id_str), "%d", policy_param->tcp_option_profile); snprintf(buffer, sizeof(buffer), "%d", profile_id);
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); struct tcp_profile_param *param = (struct tcp_profile_param *)maat_plugin_table_get_ex_data(tcp_enforcer->maat, tcp_enforcer->table_id, buffer);
if (profile_param == NULL) if (param == NULL)
{ {
TFE_LOG_INFO(enforcer->logger, "Failed to get tcp option parameter of profile %lu.", rule_id); TFE_LOG_INFO(tcp_enforcer->logger, "Failed to get tcp option parameter of profile %d.", profile_id);
intercept_param_free(policy_param); return -1;
return;
} }
tfe_cmsg_set(cmsg, TFE_CMSG_TCP_PASSTHROUGH, (unsigned char *)&profile_param->tcp_passthrough, sizeof(profile_param->tcp_passthrough)); tfe_cmsg_set(cmsg, TFE_CMSG_TCP_PASSTHROUGH, (unsigned char *)&param->tcp_passthrough, sizeof(param->tcp_passthrough));
struct side_conn_param *client_side = &profile_param->client_side; struct side_conn_param *client_side = &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_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_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_NODELAY, (unsigned char *)&client_side->nodelay, sizeof(client_side->nodelay));
@@ -378,7 +267,7 @@ void tcp_policy_enforce(struct tcp_policy_enforcer *enforcer, struct tfe_cmsg *c
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_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)); 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; struct side_conn_param *server_side = &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_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_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_NODELAY, (unsigned char *)&server_side->nodelay, sizeof(server_side->nodelay));
@@ -389,12 +278,13 @@ void tcp_policy_enforce(struct tcp_policy_enforcer *enforcer, struct tfe_cmsg *c
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_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_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 " TFE_LOG_INFO(tcp_enforcer->logger, "hit 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} " "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} ", "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, profile_id, 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, 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); 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); profile_param_free(param);
intercept_param_free(policy_param);
return 0;
} }

View File

@@ -1,8 +1,9 @@
#pragma once #pragma once
#include <tfe_cmsg.h> #include <tfe_cmsg.h>
#include <MESA/maat.h>
struct tcp_policy_enforcer; struct tcp_policy_enforcer;
struct tcp_policy_enforcer *tcp_policy_enforcer_create(void *logger); struct tcp_policy_enforcer *tcp_policy_enforcer_create(void *logger);
void tcp_policy_enforcer_destory(struct tcp_policy_enforcer *enforcer); 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); // return 0 : success
// return -1 : error (need passthrough)
int tcp_policy_enforce(struct tcp_policy_enforcer *tcp_enforcer, struct tfe_cmsg *cmsg);