comparison src/mail/ngx_mail_core_module.c @ 1487:f69493e8faab

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