From 99d7bb690924e60e9e03096ac5e507111f7c182d Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Sun, 3 Mar 2019 16:48:06 +0300 Subject: [PATCH] SSL: server name callback changed to return fatal errors. Notably this affects various allocation errors, and should generally improve things if an allocation error actually happens during a callback. Depending on the OpenSSL version, returning an error can result in either SSL_R_CALLBACK_FAILED or SSL_R_CLIENTHELLO_TLSEXT error from SSL_do_handshake(), so both errors were switched to the "info" level. --- src/event/ngx_event_openssl.c | 6 ++++++ src/http/ngx_http_request.c | 29 ++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c index e18778e2a..e18480c0d 100644 --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -2855,8 +2855,14 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err, || n == SSL_R_NO_COMPRESSION_SPECIFIED /* 187 */ || n == SSL_R_NO_SHARED_CIPHER /* 193 */ || n == SSL_R_RECORD_LENGTH_MISMATCH /* 213 */ +#ifdef SSL_R_CLIENTHELLO_TLSEXT + || n == SSL_R_CLIENTHELLO_TLSEXT /* 226 */ +#endif #ifdef SSL_R_PARSE_TLSEXT || n == SSL_R_PARSE_TLSEXT /* 227 */ +#endif +#ifdef SSL_R_CALLBACK_FAILED + || n == SSL_R_CALLBACK_FAILED /* 234 */ #endif || n == SSL_R_UNEXPECTED_MESSAGE /* 244 */ || n == SSL_R_UNEXPECTED_RECORD /* 245 */ diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index 9cdc4a543..d87e872bf 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -855,6 +855,7 @@ ngx_http_ssl_handshake_handler(ngx_connection_t *c) int ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg) { + ngx_int_t rc; ngx_str_t host; const char *servername; ngx_connection_t *c; @@ -872,7 +873,8 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg) c = ngx_ssl_get_connection(ssl_conn); if (c->ssl->handshaked) { - return SSL_TLSEXT_ERR_OK; + *ad = SSL_AD_NO_RENEGOTIATION; + return SSL_TLSEXT_ERR_ALERT_FATAL; } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, @@ -886,22 +888,35 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg) host.data = (u_char *) servername; - if (ngx_http_validate_host(&host, c->pool, 1) != NGX_OK) { + rc = ngx_http_validate_host(&host, c->pool, 1); + + if (rc == NGX_ERROR) { + *ad = SSL_AD_INTERNAL_ERROR; + return SSL_TLSEXT_ERR_ALERT_FATAL; + } + + if (rc == NGX_DECLINED) { return SSL_TLSEXT_ERR_OK; } hc = c->data; - if (ngx_http_find_virtual_server(c, hc->addr_conf->virtual_names, &host, - NULL, &cscf) - != NGX_OK) - { + rc = ngx_http_find_virtual_server(c, hc->addr_conf->virtual_names, &host, + NULL, &cscf); + + if (rc == NGX_ERROR) { + *ad = SSL_AD_INTERNAL_ERROR; + return SSL_TLSEXT_ERR_ALERT_FATAL; + } + + if (rc == NGX_DECLINED) { return SSL_TLSEXT_ERR_OK; } hc->ssl_servername = ngx_palloc(c->pool, sizeof(ngx_str_t)); if (hc->ssl_servername == NULL) { - return SSL_TLSEXT_ERR_OK; + *ad = SSL_AD_INTERNAL_ERROR; + return SSL_TLSEXT_ERR_ALERT_FATAL; } *hc->ssl_servername = host;