ssl stream隐藏peek_sni和cert store的处理流程。

This commit is contained in:
zhengchao
2018-08-24 19:22:43 +08:00
parent 6d7940ff00
commit b000487322
2 changed files with 95 additions and 92 deletions

View File

@@ -27,23 +27,27 @@
#include <tfe_future.h>
#include <stream.h>
#include <cert.h>
#include <ssl_sess_cache.h>
#include <ssl.h>
#include <MESA_htable.h>
#define SSL_EX_DATA_IDX_SSLMGR 0
#define MAX_NET_RETRIES 50
struct ssl_mgr
{
uint8_t sslcomp;
uint8_t no_ssl2;
uint8_t no_ssl3;
uint8_t no_tls10;
uint8_t no_tls11;
uint8_t no_tls12;
CONST_SSL_METHOD *(*sslmethod)(void);
int sslcomp;
int no_ssl2;
int no_ssl3;
int no_tls10;
int no_tls11;
int no_tls12;
CONST_SSL_METHOD *(*sslmethod)(void); //Parameter of SSL_CTX_new
int sslversion;
char ssl_session_context[8];
MESA_htable_handle down_sess_cache;
MESA_htable_handle up_sess_cache;
char* default_ciphers;
int cache_slot_num;
int sess_expire_seconds;
struct sess_cache* down_sess_cache;
struct sess_cache* up_sess_cache;
char* default_ciphers[TFE_SYMBOL_MAX];
DH * dh;
char * ecdhcurve;
char * crlurl;
@@ -57,13 +61,19 @@ struct ssl_stream
struct ssl_mgr* ref_mgr;
char* sni;
};
struct ssl_chello
{
//client hello
int version;
char* sni;
char* cipher_suites;
};
struct peek_client_hello_ctx
{
unsigned char sni_peek_retries; /* max 64 SNI parse retries */
struct event* ev;
struct event_base* evbase;
};
struct ssl_connect_origin_ctx
{
@@ -81,64 +91,76 @@ struct ssl_shutdown_ctx {
struct event *ev;
unsigned int retries;
};
struct ssl_mgr* init_ssl_manager(const char* ini_profile, const char* section, void* logger)
static int parse_ssl_version(const char * version_str)
{
struct ssl_mgr* mgr=ALLOC(struct ssl_mgr, 1);
mgr->logger=logger;
memcpy(mgr->ssl_session_context,"mesa-tfe",sizeof(mgr->ssl_session_context));
return mgr;
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
{
sslversion =-1;
}
return sslversion;
}
void destroy_ssl_manager(struct ssl_mgr* mgr)
void ssl_manager_destroy(struct ssl_mgr* mgr)
{
free(mgr);
}
SSL_SESSION* up_session_get(MESA_htable_handle* cache, struct sockaddr * addr, socklen_t addr_len, const char* sni)
{
}
void up_session_set(MESA_htable_handle* cache, struct sockaddr * addr, socklen_t addr_len, const char* sni, SSL_SESSION * value)
struct ssl_mgr* ssl_manager_init(const char* ini_profile, const char* section, void* logger)
{
}
SSL_SESSION* down_session_get(MESA_htable_handle* cache, unsigned char * id, int idlen)
{
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;
sess = d2i_SSL_SESSION(NULL, &p, valbuf->sz); /* increments p */
if (!sess)
return NULL;
if (!ssl_session_is_valid(sess)) {
SSL_SESSION_free(sess);
return NULL;
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;
}
if (copy)
return sess;
SSL_SESSION_free(sess);
return ((void*)-1);
//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);
mgr->down_sess_cache=ssl_sess_cache_create(mgr->cache_slot_num, mgr->sess_expire_seconds,CONN_DIR_DOWNSTREAM);
memcpy(mgr->ssl_session_context,"mesa-tfe",sizeof(mgr->ssl_session_context));
return mgr;
error_out:
ssl_manager_destroy(mgr);
return NULL;
}
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)
{
@@ -223,7 +245,7 @@ static void peek_client_hello_cb(evutil_socket_t fd, short what, void * arg)
reason="see no client hello";
goto failed;
}
if(ctx->sni_peek_retries++ > MAX_NET_RETRIES)
{
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;
}
void ssl_stream_shutdown(struct bufferevent *bev,struct ssl_stream* ssl)
{
//TODO:
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);
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)
{
struct promise* p=future_to_promise(future);
@@ -453,6 +470,7 @@ static void
static void
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);
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_get_cb(sslctx, ossl_sessget_cb);
SSL_CTX_set_session_cache_mode(sslctx, SSL_SESS_CACHE_SERVER |
SSL_SESS_CACHE_NO_INTERNAL);
SSL_SESS_CACHE_NO_INTERNAL);
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));
#ifndef OPENSSL_NO_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
* 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)
{
struct cert* crt;
struct ssl_stream* p=NULL;
if(crt==NULL)
@@ -639,7 +655,7 @@ struct ssl_stream * ssl_downstream_create(struct ssl_mgr* mgr, struct ssl_chello
}
if(mgr->SSL_MODE_RELEASE_BUFFERS==1)
{
/* lower memory footprint for idle connections */
/* lower memory footprint for idle connections */
SSL_set_mode(p->ssl, SSL_get_mode(p->ssl) | SSL_MODE_RELEASE_BUFFERS);
}
p->sni=tfe_strdup(hello->sni);
@@ -735,7 +751,7 @@ pxy_ssl_shutdown_cb(evutil_socket_t fd, UNUSED short what, void *arg)
}
goto complete;
retry:
retry:
if (ctx->retries++ >= MAX_NET_RETRIES) {
TFE_LOG_ERROR(logger,"Failed to shutdown SSL connection cleanly: "
"Max retries reached. Closing fd.\n");