业务层拦截策略(ssl policy)对接ssl stream。

This commit is contained in:
zhengchao
2019-05-19 17:45:16 +08:00
parent 61bc647d1f
commit 7cbd432a25
5 changed files with 89 additions and 46 deletions

View File

@@ -8,7 +8,7 @@
struct ssl_policy_enforcer
{
Maat_feather_t maat;
int compile_table_id;
int table_id;
void* logger;
};
struct intercept_param
@@ -27,24 +27,19 @@ struct intercept_param
int block_fake_cert;
int ssl_min_version;
int ssl_max_version;
int mirror_client;
int mirror_client_version;
int decrypt_mirror_enabled;
int mirror_profile_id;
};
struct ssl_policy_enforcer* ssl_policy_enforcer_create(void)
{
struct ssl_policy_enforcer* enforcer=ALLOC(struct ssl_policy_enforcer, 1);
return enforcer;
}
void intercept_policy_dup_cb(int table_id, MAAT_PLUGIN_EX_DATA* to, MAAT_PLUGIN_EX_DATA* from, long argl, void* argp)
void intercept_param_dup_cb(int table_id, MAAT_PLUGIN_EX_DATA* to, MAAT_PLUGIN_EX_DATA* from, long argl, void* argp)
{
struct intercept_param* param= (struct intercept_param*) *from;
param->ref_cnt++;
*to = param;
return;
}
void intercept_policy_new_cb(int table_id, const char* key, const char* table_line, MAAT_PLUGIN_EX_DATA* ad, long argl, void* argp)
void intercept_param_new_cb(int table_id, const char* key, const char* table_line, MAAT_PLUGIN_EX_DATA* ad, long argl, void* argp)
{
int ret=0;
size_t intercept_user_region_offset=0, len=0;
@@ -116,11 +111,14 @@ void intercept_policy_new_cb(int table_id, const char* key, const char* table_li
if(ssl_ver)
{
item=cJSON_GetObjectItem(ssl_ver, "mirror_client");
if(item && item->type==cJSON_String) param->mirror_client=item->valueint;
item=cJSON_GetObjectItem(ssl_ver, "min");
if(item && item->type==cJSON_String) param->ssl_min_version=sslver_str2num(item->string);
item=cJSON_GetObjectItem(ssl_ver, "max");
if(item && item->type==cJSON_String) param->ssl_max_version=sslver_str2num(item->string);
if(item && item->type==cJSON_String) param->mirror_client_version=item->valueint;
if(!param->mirror_client_version)
{
item=cJSON_GetObjectItem(ssl_ver, "min");
if(item && item->type==cJSON_String) param->ssl_min_version=sslver_str2num(item->string);
item=cJSON_GetObjectItem(ssl_ver, "max");
if(item && item->type==cJSON_String) param->ssl_max_version=sslver_str2num(item->string);
}
}
*ad=param;
TFE_LOG_INFO(enforcer->logger, "Add intercept policy: %d", param->policy_id);
@@ -129,7 +127,7 @@ error_out:
free(json_str);
return;
}
void intercept_policy_free_cb(int table_id, MAAT_PLUGIN_EX_DATA* ad, long argl, void* argp)
void intercept_param_free_cb(int table_id, MAAT_PLUGIN_EX_DATA* ad, long argl, void* argp)
{
struct ssl_policy_enforcer* enforcer=(struct ssl_policy_enforcer*)argp;
struct intercept_param* param= (struct intercept_param*) *ad;
@@ -142,45 +140,77 @@ void intercept_policy_free_cb(int table_id, MAAT_PLUGIN_EX_DATA* ad, long argl,
*ad=NULL;
}
}
void ssl_policy_enforcer_init(struct ssl_policy_enforcer* enforcer, Maat_feather_t maat, void* logger)
void intercept_param_free(struct intercept_param* param)
{
intercept_param_free_cb(0, (void**)&param, 0, NULL);
return;
}
struct ssl_policy_enforcer* ssl_policy_enforcer_create(Maat_feather_t maat, void* logger)
{
struct ssl_policy_enforcer* enforcer=ALLOC(struct ssl_policy_enforcer, 1);
enforcer->maat=maat;
enforcer->logger=logger;
enforcer->compile_table_id=Maat_table_register(enforcer->maat, "PXY_INTERCEPT_COMPILE");
enforcer->table_id=Maat_table_register(enforcer->maat, "PXY_INTERCEPT_COMPILE");
int ret=Maat_plugin_EX_register(enforcer->maat,
enforcer->compile_table_id,
intercept_policy_new_cb,
intercept_policy_free_cb,
intercept_policy_dup_cb,
enforcer->table_id,
intercept_param_new_cb,
intercept_param_free_cb,
intercept_param_dup_cb,
NULL,
0,
enforcer);
assert(ret==1);
return;
return enforcer;
}
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;
struct intercept_param *param=NULL;
enum ssl_stream_action action=SSL_ACTION_PASSTHROUGH;
UNUSED int ret=0;
int pinning_staus=0, is_ev=0, is_mauth=0;
int policy_id=0;
char policy_id_str[16]={0};
snprintf(policy_id_str, sizeof(policy_id_str), "%d", policy_id);
param=(struct intercept_param *)Maat_plugin_get_EX_data(enforcer->maat, enforcer->table_id, policy_id_str);
if(param==NULL)
{
TFE_LOG_INFO(enforcer->logger, "Failed to get intercept parameter of policy %d.", param->policy_id);
return SSL_ACTION_PASSTHROUGH;
}
int pinning_staus=0, is_ev=0, is_ct=0, is_mauth=0;
if(!param->mirror_client_version)
{
ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_PROTOCOL_MIN_VERSION, SSL3_VERSION);
ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_PROTOCOL_MIN_VERSION, TLS1_3_VERSION);
}
ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_COMMON_NAME, param->no_verify_cn);
ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_ISSUER, param->no_verify_issuer);
ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_SELF_SIGNED, param->no_verify_self_signed);
ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_EXPIRY_DATE, param->no_verify_expry_date);
if(param->block_fake_cert)
{
ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_BLOCK_FAKE_CERT, 1);
}
ret=ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_PINNING_STATUS, &pinning_staus);
assert(ret==1);
ret=ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_IS_EV_CERT, &is_ev);
assert(ret==1);
ret=ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_IS_MUTUAL_AUTH, &is_mauth);
ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_EXPIRY_DATE, 1);
ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_PROTOCOL_MIN_VERSION, SSL3_VERSION);
ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_PROTOCOL_MIN_VERSION, TLS1_3_VERSION);
ret=ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_IS_CT_CERT, &is_ct);
assert(ret=1);
if(pinning_staus>0||is_ev||is_mauth)
if( (pinning_staus>1 && param->bypass_pinning) ||
(is_mauth && param->bypass_mutual_auth) ||
(is_ev && param->bypass_ev_cert) ||
(is_ct && param->bypass_ct_cert) )
{
return SSL_ACTION_PASSTHROUGH;
action=SSL_ACTION_PASSTHROUGH;
}
else
{
return SSL_ACTION_INTERCEPT;
action=SSL_ACTION_INTERCEPT;
}
intercept_param_free(param);
param=NULL;
return action;
}