summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/event/ngx_event_openssl.c12
-rw-r--r--src/event/ngx_event_openssl.h1
-rw-r--r--src/http/modules/ngx_http_ssl_module.c91
-rw-r--r--src/http/modules/ngx_http_ssl_module.h1
-rw-r--r--src/http/ngx_http_request.c41
5 files changed, 104 insertions, 42 deletions
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index dfb816055..2eef87e5e 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -1793,6 +1793,13 @@ ngx_ssl_handshake(ngx_connection_t *c)
return NGX_ERROR;
}
+ if (c->ssl->handshake_rejected) {
+ ngx_connection_error(c, err, "handshake rejected");
+ ERR_clear_error();
+
+ return NGX_ERROR;
+ }
+
c->read->error = 1;
ngx_ssl_connection_error(c, sslerr, err, "SSL_do_handshake() failed");
@@ -3354,8 +3361,9 @@ ngx_ssl_session_id_context(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
}
}
- if (SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index) == NULL) {
-
+ if (SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index) == NULL
+ && certificates != NULL)
+ {
/*
* If certificates are loaded dynamically, we use certificate
* names as specified in the configuration (with variables).
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
index 821bb13d1..329760d09 100644
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -95,6 +95,7 @@ struct ngx_ssl_connection_s {
u_char early_buf;
unsigned handshaked:1;
+ unsigned handshake_rejected:1;
unsigned renegotiation:1;
unsigned buffer:1;
unsigned no_wait_shutdown:1;
diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
index 2702f1e20..e062b03a1 100644
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -294,6 +294,13 @@ static ngx_command_t ngx_http_ssl_commands[] = {
offsetof(ngx_http_ssl_srv_conf_t, conf_commands),
&ngx_http_ssl_conf_command_post },
+ { ngx_string("ssl_reject_handshake"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
+ ngx_conf_set_flag_slot,
+ NGX_HTTP_SRV_CONF_OFFSET,
+ offsetof(ngx_http_ssl_srv_conf_t, reject_handshake),
+ NULL },
+
ngx_null_command
};
@@ -614,6 +621,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
sscf->enable = NGX_CONF_UNSET;
sscf->prefer_server_ciphers = NGX_CONF_UNSET;
sscf->early_data = NGX_CONF_UNSET;
+ sscf->reject_handshake = NGX_CONF_UNSET;
sscf->buffer_size = NGX_CONF_UNSET_SIZE;
sscf->verify = NGX_CONF_UNSET_UINT;
sscf->verify_depth = NGX_CONF_UNSET_UINT;
@@ -660,6 +668,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
prev->prefer_server_ciphers, 0);
ngx_conf_merge_value(conf->early_data, prev->early_data, 0);
+ ngx_conf_merge_value(conf->reject_handshake, prev->reject_handshake, 0);
ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
(NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1
@@ -707,38 +716,35 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
if (conf->enable) {
- if (conf->certificates == NULL) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "no \"ssl_certificate\" is defined for "
- "the \"ssl\" directive in %s:%ui",
- conf->file, conf->line);
- return NGX_CONF_ERROR;
- }
+ if (conf->certificates) {
+ if (conf->certificate_keys == NULL) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "no \"ssl_certificate_key\" is defined for "
+ "the \"ssl\" directive in %s:%ui",
+ conf->file, conf->line);
+ return NGX_CONF_ERROR;
+ }
- if (conf->certificate_keys == NULL) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "no \"ssl_certificate_key\" is defined for "
- "the \"ssl\" directive in %s:%ui",
- conf->file, conf->line);
- return NGX_CONF_ERROR;
- }
+ if (conf->certificate_keys->nelts < conf->certificates->nelts) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "no \"ssl_certificate_key\" is defined "
+ "for certificate \"%V\" and "
+ "the \"ssl\" directive in %s:%ui",
+ ((ngx_str_t *) conf->certificates->elts)
+ + conf->certificates->nelts - 1,
+ conf->file, conf->line);
+ return NGX_CONF_ERROR;
+ }
- if (conf->certificate_keys->nelts < conf->certificates->nelts) {
+ } else if (!conf->reject_handshake) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "no \"ssl_certificate_key\" is defined "
- "for certificate \"%V\" and "
+ "no \"ssl_certificate\" is defined for "
"the \"ssl\" directive in %s:%ui",
- ((ngx_str_t *) conf->certificates->elts)
- + conf->certificates->nelts - 1,
conf->file, conf->line);
return NGX_CONF_ERROR;
}
- } else {
-
- if (conf->certificates == NULL) {
- return NGX_CONF_OK;
- }
+ } else if (conf->certificates) {
if (conf->certificate_keys == NULL
|| conf->certificate_keys->nelts < conf->certificates->nelts)
@@ -750,6 +756,9 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
+ conf->certificates->nelts - 1);
return NGX_CONF_ERROR;
}
+
+ } else if (!conf->reject_handshake) {
+ return NGX_CONF_OK;
}
if (ngx_ssl_create(&conf->ssl, conf->protocols, conf) != NGX_OK) {
@@ -808,7 +817,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
return NGX_CONF_ERROR;
#endif
- } else {
+ } else if (conf->certificates) {
/* configure certificates */
@@ -947,6 +956,10 @@ ngx_http_ssl_compile_certificates(ngx_conf_t *cf,
ngx_http_complex_value_t *cv;
ngx_http_compile_complex_value_t ccv;
+ if (conf->certificates == NULL) {
+ return NGX_OK;
+ }
+
cert = conf->certificates->elts;
key = conf->certificate_keys->elts;
nelts = conf->certificates->nelts;
@@ -1327,7 +1340,33 @@ ngx_http_ssl_init(ngx_conf_t *cf)
cscf = addr[a].default_server;
sscf = cscf->ctx->srv_conf[ngx_http_ssl_module.ctx_index];
- if (sscf->certificates == NULL) {
+ if (sscf->certificates) {
+ continue;
+ }
+
+ if (!sscf->reject_handshake) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "no \"ssl_certificate\" is defined for "
+ "the \"listen ... ssl\" directive in %s:%ui",
+ cscf->file_name, cscf->line);
+ return NGX_ERROR;
+ }
+
+ /*
+ * if no certificates are defined in the default server,
+ * check all non-default server blocks
+ */
+
+ cscfp = addr[a].servers.elts;
+ for (s = 0; s < addr[a].servers.nelts; s++) {
+
+ cscf = cscfp[s];
+ sscf = cscf->ctx->srv_conf[ngx_http_ssl_module.ctx_index];
+
+ if (sscf->certificates || sscf->reject_handshake) {
+ continue;
+ }
+
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"no \"ssl_certificate\" is defined for "
"the \"listen ... ssl\" directive in %s:%ui",
diff --git a/src/http/modules/ngx_http_ssl_module.h b/src/http/modules/ngx_http_ssl_module.h
index 127570332..7ab0f7eae 100644
--- a/src/http/modules/ngx_http_ssl_module.h
+++ b/src/http/modules/ngx_http_ssl_module.h
@@ -21,6 +21,7 @@ typedef struct {
ngx_flag_t prefer_server_ciphers;
ngx_flag_t early_data;
+ ngx_flag_t reject_handshake;
ngx_uint_t protocols;
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 2a0528c68..204a9399d 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -871,10 +871,14 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
return SSL_TLSEXT_ERR_ALERT_FATAL;
}
+ hc = c->data;
+
servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);
if (servername == NULL) {
- return SSL_TLSEXT_ERR_OK;
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
+ "SSL server name: null");
+ goto done;
}
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
@@ -883,7 +887,7 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
host.len = ngx_strlen(servername);
if (host.len == 0) {
- return SSL_TLSEXT_ERR_OK;
+ goto done;
}
host.data = (u_char *) servername;
@@ -891,32 +895,27 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
rc = ngx_http_validate_host(&host, c->pool, 1);
if (rc == NGX_ERROR) {
- *ad = SSL_AD_INTERNAL_ERROR;
- return SSL_TLSEXT_ERR_ALERT_FATAL;
+ goto error;
}
if (rc == NGX_DECLINED) {
- return SSL_TLSEXT_ERR_OK;
+ goto done;
}
- hc = c->data;
-
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;
+ goto error;
}
if (rc == NGX_DECLINED) {
- return SSL_TLSEXT_ERR_OK;
+ goto done;
}
hc->ssl_servername = ngx_palloc(c->pool, sizeof(ngx_str_t));
if (hc->ssl_servername == NULL) {
- *ad = SSL_AD_INTERNAL_ERROR;
- return SSL_TLSEXT_ERR_ALERT_FATAL;
+ goto error;
}
*hc->ssl_servername = host;
@@ -933,8 +932,7 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
if (sscf->ssl.ctx) {
if (SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx) == NULL) {
- *ad = SSL_AD_INTERNAL_ERROR;
- return SSL_TLSEXT_ERR_ALERT_FATAL;
+ goto error;
}
/*
@@ -960,7 +958,22 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
#endif
}
+done:
+
+ sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module);
+
+ if (sscf->reject_handshake) {
+ c->ssl->handshake_rejected = 1;
+ *ad = SSL_AD_UNRECOGNIZED_NAME;
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
+ }
+
return SSL_TLSEXT_ERR_OK;
+
+error:
+
+ *ad = SSL_AD_INTERNAL_ERROR;
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
}
#endif