From fd216a51deb8444a08d672b1ab55f0a71eb7761b Mon Sep 17 00:00:00 2001 From: zhengchao Date: Fri, 31 Aug 2018 14:32:34 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=84=E7=90=86ssl=20upstream=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E5=A4=B1=E8=B4=A5=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- platform/src/ssl_stream.cpp | 134 +++++++++++++++++++++++++++++++----- platform/src/tcp_stream.cpp | 13 +++- 2 files changed, 128 insertions(+), 19 deletions(-) diff --git a/platform/src/ssl_stream.cpp b/platform/src/ssl_stream.cpp index 7a94427..c24a063 100644 --- a/platform/src/ssl_stream.cpp +++ b/platform/src/ssl_stream.cpp @@ -35,6 +35,19 @@ #define SSL_EX_DATA_IDX_SSLMGR 0 #define MAX_NET_RETRIES 50 +/* + * Default cipher suite spec. + * Use 'openssl ciphers -v spec' to see what ciphers are effectively enabled + * by a cipher suite spec with a given version of OpenSSL. + */ +#define DFLT_CIPHERS "ALL:-aNULL" + +/* + * Default elliptic curve for EC cipher suites. + */ +#define DFLT_CURVE "prime256v1" + + struct ssl_mgr { unsigned int sslcomp; @@ -304,6 +317,10 @@ struct ssl_mgr * ssl_manager_init(const char * ini_profile, const char * section MESA_load_profile_uint_def(ini_profile, section, "no_tls10", &(mgr->no_tls10), 1); MESA_load_profile_uint_def(ini_profile, section, "no_tls11", &(mgr->no_tls11), 0); MESA_load_profile_uint_def(ini_profile, section, "no_tls12", &(mgr->no_tls12), 0); + MESA_load_profile_string_def(ini_profile, section, "default_ciphers", mgr->default_ciphers, + sizeof(mgr->default_ciphers), DFLT_CIPHERS); + + MESA_load_profile_uint_def(ini_profile, section, "session_cache_slot_num", &(mgr->cache_slot_num), 4 * 1024 * 1024); MESA_load_profile_uint_def(ini_profile, section, "session_cache_slot_num", &(mgr->sess_expire_seconds), 30 * 60); @@ -311,13 +328,13 @@ struct ssl_mgr * ssl_manager_init(const char * ini_profile, const char * section 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); mgr->keeper_of_keys = key_keeper_init(ini_profile, section, logger); - +#if 0 if (mgr->keeper_of_keys == NULL) { TFE_LOG_ERROR(logger, "Certificate Manager initiate failed."); goto error_out; } - +#endif mgr->trust_CA_store = X509_STORE_new(); if (mgr->trust_CA_store == NULL) { @@ -583,6 +600,85 @@ struct bufferevent * ssl_upstream_create_result_release_bev(future_result_t * re ctx->bev = NULL; //giveup ownership return ret; } +void ssl_handle_conn_origin_err(struct bufferevent * bev, void* logger) +{ + unsigned long sslerr=0; + + /* Can happen for socket errs, ssl errs; + * may happen for unclean ssl socket shutdowns. */ + sslerr = bufferevent_get_openssl_error(bev); + + if (!errno && !sslerr) + { + /* We have disabled notification for unclean shutdowns + * so this should not happen; log a warning. */ + TFE_LOG_ERROR(logger,"Warning: Spurious error from " + "bufferevent (errno=0,sslerr=0)\n"); + } + else if (ERR_GET_REASON(sslerr) == + SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE) + { + /* these can happen due to client cert auth, + * only log error if debugging is activated */ + TFE_LOG_ERROR(logger,"Error from upstream bufferevent: " + "%i:%s %lu:%i:%s:%i:%s:%i:%s\n", + errno, + errno ? strerror(errno) : "-", + sslerr, + ERR_GET_REASON(sslerr), + sslerr ? + ERR_reason_error_string(sslerr) : "-", + ERR_GET_LIB(sslerr), + sslerr ? + ERR_lib_error_string(sslerr) : "-", + ERR_GET_FUNC(sslerr), + sslerr ? + ERR_func_error_string(sslerr) : "-"); + while ((sslerr = bufferevent_get_openssl_error(bev))) + { + TFE_LOG_ERROR(logger,"Additional SSL error: " + "%lu:%i:%s:%i:%s:%i:%s\n", + sslerr, + ERR_GET_REASON(sslerr), + ERR_reason_error_string(sslerr), + ERR_GET_LIB(sslerr), + ERR_lib_error_string(sslerr), + ERR_GET_FUNC(sslerr), + ERR_func_error_string(sslerr)); + } + } + else + { + /* real errors */ + TFE_LOG_ERROR(logger,"Error from upstream bufferevent: " + "%i:%s %lu:%i:%s:%i:%s:%i:%s\n", + errno, + errno ? strerror(errno) : "-", + sslerr, + ERR_GET_REASON(sslerr), + sslerr ? + ERR_reason_error_string(sslerr) : "-", + ERR_GET_LIB(sslerr), + sslerr ? + ERR_lib_error_string(sslerr) : "-", + ERR_GET_FUNC(sslerr), + sslerr ? + ERR_func_error_string(sslerr) : "-"); + while ((sslerr = bufferevent_get_openssl_error(bev))) + { + TFE_LOG_ERROR(logger,"Additional SSL error: " + "%lu:%i:%s:%i:%s:%i:%s\n", + sslerr, + ERR_GET_REASON(sslerr), + ERR_reason_error_string(sslerr), + ERR_GET_LIB(sslerr), + ERR_lib_error_string(sslerr), + ERR_GET_FUNC(sslerr), + ERR_func_error_string(sslerr)); + } + } + +} /* * Callback for meta events on the up- and downstream connection bufferevents. @@ -598,24 +694,26 @@ static void ssl_connect_origin_eventcb(struct bufferevent * bev, short events, v if (events & BEV_EVENT_ERROR) { - promise_failed(promise, FUTURE_ERROR_EXCEPTION, "connect to orignal server failed."); + ssl_handle_conn_origin_err(bev,ctx->mgr->logger); + promise_failed(promise, FUTURE_ERROR_EXCEPTION, "connect to original server failed."); } - else + else if(events & BEV_EVENT_EOF) { - if (events & BEV_EVENT_CONNECTED) - { - bufferevent_setcb(ctx->bev, NULL, NULL, NULL, NULL); //leave a clean bev for on_success - ssl_sess = SSL_get0_session(s_stream->ssl); - up_session_set(s_stream->mgr->up_sess_cache, (struct sockaddr *)&(ctx->addr), - ctx->addrlen, s_stream->client_hello->sni, ssl_sess); - promise_success(promise, ctx); - } - else - { - assert(0); - } + promise_failed(promise, FUTURE_ERROR_EXCEPTION, "original server closed."); + } + else if(events & BEV_EVENT_TIMEOUT) + { + promise_failed(promise, FUTURE_ERROR_TIMEOUT, NULL); + } + else if(events & BEV_EVENT_CONNECTED) + { + bufferevent_disable(ctx->bev, EV_READ | EV_WRITE); + bufferevent_setcb(ctx->bev, NULL, NULL, NULL, NULL); //leave a clean bev for on_success + ssl_sess = SSL_get0_session(s_stream->ssl); + up_session_set(s_stream->mgr->up_sess_cache, (struct sockaddr *)&(ctx->addr), + ctx->addrlen, s_stream->client_hello->sni, ssl_sess); + promise_success(promise, ctx); } - ssl_connect_origin_ctx_free(ctx); return; } @@ -632,7 +730,7 @@ static void peek_chello_on_succ(future_result_t * result, void * user) bufferevent_openssl_set_allow_dirty_shutdown(ctx->bev, 1); bufferevent_setcb(ctx->bev, NULL, NULL, ssl_connect_origin_eventcb, p); - bufferevent_disable(ctx->bev, EV_READ | EV_WRITE); //waiting for connect event only + bufferevent_enable(ctx->bev, EV_READ | EV_WRITE); //waiting for connect event only future_destroy(ctx->f_peek_chello); ctx->f_peek_chello = NULL; diff --git a/platform/src/tcp_stream.cpp b/platform/src/tcp_stream.cpp index 4f68eec..e744a8c 100644 --- a/platform/src/tcp_stream.cpp +++ b/platform/src/tcp_stream.cpp @@ -461,7 +461,6 @@ static tfe_conn_private * __conn_private_create(struct tfe_stream_private * stre __stream_bev_writecb, __stream_bev_eventcb, stream); } - bufferevent_enable(__conn_private->bev, EV_READ | EV_WRITE); return __conn_private; __errout: @@ -470,6 +469,11 @@ __errout: } +void __conn_private_enable(struct tfe_conn_private * conn_private) +{ + assert(conn_private != NULL && conn_private->bev != NULL); + bufferevent_enable(conn_private->bev, EV_READ | EV_WRITE); +} void ssl_downstream_create_on_success(future_result_t * result, void * user) { @@ -484,6 +488,10 @@ void ssl_downstream_create_on_success(future_result_t * result, void * user) _stream->future_downstream_create = NULL; _stream->defer_fd_downstream = 0; + assert(_stream->conn_downstream != NULL && _stream->conn_upstream != NULL); + __conn_private_enable(_stream->conn_downstream); + __conn_private_enable(_stream->conn_upstream); + return; } @@ -600,6 +608,9 @@ void tfe_stream_init_by_fds(struct tfe_stream * stream, evutil_socket_t fd_downs assert(_stream->conn_downstream != NULL); assert(_stream->conn_upstream != NULL); + + __conn_private_enable(_stream->conn_downstream); + __conn_private_enable(_stream->conn_upstream); } if (_stream->session_type == SESSION_PROTO_SSL)