2019-05-17 21:35:20 +08:00
|
|
|
#include <ssl_stream.h>
|
|
|
|
|
#include <tfe_utils.h>
|
2019-05-18 18:27:13 +08:00
|
|
|
#include <MESA/Maat_rule.h>
|
|
|
|
|
#include <cjson/cJSON.h>
|
2019-05-20 15:08:42 +08:00
|
|
|
#include <openssl/ssl.h>
|
|
|
|
|
#include <assert.h>
|
2020-06-11 17:57:18 +08:00
|
|
|
#include <tfe_resource.h>
|
2019-05-18 18:27:13 +08:00
|
|
|
|
2019-05-17 21:35:20 +08:00
|
|
|
struct ssl_policy_enforcer
|
|
|
|
|
{
|
2019-05-18 18:27:13 +08:00
|
|
|
Maat_feather_t maat;
|
2020-04-16 16:17:00 +08:00
|
|
|
int policy_table_id;
|
|
|
|
|
int profile_table_id;
|
2019-05-18 18:27:13 +08:00
|
|
|
void* logger;
|
|
|
|
|
};
|
|
|
|
|
struct intercept_param
|
|
|
|
|
{
|
|
|
|
|
int policy_id;
|
|
|
|
|
int ref_cnt;
|
|
|
|
|
int keyring;
|
2020-04-16 16:17:00 +08:00
|
|
|
/*
|
2019-05-18 18:27:13 +08:00
|
|
|
int bypass_ev_cert;
|
|
|
|
|
int bypass_ct_cert;
|
|
|
|
|
int bypass_mutual_auth;
|
|
|
|
|
int bypass_pinning;
|
2019-05-21 11:47:09 +08:00
|
|
|
int bypass_protocol_errors;
|
2019-05-18 18:27:13 +08:00
|
|
|
int no_verify_cn;
|
|
|
|
|
int no_verify_issuer;
|
|
|
|
|
int no_verify_self_signed;
|
|
|
|
|
int no_verify_expry_date;
|
|
|
|
|
int block_fake_cert;
|
|
|
|
|
int ssl_min_version;
|
|
|
|
|
int ssl_max_version;
|
2019-05-27 14:17:52 +08:00
|
|
|
int allow_http2;
|
2019-05-19 17:45:16 +08:00
|
|
|
int mirror_client_version;
|
2019-05-18 18:27:13 +08:00
|
|
|
int decrypt_mirror_enabled;
|
|
|
|
|
int mirror_profile_id;
|
2020-04-16 16:17:00 +08:00
|
|
|
*/
|
|
|
|
|
int decryption_profile_id;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct decryption_param
|
|
|
|
|
{
|
|
|
|
|
int ref_cnt;
|
|
|
|
|
int bypass_ev_cert;
|
|
|
|
|
int bypass_ct_cert;
|
|
|
|
|
int bypass_mutual_auth;
|
|
|
|
|
int bypass_pinning;
|
2020-05-19 18:07:04 +08:00
|
|
|
int bypass_uninstall_cert_traffic;
|
2020-04-16 16:17:00 +08:00
|
|
|
int bypass_protocol_errors;
|
|
|
|
|
int no_verify_cn;
|
|
|
|
|
int no_verify_issuer;
|
|
|
|
|
int no_verify_self_signed;
|
|
|
|
|
int no_verify_expry_date;
|
|
|
|
|
int block_fake_cert;
|
|
|
|
|
int ssl_min_version;
|
|
|
|
|
int ssl_max_version;
|
|
|
|
|
int allow_http2;
|
|
|
|
|
int mirror_client_version;
|
2019-05-17 21:35:20 +08:00
|
|
|
};
|
2019-05-18 18:27:13 +08:00
|
|
|
|
2019-05-19 17:45:16 +08:00
|
|
|
void intercept_param_dup_cb(int table_id, MAAT_PLUGIN_EX_DATA* to, MAAT_PLUGIN_EX_DATA* from, long argl, void* argp)
|
2019-05-18 18:27:13 +08:00
|
|
|
{
|
|
|
|
|
struct intercept_param* param= (struct intercept_param*) *from;
|
2019-06-21 14:58:35 +08:00
|
|
|
if(param)
|
2019-06-06 19:04:31 +08:00
|
|
|
{
|
2019-06-21 14:58:35 +08:00
|
|
|
__sync_add_and_fetch(&(param->ref_cnt), 1);
|
|
|
|
|
*to = param;
|
2019-06-06 19:04:31 +08:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-06-21 14:58:35 +08:00
|
|
|
*to=NULL;
|
2019-06-06 19:04:31 +08:00
|
|
|
}
|
2019-05-18 18:27:13 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2019-05-19 17:45:16 +08:00
|
|
|
void intercept_param_new_cb(int table_id, const char* key, const char* table_line, MAAT_PLUGIN_EX_DATA* ad, long argl, void* argp)
|
2019-05-18 18:27:13 +08:00
|
|
|
{
|
|
|
|
|
int ret=0;
|
|
|
|
|
size_t intercept_user_region_offset=0, len=0;
|
|
|
|
|
char* json_str=NULL;
|
2020-04-16 16:17:00 +08:00
|
|
|
cJSON *json=NULL, *item=NULL;
|
2019-05-18 18:27:13 +08:00
|
|
|
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)
|
2019-11-19 10:02:51 +08:00
|
|
|
{
|
2019-05-18 18:27:13 +08:00
|
|
|
TFE_LOG_ERROR(enforcer->logger, "Get intercept user region: %s", table_line);
|
|
|
|
|
return;
|
2019-11-19 10:02:51 +08:00
|
|
|
}
|
2019-05-18 18:27:13 +08:00
|
|
|
json_str=ALLOC(char, len+1);
|
2019-11-19 10:02:51 +08:00
|
|
|
memcpy(json_str, table_line+intercept_user_region_offset, len);
|
2019-05-18 18:27:13 +08:00
|
|
|
json=cJSON_Parse(json_str);
|
|
|
|
|
if(json==NULL)
|
|
|
|
|
{
|
|
|
|
|
TFE_LOG_ERROR(enforcer->logger, "Invalid intercept parameter: id = %s", key);
|
|
|
|
|
goto error_out;
|
|
|
|
|
}
|
2019-11-19 10:02:51 +08:00
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
2019-11-25 11:34:14 +08:00
|
|
|
if(0!=strcasecmp(item->valuestring, "SSL")&& 0!=strcasecmp(item->valuestring, "HTTP"))
|
2019-11-19 10:02:51 +08:00
|
|
|
{
|
|
|
|
|
goto error_out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
param=ALLOC(struct intercept_param, 1);
|
2019-05-18 18:27:13 +08:00
|
|
|
param->policy_id=atoi(key);
|
|
|
|
|
param->ref_cnt=1;
|
2020-04-16 16:17:00 +08:00
|
|
|
/*
|
2019-05-18 18:27:13 +08:00
|
|
|
param->bypass_mutual_auth=1;
|
|
|
|
|
param->bypass_pinning=1;
|
2019-05-20 15:08:42 +08:00
|
|
|
param->mirror_client_version=1;
|
2020-04-16 16:17:00 +08:00
|
|
|
*/
|
2019-06-11 17:03:05 +08:00
|
|
|
param->keyring=1;
|
2020-04-16 16:17:00 +08:00
|
|
|
param->decryption_profile_id=0;
|
2019-11-19 10:02:51 +08:00
|
|
|
|
2019-05-18 18:27:13 +08:00
|
|
|
item=cJSON_GetObjectItem(json, "keyring");
|
2019-06-15 12:43:24 +08:00
|
|
|
if(item)
|
|
|
|
|
{
|
|
|
|
|
if(item->type==cJSON_Number)
|
|
|
|
|
{
|
|
|
|
|
param->keyring=item->valueint;
|
|
|
|
|
}
|
|
|
|
|
else if(item->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
param->keyring=atoi(item->valuestring);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TFE_LOG_ERROR(enforcer->logger, "Invalid intercept parameter: %d invalid keyring format", param->policy_id);
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-11-19 10:02:51 +08:00
|
|
|
|
2020-04-16 16:17:00 +08:00
|
|
|
/*
|
2019-10-14 11:12:01 +08:00
|
|
|
exclusions=cJSON_GetObjectItem(json, "dynamic_bypass");
|
2019-05-18 18:27:13 +08:00
|
|
|
if(exclusions)
|
|
|
|
|
{
|
|
|
|
|
item=cJSON_GetObjectItem(exclusions, "ev_cert");
|
|
|
|
|
if(item && item->type==cJSON_Number) param->bypass_ev_cert=item->valueint;
|
|
|
|
|
item=cJSON_GetObjectItem(exclusions, "cert_transparency");
|
|
|
|
|
if(item && item->type==cJSON_Number) param->bypass_ct_cert=item->valueint;
|
2019-10-14 11:12:01 +08:00
|
|
|
item=cJSON_GetObjectItem(exclusions, "mutual_authentication");
|
2019-05-18 18:27:13 +08:00
|
|
|
if(item && item->type==cJSON_Number) param->bypass_mutual_auth=item->valueint;
|
2019-10-14 11:12:01 +08:00
|
|
|
item=cJSON_GetObjectItem(exclusions, "cert_pinning");
|
2019-05-18 18:27:13 +08:00
|
|
|
if(item && item->type==cJSON_Number) param->bypass_pinning=item->valueint;
|
2019-05-21 11:47:09 +08:00
|
|
|
item=cJSON_GetObjectItem(exclusions, "protocol_errors");
|
|
|
|
|
if(item && item->type==cJSON_Number) param->bypass_protocol_errors=item->valueint;
|
|
|
|
|
|
2019-05-18 18:27:13 +08:00
|
|
|
}
|
2019-10-14 11:12:01 +08:00
|
|
|
cert_verify=cJSON_GetObjectItem(json, "certificate_checks");
|
2019-05-18 18:27:13 +08:00
|
|
|
if(cert_verify)
|
|
|
|
|
{
|
|
|
|
|
approach=cJSON_GetObjectItem(cert_verify, "approach");
|
|
|
|
|
if(approach)
|
|
|
|
|
{
|
|
|
|
|
item=cJSON_GetObjectItem(approach, "cn");
|
2019-11-19 10:02:51 +08:00
|
|
|
if(item && item->type==cJSON_Number && item->valueint==0) param->no_verify_cn=1;
|
2019-05-18 18:27:13 +08:00
|
|
|
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;
|
|
|
|
|
}
|
2019-10-14 11:12:01 +08:00
|
|
|
item=cJSON_GetObjectItem(cert_verify, "fail_action");
|
2019-05-18 18:27:13 +08:00
|
|
|
if(item && item->type==cJSON_String)
|
|
|
|
|
{
|
2019-05-24 11:26:41 +08:00
|
|
|
if(0==strcasecmp(item->valuestring, "Fail-Close"))
|
2019-05-18 18:27:13 +08:00
|
|
|
{
|
|
|
|
|
param->block_fake_cert=1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-10-14 11:12:01 +08:00
|
|
|
ssl_ver=cJSON_GetObjectItem(json, "protocol_version");
|
2019-05-18 18:27:13 +08:00
|
|
|
if(ssl_ver)
|
2019-11-19 10:02:51 +08:00
|
|
|
{
|
|
|
|
|
item=cJSON_GetObjectItem(ssl_ver, "mirror_client");
|
2019-05-20 15:08:42 +08:00
|
|
|
if(item && item->type==cJSON_Number) param->mirror_client_version=item->valueint;
|
2019-05-19 17:45:16 +08:00
|
|
|
if(!param->mirror_client_version)
|
|
|
|
|
{
|
2019-11-19 10:02:51 +08:00
|
|
|
item=cJSON_GetObjectItem(ssl_ver, "min");
|
2019-05-24 11:26:41 +08:00
|
|
|
if(item && item->type==cJSON_String) param->ssl_min_version=sslver_str2num(item->valuestring);
|
2019-11-19 10:02:51 +08:00
|
|
|
item=cJSON_GetObjectItem(ssl_ver, "max");
|
2019-05-24 11:26:41 +08:00
|
|
|
if(item && item->type==cJSON_String) param->ssl_max_version=sslver_str2num(item->valuestring);
|
2019-06-10 21:27:27 +08:00
|
|
|
if(param->ssl_min_version<0||param->ssl_max_version<0)
|
|
|
|
|
{
|
|
|
|
|
param->mirror_client_version=1;
|
|
|
|
|
TFE_LOG_ERROR(enforcer->logger, "Invalid intercept parameter: ssl version = %s", item->valuestring);
|
|
|
|
|
}
|
2019-05-19 17:45:16 +08:00
|
|
|
}
|
2019-11-19 10:02:51 +08:00
|
|
|
item=cJSON_GetObjectItem(ssl_ver, "allow_http2");
|
2019-05-27 14:17:52 +08:00
|
|
|
if(item && item->type==cJSON_Number) param->allow_http2=item->valueint;
|
2019-05-18 18:27:13 +08:00
|
|
|
}
|
2020-04-16 16:17:00 +08:00
|
|
|
*/
|
|
|
|
|
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:%d invalid decryption format", param->policy_id);
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-05-18 18:27:13 +08:00
|
|
|
*ad=param;
|
|
|
|
|
TFE_LOG_INFO(enforcer->logger, "Add intercept policy: %d", param->policy_id);
|
2019-11-19 10:02:51 +08:00
|
|
|
error_out:
|
2019-05-18 18:27:13 +08:00
|
|
|
cJSON_Delete(json);
|
|
|
|
|
free(json_str);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-05-19 17:45:16 +08:00
|
|
|
void intercept_param_free_cb(int table_id, MAAT_PLUGIN_EX_DATA* ad, long argl, void* argp)
|
2019-05-18 18:27:13 +08:00
|
|
|
{
|
|
|
|
|
struct ssl_policy_enforcer* enforcer=(struct ssl_policy_enforcer*)argp;
|
|
|
|
|
struct intercept_param* param= (struct intercept_param*) *ad;
|
2019-06-06 19:04:31 +08:00
|
|
|
if(param==NULL)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-11-19 10:02:51 +08:00
|
|
|
|
2019-06-21 14:58:35 +08:00
|
|
|
if ((__sync_sub_and_fetch(¶m->ref_cnt, 1) == 0))
|
2019-05-18 18:27:13 +08:00
|
|
|
{
|
2019-05-20 16:56:37 +08:00
|
|
|
TFE_LOG_INFO(enforcer->logger, "Del intercept policy %d", param->policy_id);\
|
2019-05-18 18:27:13 +08:00
|
|
|
free(param);
|
|
|
|
|
*ad=NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-05-19 17:45:16 +08:00
|
|
|
void intercept_param_free(struct intercept_param* param)
|
2019-05-18 18:27:13 +08:00
|
|
|
{
|
2019-05-19 17:45:16 +08:00
|
|
|
intercept_param_free_cb(0, (void**)¶m, 0, NULL);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-04-16 16:17:00 +08:00
|
|
|
|
|
|
|
|
void profile_param_dup_cb(int table_id, MAAT_PLUGIN_EX_DATA* to, MAAT_PLUGIN_EX_DATA* from, long argl, void* argp)
|
|
|
|
|
{
|
|
|
|
|
struct decryption_param* param= (struct decryption_param*) *from;
|
|
|
|
|
if(param)
|
|
|
|
|
{
|
|
|
|
|
__sync_add_and_fetch(&(param->ref_cnt), 1);
|
|
|
|
|
*to = param;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
*to=NULL;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
void profile_param_free_cb(int table_id, MAAT_PLUGIN_EX_DATA* ad, long argl, void* argp)
|
|
|
|
|
{
|
|
|
|
|
struct decryption_param* param= (struct decryption_param*) *ad;
|
|
|
|
|
if(param==NULL)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((__sync_sub_and_fetch(¶m->ref_cnt, 1) == 0))
|
|
|
|
|
{
|
|
|
|
|
free(param);
|
|
|
|
|
*ad=NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void profile_param_free(struct decryption_param* param)
|
|
|
|
|
{
|
|
|
|
|
profile_param_free_cb(0, (void**)¶m, 0, NULL);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
void profile_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;
|
2020-04-27 11:57:18 +08:00
|
|
|
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;
|
2020-04-16 16:17:00 +08:00
|
|
|
struct decryption_param* param=NULL;
|
|
|
|
|
struct ssl_policy_enforcer* enforcer=(struct ssl_policy_enforcer*)argp;
|
|
|
|
|
|
2020-04-27 11:57:18 +08:00
|
|
|
ret=Maat_helper_read_column(table_line, 3, &offset, &len);
|
|
|
|
|
if(ret<0)
|
2020-04-16 16:17:00 +08:00
|
|
|
{
|
2020-04-27 11:57:18 +08:00
|
|
|
TFE_LOG_ERROR(enforcer->logger, "Get decryption param: %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;
|
2020-04-16 16:17:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
param=ALLOC(struct decryption_param, 1);
|
|
|
|
|
param->ref_cnt=1;
|
|
|
|
|
param->bypass_mutual_auth=1;
|
|
|
|
|
param->bypass_pinning=1;
|
|
|
|
|
param->mirror_client_version=1;
|
|
|
|
|
|
2020-04-27 11:57:18 +08:00
|
|
|
exclusions=cJSON_GetObjectItem(json, "dynamic_bypass");
|
2020-04-16 16:17:00 +08:00
|
|
|
if(exclusions)
|
|
|
|
|
{
|
|
|
|
|
item=cJSON_GetObjectItem(exclusions, "ev_cert");
|
|
|
|
|
if(item && item->type==cJSON_Number) param->bypass_ev_cert=item->valueint;
|
|
|
|
|
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;
|
2020-05-19 18:07:04 +08:00
|
|
|
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;
|
2020-04-16 16:17:00 +08:00
|
|
|
}
|
2020-04-27 11:57:18 +08:00
|
|
|
ssl_ver=cJSON_GetObjectItem(json, "protocol_version");
|
2020-04-16 16:17:00 +08:00
|
|
|
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->ssl_min_version=sslver_str2num(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(enforcer->logger, "Invalid intercept parameter: ssl version = %s", item->valuestring);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
item=cJSON_GetObjectItem(ssl_ver, "allow_http2");
|
|
|
|
|
if(item && item->type==cJSON_Number) param->allow_http2=item->valueint;
|
|
|
|
|
}
|
2020-04-27 11:57:18 +08:00
|
|
|
cert_verify=cJSON_GetObjectItem(json, "certificate_checks");
|
2020-04-16 16:17:00 +08:00
|
|
|
if(cert_verify)
|
|
|
|
|
{
|
|
|
|
|
approach=cJSON_GetObjectItem(cert_verify, "approach");
|
|
|
|
|
if(approach)
|
|
|
|
|
{
|
|
|
|
|
item=cJSON_GetObjectItem(approach, "cn");
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
if(0==strcasecmp(item->valuestring, "Fail-Close"))
|
|
|
|
|
{
|
|
|
|
|
param->block_fake_cert=1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*ad=param;
|
2020-04-28 18:52:44 +08:00
|
|
|
TFE_LOG_INFO(enforcer->logger, "Add decryption profile: %s", key);
|
2020-04-16 16:17:00 +08:00
|
|
|
error_out:
|
2020-04-27 11:57:18 +08:00
|
|
|
if (json)
|
|
|
|
|
cJSON_Delete(json);
|
|
|
|
|
if (json_str)
|
|
|
|
|
free(json_str);
|
2020-04-16 16:17:00 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2019-05-20 15:08:42 +08:00
|
|
|
struct ssl_policy_enforcer* ssl_policy_enforcer_create(void* logger)
|
2019-05-19 17:45:16 +08:00
|
|
|
{
|
|
|
|
|
struct ssl_policy_enforcer* enforcer=ALLOC(struct ssl_policy_enforcer, 1);
|
2020-06-11 17:57:18 +08:00
|
|
|
enforcer->maat=(Maat_feather_t)tfe_bussiness_resouce_get(STATIC_MAAT);;
|
2019-05-18 18:27:13 +08:00
|
|
|
enforcer->logger=logger;
|
2020-04-16 16:17:00 +08:00
|
|
|
enforcer->policy_table_id=Maat_table_register(enforcer->maat, "TSG_SECURITY_COMPILE");
|
|
|
|
|
assert(enforcer->policy_table_id >= 0);
|
|
|
|
|
enforcer->profile_table_id=Maat_table_register(enforcer->maat, "TSG_PROFILE_DECRYPTION");
|
|
|
|
|
assert(enforcer->profile_table_id >= 0);
|
2019-11-19 10:02:51 +08:00
|
|
|
UNUSED int ret=Maat_plugin_EX_register(enforcer->maat,
|
2020-04-16 16:17:00 +08:00
|
|
|
enforcer->policy_table_id,
|
2019-11-19 10:02:51 +08:00
|
|
|
intercept_param_new_cb,
|
2019-05-19 17:45:16 +08:00
|
|
|
intercept_param_free_cb,
|
|
|
|
|
intercept_param_dup_cb,
|
2019-05-18 18:27:13 +08:00
|
|
|
NULL,
|
|
|
|
|
0,
|
|
|
|
|
enforcer);
|
2019-05-20 15:08:42 +08:00
|
|
|
assert(ret==0);
|
2020-04-16 16:17:00 +08:00
|
|
|
ret=Maat_plugin_EX_register(enforcer->maat,
|
|
|
|
|
enforcer->profile_table_id,
|
|
|
|
|
profile_param_new_cb,
|
|
|
|
|
profile_param_free_cb,
|
|
|
|
|
profile_param_dup_cb,
|
|
|
|
|
NULL,
|
|
|
|
|
0,
|
|
|
|
|
enforcer);
|
|
|
|
|
assert(ret==0);
|
2019-05-19 17:45:16 +08:00
|
|
|
return enforcer;
|
2019-05-17 21:35:20 +08:00
|
|
|
}
|
|
|
|
|
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;
|
2020-04-16 16:17:00 +08:00
|
|
|
struct intercept_param *policy_param=NULL;
|
|
|
|
|
struct decryption_param *profile_param=NULL;
|
2019-05-19 17:45:16 +08:00
|
|
|
enum ssl_stream_action action=SSL_ACTION_PASSTHROUGH;
|
2019-05-17 21:35:20 +08:00
|
|
|
UNUSED int ret=0;
|
2019-05-19 17:45:16 +08:00
|
|
|
int policy_id=0;
|
|
|
|
|
char policy_id_str[16]={0};
|
2020-04-16 16:17:00 +08:00
|
|
|
char profile_id_str[16]={0};
|
2019-06-14 18:58:03 +08:00
|
|
|
char sni[512], addr_string[512];
|
2019-06-01 20:28:07 +08:00
|
|
|
ret=ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_INTERCEPT_POLICY_ID, &policy_id);
|
|
|
|
|
assert(ret==0);
|
2019-05-19 17:45:16 +08:00
|
|
|
snprintf(policy_id_str, sizeof(policy_id_str), "%d", policy_id);
|
2020-04-16 16:17:00 +08:00
|
|
|
policy_param=(struct intercept_param *)Maat_plugin_get_EX_data(enforcer->maat, enforcer->policy_table_id, policy_id_str);
|
|
|
|
|
if(policy_param==NULL)
|
2019-05-19 17:45:16 +08:00
|
|
|
{
|
2019-06-04 21:13:28 +08:00
|
|
|
TFE_LOG_INFO(enforcer->logger, "Failed to get intercept parameter of policy %d.", policy_id);
|
2019-05-19 17:45:16 +08:00
|
|
|
return SSL_ACTION_PASSTHROUGH;
|
|
|
|
|
}
|
2019-06-14 18:58:03 +08:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ssl_stream_get_string_opt(upstream, SSL_STREAM_OPT_SNI, sni, sizeof(sni));
|
2019-11-19 10:02:51 +08:00
|
|
|
ssl_stream_get_string_opt(upstream, SSL_STREAM_OPT_ADDR, addr_string, sizeof(addr_string));
|
2019-06-14 18:58:03 +08:00
|
|
|
TFE_LOG_DEBUG(enforcer->logger, "%s %s enforce policy %d", addr_string, sni, policy_id);
|
|
|
|
|
}
|
2020-04-16 16:17:00 +08:00
|
|
|
|
|
|
|
|
snprintf(profile_id_str, sizeof(profile_id_str), "%u", policy_param->decryption_profile_id);
|
|
|
|
|
profile_param=(struct decryption_param *)Maat_plugin_get_EX_data(enforcer->maat, enforcer->profile_table_id, profile_id_str);
|
|
|
|
|
if (profile_param==NULL)
|
|
|
|
|
{
|
|
|
|
|
TFE_LOG_INFO(enforcer->logger, "Failed to get decryption parameter of profile %s.", profile_id_str);
|
|
|
|
|
return SSL_ACTION_PASSTHROUGH;
|
|
|
|
|
}
|
2020-05-19 18:07:04 +08:00
|
|
|
int pinning_staus=0, is_ev=0, is_ct=0, is_mauth=0, has_error=0, app_staus=0;
|
2020-04-16 16:17:00 +08:00
|
|
|
if(!profile_param->mirror_client_version)
|
2019-05-19 17:45:16 +08:00
|
|
|
{
|
2020-04-16 16:17:00 +08:00
|
|
|
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);
|
2019-05-19 17:45:16 +08:00
|
|
|
}
|
2020-04-16 16:17:00 +08:00
|
|
|
if(profile_param->allow_http2)
|
2019-05-27 14:17:52 +08:00
|
|
|
{
|
|
|
|
|
ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_ENABLE_ALPN, 1);
|
|
|
|
|
}
|
2020-04-16 16:17:00 +08:00
|
|
|
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);
|
|
|
|
|
ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_SELF_SIGNED, profile_param->no_verify_self_signed);
|
|
|
|
|
ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_EXPIRY_DATE, profile_param->no_verify_expry_date);
|
|
|
|
|
if(profile_param->block_fake_cert)
|
2019-05-19 17:45:16 +08:00
|
|
|
{
|
|
|
|
|
ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_BLOCK_FAKE_CERT, 1);
|
|
|
|
|
}
|
2020-04-16 16:17:00 +08:00
|
|
|
ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_KEYRING_ID, policy_param->keyring);
|
2019-05-20 16:56:37 +08:00
|
|
|
|
2019-05-17 21:35:20 +08:00
|
|
|
ret=ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_PINNING_STATUS, &pinning_staus);
|
2019-06-01 20:28:07 +08:00
|
|
|
assert(ret==0);
|
2020-05-19 18:07:04 +08:00
|
|
|
ret=ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_APP_STATUS, &app_staus);
|
|
|
|
|
assert(ret==0);
|
2019-05-17 21:35:20 +08:00
|
|
|
ret=ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_IS_EV_CERT, &is_ev);
|
2019-06-01 20:28:07 +08:00
|
|
|
assert(ret==0);
|
2019-05-18 12:39:19 +08:00
|
|
|
ret=ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_IS_MUTUAL_AUTH, &is_mauth);
|
2019-05-19 17:45:16 +08:00
|
|
|
ret=ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_IS_CT_CERT, &is_ct);
|
2019-05-21 11:47:09 +08:00
|
|
|
ret=ssl_stream_get_integer_opt(upstream, SSL_STREAM_OPT_HAS_PROTOCOL_ERRORS, &has_error);
|
2019-06-02 17:18:34 +08:00
|
|
|
assert(ret==0);
|
2020-05-19 18:07:04 +08:00
|
|
|
|
|
|
|
|
if ((pinning_staus==1 && app_staus && profile_param->bypass_uninstall_cert_traffic) ||
|
|
|
|
|
(pinning_staus==1 && !app_staus && profile_param->bypass_pinning) ||
|
2020-04-16 16:17:00 +08:00
|
|
|
(is_mauth && profile_param->bypass_mutual_auth) ||
|
|
|
|
|
(is_ev && profile_param->bypass_ev_cert) ||
|
|
|
|
|
(is_ct && profile_param->bypass_ct_cert) ||
|
|
|
|
|
(has_error && profile_param->bypass_protocol_errors))
|
2019-05-17 21:35:20 +08:00
|
|
|
{
|
2019-05-19 17:45:16 +08:00
|
|
|
action=SSL_ACTION_PASSTHROUGH;
|
2020-05-19 18:07:04 +08:00
|
|
|
TFE_LOG_DEBUG(enforcer->logger, "%s %s enforce policy_id %d, action PASSTHROUGH due to uninstall_cert:%d, pinning:%d, mutual_auth:%d, is_ev:%d, is_ct:%d, has_error:%d",
|
2020-04-28 18:52:44 +08:00
|
|
|
addr_string, sni, policy_param->policy_id,
|
2020-05-19 18:07:04 +08:00
|
|
|
((pinning_staus == 1 && app_staus && profile_param->bypass_uninstall_cert_traffic) ? 1 : 0),
|
|
|
|
|
((pinning_staus == 1 && !app_staus && profile_param->bypass_pinning) ? 1 : 0),
|
2020-04-28 18:52:44 +08:00
|
|
|
((is_mauth && profile_param->bypass_mutual_auth) ? 1 : 0),
|
|
|
|
|
((is_ev && profile_param->bypass_ev_cert) ? 1 : 0),
|
|
|
|
|
((is_ct && profile_param->bypass_ct_cert) ? 1 : 0),
|
|
|
|
|
((has_error && profile_param->bypass_protocol_errors) ? 1 : 0));
|
2019-05-17 21:35:20 +08:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-05-19 17:45:16 +08:00
|
|
|
action=SSL_ACTION_INTERCEPT;
|
2019-05-17 21:35:20 +08:00
|
|
|
}
|
2020-04-16 16:17:00 +08:00
|
|
|
|
|
|
|
|
intercept_param_free(policy_param);
|
|
|
|
|
profile_param_free(profile_param);
|
|
|
|
|
policy_param=NULL;
|
|
|
|
|
profile_param=NULL;
|
2019-05-19 17:45:16 +08:00
|
|
|
return action;
|
2019-05-17 21:35:20 +08:00
|
|
|
}
|
|
|
|
|
|