1 2 /* 3 * Copyright (C) Igor Sysoev 4 * Copyright (C) Nginx, Inc. 5 */ 6 7 8 #include <ngx_config.h> 9 #include <ngx_core.h> 10 #include <ngx_mail.h> 11 12 13 #define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5" 14 #define NGX_DEFAULT_ECDH_CURVE "auto" 15 16 17 #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation 18 static int ngx_mail_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, 19 const unsigned char **out, unsigned char *outlen, 20 const unsigned char *in, unsigned int inlen, void *arg); 21 #endif 22 23 static void *ngx_mail_ssl_create_conf(ngx_conf_t *cf); 24 static char *ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child); 25 26 static char *ngx_mail_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd, 27 void *conf); 28 static char *ngx_mail_ssl_starttls(ngx_conf_t *cf, ngx_command_t *cmd, 29 void *conf); 30 static char *ngx_mail_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, 31 void *conf); 32 static char *ngx_mail_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, 33 void *conf); 34 35 static char *ngx_mail_ssl_conf_command_check(ngx_conf_t *cf, void *post, 36 void *data); 37 38 39 static ngx_conf_enum_t ngx_mail_starttls_state[] = { 40 { ngx_string("off"), NGX_MAIL_STARTTLS_OFF }, 41 { ngx_string("on"), NGX_MAIL_STARTTLS_ON }, 42 { ngx_string("only"), NGX_MAIL_STARTTLS_ONLY }, 43 { ngx_null_string, 0 } 44 }; 45 46 47 48 static ngx_conf_bitmask_t ngx_mail_ssl_protocols[] = { 49 { ngx_string("SSLv2"), NGX_SSL_SSLv2 }, 50 { ngx_string("SSLv3"), NGX_SSL_SSLv3 }, 51 { ngx_string("TLSv1"), NGX_SSL_TLSv1 }, 52 { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 }, 53 { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 }, 54 { ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 }, 55 { ngx_null_string, 0 } 56 }; 57 58 59 static ngx_conf_enum_t ngx_mail_ssl_verify[] = { 60 { ngx_string("off"), 0 }, 61 { ngx_string("on"), 1 }, 62 { ngx_string("optional"), 2 }, 63 { ngx_string("optional_no_ca"), 3 }, 64 { ngx_null_string, 0 } 65 }; 66 67 68 static ngx_conf_deprecated_t ngx_mail_ssl_deprecated = { 69 ngx_conf_deprecated, "ssl", "listen ... ssl" 70 }; 71 72 73 static ngx_conf_post_t ngx_mail_ssl_conf_command_post = 74 { ngx_mail_ssl_conf_command_check }; 75 76 77 static ngx_command_t ngx_mail_ssl_commands[] = { 78 79 { ngx_string("ssl"), 80 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, 81 ngx_mail_ssl_enable, 82 NGX_MAIL_SRV_CONF_OFFSET, 83 offsetof(ngx_mail_ssl_conf_t, enable), 84 &ngx_mail_ssl_deprecated }, 85 86 { ngx_string("starttls"), 87 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, 88 ngx_mail_ssl_starttls, 89 NGX_MAIL_SRV_CONF_OFFSET, 90 offsetof(ngx_mail_ssl_conf_t, starttls), 91 ngx_mail_starttls_state }, 92 93 { ngx_string("ssl_certificate"), 94 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, 95 ngx_conf_set_str_array_slot, 96 NGX_MAIL_SRV_CONF_OFFSET, 97 offsetof(ngx_mail_ssl_conf_t, certificates), 98 NULL }, 99 100 { ngx_string("ssl_certificate_key"), 101 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, 102 ngx_conf_set_str_array_slot, 103 NGX_MAIL_SRV_CONF_OFFSET, 104 offsetof(ngx_mail_ssl_conf_t, certificate_keys), 105 NULL }, 106 107 { ngx_string("ssl_password_file"), 108 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, 109 ngx_mail_ssl_password_file, 110 NGX_MAIL_SRV_CONF_OFFSET, 111 0, 112 NULL }, 113 114 { ngx_string("ssl_dhparam"), 115 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, 116 ngx_conf_set_str_slot, 117 NGX_MAIL_SRV_CONF_OFFSET, 118 offsetof(ngx_mail_ssl_conf_t, dhparam), 119 NULL }, 120 121 { ngx_string("ssl_ecdh_curve"), 122 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, 123 ngx_conf_set_str_slot, 124 NGX_MAIL_SRV_CONF_OFFSET, 125 offsetof(ngx_mail_ssl_conf_t, ecdh_curve), 126 NULL }, 127 128 { ngx_string("ssl_protocols"), 129 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE, 130 ngx_conf_set_bitmask_slot, 131 NGX_MAIL_SRV_CONF_OFFSET, 132 offsetof(ngx_mail_ssl_conf_t, protocols), 133 &ngx_mail_ssl_protocols }, 134 135 { ngx_string("ssl_ciphers"), 136 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, 137 ngx_conf_set_str_slot, 138 NGX_MAIL_SRV_CONF_OFFSET, 139 offsetof(ngx_mail_ssl_conf_t, ciphers), 140 NULL }, 141 142 { ngx_string("ssl_prefer_server_ciphers"), 143 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, 144 ngx_conf_set_flag_slot, 145 NGX_MAIL_SRV_CONF_OFFSET, 146 offsetof(ngx_mail_ssl_conf_t, prefer_server_ciphers), 147 NULL }, 148 149 { ngx_string("ssl_session_cache"), 150 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12, 151 ngx_mail_ssl_session_cache, 152 NGX_MAIL_SRV_CONF_OFFSET, 153 0, 154 NULL }, 155 156 { ngx_string("ssl_session_tickets"), 157 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, 158 ngx_conf_set_flag_slot, 159 NGX_MAIL_SRV_CONF_OFFSET, 160 offsetof(ngx_mail_ssl_conf_t, session_tickets), 161 NULL }, 162 163 { ngx_string("ssl_session_ticket_key"), 164 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, 165 ngx_conf_set_str_array_slot, 166 NGX_MAIL_SRV_CONF_OFFSET, 167 offsetof(ngx_mail_ssl_conf_t, session_ticket_keys), 168 NULL }, 169 170 { ngx_string("ssl_session_timeout"), 171 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, 172 ngx_conf_set_sec_slot, 173 NGX_MAIL_SRV_CONF_OFFSET, 174 offsetof(ngx_mail_ssl_conf_t, session_timeout), 175 NULL }, 176 177 { ngx_string("ssl_verify_client"), 178 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, 179 ngx_conf_set_enum_slot, 180 NGX_MAIL_SRV_CONF_OFFSET, 181 offsetof(ngx_mail_ssl_conf_t, verify), 182 &ngx_mail_ssl_verify }, 183 184 { ngx_string("ssl_verify_depth"), 185 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, 186 ngx_conf_set_num_slot, 187 NGX_MAIL_SRV_CONF_OFFSET, 188 offsetof(ngx_mail_ssl_conf_t, verify_depth), 189 NULL }, 190 191 { ngx_string("ssl_client_certificate"), 192 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, 193 ngx_conf_set_str_slot, 194 NGX_MAIL_SRV_CONF_OFFSET, 195 offsetof(ngx_mail_ssl_conf_t, client_certificate), 196 NULL }, 197 198 { ngx_string("ssl_trusted_certificate"), 199 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, 200 ngx_conf_set_str_slot, 201 NGX_MAIL_SRV_CONF_OFFSET, 202 offsetof(ngx_mail_ssl_conf_t, trusted_certificate), 203 NULL }, 204 205 { ngx_string("ssl_crl"), 206 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, 207 ngx_conf_set_str_slot, 208 NGX_MAIL_SRV_CONF_OFFSET, 209 offsetof(ngx_mail_ssl_conf_t, crl), 210 NULL }, 211 212 { ngx_string("ssl_conf_command"), 213 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE2, 214 ngx_conf_set_keyval_slot, 215 NGX_MAIL_SRV_CONF_OFFSET, 216 offsetof(ngx_mail_ssl_conf_t, conf_commands), 217 &ngx_mail_ssl_conf_command_post }, 218 219 ngx_null_command 220 }; 221 222 223 static ngx_mail_module_t ngx_mail_ssl_module_ctx = { 224 NULL, /* protocol */ 225 226 NULL, /* create main configuration */ 227 NULL, /* init main configuration */ 228 229 ngx_mail_ssl_create_conf, /* create server configuration */ 230 ngx_mail_ssl_merge_conf /* merge server configuration */ 231 }; 232 233 234 ngx_module_t ngx_mail_ssl_module = { 235 NGX_MODULE_V1, 236 &ngx_mail_ssl_module_ctx, /* module context */ 237 ngx_mail_ssl_commands, /* module directives */ 238 NGX_MAIL_MODULE, /* module type */ 239 NULL, /* init master */ 240 NULL, /* init module */ 241 NULL, /* init process */ 242 NULL, /* init thread */ 243 NULL, /* exit thread */ 244 NULL, /* exit process */ 245 NULL, /* exit master */ 246 NGX_MODULE_V1_PADDING 247 }; 248 249 250 static ngx_str_t ngx_mail_ssl_sess_id_ctx = ngx_string("MAIL"); 251 252 253 #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation 254 255 static int 256 ngx_mail_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, const unsigned char **out, 257 unsigned char *outlen, const unsigned char *in, unsigned int inlen, 258 void *arg) 259 { 260 unsigned int srvlen; 261 unsigned char *srv; 262 ngx_connection_t *c; 263 ngx_mail_session_t *s; 264 ngx_mail_core_srv_conf_t *cscf; 265 #if (NGX_DEBUG) 266 unsigned int i; 267 #endif 268 269 c = ngx_ssl_get_connection(ssl_conn); 270 s = c->data; 271 272 #if (NGX_DEBUG) 273 for (i = 0; i < inlen; i += in[i] + 1) { 274 ngx_log_debug2(NGX_LOG_DEBUG_MAIL, c->log, 0, 275 "SSL ALPN supported by client: %*s", 276 (size_t) in[i], &in[i + 1]); 277 } 278 #endif 279 280 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); 281 282 srv = cscf->protocol->alpn.data; 283 srvlen = cscf->protocol->alpn.len; 284 285 if (SSL_select_next_proto((unsigned char **) out, outlen, srv, srvlen, 286 in, inlen) 287 != OPENSSL_NPN_NEGOTIATED) 288 { 289 return SSL_TLSEXT_ERR_ALERT_FATAL; 290 } 291 292 ngx_log_debug2(NGX_LOG_DEBUG_MAIL, c->log, 0, 293 "SSL ALPN selected: %*s", (size_t) *outlen, *out); 294 295 return SSL_TLSEXT_ERR_OK; 296 } 297 298 #endif 299 300 301 static void * 302 ngx_mail_ssl_create_conf(ngx_conf_t *cf) 303 { 304 ngx_mail_ssl_conf_t *scf; 305 306 scf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_ssl_conf_t)); 307 if (scf == NULL) { 308 return NULL; 309 } 310 311 /* 312 * set by ngx_pcalloc(): 313 * 314 * scf->listen = 0; 315 * scf->protocols = 0; 316 * scf->dhparam = { 0, NULL }; 317 * scf->ecdh_curve = { 0, NULL }; 318 * scf->client_certificate = { 0, NULL }; 319 * scf->trusted_certificate = { 0, NULL }; 320 * scf->crl = { 0, NULL }; 321 * scf->ciphers = { 0, NULL }; 322 * scf->shm_zone = NULL; 323 */ 324 325 scf->enable = NGX_CONF_UNSET; 326 scf->starttls = NGX_CONF_UNSET_UINT; 327 scf->certificates = NGX_CONF_UNSET_PTR; 328 scf->certificate_keys = NGX_CONF_UNSET_PTR; 329 scf->passwords = NGX_CONF_UNSET_PTR; 330 scf->conf_commands = NGX_CONF_UNSET_PTR; 331 scf->prefer_server_ciphers = NGX_CONF_UNSET; 332 scf->verify = NGX_CONF_UNSET_UINT; 333 scf->verify_depth = NGX_CONF_UNSET_UINT; 334 scf->builtin_session_cache = NGX_CONF_UNSET; 335 scf->session_timeout = NGX_CONF_UNSET; 336 scf->session_tickets = NGX_CONF_UNSET; 337 scf->session_ticket_keys = NGX_CONF_UNSET_PTR; 338 339 return scf; 340 } 341 342 343 static char * 344 ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child) 345 { 346 ngx_mail_ssl_conf_t *prev = parent; 347 ngx_mail_ssl_conf_t *conf = child; 348 349 char *mode; 350 ngx_pool_cleanup_t *cln; 351 352 ngx_conf_merge_value(conf->enable, prev->enable, 0); 353 ngx_conf_merge_uint_value(conf->starttls, prev->starttls, 354 NGX_MAIL_STARTTLS_OFF); 355 356 ngx_conf_merge_value(conf->session_timeout, 357 prev->session_timeout, 300); 358 359 ngx_conf_merge_value(conf->prefer_server_ciphers, 360 prev->prefer_server_ciphers, 0); 361 362 ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols, 363 (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1 364 |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2)); 365 366 ngx_conf_merge_uint_value(conf->verify, prev->verify, 0); 367 ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1); 368 369 ngx_conf_merge_ptr_value(conf->certificates, prev->certificates, NULL); 370 ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys, 371 NULL); 372 373 ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL); 374 375 ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, ""); 376 377 ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve, 378 NGX_DEFAULT_ECDH_CURVE); 379 380 ngx_conf_merge_str_value(conf->client_certificate, 381 prev->client_certificate, ""); 382 ngx_conf_merge_str_value(conf->trusted_certificate, 383 prev->trusted_certificate, ""); 384 ngx_conf_merge_str_value(conf->crl, prev->crl, ""); 385 386 ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS); 387 388 ngx_conf_merge_ptr_value(conf->conf_commands, prev->conf_commands, NULL); 389 390 391 conf->ssl.log = cf->log; 392 393 if (conf->listen) { 394 mode = "listen ... ssl"; 395 396 } else if (conf->enable) { 397 mode = "ssl"; 398 399 } else if (conf->starttls != NGX_MAIL_STARTTLS_OFF) { 400 mode = "starttls"; 401 402 } else { 403 return NGX_CONF_OK; 404 } 405 406 if (conf->file == NULL) { 407 conf->file = prev->file; 408 conf->line = prev->line; 409 } 410 411 if (conf->certificates == NULL) { 412 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, 413 "no \"ssl_certificate\" is defined for " 414 "the \"%s\" directive in %s:%ui", 415 mode, conf->file, conf->line); 416 return NGX_CONF_ERROR; 417 } 418 419 if (conf->certificate_keys == NULL) { 420 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, 421 "no \"ssl_certificate_key\" is defined for " 422 "the \"%s\" directive in %s:%ui", 423 mode, conf->file, conf->line); 424 return NGX_CONF_ERROR; 425 } 426 427 if (conf->certificate_keys->nelts < conf->certificates->nelts) { 428 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, 429 "no \"ssl_certificate_key\" is defined " 430 "for certificate \"%V\" and " 431 "the \"%s\" directive in %s:%ui", 432 ((ngx_str_t *) conf->certificates->elts) 433 + conf->certificates->nelts - 1, 434 mode, conf->file, conf->line); 435 return NGX_CONF_ERROR; 436 } 437 438 if (ngx_ssl_create(&conf->ssl, conf->protocols, NULL) != NGX_OK) { 439 return NGX_CONF_ERROR; 440 } 441 442 cln = ngx_pool_cleanup_add(cf->pool, 0); 443 if (cln == NULL) { 444 ngx_ssl_cleanup_ctx(&conf->ssl); 445 return NGX_CONF_ERROR; 446 } 447 448 cln->handler = ngx_ssl_cleanup_ctx; 449 cln->data = &conf->ssl; 450 451 #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation 452 SSL_CTX_set_alpn_select_cb(conf->ssl.ctx, ngx_mail_ssl_alpn_select, NULL); 453 #endif 454 455 if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers, 456 conf->prefer_server_ciphers) 457 != NGX_OK) 458 { 459 return NGX_CONF_ERROR; 460 } 461 462 if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, 463 conf->certificate_keys, conf->passwords) 464 != NGX_OK) 465 { 466 return NGX_CONF_ERROR; 467 } 468 469 if (conf->verify) { 470 471 if (conf->client_certificate.len == 0 && conf->verify != 3) { 472 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, 473 "no ssl_client_certificate for ssl_verify_client"); 474 return NGX_CONF_ERROR; 475 } 476 477 if (ngx_ssl_client_certificate(cf, &conf->ssl, 478 &conf->client_certificate, 479 conf->verify_depth) 480 != NGX_OK) 481 { 482 return NGX_CONF_ERROR; 483 } 484 485 if (ngx_ssl_trusted_certificate(cf, &conf->ssl, 486 &conf->trusted_certificate, 487 conf->verify_depth) 488 != NGX_OK) 489 { 490 return NGX_CONF_ERROR; 491 } 492 493 if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) { 494 return NGX_CONF_ERROR; 495 } 496 } 497 498 if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) { 499 return NGX_CONF_ERROR; 500 } 501 502 if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) { 503 return NGX_CONF_ERROR; 504 } 505 506 ngx_conf_merge_value(conf->builtin_session_cache, 507 prev->builtin_session_cache, NGX_SSL_NONE_SCACHE); 508 509 if (conf->shm_zone == NULL) { 510 conf->shm_zone = prev->shm_zone; 511 } 512 513 if (ngx_ssl_session_cache(&conf->ssl, &ngx_mail_ssl_sess_id_ctx, 514 conf->certificates, conf->builtin_session_cache, 515 conf->shm_zone, conf->session_timeout) 516 != NGX_OK) 517 { 518 return NGX_CONF_ERROR; 519 } 520 521 ngx_conf_merge_value(conf->session_tickets, 522 prev->session_tickets, 1); 523 524 #ifdef SSL_OP_NO_TICKET 525 if (!conf->session_tickets) { 526 SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_NO_TICKET); 527 } 528 #endif 529 530 ngx_conf_merge_ptr_value(conf->session_ticket_keys, 531 prev->session_ticket_keys, NULL); 532 533 if (ngx_ssl_session_ticket_keys(cf, &conf->ssl, conf->session_ticket_keys) 534 != NGX_OK) 535 { 536 return NGX_CONF_ERROR; 537 } 538 539 if (ngx_ssl_conf_commands(cf, &conf->ssl, conf->conf_commands) != NGX_OK) { 540 return NGX_CONF_ERROR; 541 } 542 543 return NGX_CONF_OK; 544 } 545 546 547 static char * 548 ngx_mail_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 549 { 550 ngx_mail_ssl_conf_t *scf = conf; 551 552 char *rv; 553 554 rv = ngx_conf_set_flag_slot(cf, cmd, conf); 555 556 if (rv != NGX_CONF_OK) { 557 return rv; 558 } 559 560 if (scf->enable && (ngx_int_t) scf->starttls > NGX_MAIL_STARTTLS_OFF) { 561 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 562 "\"starttls\" directive conflicts with \"ssl on\""); 563 return NGX_CONF_ERROR; 564 } 565 566 if (!scf->listen) { 567 scf->file = cf->conf_file->file.name.data; 568 scf->line = cf->conf_file->line; 569 } 570 571 return NGX_CONF_OK; 572 } 573 574 575 static char * 576 ngx_mail_ssl_starttls(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 577 { 578 ngx_mail_ssl_conf_t *scf = conf; 579 580 char *rv; 581 582 rv = ngx_conf_set_enum_slot(cf, cmd, conf); 583 584 if (rv != NGX_CONF_OK) { 585 return rv; 586 } 587 588 if (scf->enable == 1 && (ngx_int_t) scf->starttls > NGX_MAIL_STARTTLS_OFF) { 589 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 590 "\"ssl\" directive conflicts with \"starttls\""); 591 return NGX_CONF_ERROR; 592 } 593 594 if (!scf->listen) { 595 scf->file = cf->conf_file->file.name.data; 596 scf->line = cf->conf_file->line; 597 } 598 599 return NGX_CONF_OK; 600 } 601 602 603 static char * 604 ngx_mail_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 605 { 606 ngx_mail_ssl_conf_t *scf = conf; 607 608 ngx_str_t *value; 609 610 if (scf->passwords != NGX_CONF_UNSET_PTR) { 611 return "is duplicate"; 612 } 613 614 value = cf->args->elts; 615 616 scf->passwords = ngx_ssl_read_password_file(cf, &value[1]); 617 618 if (scf->passwords == NULL) { 619 return NGX_CONF_ERROR; 620 } 621 622 return NGX_CONF_OK; 623 } 624 625 626 static char * 627 ngx_mail_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 628 { 629 ngx_mail_ssl_conf_t *scf = conf; 630 631 size_t len; 632 ngx_str_t *value, name, size; 633 ngx_int_t n; 634 ngx_uint_t i, j; 635 636 value = cf->args->elts; 637 638 for (i = 1; i < cf->args->nelts; i++) { 639 640 if (ngx_strcmp(value[i].data, "off") == 0) { 641 scf->builtin_session_cache = NGX_SSL_NO_SCACHE; 642 continue; 643 } 644 645 if (ngx_strcmp(value[i].data, "none") == 0) { 646 scf->builtin_session_cache = NGX_SSL_NONE_SCACHE; 647 continue; 648 } 649 650 if (ngx_strcmp(value[i].data, "builtin") == 0) { 651 scf->builtin_session_cache = NGX_SSL_DFLT_BUILTIN_SCACHE; 652 continue; 653 } 654 655 if (value[i].len > sizeof("builtin:") - 1 656 && ngx_strncmp(value[i].data, "builtin:", sizeof("builtin:") - 1) 657 == 0) 658 { 659 n = ngx_atoi(value[i].data + sizeof("builtin:") - 1, 660 value[i].len - (sizeof("builtin:") - 1)); 661 662 if (n == NGX_ERROR) { 663 goto invalid; 664 } 665 666 scf->builtin_session_cache = n; 667 668 continue; 669 } 670 671 if (value[i].len > sizeof("shared:") - 1 672 && ngx_strncmp(value[i].data, "shared:", sizeof("shared:") - 1) 673 == 0) 674 { 675 len = 0; 676 677 for (j = sizeof("shared:") - 1; j < value[i].len; j++) { 678 if (value[i].data[j] == ':') { 679 break; 680 } 681 682 len++; 683 } 684 685 if (len == 0) { 686 goto invalid; 687 } 688 689 name.len = len; 690 name.data = value[i].data + sizeof("shared:") - 1; 691 692 size.len = value[i].len - j - 1; 693 size.data = name.data + len + 1; 694 695 n = ngx_parse_size(&size); 696 697 if (n == NGX_ERROR) { 698 goto invalid; 699 } 700 701 if (n < (ngx_int_t) (8 * ngx_pagesize)) { 702 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 703 "session cache \"%V\" is too small", 704 &value[i]); 705 706 return NGX_CONF_ERROR; 707 } 708 709 scf->shm_zone = ngx_shared_memory_add(cf, &name, n, 710 &ngx_mail_ssl_module); 711 if (scf->shm_zone == NULL) { 712 return NGX_CONF_ERROR; 713 } 714 715 scf->shm_zone->init = ngx_ssl_session_cache_init; 716 717 continue; 718 } 719 720 goto invalid; 721 } 722 723 if (scf->shm_zone && scf->builtin_session_cache == NGX_CONF_UNSET) { 724 scf->builtin_session_cache = NGX_SSL_NO_BUILTIN_SCACHE; 725 } 726 727 return NGX_CONF_OK; 728 729 invalid: 730 731 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 732 "invalid session cache \"%V\"", &value[i]); 733 734 return NGX_CONF_ERROR; 735 } 736 737 738 static char * 739 ngx_mail_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data) 740 { 741 #ifndef SSL_CONF_FLAG_FILE 742 return "is not supported on this platform"; 743 #else 744 return NGX_CONF_OK; 745 #endif 746 } 747