comparison src/mail/ngx_mail_core_module.c @ 409:52b28d322d76

Merge with nginx 0.6.12.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 11 Aug 2008 21:22:47 +0400
parents 05c02cbce7be 1c519aff5c0c
children cd9cb7a3ff9e
comparison
equal deleted inserted replaced
408:4243eecbd594 409:52b28d322d76
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_string("none"), NGX_MAIL_AUTH_NONE_ENABLED },
70 { ngx_null_string, 0 }
71 };
72
73
74 static ngx_str_t ngx_imap_auth_methods_names[] = {
75 ngx_string("AUTH=PLAIN"),
76 ngx_string("AUTH=LOGIN"),
77 ngx_null_string, /* APOP */
78 ngx_string("AUTH=CRAM-MD5"),
79 ngx_null_string /* NONE */
80 };
81
82
83 static ngx_str_t ngx_smtp_auth_methods_names[] = {
84 ngx_string("PLAIN"),
85 ngx_string("LOGIN"),
86 ngx_null_string, /* APOP */
87 ngx_string("CRAM-MD5"),
88 ngx_null_string /* NONE */
89 };
90
91
92 static ngx_str_t ngx_pop3_auth_plain_capability =
93 ngx_string("+OK methods supported:" CRLF
94 "LOGIN" CRLF
95 "PLAIN" CRLF
96 "." CRLF);
97
98
99 static ngx_str_t ngx_pop3_auth_cram_md5_capability =
100 ngx_string("+OK methods supported:" CRLF
101 "LOGIN" CRLF
102 "PLAIN" CRLF
103 "CRAM-MD5" CRLF
104 "." CRLF);
105
106 23
107 24
108 static ngx_command_t ngx_mail_core_commands[] = { 25 static ngx_command_t ngx_mail_core_commands[] = {
109 26
110 { ngx_string("server"), 27 { ngx_string("server"),
115 NULL }, 32 NULL },
116 33
117 { ngx_string("listen"), 34 { ngx_string("listen"),
118 NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12, 35 NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12,
119 ngx_mail_core_listen, 36 ngx_mail_core_listen,
120 0, 37 NGX_MAIL_SRV_CONF_OFFSET,
121 0, 38 0,
122 NULL }, 39 NULL },
123 40
124 { ngx_string("protocol"), 41 { ngx_string("protocol"),
125 NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, 42 NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
126 ngx_conf_set_enum_slot, 43 ngx_mail_core_protocol,
127 NGX_MAIL_SRV_CONF_OFFSET, 44 NGX_MAIL_SRV_CONF_OFFSET,
128 offsetof(ngx_mail_core_srv_conf_t, protocol), 45 0,
129 &ngx_mail_core_procotol },
130
131 { ngx_string("imap_client_buffer"),
132 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
133 ngx_conf_set_size_slot,
134 NGX_MAIL_SRV_CONF_OFFSET,
135 offsetof(ngx_mail_core_srv_conf_t, imap_client_buffer_size),
136 NULL }, 46 NULL },
137 47
138 { ngx_string("so_keepalive"), 48 { ngx_string("so_keepalive"),
139 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, 49 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
140 ngx_conf_set_flag_slot, 50 ngx_conf_set_flag_slot,
147 ngx_conf_set_msec_slot, 57 ngx_conf_set_msec_slot,
148 NGX_MAIL_SRV_CONF_OFFSET, 58 NGX_MAIL_SRV_CONF_OFFSET,
149 offsetof(ngx_mail_core_srv_conf_t, timeout), 59 offsetof(ngx_mail_core_srv_conf_t, timeout),
150 NULL }, 60 NULL },
151 61
152 { ngx_string("pop3_capabilities"),
153 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
154 ngx_mail_core_capability,
155 NGX_MAIL_SRV_CONF_OFFSET,
156 offsetof(ngx_mail_core_srv_conf_t, pop3_capabilities),
157 NULL },
158
159 { ngx_string("imap_capabilities"),
160 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
161 ngx_mail_core_capability,
162 NGX_MAIL_SRV_CONF_OFFSET,
163 offsetof(ngx_mail_core_srv_conf_t, imap_capabilities),
164 NULL },
165
166 { ngx_string("smtp_capabilities"),
167 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
168 ngx_mail_core_capability,
169 NGX_MAIL_SRV_CONF_OFFSET,
170 offsetof(ngx_mail_core_srv_conf_t, smtp_capabilities),
171 NULL },
172
173 { ngx_string("server_name"), 62 { ngx_string("server_name"),
174 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, 63 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
175 ngx_conf_set_str_slot, 64 ngx_conf_set_str_slot,
176 NGX_MAIL_SRV_CONF_OFFSET, 65 NGX_MAIL_SRV_CONF_OFFSET,
177 offsetof(ngx_mail_core_srv_conf_t, server_name), 66 offsetof(ngx_mail_core_srv_conf_t, server_name),
178 NULL }, 67 NULL },
179 68
180 { ngx_string("auth"),
181 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
182 ngx_conf_set_bitmask_slot,
183 NGX_MAIL_SRV_CONF_OFFSET,
184 offsetof(ngx_mail_core_srv_conf_t, pop3_auth_methods),
185 &ngx_pop3_auth_methods },
186
187 { ngx_string("pop3_auth"),
188 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
189 ngx_conf_set_bitmask_slot,
190 NGX_MAIL_SRV_CONF_OFFSET,
191 offsetof(ngx_mail_core_srv_conf_t, pop3_auth_methods),
192 &ngx_pop3_auth_methods },
193
194 { ngx_string("imap_auth"),
195 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
196 ngx_conf_set_bitmask_slot,
197 NGX_MAIL_SRV_CONF_OFFSET,
198 offsetof(ngx_mail_core_srv_conf_t, imap_auth_methods),
199 &ngx_imap_auth_methods },
200
201 { ngx_string("smtp_auth"),
202 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
203 ngx_conf_set_bitmask_slot,
204 NGX_MAIL_SRV_CONF_OFFSET,
205 offsetof(ngx_mail_core_srv_conf_t, smtp_auth_methods),
206 &ngx_smtp_auth_methods },
207
208 ngx_null_command 69 ngx_null_command
209 }; 70 };
210 71
211 72
212 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
213 ngx_mail_core_create_main_conf, /* create main configuration */ 76 ngx_mail_core_create_main_conf, /* create main configuration */
214 NULL, /* init main configuration */ 77 NULL, /* init main configuration */
215 78
216 ngx_mail_core_create_srv_conf, /* create server configuration */ 79 ngx_mail_core_create_srv_conf, /* create server configuration */
217 ngx_mail_core_merge_srv_conf /* merge server configuration */ 80 ngx_mail_core_merge_srv_conf /* merge server configuration */
269 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));
270 if (cscf == NULL) { 133 if (cscf == NULL) {
271 return NULL; 134 return NULL;
272 } 135 }
273 136
274 cscf->imap_client_buffer_size = NGX_CONF_UNSET_SIZE; 137 /*
275 cscf->protocol = NGX_CONF_UNSET_UINT; 138 * set by ngx_pcalloc():
139 *
140 * cscf->protocol = NULL;
141 */
142
276 cscf->timeout = NGX_CONF_UNSET_MSEC; 143 cscf->timeout = NGX_CONF_UNSET_MSEC;
277 cscf->so_keepalive = NGX_CONF_UNSET; 144 cscf->so_keepalive = NGX_CONF_UNSET;
278 145
279 if (ngx_array_init(&cscf->pop3_capabilities, cf->pool, 4, sizeof(ngx_str_t))
280 != NGX_OK)
281 {
282 return NULL;
283 }
284
285 if (ngx_array_init(&cscf->imap_capabilities, cf->pool, 4, sizeof(ngx_str_t))
286 != NGX_OK)
287 {
288 return NULL;
289 }
290
291 if (ngx_array_init(&cscf->smtp_capabilities, cf->pool, 4, sizeof(ngx_str_t))
292 != NGX_OK)
293 {
294 return NULL;
295 }
296
297 return cscf; 146 return cscf;
298 } 147 }
299 148
300 149
301 static char * 150 static char *
302 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)
303 { 152 {
304 ngx_mail_core_srv_conf_t *prev = parent; 153 ngx_mail_core_srv_conf_t *prev = parent;
305 ngx_mail_core_srv_conf_t *conf = child; 154 ngx_mail_core_srv_conf_t *conf = child;
306 155
307 u_char *p, *auth, *last;
308 size_t size, stls_only_size;
309 ngx_str_t *c, *d;
310 ngx_uint_t i, m, smtp_auth_enabled;
311
312 ngx_conf_merge_size_value(conf->imap_client_buffer_size,
313 prev->imap_client_buffer_size,
314 (size_t) ngx_pagesize);
315 ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000); 156 ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000);
316 ngx_conf_merge_uint_value(conf->protocol, prev->protocol, 157
317 NGX_MAIL_IMAP_PROTOCOL);
318 ngx_conf_merge_value(conf->so_keepalive, prev->so_keepalive, 0); 158 ngx_conf_merge_value(conf->so_keepalive, prev->so_keepalive, 0);
319
320
321 ngx_conf_merge_bitmask_value(conf->pop3_auth_methods,
322 prev->pop3_auth_methods,
323 (NGX_CONF_BITMASK_SET
324 |NGX_MAIL_AUTH_PLAIN_ENABLED));
325
326 ngx_conf_merge_bitmask_value(conf->imap_auth_methods,
327 prev->imap_auth_methods,
328 (NGX_CONF_BITMASK_SET
329 |NGX_MAIL_AUTH_PLAIN_ENABLED));
330
331 ngx_conf_merge_bitmask_value(conf->smtp_auth_methods,
332 prev->smtp_auth_methods,
333 (NGX_CONF_BITMASK_SET
334 |NGX_MAIL_AUTH_PLAIN_ENABLED
335 |NGX_MAIL_AUTH_LOGIN_ENABLED));
336 159
337 160
338 ngx_conf_merge_str_value(conf->server_name, prev->server_name, ""); 161 ngx_conf_merge_str_value(conf->server_name, prev->server_name, "");
339 162
340 if (conf->server_name.len == 0) { 163 if (conf->server_name.len == 0) {
344 } 167 }
345 168
346 if (gethostname((char *) conf->server_name.data, NGX_MAXHOSTNAMELEN) 169 if (gethostname((char *) conf->server_name.data, NGX_MAXHOSTNAMELEN)
347 == -1) 170 == -1)
348 { 171 {
349 ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno, 172 ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
350 "gethostname() failed"); 173 "gethostname() failed");
351 return NGX_CONF_ERROR; 174 return NGX_CONF_ERROR;
352 } 175 }
353 176
354 conf->server_name.len = ngx_strlen(conf->server_name.data); 177 conf->server_name.len = ngx_strlen(conf->server_name.data);
355 } 178 }
356 179
357 180 if (conf->protocol == NULL) {
358 if (conf->pop3_capabilities.nelts == 0) { 181 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
359 conf->pop3_capabilities = prev->pop3_capabilities; 182 "unknown mail protocol for server in %s:%ui",
360 } 183 conf->file_name, conf->line);
361 184 return NGX_CONF_ERROR;
362 if (conf->pop3_capabilities.nelts == 0) {
363
364 for (d = ngx_pop3_default_capabilities; d->len; d++) {
365 c = ngx_array_push(&conf->pop3_capabilities);
366 if (c == NULL) {
367 return NGX_CONF_ERROR;
368 }
369
370 *c = *d;
371 }
372 }
373
374 size = sizeof("+OK Capability list follows" CRLF) - 1
375 + sizeof("." CRLF) - 1;
376
377 stls_only_size = size + sizeof("STLS" CRLF) - 1;
378
379 c = conf->pop3_capabilities.elts;
380 for (i = 0; i < conf->pop3_capabilities.nelts; i++) {
381 size += c[i].len + sizeof(CRLF) - 1;
382
383 if (ngx_strcasecmp(c[i].data, (u_char *) "USER") == 0) {
384 continue;
385 }
386
387 stls_only_size += c[i].len + sizeof(CRLF) - 1;
388 }
389
390 if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
391 size += sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1;
392
393 } else {
394 size += sizeof("SASL LOGIN PLAIN" CRLF) - 1;
395 }
396
397 p = ngx_palloc(cf->pool, size);
398 if (p == NULL) {
399 return NGX_CONF_ERROR;
400 }
401
402 conf->pop3_capability.len = size;
403 conf->pop3_capability.data = p;
404
405 p = ngx_cpymem(p, "+OK Capability list follows" CRLF,
406 sizeof("+OK Capability list follows" CRLF) - 1);
407
408 for (i = 0; i < conf->pop3_capabilities.nelts; i++) {
409 p = ngx_cpymem(p, c[i].data, c[i].len);
410 *p++ = CR; *p++ = LF;
411 }
412
413 if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
414 p = ngx_cpymem(p, "SASL LOGIN PLAIN CRAM-MD5" CRLF,
415 sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1);
416
417 } else {
418 p = ngx_cpymem(p, "SASL LOGIN PLAIN" CRLF,
419 sizeof("SASL LOGIN PLAIN" CRLF) - 1);
420 }
421
422 *p++ = '.'; *p++ = CR; *p = LF;
423
424
425 size += sizeof("STLS" CRLF) - 1;
426
427 p = ngx_palloc(cf->pool, size);
428 if (p == NULL) {
429 return NGX_CONF_ERROR;
430 }
431
432 conf->pop3_starttls_capability.len = size;
433 conf->pop3_starttls_capability.data = p;
434
435 p = ngx_cpymem(p, conf->pop3_capability.data,
436 conf->pop3_capability.len - (sizeof("." CRLF) - 1));
437
438 p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1);
439 *p++ = '.'; *p++ = CR; *p = LF;
440
441
442 if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
443 conf->pop3_auth_capability = ngx_pop3_auth_cram_md5_capability;
444
445 } else {
446 conf->pop3_auth_capability = ngx_pop3_auth_plain_capability;
447 }
448
449
450 p = ngx_palloc(cf->pool, stls_only_size);
451 if (p == NULL) {
452 return NGX_CONF_ERROR;
453 }
454
455 conf->pop3_starttls_only_capability.len = stls_only_size;
456 conf->pop3_starttls_only_capability.data = p;
457
458 p = ngx_cpymem(p, "+OK Capability list follows" CRLF,
459 sizeof("+OK Capability list follows" CRLF) - 1);
460
461 for (i = 0; i < conf->pop3_capabilities.nelts; i++) {
462 if (ngx_strcasecmp(c[i].data, (u_char *) "USER") == 0) {
463 continue;
464 }
465
466 p = ngx_cpymem(p, c[i].data, c[i].len);
467 *p++ = CR; *p++ = LF;
468 }
469
470 p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1);
471 *p++ = '.'; *p++ = CR; *p = LF;
472
473
474 if (conf->imap_capabilities.nelts == 0) {
475 conf->imap_capabilities = prev->imap_capabilities;
476 }
477
478 if (conf->imap_capabilities.nelts == 0) {
479
480 for (d = ngx_imap_default_capabilities; d->len; d++) {
481 c = ngx_array_push(&conf->imap_capabilities);
482 if (c == NULL) {
483 return NGX_CONF_ERROR;
484 }
485
486 *c = *d;
487 }
488 }
489
490 size = sizeof("* CAPABILITY" CRLF) - 1;
491
492 c = conf->imap_capabilities.elts;
493 for (i = 0; i < conf->imap_capabilities.nelts; i++) {
494 size += 1 + c[i].len;
495 }
496
497 for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
498 m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
499 m <<= 1, i++)
500 {
501 if (m & conf->imap_auth_methods) {
502 size += 1 + ngx_imap_auth_methods_names[i].len;
503 }
504 }
505
506 p = ngx_palloc(cf->pool, size);
507 if (p == NULL) {
508 return NGX_CONF_ERROR;
509 }
510
511 conf->imap_capability.len = size;
512 conf->imap_capability.data = p;
513
514 p = ngx_cpymem(p, "* CAPABILITY", sizeof("* CAPABILITY") - 1);
515
516 for (i = 0; i < conf->imap_capabilities.nelts; i++) {
517 *p++ = ' ';
518 p = ngx_cpymem(p, c[i].data, c[i].len);
519 }
520
521 auth = p;
522
523 for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
524 m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
525 m <<= 1, i++)
526 {
527 if (m & conf->imap_auth_methods) {
528 *p++ = ' ';
529 p = ngx_cpymem(p, ngx_imap_auth_methods_names[i].data,
530 ngx_imap_auth_methods_names[i].len);
531 }
532 }
533
534 *p++ = CR; *p = LF;
535
536
537 size += sizeof(" STARTTLS") - 1;
538
539 p = ngx_palloc(cf->pool, size);
540 if (p == NULL) {
541 return NGX_CONF_ERROR;
542 }
543
544 conf->imap_starttls_capability.len = size;
545 conf->imap_starttls_capability.data = p;
546
547 p = ngx_cpymem(p, conf->imap_capability.data,
548 conf->imap_capability.len - (sizeof(CRLF) - 1));
549 p = ngx_cpymem(p, " STARTTLS", sizeof(" STARTTLS") - 1);
550 *p++ = CR; *p = LF;
551
552
553 size = (auth - conf->imap_capability.data) + sizeof(CRLF) - 1
554 + sizeof(" STARTTLS LOGINDISABLED") - 1;
555
556 p = ngx_palloc(cf->pool, size);
557 if (p == NULL) {
558 return NGX_CONF_ERROR;
559 }
560
561 conf->imap_starttls_only_capability.len = size;
562 conf->imap_starttls_only_capability.data = p;
563
564 p = ngx_cpymem(p, conf->imap_capability.data,
565 auth - conf->imap_capability.data);
566 p = ngx_cpymem(p, " STARTTLS LOGINDISABLED",
567 sizeof(" STARTTLS LOGINDISABLED") - 1);
568 *p++ = CR; *p = LF;
569
570
571 size = sizeof("220 ESMTP ready" CRLF) - 1 + conf->server_name.len;
572
573 p = ngx_palloc(cf->pool, size);
574 if (p == NULL) {
575 return NGX_CONF_ERROR;
576 }
577
578 conf->smtp_greeting.len = size;
579 conf->smtp_greeting.data = p;
580
581 *p++ = '2'; *p++ = '2'; *p++ = '0'; *p++ = ' ';
582 p = ngx_cpymem(p, conf->server_name.data, conf->server_name.len);
583 ngx_memcpy(p, " ESMTP ready" CRLF, sizeof(" ESMTP ready" CRLF) - 1);
584
585
586 size = sizeof("250 " CRLF) - 1 + conf->server_name.len;
587
588 p = ngx_palloc(cf->pool, size);
589 if (p == NULL) {
590 return NGX_CONF_ERROR;
591 }
592
593 conf->smtp_server_name.len = size;
594 conf->smtp_server_name.data = p;
595
596 *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = ' ';
597 p = ngx_cpymem(p, conf->server_name.data, conf->server_name.len);
598 *p++ = CR; *p = LF;
599
600
601 if (conf->smtp_capabilities.nelts == 0) {
602 conf->smtp_capabilities = prev->smtp_capabilities;
603 }
604
605 size = sizeof("250-") - 1 + conf->server_name.len + sizeof(CRLF) - 1;
606
607 c = conf->smtp_capabilities.elts;
608 for (i = 0; i < conf->smtp_capabilities.nelts; i++) {
609 size += sizeof("250 ") - 1 + c[i].len + sizeof(CRLF) - 1;
610 }
611
612 smtp_auth_enabled = 0;
613 for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
614 m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
615 m <<= 1, i++)
616 {
617 if (m & conf->smtp_auth_methods) {
618 size += 1 + ngx_smtp_auth_methods_names[i].len;
619 smtp_auth_enabled = 1;
620 }
621 }
622
623 if (smtp_auth_enabled) {
624 size += sizeof("250 AUTH") - 1 + sizeof(CRLF) - 1;
625 }
626
627 p = ngx_palloc(cf->pool, size);
628 if (p == NULL) {
629 return NGX_CONF_ERROR;
630 }
631
632 conf->smtp_capability.len = size;
633 conf->smtp_capability.data = p;
634
635 last = p;
636 *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = '-';
637 p = ngx_cpymem(p, conf->server_name.data, conf->server_name.len);
638 *p++ = CR; *p++ = LF;
639
640 for (i = 0; i < conf->smtp_capabilities.nelts; i++) {
641 last = p;
642 *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = '-';
643 p = ngx_cpymem(p, c[i].data, c[i].len);
644 *p++ = CR; *p++ = LF;
645 }
646
647 auth = p;
648
649 if (smtp_auth_enabled) {
650 last = p;
651
652 *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = ' ';
653 *p++ = 'A'; *p++ = 'U'; *p++ = 'T'; *p++ = 'H';
654
655 for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
656 m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
657 m <<= 1, i++)
658 {
659 if (m & conf->smtp_auth_methods) {
660 *p++ = ' ';
661 p = ngx_cpymem(p, ngx_smtp_auth_methods_names[i].data,
662 ngx_smtp_auth_methods_names[i].len);
663 }
664 }
665
666 *p++ = CR; *p = LF;
667
668 } else {
669 last[3] = ' ';
670 }
671
672 size += sizeof("250 STARTTLS" CRLF) - 1;
673
674 p = ngx_palloc(cf->pool, size);
675 if (p == NULL) {
676 return NGX_CONF_ERROR;
677 }
678
679 conf->smtp_starttls_capability.len = size;
680 conf->smtp_starttls_capability.data = p;
681
682 p = ngx_cpymem(p, conf->smtp_capability.data,
683 conf->smtp_capability.len);
684
685 p = ngx_cpymem(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1);
686 *p++ = CR; *p = LF;
687
688 p = conf->smtp_starttls_capability.data
689 + (last - conf->smtp_capability.data) + 3;
690 *p = '-';
691
692 size = (auth - conf->smtp_capability.data)
693 + sizeof("250 STARTTLS" CRLF) - 1;
694
695 p = ngx_palloc(cf->pool, size);
696 if (p == NULL) {
697 return NGX_CONF_ERROR;
698 }
699
700 conf->smtp_starttls_only_capability.len = size;
701 conf->smtp_starttls_only_capability.data = p;
702
703 p = ngx_cpymem(p, conf->smtp_capability.data,
704 auth - conf->smtp_capability.data);
705
706 ngx_memcpy(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1);
707
708 if (last < auth) {
709 p = conf->smtp_starttls_only_capability.data
710 + (last - conf->smtp_capability.data) + 3;
711 *p = '-';
712 } 185 }
713 186
714 return NGX_CONF_OK; 187 return NGX_CONF_OK;
715 } 188 }
716 189
725 ngx_mail_module_t *module; 198 ngx_mail_module_t *module;
726 ngx_mail_conf_ctx_t *ctx, *mail_ctx; 199 ngx_mail_conf_ctx_t *ctx, *mail_ctx;
727 ngx_mail_core_srv_conf_t *cscf, **cscfp; 200 ngx_mail_core_srv_conf_t *cscf, **cscfp;
728 ngx_mail_core_main_conf_t *cmcf; 201 ngx_mail_core_main_conf_t *cmcf;
729 202
730
731 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_mail_conf_ctx_t)); 203 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_mail_conf_ctx_t));
732 if (ctx == NULL) { 204 if (ctx == NULL) {
733 return NGX_CONF_ERROR; 205 return NGX_CONF_ERROR;
734 } 206 }
735 207
763 /* the server configuration context */ 235 /* the server configuration context */
764 236
765 cscf = ctx->srv_conf[ngx_mail_core_module.ctx_index]; 237 cscf = ctx->srv_conf[ngx_mail_core_module.ctx_index];
766 cscf->ctx = ctx; 238 cscf->ctx = ctx;
767 239
240 cscf->file_name = cf->conf_file->file.name.data;
241 cscf->line = cf->conf_file->line;
242
768 cmcf = ctx->main_conf[ngx_mail_core_module.ctx_index]; 243 cmcf = ctx->main_conf[ngx_mail_core_module.ctx_index];
769 244
770 cscfp = ngx_array_push(&cmcf->servers); 245 cscfp = ngx_array_push(&cmcf->servers);
771 if (cscfp == NULL) { 246 if (cscfp == NULL) {
772 return NGX_CONF_ERROR; 247 return NGX_CONF_ERROR;
792 /* AF_INET only */ 267 /* AF_INET only */
793 268
794 static char * 269 static char *
795 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)
796 { 271 {
272 ngx_mail_core_srv_conf_t *cscf = conf;
273
797 ngx_str_t *value; 274 ngx_str_t *value;
798 ngx_url_t u; 275 ngx_url_t u;
799 ngx_uint_t i; 276 ngx_uint_t i, m;
800 ngx_mail_listen_t *imls; 277 ngx_mail_listen_t *imls;
278 ngx_mail_module_t *module;
801 ngx_mail_core_main_conf_t *cmcf; 279 ngx_mail_core_main_conf_t *cmcf;
802 280
803 value = cf->args->elts; 281 value = cf->args->elts;
804 282
805 ngx_memzero(&u, sizeof(ngx_url_t)); 283 ngx_memzero(&u, sizeof(ngx_url_t));
842 imls->addr = u.addr.in_addr; 320 imls->addr = u.addr.in_addr;
843 imls->port = u.port; 321 imls->port = u.port;
844 imls->family = AF_INET; 322 imls->family = AF_INET;
845 imls->ctx = cf->ctx; 323 imls->ctx = cf->ctx;
846 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
847 if (cf->args->nelts == 2) { 344 if (cf->args->nelts == 2) {
848 return NGX_CONF_OK; 345 return NGX_CONF_OK;
849 } 346 }
850 347
851 if (ngx_strcmp(value[2].data, "bind") == 0) { 348 if (ngx_strcmp(value[2].data, "bind") == 0) {
858 return NGX_CONF_ERROR; 355 return NGX_CONF_ERROR;
859 } 356 }
860 357
861 358
862 static char * 359 static char *
863 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)
864 { 394 {
865 char *p = conf; 395 char *p = conf;
866 396
867 ngx_str_t *c, *value; 397 ngx_str_t *c, *value;
868 ngx_uint_t i; 398 ngx_uint_t i;