Klaus Demo nginx / 4871408
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module Igor Sysoev 14 years ago
19 changed file(s) with 1214 addition(s) and 749 deletion(s). Raw diff Collapse all Expand all
307307
308308
309309 if [ $MAIL_SSL = YES ]; then
310 MAIL_DEPS="$MAIL_DEPS $MAIL_SSL_DEPS"
311 MAIL_SRCS="$MAIL_SRCS $MAIL_SSL_SRCS"
312310 have=NGX_MAIL_SSL . auto/have
313311 USE_OPENSSL=YES
314312 fi
340338
341339 if [ $MAIL_SSL = YES ]; then
342340 modules="$modules $MAIL_SSL_MODULE"
341 MAIL_DEPS="$MAIL_DEPS $MAIL_SSL_DEPS"
342 MAIL_SRCS="$MAIL_SRCS $MAIL_SSL_SRCS"
343 fi
344
345 if [ $MAIL_POP3 = YES ]; then
346 modules="$modules $MAIL_POP3_MODULE"
347 MAIL_DEPS="$MAIL_DEPS $MAIL_POP3_DEPS"
348 MAIL_SRCS="$MAIL_SRCS $MAIL_POP3_SRCS"
349 fi
350
351 if [ $MAIL_IMAP = YES ]; then
352 modules="$modules $MAIL_IMAP_MODULE"
353 MAIL_DEPS="$MAIL_DEPS $MAIL_IMAP_DEPS"
354 MAIL_SRCS="$MAIL_SRCS $MAIL_IMAP_SRCS"
355 fi
356
357 if [ $MAIL_SMTP = YES ]; then
358 modules="$modules $MAIL_SMTP_MODULE"
359 MAIL_DEPS="$MAIL_DEPS $MAIL_SMTP_DEPS"
360 MAIL_SRCS="$MAIL_SRCS $MAIL_SMTP_SRCS"
343361 fi
344362
345363 modules="$modules $MAIL_AUTH_HTTP_MODULE"
8080
8181 MAIL=NO
8282 MAIL_SSL=NO
83 MAIL_POP3=YES
84 MAIL_IMAP=YES
85 MAIL_SMTP=YES
8386
8487 NGX_ADDONS=
8588
189192 # STUB
190193 --with-imap) MAIL=YES ;;
191194 --with-imap_ssl_module) MAIL_SSL=YES ;;
195 --without-mail_pop3_module) MAIL_POP3=NO ;;
196 --without-mail_imap_module) MAIL_IMAP=NO ;;
197 --without-mail_smtp_module) MAIL_SMTP=NO ;;
192198
193199 --add-module=*) NGX_ADDONS="$NGX_ADDONS $value" ;;
194200
422422 MAIL_SRCS="src/mail/ngx_mail.c \
423423 src/mail/ngx_mail_core_module.c \
424424 src/mail/ngx_mail_handler.c \
425 src/mail/ngx_mail_pop3_handler.c \
426 src/mail/ngx_mail_imap_handler.c \
427 src/mail/ngx_mail_smtp_handler.c \
428425 src/mail/ngx_mail_parse.c"
426
427 MAIL_POP3_MODULE="ngx_mail_pop3_module"
428 MAIL_POP3_DEPS="src/mail/ngx_mail_pop3_module.h"
429 MAIL_POP3_SRCS="src/mail/ngx_mail_pop3_module.c \
430 src/mail/ngx_mail_pop3_handler.c"
431
432 MAIL_IMAP_MODULE="ngx_mail_imap_module"
433 MAIL_IMAP_DEPS="src/mail/ngx_mail_imap_module.h"
434 MAIL_IMAP_SRCS="src/mail/ngx_mail_imap_module.c \
435 src/mail/ngx_mail_imap_handler.c"
436
437 MAIL_SMTP_MODULE="ngx_mail_smtp_module"
438 MAIL_SMTP_DEPS="src/mail/ngx_mail_smtp_module.h"
439 MAIL_SMTP_SRCS="src/mail/ngx_mail_smtp_module.c \
440 src/mail/ngx_mail_smtp_handler.c"
429441
430442 MAIL_SSL_MODULE="ngx_mail_ssl_module"
431443 MAIL_SSL_DEPS="src/mail/ngx_mail_ssl_module.h"
184184
185185 /* init mail{} main_conf's */
186186
187 cf->ctx = ctx;
188
187189 if (module->init_main_conf) {
188190 rv = module->init_main_conf(cf, ctx->main_conf[mi]);
189191 if (rv != NGX_CONF_OK) {
195197 for (s = 0; s < cmcf->servers.nelts; s++) {
196198
197199 /* merge the server{}s' srv_conf's */
200
201 cf->ctx = cscfp[s]->ctx;
198202
199203 if (module->merge_srv_conf) {
200204 rv = module->merge_srv_conf(cf,
208212 }
209213 }
210214
211 /* mail{}'s cf->ctx was needed while the configuration merging */
212
213215 *cf = pcf;
214216
215217
7272 #define NGX_MAIL_IMAP_PROTOCOL 1
7373 #define NGX_MAIL_SMTP_PROTOCOL 2
7474
75 typedef struct {
75
76 typedef struct ngx_mail_protocol_s ngx_mail_protocol_t;
77
78
79 typedef struct {
80 ngx_mail_protocol_t *protocol;
81
7682 ngx_msec_t timeout;
77 ngx_msec_t smtp_greeting_delay;
78
79 size_t imap_client_buffer_size;
80 size_t smtp_client_buffer_size;
81
82 ngx_uint_t protocol;
8383
8484 ngx_flag_t so_keepalive;
8585
86 ngx_str_t pop3_capability;
87 ngx_str_t pop3_starttls_capability;
88 ngx_str_t pop3_starttls_only_capability;
89 ngx_str_t pop3_auth_capability;
90
91 ngx_str_t imap_capability;
92 ngx_str_t imap_starttls_capability;
93 ngx_str_t imap_starttls_only_capability;
94
95 ngx_str_t smtp_capability;
96 ngx_str_t smtp_starttls_capability;
97 ngx_str_t smtp_starttls_only_capability;
98
9986 ngx_str_t server_name;
100 ngx_str_t smtp_server_name;
101 ngx_str_t smtp_greeting;
102
103 ngx_uint_t pop3_auth_methods;
104 ngx_uint_t imap_auth_methods;
105 ngx_uint_t smtp_auth_methods;
106
107 ngx_array_t pop3_capabilities;
108 ngx_array_t imap_capabilities;
109 ngx_array_t smtp_capabilities;
87
88 u_char *file_name;
89 ngx_int_t line;
11090
11191 /* server ctx */
11292 ngx_mail_conf_ctx_t *ctx;
11393 } ngx_mail_core_srv_conf_t;
114
115
116 typedef struct {
117 void *(*create_main_conf)(ngx_conf_t *cf);
118 char *(*init_main_conf)(ngx_conf_t *cf, void *conf);
119
120 void *(*create_srv_conf)(ngx_conf_t *cf);
121 char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev,
122 void *conf);
123 } ngx_mail_module_t;
12494
12595
12696 typedef enum {
180150
181151 ngx_uint_t mail_state;
182152
153 unsigned protocol:3;
183154 unsigned blocked:1;
184155 unsigned quit:1;
185 unsigned protocol:2;
186156 unsigned quoted:1;
187157 unsigned backslash:1;
188158 unsigned no_sync_literal:1;
207177
208178 ngx_uint_t login_attempt;
209179
210 /* used to parse IMAP/POP3/SMTP command */
180 /* used to parse POP3/IMAP/SMTP command */
211181
212182 ngx_uint_t state;
213183 u_char *cmd_start;
281251 #define NGX_MAIL_PARSE_INVALID_COMMAND 20
282252
283253
284 #define NGX_MAIL_MODULE 0x4C49414D /* "MAIL" */
285
286 #define NGX_MAIL_MAIN_CONF 0x02000000
287 #define NGX_MAIL_SRV_CONF 0x04000000
288
289
290 #define NGX_MAIL_MAIN_CONF_OFFSET offsetof(ngx_mail_conf_ctx_t, main_conf)
291 #define NGX_MAIL_SRV_CONF_OFFSET offsetof(ngx_mail_conf_ctx_t, srv_conf)
292
293
294 #define ngx_mail_get_module_ctx(s, module) (s)->ctx[module.ctx_index]
295 #define ngx_mail_set_ctx(s, c, module) s->ctx[module.ctx_index] = c;
296 #define ngx_mail_delete_ctx(s, module) s->ctx[module.ctx_index] = NULL;
297
298
299 #define ngx_mail_get_module_main_conf(s, module) \
300 (s)->main_conf[module.ctx_index]
301 #define ngx_mail_get_module_srv_conf(s, module) (s)->srv_conf[module.ctx_index]
302
303 #define ngx_mail_conf_get_module_main_conf(cf, module) \
304 ((ngx_mail_conf_ctx_t *) cf->ctx)->main_conf[module.ctx_index]
305 #define ngx_mail_conf_get_module_srv_conf(cf, module) \
306 ((ngx_mail_conf_ctx_t *) cf->ctx)->srv_conf[module.ctx_index]
307
308254 typedef void (*ngx_mail_init_session_pt)(ngx_mail_session_t *s,
309255 ngx_connection_t *c);
310256 typedef void (*ngx_mail_init_protocol_pt)(ngx_event_t *rev);
312258 typedef ngx_int_t (*ngx_mail_parse_command_pt)(ngx_mail_session_t *s);
313259
314260
261 struct ngx_mail_protocol_s {
262 ngx_str_t name;
263 in_port_t port[4];
264 ngx_uint_t type;
265
266 ngx_mail_init_session_pt init_session;
267 ngx_mail_init_protocol_pt init_protocol;
268 ngx_mail_parse_command_pt parse_command;
269 ngx_mail_auth_state_pt auth_state;
270
271 ngx_str_t internal_server_error;
272 };
273
274
275 typedef struct {
276 ngx_mail_protocol_t *protocol;
277
278 void *(*create_main_conf)(ngx_conf_t *cf);
279 char *(*init_main_conf)(ngx_conf_t *cf, void *conf);
280
281 void *(*create_srv_conf)(ngx_conf_t *cf);
282 char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev,
283 void *conf);
284 } ngx_mail_module_t;
285
286
287 #define NGX_MAIL_MODULE 0x4C49414D /* "MAIL" */
288
289 #define NGX_MAIL_MAIN_CONF 0x02000000
290 #define NGX_MAIL_SRV_CONF 0x04000000
291
292
293 #define NGX_MAIL_MAIN_CONF_OFFSET offsetof(ngx_mail_conf_ctx_t, main_conf)
294 #define NGX_MAIL_SRV_CONF_OFFSET offsetof(ngx_mail_conf_ctx_t, srv_conf)
295
296
297 #define ngx_mail_get_module_ctx(s, module) (s)->ctx[module.ctx_index]
298 #define ngx_mail_set_ctx(s, c, module) s->ctx[module.ctx_index] = c;
299 #define ngx_mail_delete_ctx(s, module) s->ctx[module.ctx_index] = NULL;
300
301
302 #define ngx_mail_get_module_main_conf(s, module) \
303 (s)->main_conf[module.ctx_index]
304 #define ngx_mail_get_module_srv_conf(s, module) (s)->srv_conf[module.ctx_index]
305
306 #define ngx_mail_conf_get_module_main_conf(cf, module) \
307 ((ngx_mail_conf_ctx_t *) cf->ctx)->main_conf[module.ctx_index]
308 #define ngx_mail_conf_get_module_srv_conf(cf, module) \
309 ((ngx_mail_conf_ctx_t *) cf->ctx)->srv_conf[module.ctx_index]
310
311
315312 #if (NGX_MAIL_SSL)
316313 void ngx_mail_starttls_handler(ngx_event_t *rev);
317314 ngx_int_t ngx_mail_starttls_only(ngx_mail_session_t *s, ngx_connection_t *c);
319316
320317
321318 void ngx_mail_init_connection(ngx_connection_t *c);
322
323 void ngx_mail_pop3_auth_state(ngx_event_t *rev);
324 void ngx_mail_imap_auth_state(ngx_event_t *rev);
325 void ngx_mail_smtp_auth_state(ngx_event_t *rev);
326319
327320 ngx_int_t ngx_mail_salt(ngx_mail_session_t *s, ngx_connection_t *c,
328321 ngx_mail_core_srv_conf_t *cscf);
335328 ngx_int_t ngx_mail_auth_cram_md5_salt(ngx_mail_session_t *s,
336329 ngx_connection_t *c, char *prefix, size_t len);
337330 ngx_int_t ngx_mail_auth_cram_md5(ngx_mail_session_t *s, ngx_connection_t *c);
331 ngx_int_t ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c);
338332
339333 void ngx_mail_send(ngx_event_t *wev);
340334 ngx_int_t ngx_mail_read_command(ngx_mail_session_t *s, ngx_connection_t *c);
344338 u_char *ngx_mail_log_error(ngx_log_t *log, u_char *buf, size_t len);
345339
346340
347 void ngx_mail_pop3_init_session(ngx_mail_session_t *s, ngx_connection_t *c);
348 void ngx_mail_imap_init_session(ngx_mail_session_t *s, ngx_connection_t *c);
349 void ngx_mail_smtp_init_session(ngx_mail_session_t *s, ngx_connection_t *c);
350
351 void ngx_mail_pop3_init_protocol(ngx_event_t *rev);
352 void ngx_mail_imap_init_protocol(ngx_event_t *rev);
353 void ngx_mail_smtp_init_protocol(ngx_event_t *rev);
354
355 ngx_int_t ngx_mail_pop3_parse_command(ngx_mail_session_t *s);
356 ngx_int_t ngx_mail_imap_parse_command(ngx_mail_session_t *s);
357 ngx_int_t ngx_mail_smtp_parse_command(ngx_mail_session_t *s);
358 ngx_int_t ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c);
341 char *ngx_mail_capabilities(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
359342
360343
361344 /* STUB */
110110
111111
112112 static ngx_mail_module_t ngx_mail_auth_http_module_ctx = {
113 NULL, /* protocol */
114
113115 NULL, /* create main configuration */
114116 NULL, /* init main configuration */
115117
134136 };
135137
136138
137 static char *ngx_mail_auth_http_protocol[] = { "pop3", "imap", "smtp" };
138139 static ngx_str_t ngx_mail_auth_http_method[] = {
139140 ngx_string("plain"),
140141 ngx_string("plain"),
143144 };
144145
145146 static ngx_str_t ngx_mail_smtp_errcode = ngx_string("535 5.7.0");
146
147 static ngx_uint_t ngx_mail_start_states[] = {
148 ngx_pop3_start,
149 ngx_imap_start,
150 ngx_smtp_start
151 };
152
153 static ngx_mail_auth_state_pt ngx_mail_auth_states[] = {
154 ngx_mail_pop3_auth_state,
155 ngx_mail_imap_auth_state,
156 ngx_mail_smtp_auth_state
157 };
158147
159148
160149 void
761750 return;
762751 }
763752
764 if (s->passwd.data == NULL && s->protocol != NGX_MAIL_SMTP_PROTOCOL)
753 if (s->passwd.data == NULL
754 && s->protocol != NGX_MAIL_SMTP_PROTOCOL)
765755 {
766756 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
767757 "auth http server %V did not send password",
880870 return;
881871 }
882872
883 s->mail_state = ngx_mail_start_states[s->protocol];
884 rev->handler = ngx_mail_auth_states[s->protocol];
885
873 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
874
875 rev->handler = cscf->protocol->auth_state;
876
877 s->mail_state = 0;
886878 s->auth_method = NGX_MAIL_AUTH_PLAIN;
887879
888880 c->log->action = "in auth state";
892884 if (c->destroyed) {
893885 return;
894886 }
895
896 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
897887
898888 ngx_add_timer(rev, cscf->timeout);
899889
11441134 ngx_mail_auth_http_create_request(ngx_mail_session_t *s, ngx_pool_t *pool,
11451135 ngx_mail_auth_http_conf_t *ahcf)
11461136 {
1147 size_t len;
1148 ngx_buf_t *b;
1149 ngx_str_t login, passwd;
1137 size_t len;
1138 ngx_buf_t *b;
1139 ngx_str_t login, passwd;
1140 ngx_mail_core_srv_conf_t *cscf;
11501141
11511142 if (ngx_mail_auth_http_escape(pool, &s->login, &login) != NGX_OK) {
11521143 return NULL;
11551146 if (ngx_mail_auth_http_escape(pool, &s->passwd, &passwd) != NGX_OK) {
11561147 return NULL;
11571148 }
1149
1150 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
11581151
11591152 len = sizeof("GET ") - 1 + ahcf->uri.len + sizeof(" HTTP/1.0" CRLF) - 1
11601153 + sizeof("Host: ") - 1 + ahcf->host_header.len + sizeof(CRLF) - 1
11641157 + sizeof("Auth-User: ") - 1 + login.len + sizeof(CRLF) - 1
11651158 + sizeof("Auth-Pass: ") - 1 + passwd.len + sizeof(CRLF) - 1
11661159 + sizeof("Auth-Salt: ") - 1 + s->salt.len
1167 + sizeof("Auth-Protocol: imap" CRLF) - 1
1160 + sizeof("Auth-Protocol: ") - 1 + cscf->protocol->name.len
1161 + sizeof(CRLF) - 1
11681162 + sizeof("Auth-Login-Attempt: ") - 1 + NGX_INT_T_LEN
11691163 + sizeof(CRLF) - 1
11701164 + sizeof("Client-IP: ") - 1 + s->connection->addr_text.len
12111205
12121206 b->last = ngx_cpymem(b->last, "Auth-Protocol: ",
12131207 sizeof("Auth-Protocol: ") - 1);
1214 b->last = ngx_cpymem(b->last, ngx_mail_auth_http_protocol[s->protocol],
1215 sizeof("imap") - 1);
1208 b->last = ngx_cpymem(b->last, cscf->protocol->name.data,
1209 cscf->protocol->name.len);
12161210 *b->last++ = CR; *b->last++ = LF;
12171211
12181212 b->last = ngx_sprintf(b->last, "Auth-Login-Attempt: %ui" CRLF,
1717 void *conf);
1818 static char *ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd,
1919 void *conf);
20 static char *ngx_mail_core_capability(ngx_conf_t *cf, ngx_command_t *cmd,
20 static char *ngx_mail_core_protocol(ngx_conf_t *cf, ngx_command_t *cmd,
2121 void *conf);
22
23
24 static ngx_conf_enum_t ngx_mail_core_procotol[] = {
25 { ngx_string("pop3"), NGX_MAIL_POP3_PROTOCOL },
26 { ngx_string("imap"), NGX_MAIL_IMAP_PROTOCOL },
27 { ngx_string("smtp"), NGX_MAIL_SMTP_PROTOCOL },
28 { ngx_null_string, 0 }
29 };
30
31
32 static ngx_str_t ngx_pop3_default_capabilities[] = {
33 ngx_string("TOP"),
34 ngx_string("USER"),
35 ngx_string("UIDL"),
36 ngx_null_string
37 };
38
39
40 static ngx_str_t ngx_imap_default_capabilities[] = {
41 ngx_string("IMAP4"),
42 ngx_string("IMAP4rev1"),
43 ngx_string("UIDPLUS"),
44 ngx_null_string
45 };
46
47
48 static ngx_conf_bitmask_t ngx_pop3_auth_methods[] = {
49 { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED },
50 { ngx_string("apop"), NGX_MAIL_AUTH_APOP_ENABLED },
51 { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED },
52 { ngx_null_string, 0 }
53 };
54
55
56 static ngx_conf_bitmask_t ngx_imap_auth_methods[] = {
57 { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED },
58 { ngx_string("login"), NGX_MAIL_AUTH_LOGIN_ENABLED },
59 { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED },
60 { ngx_null_string, 0 }
61 };
62
63
64 static ngx_conf_bitmask_t ngx_smtp_auth_methods[] = {
65 { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED },
66 { ngx_string("login"), NGX_MAIL_AUTH_LOGIN_ENABLED },
67 { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED },
68 { ngx_null_string, 0 }
69 };
70
71
72 static ngx_str_t ngx_imap_auth_methods_names[] = {
73 ngx_string("AUTH=PLAIN"),
74 ngx_string("AUTH=LOGIN"),
75 ngx_null_string, /* APOP */
76 ngx_string("AUTH=CRAM-MD5")
77 };
78
79
80 static ngx_str_t ngx_smtp_auth_methods_names[] = {
81 ngx_string("PLAIN"),
82 ngx_string("LOGIN"),
83 ngx_null_string, /* APOP */
84 ngx_string("CRAM-MD5")
85 };
86
87
88 static ngx_str_t ngx_pop3_auth_plain_capability =
89 ngx_string("+OK methods supported:" CRLF
90 "LOGIN" CRLF
91 "PLAIN" CRLF
92 "." CRLF);
93
94
95 static ngx_str_t ngx_pop3_auth_cram_md5_capability =
96 ngx_string("+OK methods supported:" CRLF
97 "LOGIN" CRLF
98 "PLAIN" CRLF
99 "CRAM-MD5" CRLF
100 "." CRLF);
101
10222
10323
10424 static ngx_command_t ngx_mail_core_commands[] = {
11333 { ngx_string("listen"),
11434 NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12,
11535 ngx_mail_core_listen,
116 0,
36 NGX_MAIL_SRV_CONF_OFFSET,
11737 0,
11838 NULL },
11939
12040 { ngx_string("protocol"),
12141 NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
122 ngx_conf_set_enum_slot,
42 ngx_mail_core_protocol,
12343 NGX_MAIL_SRV_CONF_OFFSET,
124 offsetof(ngx_mail_core_srv_conf_t, protocol),
125 &ngx_mail_core_procotol },
126
127 { ngx_string("imap_client_buffer"),
128 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
129 ngx_conf_set_size_slot,
130 NGX_MAIL_SRV_CONF_OFFSET,
131 offsetof(ngx_mail_core_srv_conf_t, imap_client_buffer_size),
132 NULL },
133
134 { ngx_string("smtp_client_buffer"),
135 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
136 ngx_conf_set_size_slot,
137 NGX_MAIL_SRV_CONF_OFFSET,
138 offsetof(ngx_mail_core_srv_conf_t, smtp_client_buffer_size),
139 NULL },
140
141 { ngx_string("smtp_greeting_delay"),
142 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
143 ngx_conf_set_msec_slot,
144 NGX_MAIL_SRV_CONF_OFFSET,
145 offsetof(ngx_mail_core_srv_conf_t, smtp_greeting_delay),
44 0,
14645 NULL },
14746
14847 { ngx_string("so_keepalive"),
15958 offsetof(ngx_mail_core_srv_conf_t, timeout),
16059 NULL },
16160
162 { ngx_string("pop3_capabilities"),
163 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
164 ngx_mail_core_capability,
165 NGX_MAIL_SRV_CONF_OFFSET,
166 offsetof(ngx_mail_core_srv_conf_t, pop3_capabilities),
167 NULL },
168
169 { ngx_string("imap_capabilities"),
170 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
171 ngx_mail_core_capability,
172 NGX_MAIL_SRV_CONF_OFFSET,
173 offsetof(ngx_mail_core_srv_conf_t, imap_capabilities),
174 NULL },
175
176 { ngx_string("smtp_capabilities"),
177 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
178 ngx_mail_core_capability,
179 NGX_MAIL_SRV_CONF_OFFSET,
180 offsetof(ngx_mail_core_srv_conf_t, smtp_capabilities),
181 NULL },
182
18361 { ngx_string("server_name"),
18462 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
18563 ngx_conf_set_str_slot,
18765 offsetof(ngx_mail_core_srv_conf_t, server_name),
18866 NULL },
18967
190 { ngx_string("auth"),
191 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
192 ngx_conf_set_bitmask_slot,
193 NGX_MAIL_SRV_CONF_OFFSET,
194 offsetof(ngx_mail_core_srv_conf_t, pop3_auth_methods),
195 &ngx_pop3_auth_methods },
196
197 { ngx_string("pop3_auth"),
198 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
199 ngx_conf_set_bitmask_slot,
200 NGX_MAIL_SRV_CONF_OFFSET,
201 offsetof(ngx_mail_core_srv_conf_t, pop3_auth_methods),
202 &ngx_pop3_auth_methods },
203
204 { ngx_string("imap_auth"),
205 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
206 ngx_conf_set_bitmask_slot,
207 NGX_MAIL_SRV_CONF_OFFSET,
208 offsetof(ngx_mail_core_srv_conf_t, imap_auth_methods),
209 &ngx_imap_auth_methods },
210
211 { ngx_string("smtp_auth"),
212 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
213 ngx_conf_set_bitmask_slot,
214 NGX_MAIL_SRV_CONF_OFFSET,
215 offsetof(ngx_mail_core_srv_conf_t, smtp_auth_methods),
216 &ngx_smtp_auth_methods },
217
21868 ngx_null_command
21969 };
22070
22171
22272 static ngx_mail_module_t ngx_mail_core_module_ctx = {
73 NULL, /* protocol */
74
22375 ngx_mail_core_create_main_conf, /* create main configuration */
22476 NULL, /* init main configuration */
22577
281133 return NULL;
282134 }
283135
284 cscf->imap_client_buffer_size = NGX_CONF_UNSET_SIZE;
285 cscf->smtp_client_buffer_size = NGX_CONF_UNSET_SIZE;
286 cscf->protocol = NGX_CONF_UNSET_UINT;
136 /*
137 * set by ngx_pcalloc():
138 *
139 * cscf->protocol = NULL;
140 */
141
287142 cscf->timeout = NGX_CONF_UNSET_MSEC;
288 cscf->smtp_greeting_delay = NGX_CONF_UNSET_MSEC;
289143 cscf->so_keepalive = NGX_CONF_UNSET;
290
291 if (ngx_array_init(&cscf->pop3_capabilities, cf->pool, 4, sizeof(ngx_str_t))
292 != NGX_OK)
293 {
294 return NULL;
295 }
296
297 if (ngx_array_init(&cscf->imap_capabilities, cf->pool, 4, sizeof(ngx_str_t))
298 != NGX_OK)
299 {
300 return NULL;
301 }
302
303 if (ngx_array_init(&cscf->smtp_capabilities, cf->pool, 4, sizeof(ngx_str_t))
304 != NGX_OK)
305 {
306 return NULL;
307 }
308144
309145 return cscf;
310146 }
316152 ngx_mail_core_srv_conf_t *prev = parent;
317153 ngx_mail_core_srv_conf_t *conf = child;
318154
319 u_char *p, *auth;
320 size_t size, stls_only_size;
321 ngx_str_t *c, *d;
322 ngx_uint_t i, m;
323
324 ngx_conf_merge_size_value(conf->imap_client_buffer_size,
325 prev->imap_client_buffer_size,
326 (size_t) ngx_pagesize);
327 ngx_conf_merge_size_value(conf->smtp_client_buffer_size,
328 prev->smtp_client_buffer_size,
329 (size_t) ngx_pagesize);
330
331155 ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000);
332 ngx_conf_merge_msec_value(conf->smtp_greeting_delay,
333 prev->smtp_greeting_delay, 0);
334
335 ngx_conf_merge_uint_value(conf->protocol, prev->protocol,
336 NGX_MAIL_IMAP_PROTOCOL);
156
337157 ngx_conf_merge_value(conf->so_keepalive, prev->so_keepalive, 0);
338
339 ngx_conf_merge_bitmask_value(conf->pop3_auth_methods,
340 prev->pop3_auth_methods,
341 (NGX_CONF_BITMASK_SET
342 |NGX_MAIL_AUTH_PLAIN_ENABLED));
343
344 ngx_conf_merge_bitmask_value(conf->imap_auth_methods,
345 prev->imap_auth_methods,
346 (NGX_CONF_BITMASK_SET
347 |NGX_MAIL_AUTH_PLAIN_ENABLED));
348
349 ngx_conf_merge_bitmask_value(conf->smtp_auth_methods,
350 prev->smtp_auth_methods,
351 (NGX_CONF_BITMASK_SET
352 |NGX_MAIL_AUTH_PLAIN_ENABLED
353 |NGX_MAIL_AUTH_LOGIN_ENABLED));
354158
355159
356160 ngx_conf_merge_str_value(conf->server_name, prev->server_name, "");
364168 if (gethostname((char *) conf->server_name.data, NGX_MAXHOSTNAMELEN)
365169 == -1)
366170 {
367 ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
368 "gethostname() failed");
171 ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
172 "gethostname() failed");
369173 return NGX_CONF_ERROR;
370174 }
371175
372176 conf->server_name.len = ngx_strlen(conf->server_name.data);
373177 }
374178
375
376 if (conf->pop3_capabilities.nelts == 0) {
377 conf->pop3_capabilities = prev->pop3_capabilities;
378 }
379
380 if (conf->pop3_capabilities.nelts == 0) {
381
382 for (d = ngx_pop3_default_capabilities; d->len; d++) {
383 c = ngx_array_push(&conf->pop3_capabilities);
384 if (c == NULL) {
385 return NGX_CONF_ERROR;
386 }
387
388 *c = *d;
389 }
390 }
391
392 size = sizeof("+OK Capability list follows" CRLF) - 1
393 + sizeof("." CRLF) - 1;
394
395 stls_only_size = size + sizeof("STLS" CRLF) - 1;
396
397 c = conf->pop3_capabilities.elts;
398 for (i = 0; i < conf->pop3_capabilities.nelts; i++) {
399 size += c[i].len + sizeof(CRLF) - 1;
400
401 if (ngx_strcasecmp(c[i].data, (u_char *) "USER") == 0) {
402 continue;
403 }
404
405 stls_only_size += c[i].len + sizeof(CRLF) - 1;
406 }
407
408 if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
409 size += sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1;
410
411 } else {
412 size += sizeof("SASL LOGIN PLAIN" CRLF) - 1;
413 }
414
415 p = ngx_palloc(cf->pool, size);
416 if (p == NULL) {
417 return NGX_CONF_ERROR;
418 }
419
420 conf->pop3_capability.len = size;
421 conf->pop3_capability.data = p;
422
423 p = ngx_cpymem(p, "+OK Capability list follows" CRLF,
424 sizeof("+OK Capability list follows" CRLF) - 1);
425
426 for (i = 0; i < conf->pop3_capabilities.nelts; i++) {
427 p = ngx_cpymem(p, c[i].data, c[i].len);
428 *p++ = CR; *p++ = LF;
429 }
430
431 if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
432 p = ngx_cpymem(p, "SASL LOGIN PLAIN CRAM-MD5" CRLF,
433 sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1);
434
435 } else {
436 p = ngx_cpymem(p, "SASL LOGIN PLAIN" CRLF,
437 sizeof("SASL LOGIN PLAIN" CRLF) - 1);
438 }
439
440 *p++ = '.'; *p++ = CR; *p = LF;
441
442
443 size += sizeof("STLS" CRLF) - 1;
444
445 p = ngx_palloc(cf->pool, size);
446 if (p == NULL) {
447 return NGX_CONF_ERROR;
448 }
449
450 conf->pop3_starttls_capability.len = size;
451 conf->pop3_starttls_capability.data = p;
452
453 p = ngx_cpymem(p, conf->pop3_capability.data,
454 conf->pop3_capability.len - (sizeof("." CRLF) - 1));
455
456 p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1);
457 *p++ = '.'; *p++ = CR; *p = LF;
458
459
460 if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
461 conf->pop3_auth_capability = ngx_pop3_auth_cram_md5_capability;
462
463 } else {
464 conf->pop3_auth_capability = ngx_pop3_auth_plain_capability;
465 }
466
467
468 p = ngx_palloc(cf->pool, stls_only_size);
469 if (p == NULL) {
470 return NGX_CONF_ERROR;
471 }
472
473 conf->pop3_starttls_only_capability.len = stls_only_size;
474 conf->pop3_starttls_only_capability.data = p;
475
476 p = ngx_cpymem(p, "+OK Capability list follows" CRLF,
477 sizeof("+OK Capability list follows" CRLF) - 1);
478
479 for (i = 0; i < conf->pop3_capabilities.nelts; i++) {
480 if (ngx_strcasecmp(c[i].data, (u_char *) "USER") == 0) {
481 continue;
482 }
483
484 p = ngx_cpymem(p, c[i].data, c[i].len);
485 *p++ = CR; *p++ = LF;
486 }
487
488 p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1);
489 *p++ = '.'; *p++ = CR; *p = LF;
490
491
492 if (conf->imap_capabilities.nelts == 0) {
493 conf->imap_capabilities = prev->imap_capabilities;
494 }
495
496 if (conf->imap_capabilities.nelts == 0) {
497
498 for (d = ngx_imap_default_capabilities; d->len; d++) {
499 c = ngx_array_push(&conf->imap_capabilities);
500 if (c == NULL) {
501 return NGX_CONF_ERROR;
502 }
503
504 *c = *d;
505 }
506 }
507
508 size = sizeof("* CAPABILITY" CRLF) - 1;
509
510 c = conf->imap_capabilities.elts;
511 for (i = 0; i < conf->imap_capabilities.nelts; i++) {
512 size += 1 + c[i].len;
513 }
514
515 for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
516 m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
517 m <<= 1, i++)
518 {
519 if (m & conf->imap_auth_methods) {
520 size += 1 + ngx_imap_auth_methods_names[i].len;
521 }
522 }
523
524 p = ngx_palloc(cf->pool, size);
525 if (p == NULL) {
526 return NGX_CONF_ERROR;
527 }
528
529 conf->imap_capability.len = size;
530 conf->imap_capability.data = p;
531
532 p = ngx_cpymem(p, "* CAPABILITY", sizeof("* CAPABILITY") - 1);
533
534 for (i = 0; i < conf->imap_capabilities.nelts; i++) {
535 *p++ = ' ';
536 p = ngx_cpymem(p, c[i].data, c[i].len);
537 }
538
539 auth = p;
540
541 for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
542 m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
543 m <<= 1, i++)
544 {
545 if (m & conf->imap_auth_methods) {
546 *p++ = ' ';
547 p = ngx_cpymem(p, ngx_imap_auth_methods_names[i].data,
548 ngx_imap_auth_methods_names[i].len);
549 }
550 }
551
552 *p++ = CR; *p = LF;
553
554
555 size += sizeof(" STARTTLS") - 1;
556
557 p = ngx_palloc(cf->pool, size);
558 if (p == NULL) {
559 return NGX_CONF_ERROR;
560 }
561
562 conf->imap_starttls_capability.len = size;
563 conf->imap_starttls_capability.data = p;
564
565 p = ngx_cpymem(p, conf->imap_capability.data,
566 conf->imap_capability.len - (sizeof(CRLF) - 1));
567 p = ngx_cpymem(p, " STARTTLS", sizeof(" STARTTLS") - 1);
568 *p++ = CR; *p = LF;
569
570
571 size = (auth - conf->imap_capability.data) + sizeof(CRLF) - 1
572 + sizeof(" STARTTLS LOGINDISABLED") - 1;
573
574 p = ngx_palloc(cf->pool, size);
575 if (p == NULL) {
576 return NGX_CONF_ERROR;
577 }
578
579 conf->imap_starttls_only_capability.len = size;
580 conf->imap_starttls_only_capability.data = p;
581
582 p = ngx_cpymem(p, conf->imap_capability.data,
583 auth - conf->imap_capability.data);
584 p = ngx_cpymem(p, " STARTTLS LOGINDISABLED",
585 sizeof(" STARTTLS LOGINDISABLED") - 1);
586 *p++ = CR; *p = LF;
587
588
589 size = sizeof("220 ESMTP ready" CRLF) - 1 + conf->server_name.len;
590
591 p = ngx_palloc(cf->pool, size);
592 if (p == NULL) {
593 return NGX_CONF_ERROR;
594 }
595
596 conf->smtp_greeting.len = size;
597 conf->smtp_greeting.data = p;
598
599 *p++ = '2'; *p++ = '2'; *p++ = '0'; *p++ = ' ';
600 p = ngx_cpymem(p, conf->server_name.data, conf->server_name.len);
601 ngx_memcpy(p, " ESMTP ready" CRLF, sizeof(" ESMTP ready" CRLF) - 1);
602
603
604 size = sizeof("250 " CRLF) - 1 + conf->server_name.len;
605
606 p = ngx_palloc(cf->pool, size);
607 if (p == NULL) {
608 return NGX_CONF_ERROR;
609 }
610
611 conf->smtp_server_name.len = size;
612 conf->smtp_server_name.data = p;
613
614 *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = ' ';
615 p = ngx_cpymem(p, conf->server_name.data, conf->server_name.len);
616 *p++ = CR; *p = LF;
617
618
619 if (conf->smtp_capabilities.nelts == 0) {
620 conf->smtp_capabilities = prev->smtp_capabilities;
621 }
622
623 size = sizeof("250-") - 1 + conf->server_name.len + sizeof(CRLF) - 1
624 + sizeof("250 AUTH") - 1 + sizeof(CRLF) - 1;
625
626 c = conf->smtp_capabilities.elts;
627 for (i = 0; i < conf->smtp_capabilities.nelts; i++) {
628 size += sizeof("250 ") - 1 + c[i].len + sizeof(CRLF) - 1;
629 }
630
631 for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
632 m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
633 m <<= 1, i++)
634 {
635 if (m & conf->smtp_auth_methods) {
636 size += 1 + ngx_smtp_auth_methods_names[i].len;
637 }
638 }
639
640 p = ngx_palloc(cf->pool, size);
641 if (p == NULL) {
642 return NGX_CONF_ERROR;
643 }
644
645 conf->smtp_capability.len = size;
646 conf->smtp_capability.data = p;
647
648 *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = '-';
649 p = ngx_cpymem(p, conf->server_name.data, conf->server_name.len);
650 *p++ = CR; *p++ = LF;
651
652 for (i = 0; i < conf->smtp_capabilities.nelts; i++) {
653 *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = '-';
654 p = ngx_cpymem(p, c[i].data, c[i].len);
655 *p++ = CR; *p++ = LF;
656 }
657
658 auth = p;
659
660 *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = ' ';
661 *p++ = 'A'; *p++ = 'U'; *p++ = 'T'; *p++ = 'H';
662
663 for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
664 m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
665 m <<= 1, i++)
666 {
667 if (m & conf->smtp_auth_methods) {
668 *p++ = ' ';
669 p = ngx_cpymem(p, ngx_smtp_auth_methods_names[i].data,
670 ngx_smtp_auth_methods_names[i].len);
671 }
672 }
673
674 *p++ = CR; *p = LF;
675
676 size += 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_capability.len = size;
684 conf->smtp_starttls_capability.data = p;
685
686 p = ngx_cpymem(p, conf->smtp_capability.data,
687 conf->smtp_capability.len);
688
689 p = ngx_cpymem(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1);
690 *p++ = CR; *p = LF;
691
692 p = conf->smtp_starttls_capability.data
693 + (auth - conf->smtp_capability.data) + 3;
694 *p = '-';
695
696 size = (auth - conf->smtp_capability.data)
697 + sizeof("250 STARTTLS" CRLF) - 1;
698
699 p = ngx_palloc(cf->pool, size);
700 if (p == NULL) {
701 return NGX_CONF_ERROR;
702 }
703
704 conf->smtp_starttls_only_capability.len = size;
705 conf->smtp_starttls_only_capability.data = p;
706
707 p = ngx_cpymem(p, conf->smtp_capability.data,
708 auth - conf->smtp_capability.data);
709
710 ngx_memcpy(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1);
179 if (conf->protocol == NULL) {
180 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
181 "unknown mail protocol for server in %s:%ui",
182 conf->file_name, conf->line);
183 return NGX_CONF_ERROR;
184 }
711185
712186 return NGX_CONF_OK;
713187 }
725199 ngx_mail_core_srv_conf_t *cscf, **cscfp;
726200 ngx_mail_core_main_conf_t *cmcf;
727201
728
729202 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_mail_conf_ctx_t));
730203 if (ctx == NULL) {
731204 return NGX_CONF_ERROR;
763236 cscf = ctx->srv_conf[ngx_mail_core_module.ctx_index];
764237 cscf->ctx = ctx;
765238
239 cscf->file_name = cf->conf_file->file.name.data;
240 cscf->line = cf->conf_file->line;
241
766242 cmcf = ctx->main_conf[ngx_mail_core_module.ctx_index];
767243
768244 cscfp = ngx_array_push(&cmcf->servers);
792268 static char *
793269 ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
794270 {
271 ngx_mail_core_srv_conf_t *cscf = conf;
272
795273 ngx_str_t *value;
796274 ngx_url_t u;
797 ngx_uint_t i;
275 ngx_uint_t i, m;
798276 ngx_mail_listen_t *imls;
277 ngx_mail_module_t *module;
799278 ngx_mail_core_main_conf_t *cmcf;
800279
801280 value = cf->args->elts;
842321 imls->family = AF_INET;
843322 imls->ctx = cf->ctx;
844323
324 for (m = 0; ngx_modules[m]; m++) {
325 if (ngx_modules[m]->type != NGX_MAIL_MODULE) {
326 continue;
327 }
328
329 module = ngx_modules[m]->ctx;
330
331 if (module->protocol == NULL) {
332 continue;
333 }
334
335 for (i = 0; module->protocol->port[i]; i++) {
336 if (module->protocol->port[i] == u.port) {
337 cscf->protocol = module->protocol;
338 break;
339 }
340 }
341 }
342
845343 if (cf->args->nelts == 2) {
846344 return NGX_CONF_OK;
847345 }
858356
859357
860358 static char *
861 ngx_mail_core_capability(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
359 ngx_mail_core_protocol(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
360 {
361 ngx_mail_core_srv_conf_t *cscf = conf;
362
363 ngx_str_t *value;
364 ngx_uint_t m;
365 ngx_mail_module_t *module;
366
367 value = cf->args->elts;
368
369 for (m = 0; ngx_modules[m]; m++) {
370 if (ngx_modules[m]->type != NGX_MAIL_MODULE) {
371 continue;
372 }
373
374 module = ngx_modules[m]->ctx;
375
376 if (module->protocol
377 && ngx_strcmp(module->protocol->name.data, value[1].data) == 0)
378 {
379 cscf->protocol = module->protocol;
380
381 return NGX_CONF_OK;
382 }
383 }
384
385 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
386 "unknown protocol \"%V\"", &value[1]);
387 return NGX_CONF_ERROR;
388 }
389
390
391 char *
392 ngx_mail_capabilities(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
862393 {
863394 char *p = conf;
864395
1515 static void ngx_mail_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c);
1616 static void ngx_mail_ssl_handshake_handler(ngx_connection_t *c);
1717 #endif
18
19
20 static ngx_mail_init_session_pt ngx_mail_init_sessions[] = {
21 ngx_mail_pop3_init_session,
22 ngx_mail_imap_init_session,
23 ngx_mail_smtp_init_session
24 };
25
26
27 static ngx_mail_init_protocol_pt ngx_mail_init_protocols[] = {
28 ngx_mail_pop3_init_protocol,
29 ngx_mail_imap_init_protocol,
30 ngx_mail_smtp_init_protocol
31 };
32
33
34 static ngx_mail_parse_command_pt ngx_mail_parse_commands[] = {
35 ngx_mail_pop3_parse_command,
36 ngx_mail_imap_parse_command,
37 ngx_mail_smtp_parse_command
38 };
39
40
41 static ngx_str_t internal_server_errors[] = {
42 ngx_string("-ERR internal server error" CRLF),
43 ngx_string("* BAD internal server error" CRLF),
44 ngx_string("451 4.3.2 Internal server error" CRLF),
45 };
4618
4719
4820 void
209181 static void
210182 ngx_mail_ssl_handshake_handler(ngx_connection_t *c)
211183 {
212 ngx_mail_session_t *s;
184 ngx_mail_session_t *s;
185 ngx_mail_core_srv_conf_t *cscf;
213186
214187 if (c->ssl->handshaked) {
215188
216189 s = c->data;
217190
218191 if (s->starttls) {
219 c->read->handler = ngx_mail_init_protocols[s->protocol];
192 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
193
194 c->read->handler = cscf->protocol->init_protocol;
220195 c->write->handler = ngx_mail_send;
221196
222 ngx_mail_init_protocols[s->protocol](c->read);
197 cscf->protocol->init_protocol(c->read);
223198
224199 return;
225200 }
244219
245220 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
246221
247 s->protocol = cscf->protocol;
222 s->protocol = cscf->protocol->type;
248223
249224 s->ctx = ngx_pcalloc(c->pool, sizeof(void *) * ngx_mail_max_module);
250225 if (s->ctx == NULL) {
254229
255230 c->write->handler = ngx_mail_send;
256231
257 ngx_mail_init_sessions[s->protocol](s, c);
232 cscf->protocol->init_session(s, c);
258233 }
259234
260235
566541 ngx_int_t
567542 ngx_mail_read_command(ngx_mail_session_t *s, ngx_connection_t *c)
568543 {
569 ssize_t n;
570 ngx_int_t rc;
571 ngx_str_t l;
544 ssize_t n;
545 ngx_int_t rc;
546 ngx_str_t l;
547 ngx_mail_core_srv_conf_t *cscf;
572548
573549 n = c->recv(c, s->buffer->last, s->buffer->end - s->buffer->last);
574550
590566 return NGX_AGAIN;
591567 }
592568
593 rc = ngx_mail_parse_commands[s->protocol](s);
569 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
570
571 rc = cscf->protocol->parse_command(s);
594572
595573 if (rc == NGX_AGAIN) {
596574
643621 void
644622 ngx_mail_session_internal_server_error(ngx_mail_session_t *s)
645623 {
646 s->out = internal_server_errors[s->protocol];
624 ngx_mail_core_srv_conf_t *cscf;
625
626 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
627
628 s->out = cscf->protocol->internal_server_error;
647629 s->quit = 1;
648630
649631 ngx_mail_send(s->connection->write);
77 #include <ngx_core.h>
88 #include <ngx_event.h>
99 #include <ngx_mail.h>
10 #include <ngx_mail_imap_module.h>
1011
1112
1213 static ngx_int_t ngx_mail_imap_login(ngx_mail_session_t *s,
5758 {
5859 ngx_connection_t *c;
5960 ngx_mail_session_t *s;
60 ngx_mail_core_srv_conf_t *cscf;
61 ngx_mail_imap_srv_conf_t *iscf;
6162
6263 c = rev->data;
6364
8081 return;
8182 }
8283
83 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
84
85 s->buffer = ngx_create_temp_buf(c->pool, cscf->imap_client_buffer_size);
84 iscf = ngx_mail_get_module_srv_conf(s, ngx_mail_imap_module);
85
86 s->buffer = ngx_create_temp_buf(c->pool, iscf->client_buffer_size);
8687 if (s->buffer == NULL) {
8788 ngx_mail_session_internal_server_error(s);
8889 return;
348349 {
349350 ngx_int_t rc;
350351 ngx_mail_core_srv_conf_t *cscf;
352 ngx_mail_imap_srv_conf_t *iscf;
351353
352354 #if (NGX_MAIL_SSL)
353355 if (ngx_mail_starttls_only(s, c)) {
377379
378380 case NGX_MAIL_AUTH_CRAM_MD5:
379381
380 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
381
382 if (!(cscf->imap_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED)) {
382 iscf = ngx_mail_get_module_srv_conf(s, ngx_mail_imap_module);
383
384 if (!(iscf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED)) {
383385 return NGX_MAIL_PARSE_INVALID_COMMAND;
384386 }
385387
386388 if (s->salt.data == NULL) {
389 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
390
387391 if (ngx_mail_salt(s, c, cscf) != NGX_OK) {
388392 return NGX_ERROR;
389393 }
404408 static ngx_int_t
405409 ngx_mail_imap_capability(ngx_mail_session_t *s, ngx_connection_t *c)
406410 {
407 ngx_mail_core_srv_conf_t *cscf;
411 ngx_mail_imap_srv_conf_t *iscf;
408412 #if (NGX_MAIL_SSL)
409413 ngx_mail_ssl_conf_t *sslcf;
410414 #endif
411415
412 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
416 iscf = ngx_mail_get_module_srv_conf(s, ngx_mail_imap_module);
413417
414418 #if (NGX_MAIL_SSL)
415419
417421 sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
418422
419423 if (sslcf->starttls == NGX_MAIL_STARTTLS_ON) {
420 s->text = cscf->imap_starttls_capability;
424 s->text = iscf->starttls_capability;
421425 return NGX_OK;
422426 }
423427
424428 if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
425 s->text = cscf->imap_starttls_only_capability;
429 s->text = iscf->starttls_only_capability;
426430 return NGX_OK;
427431 }
428432 }
429433 #endif
430434
431 s->text = cscf->imap_capability;
435 s->text = iscf->capability;
432436
433437 return NGX_OK;
434438 }
0
1 /*
2 * Copyright (C) Igor Sysoev
3 */
4
5
6 #include <ngx_config.h>
7 #include <ngx_core.h>
8 #include <ngx_event.h>
9 #include <ngx_mail.h>
10 #include <ngx_mail_imap_module.h>
11
12
13 static void *ngx_mail_imap_create_srv_conf(ngx_conf_t *cf);
14 static char *ngx_mail_imap_merge_srv_conf(ngx_conf_t *cf, void *parent,
15 void *child);
16
17
18 static ngx_str_t ngx_mail_imap_default_capabilities[] = {
19 ngx_string("IMAP4"),
20 ngx_string("IMAP4rev1"),
21 ngx_string("UIDPLUS"),
22 ngx_null_string
23 };
24
25
26 static ngx_conf_bitmask_t ngx_mail_imap_auth_methods[] = {
27 { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED },
28 { ngx_string("login"), NGX_MAIL_AUTH_LOGIN_ENABLED },
29 { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED },
30 { ngx_null_string, 0 }
31 };
32
33
34 static ngx_str_t ngx_mail_imap_auth_methods_names[] = {
35 ngx_string("AUTH=PLAIN"),
36 ngx_string("AUTH=LOGIN"),
37 ngx_null_string, /* APOP */
38 ngx_string("AUTH=CRAM-MD5")
39 };
40
41
42 static ngx_mail_protocol_t ngx_mail_imap_protocol = {
43 ngx_string("imap"),
44 { 143, 993, 0, 0 },
45 NGX_MAIL_IMAP_PROTOCOL,
46
47 ngx_mail_imap_init_session,
48 ngx_mail_imap_init_protocol,
49 ngx_mail_imap_parse_command,
50 ngx_mail_imap_auth_state,
51
52 ngx_string("* BAD internal server error" CRLF)
53 };
54
55
56 static ngx_command_t ngx_mail_imap_commands[] = {
57
58 { ngx_string("imap_client_buffer"),
59 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
60 ngx_conf_set_size_slot,
61 NGX_MAIL_SRV_CONF_OFFSET,
62 offsetof(ngx_mail_imap_srv_conf_t, client_buffer_size),
63 NULL },
64
65 { ngx_string("imap_capabilities"),
66 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
67 ngx_mail_capabilities,
68 NGX_MAIL_SRV_CONF_OFFSET,
69 offsetof(ngx_mail_imap_srv_conf_t, capabilities),
70 NULL },
71
72 { ngx_string("imap_auth"),
73 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
74 ngx_conf_set_bitmask_slot,
75 NGX_MAIL_SRV_CONF_OFFSET,
76 offsetof(ngx_mail_imap_srv_conf_t, auth_methods),
77 &ngx_mail_imap_auth_methods },
78
79 ngx_null_command
80 };
81
82
83 static ngx_mail_module_t ngx_mail_imap_module_ctx = {
84 &ngx_mail_imap_protocol, /* protocol */
85
86 NULL, /* create main configuration */
87 NULL, /* init main configuration */
88
89 ngx_mail_imap_create_srv_conf, /* create server configuration */
90 ngx_mail_imap_merge_srv_conf /* merge server configuration */
91 };
92
93
94 ngx_module_t ngx_mail_imap_module = {
95 NGX_MODULE_V1,
96 &ngx_mail_imap_module_ctx, /* module context */
97 ngx_mail_imap_commands, /* module directives */
98 NGX_MAIL_MODULE, /* module type */
99 NULL, /* init master */
100 NULL, /* init module */
101 NULL, /* init process */
102 NULL, /* init thread */
103 NULL, /* exit thread */
104 NULL, /* exit process */
105 NULL, /* exit master */
106 NGX_MODULE_V1_PADDING
107 };
108
109
110 static void *
111 ngx_mail_imap_create_srv_conf(ngx_conf_t *cf)
112 {
113 ngx_mail_imap_srv_conf_t *iscf;
114
115 iscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_imap_srv_conf_t));
116 if (iscf == NULL) {
117 return NULL;
118 }
119
120 iscf->client_buffer_size = NGX_CONF_UNSET_SIZE;
121
122 if (ngx_array_init(&iscf->capabilities, cf->pool, 4, sizeof(ngx_str_t))
123 != NGX_OK)
124 {
125 return NULL;
126 }
127
128 return iscf;
129 }
130
131
132 static char *
133 ngx_mail_imap_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
134 {
135 ngx_mail_imap_srv_conf_t *prev = parent;
136 ngx_mail_imap_srv_conf_t *conf = child;
137
138 u_char *p, *auth;
139 size_t size;
140 ngx_str_t *c, *d;
141 ngx_uint_t i, m;
142
143 ngx_conf_merge_size_value(conf->client_buffer_size,
144 prev->client_buffer_size,
145 (size_t) ngx_pagesize);
146
147 ngx_conf_merge_bitmask_value(conf->auth_methods,
148 prev->auth_methods,
149 (NGX_CONF_BITMASK_SET
150 |NGX_MAIL_AUTH_PLAIN_ENABLED));
151
152
153 if (conf->capabilities.nelts == 0) {
154 conf->capabilities = prev->capabilities;
155 }
156
157 if (conf->capabilities.nelts == 0) {
158
159 for (d = ngx_mail_imap_default_capabilities; d->len; d++) {
160 c = ngx_array_push(&conf->capabilities);
161 if (c == NULL) {
162 return NGX_CONF_ERROR;
163 }
164
165 *c = *d;
166 }
167 }
168
169 size = sizeof("* CAPABILITY" CRLF) - 1;
170
171 c = conf->capabilities.elts;
172 for (i = 0; i < conf->capabilities.nelts; i++) {
173 size += 1 + c[i].len;
174 }
175
176 for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
177 m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
178 m <<= 1, i++)
179 {
180 if (m & conf->auth_methods) {
181 size += 1 + ngx_mail_imap_auth_methods_names[i].len;
182 }
183 }
184
185 p = ngx_palloc(cf->pool, size);
186 if (p == NULL) {
187 return NGX_CONF_ERROR;
188 }
189
190 conf->capability.len = size;
191 conf->capability.data = p;
192
193 p = ngx_cpymem(p, "* CAPABILITY", sizeof("* CAPABILITY") - 1);
194
195 for (i = 0; i < conf->capabilities.nelts; i++) {
196 *p++ = ' ';
197 p = ngx_cpymem(p, c[i].data, c[i].len);
198 }
199
200 auth = p;
201
202 for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
203 m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
204 m <<= 1, i++)
205 {
206 if (m & conf->auth_methods) {
207 *p++ = ' ';
208 p = ngx_cpymem(p, ngx_mail_imap_auth_methods_names[i].data,
209 ngx_mail_imap_auth_methods_names[i].len);
210 }
211 }
212
213 *p++ = CR; *p = LF;
214
215
216 size += sizeof(" STARTTLS") - 1;
217
218 p = ngx_palloc(cf->pool, size);
219 if (p == NULL) {
220 return NGX_CONF_ERROR;
221 }
222
223 conf->starttls_capability.len = size;
224 conf->starttls_capability.data = p;
225
226 p = ngx_cpymem(p, conf->capability.data,
227 conf->capability.len - (sizeof(CRLF) - 1));
228 p = ngx_cpymem(p, " STARTTLS", sizeof(" STARTTLS") - 1);
229 *p++ = CR; *p = LF;
230
231
232 size = (auth - conf->capability.data) + sizeof(CRLF) - 1
233 + sizeof(" STARTTLS LOGINDISABLED") - 1;
234
235 p = ngx_palloc(cf->pool, size);
236 if (p == NULL) {
237 return NGX_CONF_ERROR;
238 }
239
240 conf->starttls_only_capability.len = size;
241 conf->starttls_only_capability.data = p;
242
243 p = ngx_cpymem(p, conf->capability.data,
244 auth - conf->capability.data);
245 p = ngx_cpymem(p, " STARTTLS LOGINDISABLED",
246 sizeof(" STARTTLS LOGINDISABLED") - 1);
247 *p++ = CR; *p = LF;
248
249 return NGX_CONF_OK;
250 }
0
1 /*
2 * Copyright (C) Igor Sysoev
3 */
4
5
6 #ifndef _NGX_MAIL_IMAP_MODULE_H_INCLUDED_
7 #define _NGX_MAIL_IMAP_MODULE_H_INCLUDED_
8
9
10 #include <ngx_config.h>
11 #include <ngx_core.h>
12 #include <ngx_mail.h>
13
14
15 typedef struct {
16 size_t client_buffer_size;
17
18 ngx_str_t capability;
19 ngx_str_t starttls_capability;
20 ngx_str_t starttls_only_capability;
21
22 ngx_uint_t auth_methods;
23
24 ngx_array_t capabilities;
25 } ngx_mail_imap_srv_conf_t;
26
27
28 void ngx_mail_imap_init_session(ngx_mail_session_t *s, ngx_connection_t *c);
29 void ngx_mail_imap_init_protocol(ngx_event_t *rev);
30 void ngx_mail_imap_auth_state(ngx_event_t *rev);
31 ngx_int_t ngx_mail_imap_parse_command(ngx_mail_session_t *s);
32
33
34 extern ngx_module_t ngx_mail_imap_module;
35
36
37 #endif /* _NGX_MAIL_IMAP_MODULE_H_INCLUDED_ */
77 #include <ngx_core.h>
88 #include <ngx_event.h>
99 #include <ngx_mail.h>
10 #include <ngx_mail_pop3_module.h>
1011
1112
1213 static ngx_int_t ngx_mail_pop3_user(ngx_mail_session_t *s, ngx_connection_t *c);
3132 {
3233 u_char *p;
3334 ngx_mail_core_srv_conf_t *cscf;
34
35 ngx_mail_pop3_srv_conf_t *pscf;
36
37 pscf = ngx_mail_get_module_srv_conf(s, ngx_mail_pop3_module);
3538 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
3639
37 if (cscf->pop3_auth_methods
40 if (pscf->auth_methods
3841 & (NGX_MAIL_AUTH_APOP_ENABLED|NGX_MAIL_AUTH_CRAM_MD5_ENABLED))
3942 {
4043 if (ngx_mail_salt(s, c, cscf) != NGX_OK) {
339342 static ngx_int_t
340343 ngx_mail_pop3_capa(ngx_mail_session_t *s, ngx_connection_t *c, ngx_int_t stls)
341344 {
342 ngx_mail_core_srv_conf_t *cscf;
345 ngx_mail_pop3_srv_conf_t *pscf;
343346 #if (NGX_MAIL_SSL)
344347 ngx_mail_ssl_conf_t *sslcf;
345348 #endif
346349
347 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
350 pscf = ngx_mail_get_module_srv_conf(s, ngx_mail_pop3_module);
348351
349352 #if (NGX_MAIL_SSL)
350353
352355 sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
353356
354357 if (sslcf->starttls == NGX_MAIL_STARTTLS_ON) {
355 s->out = cscf->pop3_starttls_capability;
358 s->out = pscf->starttls_capability;
356359 return NGX_OK;
357360 }
358361
359362 if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
360 s->out = cscf->pop3_starttls_only_capability;
363 s->out = pscf->starttls_only_capability;
361364 return NGX_OK;
362365 }
363366 }
364367
365368 #endif
366369
367 s->out = cscf->pop3_capability;
370 s->out = pscf->capability;
368371 return NGX_OK;
369372 }
370373
393396 ngx_mail_pop3_apop(ngx_mail_session_t *s, ngx_connection_t *c)
394397 {
395398 ngx_str_t *arg;
396 ngx_mail_core_srv_conf_t *cscf;
399 ngx_mail_pop3_srv_conf_t *pscf;
397400
398401 #if (NGX_MAIL_SSL)
399402 if (ngx_mail_starttls_only(s, c)) {
405408 return NGX_MAIL_PARSE_INVALID_COMMAND;
406409 }
407410
408 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
409
410 if (!(cscf->pop3_auth_methods & NGX_MAIL_AUTH_APOP_ENABLED)) {
411 pscf = ngx_mail_get_module_srv_conf(s, ngx_mail_pop3_module);
412
413 if (!(pscf->auth_methods & NGX_MAIL_AUTH_APOP_ENABLED)) {
411414 return NGX_MAIL_PARSE_INVALID_COMMAND;
412415 }
413416
442445 ngx_mail_pop3_auth(ngx_mail_session_t *s, ngx_connection_t *c)
443446 {
444447 ngx_int_t rc;
445 ngx_mail_core_srv_conf_t *cscf;
448 ngx_mail_pop3_srv_conf_t *pscf;
446449
447450 #if (NGX_MAIL_SSL)
448451 if (ngx_mail_starttls_only(s, c)) {
450453 }
451454 #endif
452455
453 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
456 pscf = ngx_mail_get_module_srv_conf(s, ngx_mail_pop3_module);
454457
455458 if (s->args.nelts == 0) {
456 s->out = cscf->pop3_auth_capability;
459 s->out = pscf->auth_capability;
457460 s->state = 0;
458461
459462 return NGX_OK;
481484
482485 case NGX_MAIL_AUTH_CRAM_MD5:
483486
484 if (!(cscf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED)) {
487 if (!(pscf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED)) {
485488 return NGX_MAIL_PARSE_INVALID_COMMAND;
486489 }
487490
0
1 /*
2 * Copyright (C) Igor Sysoev
3 */
4
5
6 #include <ngx_config.h>
7 #include <ngx_core.h>
8 #include <ngx_event.h>
9 #include <ngx_mail.h>
10 #include <ngx_mail_pop3_module.h>
11
12
13 static void *ngx_mail_pop3_create_srv_conf(ngx_conf_t *cf);
14 static char *ngx_mail_pop3_merge_srv_conf(ngx_conf_t *cf, void *parent,
15 void *child);
16
17
18 static ngx_str_t ngx_mail_pop3_default_capabilities[] = {
19 ngx_string("TOP"),
20 ngx_string("USER"),
21 ngx_string("UIDL"),
22 ngx_null_string
23 };
24
25
26 static ngx_conf_bitmask_t ngx_mail_pop3_auth_methods[] = {
27 { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED },
28 { ngx_string("apop"), NGX_MAIL_AUTH_APOP_ENABLED },
29 { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED },
30 { ngx_null_string, 0 }
31 };
32
33
34 static ngx_str_t ngx_mail_pop3_auth_plain_capability =
35 ngx_string("+OK methods supported:" CRLF
36 "LOGIN" CRLF
37 "PLAIN" CRLF
38 "." CRLF);
39
40
41 static ngx_str_t ngx_mail_pop3_auth_cram_md5_capability =
42 ngx_string("+OK methods supported:" CRLF
43 "LOGIN" CRLF
44 "PLAIN" CRLF
45 "CRAM-MD5" CRLF
46 "." CRLF);
47
48
49 static ngx_mail_protocol_t ngx_mail_pop3_protocol = {
50 ngx_string("pop3"),
51 { 110, 995, 0, 0 },
52 NGX_MAIL_POP3_PROTOCOL,
53
54 ngx_mail_pop3_init_session,
55 ngx_mail_pop3_init_protocol,
56 ngx_mail_pop3_parse_command,
57 ngx_mail_pop3_auth_state,
58
59 ngx_string("-ERR internal server error" CRLF)
60 };
61
62
63 static ngx_command_t ngx_mail_pop3_commands[] = {
64
65 { ngx_string("pop3_capabilities"),
66 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
67 ngx_mail_capabilities,
68 NGX_MAIL_SRV_CONF_OFFSET,
69 offsetof(ngx_mail_pop3_srv_conf_t, capabilities),
70 NULL },
71
72 { ngx_string("pop3_auth"),
73 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
74 ngx_conf_set_bitmask_slot,
75 NGX_MAIL_SRV_CONF_OFFSET,
76 offsetof(ngx_mail_pop3_srv_conf_t, auth_methods),
77 &ngx_mail_pop3_auth_methods },
78
79 ngx_null_command
80 };
81
82
83 static ngx_mail_module_t ngx_mail_pop3_module_ctx = {
84 &ngx_mail_pop3_protocol, /* protocol */
85
86 NULL, /* create main configuration */
87 NULL, /* init main configuration */
88
89 ngx_mail_pop3_create_srv_conf, /* create server configuration */
90 ngx_mail_pop3_merge_srv_conf /* merge server configuration */
91 };
92
93
94 ngx_module_t ngx_mail_pop3_module = {
95 NGX_MODULE_V1,
96 &ngx_mail_pop3_module_ctx, /* module context */
97 ngx_mail_pop3_commands, /* module directives */
98 NGX_MAIL_MODULE, /* module type */
99 NULL, /* init master */
100 NULL, /* init module */
101 NULL, /* init process */
102 NULL, /* init thread */
103 NULL, /* exit thread */
104 NULL, /* exit process */
105 NULL, /* exit master */
106 NGX_MODULE_V1_PADDING
107 };
108
109
110 static void *
111 ngx_mail_pop3_create_srv_conf(ngx_conf_t *cf)
112 {
113 ngx_mail_pop3_srv_conf_t *pscf;
114
115 pscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_pop3_srv_conf_t));
116 if (pscf == NULL) {
117 return NULL;
118 }
119
120 if (ngx_array_init(&pscf->capabilities, cf->pool, 4, sizeof(ngx_str_t))
121 != NGX_OK)
122 {
123 return NULL;
124 }
125
126 return pscf;
127 }
128
129
130 static char *
131 ngx_mail_pop3_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
132 {
133 ngx_mail_pop3_srv_conf_t *prev = parent;
134 ngx_mail_pop3_srv_conf_t *conf = child;
135
136 u_char *p;
137 size_t size, stls_only_size;
138 ngx_str_t *c, *d;
139 ngx_uint_t i;
140
141 ngx_conf_merge_bitmask_value(conf->auth_methods,
142 prev->auth_methods,
143 (NGX_CONF_BITMASK_SET
144 |NGX_MAIL_AUTH_PLAIN_ENABLED));
145
146 if (conf->capabilities.nelts == 0) {
147 conf->capabilities = prev->capabilities;
148 }
149
150 if (conf->capabilities.nelts == 0) {
151
152 for (d = ngx_mail_pop3_default_capabilities; d->len; d++) {
153 c = ngx_array_push(&conf->capabilities);
154 if (c == NULL) {
155 return NGX_CONF_ERROR;
156 }
157
158 *c = *d;
159 }
160 }
161
162 size = sizeof("+OK Capability list follows" CRLF) - 1
163 + sizeof("." CRLF) - 1;
164
165 stls_only_size = size + sizeof("STLS" CRLF) - 1;
166
167 c = conf->capabilities.elts;
168 for (i = 0; i < conf->capabilities.nelts; i++) {
169 size += c[i].len + sizeof(CRLF) - 1;
170
171 if (ngx_strcasecmp(c[i].data, (u_char *) "USER") == 0) {
172 continue;
173 }
174
175 stls_only_size += c[i].len + sizeof(CRLF) - 1;
176 }
177
178 if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
179 size += sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1;
180
181 } else {
182 size += sizeof("SASL LOGIN PLAIN" CRLF) - 1;
183 }
184
185 p = ngx_palloc(cf->pool, size);
186 if (p == NULL) {
187 return NGX_CONF_ERROR;
188 }
189
190 conf->capability.len = size;
191 conf->capability.data = p;
192
193 p = ngx_cpymem(p, "+OK Capability list follows" CRLF,
194 sizeof("+OK Capability list follows" CRLF) - 1);
195
196 for (i = 0; i < conf->capabilities.nelts; i++) {
197 p = ngx_cpymem(p, c[i].data, c[i].len);
198 *p++ = CR; *p++ = LF;
199 }
200
201 if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
202 p = ngx_cpymem(p, "SASL LOGIN PLAIN CRAM-MD5" CRLF,
203 sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1);
204
205 } else {
206 p = ngx_cpymem(p, "SASL LOGIN PLAIN" CRLF,
207 sizeof("SASL LOGIN PLAIN" CRLF) - 1);
208 }
209
210 *p++ = '.'; *p++ = CR; *p = LF;
211
212
213 size += sizeof("STLS" CRLF) - 1;
214
215 p = ngx_palloc(cf->pool, size);
216 if (p == NULL) {
217 return NGX_CONF_ERROR;
218 }
219
220 conf->starttls_capability.len = size;
221 conf->starttls_capability.data = p;
222
223 p = ngx_cpymem(p, conf->capability.data,
224 conf->capability.len - (sizeof("." CRLF) - 1));
225
226 p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1);
227 *p++ = '.'; *p++ = CR; *p = LF;
228
229
230 if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
231 conf->auth_capability = ngx_mail_pop3_auth_cram_md5_capability;
232
233 } else {
234 conf->auth_capability = ngx_mail_pop3_auth_plain_capability;
235 }
236
237
238 p = ngx_palloc(cf->pool, stls_only_size);
239 if (p == NULL) {
240 return NGX_CONF_ERROR;
241 }
242
243 conf->starttls_only_capability.len = stls_only_size;
244 conf->starttls_only_capability.data = p;
245
246 p = ngx_cpymem(p, "+OK Capability list follows" CRLF,
247 sizeof("+OK Capability list follows" CRLF) - 1);
248
249 for (i = 0; i < conf->capabilities.nelts; i++) {
250 if (ngx_strcasecmp(c[i].data, (u_char *) "USER") == 0) {
251 continue;
252 }
253
254 p = ngx_cpymem(p, c[i].data, c[i].len);
255 *p++ = CR; *p++ = LF;
256 }
257
258 p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1);
259 *p++ = '.'; *p++ = CR; *p = LF;
260
261 return NGX_CONF_OK;
262 }
0
1 /*
2 * Copyright (C) Igor Sysoev
3 */
4
5
6 #ifndef _NGX_MAIL_POP3_MODULE_H_INCLUDED_
7 #define _NGX_MAIL_POP3_MODULE_H_INCLUDED_
8
9
10 #include <ngx_config.h>
11 #include <ngx_core.h>
12 #include <ngx_mail.h>
13
14
15 typedef struct {
16 ngx_str_t capability;
17 ngx_str_t starttls_capability;
18 ngx_str_t starttls_only_capability;
19 ngx_str_t auth_capability;
20
21 ngx_uint_t auth_methods;
22
23 ngx_array_t capabilities;
24 } ngx_mail_pop3_srv_conf_t;
25
26
27 void ngx_mail_pop3_init_session(ngx_mail_session_t *s, ngx_connection_t *c);
28 void ngx_mail_pop3_init_protocol(ngx_event_t *rev);
29 void ngx_mail_pop3_auth_state(ngx_event_t *rev);
30 ngx_int_t ngx_mail_pop3_parse_command(ngx_mail_session_t *s);
31
32
33 extern ngx_module_t ngx_mail_pop3_module;
34
35
36 #endif /* _NGX_MAIL_POP3_MODULE_H_INCLUDED_ */
7777
7878
7979 static ngx_mail_module_t ngx_mail_proxy_module_ctx = {
80 NULL, /* protocol */
81
8082 NULL, /* create main configuration */
8183 NULL, /* init main configuration */
8284
77 #include <ngx_core.h>
88 #include <ngx_event.h>
99 #include <ngx_mail.h>
10 #include <ngx_mail_smtp_module.h>
1011
1112
1213 static void ngx_mail_smtp_invalid_pipelining(ngx_event_t *rev);
4243 {
4344 ngx_msec_t timeout;
4445 ngx_mail_core_srv_conf_t *cscf;
46 ngx_mail_smtp_srv_conf_t *sscf;
4547
4648 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
47
48 timeout = cscf->smtp_greeting_delay ? cscf->smtp_greeting_delay:
49 cscf->timeout;
49 sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module);
50
51 timeout = sscf->greeting_delay ? sscf->greeting_delay : cscf->timeout;
5052 ngx_add_timer(c->read, timeout);
5153
5254 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
5355 ngx_mail_close_connection(c);
5456 }
5557
56 if (cscf->smtp_greeting_delay) {
58 if (sscf->greeting_delay) {
5759 c->read->handler = ngx_mail_smtp_invalid_pipelining;
5860 return;
5961 }
6062
6163 c->read->handler = ngx_mail_smtp_init_protocol;
6264
63 s->out = cscf->smtp_greeting;
65 s->out = sscf->greeting;
6466
6567 ngx_mail_send(c->write);
6668 }
7274 ngx_connection_t *c;
7375 ngx_mail_session_t *s;
7476 ngx_mail_core_srv_conf_t *cscf;
77 ngx_mail_smtp_srv_conf_t *sscf;
7578
7679 c = rev->data;
7780 s = c->data;
9598 return;
9699 }
97100
98 s->out = cscf->smtp_greeting;
101 sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module);
102
103 s->out = sscf->greeting;
99104
100105 } else {
101106
157162 static ngx_int_t
158163 ngx_mail_smtp_create_buffer(ngx_mail_session_t *s, ngx_connection_t *c)
159164 {
160 ngx_mail_core_srv_conf_t *cscf;
165 ngx_mail_smtp_srv_conf_t *sscf;
161166
162167 if (ngx_array_init(&s->args, c->pool, 2, sizeof(ngx_str_t)) == NGX_ERROR) {
163168 ngx_mail_session_internal_server_error(s);
164169 return NGX_ERROR;
165170 }
166171
167 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
168
169 s->buffer = ngx_create_temp_buf(c->pool, cscf->smtp_client_buffer_size);
172 sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module);
173
174 s->buffer = ngx_create_temp_buf(c->pool, sscf->client_buffer_size);
170175 if (s->buffer == NULL) {
171176 ngx_mail_session_internal_server_error(s);
172177 return NGX_ERROR;
312317 ngx_mail_smtp_helo(ngx_mail_session_t *s, ngx_connection_t *c)
313318 {
314319 ngx_str_t *arg;
315 ngx_mail_core_srv_conf_t *cscf;
320 ngx_mail_smtp_srv_conf_t *sscf;
316321 #if (NGX_MAIL_SSL)
317322 ngx_mail_ssl_conf_t *sslcf;
318323 #endif
319
320 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
321324
322325 if (s->args.nelts != 1) {
323326 s->out.len = sizeof(smtp_invalid_argument) - 1;
337340
338341 ngx_memcpy(s->smtp_helo.data, arg[0].data, arg[0].len);
339342
343 sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module);
344
340345 if (s->command == NGX_SMTP_HELO) {
341 s->out = cscf->smtp_server_name;
346 s->out = sscf->server_name;
342347
343348 } else {
344349 s->esmtp = 1;
349354 sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
350355
351356 if (sslcf->starttls == NGX_MAIL_STARTTLS_ON) {
352 s->out = cscf->smtp_starttls_capability;
357 s->out = sscf->starttls_capability;
353358 return NGX_OK;
354359 }
355360
356361 if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
357 s->out = cscf->smtp_starttls_only_capability;
362 s->out = sscf->starttls_only_capability;
358363 return NGX_OK;
359364 }
360365 }
361366 #endif
362367
363 s->out = cscf->smtp_capability;
368 s->out = sscf->capability;
364369 }
365370
366371 return NGX_OK;
372377 {
373378 ngx_int_t rc;
374379 ngx_mail_core_srv_conf_t *cscf;
380 ngx_mail_smtp_srv_conf_t *sscf;
375381
376382 #if (NGX_MAIL_SSL)
377383 if (ngx_mail_starttls_only(s, c)) {
408414
409415 case NGX_MAIL_AUTH_CRAM_MD5:
410416
411 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
412
413 if (!(cscf->smtp_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED)) {
417 sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module);
418
419 if (!(sscf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED)) {
414420 return NGX_MAIL_PARSE_INVALID_COMMAND;
415421 }
416422
417423 if (s->salt.data == NULL) {
424 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
425
418426 if (ngx_mail_salt(s, c, cscf) != NGX_OK) {
419427 return NGX_ERROR;
420428 }
0
1 /*
2 * Copyright (C) Igor Sysoev
3 */
4
5
6 #include <ngx_config.h>
7 #include <ngx_core.h>
8 #include <ngx_event.h>
9 #include <ngx_mail.h>
10 #include <ngx_mail_smtp_module.h>
11
12
13 static void *ngx_mail_smtp_create_srv_conf(ngx_conf_t *cf);
14 static char *ngx_mail_smtp_merge_srv_conf(ngx_conf_t *cf, void *parent,
15 void *child);
16
17
18 static ngx_conf_bitmask_t ngx_mail_smtp_auth_methods[] = {
19 { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED },
20 { ngx_string("login"), NGX_MAIL_AUTH_LOGIN_ENABLED },
21 { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED },
22 { ngx_null_string, 0 }
23 };
24
25
26 static ngx_str_t ngx_mail_smtp_auth_methods_names[] = {
27 ngx_string("PLAIN"),
28 ngx_string("LOGIN"),
29 ngx_null_string, /* APOP */
30 ngx_string("CRAM-MD5")
31 };
32
33
34 static ngx_mail_protocol_t ngx_mail_smtp_protocol = {
35 ngx_string("smtp"),
36 { 25, 465, 587, 0 },
37 NGX_MAIL_SMTP_PROTOCOL,
38
39 ngx_mail_smtp_init_session,
40 ngx_mail_smtp_init_protocol,
41 ngx_mail_smtp_parse_command,
42 ngx_mail_smtp_auth_state,
43
44 ngx_string("451 4.3.2 Internal server error" CRLF)
45 };
46
47
48 static ngx_command_t ngx_mail_smtp_commands[] = {
49
50 { ngx_string("smtp_client_buffer"),
51 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
52 ngx_conf_set_size_slot,
53 NGX_MAIL_SRV_CONF_OFFSET,
54 offsetof(ngx_mail_smtp_srv_conf_t, client_buffer_size),
55 NULL },
56
57 { ngx_string("smtp_greeting_delay"),
58 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
59 ngx_conf_set_msec_slot,
60 NGX_MAIL_SRV_CONF_OFFSET,
61 offsetof(ngx_mail_smtp_srv_conf_t, greeting_delay),
62 NULL },
63
64 { ngx_string("smtp_capabilities"),
65 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
66 ngx_mail_capabilities,
67 NGX_MAIL_SRV_CONF_OFFSET,
68 offsetof(ngx_mail_smtp_srv_conf_t, capabilities),
69 NULL },
70
71 { ngx_string("smtp_auth"),
72 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
73 ngx_conf_set_bitmask_slot,
74 NGX_MAIL_SRV_CONF_OFFSET,
75 offsetof(ngx_mail_smtp_srv_conf_t, auth_methods),
76 &ngx_mail_smtp_auth_methods },
77
78 ngx_null_command
79 };
80
81
82 static ngx_mail_module_t ngx_mail_smtp_module_ctx = {
83 &ngx_mail_smtp_protocol, /* protocol */
84
85 NULL, /* create main configuration */
86 NULL, /* init main configuration */
87
88 ngx_mail_smtp_create_srv_conf, /* create server configuration */
89 ngx_mail_smtp_merge_srv_conf /* merge server configuration */
90 };
91
92
93 ngx_module_t ngx_mail_smtp_module = {
94 NGX_MODULE_V1,
95 &ngx_mail_smtp_module_ctx, /* module context */
96 ngx_mail_smtp_commands, /* module directives */
97 NGX_MAIL_MODULE, /* module type */
98 NULL, /* init master */
99 NULL, /* init module */
100 NULL, /* init process */
101 NULL, /* init thread */
102 NULL, /* exit thread */
103 NULL, /* exit process */
104 NULL, /* exit master */
105 NGX_MODULE_V1_PADDING
106 };
107
108
109 static void *
110 ngx_mail_smtp_create_srv_conf(ngx_conf_t *cf)
111 {
112 ngx_mail_smtp_srv_conf_t *sscf;
113
114 sscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_smtp_srv_conf_t));
115 if (sscf == NULL) {
116 return NULL;
117 }
118
119 sscf->client_buffer_size = NGX_CONF_UNSET_SIZE;
120 sscf->greeting_delay = NGX_CONF_UNSET_MSEC;
121
122 if (ngx_array_init(&sscf->capabilities, cf->pool, 4, sizeof(ngx_str_t))
123 != NGX_OK)
124 {
125 return NULL;
126 }
127
128 return sscf;
129 }
130
131
132 static char *
133 ngx_mail_smtp_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
134 {
135 ngx_mail_smtp_srv_conf_t *prev = parent;
136 ngx_mail_smtp_srv_conf_t *conf = child;
137
138 u_char *p, *auth;
139 size_t size;
140 ngx_str_t *c;
141 ngx_uint_t i, m;
142 ngx_mail_core_srv_conf_t *cscf;
143
144 ngx_conf_merge_size_value(conf->client_buffer_size,
145 prev->client_buffer_size,
146 (size_t) ngx_pagesize);
147
148 ngx_conf_merge_msec_value(conf->greeting_delay,
149 prev->greeting_delay, 0);
150
151 ngx_conf_merge_bitmask_value(conf->auth_methods,
152 prev->auth_methods,
153 (NGX_CONF_BITMASK_SET
154 |NGX_MAIL_AUTH_PLAIN_ENABLED
155 |NGX_MAIL_AUTH_LOGIN_ENABLED));
156
157
158 cscf = ngx_mail_conf_get_module_srv_conf(cf, ngx_mail_core_module);
159
160 size = sizeof("220 ESMTP ready" CRLF) - 1 + cscf->server_name.len;
161
162 p = ngx_palloc(cf->pool, size);
163 if (p == NULL) {
164 return NGX_CONF_ERROR;
165 }
166
167 conf->greeting.len = size;
168 conf->greeting.data = p;
169
170 *p++ = '2'; *p++ = '2'; *p++ = '0'; *p++ = ' ';
171 p = ngx_cpymem(p, cscf->server_name.data, cscf->server_name.len);
172 ngx_memcpy(p, " ESMTP ready" CRLF, sizeof(" ESMTP ready" CRLF) - 1);
173
174
175 size = sizeof("250 " CRLF) - 1 + cscf->server_name.len;
176
177 p = ngx_palloc(cf->pool, size);
178 if (p == NULL) {
179 return NGX_CONF_ERROR;
180 }
181
182 conf->server_name.len = size;
183 conf->server_name.data = p;
184
185 *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = ' ';
186 p = ngx_cpymem(p, cscf->server_name.data, cscf->server_name.len);
187 *p++ = CR; *p = LF;
188
189
190 if (conf->capabilities.nelts == 0) {
191 conf->capabilities = prev->capabilities;
192 }
193
194 size = sizeof("250-") - 1 + cscf->server_name.len + sizeof(CRLF) - 1
195 + sizeof("250 AUTH") - 1 + sizeof(CRLF) - 1;
196
197 c = conf->capabilities.elts;
198 for (i = 0; i < conf->capabilities.nelts; i++) {
199 size += sizeof("250 ") - 1 + c[i].len + sizeof(CRLF) - 1;
200 }
201
202 for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
203 m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
204 m <<= 1, i++)
205 {
206 if (m & conf->auth_methods) {
207 size += 1 + ngx_mail_smtp_auth_methods_names[i].len;
208 }
209 }
210
211 p = ngx_palloc(cf->pool, size);
212 if (p == NULL) {
213 return NGX_CONF_ERROR;
214 }
215
216 conf->capability.len = size;
217 conf->capability.data = p;
218
219 *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = '-';
220 p = ngx_cpymem(p, cscf->server_name.data, cscf->server_name.len);
221 *p++ = CR; *p++ = LF;
222
223 for (i = 0; i < conf->capabilities.nelts; i++) {
224 *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = '-';
225 p = ngx_cpymem(p, c[i].data, c[i].len);
226 *p++ = CR; *p++ = LF;
227 }
228
229 auth = p;
230
231 *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = ' ';
232 *p++ = 'A'; *p++ = 'U'; *p++ = 'T'; *p++ = 'H';
233
234 for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
235 m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
236 m <<= 1, i++)
237 {
238 if (m & conf->auth_methods) {
239 *p++ = ' ';
240 p = ngx_cpymem(p, ngx_mail_smtp_auth_methods_names[i].data,
241 ngx_mail_smtp_auth_methods_names[i].len);
242 }
243 }
244
245 *p++ = CR; *p = LF;
246
247 size += sizeof("250 STARTTLS" CRLF) - 1;
248
249 p = ngx_palloc(cf->pool, size);
250 if (p == NULL) {
251 return NGX_CONF_ERROR;
252 }
253
254 conf->starttls_capability.len = size;
255 conf->starttls_capability.data = p;
256
257 p = ngx_cpymem(p, conf->capability.data,
258 conf->capability.len);
259
260 p = ngx_cpymem(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1);
261 *p++ = CR; *p = LF;
262
263 p = conf->starttls_capability.data
264 + (auth - conf->capability.data) + 3;
265 *p = '-';
266
267 size = (auth - conf->capability.data)
268 + sizeof("250 STARTTLS" CRLF) - 1;
269
270 p = ngx_palloc(cf->pool, size);
271 if (p == NULL) {
272 return NGX_CONF_ERROR;
273 }
274
275 conf->starttls_only_capability.len = size;
276 conf->starttls_only_capability.data = p;
277
278 p = ngx_cpymem(p, conf->capability.data,
279 auth - conf->capability.data);
280
281 ngx_memcpy(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1);
282
283 return NGX_CONF_OK;
284 }
0
1 /*
2 * Copyright (C) Igor Sysoev
3 */
4
5
6 #ifndef _NGX_MAIL_SMTP_MODULE_H_INCLUDED_
7 #define _NGX_MAIL_SMTP_MODULE_H_INCLUDED_
8
9
10 #include <ngx_config.h>
11 #include <ngx_core.h>
12 #include <ngx_mail.h>
13 #include <ngx_mail_smtp_module.h>
14
15
16 typedef struct {
17 ngx_msec_t greeting_delay;
18
19 size_t client_buffer_size;
20
21 ngx_str_t capability;
22 ngx_str_t starttls_capability;
23 ngx_str_t starttls_only_capability;
24
25 ngx_str_t server_name;
26 ngx_str_t greeting;
27
28 ngx_uint_t auth_methods;
29
30 ngx_array_t capabilities;
31 } ngx_mail_smtp_srv_conf_t;
32
33
34 void ngx_mail_smtp_init_session(ngx_mail_session_t *s, ngx_connection_t *c);
35 void ngx_mail_smtp_init_protocol(ngx_event_t *rev);
36 void ngx_mail_smtp_auth_state(ngx_event_t *rev);
37 ngx_int_t ngx_mail_smtp_parse_command(ngx_mail_session_t *s);
38
39
40 extern ngx_module_t ngx_mail_smtp_module;
41
42
43 #endif /* _NGX_MAIL_SMTP_MODULE_H_INCLUDED_ */
119119
120120
121121 static ngx_mail_module_t ngx_mail_ssl_module_ctx = {
122 NULL, /* protocol */
123
122124 NULL, /* create main configuration */
123125 NULL, /* init main configuration */
124126