diff --git a/platform/include/internal/ssl_stream.h b/platform/include/internal/ssl_stream.h index 47b619f..b6407fc 100644 --- a/platform/include/internal/ssl_stream.h +++ b/platform/include/internal/ssl_stream.h @@ -2,35 +2,22 @@ #include #include #include - +#include struct ssl_stream; struct ssl_mgr; -struct ssl_mgr* init_ssl_manager(const char* ini_profile, const char* section, void* logger); -void destroy_ssl_manager(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_mgr* ssl_manager_init(const char* ini_profile, const char* section, struct event_base *evbase, void* logger, screen_stat_handle_t* fs); +void ssl_manager_destroy(struct ssl_mgr* mgr); 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* 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); - diff --git a/platform/src/ssl_stream.cpp b/platform/src/ssl_stream.cpp index ba0c5de..c6f3565 100644 --- a/platform/src/ssl_stream.cpp +++ b/platform/src/ssl_stream.cpp @@ -27,23 +27,27 @@ #include #include #include +#include #include #include #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) goto failed; } - if(ctx->sni_peek_retries++ > 50) + if(ctx->sni_peek_retries++ > MAX_NET_RETRIES) { TFE_LOG_ERROR("Peek failed due to too many retries\n"); reason="too many peek retries"; @@ -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) { if(ctx->ssl!=NULL) @@ -395,7 +412,7 @@ static void ssl_connect_origin_eventcb(struct bufferevent * bev, short events, v return } -void ssl_async_connect_origin(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, const struct ssl_chello* chello, evutil_socket_t fd, struct event_base *evbase) { struct promise* p=future_to_promise(future); struct ssl_connect_origin_ctx* ctx=ALLOC(struct ssl_connect_origin_ctx, 1); @@ -453,6 +470,7 @@ 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) { down_session_del(mgr->down_sess_cache, sess); @@ -566,11 +584,8 @@ static SSL_CTX * down_sslctx_create(struct ssl_mgr* mgr, struct cert* crt) 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); -#ifdef USE_SSL_SESSION_ID_CONTEXT SSL_CTX_set_session_id_context(sslctx, (void *)(mgr->ssl_session_context), sizeof(mgr->ssl_session_context)); -#endif /* USE_SSL_SESSION_ID_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. */ -struct ssl_stream * ssl_downstream_create(struct ssl_mgr* mgr, struct ssl_chello* hello, struct cert* crt) +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 */ - SSL_set_mode( p->ssl, SSL_get_mode(p->ssl) | SSL_MODE_RELEASE_BUFFERS); + SSL_set_mode(p->ssl, SSL_get_mode(p->ssl) | SSL_MODE_RELEASE_BUFFERS); } p->sni=tfe_strdup(hello->sni); return p; @@ -735,7 +751,7 @@ pxy_ssl_shutdown_cb(evutil_socket_t fd, UNUSED short what, void *arg) goto complete; retry: - if (ctx->retries++ >= 50) { + if (ctx->retries++ >= MAX_NET_RETRIES) { TFE_LOG_ERROR(logger,"Failed to shutdown SSL connection cleanly: " "Max retries reached. Closing fd.\n"); goto complete;