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