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