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