feature(adapt maat): PXY_PROFILE_DECRYPTION adapt uuid

This commit is contained in:
luwenpeng
2024-09-25 16:08:00 +08:00
parent 4ef367ac41
commit 3617db7201
8 changed files with 283 additions and 200 deletions

View File

@@ -41,16 +41,16 @@ enum ssl_ja3_pinning_status
int sslver_str2num(const char * version_str); int sslver_str2num(const char * version_str);
//s_stream must be upstream. //s_stream must be upstream.
int ssl_stream_set_integer_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT opt_type, int opt_val); int ssl_stream_set_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); int ssl_stream_get_integer_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT opt_type, int *opt_val);
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);
int ssl_stream_set_uuid_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT opt_type, uuid_t *uuid);
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); void ssl_stream_get_policy_id(struct ssl_stream *upstream, uuid_t *policy_id);
int ssl_stream_get_decrypted_profile_id(struct ssl_stream *upstream); void ssl_stream_get_decrypted_profile_id(struct ssl_stream *upstream, uuid_t *profile_id);
int ssl_stream_get_trusted_keyring_profile_id(struct ssl_stream *upstream); void ssl_stream_get_trusted_keyring_profile_id(struct ssl_stream *upstream, uuid_t *profile_id);
int ssl_stream_get_untrusted_keyring_profile_id(struct ssl_stream *upstream); void ssl_stream_get_untrusted_keyring_profile_id(struct ssl_stream *upstream, uuid_t *profile_id);
unsigned int is_ssl_debug(); unsigned int is_ssl_debug();

View File

@@ -34,12 +34,12 @@ 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, // size uint64_t TFE_CMSG_POLICY_ID = 0x10, // size uuid_t
TFE_CMSG_STREAM_TRACE_ID = 0x11, TFE_CMSG_STREAM_TRACE_ID = 0x11,
TFE_CMSG_TCP_OPTION_PROFILE_ID, // size int TFE_CMSG_TCP_OPTION_PROFILE_ID, // size uuid_t
TFE_CMSG_DECRYPTION_PROFILE_ID, // size int TFE_CMSG_DECRYPTION_PROFILE_ID, // size uuid_t
TFE_CMSG_KEYRING_FOR_TRUSTED_ID, // size int TFE_CMSG_KEYRING_FOR_TRUSTED_ID, // size uuid_t
TFE_CMSG_KEYRING_FOR_UNTRUSTED, // size int TFE_CMSG_KEYRING_FOR_UNTRUSTED, // size uuid_t
TFE_CMSG_SSL_INTERCEPT_STATE, // size uint8_t, 0-passthrough, 1-intercept, 2-shutdown, referer from enum ssl_stream_action TFE_CMSG_SSL_INTERCEPT_STATE, // size uint8_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

@@ -65,7 +65,7 @@
extern struct tcp_policy_enforcer *tcp_policy_enforcer_create(void *logger); extern struct tcp_policy_enforcer *tcp_policy_enforcer_create(void *logger);
extern struct chaining_policy_enforcer *chaining_policy_enforcer_create(void *logger); extern struct chaining_policy_enforcer *chaining_policy_enforcer_create(void *logger);
extern struct ssl_policy_enforcer *ssl_policy_enforcer_create(void *logger); extern struct ssl_policy_enforcer *ssl_policy_enforcer_create();
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);
static int signals[] = {SIGHUP, SIGPIPE, SIGUSR1, SIGUSR2}; static int signals[] = {SIGHUP, SIGPIPE, SIGUSR1, SIGUSR2};

View File

