diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f310ad..ecdf867 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,7 @@ option(ENABLE_PLUGIN_HTTP "Enable HTTP support" TRUE) option(ENABLE_PLUGIN_DECRYPT_MIRRORING "Enable decrypt mirroring" TRUE) option(ENABLE_PLUGIN_PANGU_HTTP "Enable Pangu-HTTP business" TRUE) option(ENABLE_PLUGIN_HTTP2 "Enable HTTP2 business" TRUE) +option(ENABLE_PLUGIN_SSL_POLICY "Enable SSL policy support" TRUE) if(ENABLE_PIC) set(CMAKE_POSITION_INDEPENDENT_CODE 1) diff --git a/common/include/ssl_stream.h b/common/include/ssl_stream.h new file mode 100644 index 0000000..bc559e6 --- /dev/null +++ b/common/include/ssl_stream.h @@ -0,0 +1,32 @@ +#pragma once + +struct ssl_stream; + +enum ssl_stream_action +{ + SSL_ACTION_PASSTHROUGH, + SSL_ACTION_INTERCEPT, + SSL_ACTION_SHUTDOWN +}; +typedef enum ssl_stream_action ssl_stream_new_hook(struct ssl_stream *upstream, void* u_para); + +enum SSL_STREAM_OPT +{ + SSL_STREAM_OPT_IS_EV_CERT, //0:FALSE, 1:TRUE. + SSL_STREAM_OPT_IS_CT_CERT, //0:FALSE, 1:TRUE. + SSL_STREAM_OPT_IS_MUTUAL_AUTH, //0:FALSE, 1:TRUE. + SSL_STREAM_OPT_PINNING_STATUS, //0:FALSE, 1:TRUE. + SSL_STREAM_OPT_NO_VERIFY_SELF_SIGNED, //VALUE is an interger, SIZE=sizeof(int). 1:ON, 0:OFF. DEFAULT:0. + SSL_STREAM_OPT_NO_VERIFY_COMMON_NAME, //VALUE is an interger, SIZE=sizeof(int). 1:ON, 0:OFF. DEFAULT:1. + SSL_STREAM_OPT_NO_VERIFY_ISSUER, //VALUE is an interger, SIZE=sizeof(int). 1:ON, 0:OFF. DEFAULT:0. + SSL_STREAM_OPT_NO_VERIFY_EXPIRY_DATE, //VALUE is an interger, SIZE=sizeof(int). 1:ON, 0:OFF. DEFAULT:0. + SSL_STREAM_OPT_BLOCK_FAKE_CERT, //VALUE is an interger, SIZE=sizeof(int). 1:PASSTHROUGH, 0:BLOCK. DEFAULT:1. + SSL_STREAM_OPT_PROTOCOL_MIN_VERSION, + SSL_STREAM_OPT_PROTOCOL_MAX_VERSION +}; +int sslver_str2num(const char * version_str); + +//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_get_integer_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT opt_type, int *opt_val); + diff --git a/platform/CMakeLists.txt b/platform/CMakeLists.txt index 2d8148d..2d050d5 100644 --- a/platform/CMakeLists.txt +++ b/platform/CMakeLists.txt @@ -1,7 +1,6 @@ add_executable(tfe src/key_keeper.cpp src/kni_acceptor.cpp src/ssl_stream.cpp src/ssl_sess_cache.cpp src/ssl_service_cache.cpp - src/ssl_trusted_cert_storage.cpp src/ev_root_ca_metadata.cpp - src/ssl_policy.cpp src/ssl_utils.cpp + src/ssl_trusted_cert_storage.cpp src/ev_root_ca_metadata.cpp src/ssl_utils.cpp src/tcp_stream.cpp src/main.cpp src/proxy.cpp) target_include_directories(tfe PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include/external) @@ -38,6 +37,11 @@ endif() if(ENABLE_PLUGIN_HTTP2) target_link_libraries(tfe -Wl,--whole-archive http2 -Wl,--no-whole-archive) endif() +if(ENABLE_PLUGIN_SSL_POLICY) + target_link_libraries(tfe -Wl,--whole-archive ssl-policy -Wl,--no-whole-archive) +endif() + + install(TARGETS tfe RUNTIME DESTINATION bin COMPONENT Program) diff --git a/platform/include/internal/proxy.h b/platform/include/internal/proxy.h index b9195c5..432e695 100644 --- a/platform/include/internal/proxy.h +++ b/platform/include/internal/proxy.h @@ -2,7 +2,7 @@ #include #include -#include +#include struct ssl_mgr; struct key_keeper; diff --git a/platform/include/internal/ssl_stream.h b/platform/include/internal/ssl_stream_core.h similarity index 60% rename from platform/include/internal/ssl_stream.h rename to platform/include/internal/ssl_stream_core.h index fabfc2b..47b2549 100644 --- a/platform/include/internal/ssl_stream.h +++ b/platform/include/internal/ssl_stream_core.h @@ -1,23 +1,12 @@ #pragma once +#include #include #include #include - -struct ssl_stream; - struct ssl_mgr; -enum ssl_stream_action -{ - SSL_ACTION_PASSTHROUGH, - SSL_ACTION_INTERCEPT, - SSL_ACTION_SHUTDOWN -}; - -typedef enum ssl_stream_action ssl_stream_new_hook(struct ssl_stream *upstream, void* u_para); - struct ssl_mgr * ssl_manager_init(const char * ini_profile, const char * section, struct event_base * ev_base_gc, void * logger); void ssl_manager_set_new_upstream_cb(struct ssl_mgr * mgr, ssl_stream_new_hook* new_upstream_cb, void* u_para); @@ -46,22 +35,4 @@ int ssl_manager_add_crl(struct ssl_mgr* mgr, const char* pem_file); int ssl_manager_del_crl(struct ssl_mgr* mgr, const char* pem_file); void ssl_manager_reset_trust_ca(struct ssl_mgr* mgr); -enum SSL_STREAM_OPT -{ - SSL_STREAM_OPT_IS_EV_CERT, //0:FALSE, 1:TRUE. - SSL_STREAM_OPT_IS_CT_CERT, //0:FALSE, 1:TRUE. - SSL_STREAM_OPT_IS_MUTUAL_AUTH, //0:FALSE, 1:TRUE. - SSL_STREAM_OPT_PINNING_STATUS, //0:FALSE, 1:TRUE. - SSL_STREAM_OPT_NO_VERIFY_SELF_SIGNED, //VALUE is an interger, SIZE=sizeof(int). 1:ON, 0:OFF. DEFAULT:0. - SSL_STREAM_OPT_NO_VERIFY_COMMON_NAME, //VALUE is an interger, SIZE=sizeof(int). 1:ON, 0:OFF. DEFAULT:1. - SSL_STREAM_OPT_NO_VERIFY_ISSUER, //VALUE is an interger, SIZE=sizeof(int). 1:ON, 0:OFF. DEFAULT:0. - SSL_STREAM_OPT_NO_VERIFY_EXPIRY_DATE, //VALUE is an interger, SIZE=sizeof(int). 1:ON, 0:OFF. DEFAULT:0. - SSL_STREAM_OPT_BLOCK_FAKE_CERT, //VALUE is an interger, SIZE=sizeof(int). 1:PASSTHROUGH, 0:BLOCK. DEFAULT:1. - SSL_STREAM_OPT_PROTOCOL_MIN_VERSION, - SSL_STREAM_OPT_PROTOCOL_MAX_VERSION -}; - -//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_get_integer_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT opt_type, int *opt_val); diff --git a/platform/include/internal/ssl_utils.h b/platform/include/internal/ssl_utils.h index 7c7e002..cd6dcf7 100644 --- a/platform/include/internal/ssl_utils.h +++ b/platform/include/internal/ssl_utils.h @@ -122,7 +122,6 @@ void ssl_openssl_version(void); int ssl_init(void); int ssl_reinit(void); void ssl_fini(void); -int sslver_str2num(const char * version_str); char * ssl_sha1_to_str(unsigned char *, int); diff --git a/platform/src/proxy.cpp b/platform/src/proxy.cpp index 684527a..91e96a8 100644 --- a/platform/src/proxy.cpp +++ b/platform/src/proxy.cpp @@ -38,14 +38,16 @@ #include #include #include -#include + +extern struct ssl_policy_enforcer* ssl_policy_enforcer_create(void* logger); +extern enum ssl_stream_action ssl_policy_enforce(struct ssl_stream *upstream, void* u_para); + static int signals[] = {SIGHUP, SIGPIPE, SIGUSR1}; /* Global Resource */ void * g_default_logger = NULL; struct tfe_proxy * g_default_proxy = NULL; -extern Maat_feather_t g_business_maat; /* Per thread resource */ thread_local unsigned int __currect_thread_id = 0; thread_local void * __currect_default_logger = NULL; @@ -417,7 +419,7 @@ int main(int argc, char * argv[]) } //ugly here. g_business_maat is available after plugin initiate. - g_default_proxy->ssl_ply_enforcer=ssl_policy_enforcer_create(g_business_maat, g_default_logger); + g_default_proxy->ssl_ply_enforcer=ssl_policy_enforcer_create(g_default_logger); ssl_manager_set_new_upstream_cb(g_default_proxy->ssl_mgr_handler, ssl_policy_enforce, g_default_proxy->ssl_ply_enforcer); ret = tfe_proxy_work_thread_run(g_default_proxy); CHECK_OR_EXIT(ret == 0, "Failed at creating thread. Exit."); diff --git a/platform/src/ssl_stream.cpp b/platform/src/ssl_stream.cpp index 9ba6b0b..de934e0 100644 --- a/platform/src/ssl_stream.cpp +++ b/platform/src/ssl_stream.cpp @@ -266,6 +266,46 @@ struct fs_spec enum ssl_stream_stat id; const char* name; }; +int sslver_str2num(const char * version_str) +{ + int sslversion = -1; + + assert(OPENSSL_VERSION_NUMBER >= 0x10100000L); + + /* + * Support for SSLv2 and the corresponding SSLv2_method(), + * SSLv2_server_method() and SSLv2_client_method() functions were + * removed in OpenSSL 1.1.0. + */ + if (!strcmp(version_str, "ssl3")) + { + sslversion = SSL3_VERSION; + } + else if (!strcmp(version_str, "tls10") || !strcmp(version_str, "tls1")) + { + sslversion = TLS1_VERSION; + } + else if (!strcmp(version_str, "tls11")) + { + sslversion = TLS1_1_VERSION; + } + else if (!strcmp(version_str, "tls12")) + { + sslversion = TLS1_2_VERSION; + } + else if (!strcmp(version_str, "tls13")) + { + sslversion = TLS1_3_VERSION; + } + + else + { + sslversion = -1; + } + + return sslversion; +} + /* * Garbage collection handler. */ @@ -411,7 +451,6 @@ struct ssl_stream * ssl_stream_new(struct ssl_mgr * mgr, evutil_socket_t fd, enu { UNUSED int ret = 0; - const unsigned char* selected_alpn=peer->alpn_selected; struct ssl_stream * s_stream = ALLOC(struct ssl_stream, 1); s_stream->dir = dir; @@ -427,7 +466,7 @@ struct ssl_stream * ssl_stream_new(struct ssl_mgr * mgr, evutil_socket_t fd, enu assert(peer!=NULL); ATOMIC_INC(&(s_stream->mgr->stat_val[SSL_DOWN_NEW])); s_stream->down_parts.keyring = kyr; - s_stream->ssl = downstream_ssl_create(mgr, kyr, peer->negotiated_version, selected_alpn); + s_stream->ssl = downstream_ssl_create(mgr, kyr, peer->negotiated_version, peer->alpn_selected); break; case CONN_DIR_UPSTREAM: ATOMIC_INC(&(s_stream->mgr->stat_val[SSL_UP_NEW])); diff --git a/platform/src/ssl_utils.cpp b/platform/src/ssl_utils.cpp index 19e33d3..b2680a0 100644 --- a/platform/src/ssl_utils.cpp +++ b/platform/src/ssl_utils.cpp @@ -151,45 +151,7 @@ void ssl_openssl_version(void) #endif /* !SSL_OP_TLS_ROLLBACK_BUG */ fprintf(stderr, "\n"); } -int sslver_str2num(const char * version_str) -{ - int sslversion = -1; - assert(OPENSSL_VERSION_NUMBER >= 0x10100000L); - - /* - * Support for SSLv2 and the corresponding SSLv2_method(), - * SSLv2_server_method() and SSLv2_client_method() functions were - * removed in OpenSSL 1.1.0. - */ - if (!strcmp(version_str, "ssl3")) - { - sslversion = SSL3_VERSION; - } - else if (!strcmp(version_str, "tls10") || !strcmp(version_str, "tls1")) - { - sslversion = TLS1_VERSION; - } - else if (!strcmp(version_str, "tls11")) - { - sslversion = TLS1_1_VERSION; - } - else if (!strcmp(version_str, "tls12")) - { - sslversion = TLS1_2_VERSION; - } - else if (!strcmp(version_str, "tls13")) - { - sslversion = TLS1_3_VERSION; - } - - else - { - sslversion = -1; - } - - return sslversion; -} /* * 1 if OpenSSL has been initialized, 0 if not. When calling a _load() diff --git a/plugin/business/CMakeLists.txt b/plugin/business/CMakeLists.txt index 03542d6..f5684ac 100644 --- a/plugin/business/CMakeLists.txt +++ b/plugin/business/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(decrypt-mirroring) -add_subdirectory(pangu-http) \ No newline at end of file +add_subdirectory(pangu-http) +add_subdirectory(ssl-policy) \ No newline at end of file diff --git a/plugin/business/ssl-policy/CMakeLists.txt b/plugin/business/ssl-policy/CMakeLists.txt new file mode 100644 index 0000000..3dcb139 --- /dev/null +++ b/plugin/business/ssl-policy/CMakeLists.txt @@ -0,0 +1,5 @@ +add_library(ssl-policy src/ssl_policy.cpp) +target_link_libraries(ssl-policy PUBLIC common) +target_link_libraries(ssl-policy PUBLIC cjson pthread openssl-ssl-static) +target_link_libraries(ssl-policy PUBLIC maatframe) + diff --git a/platform/src/ssl_policy.cpp b/plugin/business/ssl-policy/src/ssl_policy.cpp similarity index 95% rename from platform/src/ssl_policy.cpp rename to plugin/business/ssl-policy/src/ssl_policy.cpp index 1cd1bf5..dcbb12b 100644 --- a/platform/src/ssl_policy.cpp +++ b/plugin/business/ssl-policy/src/ssl_policy.cpp @@ -1,9 +1,10 @@ #include -#include #include -#include #include #include +#include +#include +extern Maat_feather_t g_business_maat; struct ssl_policy_enforcer { @@ -67,6 +68,7 @@ void intercept_param_new_cb(int table_id, const char* key, const char* table_lin param->ref_cnt=1; param->bypass_mutual_auth=1; param->bypass_pinning=1; + param->mirror_client_version=1; item=cJSON_GetObjectItem(json, "keyring"); if(item && item->type==cJSON_Number) param->keyring=item->valueint; @@ -98,7 +100,7 @@ void intercept_param_new_cb(int table_id, const char* key, const char* table_lin item=cJSON_GetObjectItem(approach, "expiration"); if(item && item->type==cJSON_Number && item->valueint==0) param->no_verify_expry_date=1; } - item=cJSON_GetObjectItem(exclusions, "fail_method"); + item=cJSON_GetObjectItem(cert_verify, "fail_method"); if(item && item->type==cJSON_String) { if(0==strcasecmp(item->string, "Fail-Close")) @@ -111,7 +113,7 @@ void intercept_param_new_cb(int table_id, const char* key, const char* table_lin if(ssl_ver) { item=cJSON_GetObjectItem(ssl_ver, "mirror_client"); - if(item && item->type==cJSON_String) param->mirror_client_version=item->valueint; + if(item && item->type==cJSON_Number) param->mirror_client_version=item->valueint; if(!param->mirror_client_version) { item=cJSON_GetObjectItem(ssl_ver, "min"); @@ -145,10 +147,10 @@ void intercept_param_free(struct intercept_param* param) intercept_param_free_cb(0, (void**)¶m, 0, NULL); return; } -struct ssl_policy_enforcer* ssl_policy_enforcer_create(Maat_feather_t maat, void* logger) +struct ssl_policy_enforcer* ssl_policy_enforcer_create(void* logger) { struct ssl_policy_enforcer* enforcer=ALLOC(struct ssl_policy_enforcer, 1); - enforcer->maat=maat; + enforcer->maat=g_business_maat; enforcer->logger=logger; enforcer->table_id=Maat_table_register(enforcer->maat, "PXY_INTERCEPT_COMPILE"); int ret=Maat_plugin_EX_register(enforcer->maat, @@ -159,7 +161,7 @@ struct ssl_policy_enforcer* ssl_policy_enforcer_create(Maat_feather_t maat, void NULL, 0, enforcer); - assert(ret==1); + assert(ret==0); return enforcer; } enum ssl_stream_action ssl_policy_enforce(struct ssl_stream *upstream, void* u_para) diff --git a/platform/include/internal/ssl_policy.h b/plugin/business/ssl-policy/src/ssl_policy.h similarity index 66% rename from platform/include/internal/ssl_policy.h rename to plugin/business/ssl-policy/src/ssl_policy.h index 186077c..e38f98d 100644 --- a/platform/include/internal/ssl_policy.h +++ b/plugin/business/ssl-policy/src/ssl_policy.h @@ -3,6 +3,6 @@ #include struct ssl_policy_enforcer; -struct ssl_policy_enforcer* ssl_policy_enforcer_create(Maat_feather_t maat, void* logger); +struct ssl_policy_enforcer* ssl_policy_enforcer_create(void* logger); enum ssl_stream_action ssl_policy_enforce(struct ssl_stream *upstream, void* u_para);