Mercurial > hg > nginx-quic
annotate src/imap/ngx_imap_handler.c @ 725:86862ad988da
fix segfault when zero length file is PUT
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sun, 01 Oct 2006 07:17:01 +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 } |