@@ -199,8 +199,8 @@ struct ssl_upstream_parts
struct ssl_service_status svc_status; struct ssl_service_status svc_status;
enum ssl_stream_action action; enum ssl_stream_action action;
int apln_enabled; int apln_enabled;
int keyring_for_trusted; uuid_t keyring_for_trusted;
int keyring_for_untrusted; uuid_t keyring_for_untrusted;
struct ssl_chello * client_hello; struct ssl_chello * client_hello;
uint8_t is_server_cert_verify_passed; uint8_t is_server_cert_verify_passed;
}; };
@@ -2162,12 +2162,6 @@ int ssl_stream_set_integer_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT
case SSL_STREAM_OPT_ENABLE_ALPN: case SSL_STREAM_OPT_ENABLE_ALPN:
upstream->up_parts.apln_enabled=opt_val; upstream->up_parts.apln_enabled=opt_val;
break; break;
case SSL_STREAM_OPT_KEYRING_FOR_TRUSTED:
upstream->up_parts.keyring_for_trusted=opt_val;
break;
case SSL_STREAM_OPT_KEYRING_FOR_UNTRUSTED:
upstream->up_parts.keyring_for_untrusted=opt_val;
break;
default: default:
assert(0); assert(0);
return 0; return 0;
@@ -2206,52 +2200,65 @@ int ssl_stream_get_integer_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT
} }
uint64_t ssl_stream_get_policy_id(struct ssl_stream *upstream) void ssl_stream_get_policy_id(struct ssl_stream *upstream, uuid_t *policy_id)
{ {
uuid_clear(*policy_id);
uint16_t out_size; uint16_t out_size;
uint64_t policy_id = 0;
struct tfe_cmsg *cmsg = tfe_stream_get0_cmsg(upstream->tcp_stream); 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); int ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_POLICY_ID, (unsigned char *)policy_id, sizeof(uuid_t), &out_size);
assert(ret == 0); assert(ret == 0);
assert(out_size == sizeof(uuid_t));
(void)ret; (void)ret;
return policy_id;
} }
int ssl_stream_get_decrypted_profile_id(struct ssl_stream *upstream) void ssl_stream_get_decrypted_profile_id(struct ssl_stream *upstream, uuid_t *profile_id)
{ {
uuid_clear(*profile_id);
uint16_t out_size; uint16_t out_size;
int profile_id = 0;
struct tfe_cmsg *cmsg = tfe_stream_get0_cmsg(upstream->tcp_stream); 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); int ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_DECRYPTION_PROFILE_ID, (unsigned char *)profile_id, sizeof(uuid_t), &out_size);
assert(ret == 0); assert(ret == 0);
assert(out_size == sizeof(uuid_t));
(void)ret; (void)ret;
return profile_id;
} }
int ssl_stream_get_trusted_keyring_profile_id(struct ssl_stream *upstream) void ssl_stream_get_trusted_keyring_profile_id(struct ssl_stream *upstream, uuid_t *profile_id)
{ {
uuid_clear(*profile_id);
uint16_t out_size; uint16_t out_size;
int keyring_id = 0;
struct tfe_cmsg *cmsg = tfe_stream_get0_cmsg(upstream->tcp_stream); 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); int ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_KEYRING_FOR_TRUSTED_ID, (unsigned char *)profile_id, sizeof(uuid_t), &out_size);
assert(ret == 0); assert(ret == 0);
assert(out_size == sizeof(uuid_t));
(void)ret; (void)ret;
return keyring_id;
} }
int ssl_stream_get_untrusted_keyring_profile_id(struct ssl_stream *upstream) void ssl_stream_get_untrusted_keyring_profile_id(struct ssl_stream *upstream, uuid_t *profile_id)
{ {
uuid_clear(*profile_id);
uint16_t out_size; uint16_t out_size;
int keyring_id = 0;
struct tfe_cmsg *cmsg = tfe_stream_get0_cmsg(upstream->tcp_stream); 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); int ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_KEYRING_FOR_UNTRUSTED, (unsigned char *)profile_id, sizeof(profile_id), &out_size);
assert(ret == 0); assert(ret == 0);
assert(out_size == sizeof(uuid_t));
(void)ret; (void)ret;
}
return keyring_id; int ssl_stream_set_uuid_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT opt_type, uuid_t *uuid)
{
switch (opt_type)
{
case SSL_STREAM_OPT_KEYRING_FOR_TRUSTED:
uuid_copy(upstream->up_parts.keyring_for_trusted, *uuid);
break;
case SSL_STREAM_OPT_KEYRING_FOR_UNTRUSTED:
uuid_copy(upstream->up_parts.keyring_for_untrusted, *uuid);
break;
default:
assert(0);
return 0;
}
return 1;
} }
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)

View File

