Mercurial > hg > nginx
annotate src/imap/ngx_imap_handler.c @ 583:4e296b7d25bf release-0.3.13
nginx-0.3.13-RELEASE import
*) Feature: the IMAP/POP3 proxy supports STARTTLS and STLS.
*) Bugfix: the IMAP/POP3 proxy did not work with the select, poll, and
/dev/poll methods.
*) Bugfix: in SSI handling.
*) Bugfix: now Solaris sendfilev() is not used to transfer the client
request body to FastCGI-server via the unix domain socket.
*) Bugfix: the "auth_basic" directive did not disable the
authorization; the bug had appeared in 0.3.11.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 05 Dec 2005 13:18:09 +0000 |
parents | 4d9ea73a627a |
children | 5e8fb59c18c1 |
rev | line source |
---|---|
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
423
diff
changeset
|
1 |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
423
diff
changeset
|
2 /* |
444
42d11f017717
nginx-0.1.0-2004-09-29-20:00:49 import; remove years from copyright
Igor Sysoev <igor@sysoev.ru>
parents:
441
diff
changeset
|
3 * Copyright (C) Igor Sysoev |
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
423
diff
changeset
|
4 */ |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
423
diff
changeset
|
5 |
413
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
6 |
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
7 #include <ngx_config.h> |
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
8 #include <ngx_core.h> |
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
9 #include <ngx_event.h> |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
10 #include <ngx_imap.h> |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
11 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
12 |
547 | 13 static void ngx_imap_init_session(ngx_connection_t *c); |
541 | 14 static void ngx_imap_init_protocol(ngx_event_t *rev); |
527 | 15 static ngx_int_t ngx_imap_read_command(ngx_imap_session_t *s); |
541 | 16 static u_char *ngx_imap_log_error(ngx_log_t *log, u_char *buf, size_t len); |
413
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
17 |
539 | 18 #if (NGX_IMAP_SSL) |
583 | 19 static void ngx_imap_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c); |
547 | 20 static void ngx_imap_ssl_handshake_handler(ngx_connection_t *c); |
539 | 21 #endif |
22 | |
413
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
23 |
521 | 24 static ngx_str_t greetings[] = { |
527 | 25 ngx_string("+OK POP3 ready" CRLF), |
529 | 26 ngx_string("* OK IMAP4 ready" CRLF) |
521 | 27 }; |
28 | |
525 | 29 static ngx_str_t internal_server_errors[] = { |
30 ngx_string("-ERR internal server error" CRLF), | |
31 ngx_string("* BAD internal server error" CRLF), | |
32 }; | |
33 | |
521 | 34 static u_char pop3_ok[] = "+OK" CRLF; |
35 static u_char pop3_invalid_command[] = "-ERR invalid command" CRLF; | |
36 | |
543 | 37 static u_char imap_star[] = "* "; |
529 | 38 static u_char imap_ok[] = "OK completed" CRLF; |
527 | 39 static u_char imap_next[] = "+ OK" CRLF; |
40 static u_char imap_bye[] = "* BYE" CRLF; | |
41 static u_char imap_invalid_command[] = "BAD invalid command" CRLF; | |
42 | |
521 | 43 |
44 void | |
45 ngx_imap_init_connection(ngx_connection_t *c) | |
413
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
46 { |
583 | 47 ngx_imap_log_ctx_t *lctx; |
543 | 48 #if (NGX_IMAP_SSL) |
583 | 49 ngx_imap_conf_ctx_t *ctx; |
50 ngx_imap_ssl_conf_t *sslcf; | |
543 | 51 #endif |
541 | 52 |
547 | 53 ngx_log_error(NGX_LOG_INFO, c->log, 0, "*%ui client %V connected to %V", |
54 c->number, &c->addr_text, &c->listening->addr_text); | |
541 | 55 |
543 | 56 lctx = ngx_palloc(c->pool, sizeof(ngx_imap_log_ctx_t)); |
57 if (lctx == NULL) { | |
541 | 58 ngx_imap_close_connection(c); |
59 return; | |
577 | 60 } |
541 | 61 |
543 | 62 lctx->client = &c->addr_text; |
63 lctx->session = NULL; | |
541 | 64 |
65 c->log->connection = c->number; | |
66 c->log->handler = ngx_imap_log_error; | |
543 | 67 c->log->data = lctx; |
541 | 68 c->log->action = "sending client greeting line"; |
69 | |
70 c->log_error = NGX_ERROR_INFO; | |
71 | |
543 | 72 #if (NGX_IMAP_SSL) |
73 | |
74 ctx = c->ctx; | |
75 sslcf = ngx_imap_get_module_srv_conf(ctx, ngx_imap_ssl_module); | |
76 | |
77 if (sslcf->enable) { | |
583 | 78 ngx_imap_ssl_init_connection(&sslcf->ssl, c); |
547 | 79 return; |
543 | 80 } |
81 | |
82 #endif | |
83 | |
547 | 84 ngx_imap_init_session(c); |
541 | 85 } |
86 | |
87 | |
547 | 88 #if (NGX_IMAP_SSL) |
89 | |
541 | 90 static void |
583 | 91 ngx_imap_starttls_handler(ngx_event_t *rev) |
92 { | |
93 ngx_connection_t *c; | |
94 ngx_imap_session_t *s; | |
95 ngx_imap_ssl_conf_t *sslcf; | |
96 | |
97 c = rev->data; | |
98 s = c->data; | |
99 | |
100 c->log->action = "in starttls state"; | |
101 | |
102 sslcf = ngx_imap_get_module_srv_conf(s, ngx_imap_ssl_module); | |
103 | |
104 ngx_imap_ssl_init_connection(&sslcf->ssl, c); | |
105 } | |
106 | |
107 | |
108 static void | |
109 ngx_imap_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c) | |
110 { | |
111 ngx_imap_conf_ctx_t *ctx; | |
112 ngx_imap_core_srv_conf_t *cscf; | |
113 | |
114 if (ngx_ssl_create_connection(ssl, c, 0) == NGX_ERROR) { | |
115 ngx_imap_close_connection(c); | |
116 return; | |
117 } | |
118 | |
119 if (ngx_ssl_handshake(c) == NGX_AGAIN) { | |
120 | |
121 ctx = c->ctx; | |
122 cscf = ngx_imap_get_module_srv_conf(ctx, ngx_imap_core_module); | |
123 | |
124 ngx_add_timer(c->read, cscf->timeout); | |
125 | |
126 c->ssl->handler = ngx_imap_ssl_handshake_handler; | |
127 | |
128 return; | |
129 } | |
130 | |
131 ngx_imap_ssl_handshake_handler(c); | |
132 } | |
133 | |
134 | |
135 static void | |
547 | 136 ngx_imap_ssl_handshake_handler(ngx_connection_t *c) |
577 | 137 { |
547 | 138 if (c->ssl->handshaked) { |
583 | 139 |
140 if (c->data) { | |
141 c->read->handler = ngx_imap_init_protocol; | |
142 c->write->handler = ngx_imap_send; | |
143 | |
144 ngx_imap_init_protocol(c->read); | |
145 | |
146 return; | |
147 } | |
148 | |
547 | 149 ngx_imap_init_session(c); |
150 return; | |
151 } | |
152 | |
153 ngx_imap_close_connection(c); | |
154 } | |
155 | |
156 #endif | |
157 | |
158 | |
159 static void | |
160 ngx_imap_init_session(ngx_connection_t *c) | |
541 | 161 { |
539 | 162 ngx_imap_session_t *s; |
541 | 163 ngx_imap_log_ctx_t *lctx; |
521 | 164 ngx_imap_conf_ctx_t *ctx; |
541 | 165 ngx_imap_core_srv_conf_t *cscf; |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
166 |
547 | 167 c->read->handler = ngx_imap_init_protocol; |
168 c->write->handler = ngx_imap_send; | |
539 | 169 |
170 s = ngx_pcalloc(c->pool, sizeof(ngx_imap_session_t)); | |
171 if (s == NULL) { | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
172 ngx_imap_close_connection(c); |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
173 return; |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
174 } |
413
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
175 |
547 | 176 ctx = c->ctx; |
177 cscf = ngx_imap_get_module_srv_conf(ctx, ngx_imap_core_module); | |
178 | |
539 | 179 c->data = s; |
180 s->connection = c; | |
181 | |
182 s->protocol = cscf->protocol; | |
183 | |
184 s->ctx = ngx_pcalloc(c->pool, sizeof(void *) * ngx_imap_max_module); | |
185 if (s->ctx == NULL) { | |
186 ngx_imap_session_internal_server_error(s); | |
187 return; | |
188 } | |
189 | |
190 s->main_conf = ctx->main_conf; | |
191 s->srv_conf = ctx->srv_conf; | |
192 | |
193 s->out = greetings[s->protocol]; | |
194 | |
541 | 195 lctx = c->log->data; |
196 lctx->session = s; | |
197 | |
547 | 198 ngx_add_timer(c->read, cscf->timeout); |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
199 |
547 | 200 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) { |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
201 ngx_imap_close_connection(c); |
413
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
202 } |
539 | 203 |
204 ngx_imap_send(c->write); | |
205 } | |
206 | |
207 | |
208 void | |
209 ngx_imap_send(ngx_event_t *wev) | |
210 { | |
541 | 211 ngx_int_t n; |
212 ngx_connection_t *c; | |
213 ngx_imap_session_t *s; | |
214 ngx_imap_core_srv_conf_t *cscf; | |
539 | 215 |
216 c = wev->data; | |
217 s = c->data; | |
218 | |
219 if (wev->timedout) { | |
220 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); | |
577 | 221 c->timedout = 1; |
539 | 222 ngx_imap_close_connection(c); |
223 return; | |
224 } | |
225 | |
226 if (s->out.len == 0) { | |
227 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { | |
228 ngx_imap_close_connection(c); | |
229 } | |
230 | |
231 return; | |
232 } | |
233 | |
234 n = c->send(c, s->out.data, s->out.len); | |
235 | |
236 if (n > 0) { | |
237 s->out.len -= n; | |
238 | |
541 | 239 if (wev->timer_set) { |
240 ngx_del_timer(wev); | |
241 } | |
242 | |
539 | 243 if (s->quit) { |
244 ngx_imap_close_connection(c); | |
245 return; | |
246 } | |
247 | |
248 if (s->blocked) { | |
249 c->read->handler(c->read); | |
250 } | |
251 | |
252 return; | |
253 } | |
254 | |
255 if (n == NGX_ERROR) { | |
256 ngx_imap_close_connection(c); | |
257 return; | |
258 } | |
259 | |
260 /* n == NGX_AGAIN */ | |
261 | |
541 | 262 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); |
263 | |
264 ngx_add_timer(c->write, cscf->timeout); | |
265 | |
539 | 266 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { |
267 ngx_imap_close_connection(c); | |
268 return; | |
269 } | |
413
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
270 } |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
271 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
272 |
521 | 273 static void |
541 | 274 ngx_imap_init_protocol(ngx_event_t *rev) |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
275 { |
521 | 276 size_t size; |
277 ngx_connection_t *c; | |
278 ngx_imap_session_t *s; | |
279 ngx_imap_core_srv_conf_t *cscf; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
280 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
281 c = rev->data; |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
282 |
541 | 283 c->log->action = "in auth state"; |
284 | |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
285 if (rev->timedout) { |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
286 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); |
577 | 287 c->timedout = 1; |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
288 ngx_imap_close_connection(c); |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
289 return; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
290 } |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
291 |
539 | 292 s = c->data; |
521 | 293 |
539 | 294 if (s->protocol == NGX_IMAP_POP3_PROTOCOL) { |
521 | 295 size = 128; |
527 | 296 s->imap_state = ngx_pop3_start; |
521 | 297 c->read->handler = ngx_pop3_auth_state; |
298 | |
299 } else { | |
539 | 300 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); |
521 | 301 size = cscf->imap_client_buffer_size; |
527 | 302 s->imap_state = ngx_imap_start; |
521 | 303 c->read->handler = ngx_imap_auth_state; |
304 } | |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
305 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
306 if (s->buffer == NULL) { |
583 | 307 if (ngx_array_init(&s->args, c->pool, 2, sizeof(ngx_str_t)) |
308 == NGX_ERROR) | |
309 { | |
310 ngx_imap_session_internal_server_error(s); | |
311 return; | |
312 } | |
313 | |
314 s->buffer = ngx_create_temp_buf(c->pool, size); | |
315 if (s->buffer == NULL) { | |
316 ngx_imap_session_internal_server_error(s); | |
317 return; | |
318 } | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
319 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
320 |
521 | 321 c->read->handler(rev); |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
322 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
323 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
324 |
527 | 325 void |
521 | 326 ngx_imap_auth_state(ngx_event_t *rev) |
327 { | |
543 | 328 u_char *text, *last, *p, *dst, *src, *end; |
539 | 329 ssize_t text_len, last_len; |
527 | 330 ngx_str_t *arg; |
331 ngx_int_t rc; | |
543 | 332 ngx_uint_t tag, i; |
527 | 333 ngx_connection_t *c; |
334 ngx_imap_session_t *s; | |
335 ngx_imap_core_srv_conf_t *cscf; | |
583 | 336 #if (NGX_IMAP_SSL) |
337 ngx_imap_ssl_conf_t *sslcf; | |
338 #endif | |
521 | 339 |
340 c = rev->data; | |
527 | 341 s = c->data; |
521 | 342 |
527 | 343 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap auth state"); |
344 | |
345 if (rev->timedout) { | |
346 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); | |
577 | 347 c->timedout = 1; |
527 | 348 ngx_imap_close_connection(c); |
349 return; | |
350 } | |
351 | |
539 | 352 if (s->out.len) { |
353 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap send handler busy"); | |
354 s->blocked = 1; | |
355 return; | |
356 } | |
357 | |
358 s->blocked = 0; | |
359 | |
527 | 360 rc = ngx_imap_read_command(s); |
361 | |
362 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap auth: %i", rc); | |
363 | |
364 if (rc == NGX_AGAIN || rc == NGX_ERROR) { | |
365 return; | |
366 } | |
367 | |
368 tag = 1; | |
369 | |
370 text = NULL; | |
371 text_len = 0; | |
372 | |
373 last = imap_ok; | |
374 last_len = sizeof(imap_ok) - 1; | |
375 | |
376 if (rc == NGX_OK) { | |
377 | |
378 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap auth command: %i", | |
379 s->command); | |
380 | |
543 | 381 if (s->backslash) { |
382 | |
383 arg = s->args.elts; | |
384 | |
385 for (i = 0; i < s->args.nelts; i++) { | |
386 dst = arg[i].data; | |
387 end = dst + arg[i].len; | |
388 | |
389 for (src = dst; src < end; dst++) { | |
390 *dst = *src; | |
391 if (*src++ == '\\') { | |
392 *dst = *src++; | |
393 } | |
394 } | |
395 | |
396 arg[i].len = dst - arg[i].data; | |
397 } | |
398 | |
399 s->backslash = 0; | |
400 } | |
401 | |
527 | 402 switch (s->command) { |
403 | |
404 case NGX_IMAP_LOGIN: | |
583 | 405 |
406 #if (NGX_IMAP_SSL) | |
407 | |
408 if (c->ssl == NULL) { | |
409 sslcf = ngx_imap_get_module_srv_conf(s, ngx_imap_ssl_module); | |
410 | |
411 if (sslcf->starttls == NGX_IMAP_STARTTLS_ONLY) { | |
412 rc = NGX_IMAP_PARSE_INVALID_COMMAND; | |
413 break; | |
414 } | |
415 } | |
416 #endif | |
417 | |
569 | 418 arg = s->args.elts; |
527 | 419 |
569 | 420 if (s->args.nelts == 2 && arg[0].len) { |
527 | 421 |
422 s->login.len = arg[0].len; | |
423 s->login.data = ngx_palloc(c->pool, s->login.len); | |
424 if (s->login.data == NULL) { | |
425 ngx_imap_session_internal_server_error(s); | |
426 return; | |
427 } | |
428 | |
429 ngx_memcpy(s->login.data, arg[0].data, s->login.len); | |
430 | |
431 s->passwd.len = arg[1].len; | |
432 s->passwd.data = ngx_palloc(c->pool, s->passwd.len); | |
433 if (s->passwd.data == NULL) { | |
434 ngx_imap_session_internal_server_error(s); | |
435 return; | |
436 } | |
437 | |
438 ngx_memcpy(s->passwd.data, arg[1].data, s->passwd.len); | |
439 | |
547 | 440 #if (NGX_DEBUG_IMAP_PASSWD) |
527 | 441 ngx_log_debug2(NGX_LOG_DEBUG_IMAP, c->log, 0, |
442 "imap login:\"%V\" passwd:\"%V\"", | |
443 &s->login, &s->passwd); | |
547 | 444 #else |
445 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, | |
446 "imap login:\"%V\"", &s->login); | |
447 #endif | |
527 | 448 |
449 s->args.nelts = 0; | |
450 s->buffer->pos = s->buffer->start; | |
451 s->buffer->last = s->buffer->start; | |
452 | |
453 if (rev->timer_set) { | |
454 ngx_del_timer(rev); | |
455 } | |
456 | |
457 s->login_attempt++; | |
458 | |
459 ngx_imap_auth_http_init(s); | |
460 | |
461 return; | |
462 | |
463 } else { | |
464 rc = NGX_IMAP_PARSE_INVALID_COMMAND; | |
465 } | |
466 | |
467 break; | |
468 | |
469 case NGX_IMAP_CAPABILITY: | |
470 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); | |
583 | 471 |
472 #if (NGX_IMAP_SSL) | |
473 | |
474 if (c->ssl == NULL) { | |
475 sslcf = ngx_imap_get_module_srv_conf(s, ngx_imap_ssl_module); | |
476 | |
477 if (sslcf->starttls == NGX_IMAP_STARTTLS_ON) { | |
478 text_len = cscf->imap_starttls_capability.len; | |
479 text = cscf->imap_starttls_capability.data; | |
480 break; | |
481 } | |
482 | |
483 if (sslcf->starttls == NGX_IMAP_STARTTLS_ONLY) { | |
484 text_len = cscf->imap_starttls_only_capability.len; | |
485 text = cscf->imap_starttls_only_capability.data; | |
486 break; | |
487 } | |
488 } | |
489 #endif | |
490 | |
491 text_len = cscf->imap_capability.len; | |
492 text = cscf->imap_capability.data; | |
527 | 493 break; |
494 | |
495 case NGX_IMAP_LOGOUT: | |
539 | 496 s->quit = 1; |
527 | 497 text = imap_bye; |
498 text_len = sizeof(imap_bye) - 1; | |
499 break; | |
500 | |
501 case NGX_IMAP_NOOP: | |
502 break; | |
503 | |
583 | 504 #if (NGX_IMAP_SSL) |
505 | |
506 case NGX_IMAP_STARTTLS: | |
507 if (c->ssl == NULL) { | |
508 sslcf = ngx_imap_get_module_srv_conf(s, ngx_imap_ssl_module); | |
509 if (sslcf->starttls) { | |
510 c->read->handler = ngx_imap_starttls_handler; | |
511 break; | |
512 } | |
513 } | |
514 | |
515 rc = NGX_IMAP_PARSE_INVALID_COMMAND; | |
516 break; | |
517 #endif | |
518 | |
527 | 519 default: |
520 rc = NGX_IMAP_PARSE_INVALID_COMMAND; | |
521 break; | |
522 } | |
523 | |
524 } else if (rc == NGX_IMAP_NEXT) { | |
525 last = imap_next; | |
526 last_len = sizeof(imap_next) - 1; | |
527 tag = 0; | |
528 } | |
529 | |
530 if (rc == NGX_IMAP_PARSE_INVALID_COMMAND) { | |
531 last = imap_invalid_command; | |
532 last_len = sizeof(imap_invalid_command) - 1; | |
533 } | |
534 | |
535 if (tag) { | |
543 | 536 if (s->tag.len == 0) { |
537 s->tag.len = sizeof(imap_star) - 1; | |
538 s->tag.data = (u_char *) imap_star; | |
539 } | |
540 | |
539 | 541 if (s->tagged_line.len < s->tag.len + text_len + last_len) { |
542 s->tagged_line.len = s->tag.len + text_len + last_len; | |
543 s->tagged_line.data = ngx_palloc(c->pool, s->tagged_line.len); | |
544 if (s->tagged_line.data == NULL) { | |
527 | 545 ngx_imap_close_connection(c); |
546 return; | |
547 } | |
548 } | |
549 | |
539 | 550 s->out.data = s->tagged_line.data; |
551 s->out.len = s->tag.len + text_len + last_len; | |
552 | |
553 p = s->out.data; | |
527 | 554 |
555 if (text) { | |
556 p = ngx_cpymem(p, text, text_len); | |
557 } | |
558 p = ngx_cpymem(p, s->tag.data, s->tag.len); | |
559 ngx_memcpy(p, last, last_len); | |
560 | |
561 | |
562 } else { | |
539 | 563 s->out.data = last; |
564 s->out.len = last_len; | |
527 | 565 } |
566 | |
539 | 567 if (rc != NGX_IMAP_NEXT) { |
568 s->args.nelts = 0; | |
569 s->buffer->pos = s->buffer->start; | |
570 s->buffer->last = s->buffer->start; | |
571 s->tag.len = 0; | |
527 | 572 } |
573 | |
539 | 574 ngx_imap_send(c->write); |
521 | 575 } |
576 | |
577 | |
527 | 578 void |
521 | 579 ngx_pop3_auth_state(ngx_event_t *rev) |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
580 { |
527 | 581 u_char *text; |
582 ssize_t size; | |
583 ngx_int_t rc; | |
584 ngx_str_t *arg; | |
585 ngx_connection_t *c; | |
586 ngx_imap_session_t *s; | |
587 ngx_imap_core_srv_conf_t *cscf; | |
583 | 588 #if (NGX_IMAP_SSL) |
589 ngx_imap_ssl_conf_t *sslcf; | |
590 #endif | |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
591 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
592 c = rev->data; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
593 s = c->data; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
594 |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
595 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, c->log, 0, "pop3 auth state"); |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
596 |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
597 if (rev->timedout) { |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
598 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); |
577 | 599 c->timedout = 1; |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
600 ngx_imap_close_connection(c); |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
601 return; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
602 } |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
603 |
539 | 604 if (s->out.len) { |
605 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap send handler busy"); | |
606 s->blocked = 1; | |
607 return; | |
608 } | |
609 | |
610 s->blocked = 0; | |
611 | |
527 | 612 rc = ngx_imap_read_command(s); |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
613 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
614 if (rc == NGX_AGAIN || rc == NGX_ERROR) { |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
615 return; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
616 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
617 |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
618 text = pop3_ok; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
619 size = sizeof(pop3_ok) - 1; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
620 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
621 if (rc == NGX_OK) { |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
622 switch (s->imap_state) { |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
623 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
624 case ngx_pop3_start: |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
625 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
626 switch (s->command) { |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
627 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
628 case NGX_POP3_USER: |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
629 if (s->args.nelts == 1) { |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
630 s->imap_state = ngx_pop3_user; |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
631 |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
632 arg = s->args.elts; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
633 s->login.len = arg[0].len; |
527 | 634 s->login.data = ngx_palloc(c->pool, s->login.len); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
635 if (s->login.data == NULL) { |
527 | 636 ngx_imap_session_internal_server_error(s); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
637 return; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
638 } |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
639 |
527 | 640 ngx_memcpy(s->login.data, arg[0].data, s->login.len); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
641 |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
642 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, |
527 | 643 "pop3 login: \"%V\"", &s->login); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
644 |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
645 } else { |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
646 rc = NGX_IMAP_PARSE_INVALID_COMMAND; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
647 } |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
648 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
649 break; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
650 |
527 | 651 case NGX_POP3_CAPA: |
652 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); | |
583 | 653 |
654 #if (NGX_IMAP_SSL) | |
655 | |
656 if (c->ssl == NULL) { | |
657 sslcf = ngx_imap_get_module_srv_conf(s, | |
658 ngx_imap_ssl_module); | |
659 if (sslcf->starttls) { | |
660 size = cscf->pop3_starttls_capability.len; | |
661 text = cscf->pop3_starttls_capability.data; | |
662 break; | |
663 } | |
664 } | |
665 #endif | |
666 | |
667 size = cscf->pop3_capability.len; | |
668 text = cscf->pop3_capability.data; | |
527 | 669 break; |
670 | |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
671 case NGX_POP3_QUIT: |
539 | 672 s->quit = 1; |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
673 break; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
674 |
527 | 675 case NGX_POP3_NOOP: |
676 break; | |
677 | |
583 | 678 #if (NGX_IMAP_SSL) |
679 | |
680 case NGX_POP3_STLS: | |
681 if (c->ssl == NULL) { | |
682 sslcf = ngx_imap_get_module_srv_conf(s, | |
683 ngx_imap_ssl_module); | |
684 if (sslcf->starttls) { | |
685 c->read->handler = ngx_imap_starttls_handler; | |
686 break; | |
687 } | |
688 } | |
689 | |
690 rc = NGX_IMAP_PARSE_INVALID_COMMAND; | |
691 break; | |
692 #endif | |
693 | |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
694 default: |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
695 s->imap_state = ngx_pop3_start; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
696 rc = NGX_IMAP_PARSE_INVALID_COMMAND; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
697 break; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
698 } |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
699 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
700 break; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
701 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
702 case ngx_pop3_user: |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
703 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
704 switch (s->command) { |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
705 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
706 case NGX_POP3_PASS: |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
707 if (s->args.nelts == 1) { |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
708 /* STUB */ s->imap_state = ngx_pop3_start; |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
709 |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
710 arg = s->args.elts; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
711 s->passwd.len = arg[0].len; |
527 | 712 s->passwd.data = ngx_palloc(c->pool, s->passwd.len); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
713 if (s->passwd.data == NULL) { |
527 | 714 ngx_imap_session_internal_server_error(s); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
715 return; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
716 } |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
717 |
527 | 718 ngx_memcpy(s->passwd.data, arg[0].data, s->passwd.len); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
719 |
547 | 720 #if (NGX_DEBUG_IMAP_PASSWD) |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
721 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, |
527 | 722 "pop3 passwd: \"%V\"", &s->passwd); |
547 | 723 #endif |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
724 |
527 | 725 s->args.nelts = 0; |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
726 s->buffer->pos = s->buffer->start; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
727 s->buffer->last = s->buffer->start; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
728 |
527 | 729 if (rev->timer_set) { |
730 ngx_del_timer(rev); | |
731 } | |
732 | |
521 | 733 ngx_imap_auth_http_init(s); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
734 |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
735 return; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
736 |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
737 } else { |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
738 rc = NGX_IMAP_PARSE_INVALID_COMMAND; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
739 } |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
740 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
741 break; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
742 |
527 | 743 case NGX_POP3_CAPA: |
744 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); | |
583 | 745 size = cscf->pop3_capability.len; |
746 text = cscf->pop3_capability.data; | |
527 | 747 break; |
748 | |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
749 case NGX_POP3_QUIT: |
539 | 750 s->quit = 1; |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
751 break; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
752 |
527 | 753 case NGX_POP3_NOOP: |
754 break; | |
755 | |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
756 default: |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
757 s->imap_state = ngx_pop3_start; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
758 rc = NGX_IMAP_PARSE_INVALID_COMMAND; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
759 break; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
760 } |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
761 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
762 break; |
527 | 763 |
764 /* suppress warinings */ | |
765 case ngx_pop3_passwd: | |
766 break; | |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
767 } |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
768 } |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
769 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
770 if (rc == NGX_IMAP_PARSE_INVALID_COMMAND) { |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
771 text = pop3_invalid_command; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
772 size = sizeof(pop3_invalid_command) - 1; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
773 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
774 |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
775 s->args.nelts = 0; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
776 s->buffer->pos = s->buffer->start; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
777 s->buffer->last = s->buffer->start; |
539 | 778 |
779 s->out.data = text; | |
780 s->out.len = size; | |
781 | |
782 ngx_imap_send(c->write); | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
783 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
784 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
785 |
521 | 786 static ngx_int_t |
527 | 787 ngx_imap_read_command(ngx_imap_session_t *s) |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
788 { |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
789 ssize_t n; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
790 ngx_int_t rc; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
791 |
539 | 792 n = s->connection->recv(s->connection, s->buffer->last, |
793 s->buffer->end - s->buffer->last); | |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
794 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
795 if (n == NGX_ERROR || n == 0) { |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
796 ngx_imap_close_connection(s->connection); |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
797 return NGX_ERROR; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
798 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
799 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
800 if (n > 0) { |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
801 s->buffer->last += n; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
802 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
803 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
804 if (n == NGX_AGAIN) { |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
805 if (ngx_handle_read_event(s->connection->read, 0) == NGX_ERROR) { |
527 | 806 ngx_imap_session_internal_server_error(s); |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
807 return NGX_ERROR; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
808 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
809 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
810 return NGX_AGAIN; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
811 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
812 |
527 | 813 if (s->protocol == NGX_IMAP_POP3_PROTOCOL) { |
814 rc = ngx_pop3_parse_command(s); | |
815 } else { | |
816 rc = ngx_imap_parse_command(s); | |
817 } | |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
818 |
527 | 819 if (rc == NGX_AGAIN |
820 || rc == NGX_IMAP_NEXT | |
821 || rc == NGX_IMAP_PARSE_INVALID_COMMAND) | |
822 { | |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
823 return rc; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
824 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
825 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
826 if (rc == NGX_ERROR) { |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
827 ngx_imap_close_connection(s->connection); |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
828 return NGX_ERROR; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
829 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
830 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
831 return NGX_OK; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
832 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
833 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
834 |
521 | 835 void |
525 | 836 ngx_imap_session_internal_server_error(ngx_imap_session_t *s) |
837 { | |
539 | 838 s->out = internal_server_errors[s->protocol]; |
839 s->quit = 1; | |
525 | 840 |
539 | 841 ngx_imap_send(s->connection->write); |
525 | 842 } |
843 | |
844 | |
845 void | |
521 | 846 ngx_imap_close_connection(ngx_connection_t *c) |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
847 { |
479 | 848 ngx_pool_t *pool; |
849 | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
850 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
851 "close imap connection: %d", c->fd); |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
852 |
539 | 853 #if (NGX_IMAP_SSL) |
854 | |
855 if (c->ssl) { | |
856 if (ngx_ssl_shutdown(c) == NGX_AGAIN) { | |
577 | 857 c->ssl->handler = ngx_imap_close_connection; |
539 | 858 return; |
859 } | |
860 } | |
861 | |
862 #endif | |
863 | |
583 | 864 c->destroyed = 1; |
543 | 865 |
479 | 866 pool = c->pool; |
867 | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
868 ngx_close_connection(c); |
479 | 869 |
501 | 870 ngx_destroy_pool(pool); |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
871 } |
539 | 872 |
873 | |
541 | 874 static u_char * |
875 ngx_imap_log_error(ngx_log_t *log, u_char *buf, size_t len) | |
876 { | |
567 | 877 u_char *p; |
878 ngx_imap_session_t *s; | |
879 ngx_imap_log_ctx_t *ctx; | |
541 | 880 |
881 if (log->action) { | |
882 p = ngx_snprintf(buf, len, " while %s", log->action); | |
883 len -= p - buf; | |
884 buf = p; | |
885 } | |
577 | 886 |
541 | 887 ctx = log->data; |
888 | |
889 p = ngx_snprintf(buf, len, ", client: %V", ctx->client); | |
890 len -= p - buf; | |
891 buf = p; | |
892 | |
893 s = ctx->session; | |
894 | |
895 if (s == NULL) { | |
896 return p; | |
897 } | |
898 | |
899 p = ngx_snprintf(buf, len, ", server: %V", | |
900 &s->connection->listening->addr_text); | |
901 len -= p - buf; | |
902 buf = p; | |
903 | |
904 if (s->login.len == 0) { | |
905 return p; | |
906 } | |
907 | |
908 p = ngx_snprintf(buf, len, ", login: \"%V\"", &s->login); | |
909 len -= p - buf; | |
910 buf = p; | |
911 | |
912 if (s->proxy == NULL) { | |
913 return p; | |
914 } | |
915 | |
916 p = ngx_snprintf(buf, len, ", upstream: %V", | |
917 &s->proxy->upstream.peers->peer[0].name); | |
918 | |
919 return p; | |
920 } |