Skip to content

Commit

Permalink
SSL: detect "listen ... ssl" without certificates (ticket nginx#178).
Browse files Browse the repository at this point in the history
In mail and stream modules, no certificate provided is a fatal condition,
much like with the "ssl" and "starttls" directives.

In http, "listen ... ssl" can be used in a non-default server without
certificates as long as there is a certificate in the default one, so
missing certificate is only fatal for default servers.
  • Loading branch information
mdounin committed Apr 24, 2018
1 parent 5d3a854 commit 76be1ea
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 93 deletions.
33 changes: 31 additions & 2 deletions src/http/modules/ngx_http_ssl_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -966,10 +966,12 @@ ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static ngx_int_t
ngx_http_ssl_init(ngx_conf_t *cf)
{
ngx_uint_t s;
ngx_uint_t a, p, s;
ngx_http_conf_addr_t *addr;
ngx_http_conf_port_t *port;
ngx_http_ssl_srv_conf_t *sscf;
ngx_http_core_loc_conf_t *clcf;
ngx_http_core_srv_conf_t **cscfp;
ngx_http_core_srv_conf_t **cscfp, *cscf;
ngx_http_core_main_conf_t *cmcf;

cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
Expand All @@ -993,5 +995,32 @@ ngx_http_ssl_init(ngx_conf_t *cf)
}
}

if (cmcf->ports == NULL) {
return NGX_OK;
}

port = cmcf->ports->elts;
for (p = 0; p < cmcf->ports->nelts; p++) {

addr = port[p].addrs.elts;
for (a = 0; a < port[p].addrs.nelts; a++) {

if (!addr[a].opt.ssl) {
continue;
}

cscf = addr[a].default_server;
sscf = cscf->ctx->srv_conf[ngx_http_ssl_module.ctx_index];

if (sscf->certificates == NULL) {
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;
}
}
}

return NGX_OK;
}
3 changes: 3 additions & 0 deletions src/http/ngx_http_core_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -3256,6 +3256,9 @@ ngx_http_core_create_srv_conf(ngx_conf_t *cf)
cscf->merge_slashes = NGX_CONF_UNSET;
cscf->underscores_in_headers = NGX_CONF_UNSET;

cscf->file_name = cf->conf_file->file.name.data;
cscf->line = cf->conf_file->line;

return cscf;
}

Expand Down
3 changes: 3 additions & 0 deletions src/http/ngx_http_core_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ typedef struct {
/* server ctx */
ngx_http_conf_ctx_t *ctx;

u_char *file_name;
ngx_uint_t line;

ngx_str_t server_name;

size_t connection_pool_size;
Expand Down
13 changes: 1 addition & 12 deletions src/http/ngx_http_request.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,19 +336,8 @@ ngx_http_init_connection(ngx_connection_t *c)
sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module);

if (sscf->enable || hc->addr_conf->ssl) {

c->log->action = "SSL handshaking";

if (hc->addr_conf->ssl && sscf->ssl.ctx == NULL) {
ngx_log_error(NGX_LOG_ERR, c->log, 0,
"no \"ssl_certificate\" is defined "
"in server listening on SSL port");
ngx_http_close_connection(c);
return;
}

hc->ssl = 1;

c->log->action = "SSL handshaking";
rev->handler = ngx_http_ssl_handshake;
}
}
Expand Down
9 changes: 9 additions & 0 deletions src/mail/ngx_mail_core_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,16 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

if (ngx_strcmp(value[i].data, "ssl") == 0) {
#if (NGX_MAIL_SSL)
ngx_mail_ssl_conf_t *sslcf;

sslcf = ngx_mail_conf_get_module_srv_conf(cf, ngx_mail_ssl_module);

sslcf->listen = 1;
sslcf->file = cf->conf_file->file.name.data;
sslcf->line = cf->conf_file->line;

ls->ssl = 1;

continue;
#else
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Expand Down
18 changes: 1 addition & 17 deletions src/mail/ngx_mail_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,29 +165,13 @@ ngx_mail_init_connection(ngx_connection_t *c)

sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);

if (sslcf->enable) {
if (sslcf->enable || addr_conf->ssl) {
c->log->action = "SSL handshaking";

ngx_mail_ssl_init_connection(&sslcf->ssl, c);
return;
}

if (addr_conf->ssl) {

c->log->action = "SSL handshaking";

if (sslcf->ssl.ctx == NULL) {
ngx_log_error(NGX_LOG_ERR, c->log, 0,
"no \"ssl_certificate\" is defined "
"in server listening on SSL port");
ngx_mail_close_connection(c);
return;
}

ngx_mail_ssl_init_connection(&sslcf->ssl, c);
return;
}

}
#endif

