Back to home page

Nginx displayed by LXR

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