Mercurial > hg > nginx-quic
annotate src/mail/ngx_mail_core_module.c @ 1297:4ec0bc95172b
"?" should not be escaped
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 13 Jul 2007 09:35:51 +0000 |
parents | 6be5ee17d80b |
children | 27f2299e0d80 |
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 | |
1136 | 57 static ngx_conf_bitmask_t ngx_smtp_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_str_t ngx_smtp_auth_methods_names[] = { | |
1174
6be5ee17d80b
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
1136
diff
changeset
|
66 ngx_string("PLAIN"), |
1136 | 67 ngx_string("LOGIN"), |
68 ngx_null_string, /* APOP */ | |
69 ngx_string("CRAM-MD5") | |
70 }; | |
71 | |
72 | |
809 | 73 static ngx_str_t ngx_pop3_auth_plain_capability = |
74 ngx_string("+OK methods supported:" CRLF | |
75 "LOGIN" CRLF | |
76 "PLAIN" CRLF | |
77 "." CRLF); | |
78 | |
79 | |
80 static ngx_str_t ngx_pop3_auth_cram_md5_capability = | |
81 ngx_string("+OK methods supported:" CRLF | |
82 "LOGIN" CRLF | |
83 "PLAIN" CRLF | |
84 "CRAM-MD5" CRLF | |
85 "." CRLF); | |
86 | |
87 | |
88 | |
1136 | 89 static ngx_command_t ngx_mail_core_commands[] = { |
521 | 90 |
91 { ngx_string("server"), | |
1136 | 92 NGX_MAIL_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, |
93 ngx_mail_core_server, | |
521 | 94 0, |
95 0, | |
96 NULL }, | |
97 | |
98 { ngx_string("listen"), | |
1136 | 99 NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12, |
100 ngx_mail_core_listen, | |
521 | 101 0, |
102 0, | |
103 NULL }, | |
104 | |
105 { ngx_string("protocol"), | |
1136 | 106 NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, |
521 | 107 ngx_conf_set_enum_slot, |
1136 | 108 NGX_MAIL_SRV_CONF_OFFSET, |
109 offsetof(ngx_mail_core_srv_conf_t, protocol), | |
110 &ngx_mail_core_procotol }, | |
521 | 111 |
112 { ngx_string("imap_client_buffer"), | |
1136 | 113 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, |
521 | 114 ngx_conf_set_size_slot, |
1136 | 115 NGX_MAIL_SRV_CONF_OFFSET, |
116 offsetof(ngx_mail_core_srv_conf_t, imap_client_buffer_size), | |
521 | 117 NULL }, |
118 | |
587 | 119 { ngx_string("so_keepalive"), |
1136 | 120 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, |
587 | 121 ngx_conf_set_flag_slot, |
1136 | 122 NGX_MAIL_SRV_CONF_OFFSET, |
123 offsetof(ngx_mail_core_srv_conf_t, so_keepalive), | |
587 | 124 NULL }, |
125 | |
521 | 126 { ngx_string("timeout"), |
1136 | 127 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, |
521 | 128 ngx_conf_set_msec_slot, |
1136 | 129 NGX_MAIL_SRV_CONF_OFFSET, |
130 offsetof(ngx_mail_core_srv_conf_t, timeout), | |
521 | 131 NULL }, |
132 | |
527 | 133 { ngx_string("pop3_capabilities"), |
1136 | 134 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE, |
135 ngx_mail_core_capability, | |
136 NGX_MAIL_SRV_CONF_OFFSET, | |
137 offsetof(ngx_mail_core_srv_conf_t, pop3_capabilities), | |
527 | 138 NULL }, |
139 | |
140 { ngx_string("imap_capabilities"), | |
1136 | 141 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE, |
142 ngx_mail_core_capability, | |
143 NGX_MAIL_SRV_CONF_OFFSET, | |
144 offsetof(ngx_mail_core_srv_conf_t, imap_capabilities), | |
145 NULL }, | |
146 | |
147 { ngx_string("smtp_capabilities"), | |
148 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE, | |
149 ngx_mail_core_capability, | |
150 NGX_MAIL_SRV_CONF_OFFSET, | |
151 offsetof(ngx_mail_core_srv_conf_t, smtp_capabilities), | |
527 | 152 NULL }, |
153 | |
800 | 154 { ngx_string("server_name"), |
1136 | 155 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, |
800 | 156 ngx_conf_set_str_slot, |
1136 | 157 NGX_MAIL_SRV_CONF_OFFSET, |
158 offsetof(ngx_mail_core_srv_conf_t, server_name), | |
800 | 159 NULL }, |
160 | |
161 { ngx_string("auth"), | |
1136 | 162 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE, |
163 ngx_conf_set_bitmask_slot, | |
164 NGX_MAIL_SRV_CONF_OFFSET, | |
165 offsetof(ngx_mail_core_srv_conf_t, pop3_auth_methods), | |
166 &ngx_pop3_auth_methods }, | |
167 | |
168 { ngx_string("pop3_auth"), | |
169 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE, | |
800 | 170 ngx_conf_set_bitmask_slot, |
1136 | 171 NGX_MAIL_SRV_CONF_OFFSET, |
172 offsetof(ngx_mail_core_srv_conf_t, pop3_auth_methods), | |
173 &ngx_pop3_auth_methods }, | |
174 | |
175 { ngx_string("smtp_auth"), | |
176 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE, | |
177 ngx_conf_set_bitmask_slot, | |
178 NGX_MAIL_SRV_CONF_OFFSET, | |
179 offsetof(ngx_mail_core_srv_conf_t, smtp_auth_methods), | |
180 &ngx_smtp_auth_methods }, | |
800 | 181 |
521 | 182 ngx_null_command |
183 }; | |
184 | |
185 | |
1136 | 186 static ngx_mail_module_t ngx_mail_core_module_ctx = { |
187 ngx_mail_core_create_main_conf, /* create main configuration */ | |
521 | 188 NULL, /* init main configuration */ |
189 | |
1136 | 190 ngx_mail_core_create_srv_conf, /* create server configuration */ |
191 ngx_mail_core_merge_srv_conf /* merge server configuration */ | |
521 | 192 }; |
193 | |
194 | |
1136 | 195 ngx_module_t ngx_mail_core_module = { |
521 | 196 NGX_MODULE_V1, |
1136 | 197 &ngx_mail_core_module_ctx, /* module context */ |
198 ngx_mail_core_commands, /* module directives */ | |
199 NGX_MAIL_MODULE, /* module type */ | |
541 | 200 NULL, /* init master */ |
521 | 201 NULL, /* init module */ |
541 | 202 NULL, /* init process */ |
203 NULL, /* init thread */ | |
204 NULL, /* exit thread */ | |
205 NULL, /* exit process */ | |
206 NULL, /* exit master */ | |
207 NGX_MODULE_V1_PADDING | |
521 | 208 }; |
209 | |
210 | |
211 static void * | |
1136 | 212 ngx_mail_core_create_main_conf(ngx_conf_t *cf) |
577 | 213 { |
1136 | 214 ngx_mail_core_main_conf_t *cmcf; |
521 | 215 |
1136 | 216 cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_main_conf_t)); |
521 | 217 if (cmcf == NULL) { |
218 return NGX_CONF_ERROR; | |
219 } | |
220 | |
221 if (ngx_array_init(&cmcf->servers, cf->pool, 4, | |
1136 | 222 sizeof(ngx_mail_core_srv_conf_t *)) |
641 | 223 != NGX_OK) |
224 { | |
225 return NGX_CONF_ERROR; | |
226 } | |
227 | |
1136 | 228 if (ngx_array_init(&cmcf->listen, cf->pool, 4, sizeof(ngx_mail_listen_t)) |
641 | 229 != NGX_OK) |
521 | 230 { |
231 return NGX_CONF_ERROR; | |
232 } | |
233 | |
234 return cmcf; | |
235 } | |
236 | |
237 | |
238 static void * | |
1136 | 239 ngx_mail_core_create_srv_conf(ngx_conf_t *cf) |
577 | 240 { |
1136 | 241 ngx_mail_core_srv_conf_t *cscf; |
577 | 242 |
1136 | 243 cscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_srv_conf_t)); |
521 | 244 if (cscf == NULL) { |
527 | 245 return NULL; |
521 | 246 } |
247 | |
248 cscf->imap_client_buffer_size = NGX_CONF_UNSET_SIZE; | |
587 | 249 cscf->protocol = NGX_CONF_UNSET_UINT; |
521 | 250 cscf->timeout = NGX_CONF_UNSET_MSEC; |
587 | 251 cscf->so_keepalive = NGX_CONF_UNSET; |
521 | 252 |
527 | 253 if (ngx_array_init(&cscf->pop3_capabilities, cf->pool, 4, sizeof(ngx_str_t)) |
254 != NGX_OK) | |
255 { | |
256 return NULL; | |
257 } | |
258 | |
259 if (ngx_array_init(&cscf->imap_capabilities, cf->pool, 4, sizeof(ngx_str_t)) | |
260 != NGX_OK) | |
261 { | |
262 return NULL; | |
263 } | |
264 | |
1136 | 265 if (ngx_array_init(&cscf->smtp_capabilities, cf->pool, 4, sizeof(ngx_str_t)) |
266 != NGX_OK) | |
267 { | |
268 return NULL; | |
269 } | |
270 | |
521 | 271 return cscf; |
272 } | |
273 | |
274 | |
275 static char * | |
1136 | 276 ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) |
521 | 277 { |
1136 | 278 ngx_mail_core_srv_conf_t *prev = parent; |
279 ngx_mail_core_srv_conf_t *conf = child; | |
521 | 280 |
583 | 281 u_char *p; |
1136 | 282 size_t size, stls_only_size; |
527 | 283 ngx_str_t *c, *d; |
1136 | 284 ngx_uint_t i, m; |
527 | 285 |
521 | 286 ngx_conf_merge_size_value(conf->imap_client_buffer_size, |
287 prev->imap_client_buffer_size, | |
288 (size_t) ngx_pagesize); | |
289 ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000); | |
663 | 290 ngx_conf_merge_uint_value(conf->protocol, prev->protocol, |
1136 | 291 NGX_MAIL_IMAP_PROTOCOL); |
587 | 292 ngx_conf_merge_value(conf->so_keepalive, prev->so_keepalive, 0); |
521 | 293 |
527 | 294 |
1136 | 295 ngx_conf_merge_bitmask_value(conf->pop3_auth_methods, |
296 prev->pop3_auth_methods, | |
297 (NGX_CONF_BITMASK_SET | |
298 |NGX_MAIL_AUTH_PLAIN_ENABLED)); | |
299 | |
300 ngx_conf_merge_bitmask_value(conf->smtp_auth_methods, | |
301 prev->smtp_auth_methods, | |
302 (NGX_CONF_BITMASK_SET | |
303 |NGX_MAIL_AUTH_PLAIN_ENABLED | |
304 |NGX_MAIL_AUTH_LOGIN_ENABLED)); | |
800 | 305 |
306 | |
307 ngx_conf_merge_str_value(conf->server_name, prev->server_name, ""); | |
308 | |
309 if (conf->server_name.len == 0) { | |
310 conf->server_name.data = ngx_palloc(cf->pool, NGX_MAXHOSTNAMELEN); | |
311 if (conf->server_name.data == NULL) { | |
312 return NGX_CONF_ERROR; | |
313 } | |
314 | |
315 if (gethostname((char *) conf->server_name.data, NGX_MAXHOSTNAMELEN) | |
316 == -1) | |
317 { | |
318 ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno, | |
319 "gethostname() failed"); | |
320 return NGX_CONF_ERROR; | |
321 } | |
322 | |
323 conf->server_name.len = ngx_strlen(conf->server_name.data); | |
324 } | |
325 | |
326 | |
527 | 327 if (conf->pop3_capabilities.nelts == 0) { |
328 conf->pop3_capabilities = prev->pop3_capabilities; | |
329 } | |
330 | |
331 if (conf->pop3_capabilities.nelts == 0) { | |
332 | |
333 for (d = ngx_pop3_default_capabilities; d->len; d++) { | |
334 c = ngx_array_push(&conf->pop3_capabilities); | |
335 if (c == NULL) { | |
336 return NGX_CONF_ERROR; | |
337 } | |
338 | |
339 *c = *d; | |
340 } | |
341 } | |
342 | |
343 size = sizeof("+OK Capability list follows" CRLF) - 1 | |
344 + sizeof("." CRLF) - 1; | |
345 | |
1136 | 346 stls_only_size = size + sizeof("STLS" CRLF) - 1; |
347 | |
527 | 348 c = conf->pop3_capabilities.elts; |
349 for (i = 0; i < conf->pop3_capabilities.nelts; i++) { | |
350 size += c[i].len + sizeof(CRLF) - 1; | |
1136 | 351 |
352 if (ngx_strcasecmp(c[i].data, (u_char *) "USER") == 0) { | |
353 continue; | |
354 } | |
355 | |
356 stls_only_size += c[i].len + sizeof(CRLF) - 1; | |
527 | 357 } |
358 | |
1136 | 359 if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { |
809 | 360 size += sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1; |
361 | |
362 } else { | |
363 size += sizeof("SASL LOGIN PLAIN" CRLF) - 1; | |
364 } | |
365 | |
583 | 366 p = ngx_palloc(cf->pool, size); |
367 if (p == NULL) { | |
527 | 368 return NGX_CONF_ERROR; |
369 } | |
370 | |
583 | 371 conf->pop3_capability.len = size; |
372 conf->pop3_capability.data = p; | |
373 | |
374 p = ngx_cpymem(p, "+OK Capability list follows" CRLF, | |
375 sizeof("+OK Capability list follows" CRLF) - 1); | |
527 | 376 |
377 for (i = 0; i < conf->pop3_capabilities.nelts; i++) { | |
583 | 378 p = ngx_cpymem(p, c[i].data, c[i].len); |
379 *p++ = CR; *p++ = LF; | |
527 | 380 } |
381 | |
1136 | 382 if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { |
809 | 383 p = ngx_cpymem(p, "SASL LOGIN PLAIN CRAM-MD5" CRLF, |
384 sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1); | |
385 | |
386 } else { | |
387 p = ngx_cpymem(p, "SASL LOGIN PLAIN" CRLF, | |
388 sizeof("SASL LOGIN PLAIN" CRLF) - 1); | |
389 } | |
390 | |
583 | 391 *p++ = '.'; *p++ = CR; *p = LF; |
392 | |
393 | |
394 size += sizeof("STLS" CRLF) - 1; | |
527 | 395 |
583 | 396 p = ngx_palloc(cf->pool, size); |
397 if (p == NULL) { | |
398 return NGX_CONF_ERROR; | |
399 } | |
400 | |
401 conf->pop3_starttls_capability.len = size; | |
402 conf->pop3_starttls_capability.data = p; | |
403 | |
404 p = ngx_cpymem(p, conf->pop3_capability.data, | |
405 conf->pop3_capability.len - (sizeof("." CRLF) - 1)); | |
406 | |
407 p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1); | |
408 *p++ = '.'; *p++ = CR; *p = LF; | |
527 | 409 |
410 | |
1136 | 411 if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { |
809 | 412 conf->pop3_auth_capability = ngx_pop3_auth_cram_md5_capability; |
413 | |
414 } else { | |
415 conf->pop3_auth_capability = ngx_pop3_auth_plain_capability; | |
416 } | |
417 | |
418 | |
1136 | 419 p = ngx_palloc(cf->pool, stls_only_size); |
420 if (p == NULL) { | |
421 return NGX_CONF_ERROR; | |
422 } | |
423 | |
424 conf->pop3_starttls_only_capability.len = stls_only_size; | |
425 conf->pop3_starttls_only_capability.data = p; | |
426 | |
427 p = ngx_cpymem(p, "+OK Capability list follows" CRLF, | |
428 sizeof("+OK Capability list follows" CRLF) - 1); | |
429 | |
430 for (i = 0; i < conf->pop3_capabilities.nelts; i++) { | |
431 if (ngx_strcasecmp(c[i].data, (u_char *) "USER") == 0) { | |
432 continue; | |
433 } | |
434 | |
435 p = ngx_cpymem(p, c[i].data, c[i].len); | |
436 *p++ = CR; *p++ = LF; | |
437 } | |
438 | |
439 p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1); | |
440 *p++ = '.'; *p++ = CR; *p = LF; | |
441 | |
442 | |
527 | 443 if (conf->imap_capabilities.nelts == 0) { |
444 conf->imap_capabilities = prev->imap_capabilities; | |
445 } | |
446 | |
447 if (conf->imap_capabilities.nelts == 0) { | |
448 | |
449 for (d = ngx_imap_default_capabilities; d->len; d++) { | |
450 c = ngx_array_push(&conf->imap_capabilities); | |
451 if (c == NULL) { | |
452 return NGX_CONF_ERROR; | |
453 } | |
454 | |
455 *c = *d; | |
456 } | |
457 } | |
458 | |
1136 | 459 size = sizeof("* CAPABILITY" CRLF) - 1; |
527 | 460 |
461 c = conf->imap_capabilities.elts; | |
462 for (i = 0; i < conf->imap_capabilities.nelts; i++) { | |
463 size += 1 + c[i].len; | |
464 } | |
465 | |
583 | 466 p = ngx_palloc(cf->pool, size); |
467 if (p == NULL) { | |
468 return NGX_CONF_ERROR; | |
469 } | |
470 | |
471 conf->imap_capability.len = size; | |
472 conf->imap_capability.data = p; | |
473 | |
474 p = ngx_cpymem(p, "* CAPABILITY", sizeof("* CAPABILITY") - 1); | |
475 | |
476 for (i = 0; i < conf->imap_capabilities.nelts; i++) { | |
477 *p++ = ' '; | |
478 p = ngx_cpymem(p, c[i].data, c[i].len); | |
479 } | |
480 | |
481 *p++ = CR; *p = LF; | |
482 | |
483 | |
484 size += sizeof(" STARTTLS") - 1; | |
485 | |
486 p = ngx_palloc(cf->pool, size); | |
487 if (p == NULL) { | |
527 | 488 return NGX_CONF_ERROR; |
489 } | |
490 | |
583 | 491 conf->imap_starttls_capability.len = size; |
492 conf->imap_starttls_capability.data = p; | |
527 | 493 |
583 | 494 p = ngx_cpymem(p, conf->imap_capability.data, |
495 conf->imap_capability.len - (sizeof(CRLF) - 1)); | |
496 p = ngx_cpymem(p, " STARTTLS", sizeof(" STARTTLS") - 1); | |
497 *p++ = CR; *p = LF; | |
498 | |
499 | |
500 size += sizeof(" LOGINDISABLED") - 1; | |
501 | |
502 p = ngx_palloc(cf->pool, size); | |
503 if (p == NULL) { | |
504 return NGX_CONF_ERROR; | |
527 | 505 } |
506 | |
583 | 507 conf->imap_starttls_only_capability.len = size; |
508 conf->imap_starttls_only_capability.data = p; | |
527 | 509 |
583 | 510 p = ngx_cpymem(p, conf->imap_starttls_capability.data, |
511 conf->imap_starttls_capability.len - (sizeof(CRLF) - 1)); | |
512 p = ngx_cpymem(p, " LOGINDISABLED", sizeof(" LOGINDISABLED") - 1); | |
513 *p++ = CR; *p = LF; | |
514 | |
527 | 515 |
1136 | 516 size = sizeof("220 ESMTP ready" CRLF) - 1 + conf->server_name.len; |
517 | |
518 p = ngx_palloc(cf->pool, size); | |
519 if (p == NULL) { | |
520 return NGX_CONF_ERROR; | |
521 } | |
522 | |
523 conf->smtp_greeting.len = size; | |
524 conf->smtp_greeting.data = p; | |
525 | |
526 *p++ = '2'; *p++ = '2'; *p++ = '0'; *p++ = ' '; | |
527 p = ngx_cpymem(p, conf->server_name.data, conf->server_name.len); | |
528 ngx_memcpy(p, " ESMTP ready" CRLF, sizeof(" ESMTP ready" CRLF) - 1); | |
529 | |
530 | |
531 size = sizeof("250 " CRLF) - 1 + conf->server_name.len; | |
532 | |
533 p = ngx_palloc(cf->pool, size); | |
534 if (p == NULL) { | |
535 return NGX_CONF_ERROR; | |
536 } | |
537 | |
538 conf->smtp_server_name.len = size; | |
539 conf->smtp_server_name.data = p; | |
540 | |
541 *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = ' '; | |
542 p = ngx_cpymem(p, conf->server_name.data, conf->server_name.len); | |
543 *p++ = CR; *p = LF; | |
544 | |
545 | |
546 if (conf->smtp_capabilities.nelts == 0) { | |
547 conf->smtp_capabilities = prev->smtp_capabilities; | |
548 } | |
549 | |
550 size = sizeof("250-") - 1 + conf->server_name.len + sizeof(CRLF) - 1 | |
551 + sizeof("250 AUTH") - 1 + sizeof(CRLF) - 1; | |
552 | |
553 c = conf->smtp_capabilities.elts; | |
554 for (i = 0; i < conf->smtp_capabilities.nelts; i++) { | |
555 size += sizeof("250 ") - 1 + c[i].len + sizeof(CRLF) - 1; | |
556 } | |
557 | |
558 for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; | |
559 m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; | |
560 m <<= 1, i++) | |
561 { | |
562 if (m & conf->smtp_auth_methods) { | |
563 size += 1 + ngx_smtp_auth_methods_names[i].len; | |
564 } | |
565 } | |
566 | |
567 p = ngx_palloc(cf->pool, size); | |
568 if (p == NULL) { | |
569 return NGX_CONF_ERROR; | |
570 } | |
571 | |
572 conf->smtp_capability.len = size; | |
573 conf->smtp_capability.data = p; | |
574 | |
575 *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = '-'; | |
576 p = ngx_cpymem(p, conf->server_name.data, conf->server_name.len); | |
577 *p++ = CR; *p++ = LF; | |
578 | |
579 for (i = 0; i < conf->smtp_capabilities.nelts; i++) { | |
580 *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = '-'; | |
581 p = ngx_cpymem(p, c[i].data, c[i].len); | |
582 *p++ = CR; *p++ = LF; | |
583 } | |
584 | |
585 *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = ' '; | |
586 *p++ = 'A'; *p++ = 'U'; *p++ = 'T'; *p++ = 'H'; | |
587 | |
588 for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; | |
589 m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; | |
590 m <<= 1, i++) | |
591 { | |
592 if (m & conf->smtp_auth_methods) { | |
593 *p++ = ' '; | |
594 p = ngx_cpymem(p, ngx_smtp_auth_methods_names[i].data, | |
595 ngx_smtp_auth_methods_names[i].len); | |
596 } | |
597 } | |
598 | |
599 *p++ = CR; *p = LF; | |
600 | |
521 | 601 return NGX_CONF_OK; |
602 } | |
603 | |
604 | |
605 static char * | |
1136 | 606 ngx_mail_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
521 | 607 { |
608 char *rv; | |
609 void *mconf; | |
610 ngx_uint_t m; | |
611 ngx_conf_t pcf; | |
1136 | 612 ngx_mail_module_t *module; |
613 ngx_mail_conf_ctx_t *ctx, *mail_ctx; | |
614 ngx_mail_core_srv_conf_t *cscf, **cscfp; | |
615 ngx_mail_core_main_conf_t *cmcf; | |
521 | 616 |
617 | |
1136 | 618 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_mail_conf_ctx_t)); |
521 | 619 if (ctx == NULL) { |
620 return NGX_CONF_ERROR; | |
621 } | |
622 | |
1136 | 623 mail_ctx = cf->ctx; |
624 ctx->main_conf = mail_ctx->main_conf; | |
577 | 625 |
521 | 626 /* the server{}'s srv_conf */ |
627 | |
1136 | 628 ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_mail_max_module); |
521 | 629 if (ctx->srv_conf == NULL) { |
630 return NGX_CONF_ERROR; | |
631 } | |
632 | |
633 for (m = 0; ngx_modules[m]; m++) { | |
1136 | 634 if (ngx_modules[m]->type != NGX_MAIL_MODULE) { |
521 | 635 continue; |
636 } | |
637 | |
638 module = ngx_modules[m]->ctx; | |
639 | |
640 if (module->create_srv_conf) { | |
641 mconf = module->create_srv_conf(cf); | |
642 if (mconf == NULL) { | |
643 return NGX_CONF_ERROR; | |
644 } | |
645 | |
646 ctx->srv_conf[ngx_modules[m]->ctx_index] = mconf; | |
647 } | |
648 } | |
649 | |
650 /* the server configuration context */ | |
651 | |
1136 | 652 cscf = ctx->srv_conf[ngx_mail_core_module.ctx_index]; |
521 | 653 cscf->ctx = ctx; |
654 | |
1136 | 655 cmcf = ctx->main_conf[ngx_mail_core_module.ctx_index]; |
521 | 656 |
657 cscfp = ngx_array_push(&cmcf->servers); | |
658 if (cscfp == NULL) { | |
659 return NGX_CONF_ERROR; | |
660 } | |
661 | |
662 *cscfp = cscf; | |
663 | |
664 | |
665 /* parse inside server{} */ | |
666 | |
667 pcf = *cf; | |
668 cf->ctx = ctx; | |
1136 | 669 cf->cmd_type = NGX_MAIL_SRV_CONF; |
521 | 670 |
671 rv = ngx_conf_parse(cf, NULL); | |
672 | |
673 *cf = pcf; | |
674 | |
675 return rv; | |
676 } | |
677 | |
678 | |
679 /* AF_INET only */ | |
680 | |
681 static char * | |
1136 | 682 ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
521 | 683 { |
641 | 684 ngx_str_t *value; |
804
472cd9768ac2
now the "listen" directives use ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
685 ngx_url_t u; |
641 | 686 ngx_uint_t i; |
1136 | 687 ngx_mail_listen_t *imls; |
688 ngx_mail_core_main_conf_t *cmcf; | |
521 | 689 |
690 value = cf->args->elts; | |
691 | |
804
472cd9768ac2
now the "listen" directives use ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
692 ngx_memzero(&u, sizeof(ngx_url_t)); |
521 | 693 |
804
472cd9768ac2
now the "listen" directives use ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
694 u.url = value[1]; |
472cd9768ac2
now the "listen" directives use ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
695 u.listen = 1; |
619 | 696 |
804
472cd9768ac2
now the "listen" directives use ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
697 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
|
698 if (u.err) { |
472cd9768ac2
now the "listen" directives use ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
699 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
|
700 "%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
|
701 u.err, &u.url); |
521 | 702 } |
703 | |
804
472cd9768ac2
now the "listen" directives use ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
704 return NGX_CONF_ERROR; |
521 | 705 } |
706 | |
1136 | 707 cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module); |
521 | 708 |
641 | 709 imls = cmcf->listen.elts; |
710 | |
711 for (i = 0; i < cmcf->listen.nelts; i++) { | |
712 | |
906 | 713 if (imls[i].addr != u.addr.in_addr || imls[i].port != u.port) { |
641 | 714 continue; |
715 } | |
716 | |
717 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
|
718 "duplicate \"%V\" address and port pair", &u.url); |
577 | 719 return NGX_CONF_ERROR; |
521 | 720 } |
721 | |
641 | 722 imls = ngx_array_push(&cmcf->listen); |
723 if (imls == NULL) { | |
724 return NGX_CONF_ERROR; | |
725 } | |
563 | 726 |
1136 | 727 ngx_memzero(imls, sizeof(ngx_mail_listen_t)); |
641 | 728 |
804
472cd9768ac2
now the "listen" directives use ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
729 imls->addr = u.addr.in_addr; |
906 | 730 imls->port = u.port; |
641 | 731 imls->family = AF_INET; |
732 imls->ctx = cf->ctx; | |
521 | 733 |
641 | 734 if (cf->args->nelts == 2) { |
735 return NGX_CONF_OK; | |
736 } | |
521 | 737 |
641 | 738 if (ngx_strcmp(value[2].data, "bind") == 0) { |
739 imls->bind = 1; | |
740 return NGX_CONF_OK; | |
741 } | |
521 | 742 |
641 | 743 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
744 "the invalid \"%V\" parameter", &value[2]); | |
745 return NGX_CONF_ERROR; | |
521 | 746 } |
527 | 747 |
748 | |
749 static char * | |
1136 | 750 ngx_mail_core_capability(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
527 | 751 { |
752 char *p = conf; | |
753 | |
754 ngx_str_t *c, *value; | |
755 ngx_uint_t i; | |
756 ngx_array_t *a; | |
757 | |
758 a = (ngx_array_t *) (p + cmd->offset); | |
759 | |
760 value = cf->args->elts; | |
761 | |
762 for (i = 1; i < cf->args->nelts; i++) { | |
763 c = ngx_array_push(a); | |
764 if (c == NULL) { | |
765 return NGX_CONF_ERROR; | |
766 } | |
767 | |
768 *c = value[i]; | |
769 } | |
770 | |
771 return NGX_CONF_OK; | |
772 } |