@@ -10,12 +10,11 @@
struct ssl_policy_enforcer struct ssl_policy_enforcer
{ {
struct maat *maat; struct maat *maat;
int profile_table_id;
void* logger;
}; };
struct decryption_param struct decryption_param
{ {
uuid_t uuid;
int ref_cnt; int ref_cnt;
int bypass_ev_cert; int bypass_ev_cert;
int bypass_ct_cert; int bypass_ct_cert;
@@ -34,251 +33,330 @@ struct decryption_param
int mirror_client_version; int mirror_client_version;
}; };
void profile_param_dup_cb(int table_id, void **to, void **from, long argl, void* argp) static void profile_param_dup_cb(const char *table_name, void **to, void **from, long argl, void *argp)
{ {
struct decryption_param* param= (struct decryption_param*) *from; struct decryption_param *param = (struct decryption_param *)*from;
if(param) if (param)
{ {
__sync_add_and_fetch(&(param->ref_cnt), 1); __sync_add_and_fetch(&(param->ref_cnt), 1);
*to = param; *to = param;
} }
else else
{ {
*to=NULL; *to = NULL;
} }
return; return;
} }
void profile_param_free_cb(int table_id, void **ad, long argl, void* argp)
static void profile_param_free_cb(const char *table_name, void **ad, long argl, void *argp)
{ {
struct decryption_param* param= (struct decryption_param*) *ad; struct decryption_param *param = (struct decryption_param *)*ad;
if(param==NULL) if (param == NULL)
{ {
return; return;
} }
if ((__sync_sub_and_fetch(&param->ref_cnt, 1) == 0)) if ((__sync_sub_and_fetch(&param->ref_cnt, 1) == 0))
{ {
char uuid_str[UUID_STRING_SIZE];
uuid_unparse(param->uuid, uuid_str);
TFE_LOG_INFO(g_default_logger, "Del decryption profile: %s", uuid_str);
free(param); free(param);
*ad=NULL; *ad = NULL;
} }
} }
void profile_param_free(struct decryption_param* param)
{
profile_param_free_cb(0, (void**)&param, 0, NULL);
return;
}
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;
size_t offset=0, len=0;
char* json_str=NULL;
cJSON *json=NULL, *exclusions=NULL, *cert_verify=NULL, *approach=NULL, *ssl_ver=NULL, *item=NULL;
struct decryption_param* param=NULL;
struct ssl_policy_enforcer* enforcer=(struct ssl_policy_enforcer*)argp;
ret=maat_helper_read_column(table_line, 3, &offset, &len); static void profile_param_free(struct decryption_param *param)
if(ret<0) {
profile_param_free_cb(NULL, (void **)&param, 0, NULL);
}
static void profile_param_new_cb(const char *table_name, const char *key, const char *table_line, void **ad, long argl, void *argp)
{
int ret = 0;
cJSON *json = NULL;
cJSON *object = NULL;
cJSON *exclusions = NULL;
cJSON *cert_verify = NULL;
cJSON *approach = NULL;
cJSON *ssl_ver = NULL;
cJSON *item = NULL;
struct decryption_param *param = NULL;
char *json_str = strdup(table_line);
json = cJSON_Parse(json_str);
if (json == NULL)
{ {
TFE_LOG_ERROR(enforcer->logger, "Get decryption param: %s", table_line); TFE_LOG_ERROR(g_default_logger, "Invalid decryption parameter: (invalid json format) %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 decryption parameter: %s", table_line);
goto error_out; goto error_out;
} }
param=ALLOC(struct decryption_param, 1); param = ALLOC(struct decryption_param, 1);
param->ref_cnt=1; param->ref_cnt = 1;
param->bypass_mutual_auth=1; param->bypass_mutual_auth = 1;
param->bypass_pinning=1; param->bypass_pinning = 1;
param->mirror_client_version=1; param->mirror_client_version = 1;
uuid_parse(key, param->uuid);
exclusions=cJSON_GetObjectItem(json, "dynamic_bypass"); object = cJSON_GetObjectItem(json, "decryption");
if(exclusions) if (!object || !cJSON_IsObject(object))
{ {
item=cJSON_GetObjectItem(exclusions, "ev_cert"); TFE_LOG_ERROR(g_default_logger, "Invalid decryption parameter: (invalid decryption param) %s", table_line);
if(item && item->type==cJSON_Number) param->bypass_ev_cert=item->valueint; goto error_out;
item=cJSON_GetObjectItem(exclusions, "cert_transparency");
if(item && item->type==cJSON_Number) param->bypass_ct_cert=item->valueint;
item=cJSON_GetObjectItem(exclusions, "mutual_authentication");
if(item && item->type==cJSON_Number) param->bypass_mutual_auth=item->valueint;
item=cJSON_GetObjectItem(exclusions, "cert_pinning");
if(item && item->type==cJSON_Number) param->bypass_pinning=item->valueint;
item=cJSON_GetObjectItem(exclusions, "protocol_errors");
if(item && item->type==cJSON_Number) param->bypass_protocol_errors=item->valueint;
item=cJSON_GetObjectItem(exclusions, "trusted_root_cert_is_not_installed_on_client");
if(item && item->type==cJSON_Number) param->bypass_uninstall_cert_traffic=item->valueint;
} }
ssl_ver=cJSON_GetObjectItem(json, "protocol_version");
if(ssl_ver) exclusions = cJSON_GetObjectItem(object, "dynamic_bypass");
if (exclusions)
{ {
item=cJSON_GetObjectItem(ssl_ver, "mirror_client"); item = cJSON_GetObjectItem(exclusions, "ev_cert");
if(item && item->type==cJSON_Number) param->mirror_client_version=item->valueint; if (item && item->type == cJSON_Number)
if(!param->mirror_client_version)
{ {
item=cJSON_GetObjectItem(ssl_ver, "min"); param->bypass_ev_cert = item->valueint;
if(item && item->type==cJSON_String) param->ssl_min_version=sslver_str2num(item->valuestring); }
item=cJSON_GetObjectItem(ssl_ver, "max"); item = cJSON_GetObjectItem(exclusions, "cert_transparency");
if(item && item->type==cJSON_String) param->ssl_max_version=sslver_str2num(item->valuestring); if (item && item->type == cJSON_Number)
if(param->ssl_min_version<0||param->ssl_max_version<0) {
param->bypass_ct_cert = item->valueint;
}
item = cJSON_GetObjectItem(exclusions, "mutual_authentication");
if (item && item->type == cJSON_Number)
{
param->bypass_mutual_auth = item->valueint;
}
item = cJSON_GetObjectItem(exclusions, "cert_pinning");
if (item && item->type == cJSON_Number)
{
param->bypass_pinning = item->valueint;
}
item = cJSON_GetObjectItem(exclusions, "protocol_errors");
if (item && item->type == cJSON_Number)
{
param->bypass_protocol_errors = item->valueint;
}
item = cJSON_GetObjectItem(exclusions, "trusted_root_cert_is_not_installed_on_client");
if (item && item->type == cJSON_Number)
{
param->bypass_uninstall_cert_traffic = item->valueint;
}
}
ssl_ver = cJSON_GetObjectItem(object, "protocol_version");
if (ssl_ver)
{
item = cJSON_GetObjectItem(ssl_ver, "mirror_client");
if (item && item->type == cJSON_Number)
{
param->mirror_client_version = item->valueint;
}
if (!param->mirror_client_version)
{
item = cJSON_GetObjectItem(ssl_ver, "min");
if (item && item->type == cJSON_String)
{ {
param->mirror_client_version=1; param->ssl_min_version = sslver_str2num(item->valuestring);
TFE_LOG_ERROR(enforcer->logger, "Invalid intercept parameter: ssl version = %s", item->valuestring); }
item = cJSON_GetObjectItem(ssl_ver, "max");
if (item && item->type == cJSON_String)
{
param->ssl_max_version = sslver_str2num(item->valuestring);
}
if (param->ssl_min_version < 0 || param->ssl_max_version < 0)
{
param->mirror_client_version = 1;
TFE_LOG_ERROR(g_default_logger, "Invalid intercept parameter: ssl version = %s", item->valuestring);
} }
} }
item=cJSON_GetObjectItem(ssl_ver, "allow_http2"); item = cJSON_GetObjectItem(ssl_ver, "allow_http2");
if(item && item->type==cJSON_Number) param->allow_http2=item->valueint; if (item && item->type == cJSON_Number)
}
cert_verify=cJSON_GetObjectItem(json, "certificate_checks");
if(cert_verify)
{
approach=cJSON_GetObjectItem(cert_verify, "approach");
if(approach)
{ {
item=cJSON_GetObjectItem(approach, "cn"); param->allow_http2 = item->valueint;
if(item && item->type==cJSON_Number && item->valueint==0) param->no_verify_cn=1;
item=cJSON_GetObjectItem(approach, "issuer");
if(item && item->type==cJSON_Number && item->valueint==0) param->no_verify_issuer=1;
item=cJSON_GetObjectItem(approach, "self-signed");
if(item && item->type==cJSON_Number && item->valueint==0) param->no_verify_self_signed=1;
item=cJSON_GetObjectItem(approach, "expiration");
if(item && item->type==cJSON_Number && item->valueint==0) param->no_verify_expry_date=1;
} }
item=cJSON_GetObjectItem(cert_verify, "fail_action"); }
if(item && item->type==cJSON_String) cert_verify = cJSON_GetObjectItem(object, "certificate_checks");
if (cert_verify)
{
approach = cJSON_GetObjectItem(cert_verify, "approach");
if (approach)
{ {
if(0==strcasecmp(item->valuestring, "Fail-Close")) item = cJSON_GetObjectItem(approach, "cn");
if (item && item->type == cJSON_Number && item->valueint == 0)
{ {
param->block_fake_cert=1; param->no_verify_cn = 1;
}
item = cJSON_GetObjectItem(approach, "issuer");
if (item && item->type == cJSON_Number && item->valueint == 0)
{
param->no_verify_issuer = 1;
}
item = cJSON_GetObjectItem(approach, "self-signed");
if (item && item->type == cJSON_Number && item->valueint == 0)
{
param->no_verify_self_signed = 1;
}
item = cJSON_GetObjectItem(approach, "expiration");
if (item && item->type == cJSON_Number && item->valueint == 0)
{
param->no_verify_expry_date = 1;
}
}
item = cJSON_GetObjectItem(cert_verify, "fail_action");
if (item && item->type == cJSON_String)
{
if (0 == strcasecmp(item->valuestring, "Fail-Close"))
{
param->block_fake_cert = 1;
} }
} }
} }
*ad=param; *ad = param;
TFE_LOG_INFO(enforcer->logger, "Add decryption profile: %s", key); TFE_LOG_INFO(g_default_logger, "Add decryption profile: %s", key);
cJSON_Delete(json);
free(json_str);
error_out: error_out:
if (json) if (json)
{
cJSON_Delete(json); cJSON_Delete(json);
}
if (json_str) if (json_str)
{
free(json_str); free(json_str);
}
if (param)
{
free(param);
}
return; return;
} }
struct ssl_policy_enforcer* ssl_policy_enforcer_create(void* logger)
struct ssl_policy_enforcer *ssl_policy_enforcer_create()
{ {
UNUSED int ret=0; 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=tfe_get_maat_handle(); enforcer->maat = tfe_get_maat_handle();
enforcer->logger=logger; ret = maat_plugin_table_ex_schema_register(enforcer->maat,
enforcer->profile_table_id=maat_get_table_id(enforcer->maat, "PXY_PROFILE_DECRYPTION"); "PXY_PROFILE_DECRYPTION",
assert(enforcer->profile_table_id >= 0); profile_param_new_cb,
ret=maat_plugin_table_ex_schema_register(enforcer->maat, profile_param_free_cb,
"PXY_PROFILE_DECRYPTION", profile_param_dup_cb,
profile_param_new_cb, 0,
profile_param_free_cb, enforcer);
profile_param_dup_cb, assert(ret == 0);
0,
enforcer);
assert(ret==0);
return enforcer; return enforcer;
} }
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;
enum ssl_stream_action action=SSL_ACTION_PASSTHROUGH; enum ssl_stream_action action = SSL_ACTION_PASSTHROUGH;
UNUSED int ret=0; UNUSED int ret = 0;
char sni[512]; char sni[512];
char addr_string[512]; char addr_string[512];
char profile_id_str[16]={0}; char rule_uuid_str[UUID_STRING_SIZE];
char decrypted_uuid_str[UUID_STRING_SIZE];
uint64_t policy_id = ssl_stream_get_policy_id(upstream);
int decryption_profile_id = ssl_stream_get_decrypted_profile_id(upstream);
int keyring_for_trusted = ssl_stream_get_trusted_keyring_profile_id(upstream);
int keyring_for_untrusted = ssl_stream_get_untrusted_keyring_profile_id(upstream);
uuid_t rule_uuid;
uuid_t decrypted_uuid;
uuid_t trusted_keyring_uuid;
uuid_t untrusted_keyring_uuid;
ssl_stream_get_policy_id(upstream, &rule_uuid);
ssl_stream_get_decrypted_profile_id(upstream, &decrypted_uuid);
ssl_stream_get_trusted_keyring_profile_id(upstream, &trusted_keyring_uuid);
ssl_stream_get_untrusted_keyring_profile_id(upstream, &untrusted_keyring_uuid);
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);
snprintf(profile_id_str, sizeof(profile_id_str), "%u", decryption_profile_id); uuid_unparse(rule_uuid, rule_uuid_str);
struct decryption_param *profile_param=(struct decryption_param *)maat_plugin_table_get_ex_data(enforcer->maat, enforcer->profile_table_id, profile_id_str, strlen(profile_id_str)); uuid_unparse(decrypted_uuid, decrypted_uuid_str);
if (profile_param==NULL) TFE_LOG_DEBUG(g_default_logger, "%s %s enforce policy %s", addr_string, sni, rule_uuid_str);
struct decryption_param *profile_param = (struct decryption_param *)maat_plugin_table_get_ex_data(enforcer->maat, "PXY_PROFILE_DECRYPTION", (const char *)&decrypted_uuid, sizeof(uuid_t));
if (profile_param == NULL)
{ {
TFE_LOG_INFO(enforcer->logger, "Failed to get decryption parameter of profile %s.", profile_id_str); TFE_LOG_INFO(g_default_logger, "Failed to get decryption parameter of profile %s.", decrypted_uuid_str);
ssl_stream_set_cmsg_string(upstream, TFE_CMSG_SSL_PASSTHROUGH_REASON, "Invalid Decryption Param"); ssl_stream_set_cmsg_string(upstream, TFE_CMSG_SSL_PASSTHROUGH_REASON, "Invalid Decryption Param");
return SSL_ACTION_PASSTHROUGH; return SSL_ACTION_PASSTHROUGH;
} }
int pinning_staus=0, is_ev=0, is_ct=0, is_mauth=0, has_error=0, ja3_pinning_status=0; int pinning_staus = 0, is_ev = 0, is_ct = 0, is_mauth = 0, has_error = 0, ja3_pinning_status = 0;
if(!profile_param->mirror_client_version) if (!profile_param->mirror_client_version)
{ {
ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_PROTOCOL_MIN_VERSION, profile_param->ssl_min_version); ret = ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_PROTOCOL_MIN_VERSION, profile_param->ssl_min_version);
ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_PROTOCOL_MAX_VERSION, profile_param->ssl_max_version); assert(ret == 0);
ret = ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_PROTOCOL_MAX_VERSION, profile_param->ssl_max_version);
assert(ret == 0);
} }
if(profile_param->allow_http2) if (profile_param->allow_http2)
{ {
ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_ENABLE_ALPN, 1); ret = ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_ENABLE_ALPN, 1);
assert(ret == 0);
} }
ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_COMMON_NAME, profile_param->no_verify_cn); ret = ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_COMMON_NAME, profile_param->no_verify_cn);
ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_ISSUER, profile_param->no_verify_issuer); assert(ret == 0);
ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_SELF_SIGNED, profile_param->no_verify_self_signed); ret = ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_ISSUER, profile_param->no_verify_issuer);
ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_EXPIRY_DATE, profile_param->no_verify_expry_date); assert(ret == 0);
if(profile_param->block_fake_cert) ret = ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_SELF_SIGNED, profile_param->no_verify_self_signed);
assert(ret == 0);
ret = ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_EXPIRY_DATE, profile_param->no_verify_expry_date);
assert(ret == 0);
if (profile_param->block_fake_cert)
{ {
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);
assert(ret == 0);
} }
ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_KEYRING_FOR_TRUSTED, keyring_for_trusted); ret = ssl_stream_set_uuid_opt(upstream, SSL_STREAM_OPT_KEYRING_FOR_TRUSTED, &trusted_keyring_uuid);
ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_KEYRING_FOR_UNTRUSTED, keyring_for_untrusted); assert(ret == 0);
ret = ssl_stream_set_uuid_opt(upstream, SSL_STREAM_OPT_KEYRING_FOR_UNTRUSTED, &untrusted_keyring_uuid);
ret=ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_PINNING_STATUS, &pinning_staus); assert(ret == 0);
assert(ret==0); ret = ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_PINNING_STATUS, &pinning_staus);
ret=ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_JA3_PINNING_STATUS, &ja3_pinning_status); assert(ret == 0);
assert(ret==0); ret = ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_JA3_PINNING_STATUS, &ja3_pinning_status);
ret=ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_IS_EV_CERT, &is_ev); assert(ret == 0);
assert(ret==0); ret = ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_IS_EV_CERT, &is_ev);
ret=ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_IS_MUTUAL_AUTH, &is_mauth); assert(ret == 0);
ret=ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_IS_CT_CERT, &is_ct); ret = ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_IS_MUTUAL_AUTH, &is_mauth);
ret=ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_HAS_PROTOCOL_ERRORS, &has_error); assert(ret == 0);
assert(ret==0); ret = ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_IS_CT_CERT, &is_ct);
assert(ret == 0);
ret = ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_HAS_PROTOCOL_ERRORS, &has_error);
assert(ret == 0);
if (pinning_staus == 1 && ja3_pinning_status == JA3_PINNING_STATUS_NOT_PINNING && profile_param->bypass_uninstall_cert_traffic) if (pinning_staus == 1 && ja3_pinning_status == JA3_PINNING_STATUS_NOT_PINNING && profile_param->bypass_uninstall_cert_traffic)
{ {
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_id); TFE_LOG_DEBUG(g_default_logger, "%s %s enforce policy %s, action PASSTHROUGH due to Certificate Not Installed", addr_string, sni, rule_uuid_str);
} }
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_id); TFE_LOG_DEBUG(g_default_logger, "%s %s enforce policy %s, action PASSTHROUGH due to Certificate Pinning", addr_string, sni, rule_uuid_str);
} }
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_id); TFE_LOG_DEBUG(g_default_logger, "%s %s enforce policy %s, action PASSTHROUGH due to Mutual Authentication", addr_string, sni, rule_uuid_str);
} }
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_id); TFE_LOG_DEBUG(g_default_logger, "%s %s enforce policy %s, action PASSTHROUGH due to EV Certificate", addr_string, sni, rule_uuid_str);
} }
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_id); TFE_LOG_DEBUG(g_default_logger, "%s %s enforce policy %s, action PASSTHROUGH due to Certificate Transparency", addr_string, sni, rule_uuid_str);
} }
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_id); TFE_LOG_DEBUG(g_default_logger, "%s %s enforce policy %s, action PASSTHROUGH due to Protocol Errors", addr_string, sni, rule_uuid_str);
} }
else else
{ {
@@ -286,7 +364,6 @@ enum ssl_stream_action ssl_policy_enforce(struct ssl_stream *upstream, void* u_p
} }
profile_param_free(profile_param); profile_param_free(profile_param);
profile_param=NULL; profile_param = NULL;
return action; return action;
} }

