SSL: detect "listen ... ssl" without certificates (ticket #178).
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.
Maxim Dounin
4 years ago
965 | 965 | static ngx_int_t |
966 | 966 | ngx_http_ssl_init(ngx_conf_t *cf) |
967 | 967 | { |
968 | ngx_uint_t s; | |
968 | ngx_uint_t a, p, s; | |
969 | ngx_http_conf_addr_t *addr; | |
970 | ngx_http_conf_port_t *port; | |
969 | 971 | ngx_http_ssl_srv_conf_t *sscf; |
970 | 972 | ngx_http_core_loc_conf_t *clcf; |
971 | ngx_http_core_srv_conf_t **cscfp; | |
973 | ngx_http_core_srv_conf_t **cscfp, *cscf; | |
972 | 974 | ngx_http_core_main_conf_t *cmcf; |
973 | 975 | |
974 | 976 | cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); |
992 | 994 | } |
993 | 995 | } |
994 | 996 | |
997 | if (cmcf->ports == NULL) { | |
998 | return NGX_OK; | |
999 | } | |
1000 | ||
1001 | port = cmcf->ports->elts; | |
1002 | for (p = 0; p < cmcf->ports->nelts; p++) { | |
1003 | ||
1004 | addr = port[p].addrs.elts; | |
1005 | for (a = 0; a < port[p].addrs.nelts; a++) { | |
1006 | ||
1007 | if (!addr[a].opt.ssl) { | |
1008 | continue; | |
1009 | } | |
1010 | ||
1011 | cscf = addr[a].default_server; | |
1012 | sscf = cscf->ctx->srv_conf[ngx_http_ssl_module.ctx_index]; | |
1013 | ||
1014 | if (sscf->certificates == NULL) { | |
1015 | ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
1016 | "no \"ssl_certificate\" is defined for " | |
1017 | "the \"listen ... ssl\" directive in %s:%ui", | |
1018 | cscf->file_name, cscf->line); | |
1019 | return NGX_ERROR; | |
1020 | } | |
1021 | } | |
1022 | } | |
1023 | ||
995 | 1024 | return NGX_OK; |
996 | 1025 | } |
3254 | 3254 | cscf->ignore_invalid_headers = NGX_CONF_UNSET; |
3255 | 3255 | cscf->merge_slashes = NGX_CONF_UNSET; |
3256 | 3256 | cscf->underscores_in_headers = NGX_CONF_UNSET; |
3257 | ||
3258 | cscf->file_name = cf->conf_file->file.name.data; | |
3259 | cscf->line = cf->conf_file->line; | |
3257 | 3260 | |
3258 | 3261 | return cscf; |
3259 | 3262 | } |
182 | 182 | |
183 | 183 | /* server ctx */ |
184 | 184 | ngx_http_conf_ctx_t *ctx; |
185 | ||
186 | u_char *file_name; | |
187 | ngx_uint_t line; | |
185 | 188 | |
186 | 189 | ngx_str_t server_name; |
187 | 190 |
335 | 335 | sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module); |
336 | 336 | |
337 | 337 | if (sscf->enable || hc->addr_conf->ssl) { |
338 | ||
338 | hc->ssl = 1; | |
339 | 339 | c->log->action = "SSL handshaking"; |
340 | ||
341 | if (hc->addr_conf->ssl && sscf->ssl.ctx == NULL) { | |
342 | ngx_log_error(NGX_LOG_ERR, c->log, 0, | |
343 | "no \"ssl_certificate\" is defined " | |
344 | "in server listening on SSL port"); | |
345 | ngx_http_close_connection(c); | |
346 | return; | |
347 | } | |
348 | ||
349 | hc->ssl = 1; | |
350 | ||
351 | 340 | rev->handler = ngx_http_ssl_handshake; |
352 | 341 | } |
353 | 342 | } |
473 | 473 | |
474 | 474 | if (ngx_strcmp(value[i].data, "ssl") == 0) { |
475 | 475 | #if (NGX_MAIL_SSL) |
476 | ngx_mail_ssl_conf_t *sslcf; | |
477 | ||
478 | sslcf = ngx_mail_conf_get_module_srv_conf(cf, ngx_mail_ssl_module); | |
479 | ||
480 | sslcf->listen = 1; | |
481 | sslcf->file = cf->conf_file->file.name.data; | |
482 | sslcf->line = cf->conf_file->line; | |
483 | ||
476 | 484 | ls->ssl = 1; |
485 | ||
477 | 486 | continue; |
478 | 487 | #else |
479 | 488 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
164 | 164 | |
165 | 165 | sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module); |
166 | 166 | |
167 | if (sslcf->enable) { | |
167 | if (sslcf->enable || addr_conf->ssl) { | |
168 | 168 | c->log->action = "SSL handshaking"; |
169 | ||
170 | ngx_mail_ssl_init_connection(&sslcf->ssl, c); | |
171 | return; | |
172 | } | |
173 | ||
174 | if (addr_conf->ssl) { | |
175 | ||
176 | c->log->action = "SSL handshaking"; | |
177 | ||
178 | if (sslcf->ssl.ctx == NULL) { | |
179 | ngx_log_error(NGX_LOG_ERR, c->log, 0, | |
180 | "no \"ssl_certificate\" is defined " | |
181 | "in server listening on SSL port"); | |
182 | ngx_mail_close_connection(c); | |
183 | return; | |
184 | } | |
185 | 169 | |
186 | 170 | ngx_mail_ssl_init_connection(&sslcf->ssl, c); |
187 | 171 | return; |
237 | 237 | /* |
238 | 238 | * set by ngx_pcalloc(): |
239 | 239 | * |
240 | * scf->listen = 0; | |
240 | 241 | * scf->protocols = 0; |
241 | 242 | * scf->dhparam = { 0, NULL }; |
242 | 243 | * scf->ecdh_curve = { 0, NULL }; |
312 | 313 | |
313 | 314 | conf->ssl.log = cf->log; |
314 | 315 | |
315 | if (conf->enable) { | |
316 | if (conf->listen) { | |
317 | mode = "listen ... ssl"; | |
318 | ||
319 | } else if (conf->enable) { | |
316 | 320 | mode = "ssl"; |
317 | 321 | |
318 | 322 | } else if (conf->starttls != NGX_MAIL_STARTTLS_OFF) { |
319 | 323 | mode = "starttls"; |
320 | 324 | |
321 | 325 | } else { |
322 | mode = ""; | |
326 | return NGX_CONF_OK; | |
323 | 327 | } |
324 | 328 | |
325 | 329 | if (conf->file == NULL) { |
327 | 331 | conf->line = prev->line; |
328 | 332 | } |
329 | 333 | |
330 | if (*mode) { | |
331 | ||
332 | if (conf->certificates == NULL) { | |
333 | ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
334 | "no \"ssl_certificate\" is defined for " | |
335 | "the \"%s\" directive in %s:%ui", | |
336 | mode, conf->file, conf->line); | |
337 | return NGX_CONF_ERROR; | |
338 | } | |
339 | ||
340 | if (conf->certificate_keys == NULL) { | |
341 | ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
342 | "no \"ssl_certificate_key\" is defined for " | |
343 | "the \"%s\" directive in %s:%ui", | |
344 | mode, conf->file, conf->line); | |
345 | return NGX_CONF_ERROR; | |
346 | } | |
347 | ||
348 | if (conf->certificate_keys->nelts < conf->certificates->nelts) { | |
349 | ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
350 | "no \"ssl_certificate_key\" is defined " | |
351 | "for certificate \"%V\" and " | |
352 | "the \"%s\" directive in %s:%ui", | |
353 | ((ngx_str_t *) conf->certificates->elts) | |
354 | + conf->certificates->nelts - 1, | |
355 | mode, conf->file, conf->line); | |
356 | return NGX_CONF_ERROR; | |
357 | } | |
358 | ||
359 | } else { | |
360 | ||
361 | if (conf->certificates == NULL) { | |
362 | return NGX_CONF_OK; | |
363 | } | |
364 | ||
365 | if (conf->certificate_keys == NULL | |
366 | || conf->certificate_keys->nelts < conf->certificates->nelts) | |
367 | { | |
368 | ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
369 | "no \"ssl_certificate_key\" is defined " | |
370 | "for certificate \"%V\"", | |
371 | ((ngx_str_t *) conf->certificates->elts) | |
372 | + conf->certificates->nelts - 1); | |
373 | return NGX_CONF_ERROR; | |
374 | } | |
334 | if (conf->certificates == NULL) { | |
335 | ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
336 | "no \"ssl_certificate\" is defined for " | |
337 | "the \"%s\" directive in %s:%ui", | |
338 | mode, conf->file, conf->line); | |
339 | return NGX_CONF_ERROR; | |
340 | } | |
341 | ||
342 | if (conf->certificate_keys == NULL) { | |
343 | ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
344 | "no \"ssl_certificate_key\" is defined for " | |
345 | "the \"%s\" directive in %s:%ui", | |
346 | mode, conf->file, conf->line); | |
347 | return NGX_CONF_ERROR; | |
348 | } | |
349 | ||
350 | if (conf->certificate_keys->nelts < conf->certificates->nelts) { | |
351 | ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
352 | "no \"ssl_certificate_key\" is defined " | |
353 | "for certificate \"%V\" and " | |
354 | "the \"%s\" directive in %s:%ui", | |
355 | ((ngx_str_t *) conf->certificates->elts) | |
356 | + conf->certificates->nelts - 1, | |
357 | mode, conf->file, conf->line); | |
358 | return NGX_CONF_ERROR; | |
375 | 359 | } |
376 | 360 | |
377 | 361 | if (ngx_ssl_create(&conf->ssl, conf->protocols, NULL) != NGX_OK) { |
493 | 477 | return NGX_CONF_ERROR; |
494 | 478 | } |
495 | 479 | |
496 | scf->file = cf->conf_file->file.name.data; | |
497 | scf->line = cf->conf_file->line; | |
480 | if (!scf->listen) { | |
481 | scf->file = cf->conf_file->file.name.data; | |
482 | scf->line = cf->conf_file->line; | |
483 | } | |
498 | 484 | |
499 | 485 | return NGX_CONF_OK; |
500 | 486 | } |
519 | 505 | return NGX_CONF_ERROR; |
520 | 506 | } |
521 | 507 | |
522 | scf->file = cf->conf_file->file.name.data; | |
523 | scf->line = cf->conf_file->line; | |
508 | if (!scf->listen) { | |
509 | scf->file = cf->conf_file->file.name.data; | |
510 | scf->line = cf->conf_file->line; | |
511 | } | |
524 | 512 | |
525 | 513 | return NGX_CONF_OK; |
526 | 514 | } |
25 | 25 | ngx_ssl_t ssl; |
26 | 26 | |
27 | 27 | ngx_uint_t starttls; |
28 | ngx_uint_t listen; | |
28 | 29 | ngx_uint_t protocols; |
29 | 30 | |
30 | 31 | ngx_uint_t verify; |
733 | 733 | |
734 | 734 | if (ngx_strcmp(value[i].data, "ssl") == 0) { |
735 | 735 | #if (NGX_STREAM_SSL) |
736 | ngx_stream_ssl_conf_t *sslcf; | |
737 | ||
738 | sslcf = ngx_stream_conf_get_module_srv_conf(cf, | |
739 | ngx_stream_ssl_module); | |
740 | ||
741 | sslcf->listen = 1; | |
742 | sslcf->file = cf->conf_file->file.name.data; | |
743 | sslcf->line = cf->conf_file->line; | |
744 | ||
736 | 745 | ls->ssl = 1; |
746 | ||
737 | 747 | continue; |
738 | 748 | #else |
739 | 749 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
303 | 303 | if (c->ssl == NULL) { |
304 | 304 | c->log->action = "SSL handshaking"; |
305 | 305 | |
306 | if (sslcf->ssl.ctx == NULL) { | |
307 | ngx_log_error(NGX_LOG_ERR, c->log, 0, | |
308 | "no \"ssl_certificate\" is defined " | |
309 | "in server listening on SSL port"); | |
310 | return NGX_ERROR; | |
311 | } | |
312 | ||
313 | 306 | rv = ngx_stream_ssl_init_connection(&sslcf->ssl, c); |
314 | 307 | |
315 | 308 | if (rv != NGX_OK) { |
509 | 502 | /* |
510 | 503 | * set by ngx_pcalloc(): |
511 | 504 | * |
505 | * scf->listen = 0; | |
512 | 506 | * scf->protocols = 0; |
513 | 507 | * scf->dhparam = { 0, NULL }; |
514 | 508 | * scf->ecdh_curve = { 0, NULL }; |
581 | 575 | |
582 | 576 | conf->ssl.log = cf->log; |
583 | 577 | |
578 | if (!conf->listen) { | |
579 | return NGX_CONF_OK; | |
580 | } | |
581 | ||
584 | 582 | if (conf->certificates == NULL) { |
585 | return NGX_CONF_OK; | |
586 | } | |
587 | ||
588 | if (conf->certificate_keys == NULL | |
589 | || conf->certificate_keys->nelts < conf->certificates->nelts) | |
590 | { | |
583 | ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
584 | "no \"ssl_certificate\" is defined for " | |
585 | "the \"listen ... ssl\" directive in %s:%ui", | |
586 | conf->file, conf->line); | |
587 | return NGX_CONF_ERROR; | |
588 | } | |
589 | ||
590 | if (conf->certificate_keys == NULL) { | |
591 | ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
592 | "no \"ssl_certificate_key\" is defined for " | |
593 | "the \"listen ... ssl\" directive in %s:%ui", | |
594 | conf->file, conf->line); | |
595 | return NGX_CONF_ERROR; | |
596 | } | |
597 | ||
598 | if (conf->certificate_keys->nelts < conf->certificates->nelts) { | |
591 | 599 | ngx_log_error(NGX_LOG_EMERG, cf->log, 0, |
592 | 600 | "no \"ssl_certificate_key\" is defined " |
593 | "for certificate \"%V\"", | |
601 | "for certificate \"%V\" and " | |
602 | "the \"listen ... ssl\" directive in %s:%ui", | |
594 | 603 | ((ngx_str_t *) conf->certificates->elts) |
595 | + conf->certificates->nelts - 1); | |
604 | + conf->certificates->nelts - 1, | |
605 | conf->file, conf->line); | |
596 | 606 | return NGX_CONF_ERROR; |
597 | 607 | } |
598 | 608 |