支持通过拦截策略指定ssl最大和最小版本号。
This commit is contained in:
@@ -207,6 +207,8 @@ struct ssl_stream
|
|||||||
int ssl_min_version, ssl_max_version, negotiated_version;
|
int ssl_min_version, ssl_max_version, negotiated_version;
|
||||||
const unsigned char* alpn_selected; //reference to SSL_ALPN_HTTP_2/SSL_ALPN_HTTP_1_1
|
const unsigned char* alpn_selected; //reference to SSL_ALPN_HTTP_2/SSL_ALPN_HTTP_1_1
|
||||||
struct ssl_stream* peer;
|
struct ssl_stream* peer;
|
||||||
|
socklen_t addrlen;
|
||||||
|
struct sockaddr_storage addr;
|
||||||
struct __ssl_stream_debug _do_not_use;
|
struct __ssl_stream_debug _do_not_use;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -451,8 +453,8 @@ void ssl_stat_init(struct ssl_mgr * mgr)
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
static SSL * downstream_ssl_create(struct ssl_mgr * mgr, struct keyring * crt, int negotiated_version, const unsigned char* selected_alpn);
|
static void downstream_ossl_init(struct ssl_stream* s_stream);
|
||||||
static SSL * upstream_ssl_create(struct ssl_mgr * mgr, struct ssl_stream* s_stream, evutil_socket_t fd);
|
static void upstream_ossl_init(struct ssl_stream* s_stream);
|
||||||
|
|
||||||
static void sslctx_set_opts(SSL_CTX * sslctx, struct ssl_mgr * mgr);
|
static void sslctx_set_opts(SSL_CTX * sslctx, struct ssl_mgr * mgr);
|
||||||
|
|
||||||
@@ -474,17 +476,18 @@ struct ssl_stream * ssl_stream_new(struct ssl_mgr * mgr, evutil_socket_t fd, enu
|
|||||||
s_stream->dir = dir;
|
s_stream->dir = dir;
|
||||||
s_stream->mgr = mgr;
|
s_stream->mgr = mgr;
|
||||||
s_stream->_do_not_use.fd = fd;
|
s_stream->_do_not_use.fd = fd;
|
||||||
assert(ret == 0);
|
|
||||||
s_stream->ssl_max_version=mgr->ssl_max_version;
|
s_stream->ssl_max_version=mgr->ssl_max_version;
|
||||||
s_stream->ssl_min_version=mgr->ssl_min_version;
|
s_stream->ssl_min_version=mgr->ssl_min_version;
|
||||||
s_stream->peer=peer;
|
s_stream->peer=peer;
|
||||||
|
|
||||||
|
ret = getpeername(fd, (struct sockaddr *) (&s_stream->addr), &(s_stream->addrlen));
|
||||||
switch (dir)
|
switch (dir)
|
||||||
{
|
{
|
||||||
case CONN_DIR_DOWNSTREAM:
|
case CONN_DIR_DOWNSTREAM:
|
||||||
assert(peer!=NULL);
|
assert(peer!=NULL);
|
||||||
ATOMIC_INC(&(s_stream->mgr->stat_val[SSL_DOWN_NEW]));
|
ATOMIC_INC(&(s_stream->mgr->stat_val[SSL_DOWN_NEW]));
|
||||||
s_stream->down_parts.keyring = kyr;
|
s_stream->down_parts.keyring = kyr;
|
||||||
s_stream->ssl = downstream_ssl_create(mgr, kyr, peer->negotiated_version, peer->alpn_selected);
|
s_stream->peer=peer;
|
||||||
break;
|
break;
|
||||||
case CONN_DIR_UPSTREAM:
|
case CONN_DIR_UPSTREAM:
|
||||||
ATOMIC_INC(&(s_stream->mgr->stat_val[SSL_UP_NEW]));
|
ATOMIC_INC(&(s_stream->mgr->stat_val[SSL_UP_NEW]));
|
||||||
@@ -492,17 +495,18 @@ struct ssl_stream * ssl_stream_new(struct ssl_mgr * mgr, evutil_socket_t fd, enu
|
|||||||
s_stream->up_parts.client_hello = client_hello;
|
s_stream->up_parts.client_hello = client_hello;
|
||||||
s_stream->ssl_min_version=client_hello->min_version.ossl_format;
|
s_stream->ssl_min_version=client_hello->min_version.ossl_format;
|
||||||
s_stream->ssl_max_version=client_hello->max_version.ossl_format;
|
s_stream->ssl_max_version=client_hello->max_version.ossl_format;
|
||||||
s_stream->ssl = upstream_ssl_create(mgr, s_stream, fd);
|
|
||||||
break;
|
break;
|
||||||
default: assert(0);
|
default: assert(0);
|
||||||
}
|
}
|
||||||
return s_stream;
|
return s_stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ssl_stream_free(struct ssl_stream * s_stream)
|
static void ssl_stream_free(struct ssl_stream * s_stream)
|
||||||
{
|
{
|
||||||
SSL_free(s_stream->ssl);
|
if(s_stream->ssl)
|
||||||
s_stream->ssl = NULL;
|
{
|
||||||
|
SSL_free(s_stream->ssl);
|
||||||
|
s_stream->ssl = NULL;
|
||||||
|
}
|
||||||
switch (s_stream->dir)
|
switch (s_stream->dir)
|
||||||
{
|
{
|
||||||
case CONN_DIR_DOWNSTREAM:
|
case CONN_DIR_DOWNSTREAM:
|
||||||
@@ -836,11 +840,12 @@ int ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
|||||||
* Create new SSL context for outgoing connections to the original destination.
|
* Create new SSL context for outgoing connections to the original destination.
|
||||||
* If hostname sni is provided, use it for Server Name Indication.
|
* If hostname sni is provided, use it for Server Name Indication.
|
||||||
*/
|
*/
|
||||||
static SSL * upstream_ssl_create(struct ssl_mgr * mgr, struct ssl_stream* s_stream, evutil_socket_t fd)
|
static void upstream_ossl_init(struct ssl_stream* s_stream)
|
||||||
{
|
{
|
||||||
SSL_CTX * sslctx = NULL;
|
SSL_CTX * sslctx = NULL;
|
||||||
SSL * ssl = NULL;
|
SSL * ssl = NULL;
|
||||||
SSL_SESSION * sess = NULL;
|
SSL_SESSION * sess = NULL;
|
||||||
|
struct ssl_mgr * mgr = s_stream->mgr;
|
||||||
struct ssl_chello * chello=s_stream->up_parts.client_hello;
|
struct ssl_chello * chello=s_stream->up_parts.client_hello;
|
||||||
sslctx = SSL_CTX_new(mgr->sslmethod());
|
sslctx = SSL_CTX_new(mgr->sslmethod());
|
||||||
sslctx_set_opts(sslctx, mgr);
|
sslctx_set_opts(sslctx, mgr);
|
||||||
@@ -865,7 +870,7 @@ static SSL * upstream_ssl_create(struct ssl_mgr * mgr, struct ssl_stream* s_stre
|
|||||||
SSL_CTX_set_max_proto_version(sslctx, s_stream->ssl_max_version) == 0)
|
SSL_CTX_set_max_proto_version(sslctx, s_stream->ssl_max_version) == 0)
|
||||||
{
|
{
|
||||||
SSL_CTX_free(sslctx);
|
SSL_CTX_free(sslctx);
|
||||||
return NULL;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSL_CTX_set_verify(sslctx, SSL_VERIFY_NONE, NULL);
|
SSL_CTX_set_verify(sslctx, SSL_VERIFY_NONE, NULL);
|
||||||
@@ -874,7 +879,7 @@ static SSL * upstream_ssl_create(struct ssl_mgr * mgr, struct ssl_stream* s_stre
|
|||||||
SSL_CTX_free(sslctx); /* SSL_new() increments refcount */
|
SSL_CTX_free(sslctx); /* SSL_new() increments refcount */
|
||||||
if (!ssl)
|
if (!ssl)
|
||||||
{
|
{
|
||||||
return NULL;
|
return;
|
||||||
}
|
}
|
||||||
SSL_set_ex_data(ssl, SSL_EX_DATA_IDX_SSLSTREAM, s_stream);
|
SSL_set_ex_data(ssl, SSL_EX_DATA_IDX_SSLSTREAM, s_stream);
|
||||||
|
|
||||||
@@ -890,16 +895,13 @@ static SSL * upstream_ssl_create(struct ssl_mgr * mgr, struct ssl_stream* s_stre
|
|||||||
/* lower memory footprint for idle connections */
|
/* lower memory footprint for idle connections */
|
||||||
SSL_set_mode(ssl, SSL_get_mode(ssl) | SSL_MODE_RELEASE_BUFFERS);
|
SSL_set_mode(ssl, SSL_get_mode(ssl) | SSL_MODE_RELEASE_BUFFERS);
|
||||||
|
|
||||||
struct sockaddr_storage addr;
|
|
||||||
socklen_t addrlen = sizeof(struct sockaddr_storage);
|
|
||||||
|
|
||||||
if(!mgr->no_sesscache)
|
if(!mgr->no_sesscache)
|
||||||
{
|
{
|
||||||
ret = getpeername(fd, (struct sockaddr *) (&addr), &addrlen);
|
|
||||||
if(ret == 0)
|
if(ret == 0)
|
||||||
{
|
{
|
||||||
/* session resuming based on remote endpoint address and port */
|
/* 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 *) &(s_stream->addr), s_stream->addrlen, chello->sni,
|
||||||
s_stream->ssl_min_version, s_stream->ssl_max_version);
|
s_stream->ssl_min_version, s_stream->ssl_max_version);
|
||||||
if (sess)
|
if (sess)
|
||||||
{
|
{
|
||||||
@@ -908,9 +910,8 @@ static SSL * upstream_ssl_create(struct ssl_mgr * mgr, struct ssl_stream* s_stre
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
s_stream->ssl=ssl;
|
||||||
|
return ;
|
||||||
return ssl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ssl_connect_server_ctx_free(struct ssl_connect_server_ctx * ctx)
|
void ssl_connect_server_ctx_free(struct ssl_connect_server_ctx * ctx)
|
||||||
@@ -1260,6 +1261,7 @@ static void peek_chello_on_succ(future_result_t * result, void * user)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
upstream_ossl_init(s_stream);
|
||||||
ctx->bev = bufferevent_openssl_socket_new(evbase, ctx->fd_upstream,
|
ctx->bev = bufferevent_openssl_socket_new(evbase, ctx->fd_upstream,
|
||||||
ctx->s_stream->ssl, BUFFEREVENT_SSL_CONNECTING, BEV_OPT_DEFER_CALLBACKS | BEV_OPT_THREADSAFE );
|
ctx->s_stream->ssl, BUFFEREVENT_SSL_CONNECTING, BEV_OPT_DEFER_CALLBACKS | BEV_OPT_THREADSAFE );
|
||||||
|
|
||||||
@@ -1456,17 +1458,11 @@ static void sslctx_set_opts(SSL_CTX * sslctx, struct ssl_mgr * mgr)
|
|||||||
{
|
{
|
||||||
SSL_CTX_set_options(sslctx, SSL_OP_ALL);
|
SSL_CTX_set_options(sslctx, SSL_OP_ALL);
|
||||||
|
|
||||||
#ifdef SSL_OP_TLS_ROLLBACK_BUG
|
|
||||||
SSL_CTX_set_options(sslctx, SSL_OP_TLS_ROLLBACK_BUG);
|
SSL_CTX_set_options(sslctx, SSL_OP_TLS_ROLLBACK_BUG);
|
||||||
#endif /* SSL_OP_TLS_ROLLBACK_BUG */
|
|
||||||
|
|
||||||
#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
|
|
||||||
SSL_CTX_set_options(sslctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
|
SSL_CTX_set_options(sslctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
|
||||||
#endif /* SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION */
|
|
||||||
|
|
||||||
#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
|
|
||||||
SSL_CTX_set_options(sslctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
|
SSL_CTX_set_options(sslctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
|
||||||
#endif /* SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS */
|
|
||||||
|
|
||||||
if (mgr->no_ssl2)
|
if (mgr->no_ssl2)
|
||||||
{
|
{
|
||||||
@@ -1526,10 +1522,14 @@ static int alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
|
|||||||
* Create and set up a new SSL_CTX instance for terminating SSL.
|
* Create and set up a new SSL_CTX instance for terminating SSL.
|
||||||
* Set up all the necessary callbacks, the keyring, the keyring chain and key.
|
* Set up all the necessary callbacks, the keyring, the keyring chain and key.
|
||||||
*/
|
*/
|
||||||
static SSL * downstream_ssl_create(struct ssl_mgr * mgr, struct keyring * crt, int negotiated_version, const unsigned char* selected_alpn)
|
void downstream_ossl_init(struct ssl_stream *s_stream)
|
||||||
{
|
{
|
||||||
|
struct ssl_mgr * mgr=s_stream->mgr;
|
||||||
SSL_CTX * sslctx = SSL_CTX_new(mgr->sslmethod());
|
SSL_CTX * sslctx = SSL_CTX_new(mgr->sslmethod());
|
||||||
if (!sslctx) return NULL;
|
if (!sslctx) return;
|
||||||
|
struct keyring * crt=s_stream->down_parts.keyring;
|
||||||
|
int negotiated_version=s_stream->peer->negotiated_version;
|
||||||
|
const unsigned char* selected_alpn=s_stream->peer->alpn_selected;
|
||||||
|
|
||||||
SSL * ssl = NULL;
|
SSL * ssl = NULL;
|
||||||
UNUSED int ret = 0;
|
UNUSED int ret = 0;
|
||||||
@@ -1543,7 +1543,7 @@ static SSL * downstream_ssl_create(struct ssl_mgr * mgr, struct keyring * crt, i
|
|||||||
SSL_CTX_set_max_proto_version(sslctx, negotiated_version) == 0)
|
SSL_CTX_set_max_proto_version(sslctx, negotiated_version) == 0)
|
||||||
{
|
{
|
||||||
SSL_CTX_free(sslctx);
|
SSL_CTX_free(sslctx);
|
||||||
return NULL;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(mgr->ssl_min_version)
|
else if(mgr->ssl_min_version)
|
||||||
@@ -1552,7 +1552,7 @@ static SSL * downstream_ssl_create(struct ssl_mgr * mgr, struct keyring * crt, i
|
|||||||
SSL_CTX_set_max_proto_version(sslctx, mgr->ssl_max_version) == 0)
|
SSL_CTX_set_max_proto_version(sslctx, mgr->ssl_max_version) == 0)
|
||||||
{
|
{
|
||||||
SSL_CTX_free(sslctx);
|
SSL_CTX_free(sslctx);
|
||||||
return NULL;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1615,7 +1615,8 @@ static SSL * downstream_ssl_create(struct ssl_mgr * mgr, struct keyring * crt, i
|
|||||||
/* lower memory footprint for idle connections */
|
/* lower memory footprint for idle connections */
|
||||||
SSL_set_mode(ssl, SSL_get_mode(ssl) | SSL_MODE_RELEASE_BUFFERS);
|
SSL_set_mode(ssl, SSL_get_mode(ssl) | SSL_MODE_RELEASE_BUFFERS);
|
||||||
}
|
}
|
||||||
return ssl;
|
s_stream->ssl=ssl;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ssl_connect_client_ctx_free(struct ssl_connect_client_ctx * ctx)
|
void ssl_connect_client_ctx_free(struct ssl_connect_client_ctx * ctx)
|
||||||
@@ -1751,6 +1752,7 @@ void ask_keyring_on_succ(void * result, void * user)
|
|||||||
clock_gettime(CLOCK_MONOTONIC, &(ctx->start));
|
clock_gettime(CLOCK_MONOTONIC, &(ctx->start));
|
||||||
ctx->downstream = ssl_stream_new(mgr, ctx->fd_downstream, CONN_DIR_DOWNSTREAM, NULL,
|
ctx->downstream = ssl_stream_new(mgr, ctx->fd_downstream, CONN_DIR_DOWNSTREAM, NULL,
|
||||||
kyr, ctx->origin_ssl);
|
kyr, ctx->origin_ssl);
|
||||||
|
downstream_ossl_init(ctx->downstream);
|
||||||
ctx->bev_down = bufferevent_openssl_socket_new(evbase, ctx->fd_downstream, ctx->downstream->ssl,
|
ctx->bev_down = bufferevent_openssl_socket_new(evbase, ctx->fd_downstream, ctx->downstream->ssl,
|
||||||
BUFFEREVENT_SSL_ACCEPTING, BEV_OPT_DEFER_CALLBACKS | BEV_OPT_THREADSAFE);
|
BUFFEREVENT_SSL_ACCEPTING, BEV_OPT_DEFER_CALLBACKS | BEV_OPT_THREADSAFE);
|
||||||
bufferevent_openssl_set_allow_dirty_shutdown(ctx->bev_down, 1);
|
bufferevent_openssl_set_allow_dirty_shutdown(ctx->bev_down, 1);
|
||||||
|
|||||||
@@ -185,8 +185,8 @@ enum ssl_stream_action ssl_policy_enforce(struct ssl_stream *upstream, void* u_p
|
|||||||
int pinning_staus=0, is_ev=0, is_ct=0, is_mauth=0, has_error=0;
|
int pinning_staus=0, is_ev=0, is_ct=0, is_mauth=0, has_error=0;
|
||||||
if(!param->mirror_client_version)
|
if(!param->mirror_client_version)
|
||||||
{
|
{
|
||||||
ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_PROTOCOL_MIN_VERSION, SSL3_VERSION);
|
ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_PROTOCOL_MIN_VERSION, param->ssl_min_version);
|
||||||
ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_PROTOCOL_MIN_VERSION, TLS1_3_VERSION);
|
ret=ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_PROTOCOL_MAX_VERSION, param->ssl_max_version);
|
||||||
}
|
}
|
||||||
ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_COMMON_NAME, param->no_verify_cn);
|
ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_COMMON_NAME, param->no_verify_cn);
|
||||||
ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_ISSUER, param->no_verify_issuer);
|
ssl_stream_set_integer_opt(upstream, SSL_STREAM_OPT_NO_VERIFY_ISSUER, param->no_verify_issuer);
|
||||||
|
|||||||
Reference in New Issue
Block a user