Mercurial > hg > nginx
annotate src/imap/ngx_imap_handler.c @ 800:887d8dec72dc
APOP
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 23 Oct 2006 13:10:10 +0000 |
parents | 5e8fb59c18c1 |
children | da9c1521319d |
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 { |
800 | 236 u_char *p; |
539 | 237 ngx_imap_session_t *s; |
541 | 238 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
|
239 |
547 | 240 c->read->handler = ngx_imap_init_protocol; |
241 c->write->handler = ngx_imap_send; | |
539 | 242 |
641 | 243 s = c->data; |
413
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
244 |
641 | 245 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); |
539 | 246 |
247 s->protocol = cscf->protocol; | |
248 | |
249 s->ctx = ngx_pcalloc(c->pool, sizeof(void *) * ngx_imap_max_module); | |
250 if (s->ctx == NULL) { | |
251 ngx_imap_session_internal_server_error(s); | |
252 return; | |
253 } | |
254 | |
255 s->out = greetings[s->protocol]; | |
256 | |
800 | 257 if ((cscf->auth_methods & NGX_IMAP_AUTH_APOP_ENABLED) |
258 && s->protocol == NGX_IMAP_POP3_PROTOCOL) | |
259 { | |
260 s->salt.data = ngx_palloc(c->pool, | |
261 sizeof(" <18446744073709551616.@>" CRLF) - 1 | |
262 + NGX_TIME_T_LEN | |
263 + cscf->server_name.len); | |
264 if (s->salt.data == NULL) { | |
265 ngx_imap_session_internal_server_error(s); | |
266 return; | |
267 } | |
268 | |
269 s->salt.len = ngx_sprintf(s->salt.data, "<%ul.%T@%V>" CRLF, | |
270 ngx_random(), ngx_time(), &cscf->server_name) | |
271 - s->salt.data; | |
272 | |
273 s->out.data = ngx_palloc(c->pool, greetings[0].len + 1 + s->salt.len); | |
274 if (s->out.data == NULL) { | |
275 ngx_imap_session_internal_server_error(s); | |
276 return; | |
277 } | |
278 | |
279 p = ngx_cpymem(s->out.data, greetings[0].data, greetings[0].len - 2); | |
280 *p++ = ' '; | |
281 p = ngx_cpymem(p, s->salt.data, s->salt.len); | |
282 | |
283 s->out.len = p - s->out.data; | |
284 } | |
285 | |
547 | 286 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
|
287 |
547 | 288 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
|
289 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
|
290 } |
539 | 291 |
292 ngx_imap_send(c->write); | |
293 } | |
294 | |
295 | |
296 void | |
297 ngx_imap_send(ngx_event_t *wev) | |
298 { | |
541 | 299 ngx_int_t n; |
300 ngx_connection_t *c; | |
301 ngx_imap_session_t *s; | |
302 ngx_imap_core_srv_conf_t *cscf; | |
539 | 303 |
304 c = wev->data; | |
305 s = c->data; | |
306 | |
307 if (wev->timedout) { | |
308 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); | |
577 | 309 c->timedout = 1; |
539 | 310 ngx_imap_close_connection(c); |
311 return; | |
312 } | |
313 | |
314 if (s->out.len == 0) { | |
315 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { | |
316 ngx_imap_close_connection(c); | |
317 } | |
318 | |
319 return; | |
320 } | |
321 | |
322 n = c->send(c, s->out.data, s->out.len); | |
323 | |
324 if (n > 0) { | |
325 s->out.len -= n; | |
326 | |
541 | 327 if (wev->timer_set) { |
328 ngx_del_timer(wev); | |
329 } | |
330 | |
539 | 331 if (s->quit) { |
332 ngx_imap_close_connection(c); | |
333 return; | |
334 } | |
335 | |
336 if (s->blocked) { | |
337 c->read->handler(c->read); | |
338 } | |
339 | |
340 return; | |
341 } | |
342 | |
343 if (n == NGX_ERROR) { | |
344 ngx_imap_close_connection(c); | |
345 return; | |
346 } | |
347 | |
348 /* n == NGX_AGAIN */ | |
349 | |
541 | 350 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); |
351 | |
352 ngx_add_timer(c->write, cscf->timeout); | |
353 | |
539 | 354 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { |
355 ngx_imap_close_connection(c); | |
356 return; | |
357 } | |
413
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
358 } |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
359 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
360 |
521 | 361 static void |
541 | 362 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
|
363 { |
521 | 364 size_t size; |
365 ngx_connection_t *c; | |
366 ngx_imap_session_t *s; | |
367 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
|
368 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
369 c = rev->data; |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
370 |
541 | 371 c->log->action = "in auth state"; |
372 | |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
373 if (rev->timedout) { |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
374 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); |
577 | 375 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
|
376 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
|
377 return; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
378 } |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
379 |
539 | 380 s = c->data; |
521 | 381 |
539 | 382 if (s->protocol == NGX_IMAP_POP3_PROTOCOL) { |
521 | 383 size = 128; |
527 | 384 s->imap_state = ngx_pop3_start; |
521 | 385 c->read->handler = ngx_pop3_auth_state; |
386 | |
387 } else { | |
539 | 388 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); |
521 | 389 size = cscf->imap_client_buffer_size; |
527 | 390 s->imap_state = ngx_imap_start; |
521 | 391 c->read->handler = ngx_imap_auth_state; |
392 } | |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
393 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
394 if (s->buffer == NULL) { |
583 | 395 if (ngx_array_init(&s->args, c->pool, 2, sizeof(ngx_str_t)) |
396 == NGX_ERROR) | |
397 { | |
398 ngx_imap_session_internal_server_error(s); | |
399 return; | |
400 } | |
401 | |
402 s->buffer = ngx_create_temp_buf(c->pool, size); | |
403 if (s->buffer == NULL) { | |
404 ngx_imap_session_internal_server_error(s); | |
405 return; | |
406 } | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
407 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
408 |
521 | 409 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
|
410 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
411 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
412 |
527 | 413 void |
521 | 414 ngx_imap_auth_state(ngx_event_t *rev) |
415 { | |
543 | 416 u_char *text, *last, *p, *dst, *src, *end; |
539 | 417 ssize_t text_len, last_len; |
527 | 418 ngx_str_t *arg; |
419 ngx_int_t rc; | |
543 | 420 ngx_uint_t tag, i; |
527 | 421 ngx_connection_t *c; |
422 ngx_imap_session_t *s; | |
423 ngx_imap_core_srv_conf_t *cscf; | |
583 | 424 #if (NGX_IMAP_SSL) |
425 ngx_imap_ssl_conf_t *sslcf; | |
426 #endif | |
521 | 427 |
428 c = rev->data; | |
527 | 429 s = c->data; |
521 | 430 |
527 | 431 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap auth state"); |
432 | |
433 if (rev->timedout) { | |
434 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); | |
577 | 435 c->timedout = 1; |
527 | 436 ngx_imap_close_connection(c); |
437 return; | |
438 } | |
439 | |
539 | 440 if (s->out.len) { |
441 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap send handler busy"); | |
442 s->blocked = 1; | |
443 return; | |
444 } | |
445 | |
446 s->blocked = 0; | |
447 | |
527 | 448 rc = ngx_imap_read_command(s); |
449 | |
450 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap auth: %i", rc); | |
451 | |
452 if (rc == NGX_AGAIN || rc == NGX_ERROR) { | |
453 return; | |
454 } | |
455 | |
456 tag = 1; | |
457 | |
458 text = NULL; | |
459 text_len = 0; | |
460 | |
461 last = imap_ok; | |
462 last_len = sizeof(imap_ok) - 1; | |
463 | |
464 if (rc == NGX_OK) { | |
465 | |
466 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap auth command: %i", | |
467 s->command); | |
468 | |
543 | 469 if (s->backslash) { |
470 | |
471 arg = s->args.elts; | |
472 | |
473 for (i = 0; i < s->args.nelts; i++) { | |
474 dst = arg[i].data; | |
475 end = dst + arg[i].len; | |
476 | |
477 for (src = dst; src < end; dst++) { | |
478 *dst = *src; | |
479 if (*src++ == '\\') { | |
480 *dst = *src++; | |
481 } | |
482 } | |
483 | |
484 arg[i].len = dst - arg[i].data; | |
485 } | |
486 | |
487 s->backslash = 0; | |
488 } | |
489 | |
527 | 490 switch (s->command) { |
491 | |
492 case NGX_IMAP_LOGIN: | |
583 | 493 |
494 #if (NGX_IMAP_SSL) | |
495 | |
496 if (c->ssl == NULL) { | |
497 sslcf = ngx_imap_get_module_srv_conf(s, ngx_imap_ssl_module); | |
498 | |
499 if (sslcf->starttls == NGX_IMAP_STARTTLS_ONLY) { | |
500 rc = NGX_IMAP_PARSE_INVALID_COMMAND; | |
501 break; | |
502 } | |
503 } | |
504 #endif | |
505 | |
569 | 506 arg = s->args.elts; |
527 | 507 |
569 | 508 if (s->args.nelts == 2 && arg[0].len) { |
527 | 509 |
510 s->login.len = arg[0].len; | |
511 s->login.data = ngx_palloc(c->pool, s->login.len); | |
512 if (s->login.data == NULL) { | |
513 ngx_imap_session_internal_server_error(s); | |
514 return; | |
515 } | |
516 | |
517 ngx_memcpy(s->login.data, arg[0].data, s->login.len); | |
518 | |
519 s->passwd.len = arg[1].len; | |
520 s->passwd.data = ngx_palloc(c->pool, s->passwd.len); | |
521 if (s->passwd.data == NULL) { | |
522 ngx_imap_session_internal_server_error(s); | |
523 return; | |
524 } | |
525 | |
526 ngx_memcpy(s->passwd.data, arg[1].data, s->passwd.len); | |
527 | |
547 | 528 #if (NGX_DEBUG_IMAP_PASSWD) |
527 | 529 ngx_log_debug2(NGX_LOG_DEBUG_IMAP, c->log, 0, |
530 "imap login:\"%V\" passwd:\"%V\"", | |
531 &s->login, &s->passwd); | |
547 | 532 #else |
533 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, | |
534 "imap login:\"%V\"", &s->login); | |
535 #endif | |
527 | 536 |
537 s->args.nelts = 0; | |
538 s->buffer->pos = s->buffer->start; | |
539 s->buffer->last = s->buffer->start; | |
540 | |
541 if (rev->timer_set) { | |
542 ngx_del_timer(rev); | |
543 } | |
544 | |
545 s->login_attempt++; | |
546 | |
547 ngx_imap_auth_http_init(s); | |
548 | |
549 return; | |
550 | |
551 } else { | |
552 rc = NGX_IMAP_PARSE_INVALID_COMMAND; | |
553 } | |
554 | |
555 break; | |
556 | |
557 case NGX_IMAP_CAPABILITY: | |
558 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); | |
583 | 559 |
560 #if (NGX_IMAP_SSL) | |
561 | |
562 if (c->ssl == NULL) { | |
563 sslcf = ngx_imap_get_module_srv_conf(s, ngx_imap_ssl_module); | |
564 | |
565 if (sslcf->starttls == NGX_IMAP_STARTTLS_ON) { | |
566 text_len = cscf->imap_starttls_capability.len; | |
567 text = cscf->imap_starttls_capability.data; | |
568 break; | |
569 } | |
570 | |
571 if (sslcf->starttls == NGX_IMAP_STARTTLS_ONLY) { | |
572 text_len = cscf->imap_starttls_only_capability.len; | |
573 text = cscf->imap_starttls_only_capability.data; | |
574 break; | |
575 } | |
576 } | |
577 #endif | |
578 | |
579 text_len = cscf->imap_capability.len; | |
580 text = cscf->imap_capability.data; | |
527 | 581 break; |
582 | |
583 case NGX_IMAP_LOGOUT: | |
539 | 584 s->quit = 1; |
527 | 585 text = imap_bye; |
586 text_len = sizeof(imap_bye) - 1; | |
587 break; | |
588 | |
589 case NGX_IMAP_NOOP: | |
590 break; | |
591 | |
583 | 592 #if (NGX_IMAP_SSL) |
593 | |
594 case NGX_IMAP_STARTTLS: | |
595 if (c->ssl == NULL) { | |
596 sslcf = ngx_imap_get_module_srv_conf(s, ngx_imap_ssl_module); | |
597 if (sslcf->starttls) { | |
598 c->read->handler = ngx_imap_starttls_handler; | |
599 break; | |
600 } | |
601 } | |
602 | |
603 rc = NGX_IMAP_PARSE_INVALID_COMMAND; | |
604 break; | |
605 #endif | |
606 | |
527 | 607 default: |
608 rc = NGX_IMAP_PARSE_INVALID_COMMAND; | |
609 break; | |
610 } | |
611 | |
612 } else if (rc == NGX_IMAP_NEXT) { | |
613 last = imap_next; | |
614 last_len = sizeof(imap_next) - 1; | |
615 tag = 0; | |
616 } | |
617 | |
618 if (rc == NGX_IMAP_PARSE_INVALID_COMMAND) { | |
619 last = imap_invalid_command; | |
620 last_len = sizeof(imap_invalid_command) - 1; | |
621 } | |
622 | |
623 if (tag) { | |
543 | 624 if (s->tag.len == 0) { |
625 s->tag.len = sizeof(imap_star) - 1; | |
626 s->tag.data = (u_char *) imap_star; | |
627 } | |
628 | |
539 | 629 if (s->tagged_line.len < s->tag.len + text_len + last_len) { |
630 s->tagged_line.len = s->tag.len + text_len + last_len; | |
631 s->tagged_line.data = ngx_palloc(c->pool, s->tagged_line.len); | |
632 if (s->tagged_line.data == NULL) { | |
527 | 633 ngx_imap_close_connection(c); |
634 return; | |
635 } | |
636 } | |
637 | |
539 | 638 s->out.data = s->tagged_line.data; |
639 s->out.len = s->tag.len + text_len + last_len; | |
640 | |
641 p = s->out.data; | |
527 | 642 |
643 if (text) { | |
644 p = ngx_cpymem(p, text, text_len); | |
645 } | |
646 p = ngx_cpymem(p, s->tag.data, s->tag.len); | |
647 ngx_memcpy(p, last, last_len); | |
648 | |
649 | |
650 } else { | |
539 | 651 s->out.data = last; |
652 s->out.len = last_len; | |
527 | 653 } |
654 | |
539 | 655 if (rc != NGX_IMAP_NEXT) { |
656 s->args.nelts = 0; | |
657 s->buffer->pos = s->buffer->start; | |
658 s->buffer->last = s->buffer->start; | |
659 s->tag.len = 0; | |
527 | 660 } |
661 | |
539 | 662 ngx_imap_send(c->write); |
521 | 663 } |
664 | |
665 | |
527 | 666 void |
521 | 667 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
|
668 { |
527 | 669 u_char *text; |
670 ssize_t size; | |
671 ngx_int_t rc; | |
672 ngx_str_t *arg; | |
673 ngx_connection_t *c; | |
674 ngx_imap_session_t *s; | |
675 ngx_imap_core_srv_conf_t *cscf; | |
583 | 676 #if (NGX_IMAP_SSL) |
677 ngx_imap_ssl_conf_t *sslcf; | |
678 #endif | |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
679 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
680 c = rev->data; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
681 s = c->data; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
682 |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
683 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
|
684 |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
685 if (rev->timedout) { |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
686 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); |
577 | 687 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
|
688 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
|
689 return; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
690 } |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
691 |
539 | 692 if (s->out.len) { |
693 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap send handler busy"); | |
694 s->blocked = 1; | |
695 return; | |
696 } | |
697 | |
698 s->blocked = 0; | |
699 | |
527 | 700 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
|
701 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
702 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
|
703 return; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
704 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
705 |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
706 text = pop3_ok; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
707 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
|
708 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
709 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
|
710 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
|
711 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
712 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
|
713 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
714 switch (s->command) { |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
715 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
716 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
|
717 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
|
718 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
|
719 |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
720 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
|
721 s->login.len = arg[0].len; |
527 | 722 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
|
723 if (s->login.data == NULL) { |
527 | 724 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
|
725 return; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
726 } |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
727 |
527 | 728 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
|
729 |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
730 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, |
527 | 731 "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
|
732 |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
733 } else { |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
734 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
|
735 } |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
736 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
737 break; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
738 |
527 | 739 case NGX_POP3_CAPA: |
740 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); | |
583 | 741 |
742 #if (NGX_IMAP_SSL) | |
743 | |
744 if (c->ssl == NULL) { | |
745 sslcf = ngx_imap_get_module_srv_conf(s, | |
746 ngx_imap_ssl_module); | |
747 if (sslcf->starttls) { | |
748 size = cscf->pop3_starttls_capability.len; | |
749 text = cscf->pop3_starttls_capability.data; | |
750 break; | |
751 } | |
752 } | |
753 #endif | |
754 | |
755 size = cscf->pop3_capability.len; | |
756 text = cscf->pop3_capability.data; | |
527 | 757 break; |
758 | |
800 | 759 case NGX_POP3_APOP: |
760 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); | |
761 | |
762 if ((cscf->auth_methods & NGX_IMAP_AUTH_APOP_ENABLED) | |
763 && s->args.nelts == 2) | |
764 { | |
765 arg = s->args.elts; | |
766 | |
767 s->login.len = arg[0].len; | |
768 s->login.data = ngx_palloc(c->pool, s->login.len); | |
769 if (s->login.data == NULL) { | |
770 ngx_imap_session_internal_server_error(s); | |
771 return; | |
772 } | |
773 | |
774 ngx_memcpy(s->login.data, arg[0].data, s->login.len); | |
775 | |
776 s->passwd.len = arg[1].len; | |
777 s->passwd.data = ngx_palloc(c->pool, s->passwd.len); | |
778 if (s->passwd.data == NULL) { | |
779 ngx_imap_session_internal_server_error(s); | |
780 return; | |
781 } | |
782 | |
783 ngx_memcpy(s->passwd.data, arg[1].data, s->passwd.len); | |
784 | |
785 ngx_log_debug2(NGX_LOG_DEBUG_IMAP, c->log, 0, | |
786 "pop3 apop: \"%V\" \"%V\"", | |
787 &s->login, &s->passwd); | |
788 | |
789 s->auth_method = NGX_IMAP_AUTH_APOP; | |
790 | |
791 s->args.nelts = 0; | |
792 s->buffer->pos = s->buffer->start; | |
793 s->buffer->last = s->buffer->start; | |
794 | |
795 if (rev->timer_set) { | |
796 ngx_del_timer(rev); | |
797 } | |
798 | |
799 ngx_imap_auth_http_init(s); | |
800 | |
801 return; | |
802 | |
803 } else { | |
804 rc = NGX_IMAP_PARSE_INVALID_COMMAND; | |
805 } | |
806 | |
807 break; | |
808 | |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
809 case NGX_POP3_QUIT: |
539 | 810 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
|
811 break; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
812 |
527 | 813 case NGX_POP3_NOOP: |
814 break; | |
815 | |
583 | 816 #if (NGX_IMAP_SSL) |
817 | |
818 case NGX_POP3_STLS: | |
819 if (c->ssl == NULL) { | |
820 sslcf = ngx_imap_get_module_srv_conf(s, | |
821 ngx_imap_ssl_module); | |
822 if (sslcf->starttls) { | |
823 c->read->handler = ngx_imap_starttls_handler; | |
824 break; | |
825 } | |
826 } | |
827 | |
828 rc = NGX_IMAP_PARSE_INVALID_COMMAND; | |
829 break; | |
830 #endif | |
831 | |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
832 default: |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
833 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
|
834 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
|
835 break; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
836 } |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
837 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
838 break; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
839 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
840 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
|
841 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
842 switch (s->command) { |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
843 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
844 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
|
845 if (s->args.nelts == 1) { |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
846 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
|
847 s->passwd.len = arg[0].len; |
527 | 848 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
|
849 if (s->passwd.data == NULL) { |
527 | 850 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
|
851 return; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
852 } |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
853 |
527 | 854 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
|
855 |
547 | 856 #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
|
857 ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, |
527 | 858 "pop3 passwd: \"%V\"", &s->passwd); |
547 | 859 #endif |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
860 |
527 | 861 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
|
862 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
|
863 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
|
864 |
527 | 865 if (rev->timer_set) { |
866 ngx_del_timer(rev); | |
867 } | |
868 | |
521 | 869 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
|
870 |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
871 return; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
872 |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
873 } else { |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
874 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
|
875 } |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
876 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
877 break; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
878 |
527 | 879 case NGX_POP3_CAPA: |
880 cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module); | |
583 | 881 size = cscf->pop3_capability.len; |
882 text = cscf->pop3_capability.data; | |
527 | 883 break; |
884 | |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
885 case NGX_POP3_QUIT: |
539 | 886 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
|
887 break; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
888 |
527 | 889 case NGX_POP3_NOOP: |
890 break; | |
891 | |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
892 default: |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
893 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
|
894 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
|
895 break; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
896 } |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
897 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
898 break; |
527 | 899 |
900 /* suppress warinings */ | |
901 case ngx_pop3_passwd: | |
902 break; | |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
903 } |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
904 } |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
905 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
906 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
|
907 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
|
908 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
|
909 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
910 |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
911 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
|
912 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
|
913 s->buffer->last = s->buffer->start; |
539 | 914 |
915 s->out.data = text; | |
916 s->out.len = size; | |
917 | |
918 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
|
919 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
920 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
921 |
521 | 922 static ngx_int_t |
527 | 923 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
|
924 { |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
925 ssize_t n; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
926 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
|
927 |
539 | 928 n = s->connection->recv(s->connection, s->buffer->last, |
929 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
|
930 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
931 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
|
932 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
|
933 return NGX_ERROR; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
934 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
935 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
936 if (n > 0) { |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
937 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
|
938 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
939 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
940 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
|
941 if (ngx_handle_read_event(s->connection->read, 0) == NGX_ERROR) { |
527 | 942 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
|
943 return NGX_ERROR; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
944 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
945 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
946 return NGX_AGAIN; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
947 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
948 |
527 | 949 if (s->protocol == NGX_IMAP_POP3_PROTOCOL) { |
950 rc = ngx_pop3_parse_command(s); | |
951 } else { | |
952 rc = ngx_imap_parse_command(s); | |
953 } | |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
954 |
527 | 955 if (rc == NGX_AGAIN |
956 || rc == NGX_IMAP_NEXT | |
957 || rc == NGX_IMAP_PARSE_INVALID_COMMAND) | |
958 { | |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
959 return rc; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
960 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
961 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
962 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
|
963 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
|
964 return NGX_ERROR; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
965 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
966 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
967 return NGX_OK; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
968 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
969 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
970 |
521 | 971 void |
525 | 972 ngx_imap_session_internal_server_error(ngx_imap_session_t *s) |
973 { | |
539 | 974 s->out = internal_server_errors[s->protocol]; |
975 s->quit = 1; | |
525 | 976 |
539 | 977 ngx_imap_send(s->connection->write); |
525 | 978 } |
979 | |
980 | |
981 void | |
521 | 982 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
|
983 { |
479 | 984 ngx_pool_t *pool; |
985 | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
986 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
|
987 "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
|
988 |
539 | 989 #if (NGX_IMAP_SSL) |
990 | |
991 if (c->ssl) { | |
992 if (ngx_ssl_shutdown(c) == NGX_AGAIN) { | |
577 | 993 c->ssl->handler = ngx_imap_close_connection; |
539 | 994 return; |
995 } | |
996 } | |
997 | |
998 #endif | |
999 | |
583 | 1000 c->destroyed = 1; |
543 | 1001 |
479 | 1002 pool = c->pool; |
1003 | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
1004 ngx_close_connection(c); |
479 | 1005 |
501 | 1006 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
|
1007 } |
539 | 1008 |
1009 | |
541 | 1010 static u_char * |
1011 ngx_imap_log_error(ngx_log_t *log, u_char *buf, size_t len) | |
1012 { | |
567 | 1013 u_char *p; |
1014 ngx_imap_session_t *s; | |
1015 ngx_imap_log_ctx_t *ctx; | |
541 | 1016 |
1017 if (log->action) { | |
1018 p = ngx_snprintf(buf, len, " while %s", log->action); | |
1019 len -= p - buf; | |
1020 buf = p; | |
1021 } | |
577 | 1022 |
541 | 1023 ctx = log->data; |
1024 | |
1025 p = ngx_snprintf(buf, len, ", client: %V", ctx->client); | |
1026 len -= p - buf; | |
1027 buf = p; | |
1028 | |
1029 s = ctx->session; | |
1030 | |
1031 if (s == NULL) { | |
1032 return p; | |
1033 } | |
1034 | |
641 | 1035 p = ngx_snprintf(buf, len, ", server: %V", s->addr_text); |
541 | 1036 len -= p - buf; |
1037 buf = p; | |
1038 | |
1039 if (s->login.len == 0) { | |
1040 return p; | |
1041 } | |
1042 | |
1043 p = ngx_snprintf(buf, len, ", login: \"%V\"", &s->login); | |
1044 len -= p - buf; | |
1045 buf = p; | |
1046 | |
1047 if (s->proxy == NULL) { | |
1048 return p; | |
1049 } | |
1050 | |
1051 p = ngx_snprintf(buf, len, ", upstream: %V", | |
1052 &s->proxy->upstream.peers->peer[0].name); | |
1053 | |
1054 return p; | |
1055 } |