Mercurial > hg > nginx-quic
annotate src/mail/ngx_mail_core_module.c @ 1458:614090b26fbf
test the most relevant condition first
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 03 Sep 2007 09:06:26 +0000 |
parents | c4b2c893989d |
children | b58ce1cf66da ed9cd1702f7a |
rev | line source |
---|---|
521 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_event.h> | |
1136 | 10 #include <ngx_mail.h> |
521 | 11 |
12 | |
1136 | 13 static void *ngx_mail_core_create_main_conf(ngx_conf_t *cf); |
14 static void *ngx_mail_core_create_srv_conf(ngx_conf_t *cf); | |
15 static char *ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, | |
521 | 16 void *child); |
1136 | 17 static char *ngx_mail_core_server(ngx_conf_t *cf, ngx_command_t *cmd, |
521 | 18 void *conf); |
1136 | 19 static char *ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, |
521 | 20 void *conf); |
1136 | 21 static char *ngx_mail_core_capability(ngx_conf_t *cf, ngx_command_t *cmd, |
527 | 22 void *conf); |
521 | 23 |
24 | |
1136 | 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 }, | |
521 | 29 { ngx_null_string, 0 } |
30 }; | |
31 | |
32 | |
527 | 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 | |
1136 | 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 }, | |
800 | 53 { ngx_null_string, 0 } |
54 }; | |
55 | |
56 | |
1323 | 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 | |
1136 | 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 | |
1323 | 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 | |
1136 | 81 static ngx_str_t ngx_smtp_auth_methods_names[] = { |
1174
6be5ee17d80b
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
1136
diff
changeset
|
82 ngx_string("PLAIN"), |
1136 | 83 ngx_string("LOGIN"), |
84 ngx_null_string, /* APOP */ | |
85 ngx_string("CRAM-MD5") | |
86 }; | |
87 | |
88 | |
809 | 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 | |
104 | |
1136 | 105 static ngx_command_t ngx_mail_core_commands[] = { |
521 | 106 |
107 { ngx_string("server"), | |
1136 | 108 NGX_MAIL_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, |
109 ngx_mail_core_server, | |
521 | 110 0, |
111 0, | |
112 NULL }, | |
113 | |
114 { ngx_string("listen"), | |
1136 | 115 NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12, |
116 ngx_mail_core_listen, | |
521 | 117 0, |
118 0, | |
119 NULL }, | |
120 | |
121 { ngx_string("protocol"), | |
1136 | 122 NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, |
521 | 123 ngx_conf_set_enum_slot, |
1136 | 124 NGX_MAIL_SRV_CONF_OFFSET, |
125 offsetof(ngx_mail_core_srv_conf_t, protocol), | |
126 &ngx_mail_core_procotol }, | |
521 | 127 |
128 { ngx_string("imap_client_buffer"), | |
1136 | 129 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, |
521 | 130 ngx_conf_set_size_slot, |
1136 | 131 NGX_MAIL_SRV_CONF_OFFSET, |
132 offsetof(ngx_mail_core_srv_conf_t, imap_client_buffer_size), | |
521 | 133 NULL }, |
134 | |
587 | 135 { ngx_string("so_keepalive"), |
1136 | 136 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, |
587 | 137 ngx_conf_set_flag_slot, |
1136 | 138 NGX_MAIL_SRV_CONF_OFFSET, |
139 offsetof(ngx_mail_core_srv_conf_t, so_keepalive), | |
587 | 140 NULL }, |
141 | |
521 | 142 { ngx_string("timeout"), |
1136 | 143 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, |
521 | 144 ngx_conf_set_msec_slot, |
1136 | 145 NGX_MAIL_SRV_CONF_OFFSET, |
146 offsetof(ngx_mail_core_srv_conf_t, timeout), | |
521 | 147 NULL }, |
148 | |
527 | 149 { ngx_string("pop3_capabilities"), |
1136 | 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), | |
527 | 154 NULL }, |
155 | |
156 { ngx_string("imap_capabilities"), | |
1136 | 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), | |
527 | 168 NULL }, |
169 | |
800 | 170 { ngx_string("server_name"), |
1136 | 171 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, |
800 | 172 ngx_conf_set_str_slot, |
1136 | 173 NGX_MAIL_SRV_CONF_OFFSET, |
174 offsetof(ngx_mail_core_srv_conf_t, server_name), | |
800 | 175 NULL }, |
176 | |
177 { ngx_string("auth"), | |
1136 | 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, | |
800 | 186 ngx_conf_set_bitmask_slot, |
1136 | 187 NGX_MAIL_SRV_CONF_OFFSET, |
188 offsetof(ngx_mail_core_srv_conf_t, pop3_auth_methods), | |
189 &ngx_pop3_auth_methods }, | |
190 | |
1323 | 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 | |
1136 | 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 }, | |
800 | 204 |
521 | 205 ngx_null_command |
206 }; | |
207 | |
208 | |
1136 | 209 static ngx_mail_module_t ngx_mail_core_module_ctx = { |
210 ngx_mail_core_create_main_conf, /* create main configuration */ | |
521 | 211 NULL, /* init main configuration */ |
212 | |
1136 | 213 ngx_mail_core_create_srv_conf, /* create server configuration */ |
214 ngx_mail_core_merge_srv_conf /* merge server configuration */ | |
521 | 215 }; |
216 | |
217 | |
1136 | 218 ngx_module_t ngx_mail_core_module = { |
521 | 219 NGX_MODULE_V1, |
1136 | 220 &ngx_mail_core_module_ctx, /* module context */ |
221 ngx_mail_core_commands, /* module directives */ | |
222 NGX_MAIL_MODULE, /* module type */ | |
541 | 223 NULL, /* init master */ |
521 | 224 NULL, /* init module */ |
541 | 225 NULL, /* init process */ |
226 NULL, /* init thread */ | |
227 NULL, /* exit thread */ | |
228 NULL, /* exit process */ | |
229 NULL, /* exit master */ | |
230 NGX_MODULE_V1_PADDING | |
521 | 231 }; |
232 | |
233 | |
234 static void * | |
1136 | 235 ngx_mail_core_create_main_conf(ngx_conf_t *cf) |
577 | 236 { |
1136 | 237 ngx_mail_core_main_conf_t *cmcf; |
521 | 238 |
1136 | 239 cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_main_conf_t)); |
521 | 240 if (cmcf == NULL) { |
241 return NGX_CONF_ERROR; | |
242 } | |
243 | |
244 if (ngx_array_init(&cmcf->servers, cf->pool, 4, | |
1136 | 245 sizeof(ngx_mail_core_srv_conf_t *)) |
641 | 246 != NGX_OK) |
247 { | |
248 return NGX_CONF_ERROR; | |
249 } | |
250 | |
1136 | 251 if (ngx_array_init(&cmcf->listen, cf->pool, 4, sizeof(ngx_mail_listen_t)) |
641 | 252 != NGX_OK) |
521 | 253 { |
254 return NGX_CONF_ERROR; | |
255 } | |
256 | |
257 return cmcf; | |
258 } | |
259 | |
260 | |
261 static void * | |
1136 | 262 ngx_mail_core_create_srv_conf(ngx_conf_t *cf) |
577 | 263 { |
1136 | 264 ngx_mail_core_srv_conf_t *cscf; |
577 | 265 |
1136 | 266 cscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_srv_conf_t)); |
521 | 267 if (cscf == NULL) { |
527 | 268 return NULL; |
521 | 269 } |
270 | |
271 cscf->imap_client_buffer_size = NGX_CONF_UNSET_SIZE; | |
587 | 272 cscf->protocol = NGX_CONF_UNSET_UINT; |
521 | 273 cscf->timeout = NGX_CONF_UNSET_MSEC; |
587 | 274 cscf->so_keepalive = NGX_CONF_UNSET; |
521 | 275 |
527 | 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 | |
1136 | 288 if (ngx_array_init(&cscf->smtp_capabilities, cf->pool, 4, sizeof(ngx_str_t)) |
289 != NGX_OK) | |
290 { | |
291 return NULL; | |
292 } | |
293 | |
521 | 294 return cscf; |
295 } | |
296 | |
297 | |
298 static char * | |
1136 | 299 ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) |
521 | 300 { |
1136 | 301 ngx_mail_core_srv_conf_t *prev = parent; |
302 ngx_mail_core_srv_conf_t *conf = child; | |
521 | 303 |
1322 | 304 u_char *p, *auth; |
1136 | 305 size_t size, stls_only_size; |
527 | 306 ngx_str_t *c, *d; |
1136 | 307 ngx_uint_t i, m; |
527 | 308 |
521 | 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); | |
663 | 313 ngx_conf_merge_uint_value(conf->protocol, prev->protocol, |
1136 | 314 NGX_MAIL_IMAP_PROTOCOL); |
587 | 315 ngx_conf_merge_value(conf->so_keepalive, prev->so_keepalive, 0); |
521 | 316 |
527 | 317 |
1136 | 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 | |
1323 | 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 | |
1136 | 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)); | |
800 | 333 |
334 | |
335 ngx_conf_merge_str_value(conf->server_name, prev->server_name, ""); | |
336 | |
337 if (conf->server_name.len == 0) { | |
338 conf->server_name.data = ngx_palloc(cf->pool, NGX_MAXHOSTNAMELEN); | |
339 if (conf->server_name.data == NULL) { | |
340 return NGX_CONF_ERROR; | |
341 } | |
342 | |
343 if (gethostname((char *) conf->server_name.data, NGX_MAXHOSTNAMELEN) | |
344 == -1) | |
345 { | |
346 ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno, | |
347 "gethostname() failed"); | |
348 return NGX_CONF_ERROR; | |
349 } | |
350 | |
351 conf->server_name.len = ngx_strlen(conf->server_name.data); | |
352 } | |
353 | |
354 | |
527 | 355 if (conf->pop3_capabilities.nelts == 0) { |
356 conf->pop3_capabilities = prev->pop3_capabilities; | |
357 } | |
358 | |
359 if (conf->pop3_capabilities.nelts == 0) { | |
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 | |
1136 | 374 stls_only_size = size + sizeof("STLS" CRLF) - 1; |
375 | |
527 | 376 c = conf->pop3_capabilities.elts; |
377 for (i = 0; i < conf->pop3_capabilities.nelts; i++) { | |
378 size += c[i].len + sizeof(CRLF) - 1; | |
1136 | 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; | |
527 | 385 } |
386 | |
1136 | 387 if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { |
809 | 388 size += sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1; |
389 | |
390 } else { | |
391 size += sizeof("SASL LOGIN PLAIN" CRLF) - 1; | |
392 } | |
393 | |
583 | 394 p = ngx_palloc(cf->pool, size); |
395 if (p == NULL) { | |
527 | 396 return NGX_CONF_ERROR; |
397 } | |
398 | |
583 | 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); | |
527 | 404 |
405 for (i = 0; i < conf->pop3_capabilities.nelts; i++) { | |
583 | 406 p = ngx_cpymem(p, c[i].data, c[i].len); |
407 *p++ = CR; *p++ = LF; | |
527 | 408 } |
409 | |
1136 | 410 if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { |
809 | 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 | |
583 | 419 *p++ = '.'; *p++ = CR; *p = LF; |
420 | |
421 | |
422 size += sizeof("STLS" CRLF) - 1; | |
527 | 423 |
583 | 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; | |
527 | 437 |
438 | |
1136 | 439 if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { |
809 | 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 | |
1136 | 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 | |
527 | 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 | |
1136 | 487 size = sizeof("* CAPABILITY" CRLF) - 1; |
527 | 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 | |
1323 | 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 | |
583 | 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 | |
1323 | 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 | |
583 | 531 *p++ = CR; *p = LF; |
532 | |
533 | |
534 size += sizeof(" STARTTLS") - 1; | |
535 | |
536 p = ngx_palloc(cf->pool, size); | |
537 if (p == NULL) { | |
527 | 538 return NGX_CONF_ERROR; |
539 } | |
540 | |
583 | 541 conf->imap_starttls_capability.len = size; |
542 conf->imap_starttls_capability.data = p; | |
527 | 543 |
583 | 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 | |
1323 | 550 size = (auth - conf->imap_capability.data) + sizeof(CRLF) - 1 |
551 + sizeof(" STARTTLS LOGINDISABLED") - 1; | |
583 | 552 |
553 p = ngx_palloc(cf->pool, size); | |
554 if (p == NULL) { | |
555 return NGX_CONF_ERROR; | |
527 | 556 } |
557 | |
583 | 558 conf->imap_starttls_only_capability.len = size; |
559 conf->imap_starttls_only_capability.data = p; | |
527 | 560 |
1323 | 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); | |
583 | 565 *p++ = CR; *p = LF; |
566 | |
527 | 567 |
1136 | 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 | |
1322 | 637 auth = p; |
638 | |
1136 | 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 | |
1322 | 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 | |
521 | 691 return NGX_CONF_OK; |
692 } | |
693 | |
694 | |
695 static char * | |
1136 | 696 ngx_mail_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
521 | 697 { |
698 char *rv; | |
699 void *mconf; | |
700 ngx_uint_t m; | |
701 ngx_conf_t pcf; | |
1136 | 702 ngx_mail_module_t *module; |
703 ngx_mail_conf_ctx_t *ctx, *mail_ctx; | |
704 ngx_mail_core_srv_conf_t *cscf, **cscfp; | |
705 ngx_mail_core_main_conf_t *cmcf; | |
521 | 706 |
707 | |
1136 | 708 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_mail_conf_ctx_t)); |
521 | 709 if (ctx == NULL) { |
710 return NGX_CONF_ERROR; | |
711 } | |
712 | |
1136 | 713 mail_ctx = cf->ctx; |
714 ctx->main_conf = mail_ctx->main_conf; | |
577 | 715 |
521 | 716 /* the server{}'s srv_conf */ |
717 | |
1136 | 718 ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_mail_max_module); |
521 | 719 if (ctx->srv_conf == NULL) { |
720 return NGX_CONF_ERROR; | |
721 } | |
722 | |
723 for (m = 0; ngx_modules[m]; m++) { | |
1136 | 724 if (ngx_modules[m]->type != NGX_MAIL_MODULE) { |
521 | 725 continue; |
726 } | |
727 | |
728 module = ngx_modules[m]->ctx; | |
729 | |
730 if (module->create_srv_conf) { | |
731 mconf = module->create_srv_conf(cf); | |
732 if (mconf == NULL) { | |
733 return NGX_CONF_ERROR; | |
734 } | |
735 | |
736 ctx->srv_conf[ngx_modules[m]->ctx_index] = mconf; | |
737 } | |
738 } | |
739 | |
740 /* the server configuration context */ | |
741 | |
1136 | 742 cscf = ctx->srv_conf[ngx_mail_core_module.ctx_index]; |
521 | 743 cscf->ctx = ctx; |
744 | |
1136 | 745 cmcf = ctx->main_conf[ngx_mail_core_module.ctx_index]; |
521 | 746 |
747 cscfp = ngx_array_push(&cmcf->servers); | |
748 if (cscfp == NULL) { | |
749 return NGX_CONF_ERROR; | |
750 } | |
751 | |
752 *cscfp = cscf; | |
753 | |
754 | |
755 /* parse inside server{} */ | |
756 | |
757 pcf = *cf; | |
758 cf->ctx = ctx; | |
1136 | 759 cf->cmd_type = NGX_MAIL_SRV_CONF; |
521 | 760 |
761 rv = ngx_conf_parse(cf, NULL); | |
762 | |
763 *cf = pcf; | |
764 | |
765 return rv; | |
766 } | |
767 | |
768 | |
769 /* AF_INET only */ | |
770 | |
771 static char * | |
1136 | 772 ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
521 | 773 { |
641 | 774 ngx_str_t *value; |
804
472cd9768ac2
now the "listen" directives use ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
775 ngx_url_t u; |
641 | 776 ngx_uint_t i; |
1136 | 777 ngx_mail_listen_t *imls; |
778 ngx_mail_core_main_conf_t *cmcf; | |
521 | 779 |
780 value = cf->args->elts; | |
781 | |
804
472cd9768ac2
now the "listen" directives use ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
782 ngx_memzero(&u, sizeof(ngx_url_t)); |
521 | 783 |
804
472cd9768ac2
now the "listen" directives use ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
784 u.url = value[1]; |
472cd9768ac2
now the "listen" directives use ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
785 u.listen = 1; |
619 | 786 |
804
472cd9768ac2
now the "listen" directives use ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
787 if (ngx_parse_url(cf, &u) != NGX_OK) { |
472cd9768ac2
now the "listen" directives use ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
788 if (u.err) { |
472cd9768ac2
now the "listen" directives use ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
789 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
472cd9768ac2
now the "listen" directives use ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
790 "%s in \"%V\" of the \"listen\" directive", |
472cd9768ac2
now the "listen" directives use ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
791 u.err, &u.url); |
521 | 792 } |
793 | |
804
472cd9768ac2
now the "listen" directives use ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
794 return NGX_CONF_ERROR; |
521 | 795 } |
796 | |
1136 | 797 cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module); |
521 | 798 |
641 | 799 imls = cmcf->listen.elts; |
800 | |
801 for (i = 0; i < cmcf->listen.nelts; i++) { | |
802 | |
906 | 803 if (imls[i].addr != u.addr.in_addr || imls[i].port != u.port) { |
641 | 804 continue; |
805 } | |
806 | |
807 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
804
472cd9768ac2
now the "listen" directives use ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
808 "duplicate \"%V\" address and port pair", &u.url); |
577 | 809 return NGX_CONF_ERROR; |
521 | 810 } |
811 | |
641 | 812 imls = ngx_array_push(&cmcf->listen); |
813 if (imls == NULL) { | |
814 return NGX_CONF_ERROR; | |
815 } | |
563 | 816 |
1136 | 817 ngx_memzero(imls, sizeof(ngx_mail_listen_t)); |
641 | 818 |
804
472cd9768ac2
now the "listen" directives use ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
819 imls->addr = u.addr.in_addr; |
906 | 820 imls->port = u.port; |
641 | 821 imls->family = AF_INET; |
822 imls->ctx = cf->ctx; | |
521 | 823 |
641 | 824 if (cf->args->nelts == 2) { |
825 return NGX_CONF_OK; | |
826 } | |
521 | 827 |
641 | 828 if (ngx_strcmp(value[2].data, "bind") == 0) { |
829 imls->bind = 1; | |
830 return NGX_CONF_OK; | |
831 } | |
521 | 832 |
641 | 833 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
834 "the invalid \"%V\" parameter", &value[2]); | |
835 return NGX_CONF_ERROR; | |
521 | 836 } |
527 | 837 |
838 | |
839 static char * | |
1136 | 840 ngx_mail_core_capability(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
527 | 841 { |
842 char *p = conf; | |
843 | |
844 ngx_str_t *c, *value; | |
845 ngx_uint_t i; | |
846 ngx_array_t *a; | |
847 | |
848 a = (ngx_array_t *) (p + cmd->offset); | |
849 | |
850 value = cf->args->elts; | |
851 | |
852 for (i = 1; i < cf->args->nelts; i++) { | |
853 c = ngx_array_push(a); | |
854 if (c == NULL) { | |
855 return NGX_CONF_ERROR; | |
856 } | |
857 | |
858 *c = value[i]; | |
859 } | |
860 | |
861 return NGX_CONF_OK; | |
862 } |