Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.15.11 ]​[ nginx-1.14.2 ]​

0001 
0002 /*
0003  * Copyright (C) Igor Sysoev
0004  * Copyright (C) Nginx, Inc.
0005  */
0006 
0007 
0008 #include <ngx_config.h>
0009 #include <ngx_core.h>
0010 #include <ngx_mail.h>
0011 
0012 
0013 #define NGX_DEFAULT_CIPHERS     "HIGH:!aNULL:!MD5"
0014 #define NGX_DEFAULT_ECDH_CURVE  "auto"
0015 
0016 
0017 static void *ngx_mail_ssl_create_conf(ngx_conf_t *cf);
0018 static char *ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child);
0019 
0020 static char *ngx_mail_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd,
0021     void *conf);
0022 static char *ngx_mail_ssl_starttls(ngx_conf_t *cf, ngx_command_t *cmd,
0023     void *conf);
0024 static char *ngx_mail_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
0025     void *conf);
0026 static char *ngx_mail_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
0027     void *conf);
0028 
0029 
0030 static ngx_conf_enum_t  ngx_mail_starttls_state[] = {
0031     { ngx_string("off"), NGX_MAIL_STARTTLS_OFF },
0032     { ngx_string("on"), NGX_MAIL_STARTTLS_ON },
0033     { ngx_string("only"), NGX_MAIL_STARTTLS_ONLY },
0034     { ngx_null_string, 0 }
0035 };
0036 
0037 
0038 
0039 static ngx_conf_bitmask_t  ngx_mail_ssl_protocols[] = {
0040     { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
0041     { ngx_string("SSLv3"), NGX_SSL_SSLv3 },
0042     { ngx_string("TLSv1"), NGX_SSL_TLSv1 },
0043     { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
0044     { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
0045     { ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 },
0046     { ngx_null_string, 0 }
0047 };
0048 
0049 
0050 static ngx_conf_enum_t  ngx_mail_ssl_verify[] = {
0051     { ngx_string("off"), 0 },
0052     { ngx_string("on"), 1 },
0053     { ngx_string("optional"), 2 },
0054     { ngx_string("optional_no_ca"), 3 },
0055     { ngx_null_string, 0 }
0056 };
0057 
0058 
0059 static ngx_conf_deprecated_t  ngx_mail_ssl_deprecated = {
0060     ngx_conf_deprecated, "ssl", "listen ... ssl"
0061 };
0062 
0063 
0064 static ngx_command_t  ngx_mail_ssl_commands[] = {
0065 
0066     { ngx_string("ssl"),
0067       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
0068       ngx_mail_ssl_enable,
0069       NGX_MAIL_SRV_CONF_OFFSET,
0070       offsetof(ngx_mail_ssl_conf_t, enable),
0071       &ngx_mail_ssl_deprecated },
0072 
0073     { ngx_string("starttls"),
0074       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
0075       ngx_mail_ssl_starttls,
0076       NGX_MAIL_SRV_CONF_OFFSET,
0077       offsetof(ngx_mail_ssl_conf_t, starttls),
0078       ngx_mail_starttls_state },
0079 
0080     { ngx_string("ssl_certificate"),
0081       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
0082       ngx_conf_set_str_array_slot,
0083       NGX_MAIL_SRV_CONF_OFFSET,
0084       offsetof(ngx_mail_ssl_conf_t, certificates),
0085       NULL },
0086 
0087     { ngx_string("ssl_certificate_key"),
0088       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
0089       ngx_conf_set_str_array_slot,
0090       NGX_MAIL_SRV_CONF_OFFSET,
0091       offsetof(ngx_mail_ssl_conf_t, certificate_keys),
0092       NULL },
0093 
0094     { ngx_string("ssl_password_file"),
0095       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
0096       ngx_mail_ssl_password_file,
0097       NGX_MAIL_SRV_CONF_OFFSET,
0098       0,
0099       NULL },
0100 
0101     { ngx_string("ssl_dhparam"),
0102       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
0103       ngx_conf_set_str_slot,
0104       NGX_MAIL_SRV_CONF_OFFSET,
0105       offsetof(ngx_mail_ssl_conf_t, dhparam),
0106       NULL },
0107 
0108     { ngx_string("ssl_ecdh_curve"),
0109       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
0110       ngx_conf_set_str_slot,
0111       NGX_MAIL_SRV_CONF_OFFSET,
0112       offsetof(ngx_mail_ssl_conf_t, ecdh_curve),
0113       NULL },
0114 
0115     { ngx_string("ssl_protocols"),
0116       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
0117       ngx_conf_set_bitmask_slot,
0118       NGX_MAIL_SRV_CONF_OFFSET,
0119       offsetof(ngx_mail_ssl_conf_t, protocols),
0120       &ngx_mail_ssl_protocols },
0121 
0122     { ngx_string("ssl_ciphers"),
0123       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
0124       ngx_conf_set_str_slot,
0125       NGX_MAIL_SRV_CONF_OFFSET,
0126       offsetof(ngx_mail_ssl_conf_t, ciphers),
0127       NULL },
0128 
0129     { ngx_string("ssl_prefer_server_ciphers"),
0130       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
0131       ngx_conf_set_flag_slot,
0132       NGX_MAIL_SRV_CONF_OFFSET,
0133       offsetof(ngx_mail_ssl_conf_t, prefer_server_ciphers),
0134       NULL },
0135 
0136     { ngx_string("ssl_session_cache"),
0137       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12,
0138       ngx_mail_ssl_session_cache,
0139       NGX_MAIL_SRV_CONF_OFFSET,
0140       0,
0141       NULL },
0142 
0143     { ngx_string("ssl_session_tickets"),
0144       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
0145       ngx_conf_set_flag_slot,
0146       NGX_MAIL_SRV_CONF_OFFSET,
0147       offsetof(ngx_mail_ssl_conf_t, session_tickets),
0148       NULL },
0149 
0150     { ngx_string("ssl_session_ticket_key"),
0151       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
0152       ngx_conf_set_str_array_slot,
0153       NGX_MAIL_SRV_CONF_OFFSET,
0154       offsetof(ngx_mail_ssl_conf_t, session_ticket_keys),
0155       NULL },
0156 
0157     { ngx_string("ssl_session_timeout"),
0158       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
0159       ngx_conf_set_sec_slot,
0160       NGX_MAIL_SRV_CONF_OFFSET,
0161       offsetof(ngx_mail_ssl_conf_t, session_timeout),
0162       NULL },
0163 
0164     { ngx_string("ssl_verify_client"),
0165       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
0166       ngx_conf_set_enum_slot,
0167       NGX_MAIL_SRV_CONF_OFFSET,
0168       offsetof(ngx_mail_ssl_conf_t, verify),
0169       &ngx_mail_ssl_verify },
0170 
0171     { ngx_string("ssl_verify_depth"),
0172       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
0173       ngx_conf_set_num_slot,
0174       NGX_MAIL_SRV_CONF_OFFSET,
0175       offsetof(ngx_mail_ssl_conf_t, verify_depth),
0176       NULL },
0177 
0178     { ngx_string("ssl_client_certificate"),
0179       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
0180       ngx_conf_set_str_slot,
0181       NGX_MAIL_SRV_CONF_OFFSET,
0182       offsetof(ngx_mail_ssl_conf_t, client_certificate),
0183       NULL },
0184 
0185     { ngx_string("ssl_trusted_certificate"),
0186       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
0187       ngx_conf_set_str_slot,
0188       NGX_MAIL_SRV_CONF_OFFSET,
0189       offsetof(ngx_mail_ssl_conf_t, trusted_certificate),
0190       NULL },
0191 
0192     { ngx_string("ssl_crl"),
0193       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
0194       ngx_conf_set_str_slot,
0195       NGX_MAIL_SRV_CONF_OFFSET,
0196       offsetof(ngx_mail_ssl_conf_t, crl),
0197       NULL },
0198 
0199       ngx_null_command
0200 };
0201 
0202 
0203 static ngx_mail_module_t  ngx_mail_ssl_module_ctx = {
0204     NULL,                                  /* protocol */
0205 
0206     NULL,                                  /* create main configuration */
0207     NULL,                                  /* init main configuration */
0208 
0209     ngx_mail_ssl_create_conf,              /* create server configuration */
0210     ngx_mail_ssl_merge_conf                /* merge server configuration */
0211 };
0212 
0213 
0214 ngx_module_t  ngx_mail_ssl_module = {
0215     NGX_MODULE_V1,
0216     &ngx_mail_ssl_module_ctx,              /* module context */
0217     ngx_mail_ssl_commands,                 /* module directives */
0218     NGX_MAIL_MODULE,                       /* module type */
0219     NULL,                                  /* init master */
0220     NULL,                                  /* init module */
0221     NULL,                                  /* init process */
0222     NULL,                                  /* init thread */
0223     NULL,                                  /* exit thread */
0224     NULL,                                  /* exit process */
0225     NULL,                                  /* exit master */
0226     NGX_MODULE_V1_PADDING
0227 };
0228 
0229 
0230 static ngx_str_t ngx_mail_ssl_sess_id_ctx = ngx_string("MAIL");
0231 
0232 
0233 static void *
0234 ngx_mail_ssl_create_conf(ngx_conf_t *cf)
0235 {
0236     ngx_mail_ssl_conf_t  *scf;
0237 
0238     scf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_ssl_conf_t));
0239     if (scf == NULL) {
0240         return NULL;
0241     }
0242 
0243     /*
0244      * set by ngx_pcalloc():
0245      *
0246      *     scf->listen = 0;
0247      *     scf->protocols = 0;
0248      *     scf->dhparam = { 0, NULL };
0249      *     scf->ecdh_curve = { 0, NULL };
0250      *     scf->client_certificate = { 0, NULL };
0251      *     scf->trusted_certificate = { 0, NULL };
0252      *     scf->crl = { 0, NULL };
0253      *     scf->ciphers = { 0, NULL };
0254      *     scf->shm_zone = NULL;
0255      */
0256 
0257     scf->enable = NGX_CONF_UNSET;
0258     scf->starttls = NGX_CONF_UNSET_UINT;
0259     scf->certificates = NGX_CONF_UNSET_PTR;
0260     scf->certificate_keys = NGX_CONF_UNSET_PTR;
0261     scf->passwords = NGX_CONF_UNSET_PTR;
0262     scf->prefer_server_ciphers = NGX_CONF_UNSET;
0263     scf->verify = NGX_CONF_UNSET_UINT;
0264     scf->verify_depth = NGX_CONF_UNSET_UINT;
0265     scf->builtin_session_cache = NGX_CONF_UNSET;
0266     scf->session_timeout = NGX_CONF_UNSET;
0267     scf->session_tickets = NGX_CONF_UNSET;
0268     scf->session_ticket_keys = NGX_CONF_UNSET_PTR;
0269 
0270     return scf;
0271 }
0272 
0273 
0274 static char *
0275 ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
0276 {
0277     ngx_mail_ssl_conf_t *prev = parent;
0278     ngx_mail_ssl_conf_t *conf = child;
0279 
0280     char                *mode;
0281     ngx_pool_cleanup_t  *cln;
0282 
0283     ngx_conf_merge_value(conf->enable, prev->enable, 0);
0284     ngx_conf_merge_uint_value(conf->starttls, prev->starttls,
0285                          NGX_MAIL_STARTTLS_OFF);
0286 
0287     ngx_conf_merge_value(conf->session_timeout,
0288                          prev->session_timeout, 300);
0289 
0290     ngx_conf_merge_value(conf->prefer_server_ciphers,
0291                          prev->prefer_server_ciphers, 0);
0292 
0293     ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
0294                          (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1
0295                           |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
0296 
0297     ngx_conf_merge_uint_value(conf->verify, prev->verify, 0);
0298     ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1);
0299 
0300     ngx_conf_merge_ptr_value(conf->certificates, prev->certificates, NULL);
0301     ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys,
0302                          NULL);
0303 
0304     ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL);
0305 
0306     ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");
0307 
0308     ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve,
0309                          NGX_DEFAULT_ECDH_CURVE);
0310 
0311     ngx_conf_merge_str_value(conf->client_certificate,
0312                          prev->client_certificate, "");
0313     ngx_conf_merge_str_value(conf->trusted_certificate,
0314                          prev->trusted_certificate, "");
0315     ngx_conf_merge_str_value(conf->crl, prev->crl, "");
0316 
0317     ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
0318 
0319 
0320     conf->ssl.log = cf->log;
0321 
0322     if (conf->listen) {
0323         mode = "listen ... ssl";
0324 
0325     } else if (conf->enable) {
0326         mode = "ssl";
0327 
0328     } else if (conf->starttls != NGX_MAIL_STARTTLS_OFF) {
0329         mode = "starttls";
0330 
0331     } else {
0332         return NGX_CONF_OK;
0333     }
0334 
0335     if (conf->file == NULL) {
0336         conf->file = prev->file;
0337         conf->line = prev->line;
0338     }
0339 
0340     if (conf->certificates == NULL) {
0341         ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
0342                       "no \"ssl_certificate\" is defined for "
0343                       "the \"%s\" directive in %s:%ui",
0344                       mode, conf->file, conf->line);
0345         return NGX_CONF_ERROR;
0346     }
0347 
0348     if (conf->certificate_keys == NULL) {
0349         ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
0350                       "no \"ssl_certificate_key\" is defined for "
0351                       "the \"%s\" directive in %s:%ui",
0352                       mode, conf->file, conf->line);
0353         return NGX_CONF_ERROR;
0354     }
0355 
0356     if (conf->certificate_keys->nelts < conf->certificates->nelts) {
0357         ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
0358                       "no \"ssl_certificate_key\" is defined "
0359                       "for certificate \"%V\" and "
0360                       "the \"%s\" directive in %s:%ui",
0361                       ((ngx_str_t *) conf->certificates->elts)
0362                       + conf->certificates->nelts - 1,
0363                       mode, conf->file, conf->line);
0364         return NGX_CONF_ERROR;
0365     }
0366 
0367     if (ngx_ssl_create(&conf->ssl, conf->protocols, NULL) != NGX_OK) {
0368         return NGX_CONF_ERROR;
0369     }
0370 
0371     cln = ngx_pool_cleanup_add(cf->pool, 0);
0372     if (cln == NULL) {
0373         ngx_ssl_cleanup_ctx(&conf->ssl);
0374         return NGX_CONF_ERROR;
0375     }
0376 
0377     cln->handler = ngx_ssl_cleanup_ctx;
0378     cln->data = &conf->ssl;
0379 
0380     if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates,
0381                              conf->certificate_keys, conf->passwords)
0382         != NGX_OK)
0383     {
0384         return NGX_CONF_ERROR;
0385     }
0386 
0387     if (conf->verify) {
0388 
0389         if (conf->client_certificate.len == 0 && conf->verify != 3) {
0390             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
0391                           "no ssl_client_certificate for ssl_client_verify");
0392             return NGX_CONF_ERROR;
0393         }
0394 
0395         if (ngx_ssl_client_certificate(cf, &conf->ssl,
0396                                        &conf->client_certificate,
0397                                        conf->verify_depth)
0398             != NGX_OK)
0399         {
0400             return NGX_CONF_ERROR;
0401         }
0402 
0403         if (ngx_ssl_trusted_certificate(cf, &conf->ssl,
0404                                         &conf->trusted_certificate,
0405                                         conf->verify_depth)
0406             != NGX_OK)
0407         {
0408             return NGX_CONF_ERROR;
0409         }
0410 
0411         if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) {
0412             return NGX_CONF_ERROR;
0413         }
0414     }
0415 
0416     if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers,
0417                         conf->prefer_server_ciphers)
0418         != NGX_OK)
0419     {
0420         return NGX_CONF_ERROR;
0421     }
0422 
0423     if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) {
0424         return NGX_CONF_ERROR;
0425     }
0426 
0427     if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) {
0428         return NGX_CONF_ERROR;
0429     }
0430 
0431     ngx_conf_merge_value(conf->builtin_session_cache,
0432                          prev->builtin_session_cache, NGX_SSL_NONE_SCACHE);
0433 
0434     if (conf->shm_zone == NULL) {
0435         conf->shm_zone = prev->shm_zone;
0436     }
0437 
0438     if (ngx_ssl_session_cache(&conf->ssl, &ngx_mail_ssl_sess_id_ctx,
0439                               conf->certificates, conf->builtin_session_cache,
0440                               conf->shm_zone, conf->session_timeout)
0441         != NGX_OK)
0442     {
0443         return NGX_CONF_ERROR;
0444     }
0445 
0446     ngx_conf_merge_value(conf->session_tickets,
0447                          prev->session_tickets, 1);
0448 
0449 #ifdef SSL_OP_NO_TICKET
0450     if (!conf->session_tickets) {
0451         SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_NO_TICKET);
0452     }
0453 #endif
0454 
0455     ngx_conf_merge_ptr_value(conf->session_ticket_keys,
0456                          prev->session_ticket_keys, NULL);
0457 
0458     if (ngx_ssl_session_ticket_keys(cf, &conf->ssl, conf->session_ticket_keys)
0459         != NGX_OK)
0460     {
0461         return NGX_CONF_ERROR;
0462     }
0463 
0464     return NGX_CONF_OK;
0465 }
0466 
0467 
0468 static char *
0469 ngx_mail_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
0470 {
0471     ngx_mail_ssl_conf_t  *scf = conf;
0472 
0473     char  *rv;
0474 
0475     rv = ngx_conf_set_flag_slot(cf, cmd, conf);
0476 
0477     if (rv != NGX_CONF_OK) {
0478         return rv;
0479     }
0480 
0481     if (scf->enable && (ngx_int_t) scf->starttls > NGX_MAIL_STARTTLS_OFF) {
0482         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0483                            "\"starttls\" directive conflicts with \"ssl on\"");
0484         return NGX_CONF_ERROR;
0485     }
0486 
0487     if (!scf->listen) {
0488         scf->file = cf->conf_file->file.name.data;
0489         scf->line = cf->conf_file->line;
0490     }
0491 
0492     return NGX_CONF_OK;
0493 }
0494 
0495 
0496 static char *
0497 ngx_mail_ssl_starttls(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
0498 {
0499     ngx_mail_ssl_conf_t  *scf = conf;
0500 
0501     char  *rv;
0502 
0503     rv = ngx_conf_set_enum_slot(cf, cmd, conf);
0504 
0505     if (rv != NGX_CONF_OK) {
0506         return rv;
0507     }
0508 
0509     if (scf->enable == 1 && (ngx_int_t) scf->starttls > NGX_MAIL_STARTTLS_OFF) {
0510         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0511                            "\"ssl\" directive conflicts with \"starttls\"");
0512         return NGX_CONF_ERROR;
0513     }
0514 
0515     if (!scf->listen) {
0516         scf->file = cf->conf_file->file.name.data;
0517         scf->line = cf->conf_file->line;
0518     }
0519 
0520     return NGX_CONF_OK;
0521 }
0522 
0523 
0524 static char *
0525 ngx_mail_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
0526 {
0527     ngx_mail_ssl_conf_t  *scf = conf;
0528 
0529     ngx_str_t  *value;
0530 
0531     if (scf->passwords != NGX_CONF_UNSET_PTR) {
0532         return "is duplicate";
0533     }
0534 
0535     value = cf->args->elts;
0536 
0537     scf->passwords = ngx_ssl_read_password_file(cf, &value[1]);
0538 
0539     if (scf->passwords == NULL) {
0540         return NGX_CONF_ERROR;
0541     }
0542 
0543     return NGX_CONF_OK;
0544 }
0545 
0546 
0547 static char *
0548 ngx_mail_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
0549 {
0550     ngx_mail_ssl_conf_t  *scf = conf;
0551 
0552     size_t       len;
0553     ngx_str_t   *value, name, size;
0554     ngx_int_t    n;
0555     ngx_uint_t   i, j;
0556 
0557     value = cf->args->elts;
0558 
0559     for (i = 1; i < cf->args->nelts; i++) {
0560 
0561         if (ngx_strcmp(value[i].data, "off") == 0) {
0562             scf->builtin_session_cache = NGX_SSL_NO_SCACHE;
0563             continue;
0564         }
0565 
0566         if (ngx_strcmp(value[i].data, "none") == 0) {
0567             scf->builtin_session_cache = NGX_SSL_NONE_SCACHE;
0568             continue;
0569         }
0570 
0571         if (ngx_strcmp(value[i].data, "builtin") == 0) {
0572             scf->builtin_session_cache = NGX_SSL_DFLT_BUILTIN_SCACHE;
0573             continue;
0574         }
0575 
0576         if (value[i].len > sizeof("builtin:") - 1
0577             && ngx_strncmp(value[i].data, "builtin:", sizeof("builtin:") - 1)
0578                == 0)
0579         {
0580             n = ngx_atoi(value[i].data + sizeof("builtin:") - 1,
0581                          value[i].len - (sizeof("builtin:") - 1));
0582 
0583             if (n == NGX_ERROR) {
0584                 goto invalid;
0585             }
0586 
0587             scf->builtin_session_cache = n;
0588 
0589             continue;
0590         }
0591 
0592         if (value[i].len > sizeof("shared:") - 1
0593             && ngx_strncmp(value[i].data, "shared:", sizeof("shared:") - 1)
0594                == 0)
0595         {
0596             len = 0;
0597 
0598             for (j = sizeof("shared:") - 1; j < value[i].len; j++) {
0599                 if (value[i].data[j] == ':') {
0600                     break;
0601                 }
0602 
0603                 len++;
0604             }
0605 
0606             if (len == 0) {
0607                 goto invalid;
0608             }
0609 
0610             name.len = len;
0611             name.data = value[i].data + sizeof("shared:") - 1;
0612 
0613             size.len = value[i].len - j - 1;
0614             size.data = name.data + len + 1;
0615 
0616             n = ngx_parse_size(&size);
0617 
0618             if (n == NGX_ERROR) {
0619                 goto invalid;
0620             }
0621 
0622             if (n < (ngx_int_t) (8 * ngx_pagesize)) {
0623                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0624                                    "session cache \"%V\" is too small",
0625                                    &value[i]);
0626 
0627                 return NGX_CONF_ERROR;
0628             }
0629 
0630             scf->shm_zone = ngx_shared_memory_add(cf, &name, n,
0631                                                    &ngx_mail_ssl_module);
0632             if (scf->shm_zone == NULL) {
0633                 return NGX_CONF_ERROR;
0634             }
0635 
0636             scf->shm_zone->init = ngx_ssl_session_cache_init;
0637 
0638             continue;
0639         }
0640 
0641         goto invalid;
0642     }
0643 
0644     if (scf->shm_zone && scf->builtin_session_cache == NGX_CONF_UNSET) {
0645         scf->builtin_session_cache = NGX_SSL_NO_BUILTIN_SCACHE;
0646     }
0647 
0648     return NGX_CONF_OK;
0649 
0650 invalid:
0651 
0652     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0653                        "invalid session cache \"%V\"", &value[i]);
0654 
0655     return NGX_CONF_ERROR;
0656 }