up session cache校验ssl version,增加ssl状态读写的接口。
This commit is contained in:
@@ -73,7 +73,7 @@ enum tfe_stream_opt_level
|
||||
STREAM_OPT_LEVEL_TCP,
|
||||
STREAM_OPT_LEVEL_SSL //see tfe_types.h enum SSL_STREAM_OPT
|
||||
};
|
||||
int tfe_stream_set_opt(struct tfe_stream * stream, enum tfe_stream_opt_level level, int type, const void* value, size_t size);
|
||||
int tfe_stream_set_integer_opt(struct tfe_stream * stream, enum tfe_stream_opt_level level, int type, int val);
|
||||
/*
|
||||
@return 0 if successful, or -1 if an error occurred
|
||||
*/
|
||||
|
||||
@@ -159,20 +159,5 @@ char* tfe_string_addr_create_by_fd(int fd, enum tfe_conn_dir dir);
|
||||
char * tfe_stream_addr_to_str(const struct tfe_stream_addr * addr);
|
||||
int tfe_stream_addr_str_split(char* addr_str, const char** sip, const char** sport, const char** dip, const char** dport);
|
||||
|
||||
enum SSL_STREAM_OPT
|
||||
{
|
||||
SSL_STREAM_OPT_BYPASS_EV_CERT, //VALUE is an interger, SIZE=sizeof(int). 1:BYPASS, 0:INTERCEPT. DEFAULT:0.
|
||||
SSL_STREAM_OPT_BYPASS_CT_CERT, //VALUE is an interger, SIZE=sizeof(int). 1:BYPASS, 0:INTERCEPT. DEFAULT:0.
|
||||
SSL_STREAM_OPT_BYPASS_MUTUAL_AUTH, //VALUE is an interger, SIZE=sizeof(int). 1:BYPASS, 0:BLOCKED. DEFAULT:1.
|
||||
SSL_STREAM_OPT_BYPASS_CERT_PINNING, //VALUE is an interger, SIZE=sizeof(int). 1:BYPASS, 0:BLOCKED. DEFAULT:1.
|
||||
SSL_STREAM_OPT_VERIFY_SELF_SIGNED, //VALUE is an interger, SIZE=sizeof(int). 1:ON, 0:OFF. DEFAULT:1.
|
||||
SSL_STREAM_OPT_VERIFY_COMMON_NAME, //VALUE is an interger, SIZE=sizeof(int). 1:ON, 0:OFF. DEFAULT:1.
|
||||
SSL_STREAM_OPT_VERIFY_ISSUER, //VALUE is an interger, SIZE=sizeof(int). 1:ON, 0:OFF. DEFAULT:1.
|
||||
SSL_STREAM_OPT_VERIFY_EXPIRY_DATE, //VALUE is an interger, SIZE=sizeof(int). 1:ON, 0:OFF. DEFAULT:1.
|
||||
SST_STREAM_OPT_VERIFY_FAIL_ACTION, //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
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
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_utils.cpp src/tcp_stream.cpp src/main.cpp src/proxy.cpp)
|
||||
src/ssl_policy.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)
|
||||
target_include_directories(tfe PRIVATE ${CMAKE_CURRENT_LIST_DIR}/include/internal)
|
||||
|
||||
@@ -104,8 +104,8 @@ struct tfe_stream_private
|
||||
unsigned int nr_plugin_ctxs;
|
||||
struct plugin_ctx * plugin_ctxs;
|
||||
|
||||
/* TCP forward without scan or decode when the passthough is set */
|
||||
bool passthough;
|
||||
/* TCP forward without scan or decode when the tcp_passthough is set */
|
||||
bool tcp_passthough;
|
||||
|
||||
/* For defer connection setup */
|
||||
evutil_socket_t defer_fd_downstream;
|
||||
|
||||
@@ -8,8 +8,8 @@ struct sess_cache;
|
||||
struct sess_cache * ssl_sess_cache_create(unsigned int slot_size, unsigned int expire_seconds, enum tfe_conn_dir served);
|
||||
void ssl_sess_cache_destroy(struct sess_cache * cache);
|
||||
|
||||
void up_session_set(struct sess_cache * cache, struct sockaddr * addr, socklen_t addr_len, const char * sni, SSL_SESSION * value);
|
||||
SSL_SESSION * up_session_get(struct sess_cache * cache, struct sockaddr * addr, socklen_t addr_len, const char * sni);
|
||||
void up_session_set(struct sess_cache * cache, struct sockaddr * addr, socklen_t addr_len, const char * sni, int version, SSL_SESSION * sess);
|
||||
SSL_SESSION * up_session_get(struct sess_cache * cache, struct sockaddr * addr, socklen_t addr_len, const char * sni, int min_ver, int max_ver);
|
||||
|
||||
void down_session_set(struct sess_cache * cache, const SSL_SESSION * sess);
|
||||
void down_session_del(struct sess_cache * cache, const SSL_SESSION * sess);
|
||||
|
||||
@@ -8,14 +8,6 @@
|
||||
struct ssl_stream;
|
||||
|
||||
struct ssl_mgr;
|
||||
typedef void ssl_stream_new_cb(struct ssl_stream *, void* u_para);
|
||||
typedef void ssl_stream_free_cb(struct ssl_stream *, void* u_para);
|
||||
|
||||
struct ssl_mgr * ssl_manager_init(const char * ini_profile, const char * section, struct event_base * ev_base_gc,
|
||||
void * logger);
|
||||
//, ssl_stream_new_cb* new_func, ssl_stream_free_cb* free_func, void* u_para);
|
||||
void ssl_manager_destroy(struct ssl_mgr * mgr);
|
||||
unsigned long ssl_stream_log_error(struct bufferevent * bev, enum tfe_conn_dir dir, struct ssl_mgr* mgr);
|
||||
|
||||
enum ssl_stream_action
|
||||
{
|
||||
@@ -24,7 +16,17 @@ enum ssl_stream_action
|
||||
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, ssl_stream_new_hook* hook_func, void* u_para);
|
||||
void ssl_manager_destroy(struct ssl_mgr * mgr);
|
||||
unsigned long ssl_stream_log_error(struct bufferevent * bev, enum tfe_conn_dir dir, struct ssl_mgr* mgr);
|
||||
|
||||
|
||||
enum ssl_stream_action ssl_upstream_create_result_release_action(future_result_t * result);
|
||||
evutil_socket_t ssl_upstream_create_result_release_fd(future_result_t * result);
|
||||
|
||||
struct ssl_stream * ssl_upstream_create_result_release_stream(future_result_t * result);
|
||||
struct bufferevent * ssl_upstream_create_result_release_bev(future_result_t * result);
|
||||
void ssl_async_upstream_create(struct future * f, struct ssl_mgr * mgr, evutil_socket_t fd_upstream,
|
||||
@@ -43,6 +45,22 @@ 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);
|
||||
|
||||
//s_stream must be upstream.
|
||||
int ssl_stream_set_opt(struct ssl_stream *s_stream, enum SSL_STREAM_OPT type, const void* value, size_t size);
|
||||
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.
|
||||
SST_STREAM_OPT_VERIFY_FAIL_ACTION, //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);
|
||||
|
||||
|
||||
@@ -335,6 +335,8 @@ int tfe_stat_init(struct tfe_proxy * proxy, const char * profile)
|
||||
proxy->fs_handle = fs_handle;
|
||||
return 0;
|
||||
}
|
||||
extern struct ssl_policy_enforcer* ssl_policy_enforcer_create(void);
|
||||
extern enum ssl_stream_action ssl_policy_enforce(struct ssl_stream *upstream, void* u_para);
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
@@ -382,8 +384,10 @@ int main(int argc, char * argv[])
|
||||
g_default_proxy->gcev = event_new(g_default_proxy->evbase, -1, EV_PERSIST, __gc_handler_cb, g_default_proxy);
|
||||
CHECK_OR_EXIT(g_default_proxy->gcev, "Failed at creating GC event. Exit. ");
|
||||
|
||||
|
||||
/* SSL INIT */
|
||||
g_default_proxy->ssl_mgr_handler = ssl_manager_init(main_profile, "ssl", g_default_proxy->evbase, g_default_logger);
|
||||
g_default_proxy->ssl_mgr_handler = ssl_manager_init(main_profile, "ssl", g_default_proxy->evbase, g_default_logger,
|
||||
ssl_policy_enforce, ssl_policy_enforcer_create());
|
||||
CHECK_OR_EXIT(g_default_proxy->ssl_mgr_handler, "Failed at init SSL manager. Exit.");
|
||||
|
||||
for (size_t i = 0; i < (sizeof(signals) / sizeof(int)); i++)
|
||||
|
||||
30
platform/src/ssl_policy.cpp
Normal file
30
platform/src/ssl_policy.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include <ssl_stream.h>
|
||||
#include <tfe_utils.h>
|
||||
struct ssl_policy_enforcer
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
struct ssl_policy_enforcer* ssl_policy_enforcer_create(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
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 int ret=0;
|
||||
int pinning_staus=0, is_ev=0;
|
||||
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);
|
||||
if(pinning_staus>0||is_ev)
|
||||
{
|
||||
return SSL_ACTION_PASSTHROUGH;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SSL_ACTION_INTERCEPT;
|
||||
}
|
||||
}
|
||||
|
||||
6
platform/src/ssl_policy.h
Normal file
6
platform/src/ssl_policy.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include <ssl_stream.h>
|
||||
struct ssl_policy_enforcer;
|
||||
struct ssl_policy_enforcer* ssl_policy_enforcer_create(void);
|
||||
enum ssl_stream_action ssl_policy_enforce(struct ssl_stream *upstream, void* u_para);
|
||||
|
||||
@@ -17,6 +17,7 @@ struct asn1_sess
|
||||
{
|
||||
unsigned char * buff;
|
||||
size_t size;
|
||||
int version;
|
||||
};
|
||||
|
||||
struct sess_set_args
|
||||
@@ -24,6 +25,11 @@ struct sess_set_args
|
||||
MESA_htable_handle hash;
|
||||
struct asn1_sess * new_sess;
|
||||
};
|
||||
struct sess_get_args
|
||||
{
|
||||
SSL_SESSION *sess;
|
||||
int version;
|
||||
};
|
||||
|
||||
struct sess_cache
|
||||
{
|
||||
@@ -41,7 +47,7 @@ static void ssl_sess_free_serialized(void * data)
|
||||
return;
|
||||
}
|
||||
|
||||
static struct asn1_sess * ssl_sess_serialize(SSL_SESSION * sess)
|
||||
static struct asn1_sess * ssl_sess_serialize(SSL_SESSION * sess, int version)
|
||||
{
|
||||
struct asn1_sess * result = ALLOC(struct asn1_sess, 1);
|
||||
|
||||
@@ -62,6 +68,7 @@ static struct asn1_sess * ssl_sess_serialize(SSL_SESSION * sess)
|
||||
j=i2d_SSL_SESSION(sess, &(temp));
|
||||
assert(i == j);
|
||||
assert(result->buff + i == temp);
|
||||
result->version=version;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -101,6 +108,8 @@ static int ssl_sess_verify_cb(void * data, int eliminate_type)
|
||||
|
||||
static long sess_cache_get_cb(void * data, const uchar * key, uint size, void * user_arg)
|
||||
{
|
||||
struct sess_get_args *result=(struct sess_get_args *)user_arg;
|
||||
|
||||
SSL_SESSION * sess = NULL;
|
||||
int is_valid = 0;
|
||||
if (data == NULL)
|
||||
@@ -119,7 +128,8 @@ static long sess_cache_get_cb(void * data, const uchar * key, uint size, void *
|
||||
}
|
||||
else
|
||||
{
|
||||
*(SSL_SESSION **) user_arg = sess;
|
||||
result->sess=sess;
|
||||
result->version=asn1->version;
|
||||
return SESS_CACHE_FOUND;
|
||||
}
|
||||
}
|
||||
@@ -137,6 +147,7 @@ static long sess_cache_set_cb(void * data, const uchar * key, uint size, void *
|
||||
cur_asn1->size = new_asn1->size;
|
||||
cur_asn1->buff = ALLOC(unsigned char, cur_asn1->size);
|
||||
memcpy(cur_asn1->buff, new_asn1->buff, cur_asn1->size);
|
||||
cur_asn1->version=new_asn1->version;
|
||||
return SESS_CACHE_UPDATE_OLD;
|
||||
}
|
||||
else
|
||||
@@ -178,16 +189,20 @@ static size_t upsess_mk_key(struct sockaddr * res, socklen_t addrlen, const char
|
||||
}
|
||||
|
||||
void up_session_set(struct sess_cache * cache, struct sockaddr * addr, socklen_t addr_len, const char * sni,
|
||||
SSL_SESSION * sess)
|
||||
int version, SSL_SESSION * sess)
|
||||
{
|
||||
unsigned char * key = NULL;
|
||||
size_t key_size = 0;
|
||||
long cb_ret = 0;
|
||||
assert(cache->served_for == CONN_DIR_UPSTREAM);
|
||||
if(!SSL_SESSION_is_resumable(sess))
|
||||
{
|
||||
return;
|
||||
}
|
||||
key_size = upsess_mk_key(addr, addr_len, sni, &key);
|
||||
|
||||
struct asn1_sess * asn1 = NULL;
|
||||
asn1 = ssl_sess_serialize(sess);
|
||||
asn1 = ssl_sess_serialize(sess, version);
|
||||
|
||||
struct sess_set_args set_args={.hash = cache->hash, .new_sess = asn1};
|
||||
MESA_htable_search_cb(cache->hash, key, key_size, sess_cache_set_cb, &set_args, &cb_ret);
|
||||
@@ -200,9 +215,9 @@ void up_session_set(struct sess_cache * cache, struct sockaddr * addr, socklen_t
|
||||
return;
|
||||
}
|
||||
|
||||
SSL_SESSION * up_session_get(struct sess_cache * cache, struct sockaddr * addr, socklen_t addr_len, const char * sni)
|
||||
SSL_SESSION * up_session_get(struct sess_cache * cache, struct sockaddr * addr, socklen_t addr_len, const char * sni, int min_ver, int max_ver)
|
||||
{
|
||||
SSL_SESSION * sess = NULL;
|
||||
struct sess_get_args args={NULL, 0};
|
||||
long cb_ret = 0;
|
||||
|
||||
size_t key_size = 0;
|
||||
@@ -210,14 +225,14 @@ SSL_SESSION * up_session_get(struct sess_cache * cache, struct sockaddr * addr,
|
||||
|
||||
unsigned char * key = NULL;
|
||||
key_size = upsess_mk_key(addr, addr_len, sni, &key);
|
||||
MESA_htable_search_cb(cache->hash, key, key_size, sess_cache_get_cb, &sess, &cb_ret);
|
||||
MESA_htable_search_cb(cache->hash, key, key_size, sess_cache_get_cb, &args, &cb_ret);
|
||||
// printf("%s %s\n", __FUNCTION__, key);
|
||||
free(key);
|
||||
key = NULL;
|
||||
if (cb_ret == SESS_CACHE_FOUND)
|
||||
if (cb_ret == SESS_CACHE_FOUND && args.version>=min_ver && args.version<=max_ver)
|
||||
{
|
||||
ATOMIC_INC(&(cache->hit_cnt));
|
||||
return sess;
|
||||
return args.sess;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -232,7 +247,7 @@ void down_session_set(struct sess_cache * cache, const SSL_SESSION * sess)
|
||||
struct asn1_sess * asn1 = NULL;
|
||||
long cb_ret = 0;
|
||||
assert(cache->served_for == CONN_DIR_DOWNSTREAM);
|
||||
asn1 = ssl_sess_serialize((SSL_SESSION *) sess);
|
||||
asn1 = ssl_sess_serialize((SSL_SESSION *) sess, 0);
|
||||
|
||||
/*
|
||||
* SSL_SESSION_get_id() returns a pointer to the internal session id value for the session s.
|
||||
|
||||
@@ -134,6 +134,8 @@ struct ssl_mgr
|
||||
struct sess_cache * down_sess_cache;
|
||||
struct sess_cache * up_sess_cache;
|
||||
struct ssl_service_cache* svc_cache;
|
||||
ssl_stream_new_hook* on_new_hook_func;
|
||||
void* hook_u_para;
|
||||
struct session_ticket_key ticket_key;
|
||||
|
||||
char default_ciphers[TFE_SYMBOL_MAX];
|
||||
@@ -165,7 +167,7 @@ struct __ssl_stream_debug
|
||||
{
|
||||
evutil_socket_t fd;
|
||||
};
|
||||
struct ssl_bypass
|
||||
struct ssl_bypass_condition
|
||||
{
|
||||
char bypass_ev_cert;
|
||||
char bypass_ct_cert;
|
||||
@@ -177,10 +179,10 @@ struct ssl_upstream_parts
|
||||
|
||||
struct cert_verify_param verify_param;
|
||||
struct cert_verify_result verify_result;
|
||||
char verify_failed_action;
|
||||
char block_fake_cert;
|
||||
struct ssl_service_status svc_status;
|
||||
enum ssl_stream_action action;
|
||||
|
||||
struct ssl_bypass bypass_condition;
|
||||
struct ssl_chello * client_hello;
|
||||
int is_server_cert_verify_passed;
|
||||
};
|
||||
@@ -198,6 +200,7 @@ struct ssl_stream
|
||||
struct ssl_upstream_parts up_parts;
|
||||
struct ssl_downstream_parts down_parts;
|
||||
};
|
||||
int ssl_min_ver, ssl_max_ver;
|
||||
const unsigned char* alpn_selected; //reference to SSL_ALPN_HTTP_2/SSL_ALPN_HTTP_1_1
|
||||
struct ssl_stream* peer;
|
||||
struct __ssl_stream_debug _do_not_use;
|
||||
@@ -417,8 +420,8 @@ struct ssl_stream * ssl_stream_new(struct ssl_mgr * mgr, evutil_socket_t fd, enu
|
||||
{
|
||||
case CONN_DIR_DOWNSTREAM:
|
||||
ATOMIC_INC(&(s_stream->mgr->stat_val[SSL_DOWN_NEW]));
|
||||
s_stream->ssl = downstream_ssl_create(mgr, kyr, selected_alpn);
|
||||
s_stream->down_parts.keyring = kyr;
|
||||
s_stream->ssl = downstream_ssl_create(mgr, kyr, selected_alpn);
|
||||
break;
|
||||
case CONN_DIR_UPSTREAM:
|
||||
ATOMIC_INC(&(s_stream->mgr->stat_val[SSL_UP_NEW]));
|
||||
@@ -553,7 +556,7 @@ void ssl_manager_destroy(struct ssl_mgr * mgr)
|
||||
|
||||
|
||||
struct ssl_mgr * ssl_manager_init(const char * ini_profile, const char * section,
|
||||
struct event_base * ev_base_gc, void * logger)
|
||||
struct event_base * ev_base_gc, void * logger, ssl_stream_new_hook* hook_func, void* hook_u_para)
|
||||
{
|
||||
unsigned char key_name[]="!mesalab-tfe3a~&";
|
||||
unsigned char aes_key_def[]={0xC5,0xAC,0xC1,0xA6,0xB2,0xBB,0xCA,0xC7,0xE3,0xBE,0xE3,0xB2,0xC6,0xA3,0xB1,0xB9
|
||||
@@ -622,7 +625,8 @@ struct ssl_mgr * ssl_manager_init(const char * ini_profile, const char * section
|
||||
mgr->down_sess_cache = ssl_sess_cache_create(mgr->cache_slots, mgr->sess_expire_seconds, CONN_DIR_DOWNSTREAM);
|
||||
}
|
||||
mgr->svc_cache=ssl_service_cache_create(mgr->cache_slots, mgr->sess_expire_seconds);
|
||||
|
||||
mgr->on_new_hook_func=hook_func;
|
||||
mgr->hook_u_para=hook_u_para;
|
||||
//Reference to NGINX: http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_ticket_key
|
||||
//Support key rotation in futher.
|
||||
|
||||
@@ -863,7 +867,8 @@ static SSL * upstream_ssl_create(struct ssl_mgr * mgr, struct ssl_stream* s_stre
|
||||
if(ret == 0)
|
||||
{
|
||||
/* session resuming based on remote endpoint address and port */
|
||||
sess = up_session_get(mgr->up_sess_cache, (struct sockaddr *) &addr, addrlen, chello->sni);
|
||||
sess = up_session_get(mgr->up_sess_cache, (struct sockaddr *) &addr, addrlen, chello->sni,
|
||||
SSL_get_min_proto_version(ssl), SSL_get_max_proto_version(ssl));
|
||||
if (sess)
|
||||
{
|
||||
SSL_set_session(ssl, sess); /* increments sess refcount */
|
||||
@@ -904,6 +909,16 @@ void wrap_ssl_connect_server_ctx_free(void *p)
|
||||
struct ssl_connect_server_ctx * ctx = (struct ssl_connect_server_ctx *)p;
|
||||
ssl_connect_server_ctx_free(ctx);
|
||||
}
|
||||
enum ssl_stream_action ssl_upstream_create_result_release_action(future_result_t * result)
|
||||
{
|
||||
struct ssl_connect_server_ctx * ctx = (struct ssl_connect_server_ctx *) result;
|
||||
return ctx->s_stream->up_parts.action;
|
||||
}
|
||||
evutil_socket_t ssl_upstream_create_result_release_fd(future_result_t * result)
|
||||
{
|
||||
struct ssl_connect_server_ctx * ctx = (struct ssl_connect_server_ctx *) result;
|
||||
return ctx->fd_upstream;
|
||||
}
|
||||
|
||||
struct ssl_stream * ssl_upstream_create_result_release_stream(future_result_t * result)
|
||||
{
|
||||
@@ -1105,6 +1120,10 @@ static void ssl_server_connected_eventcb(struct bufferevent * bev, short events,
|
||||
s_stream->up_parts.verify_result.is_hostmatched,
|
||||
s_stream->up_parts.verify_result.is_ct,
|
||||
s_stream->up_parts.verify_result.is_ev);
|
||||
if((!s_stream->up_parts.is_server_cert_verify_passed || !s_stream->up_parts.verify_result.is_hostmatched) && s_stream->up_parts.block_fake_cert)
|
||||
{
|
||||
s_stream->up_parts.action=SSL_ACTION_SHUTDOWN;
|
||||
}
|
||||
}
|
||||
if(s_stream->up_parts.is_server_cert_verify_passed)
|
||||
{
|
||||
@@ -1114,7 +1133,7 @@ static void ssl_server_connected_eventcb(struct bufferevent * bev, short events,
|
||||
//The reference count of the SSL_SESSION is not incremented, so no need to free.
|
||||
ssl_sess = SSL_get0_session(s_stream->ssl);
|
||||
up_session_set(mgr->up_sess_cache, (struct sockaddr *)&(ctx->addr),
|
||||
ctx->addrlen, s_upstream->client_hello->sni, ssl_sess);
|
||||
ctx->addrlen, s_upstream->client_hello->sni, SSL_version(s_stream->ssl), ssl_sess);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1161,10 +1180,10 @@ static void ssl_server_connected_eventcb(struct bufferevent * bev, short events,
|
||||
static void peek_chello_on_succ(future_result_t * result, void * user)
|
||||
{
|
||||
struct promise * p = (struct promise *) user;
|
||||
struct ssl_connect_server_ctx * ctx = (struct ssl_connect_server_ctx *) promise_get_ctx(p);
|
||||
struct ssl_connect_server_ctx* ctx = (struct ssl_connect_server_ctx *) promise_get_ctx(p);
|
||||
struct event_base* evbase=tfe_proxy_get_work_thread_evbase(ctx->thread_id);
|
||||
|
||||
struct ssl_chello * chello = ssl_peek_result_release_chello(result);//chello has been saved in ssl_stream.
|
||||
struct ssl_stream* s_stream=NULL;
|
||||
struct ssl_chello* chello = ssl_peek_result_release_chello(result);//chello has been saved in ssl_stream.
|
||||
if(chello->sni==NULL)
|
||||
{
|
||||
ATOMIC_INC(&(ctx->mgr->stat_val[SSL_NO_SNI]));
|
||||
@@ -1172,8 +1191,8 @@ static void peek_chello_on_succ(future_result_t * result, void * user)
|
||||
int ret=0;
|
||||
struct ssl_service_status* svc_status=NULL;
|
||||
clock_gettime(CLOCK_MONOTONIC, &(ctx->start));
|
||||
ctx->s_stream = ssl_stream_new(ctx->mgr, ctx->fd_upstream, CONN_DIR_UPSTREAM, chello, NULL, NULL);
|
||||
svc_status=&ctx->s_stream->up_parts.svc_status;
|
||||
s_stream= ssl_stream_new(ctx->mgr, ctx->fd_upstream, CONN_DIR_UPSTREAM, chello, NULL, NULL);
|
||||
svc_status=&s_stream->up_parts.svc_status;
|
||||
ret=ssl_service_cache_read(ctx->mgr->svc_cache, chello, svc_status);
|
||||
if(ret==1)
|
||||
{
|
||||
@@ -1184,6 +1203,15 @@ static void peek_chello_on_succ(future_result_t * result, void * user)
|
||||
svc_status->is_ct,
|
||||
svc_status->is_ev);
|
||||
}
|
||||
s_stream->up_parts.action=ctx->mgr->on_new_hook_func(s_stream, ctx->mgr->hook_u_para);
|
||||
ctx->s_stream = s_stream;
|
||||
if(s_stream->up_parts.action==SSL_ACTION_PASSTHROUGH)
|
||||
{
|
||||
promise_success(p, ctx);
|
||||
wrap_ssl_connect_server_ctx_free(ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->bev = bufferevent_openssl_socket_new(evbase, ctx->fd_upstream,
|
||||
ctx->s_stream->ssl, BUFFEREVENT_SSL_CONNECTING, BEV_OPT_DEFER_CALLBACKS | BEV_OPT_THREADSAFE );
|
||||
|
||||
@@ -1193,6 +1221,7 @@ static void peek_chello_on_succ(future_result_t * result, void * user)
|
||||
|
||||
future_destroy(ctx->f_peek_chello);
|
||||
ctx->f_peek_chello = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1316,7 +1345,7 @@ static int ossl_session_ticket_key_callback(SSL *ssl_conn,
|
||||
* the refcount decrementing. In other words, return 0 if we did not
|
||||
* keep a pointer to the object (which we never do here).
|
||||
*/
|
||||
static int ossl_sessnew_cb(SSL * ssl, SSL_SESSION * sess)
|
||||
static int ossl_downsess_new_cb(SSL * ssl, SSL_SESSION * sess)
|
||||
{
|
||||
struct ssl_mgr * mgr = (struct ssl_mgr *) SSL_get_ex_data(ssl, SSL_CTX_EX_DATA_IDX_SSLMGR);
|
||||
|
||||
@@ -1343,7 +1372,7 @@ static int ossl_sessnew_cb(SSL * ssl, SSL_SESSION * sess)
|
||||
* OpenSSL calls SSL_SESSION_free() after calling the callback;
|
||||
* we do not need to free the reference here.
|
||||
*/
|
||||
static void ossl_sessremove_cb(SSL_CTX * sslctx, SSL_SESSION * sess)
|
||||
static void ossl_downsess_remove_cb(SSL_CTX * sslctx, SSL_SESSION * sess)
|
||||
{
|
||||
struct ssl_mgr * mgr = (struct ssl_mgr *) SSL_CTX_get_ex_data(sslctx, SSL_CTX_EX_DATA_IDX_SSLMGR);
|
||||
assert(mgr != NULL);
|
||||
@@ -1360,7 +1389,7 @@ static void ossl_sessremove_cb(SSL_CTX * sslctx, SSL_SESSION * sess)
|
||||
* Called by OpenSSL when a src SSL session is requested by the client.
|
||||
OPENSSL_VERSION_NUMBER >= 0x10100000L required.
|
||||
*/
|
||||
static SSL_SESSION * ossl_sessget_cb(SSL * ssl, const unsigned char * id, int idlen, int * copy)
|
||||
static SSL_SESSION * ossl_downsess_get_cb(SSL * ssl, const unsigned char * id, int idlen, int * copy)
|
||||
{
|
||||
struct ssl_mgr * mgr = (struct ssl_mgr *) SSL_get_ex_data(ssl, SSL_CTX_EX_DATA_IDX_SSLMGR);
|
||||
SSL_SESSION * sess=NULL;
|
||||
@@ -1470,9 +1499,9 @@ static SSL * downstream_ssl_create(struct ssl_mgr * mgr, struct keyring * crt, c
|
||||
}
|
||||
}
|
||||
|
||||
SSL_CTX_sess_set_new_cb(sslctx, ossl_sessnew_cb);
|
||||
SSL_CTX_sess_set_remove_cb(sslctx, ossl_sessremove_cb);
|
||||
SSL_CTX_sess_set_get_cb(sslctx, ossl_sessget_cb);
|
||||
SSL_CTX_sess_set_new_cb(sslctx, ossl_downsess_new_cb);
|
||||
SSL_CTX_sess_set_remove_cb(sslctx, ossl_downsess_remove_cb);
|
||||
SSL_CTX_sess_set_get_cb(sslctx, ossl_downsess_get_cb);
|
||||
if(!mgr->no_sessticket)
|
||||
{
|
||||
SSL_CTX_set_tlsext_ticket_key_cb(sslctx, ossl_session_ticket_key_callback);
|
||||
@@ -1652,7 +1681,8 @@ void ask_keyring_on_succ(void * result, void * user)
|
||||
kyr = key_keeper_release_keyring(result); //kyr will be freed at ssl downstream closing.
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &(ctx->start));
|
||||
ctx->downstream = ssl_stream_new(mgr, ctx->fd_downstream, CONN_DIR_DOWNSTREAM, NULL, kyr,
|
||||
ctx->downstream = ssl_stream_new(mgr, ctx->fd_downstream, CONN_DIR_DOWNSTREAM,
|
||||
ctx->origin_ssl->up_parts.client_hello, kyr,
|
||||
ctx->origin_ssl?ctx->origin_ssl->alpn_selected:NULL);
|
||||
ctx->downstream->peer=ctx->origin_ssl;
|
||||
ctx->bev_down = bufferevent_openssl_socket_new(evbase, ctx->fd_downstream, ctx->downstream->ssl,
|
||||
@@ -1877,4 +1907,57 @@ void ssl_manager_reset_trust_ca(struct ssl_mgr* mgr)
|
||||
ssl_trusted_cert_storage_reset(mgr->trust_CA_store);
|
||||
return;
|
||||
}
|
||||
int ssl_stream_set_integer_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT opt_type, int opt_val)
|
||||
{
|
||||
struct cert_verify_param *verify_param=&(upstream->up_parts.verify_param);
|
||||
|
||||
switch(opt_type)
|
||||
{
|
||||
case SSL_STREAM_OPT_NO_VERIFY_SELF_SIGNED:
|
||||
verify_param->no_verify_self_signed=opt_val;
|
||||
break;
|
||||
case SSL_STREAM_OPT_NO_VERIFY_COMMON_NAME:
|
||||
verify_param->no_verify_cn=opt_val;
|
||||
break;
|
||||
case SSL_STREAM_OPT_NO_VERIFY_ISSUER:
|
||||
verify_param->no_verify_issuer=opt_val;
|
||||
break;
|
||||
case SSL_STREAM_OPT_NO_VERIFY_EXPIRY_DATE:
|
||||
verify_param->no_verify_expiry_date=opt_val;
|
||||
break;
|
||||
case SST_STREAM_OPT_VERIFY_FAIL_ACTION:
|
||||
upstream->up_parts.block_fake_cert=opt_val;
|
||||
break;
|
||||
case SSL_STREAM_OPT_PROTOCOL_MIN_VERSION:
|
||||
case SSL_STREAM_OPT_PROTOCOL_MAX_VERSION:
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
int ssl_stream_get_integer_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT opt_type, int *opt_val)
|
||||
{
|
||||
struct ssl_service_status* svc=&upstream->up_parts.svc_status;
|
||||
switch(opt_type)
|
||||
{
|
||||
case SSL_STREAM_OPT_IS_EV_CERT:
|
||||
*opt_val=svc->is_ev;
|
||||
break;
|
||||
case SSL_STREAM_OPT_IS_CT_CERT:
|
||||
*opt_val=svc->is_ct;
|
||||
break;
|
||||
case SSL_STREAM_OPT_IS_MUTUAL_AUTH:
|
||||
*opt_val=svc->is_mutual_auth;
|
||||
break;
|
||||
case SSL_STREAM_OPT_PINNING_STATUS:
|
||||
*opt_val=svc->pinning_status;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -341,6 +341,10 @@ int tfe_stream_action_set_opt(const struct tfe_stream * stream, enum tfe_stream_
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tfe_stream_set_integer_opt(struct tfe_stream * stream, enum tfe_stream_opt_level level, int type, int val)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
/* ====================================================================================================================
|
||||
* CONNECTION STRUCTURE AND OPERATION FUCTIONS
|
||||
* ===================================================================================================================*/
|
||||
@@ -795,7 +799,15 @@ static tfe_conn_private * __conn_private_create_by_bev(struct tfe_stream_private
|
||||
__conn_private->bev = bev;
|
||||
__conn_private->fd = bufferevent_getfd(bev);
|
||||
|
||||
if(stream->tcp_passthough)
|
||||
{
|
||||
bufferevent_setcb(__conn_private->bev, __stream_bev_passthrough_readcb,
|
||||
__stream_bev_passthrough_writecb, __stream_bev_passthrough_eventcb, stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
bufferevent_setcb(__conn_private->bev, __stream_bev_readcb, __stream_bev_writecb, __stream_bev_eventcb, stream);
|
||||
}
|
||||
bufferevent_disable(__conn_private->bev, EV_READ | EV_WRITE);
|
||||
|
||||
struct tfe_proxy * proxy_ref = stream->proxy_ref;
|
||||
@@ -825,7 +837,7 @@ static tfe_conn_private * __conn_private_create_by_fd(struct tfe_stream_private
|
||||
goto __errout;
|
||||
}
|
||||
|
||||
if (stream->passthough)
|
||||
if (stream->tcp_passthough)
|
||||
{
|
||||
bufferevent_setcb(__conn_private->bev, __stream_bev_passthrough_readcb,
|
||||
__stream_bev_passthrough_writecb, __stream_bev_passthrough_eventcb, stream);
|
||||
@@ -896,7 +908,21 @@ void ssl_downstream_create_on_fail(enum e_future_error err, const char * what, v
|
||||
void ssl_upstream_create_on_success(future_result_t * result, void * user)
|
||||
{
|
||||
struct tfe_stream_private * _stream = (struct tfe_stream_private *) user;
|
||||
|
||||
evutil_socket_t fd=-1;
|
||||
enum ssl_stream_action ssl_action=ssl_upstream_create_result_release_action(result);
|
||||
if(SSL_ACTION_PASSTHROUGH==ssl_action)
|
||||
{
|
||||
_stream->tcp_passthough=1;
|
||||
fd=ssl_upstream_create_result_release_fd(result);
|
||||
_stream->conn_upstream=__conn_private_create_by_fd(_stream, fd);
|
||||
_stream->conn_downstream=__conn_private_create_by_fd(_stream, _stream->defer_fd_downstream);
|
||||
}
|
||||
else if(SSL_ACTION_SHUTDOWN==ssl_action)
|
||||
{
|
||||
tfe_stream_destory(_stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct ssl_stream * upstream = ssl_upstream_create_result_release_stream(result);
|
||||
struct bufferevent * bev = ssl_upstream_create_result_release_bev(result);
|
||||
assert(upstream != NULL && bev != NULL);
|
||||
@@ -918,6 +944,7 @@ void ssl_upstream_create_on_success(future_result_t * result, void * user)
|
||||
|
||||
ssl_async_downstream_create(_stream->future_downstream_create, _stream->ssl_mgr,
|
||||
_stream->ssl_upstream, _stream->defer_fd_downstream, _stream->keyring_id, _stream->thread_ref->thread_id);
|
||||
}
|
||||
}
|
||||
|
||||
void ssl_upstream_create_on_fail(enum e_future_error err, const char * what, void * user)
|
||||
@@ -948,7 +975,7 @@ struct tfe_stream * tfe_stream_create(struct tfe_proxy * pxy, struct tfe_thread_
|
||||
|
||||
void __stream_access_log_write(struct tfe_stream_private * stream)
|
||||
{
|
||||
const char * str_passthrough = stream->passthough ? "PASSTHROUGH" : "-";
|
||||
const char * str_passthrough = stream->tcp_passthough ? "PASSTHROUGH" : "-";
|
||||
const char * str_kill = stream->need_to_be_kill ? "KILL" : "-";
|
||||
|
||||
char str_log_event[TFE_STRING_MAX] = "";
|
||||
@@ -1259,7 +1286,7 @@ int tfe_stream_option_set(struct tfe_stream * stream, enum tfe_stream_option opt
|
||||
else if (opt == TFE_STREAM_OPT_PASSTHROUGH)
|
||||
{
|
||||
assert(sz_arg == sizeof(bool));
|
||||
_stream->passthough = *(bool *) arg;
|
||||
_stream->tcp_passthough = *(bool *) arg;
|
||||
}
|
||||
else if (opt == TFE_STREAM_OPT_KEYRING_ID)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user