Expand Down
86 changes: 37 additions & 49 deletions src/mail/ngx_mail_ssl_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf)
/*
* set by ngx_pcalloc():
*
* scf->listen = 0;
* scf->protocols = 0;
* scf->dhparam = { 0, NULL };
* scf->ecdh_curve = { 0, NULL };
Expand Down Expand Up @@ -313,66 +314,49 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)

conf->ssl.log = cf->log;

if (conf->enable) {
if (conf->listen) {
mode = "listen ... ssl";

} else if (conf->enable) {
mode = "ssl";

} else if (conf->starttls != NGX_MAIL_STARTTLS_OFF) {
mode = "starttls";

} else {
mode = "";
return NGX_CONF_OK;
}

if (conf->file == NULL) {
conf->file = prev->file;
conf->line = prev->line;
}

if (*mode) {

if (conf->certificates == NULL) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"no \"ssl_certificate\" is defined for "
"the \"%s\" directive in %s:%ui",
mode, 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 \"%s\" directive in %s:%ui",
mode, 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 \"%s\" directive in %s:%ui",
((ngx_str_t *) conf->certificates->elts)
+ conf->certificates->nelts - 1,
mode, conf->file, conf->line);
return NGX_CONF_ERROR;
}

} else {
if (conf->certificates == NULL) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"no \"ssl_certificate\" is defined for "
"the \"%s\" directive in %s:%ui",
mode, conf->file, conf->line);
return NGX_CONF_ERROR;
}

if (conf->certificates == NULL) {
return NGX_CONF_OK;
}
if (conf->certificate_keys == NULL) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"no \"ssl_certificate_key\" is defined for "
"the \"%s\" directive in %s:%ui",
mode, conf->file, conf->line);
return NGX_CONF_ERROR;
}

if (conf->certificate_keys == NULL
|| 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\"",
((ngx_str_t *) conf->certificates->elts)
+ conf->certificates->nelts - 1);
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 \"%s\" directive in %s:%ui",
((ngx_str_t *) conf->certificates->elts)
+ conf->certificates->nelts - 1,
mode, conf->file, conf->line);
return NGX_CONF_ERROR;
}

if (ngx_ssl_create(&conf->ssl, conf->protocols, NULL) != NGX_OK) {
Expand Down Expand Up @@ -494,8 +478,10 @@ ngx_mail_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}

scf->file = cf->conf_file->file.name.data;
scf->line = cf->conf_file->line;
if (!scf->listen) {
scf->file = cf->conf_file->file.name.data;
scf->line = cf->conf_file->line;
}

return NGX_CONF_OK;
}
Expand All @@ -520,8 +506,10 @@ ngx_mail_ssl_starttls(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}

scf->file = cf->conf_file->file.name.data;
scf->line = cf->conf_file->line;
if (!scf->listen) {
scf->file = cf->conf_file->file.name.data;
scf->line = cf->conf_file->line;
}

return NGX_CONF_OK;
}
Expand Down
1 change: 1 addition & 0 deletions src/mail/ngx_mail_ssl_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ typedef struct {
ngx_ssl_t ssl;

ngx_uint_t starttls;
ngx_uint_t listen;
ngx_uint_t protocols;

ngx_uint_t verify;
Expand Down
10 changes: 10 additions & 0 deletions src/stream/ngx_stream_core_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,17 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

if (ngx_strcmp(value[i].data, "ssl") == 0) {
#if (NGX_STREAM_SSL)
ngx_stream_ssl_conf_t *sslcf;

sslcf = ngx_stream_conf_get_module_srv_conf(cf,
ngx_stream_ssl_module);

sslcf->listen = 1;
sslcf->file = cf->conf_file->file.name.data;
sslcf->line = cf->conf_file->line;

ls->ssl = 1;

continue;
#else
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Expand Down
36 changes: 23 additions & 13 deletions src/stream/ngx_stream_ssl_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,13 +304,6 @@ ngx_stream_ssl_handler(ngx_stream_session_t *s)
if (c->ssl == NULL) {
c->log->action = "SSL handshaking";

if (sslcf->ssl.ctx == NULL) {
ngx_log_error(NGX_LOG_ERR, c->log, 0,
"no \"ssl_certificate\" is defined "
"in server listening on SSL port");
return NGX_ERROR;
}

rv = ngx_stream_ssl_init_connection(&sslcf->ssl, c);

if (rv != NGX_OK) {
Expand Down Expand Up @@ -510,6 +503,7 @@ ngx_stream_ssl_create_conf(ngx_conf_t *cf)
/*
* set by ngx_pcalloc():
*
* scf->listen = 0;
* scf->protocols = 0;
* scf->dhparam = { 0, NULL };
* scf->ecdh_curve = { 0, NULL };
Expand Down Expand Up @@ -582,18 +576,34 @@ ngx_stream_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)

conf->ssl.log = cf->log;

if (conf->certificates == NULL) {
if (!conf->listen) {
return NGX_CONF_OK;
}

if (conf->certificate_keys == NULL
|| conf->certificate_keys->nelts < conf->certificates->nelts)
{
if (conf->certificates == NULL) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"no \"ssl_certificate\" is defined for "
"the \"listen ... 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 \"listen ... 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\"",
"for certificate \"%V\" and "
"the \"listen ... ssl\" directive in %s:%ui",
((ngx_str_t *) conf->certificates->elts)
+ conf->certificates->nelts - 1);
+ conf->certificates->nelts - 1,
conf->file, conf->line);
return NGX_CONF_ERROR;
}

Expand Down
4 changes: 4 additions & 0 deletions src/stream/ngx_stream_ssl_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ typedef struct {

ngx_ssl_t ssl;

ngx_uint_t listen;
ngx_uint_t protocols;

ngx_uint_t verify;
Expand All @@ -47,6 +48,9 @@ typedef struct {

ngx_flag_t session_tickets;
ngx_array_t *session_ticket_keys;

u_char *file;
ngx_uint_t line;
} ngx_stream_ssl_conf_t;


Expand Down

0 comments on commit 76be1ea

Please sign in to comment.