Mercurial > hg > nginx-mail
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; |