comparison src/mail/ngx_mail_core_module.c @ 336:1c519aff5c0c NGINX_0_6_12

nginx 0.6.12 *) Change: mail proxy was split on three modules: pop3, imap and smtp. *) Feature: the --without-mail_pop3_module, --without-mail_imap_module, and --without-mail_smtp_module configuration parameters. *) Feature: the "smtp_greeting_delay" and "smtp_client_buffer" directives of the ngx_mail_smtp_module. *) Bugfix: the trailing wildcards did not work; bug appeared in 0.6.9. *) Bugfix: nginx could not start on Solaris if the shared PCRE library located in non-standard place was used. *) Bugfix: the "proxy_hide_header" and "fastcgi_hide_header" directives did not hide response header lines whose name was longer than 32 characters. Thanks to Manlio Perillo.
author Igor Sysoev <http://sysoev.ru>
date Fri, 21 Sep 2007 00:00:00 +0400
parents d16d691432c9
children 10cc350ed8a1
comparison
equal deleted inserted replaced
335:9a32ae248b7a 336:1c519aff5c0c
16 void *child); 16 void *child);
17 static char *ngx_mail_core_server(ngx_conf_t *cf, ngx_command_t *cmd, 17 static char *ngx_mail_core_server(ngx_conf_t *cf, ngx_command_t *cmd,
18 void *conf); 18 void *conf);
19 static char *ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, 19 static char *ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd,
20 void *conf); 20 void *conf);
21 static char *ngx_mail_core_capability(ngx_conf_t *cf, ngx_command_t *cmd, 21 static char *ngx_mail_core_protocol(ngx_conf_t *cf, ngx_command_t *cmd,
22 void *conf); 22 void *conf);
23
24
25 static ngx_conf_enum_t ngx_mail_core_procotol[] = {
26 { ngx_string("pop3"), NGX_MAIL_POP3_PROTOCOL },
27 { ngx_string("imap"), NGX_MAIL_IMAP_PROTOCOL },
28 { ngx_string("smtp"), NGX_MAIL_SMTP_PROTOCOL },
29 { ngx_null_string, 0 }
30 };
31
32
33 static ngx_str_t ngx_pop3_default_capabilities[] = {
34 ngx_string("TOP"),
35 ngx_string("USER"),
36 ngx_string("UIDL"),
37 ngx_null_string
38 };
39
40
41 static ngx_str_t ngx_imap_default_capabilities[] = {
42 ngx_string("IMAP4"),
43 ngx_string("IMAP4rev1"),
44 ngx_string("UIDPLUS"),
45 ngx_null_string
46 };
47
48
49 static ngx_conf_bitmask_t ngx_pop3_auth_methods[] = {
50 { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED },
51 { ngx_string("apop"), NGX_MAIL_AUTH_APOP_ENABLED },
52 { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED },
53 { ngx_null_string, 0 }
54 };
55
56
57 static ngx_conf_bitmask_t ngx_imap_auth_methods[] = {
58 { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED },
59 { ngx_string("login"), NGX_MAIL_AUTH_LOGIN_ENABLED },
60 { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED },
61 { ngx_null_string, 0 }
62 };
63
64
65 static ngx_conf_bitmask_t ngx_smtp_auth_methods[] = {
66 { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED },
67 { ngx_string("login"), NGX_MAIL_AUTH_LOGIN_ENABLED },
68 { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED },
69 { ngx_null_string, 0 }
70 };
71
72
73 static ngx_str_t ngx_imap_auth_methods_names[] = {
74 ngx_string("AUTH=PLAIN"),
75 ngx_string("AUTH=LOGIN"),
76 ngx_null_string, /* APOP */
77 ngx_string("AUTH=CRAM-MD5")
78 };
79
80
81 static ngx_str_t ngx_smtp_auth_methods_names[] = {
82 ngx_string("PLAIN"),
83 ngx_string("LOGIN"),
84 ngx_null_string, /* APOP */
85 ngx_string("CRAM-MD5")
86 };
87
88
89 static ngx_str_t ngx_pop3_auth_plain_capability =
90 ngx_string("+OK methods supported:" CRLF
91 "LOGIN" CRLF
92 "PLAIN" CRLF
93 "." CRLF);
94
95
96 static ngx_str_t ngx_pop3_auth_cram_md5_capability =
97 ngx_string("+OK methods supported:" CRLF
98 "LOGIN" CRLF
99 "PLAIN" CRLF
100 "CRAM-MD5" CRLF
101 "." CRLF);
102
103 23
104 24
105 static ngx_command_t ngx_mail_core_commands[] = { 25 static ngx_command_t ngx_mail_core_commands[] = {
106 26
107 { ngx_string("server"), 27 { ngx_string("server"),
112 NULL }, 32 NULL },
113 33
114 { ngx_string("listen"), 34 { ngx_string("listen"),
115 NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12, 35 NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12,
116 ngx_mail_core_listen, 36 ngx_mail_core_listen,
117 0, 37 NGX_MAIL_SRV_CONF_OFFSET,
118 0, 38 0,
119 NULL }, 39 NULL },
120 40
121 { ngx_string("protocol"), 41 { ngx_string("protocol"),
122 NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, 42 NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
123 ngx_conf_set_enum_slot, 43 ngx_mail_core_protocol,
124 NGX_MAIL_SRV_CONF_OFFSET, 44 NGX_MAIL_SRV_CONF_OFFSET,
125 offsetof(ngx_mail_core_srv_conf_t, protocol), 45 0,
126 &ngx_mail_core_procotol },
127
128 { ngx_string("imap_client_buffer"),
129 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
130 ngx_conf_set_size_slot,
131 NGX_MAIL_SRV_CONF_OFFSET,
132 offsetof(ngx_mail_core_srv_conf_t, imap_client_buffer_size),
133 NULL }, 46 NULL },
134 47
135 { ngx_string("so_keepalive"), 48 { ngx_string("so_keepalive"),
136 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, 49 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
137 ngx_conf_set_flag_slot, 50 ngx_conf_set_flag_slot,
144 ngx_conf_set_msec_slot, 57 ngx_conf_set_msec_slot,
145 NGX_MAIL_SRV_CONF_OFFSET, 58 NGX_MAIL_SRV_CONF_OFFSET,
146 offsetof(ngx_mail_core_srv_conf_t, timeout), 59 offsetof(ngx_mail_core_srv_conf_t, timeout),
147 NULL }, 60 NULL },
148 61
149 { ngx_string("pop3_capabilities"),
150 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
151 ngx_mail_core_capability,
152 NGX_MAIL_SRV_CONF_OFFSET,
153 offsetof(ngx_mail_core_srv_conf_t, pop3_capabilities),
154 NULL },
155
156 { ngx_string("imap_capabilities"),
157 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
158 ngx_mail_core_capability,
159 NGX_MAIL_SRV_CONF_OFFSET,
160 offsetof(ngx_mail_core_srv_conf_t, imap_capabilities),
161 NULL },
162
163 { ngx_string("smtp_capabilities"),
164 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
165 ngx_mail_core_capability,
166 NGX_MAIL_SRV_CONF_OFFSET,
167 offsetof(ngx_mail_core_srv_conf_t, smtp_capabilities),
168 NULL },
169
170 { ngx_string("server_name"), 62 { ngx_string("server_name"),
171 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, 63 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
172 ngx_conf_set_str_slot, 64 ngx_conf_set_str_slot,
173 NGX_MAIL_SRV_CONF_OFFSET, 65 NGX_MAIL_SRV_CONF_OFFSET,
174 offsetof(ngx_mail_core_srv_conf_t, server_name), 66 offsetof(ngx_mail_core_srv_conf_t, server_name),
175 NULL }, 67 NULL },
176 68
177 { ngx_string("auth"),
178 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
179 ngx_conf_set_bitmask_slot,
180 NGX_MAIL_SRV_CONF_OFFSET,
181 offsetof(ngx_mail_core_srv_conf_t, pop3_auth_methods),
182 &ngx_pop3_auth_methods },
183
184 { ngx_string("pop3_auth"),
185 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
186 ngx_conf_set_bitmask_slot,
187 NGX_MAIL_SRV_CONF_OFFSET,
188 offsetof(ngx_mail_core_srv_conf_t, pop3_auth_methods),
189 &ngx_pop3_auth_methods },
190
191 { ngx_string("imap_auth"),
192 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
193 ngx_conf_set_bitmask_slot,
194 NGX_MAIL_SRV_CONF_OFFSET,
195 offsetof(ngx_mail_core_srv_conf_t, imap_auth_methods),
196 &ngx_imap_auth_methods },
197
198 { ngx_string("smtp_auth"),
199 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
200 ngx_conf_set_bitmask_slot,
201 NGX_MAIL_SRV_CONF_OFFSET,
202 offsetof(ngx_mail_core_srv_conf_t, smtp_auth_methods),
203 &ngx_smtp_auth_methods },
204
205 ngx_null_command 69 ngx_null_command
206 }; 70 };
207 71
208 72
209 static ngx_mail_module_t ngx_mail_core_module_ctx = { 73 static ngx_mail_module_t ngx_mail_core_module_ctx = {
74 NULL, /* protocol */
75
210 ngx_mail_core_create_main_conf, /* create main configuration */ 76 ngx_mail_core_create_main_conf, /* create main configuration */
211 NULL, /* init main configuration */ 77 NULL, /* init main configuration */
212 78
213 ngx_mail_core_create_srv_conf, /* create server configuration */ 79 ngx_mail_core_create_srv_conf, /* create server configuration */
214 ngx_mail_core_merge_srv_conf /* merge server configuration */ 80 ngx_mail_core_merge_srv_conf /* merge server configuration */
266 cscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_srv_conf_t)); 132 cscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_srv_conf_t));
267 if (cscf == NULL) { 133 if (cscf == NULL) {
268 return NULL; 134 return NULL;
269 } 135 }
270 136
271 cscf->imap_client_buffer_size = NGX_CONF_UNSET_SIZE; 137 /*
272 cscf->protocol = NGX_CONF_UNSET_UINT; 138 * set by ngx_pcalloc():
139 *
140 * cscf->protocol = NULL;
141 */
142
273 cscf->timeout = NGX_CONF_UNSET_MSEC; 143 cscf->timeout = NGX_CONF_UNSET_MSEC;
274 cscf->so_keepalive = NGX_CONF_UNSET; 144 cscf->so_keepalive = NGX_CONF_UNSET;
275 145
276 if (ngx_array_init(&cscf->pop3_capabilities, cf->pool, 4, sizeof(ngx_str_t))
277 != NGX_OK)
278 {
279 return NULL;
280 }
281
282 if (ngx_array_init(&cscf->imap_capabilities, cf->pool, 4, sizeof(ngx_str_t))
283 != NGX_OK)
284 {
285 return NULL;
286 }
287
288 if (ngx_array_init(&cscf->smtp_capabilities, cf->pool, 4, sizeof(ngx_str_t))
289 != NGX_OK)
290 {
291 return NULL;
292 }
293
294 return cscf; 146 return cscf;
295 } 147 }
296 148
297 149
298 static char * 150 static char *
299 ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) 151 ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
300 { 152 {
301 ngx_mail_core_srv_conf_t *prev = parent; 153 ngx_mail_core_srv_conf_t *prev = parent;
302 ngx_mail_core_srv_conf_t *conf = child; 154 ngx_mail_core_srv_conf_t *conf = child;
303 155
304 u_char *p, *auth;
305 size_t size, stls_only_size;
306 ngx_str_t *c, *d;
307 ngx_uint_t i, m;
308
309 ngx_conf_merge_size_value(conf->imap_client_buffer_size,
310 prev->imap_client_buffer_size,
311 (size_t) ngx_pagesize);
312 ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000); 156 ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000);
313 ngx_conf_merge_uint_value(conf->protocol, prev->protocol, 157
314 NGX_MAIL_IMAP_PROTOCOL);
315 ngx_conf_merge_value(conf->so_keepalive, prev->so_keepalive, 0); 158 ngx_conf_merge_value(conf->so_keepalive, prev->so_keepalive, 0);
316
317
318 ngx_conf_merge_bitmask_value(conf->pop3_auth_methods,
319 prev->pop3_auth_methods,
320 (NGX_CONF_BITMASK_SET
321 |NGX_MAIL_AUTH_PLAIN_ENABLED));
322
323 ngx_conf_merge_bitmask_value(conf->imap_auth_methods,
324 prev->imap_auth_methods,
325 (NGX_CONF_BITMASK_SET
326 |NGX_MAIL_AUTH_PLAIN_ENABLED));
327
328 ngx_conf_merge_bitmask_value(conf->smtp_auth_methods,
329 prev->smtp_auth_methods,
330 (NGX_CONF_BITMASK_SET
331 |NGX_MAIL_AUTH_PLAIN_ENABLED
332 |NGX_MAIL_AUTH_LOGIN_ENABLED));
333 159
334 160
335 ngx_conf_merge_str_value(conf->server_name, prev->server_name, ""); 161 ngx_conf_merge_str_value(conf->server_name, prev->server_name, "");
336 162
337 if (conf->server_name.len == 0) { 163 if (conf->server_name.len == 0) {
341 } 167 }
342 168
343 if (gethostname((char *) conf->server_name.data, NGX_MAXHOSTNAMELEN) 169 if (gethostname((char *) conf->server_name.data, NGX_MAXHOSTNAMELEN)
344 == -1) 170 == -1)
345 { 171 {
346 ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno, 172 ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
347 "gethostname() failed"); 173 "gethostname() failed");
348 return NGX_CONF_ERROR; 174 return NGX_CONF_ERROR;
349 } 175 }
350 176
351 conf->server_name.len = ngx_strlen(conf->server_name.data); 177 conf->server_name.len = ngx_strlen(conf->server_name.data);
352 } 178 }
353 179
354 180 if (conf->protocol == NULL) {
355 if (conf->pop3_capabilities.nelts == 0) { 181 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
356 conf->pop3_capabilities = prev->pop3_capabilities; 182 "unknown mail protocol for server in %s:%ui",
357 } 183 conf->file_name, conf->line);
358 184 return NGX_CONF_ERROR;
359 if (conf->pop3_capabilities.nelts == 0) { 185 }
360
361 for (d = ngx_pop3_default_capabilities; d->len; d++) {
362 c = ngx_array_push(&conf->pop3_capabilities);
363 if (c == NULL) {
364 return NGX_CONF_ERROR;
365 }
366
367 *c = *d;
368 }
369 }
370
371 size = sizeof("+OK Capability list follows" CRLF) - 1
372 + sizeof("." CRLF) - 1;
373
374 stls_only_size = size + sizeof("STLS" CRLF) - 1;
375
376 c = conf->pop3_capabilities.elts;
377 for (i = 0; i < conf->pop3_capabilities.nelts; i++) {
378 size += c[i].len + sizeof(CRLF) - 1;
379
380 if (ngx_strcasecmp(c[i].data, (u_char *) "USER") == 0) {
381 continue;
382 }
383
384 stls_only_size += c[i].len + sizeof(CRLF) - 1;
385 }
386
387 if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
388 size += sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1;
389
390 } else {
391 size += sizeof("SASL LOGIN PLAIN" CRLF) - 1;
392 }
393
394 p = ngx_palloc(cf->pool, size);
395 if (p == NULL) {
396 return NGX_CONF_ERROR;
397 }
398
399 conf->pop3_capability.len = size;
400 conf->pop3_capability.data = p;
401
402 p = ngx_cpymem(p, "+OK Capability list follows" CRLF,
403 sizeof("+OK Capability list follows" CRLF) - 1);
404
405 for (i = 0; i < conf->pop3_capabilities.nelts; i++) {
406 p = ngx_cpymem(p, c[i].data, c[i].len);
407 *p++ = CR; *p++ = LF;
408 }
409
410 if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
411 p = ngx_cpymem(p, "SASL LOGIN PLAIN CRAM-MD5" CRLF,
412 sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1);
413
414 } else {
415 p = ngx_cpymem(p, "SASL LOGIN PLAIN" CRLF,
416 sizeof("SASL LOGIN PLAIN" CRLF) - 1);
417 }
418
419 *p++ = '.'; *p++ = CR; *p = LF;
420
421
422 size += sizeof("STLS" CRLF) - 1;
423
424 p = ngx_palloc(cf->pool, size);
425 if (p == NULL) {
426 return NGX_CONF_ERROR;
427 }
428
429 conf->pop3_starttls_capability.len = size;
430 conf->pop3_starttls_capability.data = p;
431
432 p = ngx_cpymem(p, conf->pop3_capability.data,
433 conf->pop3_capability.len - (sizeof("." CRLF) - 1));
434
435 p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1);
436 *p++ = '.'; *p++ = CR; *p = LF;
437
438
439 if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
440 conf->pop3_auth_capability = ngx_pop3_auth_cram_md5_capability;
441
442 } else {
443 conf->pop3_auth_capability = ngx_pop3_auth_plain_capability;
444 }
445
446
447 p = ngx_palloc(cf->pool, stls_only_size);
448 if (p == NULL) {
449 return NGX_CONF_ERROR;
450 }
451
452 conf->pop3_starttls_only_capability.len = stls_only_size;
453 conf->pop3_starttls_only_capability.data = p;
454
455 p = ngx_cpymem(p, "+OK Capability list follows" CRLF,
456 sizeof("+OK Capability list follows" CRLF) - 1);
457
458 for (i = 0; i < conf->pop3_capabilities.nelts; i++) {
459 if (ngx_strcasecmp(c[i].data, (u_char *) "USER") == 0) {
460 continue;
461 }
462
463 p = ngx_cpymem(p, c[i].data, c[i].len);
464 *p++ = CR; *p++ = LF;
465 }
466
467 p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1);
468 *p++ = '.'; *p++ = CR; *p = LF;
469
470
471 if (conf->imap_capabilities.nelts == 0) {
472 conf->imap_capabilities = prev->imap_capabilities;
473 }
474
475 if (conf->imap_capabilities.nelts == 0) {
476
477 for (d = ngx_imap_default_capabilities; d->len; d++) {
478 c = ngx_array_push(&conf->imap_capabilities);
479 if (c == NULL) {
480 return NGX_CONF_ERROR;
481 }
482
483 *c = *d;
484 }
485 }
486
487 size = sizeof("* CAPABILITY" CRLF) - 1;
488
489 c = conf->imap_capabilities.elts;
490 for (i = 0; i < conf->imap_capabilities.nelts; i++) {
491 size += 1 + c[i].len;
492 }
493
494 for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
495 m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
496 m <<= 1, i++)
497 {
498 if (m & conf->imap_auth_methods) {
499 size += 1 + ngx_imap_auth_methods_names[i].len;
500 }
501 }
502
503 p = ngx_palloc(cf->pool, size);
504 if (p == NULL) {
505 return NGX_CONF_ERROR;
506 }
507
508 conf->imap_capability.len = size;
509 conf->imap_capability.data = p;
510
511 p = ngx_cpymem(p, "* CAPABILITY", sizeof("* CAPABILITY") - 1);
512
513 for (i = 0; i < conf->imap_capabilities.nelts; i++) {
514 *p++ = ' ';
515 p = ngx_cpymem(p, c[i].data, c[i].len);
516 }
517
518 auth = p;
519
520 for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
521 m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
522 m <<= 1, i++)
523 {
524 if (m & conf->imap_auth_methods) {
525 *p++ = ' ';
526 p = ngx_cpymem(p, ngx_imap_auth_methods_names[i].data,
527 ngx_imap_auth_methods_names[i].len);
528 }
529 }
530
531 *p++ = CR; *p = LF;
532
533
534 size += sizeof(" STARTTLS") - 1;
535
536 p = ngx_palloc(cf->pool, size);
537 if (p == NULL) {
538 return NGX_CONF_ERROR;
539 }
540
541 conf->imap_starttls_capability.len = size;
542 conf->imap_starttls_capability.data = p;
543
544 p = ngx_cpymem(p, conf->imap_capability.data,
545 conf->imap_capability.len - (sizeof(CRLF) - 1));
546 p = ngx_cpymem(p, " STARTTLS", sizeof(" STARTTLS") - 1);
547 *p++ = CR; *p = LF;
548
549
550 size = (auth - conf->imap_capability.data) + sizeof(CRLF) - 1
551 + sizeof(" STARTTLS LOGINDISABLED") - 1;
552
553 p = ngx_palloc(cf->pool, size);
554 if (p == NULL) {
555 return NGX_CONF_ERROR;
556 }
557
558 conf->imap_starttls_only_capability.len = size;
559 conf->imap_starttls_only_capability.data = p;
560
561 p = ngx_cpymem(p, conf->imap_capability.data,
562 auth - conf->imap_capability.data);
563 p = ngx_cpymem(p, " STARTTLS LOGINDISABLED",
564 sizeof(" STARTTLS LOGINDISABLED") - 1);
565 *p++ = CR; *p = LF;
566
567
568 size = sizeof("220 ESMTP ready" CRLF) - 1 + conf->server_name.len;
569
570 p = ngx_palloc(cf->pool, size);
571 if (p == NULL) {
572 return NGX_CONF_ERROR;
573 }
574
575 conf->smtp_greeting.len = size;
576 conf->smtp_greeting.data = p;
577
578 *p++ = '2'; *p++ = '2'; *p++ = '0'; *p++ = ' ';
579 p = ngx_cpymem(p, conf->server_name.data, conf->server_name.len);
580 ngx_memcpy(p, " ESMTP ready" CRLF, sizeof(" ESMTP ready" CRLF) - 1);
581
582
583 size = sizeof("250 " CRLF) - 1 + conf->server_name.len;
584
585 p = ngx_palloc(cf->pool, size);
586 if (p == NULL) {
587 return NGX_CONF_ERROR;
588 }
589
590 conf->smtp_server_name.len = size;
591 conf->smtp_server_name.data = p;
592
593 *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = ' ';
594 p = ngx_cpymem(p, conf->server_name.data, conf->server_name.len);
595 *p++ = CR; *p = LF;
596
597
598 if (conf->smtp_capabilities.nelts == 0) {
599 conf->smtp_capabilities = prev->smtp_capabilities;
600 }
601
602 size = sizeof("250-") - 1 + conf->server_name.len + sizeof(CRLF) - 1
603 + sizeof("250 AUTH") - 1 + sizeof(CRLF) - 1;
604
605 c = conf->smtp_capabilities.elts;
606 for (i = 0; i < conf->smtp_capabilities.nelts; i++) {
607 size += sizeof("250 ") - 1 + c[i].len + sizeof(CRLF) - 1;
608 }
609
610 for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
611 m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
612 m <<= 1, i++)
613 {
614 if (m & conf->smtp_auth_methods) {
615 size += 1 + ngx_smtp_auth_methods_names[i].len;
616 }
617 }
618
619 p = ngx_palloc(cf->pool, size);
620 if (p == NULL) {
621 return NGX_CONF_ERROR;
622 }
623
624 conf->smtp_capability.len = size;
625 conf->smtp_capability.data = p;
626
627 *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = '-';
628 p = ngx_cpymem(p, conf->server_name.data, conf->server_name.len);
629 *p++ = CR; *p++ = LF;
630
631 for (i = 0; i < conf->smtp_capabilities.nelts; i++) {
632 *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = '-';
633 p = ngx_cpymem(p, c[i].data, c[i].len);
634 *p++ = CR; *p++ = LF;
635 }
636
637 auth = p;
638
639 *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = ' ';
640 *p++ = 'A'; *p++ = 'U'; *p++ = 'T'; *p++ = 'H';
641
642 for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
643 m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
644 m <<= 1, i++)
645 {
646 if (m & conf->smtp_auth_methods) {
647 *p++ = ' ';
648 p = ngx_cpymem(p, ngx_smtp_auth_methods_names[i].data,
649 ngx_smtp_auth_methods_names[i].len);
650 }
651 }
652
653 *p++ = CR; *p = LF;
654
655 size += sizeof("250 STARTTLS" CRLF) - 1;
656
657 p = ngx_palloc(cf->pool, size);
658 if (p == NULL) {
659 return NGX_CONF_ERROR;
660 }
661
662 conf->smtp_starttls_capability.len = size;
663 conf->smtp_starttls_capability.data = p;
664
665 p = ngx_cpymem(p, conf->smtp_capability.data,
666 conf->smtp_capability.len);
667
668 p = ngx_cpymem(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1);
669 *p++ = CR; *p = LF;
670
671 p = conf->smtp_starttls_capability.data
672 + (auth - conf->smtp_capability.data) + 3;
673 *p = '-';
674
675 size = (auth - conf->smtp_capability.data)
676 + sizeof("250 STARTTLS" CRLF) - 1;
677
678 p = ngx_palloc(cf->pool, size);
679 if (p == NULL) {
680 return NGX_CONF_ERROR;
681 }
682
683 conf->smtp_starttls_only_capability.len = size;
684 conf->smtp_starttls_only_capability.data = p;
685
686 p = ngx_cpymem(p, conf->smtp_capability.data,
687 auth - conf->smtp_capability.data);
688
689 ngx_memcpy(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1);
690 186
691 return NGX_CONF_OK; 187 return NGX_CONF_OK;
692 } 188 }
693 189
694 190
702 ngx_mail_module_t *module; 198 ngx_mail_module_t *module;
703 ngx_mail_conf_ctx_t *ctx, *mail_ctx; 199 ngx_mail_conf_ctx_t *ctx, *mail_ctx;
704 ngx_mail_core_srv_conf_t *cscf, **cscfp; 200 ngx_mail_core_srv_conf_t *cscf, **cscfp;
705 ngx_mail_core_main_conf_t *cmcf; 201 ngx_mail_core_main_conf_t *cmcf;
706 202
707
708 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_mail_conf_ctx_t)); 203 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_mail_conf_ctx_t));
709 if (ctx == NULL) { 204 if (ctx == NULL) {
710 return NGX_CONF_ERROR; 205 return NGX_CONF_ERROR;
711 } 206 }
712 207
740 /* the server configuration context */ 235 /* the server configuration context */
741 236
742 cscf = ctx->srv_conf[ngx_mail_core_module.ctx_index]; 237 cscf = ctx->srv_conf[ngx_mail_core_module.ctx_index];
743 cscf->ctx = ctx; 238 cscf->ctx = ctx;
744 239
240 cscf->file_name = cf->conf_file->file.name.data;
241 cscf->line = cf->conf_file->line;
242
745 cmcf = ctx->main_conf[ngx_mail_core_module.ctx_index]; 243 cmcf = ctx->main_conf[ngx_mail_core_module.ctx_index];
746 244
747 cscfp = ngx_array_push(&cmcf->servers); 245 cscfp = ngx_array_push(&cmcf->servers);
748 if (cscfp == NULL) { 246 if (cscfp == NULL) {
749 return NGX_CONF_ERROR; 247 return NGX_CONF_ERROR;
769 /* AF_INET only */ 267 /* AF_INET only */
770 268
771 static char * 269 static char *
772 ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 270 ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
773 { 271 {
272 ngx_mail_core_srv_conf_t *cscf = conf;
273
774 ngx_str_t *value; 274 ngx_str_t *value;
775 ngx_url_t u; 275 ngx_url_t u;
776 ngx_uint_t i; 276 ngx_uint_t i, m;
777 ngx_mail_listen_t *imls; 277 ngx_mail_listen_t *imls;
278 ngx_mail_module_t *module;
778 ngx_mail_core_main_conf_t *cmcf; 279 ngx_mail_core_main_conf_t *cmcf;
779 280
780 value = cf->args->elts; 281 value = cf->args->elts;
781 282
782 ngx_memzero(&u, sizeof(ngx_url_t)); 283 ngx_memzero(&u, sizeof(ngx_url_t));
819 imls->addr = u.addr.in_addr; 320 imls->addr = u.addr.in_addr;
820 imls->port = u.port; 321 imls->port = u.port;
821 imls->family = AF_INET; 322 imls->family = AF_INET;
822 imls->ctx = cf->ctx; 323 imls->ctx = cf->ctx;
823 324
325 for (m = 0; ngx_modules[m]; m++) {
326 if (ngx_modules[m]->type != NGX_MAIL_MODULE) {
327 continue;
328 }
329
330 module = ngx_modules[m]->ctx;
331
332 if (module->protocol == NULL) {
333 continue;
334 }
335
336 for (i = 0; module->protocol->port[i]; i++) {
337 if (module->protocol->port[i] == u.port) {
338 cscf->protocol = module->protocol;
339 break;
340 }
341 }
342 }
343
824 if (cf->args->nelts == 2) { 344 if (cf->args->nelts == 2) {
825 return NGX_CONF_OK; 345 return NGX_CONF_OK;
826 } 346 }
827 347
828 if (ngx_strcmp(value[2].data, "bind") == 0) { 348 if (ngx_strcmp(value[2].data, "bind") == 0) {
835 return NGX_CONF_ERROR; 355 return NGX_CONF_ERROR;
836 } 356 }
837 357
838 358
839 static char * 359 static char *
840 ngx_mail_core_capability(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 360 ngx_mail_core_protocol(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
361 {
362 ngx_mail_core_srv_conf_t *cscf = conf;
363
364 ngx_str_t *value;
365 ngx_uint_t m;
366 ngx_mail_module_t *module;
367
368 value = cf->args->elts;
369
370 for (m = 0; ngx_modules[m]; m++) {
371 if (ngx_modules[m]->type != NGX_MAIL_MODULE) {
372 continue;
373 }
374
375 module = ngx_modules[m]->ctx;
376
377 if (module->protocol
378 && ngx_strcmp(module->protocol->name.data, value[1].data) == 0)
379 {
380 cscf->protocol = module->protocol;
381
382 return NGX_CONF_OK;
383 }
384 }
385
386 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
387 "unknown protocol \"%V\"", &value[1]);
388 return NGX_CONF_ERROR;
389 }
390
391
392 char *
393 ngx_mail_capabilities(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
841 { 394 {
842 char *p = conf; 395 char *p = conf;
843 396
844 ngx_str_t *c, *value; 397 ngx_str_t *c, *value;
845 ngx_uint_t i; 398 ngx_uint_t i;