View File

@@ -3,6 +3,6 @@
#include <MESA/maat.h> #include <MESA/maat.h>
struct ssl_policy_enforcer; struct ssl_policy_enforcer;
struct ssl_policy_enforcer* ssl_policy_enforcer_create(void* logger); struct ssl_policy_enforcer* ssl_policy_enforcer_create();
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);

View File

@@ -247,9 +247,9 @@
{ {
"table_name": "PXY_PROFILE_DECRYPTION", "table_name": "PXY_PROFILE_DECRYPTION",
"table_content": [ "table_content": [
"0\ttest\t{\"dynamic_bypass\":{\"ev_cert\":0,\"cert_transparency\":0,\"mutual_authentication\":1,\"cert_pinning\":1,\"protocol_errors\":1,\"trusted_root_cert_is_not_installed_on_client\":1},\"protocol_version\":{\"min\":\"ssl3\",\"max\":\"ssl3\",\"mirror_client\":1,\"allow_http2\":1},\"certificate_checks\":{\"approach\":{\"cn\":1,\"issuer\":1,\"self-signed\":1,\"expiration\":0},\"fail_action\":\"pass-through\"}}\t1", "{\"uuid\":\"DECRYPT0-0000-0000-0000-000000000001\",\"decryption\":{\"dynamic_bypass\":{\"ev_cert\":0,\"cert_transparency\":0,\"mutual_authentication\":1,\"cert_pinning\":1,\"protocol_errors\":1,\"trusted_root_cert_is_not_installed_on_client\":1},\"protocol_version\":{\"min\":\"ssl3\",\"max\":\"ssl3\",\"mirror_client\":1,\"allow_http2\":1},\"certificate_checks\":{\"approach\":{\"cn\":1,\"issuer\":1,\"self-signed\":1,\"expiration\":0},\"fail_action\":\"pass-through\"}},\"is_valid\":1}",
"3\ttest\t{\"dynamic_bypass\":{\"ev_cert\":1,\"cert_transparency\":1,\"mutual_authentication\":1,\"cert_pinning\":1,\"protocol_errors\":1,\"trusted_root_cert_is_not_installed_on_client\":0},\"protocol_version\":{\"min\":\"ssl3\",\"max\":\"tls13\",\"mirror_client\":1,\"allow_http2\":1},\"certificate_checks\":{\"approach\":{\"cn\":1,\"issuer\":1,\"self-signed\":1,\"expiration\":1},\"fail_action\":\"fail-close\"}}\t1", "{\"uuid\":\"DECRYPT0-0000-0000-0000-000000000003\",\"decryption\":{\"dynamic_bypass\":{\"ev_cert\":1,\"cert_transparency\":1,\"mutual_authentication\":1,\"cert_pinning\":1,\"protocol_errors\":1,\"trusted_root_cert_is_not_installed_on_client\":0},\"protocol_version\":{\"min\":\"ssl3\",\"max\":\"tls13\",\"mirror_client\":1,\"allow_http2\":1},\"certificate_checks\":{\"approach\":{\"cn\":1,\"issuer\":1,\"self-signed\":1,\"expiration\":1},\"fail_action\":\"fail-close\"}},\"is_valid\":1}",
"4\ttest\t{\"dynamic_bypass\":{\"ev_cert\":0,\"cert_transparency\":0,\"mutual_authentication\":0,\"cert_pinning\":0,\"protocol_errors\":0,\"trusted_root_cert_is_not_installed_on_client\":0},\"protocol_version\":{\"min\":\"ssl3\",\"max\":\"ssl3\",\"mirror_client\":0,\"allow_http2\":0},\"certificate_checks\":{\"approach\":{\"cn\":0,\"issuer\":0,\"self-signed\":0,\"expiration\":0},\"fail_action\":\"pass-through\"}}\t1" "{\"uuid\":\"DECRYPT0-0000-0000-0000-000000000004\",\"decryption\":{\"dynamic_bypass\":{\"ev_cert\":0,\"cert_transparency\":0,\"mutual_authentication\":0,\"cert_pinning\":0,\"protocol_errors\":0,\"trusted_root_cert_is_not_installed_on_client\":0},\"protocol_version\":{\"min\":\"ssl3\",\"max\":\"ssl3\",\"mirror_client\":0,\"allow_http2\":0},\"certificate_checks\":{\"approach\":{\"cn\":0,\"issuer\":0,\"self-signed\":0,\"expiration\":0},\"fail_action\":\"pass-through\"}},\"is_valid\":1}"
] ]
}, },
{ {

View File

@@ -356,10 +356,9 @@
"table_id":32, "table_id":32,
"table_name":"PXY_PROFILE_DECRYPTION", "table_name":"PXY_PROFILE_DECRYPTION",
"table_type":"plugin", "table_type":"plugin",
"valid_column":4,
"custom": { "custom": {
"key":1, "key_type":"pointer",
"key_type":"pointer" "key_name":"uuid"
} }
}, },
{ {