ssl stream隐藏peek_sni和cert store的处理流程。
This commit is contained in:
@@ -2,35 +2,22 @@
|
|||||||
#include <event2/event.h>
|
#include <event2/event.h>
|
||||||
#include <tfe_future.h>
|
#include <tfe_future.h>
|
||||||
#include <cert.h>
|
#include <cert.h>
|
||||||
|
#include <field_stat2.h>
|
||||||
|
|
||||||
|
|
||||||
struct ssl_stream;
|
struct ssl_stream;
|
||||||
|
|
||||||
struct ssl_mgr;
|
struct ssl_mgr;
|
||||||
struct ssl_mgr* init_ssl_manager(const char* ini_profile, const char* section, void* logger);
|
struct ssl_mgr* ssl_manager_init(const char* ini_profile, const char* section, struct event_base *evbase, void* logger, screen_stat_handle_t* fs);
|
||||||
void destroy_ssl_manager(struct ssl_mgr* mgr);
|
void ssl_manager_destroy(struct ssl_mgr* mgr);
|
||||||
|
|
||||||
struct ssl_chello
|
|
||||||
{
|
|
||||||
//client hello
|
|
||||||
int version;
|
|
||||||
char* sni;
|
|
||||||
char* cipher_suites;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ssl_chello* ssl_peek_result_release_chello(future_result_t* result);
|
|
||||||
void ssl_chello_free(struct ssl_chello* client_hello);
|
|
||||||
void ssl_async_peek_client_hello(struct future* future, evutil_socket_t fd, struct event_base *evbase);
|
|
||||||
|
|
||||||
|
|
||||||
struct ssl_stream* ssl_upstream_create_result_release_stream(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);
|
struct bufferevent* ssl_upstream_create_result_release_bev(future_result_t* result);
|
||||||
void ssl_async_upstream_create(struct future* future, struct ssl_mgr* mgr, const struct ssl_chello* chello, evutil_socket_t fd, struct event_base *evbase);
|
void ssl_async_upstream_create(struct future* f, struct ssl_mgr* mgr, evutil_socket_t fd_upstream, evutil_socket_t fd_downstream, struct event_base *evbase);
|
||||||
|
|
||||||
|
struct ssl_stream* ssl_downstream_create_result_release_stream(future_result_t* result);
|
||||||
|
struct bufferevent* ssl_downstream_create_result_release_bev(future_result_t* result);
|
||||||
|
void ssl_async_downstream_create(struct future* f, struct ssl_mgr* mgr, struct ssl_stream* upstream, evutil_socket_t fd_downstream, struct event_base *evbase);
|
||||||
|
|
||||||
|
|
||||||
struct ssl_stream * ssl_downstream_create(struct ssl_mgr* mgr, struct ssl_chello* hello, struct cert* crt);
|
|
||||||
void ssl_stream_free_and_close_fd(struct ssl_stream* stream, struct event_base *evbase, evutil_socket_t fd);
|
void ssl_stream_free_and_close_fd(struct ssl_stream* stream, struct event_base *evbase, evutil_socket_t fd);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,23 +27,27 @@
|
|||||||
#include <tfe_future.h>
|
#include <tfe_future.h>
|
||||||
#include <stream.h>
|
#include <stream.h>
|
||||||
#include <cert.h>
|
#include <cert.h>
|
||||||
|
#include <ssl_sess_cache.h>
|
||||||
#include <ssl.h>
|
#include <ssl.h>
|
||||||
#include <MESA_htable.h>
|
#include <MESA_htable.h>
|
||||||
#define SSL_EX_DATA_IDX_SSLMGR 0
|
#define SSL_EX_DATA_IDX_SSLMGR 0
|
||||||
|
#define MAX_NET_RETRIES 50
|
||||||
struct ssl_mgr
|
struct ssl_mgr
|
||||||
{
|
{
|
||||||
uint8_t sslcomp;
|
int sslcomp;
|
||||||
uint8_t no_ssl2;
|
int no_ssl2;
|
||||||
uint8_t no_ssl3;
|
int no_ssl3;
|
||||||
uint8_t no_tls10;
|
int no_tls10;
|
||||||
uint8_t no_tls11;
|
int no_tls11;
|
||||||
uint8_t no_tls12;
|
int no_tls12;
|
||||||
CONST_SSL_METHOD *(*sslmethod)(void);
|
CONST_SSL_METHOD *(*sslmethod)(void); //Parameter of SSL_CTX_new
|
||||||
int sslversion;
|
int sslversion;
|
||||||
char ssl_session_context[8];
|
char ssl_session_context[8];
|
||||||
MESA_htable_handle down_sess_cache;
|
int cache_slot_num;
|
||||||
MESA_htable_handle up_sess_cache;
|
int sess_expire_seconds;
|
||||||
char* default_ciphers;
|
struct sess_cache* down_sess_cache;
|
||||||
|
struct sess_cache* up_sess_cache;
|
||||||
|
char* default_ciphers[TFE_SYMBOL_MAX];
|
||||||
DH * dh;
|
DH * dh;
|
||||||
char * ecdhcurve;
|
char * ecdhcurve;
|
||||||
char * crlurl;
|
char * crlurl;
|
||||||
@@ -57,13 +61,19 @@ struct ssl_stream
|
|||||||
struct ssl_mgr* ref_mgr;
|
struct ssl_mgr* ref_mgr;
|
||||||
char* sni;
|
char* sni;
|
||||||
};
|
};
|
||||||
|
struct ssl_chello
|
||||||
|
{
|
||||||
|
//client hello
|
||||||
|
int version;
|
||||||
|
char* sni;
|
||||||
|
char* cipher_suites;
|
||||||
|
};
|
||||||
|
|
||||||
struct peek_client_hello_ctx
|
struct peek_client_hello_ctx
|
||||||
{
|
{
|
||||||
|
|
||||||
unsigned char sni_peek_retries; /* max 64 SNI parse retries */
|
unsigned char sni_peek_retries; /* max 64 SNI parse retries */
|
||||||
struct event* ev;
|
struct event* ev;
|
||||||
struct event_base* evbase;
|
struct event_base* evbase;
|
||||||
|
|
||||||
};
|
};
|
||||||
struct ssl_connect_origin_ctx
|
struct ssl_connect_origin_ctx
|
||||||
{
|
{
|
||||||
@@ -81,64 +91,76 @@ struct ssl_shutdown_ctx {
|
|||||||
struct event *ev;
|
struct event *ev;
|
||||||
unsigned int retries;
|
unsigned int retries;
|
||||||
};
|
};
|
||||||
|
static int parse_ssl_version(const char * version_str)
|
||||||
struct ssl_mgr* init_ssl_manager(const char* ini_profile, const char* section, void* logger)
|
|
||||||
{
|
{
|
||||||
struct ssl_mgr* mgr=ALLOC(struct ssl_mgr, 1);
|
int sslversion=-1;
|
||||||
mgr->logger=logger;
|
assert(OPENSSL_VERSION_NUMBER >= 0x10100000L);
|
||||||
memcpy(mgr->ssl_session_context,"mesa-tfe",sizeof(mgr->ssl_session_context));
|
/*
|
||||||
return mgr;
|
* 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;
|
||||||
}
|
}
|
||||||
void destroy_ssl_manager(struct ssl_mgr* mgr)
|
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
|
||||||
|
{
|
||||||
|
sslversion =-1;
|
||||||
|
}
|
||||||
|
return sslversion;
|
||||||
|
}
|
||||||
|
void ssl_manager_destroy(struct ssl_mgr* mgr)
|
||||||
{
|
{
|
||||||
free(mgr);
|
free(mgr);
|
||||||
}
|
}
|
||||||
SSL_SESSION* up_session_get(MESA_htable_handle* cache, struct sockaddr * addr, socklen_t addr_len, const char* sni)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
struct ssl_mgr* ssl_manager_init(const char* ini_profile, const char* section, void* logger)
|
||||||
|
{
|
||||||
|
struct ssl_mgr* mgr=ALLOC(struct ssl_mgr, 1);
|
||||||
|
int ret=0,value=0;
|
||||||
|
char version_str[TFE_SYMBOL_MAX];
|
||||||
|
mgr->logger=logger;
|
||||||
|
MESA_load_profile_string_def(ini_profile, section, "ssl_version", version_str, sizeof(version_str),"tls12");
|
||||||
|
mgr->sslversion=parse_ssl_version(version_str);
|
||||||
|
if(mgr->sslversion<0)
|
||||||
|
{
|
||||||
|
TFE_LOG_ERROR(logger, "Unsupported SSL/TLS protocol %s",version_str);
|
||||||
|
goto error_out;
|
||||||
}
|
}
|
||||||
void up_session_set(MESA_htable_handle* cache, struct sockaddr * addr, socklen_t addr_len, const char* sni, SSL_SESSION * value)
|
//tfe2a uses SSLv23_method, it was been deprecated and replaced with the TLS_method() in openssl 1.1.0.
|
||||||
{
|
mgr->sslmethod=TLS_method;
|
||||||
|
MESA_load_profile_int_def(ini_profile, section, "ssl_compression", &(mgr->sslcomp), 1);
|
||||||
|
MESA_load_profile_int_def(ini_profile, section, "no_ssl2", &(mgr->no_ssl2), 1);
|
||||||
|
MESA_load_profile_int_def(ini_profile, section, "no_ssl3", &(mgr->no_ssl3), 1);
|
||||||
|
MESA_load_profile_int_def(ini_profile, section, "no_tls10", &(mgr->no_tls10), 1);
|
||||||
|
MESA_load_profile_int_def(ini_profile, section, "no_tls11", &(mgr->no_tls11), 0);
|
||||||
|
MESA_load_profile_int_def(ini_profile, section, "no_tls12", &(mgr->no_tls12), 0);
|
||||||
|
MESA_load_profile_int_def(ini_profile, section, "session_cache_slot_num", &(mgr->cache_slot_num), 4*1024*1024);
|
||||||
|
MESA_load_profile_int_def(ini_profile, section, "session_cache_slot_num", &(mgr->sess_expire_seconds), 30*60);
|
||||||
|
|
||||||
}
|
mgr->up_sess_cache=ssl_sess_cache_create(mgr->cache_slot_num, mgr->sess_expire_seconds,CONN_DIR_UPSTREAM);
|
||||||
SSL_SESSION* down_session_get(MESA_htable_handle* cache, unsigned char * id, int idlen)
|
mgr->down_sess_cache=ssl_sess_cache_create(mgr->cache_slot_num, mgr->sess_expire_seconds,CONN_DIR_DOWNSTREAM);
|
||||||
{
|
|
||||||
dynbuf_t *valbuf = (dynbuf_t *)val;
|
|
||||||
MESA_htable_search_cb(const MESA_htable_handle table, const uchar * key, uint size, hash_cb_fun_t * cb, void * arg, long * cb_ret);
|
|
||||||
SSL_SESSION *sess;
|
|
||||||
const unsigned char *p;
|
|
||||||
|
|
||||||
p = (const unsigned char *)valbuf->buf;
|
memcpy(mgr->ssl_session_context,"mesa-tfe",sizeof(mgr->ssl_session_context));
|
||||||
sess = d2i_SSL_SESSION(NULL, &p, valbuf->sz); /* increments p */
|
return mgr;
|
||||||
if (!sess)
|
error_out:
|
||||||
return NULL;
|
ssl_manager_destroy(mgr);
|
||||||
if (!ssl_session_is_valid(sess)) {
|
|
||||||
SSL_SESSION_free(sess);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (copy)
|
|
||||||
return sess;
|
|
||||||
SSL_SESSION_free(sess);
|
|
||||||
return ((void*)-1);
|
|
||||||
|
|
||||||
}
|
|
||||||
void down_session_set(MESA_htable_handle* cache, SSL_SESSION* sess)
|
|
||||||
{
|
|
||||||
unsigned int len=0;
|
|
||||||
const unsigned char* id = SSL_SESSION_get_id(sess, &len);
|
|
||||||
unsigned char *p=NULL;
|
|
||||||
size_t asn1sz=0;
|
|
||||||
|
|
||||||
asn1sz = i2d_SSL_SESSION(sess, NULL);
|
|
||||||
p=ALLOC(char, asn1sz);
|
|
||||||
i2d_SSL_SESSION(sess, &p); /* updates p */
|
|
||||||
int ret=MESA_htable_add(cache, id, len, p);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
void down_session_del(MESA_htable_handle* cache, SSL_SESSION* sess)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void peek_client_hello_ctx_free(void* ctx)
|
void peek_client_hello_ctx_free(void* ctx)
|
||||||
{
|
{
|
||||||
@@ -223,7 +245,7 @@ static void peek_client_hello_cb(evutil_socket_t fd, short what, void * arg)
|
|||||||
reason="see no client hello";
|
reason="see no client hello";
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ctx->sni_peek_retries++ > MAX_NET_RETRIES)
|
if(ctx->sni_peek_retries++ > MAX_NET_RETRIES)
|
||||||
{
|
{
|
||||||
TFE_LOG_ERROR("Peek failed due to too many retries\n");
|
TFE_LOG_ERROR("Peek failed due to too many retries\n");
|
||||||
@@ -324,11 +346,6 @@ static SSL* upstream_ssl_create(struct ssl_mgr* mgr, const struct ssl_chello* ch
|
|||||||
|
|
||||||
return ssl;
|
return ssl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ssl_stream_shutdown(struct bufferevent *bev,struct ssl_stream* ssl)
|
|
||||||
{
|
|
||||||
//TODO:
|
|
||||||
|
|
||||||
void ssl_connect_origin_ctx_free(struct ssl_connect_origin_ctx* ctx)
|
void ssl_connect_origin_ctx_free(struct ssl_connect_origin_ctx* ctx)
|
||||||
{
|
{
|
||||||
@@ -395,7 +412,7 @@ static void ssl_connect_origin_eventcb(struct bufferevent * bev, short events, v
|
|||||||
ssl_connect_origin_ctx_free(ctx);
|
ssl_connect_origin_ctx_free(ctx);
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
void ssl_async_upstream_create(struct future* f, struct ssl_mgr* mgr, const struct ssl_chello* chello, evutil_socket_t fd, struct event_base *evbase)
|
void ssl_async_upstream_create(struct future* f, struct ssl_mgr* mgr, const struct ssl_chello* chello, evutil_socket_t fd, struct event_base *evbase)
|
||||||
{
|
{
|
||||||
struct promise* p=future_to_promise(future);
|
struct promise* p=future_to_promise(future);
|
||||||
@@ -453,6 +470,7 @@ static void
|
|||||||
static void
|
static void
|
||||||
ossl_sessremove_cb(UNUSED SSL_CTX * sslctx, SSL_SESSION * sess)
|
ossl_sessremove_cb(UNUSED SSL_CTX * sslctx, SSL_SESSION * sess)
|
||||||
{
|
{
|
||||||
|
struct ssl_mgr* mgr=(struct ssl_mgr*) SSL_get_ex_data(ssl, SSL_EX_DATA_IDX_SSLMGR, mgr);
|
||||||
assert(mgr!=NULL);
|
assert(mgr!=NULL);
|
||||||
if (sess)
|
if (sess)
|
||||||
{
|
{
|
||||||
@@ -566,11 +584,8 @@ static SSL_CTX * down_sslctx_create(struct ssl_mgr* mgr, struct cert* crt)
|
|||||||
SSL_CTX_sess_set_remove_cb(sslctx, ossl_sessremove_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_get_cb(sslctx, ossl_sessget_cb);
|
||||||
SSL_CTX_set_session_cache_mode(sslctx, SSL_SESS_CACHE_SERVER |
|
SSL_CTX_set_session_cache_mode(sslctx, SSL_SESS_CACHE_SERVER |
|
||||||
SSL_SESS_CACHE_NO_INTERNAL);
|
|
||||||
SSL_SESS_CACHE_NO_INTERNAL);
|
SSL_SESS_CACHE_NO_INTERNAL);
|
||||||
SSL_CTX_set_session_id_context(sslctx, (void *)(mgr->ssl_session_context),
|
SSL_CTX_set_session_id_context(sslctx, (void *)(mgr->ssl_session_context),
|
||||||
sizeof(mgr->ssl_session_context));
|
|
||||||
#endif /* USE_SSL_SESSION_ID_CONTEXT */
|
|
||||||
sizeof(mgr->ssl_session_context));
|
sizeof(mgr->ssl_session_context));
|
||||||
#ifndef OPENSSL_NO_DH
|
#ifndef OPENSSL_NO_DH
|
||||||
if (mgr->dh)
|
if (mgr->dh)
|
||||||
@@ -611,8 +626,9 @@ static SSL_CTX * down_sslctx_create(struct ssl_mgr* mgr, struct cert* crt)
|
|||||||
/*
|
/*
|
||||||
* Create new SSL context for the incoming connection, based on the a designate cert
|
* Create new SSL context for the incoming connection, based on the a designate cert
|
||||||
* Returns NULL when openssl error.
|
* Returns NULL when openssl error.
|
||||||
*/
|
*/
|
||||||
void ssl_async_downstream_create(struct future* f, struct ssl_mgr* mgr, struct ssl_chello* hello, evutil_socket_t fd, struct event_base *evbase)
|
void ssl_async_downstream_create(struct future* f, struct ssl_mgr* mgr, struct ssl_chello* hello, evutil_socket_t fd, struct event_base *evbase)
|
||||||
|
{
|
||||||
struct cert* crt;
|
struct cert* crt;
|
||||||
struct ssl_stream* p=NULL;
|
struct ssl_stream* p=NULL;
|
||||||
if(crt==NULL)
|
if(crt==NULL)
|
||||||
@@ -735,7 +751,7 @@ pxy_ssl_shutdown_cb(evutil_socket_t fd, UNUSED short what, void *arg)
|
|||||||
}
|
}
|
||||||
goto complete;
|
goto complete;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
if (ctx->retries++ >= MAX_NET_RETRIES) {
|
if (ctx->retries++ >= MAX_NET_RETRIES) {
|
||||||
TFE_LOG_ERROR(logger,"Failed to shutdown SSL connection cleanly: "
|
TFE_LOG_ERROR(logger,"Failed to shutdown SSL connection cleanly: "
|
||||||
"Max retries reached. Closing fd.\n");
|
"Max retries reached. Closing fd.\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user