未完成:在ssl_stream_free中检测pinning。

This commit is contained in:
zhengchao
2019-06-10 21:27:27 +08:00
parent f18c5efdb1
commit a396bec434
4 changed files with 85 additions and 41 deletions

View File

@@ -290,23 +290,24 @@ int sslver_str2num(const char * version_str)
* SSLv2_server_method() and SSLv2_client_method() functions were
* removed in OpenSSL 1.1.0.
*/
if (!strcmp(version_str, "ssl3"))
if (!strcasecmp(version_str, "ssl3")||!strcasecmp(version_str, "SSLv3"))
{
sslversion = SSL3_VERSION;
}
else if (!strcmp(version_str, "tls10") || !strcmp(version_str, "tls1"))
else if (!strcasecmp(version_str, "tls10") || !strcasecmp(version_str, "tls1") ||
!strcasecmp(version_str, "TLSv1.0") || !strcasecmp(version_str, "TLSv1"))
{
sslversion = TLS1_VERSION;
}
else if (!strcmp(version_str, "tls11"))
else if (!strcasecmp(version_str, "tls11")||!strcasecmp(version_str, "TLSv1.1"))
{
sslversion = TLS1_1_VERSION;
}
else if (!strcmp(version_str, "tls12"))
else if (!strcasecmp(version_str, "tls12")||!strcasecmp(version_str, "TLSv1.2"))
{
sslversion = TLS1_2_VERSION;
}
else if (!strcmp(version_str, "tls13"))
else if (!strcasecmp(version_str, "tls13")||!strcasecmp(version_str, "TLSv1.3"))
{
sslversion = TLS1_3_VERSION;
}
@@ -1021,6 +1022,21 @@ const char* ssl_stream_dump_info(struct ssl_stream *stream, char* buffer, size_t
stream->dir==CONN_DIR_UPSTREAM ? stream->up_parts.client_hello->sni:NULL);
return buffer;
}
static void ssl_stream_set_cmsg_string(struct ssl_stream* stream, enum tfe_cmsg_tlv_type type, const char* value_str)
{
struct tfe_cmsg* cmsg=tfe_stream_get0_cmsg(stream->tcp_stream);
int ret=tfe_cmsg_set(cmsg, type, (const unsigned char*)value_str, (uint16_t)strlen(value_str));
assert(ret==0);
return;
}
static void ssl_stream_set_cmsg_integer(struct ssl_stream* stream, enum tfe_cmsg_tlv_type type, uint64_t value_int)
{
struct tfe_cmsg* cmsg=tfe_stream_get0_cmsg(stream->tcp_stream);
int ret=tfe_cmsg_set(cmsg, type, (const unsigned char*)&value_int, (uint16_t)sizeof(value_int));
assert(ret==0);
return;
}
unsigned long ssl_stream_log_error(struct bufferevent * bev, enum tfe_conn_dir dir, struct ssl_mgr* mgr)
{
unsigned long sslerr=0, ret_sslerr=0;
@@ -1133,21 +1149,40 @@ unsigned long ssl_stream_log_error(struct bufferevent * bev, enum tfe_conn_dir d
free(addr_string);
return ret_sslerr;
}
void ssl_stream_process_error(struct ssl_stream * s_stream, unsigned long sslerr, struct ssl_mgr* mgr)
{
struct ssl_upstream_parts* s_upstream=NULL;
assert(sslerr);
switch(s_stream->dir)
{
case CONN_DIR_DOWNSTREAM:
s_upstream= &(s_stream->peer->up_parts);
if(sslerr==SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN &&
s_upstream->is_server_cert_verify_passed &&
s_upstream->verify_result.is_hostmatched)
{
s_upstream->svc_status.pinning_status=PINNING_ST_PINNING;
ssl_stream_set_cmsg_integer(s_stream, TFE_CMSG_SSL_PINNING_STATE, PINNING_ST_PINNING);
ssl_service_cache_write(mgr->svc_cache, s_upstream->client_hello, s_stream->tcp_stream->addr, &s_upstream->svc_status);
}
else if(sslerr>0 && sslerr!=SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN)
{
s_upstream->svc_status.has_protocol_errors=1;
ssl_service_cache_write(mgr->svc_cache, s_upstream->client_hello, s_stream->tcp_stream->addr, &s_upstream->svc_status);
}
break;
case CONN_DIR_UPSTREAM:
s_upstream=&(s_stream->up_parts);
s_upstream->svc_status.has_protocol_errors=1;
ssl_service_cache_write(mgr->svc_cache, s_stream->up_parts.client_hello, s_stream->tcp_stream->addr, &(s_stream->up_parts.svc_status));
break;
default:
assert(0);
}
return;
}
static void ssl_stream_set_cmsg_string(struct ssl_stream* stream, enum tfe_cmsg_tlv_type type, const char* value_str)
{
struct tfe_cmsg* cmsg=tfe_stream_get0_cmsg(stream->tcp_stream);
int ret=tfe_cmsg_set(cmsg, type, (const unsigned char*)value_str, (uint16_t)strlen(value_str));
assert(ret==0);
return;
}
static void ssl_stream_set_cmsg_integer(struct ssl_stream* stream, enum tfe_cmsg_tlv_type type, uint64_t value_int)
{
struct tfe_cmsg* cmsg=tfe_stream_get0_cmsg(stream->tcp_stream);
int ret=tfe_cmsg_set(cmsg, type, (const unsigned char*)&value_int, (uint16_t)sizeof(value_int));
assert(ret==0);
return;
}
/*
* Callback for meta events on the up- and downstream connection bufferevents.
@@ -1173,8 +1208,7 @@ static void ssl_server_connected_eventcb(struct bufferevent * bev, short events,
sslerr=ssl_stream_log_error(bev, CONN_DIR_UPSTREAM, ctx->mgr);
if(sslerr)
{
s_upstream->svc_status.has_protocol_errors=1;
ssl_service_cache_write(mgr->svc_cache, s_stream->up_parts.client_hello, s_stream->tcp_stream->addr, &(s_stream->up_parts.svc_status));
ssl_stream_process_error(s_stream, sslerr, mgr);
}
s_stream->error=SSL_STREAM_R_SERVER_PROTOCOL_ERROR;
}
@@ -1294,6 +1328,7 @@ static void peek_chello_on_succ(future_result_t * result, void * user)
struct event_base* evbase=tfe_proxy_get_work_thread_evbase(ctx->tcp_stream->thread_id);
struct ssl_stream* s_stream=NULL;
struct ssl_chello* chello = ssl_peek_result_release_chello(result);//chello has been saved in ssl_stream.
char* addr_string=NULL;
if(chello->sni==NULL)
{
ATOMIC_INC(&(ctx->mgr->stat_val[SSL_NO_SNI]));
@@ -1306,13 +1341,17 @@ static void peek_chello_on_succ(future_result_t * result, void * user)
ret=ssl_service_cache_read(ctx->mgr->svc_cache, chello, s_stream->tcp_stream->addr, svc_status);
if(ret==1)
{
TFE_LOG_DEBUG(ctx->mgr->logger, "SNI: %s service status pinning:%d, mauth:%d, err:%d, ct:%d, ev:%d",
addr_string=tfe_stream_addr_to_str(s_stream->tcp_stream->addr);
TFE_LOG_DEBUG(ctx->mgr->logger, "%s %s service status pinning:%d, mauth:%d, err:%d, ct:%d, ev:%d",
addr_string,
chello->sni,
svc_status->pinning_status,
svc_status->is_mutual_auth,
svc_status->has_protocol_errors,
svc_status->is_ct,
svc_status->is_ev);
free(addr_string);
addr_string=NULL;
}
ssl_stream_set_cmsg_integer(s_stream, TFE_CMSG_SSL_PINNING_STATE, svc_status->pinning_status);
if(ctx->mgr->on_new_upstream_cb)
@@ -1740,6 +1779,7 @@ struct bufferevent * ssl_downstream_create_result_release_bev(future_result_t *
ctx->bev_down = NULL;
return ret;
}
static void ssl_client_connected_eventcb(struct bufferevent * bev, short events, void * arg)
{
struct promise * p = (struct promise *) arg;
@@ -1756,18 +1796,9 @@ static void ssl_client_connected_eventcb(struct bufferevent * bev, short events,
{
ATOMIC_INC(&(mgr->stat_val[SSL_DOWN_ERR]));
sslerr=ssl_stream_log_error(bev, CONN_DIR_DOWNSTREAM, mgr);
if(sslerr==SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN &&
s_upstream->is_server_cert_verify_passed &&
s_upstream->verify_result.is_hostmatched)
if(sslerr)
{
s_upstream->svc_status.pinning_status=PINNING_ST_PINNING;
ssl_stream_set_cmsg_integer(s_stream, TFE_CMSG_SSL_PINNING_STATE, PINNING_ST_PINNING);
ssl_service_cache_write(mgr->svc_cache, s_upstream->client_hello, s_stream->tcp_stream->addr, &s_upstream->svc_status);
}
else if(sslerr>0 && sslerr!=SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN)
{
s_upstream->svc_status.has_protocol_errors=1;
ssl_service_cache_write(mgr->svc_cache, s_upstream->client_hello, s_stream->tcp_stream->addr, &s_upstream->svc_status);
ssl_stream_process_error(s_stream, sslerr, mgr);
}
s_stream->error=SSL_STREAM_R_CLIENT_PROTOCOL_ERROR;
}
@@ -2028,10 +2059,21 @@ complete:
* Guarantees that SSL and the corresponding SSL_CTX are freed and the
* socket is closed, eventually, or in the case of fatal errors, immediately.
*/
void ssl_stream_free_and_close_fd(struct ssl_stream * s_stream, struct event_base * evbase, evutil_socket_t fd)
void ssl_stream_free_and_close_fd(struct ssl_stream * s_stream, struct event_base * evbase, struct bufferevent * bev)
{
struct ssl_shutdown_ctx * sslshutctx = NULL;
evutil_socket_t fd=-1;
fd=bufferevent_getfd(bev);
assert(fd==s_stream->_do_not_use.fd);
unsigned long sslerr=0;
if(errno)
{
sslerr=ssl_stream_log_error(bev, s_stream->dir, s_stream->mgr);
if(sslerr)
{
ssl_stream_process_error(s_stream, sslerr, s_stream->mgr);
}
}
sslshutctx = ssl_shutdown_ctx_new(s_stream, evbase);
pxy_ssl_shutdown_cb(fd, 0, sslshutctx);
}