Mercurial > hg > nginx-quic
annotate src/mail/ngx_mail_handler.c @ 1391:4eed21047e4d
allow "http://" in auth_http URL
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 14 Aug 2007 15:00:38 +0000 |
parents | c4b2c893989d |
children | 32450a2bbdf4 |
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> |
1136 | 10 #include <ngx_mail.h> |
417
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 |
1136 | 13 static void ngx_mail_init_session(ngx_connection_t *c); |
14 static void ngx_mail_init_protocol(ngx_event_t *rev); | |
15 static ngx_int_t ngx_mail_decode_auth_plain(ngx_mail_session_t *s, | |
894
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
16 ngx_str_t *encoded); |
1136 | 17 static void ngx_mail_do_auth(ngx_mail_session_t *s); |
18 static ngx_int_t ngx_mail_read_command(ngx_mail_session_t *s); | |
19 static u_char *ngx_mail_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
|
20 |
1136 | 21 #if (NGX_MAIL_SSL) |
22 static void ngx_mail_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c); | |
23 static void ngx_mail_ssl_handshake_handler(ngx_connection_t *c); | |
539 | 24 #endif |
25 | |
413
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
26 |
521 | 27 static ngx_str_t greetings[] = { |
527 | 28 ngx_string("+OK POP3 ready" CRLF), |
529 | 29 ngx_string("* OK IMAP4 ready" CRLF) |
1136 | 30 /* SMTP greeting */ |
521 | 31 }; |
32 | |
525 | 33 static ngx_str_t internal_server_errors[] = { |
34 ngx_string("-ERR internal server error" CRLF), | |
35 ngx_string("* BAD internal server error" CRLF), | |
1136 | 36 ngx_string("451 4.3.2 Internal server error" CRLF), |
525 | 37 }; |
38 | |
521 | 39 static u_char pop3_ok[] = "+OK" CRLF; |
809 | 40 static u_char pop3_next[] = "+ " CRLF; |
41 static u_char pop3_username[] = "+ VXNlcm5hbWU6" CRLF; | |
42 static u_char pop3_password[] = "+ UGFzc3dvcmQ6" CRLF; | |
521 | 43 static u_char pop3_invalid_command[] = "-ERR invalid command" CRLF; |
44 | |
543 | 45 static u_char imap_star[] = "* "; |
529 | 46 static u_char imap_ok[] = "OK completed" CRLF; |
527 | 47 static u_char imap_next[] = "+ OK" CRLF; |
48 static u_char imap_bye[] = "* BYE" CRLF; | |
49 static u_char imap_invalid_command[] = "BAD invalid command" CRLF; | |
50 | |
1136 | 51 static u_char smtp_ok[] = "250 2.0.0 OK" CRLF; |
52 static u_char smtp_bye[] = "221 2.0.0 Bye" CRLF; | |
53 static u_char smtp_next[] = "334 " CRLF; | |
54 static u_char smtp_username[] = "334 VXNlcm5hbWU6" CRLF; | |
55 static u_char smtp_password[] = "334 UGFzc3dvcmQ6" CRLF; | |
56 static u_char smtp_invalid_command[] = "500 5.5.1 Invalid command" CRLF; | |
57 static u_char smtp_invalid_argument[] = "501 5.5.4 Invalid argument" CRLF; | |
58 static u_char smtp_auth_required[] = "530 5.7.1 Authentication required" CRLF; | |
59 | |
521 | 60 |
61 void | |
1136 | 62 ngx_mail_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
|
63 { |
641 | 64 in_addr_t in_addr; |
65 socklen_t len; | |
66 ngx_uint_t i; | |
67 struct sockaddr_in sin; | |
1136 | 68 ngx_mail_log_ctx_t *ctx; |
69 ngx_mail_in_port_t *imip; | |
70 ngx_mail_in_addr_t *imia; | |
71 ngx_mail_session_t *s; | |
72 #if (NGX_MAIL_SSL) | |
73 ngx_mail_ssl_conf_t *sslcf; | |
543 | 74 #endif |
541 | 75 |
641 | 76 |
77 /* find the server configuration for the address:port */ | |
78 | |
79 /* AF_INET only */ | |
80 | |
81 imip = c->listening->servers; | |
82 imia = imip->addrs; | |
83 | |
84 i = 0; | |
85 | |
86 if (imip->naddrs > 1) { | |
87 | |
88 /* | |
89 * There are several addresses on this port and one of them | |
90 * is the "*:port" wildcard so getsockname() is needed to determine | |
91 * the server address. | |
92 * | |
93 * AcceptEx() already gave this address. | |
94 */ | |
95 | |
96 #if (NGX_WIN32) | |
97 if (c->local_sockaddr) { | |
98 in_addr = | |
99 ((struct sockaddr_in *) c->local_sockaddr)->sin_addr.s_addr; | |
541 | 100 |
641 | 101 } else |
102 #endif | |
103 { | |
104 len = sizeof(struct sockaddr_in); | |
105 if (getsockname(c->fd, (struct sockaddr *) &sin, &len) == -1) { | |
106 ngx_connection_error(c, ngx_socket_errno, | |
107 "getsockname() failed"); | |
1136 | 108 ngx_mail_close_connection(c); |
641 | 109 return; |
110 } | |
111 | |
112 in_addr = sin.sin_addr.s_addr; | |
113 } | |
114 | |
115 /* the last address is "*" */ | |
116 | |
117 for ( /* void */ ; i < imip->naddrs - 1; i++) { | |
118 if (in_addr == imia[i].addr) { | |
119 break; | |
120 } | |
121 } | |
122 } | |
123 | |
124 | |
1136 | 125 s = ngx_pcalloc(c->pool, sizeof(ngx_mail_session_t)); |
641 | 126 if (s == NULL) { |
1136 | 127 ngx_mail_close_connection(c); |
541 | 128 return; |
577 | 129 } |
541 | 130 |
641 | 131 s->main_conf = imia[i].ctx->main_conf; |
132 s->srv_conf = imia[i].ctx->srv_conf; | |
133 | |
134 s->addr_text = &imia[i].addr_text; | |
135 | |
136 c->data = s; | |
137 s->connection = c; | |
138 | |
139 ngx_log_error(NGX_LOG_INFO, c->log, 0, "*%ui client %V connected to %V", | |
140 c->number, &c->addr_text, s->addr_text); | |
141 | |
1136 | 142 ctx = ngx_palloc(c->pool, sizeof(ngx_mail_log_ctx_t)); |
641 | 143 if (ctx == NULL) { |
1136 | 144 ngx_mail_close_connection(c); |
641 | 145 return; |
146 } | |
147 | |
148 ctx->client = &c->addr_text; | |
149 ctx->session = s; | |
541 | 150 |
151 c->log->connection = c->number; | |
1136 | 152 c->log->handler = ngx_mail_log_error; |
641 | 153 c->log->data = ctx; |
541 | 154 c->log->action = "sending client greeting line"; |
155 | |
156 c->log_error = NGX_ERROR_INFO; | |
157 | |
1136 | 158 #if (NGX_MAIL_SSL) |
543 | 159 |
1136 | 160 sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module); |
543 | 161 |
162 if (sslcf->enable) { | |
1136 | 163 ngx_mail_ssl_init_connection(&sslcf->ssl, c); |
547 | 164 return; |
543 | 165 } |
166 | |
167 #endif | |
168 | |
1136 | 169 ngx_mail_init_session(c); |
541 | 170 } |
171 | |
172 | |
1136 | 173 #if (NGX_MAIL_SSL) |
547 | 174 |
541 | 175 static void |
1136 | 176 ngx_mail_starttls_handler(ngx_event_t *rev) |
583 | 177 { |
178 ngx_connection_t *c; | |
1136 | 179 ngx_mail_session_t *s; |
180 ngx_mail_ssl_conf_t *sslcf; | |
583 | 181 |
182 c = rev->data; | |
183 s = c->data; | |
641 | 184 s->starttls = 1; |
583 | 185 |
186 c->log->action = "in starttls state"; | |
187 | |
1136 | 188 sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module); |
583 | 189 |
1136 | 190 ngx_mail_ssl_init_connection(&sslcf->ssl, c); |
583 | 191 } |
192 | |
193 | |
194 static void | |
1136 | 195 ngx_mail_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c) |
583 | 196 { |
1136 | 197 ngx_mail_session_t *s; |
198 ngx_mail_core_srv_conf_t *cscf; | |
583 | 199 |
200 if (ngx_ssl_create_connection(ssl, c, 0) == NGX_ERROR) { | |
1136 | 201 ngx_mail_close_connection(c); |
583 | 202 return; |
203 } | |
204 | |
205 if (ngx_ssl_handshake(c) == NGX_AGAIN) { | |
206 | |
641 | 207 s = c->data; |
208 | |
1136 | 209 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); |
583 | 210 |
211 ngx_add_timer(c->read, cscf->timeout); | |
212 | |
1136 | 213 c->ssl->handler = ngx_mail_ssl_handshake_handler; |
583 | 214 |
215 return; | |
216 } | |
217 | |
1136 | 218 ngx_mail_ssl_handshake_handler(c); |
583 | 219 } |
220 | |
221 | |
222 static void | |
1136 | 223 ngx_mail_ssl_handshake_handler(ngx_connection_t *c) |
577 | 224 { |
1136 | 225 ngx_mail_session_t *s; |
641 | 226 |
547 | 227 if (c->ssl->handshaked) { |
583 | 228 |
641 | 229 s = c->data; |
230 | |
231 if (s->starttls) { | |
1136 | 232 c->read->handler = ngx_mail_init_protocol; |
233 c->write->handler = ngx_mail_send; | |
583 | 234 |
1136 | 235 ngx_mail_init_protocol(c->read); |
583 | 236 |
237 return; | |
238 } | |
239 | |
1136 | 240 ngx_mail_init_session(c); |
547 | 241 return; |
242 } | |
243 | |
1136 | 244 ngx_mail_close_connection(c); |
547 | 245 } |
246 | |
247 #endif | |
248 | |
249 | |
250 static void | |
1136 | 251 ngx_mail_init_session(ngx_connection_t *c) |
541 | 252 { |
800 | 253 u_char *p; |
1136 | 254 ngx_mail_session_t *s; |
255 ngx_mail_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
|
256 |
1136 | 257 c->read->handler = ngx_mail_init_protocol; |
258 c->write->handler = ngx_mail_send; | |
539 | 259 |
641 | 260 s = c->data; |
413
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
261 |
1136 | 262 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); |
539 | 263 |
264 s->protocol = cscf->protocol; | |
265 | |
1136 | 266 s->ctx = ngx_pcalloc(c->pool, sizeof(void *) * ngx_mail_max_module); |
539 | 267 if (s->ctx == NULL) { |
1136 | 268 ngx_mail_session_internal_server_error(s); |
539 | 269 return; |
270 } | |
271 | |
1136 | 272 if (s->protocol == NGX_MAIL_SMTP_PROTOCOL) { |
273 s->out = cscf->smtp_greeting; | |
274 | |
275 } else { | |
276 s->out = greetings[s->protocol]; | |
277 } | |
539 | 278 |
1136 | 279 if ((s->protocol == NGX_MAIL_POP3_PROTOCOL |
280 && (cscf->pop3_auth_methods | |
281 & (NGX_MAIL_AUTH_APOP_ENABLED|NGX_MAIL_AUTH_CRAM_MD5_ENABLED))) | |
282 | |
1323 | 283 || (s->protocol == NGX_MAIL_IMAP_PROTOCOL |
284 && (cscf->imap_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED)) | |
285 | |
1136 | 286 || (s->protocol == NGX_MAIL_SMTP_PROTOCOL |
287 && (cscf->smtp_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED))) | |
800 | 288 { |
289 s->salt.data = ngx_palloc(c->pool, | |
290 sizeof(" <18446744073709551616.@>" CRLF) - 1 | |
291 + NGX_TIME_T_LEN | |
292 + cscf->server_name.len); | |
293 if (s->salt.data == NULL) { | |
1136 | 294 ngx_mail_session_internal_server_error(s); |
800 | 295 return; |
296 } | |
297 | |
298 s->salt.len = ngx_sprintf(s->salt.data, "<%ul.%T@%V>" CRLF, | |
299 ngx_random(), ngx_time(), &cscf->server_name) | |
300 - s->salt.data; | |
301 | |
1136 | 302 if (s->protocol == NGX_MAIL_POP3_PROTOCOL) { |
1166 | 303 s->out.data = ngx_palloc(c->pool, |
1136 | 304 greetings[0].len + 1 + s->salt.len); |
1166 | 305 if (s->out.data == NULL) { |
306 ngx_mail_session_internal_server_error(s); | |
307 return; | |
308 } | |
800 | 309 |
1166 | 310 p = ngx_cpymem(s->out.data, |
1136 | 311 greetings[0].data, greetings[0].len - 2); |
1166 | 312 *p++ = ' '; |
313 p = ngx_cpymem(p, s->salt.data, s->salt.len); | |
800 | 314 |
1166 | 315 s->out.len = p - s->out.data; |
1136 | 316 } |
800 | 317 } |
318 | |
547 | 319 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
|
320 |
547 | 321 if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) { |
1136 | 322 ngx_mail_close_connection(c); |
413
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
323 } |
539 | 324 |
1136 | 325 ngx_mail_send(c->write); |
539 | 326 } |
327 | |
328 | |
329 void | |
1136 | 330 ngx_mail_send(ngx_event_t *wev) |
539 | 331 { |
541 | 332 ngx_int_t n; |
333 ngx_connection_t *c; | |
1136 | 334 ngx_mail_session_t *s; |
335 ngx_mail_core_srv_conf_t *cscf; | |
539 | 336 |
337 c = wev->data; | |
338 s = c->data; | |
339 | |
340 if (wev->timedout) { | |
341 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); | |
577 | 342 c->timedout = 1; |
1136 | 343 ngx_mail_close_connection(c); |
539 | 344 return; |
345 } | |
346 | |
347 if (s->out.len == 0) { | |
348 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { | |
1136 | 349 ngx_mail_close_connection(c); |
539 | 350 } |
351 | |
352 return; | |
353 } | |
354 | |
355 n = c->send(c, s->out.data, s->out.len); | |
356 | |
357 if (n > 0) { | |
358 s->out.len -= n; | |
359 | |
541 | 360 if (wev->timer_set) { |
361 ngx_del_timer(wev); | |
362 } | |
363 | |
539 | 364 if (s->quit) { |
1136 | 365 ngx_mail_close_connection(c); |
539 | 366 return; |
367 } | |
368 | |
369 if (s->blocked) { | |
370 c->read->handler(c->read); | |
371 } | |
372 | |
373 return; | |
374 } | |
375 | |
376 if (n == NGX_ERROR) { | |
1136 | 377 ngx_mail_close_connection(c); |
539 | 378 return; |
379 } | |
380 | |
381 /* n == NGX_AGAIN */ | |
382 | |
1136 | 383 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); |
541 | 384 |
385 ngx_add_timer(c->write, cscf->timeout); | |
386 | |
539 | 387 if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { |
1136 | 388 ngx_mail_close_connection(c); |
539 | 389 return; |
390 } | |
413
de9d4726e28a
nginx-0.0.10-2004-08-31-23:05:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
391 } |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
392 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
393 |
521 | 394 static void |
1136 | 395 ngx_mail_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
|
396 { |
521 | 397 size_t size; |
398 ngx_connection_t *c; | |
1136 | 399 ngx_mail_session_t *s; |
400 ngx_mail_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
|
401 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
402 c = rev->data; |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
403 |
541 | 404 c->log->action = "in auth state"; |
405 | |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
406 if (rev->timedout) { |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
407 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); |
577 | 408 c->timedout = 1; |
1136 | 409 ngx_mail_close_connection(c); |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
410 return; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
411 } |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
412 |
539 | 413 s = c->data; |
521 | 414 |
1136 | 415 switch (s->protocol) { |
416 | |
417 case NGX_MAIL_POP3_PROTOCOL: | |
521 | 418 size = 128; |
1136 | 419 s->mail_state = ngx_pop3_start; |
521 | 420 c->read->handler = ngx_pop3_auth_state; |
1136 | 421 break; |
521 | 422 |
1136 | 423 case NGX_MAIL_IMAP_PROTOCOL: |
424 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); | |
521 | 425 size = cscf->imap_client_buffer_size; |
1136 | 426 s->mail_state = ngx_imap_start; |
521 | 427 c->read->handler = ngx_imap_auth_state; |
1136 | 428 break; |
429 | |
430 default: /* NGX_MAIL_SMTP_PROTOCOL */ | |
431 size = 512; | |
432 s->mail_state = ngx_smtp_start; | |
433 c->read->handler = ngx_smtp_auth_state; | |
434 break; | |
521 | 435 } |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
436 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
437 if (s->buffer == NULL) { |
583 | 438 if (ngx_array_init(&s->args, c->pool, 2, sizeof(ngx_str_t)) |
439 == NGX_ERROR) | |
440 { | |
1136 | 441 ngx_mail_session_internal_server_error(s); |
583 | 442 return; |
443 } | |
444 | |
445 s->buffer = ngx_create_temp_buf(c->pool, size); | |
446 if (s->buffer == NULL) { | |
1136 | 447 ngx_mail_session_internal_server_error(s); |
583 | 448 return; |
449 } | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
450 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
451 |
521 | 452 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
|
453 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
454 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
455 |
527 | 456 void |
1136 | 457 ngx_pop3_auth_state(ngx_event_t *rev) |
521 | 458 { |
1136 | 459 u_char *p, *last, *text; |
460 ssize_t size; | |
527 | 461 ngx_int_t rc; |
1136 | 462 ngx_str_t *arg, salt; |
527 | 463 ngx_connection_t *c; |
1136 | 464 ngx_mail_session_t *s; |
465 ngx_mail_core_srv_conf_t *cscf; | |
466 #if (NGX_MAIL_SSL) | |
467 ngx_mail_ssl_conf_t *sslcf; | |
583 | 468 #endif |
521 | 469 |
470 c = rev->data; | |
527 | 471 s = c->data; |
521 | 472 |
1136 | 473 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "pop3 auth state"); |
527 | 474 |
475 if (rev->timedout) { | |
476 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); | |
577 | 477 c->timedout = 1; |
1136 | 478 ngx_mail_close_connection(c); |
527 | 479 return; |
480 } | |
481 | |
539 | 482 if (s->out.len) { |
1136 | 483 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "pop3 send handler busy"); |
539 | 484 s->blocked = 1; |
485 return; | |
486 } | |
487 | |
488 s->blocked = 0; | |
489 | |
1136 | 490 rc = ngx_mail_read_command(s); |
491 | |
492 if (rc == NGX_AGAIN || rc == NGX_ERROR) { | |
493 return; | |
494 } | |
495 | |
496 text = pop3_ok; | |
497 size = sizeof(pop3_ok) - 1; | |
498 | |
499 if (rc == NGX_OK) { | |
500 switch (s->mail_state) { | |
501 | |
502 case ngx_pop3_start: | |
503 | |
504 switch (s->command) { | |
505 | |
506 case NGX_POP3_USER: | |
507 | |
508 #if (NGX_MAIL_SSL) | |
509 | |
510 if (c->ssl == NULL) { | |
511 sslcf = ngx_mail_get_module_srv_conf(s, | |
512 ngx_mail_ssl_module); | |
513 | |
514 if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) { | |
515 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
516 break; | |
517 } | |
518 } | |
519 #endif | |
520 | |
521 if (s->args.nelts == 1) { | |
522 s->mail_state = ngx_pop3_user; | |
523 | |
524 arg = s->args.elts; | |
525 s->login.len = arg[0].len; | |
526 s->login.data = ngx_palloc(c->pool, s->login.len); | |
527 if (s->login.data == NULL) { | |
528 ngx_mail_session_internal_server_error(s); | |
529 return; | |
530 } | |
531 | |
532 ngx_memcpy(s->login.data, arg[0].data, s->login.len); | |
533 | |
534 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, | |
535 "pop3 login: \"%V\"", &s->login); | |
536 | |
537 break; | |
538 } | |
539 | |
540 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
541 break; | |
542 | |
543 case NGX_POP3_CAPA: | |
544 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); | |
545 | |
546 #if (NGX_MAIL_SSL) | |
547 | |
548 if (c->ssl == NULL) { | |
549 sslcf = ngx_mail_get_module_srv_conf(s, | |
550 ngx_mail_ssl_module); | |
551 | |
552 if (sslcf->starttls == NGX_MAIL_STARTTLS_ON) { | |
553 size = cscf->pop3_starttls_capability.len; | |
554 text = cscf->pop3_starttls_capability.data; | |
555 break; | |
556 } | |
557 | |
558 if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) { | |
559 size = cscf->pop3_starttls_only_capability.len; | |
560 text = cscf->pop3_starttls_only_capability.data; | |
561 break; | |
562 } | |
563 } | |
564 #endif | |
565 | |
566 size = cscf->pop3_capability.len; | |
567 text = cscf->pop3_capability.data; | |
568 break; | |
569 | |
570 case NGX_POP3_APOP: | |
571 | |
572 #if (NGX_MAIL_SSL) | |
573 | |
574 if (c->ssl == NULL) { | |
575 sslcf = ngx_mail_get_module_srv_conf(s, | |
576 ngx_mail_ssl_module); | |
577 | |
578 if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) { | |
579 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
580 break; | |
581 } | |
582 } | |
583 #endif | |
584 | |
585 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); | |
586 | |
587 if ((cscf->pop3_auth_methods & NGX_MAIL_AUTH_APOP_ENABLED) | |
588 && s->args.nelts == 2) | |
589 { | |
590 arg = s->args.elts; | |
591 | |
592 s->login.len = arg[0].len; | |
593 s->login.data = ngx_palloc(c->pool, s->login.len); | |
594 if (s->login.data == NULL) { | |
595 ngx_mail_session_internal_server_error(s); | |
596 return; | |
597 } | |
598 | |
599 ngx_memcpy(s->login.data, arg[0].data, s->login.len); | |
600 | |
601 s->passwd.len = arg[1].len; | |
602 s->passwd.data = ngx_palloc(c->pool, s->passwd.len); | |
603 if (s->passwd.data == NULL) { | |
604 ngx_mail_session_internal_server_error(s); | |
605 return; | |
606 } | |
607 | |
608 ngx_memcpy(s->passwd.data, arg[1].data, s->passwd.len); | |
609 | |
610 ngx_log_debug2(NGX_LOG_DEBUG_MAIL, c->log, 0, | |
611 "pop3 apop: \"%V\" \"%V\"", | |
612 &s->login, &s->passwd); | |
613 | |
614 s->auth_method = NGX_MAIL_AUTH_APOP; | |
615 | |
616 ngx_mail_do_auth(s); | |
617 return; | |
618 } | |
619 | |
620 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
621 break; | |
622 | |
623 case NGX_POP3_AUTH: | |
624 | |
625 #if (NGX_MAIL_SSL) | |
626 | |
627 if (c->ssl == NULL) { | |
628 sslcf = ngx_mail_get_module_srv_conf(s, | |
629 ngx_mail_ssl_module); | |
630 | |
631 if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) { | |
632 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
633 break; | |
634 } | |
635 } | |
636 #endif | |
637 | |
638 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); | |
639 | |
640 if (s->args.nelts == 0) { | |
641 size = cscf->pop3_auth_capability.len; | |
642 text = cscf->pop3_auth_capability.data; | |
643 s->state = 0; | |
644 break; | |
645 } | |
646 | |
647 arg = s->args.elts; | |
648 | |
649 if (arg[0].len == 5) { | |
650 | |
651 if (ngx_strncasecmp(arg[0].data, (u_char *) "LOGIN", 5) | |
652 == 0) | |
653 { | |
654 | |
655 if (s->args.nelts != 1) { | |
656 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
657 break; | |
658 } | |
659 | |
660 s->mail_state = ngx_pop3_auth_login_username; | |
661 | |
662 size = sizeof(pop3_username) - 1; | |
663 text = pop3_username; | |
664 | |
665 break; | |
666 | |
667 } else if (ngx_strncasecmp(arg[0].data, (u_char *) "PLAIN", | |
668 5) | |
669 == 0) | |
670 { | |
671 | |
672 if (s->args.nelts == 1) { | |
673 s->mail_state = ngx_pop3_auth_plain; | |
674 | |
675 size = sizeof(pop3_next) - 1; | |
676 text = pop3_next; | |
677 | |
678 break; | |
679 } | |
680 | |
681 if (s->args.nelts == 2) { | |
682 | |
683 /* | |
684 * workaround for Eudora for Mac: it sends | |
685 * AUTH PLAIN [base64 encoded] | |
686 */ | |
687 | |
688 rc = ngx_mail_decode_auth_plain(s, &arg[1]); | |
689 | |
690 if (rc == NGX_OK) { | |
691 ngx_mail_do_auth(s); | |
692 return; | |
693 } | |
694 | |
695 if (rc == NGX_ERROR) { | |
696 ngx_mail_session_internal_server_error(s); | |
697 return; | |
698 } | |
699 | |
700 /* rc == NGX_MAIL_PARSE_INVALID_COMMAND */ | |
701 | |
702 break; | |
703 } | |
704 | |
705 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
706 break; | |
707 } | |
708 | |
709 } else if (arg[0].len == 8 | |
710 && ngx_strncasecmp(arg[0].data, | |
711 (u_char *) "CRAM-MD5", 8) | |
712 == 0) | |
713 { | |
1286
a9c361479430
fix segfault when CRAM-MD5 is not enabled but client tries it
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
714 if (!(cscf->pop3_auth_methods |
a9c361479430
fix segfault when CRAM-MD5 is not enabled but client tries it
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
715 & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) |
a9c361479430
fix segfault when CRAM-MD5 is not enabled but client tries it
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
716 || s->args.nelts != 1) |
a9c361479430
fix segfault when CRAM-MD5 is not enabled but client tries it
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
717 { |
1136 | 718 rc = NGX_MAIL_PARSE_INVALID_COMMAND; |
719 break; | |
720 } | |
721 | |
722 s->mail_state = ngx_pop3_auth_cram_md5; | |
723 | |
724 text = ngx_palloc(c->pool, | |
725 sizeof("+ " CRLF) - 1 | |
726 + ngx_base64_encoded_length(s->salt.len)); | |
727 if (text == NULL) { | |
728 ngx_mail_session_internal_server_error(s); | |
729 return; | |
730 } | |
731 | |
732 text[0] = '+'; text[1]= ' '; | |
733 salt.data = &text[2]; | |
734 s->salt.len -= 2; | |
735 | |
736 ngx_encode_base64(&salt, &s->salt); | |
737 | |
738 s->salt.len += 2; | |
739 size = 2 + salt.len; | |
740 text[size++] = CR; text[size++] = LF; | |
741 | |
742 break; | |
743 } | |
744 | |
745 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
746 break; | |
747 | |
748 case NGX_POP3_QUIT: | |
749 s->quit = 1; | |
750 break; | |
751 | |
752 case NGX_POP3_NOOP: | |
753 break; | |
754 | |
755 #if (NGX_MAIL_SSL) | |
527 | 756 |
1136 | 757 case NGX_POP3_STLS: |
758 if (c->ssl == NULL) { | |
759 sslcf = ngx_mail_get_module_srv_conf(s, | |
760 ngx_mail_ssl_module); | |
761 if (sslcf->starttls) { | |
762 c->read->handler = ngx_mail_starttls_handler; | |
763 break; | |
764 } | |
765 } | |
766 | |
767 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
768 break; | |
769 #endif | |
770 | |
771 default: | |
772 s->mail_state = ngx_pop3_start; | |
773 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
774 break; | |
775 } | |
776 | |
777 break; | |
778 | |
779 case ngx_pop3_user: | |
780 | |
781 switch (s->command) { | |
782 | |
783 case NGX_POP3_PASS: | |
784 if (s->args.nelts == 1) { | |
785 arg = s->args.elts; | |
786 s->passwd.len = arg[0].len; | |
787 s->passwd.data = ngx_palloc(c->pool, s->passwd.len); | |
788 if (s->passwd.data == NULL) { | |
789 ngx_mail_session_internal_server_error(s); | |
790 return; | |
791 } | |
792 | |
793 ngx_memcpy(s->passwd.data, arg[0].data, s->passwd.len); | |
794 | |
795 #if (NGX_DEBUG_MAIL_PASSWD) | |
796 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, | |
797 "pop3 passwd: \"%V\"", &s->passwd); | |
798 #endif | |
799 | |
800 ngx_mail_do_auth(s); | |
801 return; | |
802 } | |
803 | |
804 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
805 break; | |
806 | |
807 case NGX_POP3_CAPA: | |
808 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); | |
809 size = cscf->pop3_capability.len; | |
810 text = cscf->pop3_capability.data; | |
811 break; | |
812 | |
813 case NGX_POP3_QUIT: | |
814 s->quit = 1; | |
815 break; | |
816 | |
817 case NGX_POP3_NOOP: | |
818 break; | |
819 | |
820 default: | |
821 s->mail_state = ngx_pop3_start; | |
822 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
823 break; | |
824 } | |
825 | |
826 break; | |
827 | |
828 /* suppress warinings */ | |
829 case ngx_pop3_passwd: | |
830 break; | |
831 | |
832 case ngx_pop3_auth_login_username: | |
833 arg = s->args.elts; | |
834 s->mail_state = ngx_pop3_auth_login_password; | |
835 | |
836 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, | |
837 "pop3 auth login username: \"%V\"", &arg[0]); | |
838 | |
839 s->login.data = ngx_palloc(c->pool, | |
840 ngx_base64_decoded_length(arg[0].len)); | |
841 if (s->login.data == NULL){ | |
842 ngx_mail_session_internal_server_error(s); | |
843 return; | |
844 } | |
845 | |
846 if (ngx_decode_base64(&s->login, &arg[0]) != NGX_OK) { | |
847 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
848 "client sent invalid base64 encoding " | |
849 "in AUTH LOGIN command"); | |
850 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
851 break; | |
852 } | |
853 | |
854 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, | |
855 "pop3 auth login username: \"%V\"", &s->login); | |
856 | |
857 size = sizeof(pop3_password) - 1; | |
858 text = pop3_password; | |
859 | |
860 break; | |
861 | |
862 case ngx_pop3_auth_login_password: | |
863 arg = s->args.elts; | |
864 | |
865 #if (NGX_DEBUG_MAIL_PASSWD) | |
866 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, | |
867 "pop3 auth login password: \"%V\"", &arg[0]); | |
868 #endif | |
869 | |
870 s->passwd.data = ngx_palloc(c->pool, | |
871 ngx_base64_decoded_length(arg[0].len)); | |
872 if (s->passwd.data == NULL){ | |
873 ngx_mail_session_internal_server_error(s); | |
874 return; | |
875 } | |
876 | |
877 if (ngx_decode_base64(&s->passwd, &arg[0]) != NGX_OK) { | |
878 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
879 "client sent invalid base64 encoding " | |
880 "in AUTH LOGIN command"); | |
881 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
882 break; | |
883 } | |
884 | |
885 #if (NGX_DEBUG_MAIL_PASSWD) | |
886 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, | |
887 "pop3 auth login password: \"%V\"", &s->passwd); | |
888 #endif | |
889 | |
890 ngx_mail_do_auth(s); | |
891 return; | |
892 | |
893 case ngx_pop3_auth_plain: | |
894 arg = s->args.elts; | |
895 | |
896 rc = ngx_mail_decode_auth_plain(s, &arg[0]); | |
897 | |
898 if (rc == NGX_OK) { | |
899 ngx_mail_do_auth(s); | |
900 return; | |
901 } | |
902 | |
903 if (rc == NGX_ERROR) { | |
904 ngx_mail_session_internal_server_error(s); | |
905 return; | |
906 } | |
907 | |
908 /* rc == NGX_MAIL_PARSE_INVALID_COMMAND */ | |
909 | |
910 break; | |
911 | |
912 case ngx_pop3_auth_cram_md5: | |
913 arg = s->args.elts; | |
914 | |
915 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, | |
916 "pop3 auth cram-md5: \"%V\"", &arg[0]); | |
917 | |
918 s->login.data = ngx_palloc(c->pool, | |
919 ngx_base64_decoded_length(arg[0].len)); | |
920 if (s->login.data == NULL){ | |
921 ngx_mail_session_internal_server_error(s); | |
922 return; | |
923 } | |
924 | |
925 if (ngx_decode_base64(&s->login, &arg[0]) != NGX_OK) { | |
926 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
927 "client sent invalid base64 encoding " | |
928 "in AUTH CRAM-MD5 command"); | |
929 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
930 break; | |
931 } | |
932 | |
933 p = s->login.data; | |
934 last = p + s->login.len; | |
935 | |
936 while (p < last) { | |
937 if (*p++ == ' ') { | |
938 s->login.len = p - s->login.data - 1; | |
939 s->passwd.len = last - p; | |
940 s->passwd.data = p; | |
941 break; | |
942 } | |
943 } | |
944 | |
945 if (s->passwd.len != 32) { | |
946 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
947 "client sent invalid CRAM-MD5 hash " | |
948 "in AUTH CRAM-MD5 command"); | |
949 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
950 break; | |
951 } | |
952 | |
953 ngx_log_debug2(NGX_LOG_DEBUG_MAIL, c->log, 0, | |
954 "pop3 auth cram-md5: \"%V\" \"%V\"", | |
955 &s->login, &s->passwd); | |
956 | |
957 s->auth_method = NGX_MAIL_AUTH_CRAM_MD5; | |
958 | |
959 ngx_mail_do_auth(s); | |
960 return; | |
961 } | |
962 } | |
963 | |
964 if (rc == NGX_MAIL_PARSE_INVALID_COMMAND) { | |
965 s->mail_state = ngx_pop3_start; | |
966 s->state = 0; | |
967 text = pop3_invalid_command; | |
968 size = sizeof(pop3_invalid_command) - 1; | |
969 } | |
970 | |
971 s->args.nelts = 0; | |
972 s->buffer->pos = s->buffer->start; | |
973 s->buffer->last = s->buffer->start; | |
974 | |
975 if (s->state) { | |
976 s->arg_start = s->buffer->start; | |
977 } | |
978 | |
979 s->out.data = text; | |
980 s->out.len = size; | |
981 | |
982 ngx_mail_send(c->write); | |
983 } | |
984 | |
985 | |
986 void | |
987 ngx_imap_auth_state(ngx_event_t *rev) | |
988 { | |
989 u_char *p, *last, *text, *dst, *src, *end; | |
990 ssize_t text_len, last_len; | |
1323 | 991 ngx_str_t *arg, salt; |
1136 | 992 ngx_int_t rc; |
993 ngx_uint_t tag, i; | |
994 ngx_connection_t *c; | |
995 ngx_mail_session_t *s; | |
996 ngx_mail_core_srv_conf_t *cscf; | |
997 #if (NGX_MAIL_SSL) | |
998 ngx_mail_ssl_conf_t *sslcf; | |
999 #endif | |
1000 | |
1001 c = rev->data; | |
1002 s = c->data; | |
1003 | |
1004 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "imap auth state"); | |
1005 | |
1006 if (rev->timedout) { | |
1007 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); | |
1008 c->timedout = 1; | |
1009 ngx_mail_close_connection(c); | |
1010 return; | |
1011 } | |
1012 | |
1013 if (s->out.len) { | |
1014 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "imap send handler busy"); | |
1015 s->blocked = 1; | |
1016 return; | |
1017 } | |
1018 | |
1019 s->blocked = 0; | |
1020 | |
1021 rc = ngx_mail_read_command(s); | |
527 | 1022 |
1023 if (rc == NGX_AGAIN || rc == NGX_ERROR) { | |
1024 return; | |
1025 } | |
1026 | |
1027 tag = 1; | |
1028 | |
1029 text = NULL; | |
1030 text_len = 0; | |
1031 | |
1032 last = imap_ok; | |
1033 last_len = sizeof(imap_ok) - 1; | |
1034 | |
1035 if (rc == NGX_OK) { | |
1036 | |
1136 | 1037 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, "imap auth command: %i", |
527 | 1038 s->command); |
1039 | |
543 | 1040 if (s->backslash) { |
1041 | |
1042 arg = s->args.elts; | |
1043 | |
1044 for (i = 0; i < s->args.nelts; i++) { | |
1045 dst = arg[i].data; | |
1046 end = dst + arg[i].len; | |
1047 | |
1048 for (src = dst; src < end; dst++) { | |
1049 *dst = *src; | |
1050 if (*src++ == '\\') { | |
1051 *dst = *src++; | |
1052 } | |
1053 } | |
1054 | |
1055 arg[i].len = dst - arg[i].data; | |
1056 } | |
1057 | |
1058 s->backslash = 0; | |
1059 } | |
1060 | |
1323 | 1061 switch (s->mail_state) { |
1062 | |
1063 case ngx_imap_start: | |
1064 | |
1065 switch (s->command) { | |
1066 | |
1067 case NGX_IMAP_LOGIN: | |
583 | 1068 |
1136 | 1069 #if (NGX_MAIL_SSL) |
583 | 1070 |
1323 | 1071 if (c->ssl == NULL) { |
1072 sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module); | |
1073 | |
1074 if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) { | |
1075 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
1076 break; | |
1077 } | |
1078 } | |
1079 #endif | |
1080 | |
1081 arg = s->args.elts; | |
1082 | |
1083 if (s->args.nelts == 2 && arg[0].len) { | |
1084 | |
1085 s->login.len = arg[0].len; | |
1086 s->login.data = ngx_palloc(c->pool, s->login.len); | |
1087 if (s->login.data == NULL) { | |
1088 ngx_mail_session_internal_server_error(s); | |
1089 return; | |
1090 } | |
1091 | |
1092 ngx_memcpy(s->login.data, arg[0].data, s->login.len); | |
1093 | |
1094 s->passwd.len = arg[1].len; | |
1095 s->passwd.data = ngx_palloc(c->pool, s->passwd.len); | |
1096 if (s->passwd.data == NULL) { | |
1097 ngx_mail_session_internal_server_error(s); | |
1098 return; | |
1099 } | |
1100 | |
1101 ngx_memcpy(s->passwd.data, arg[1].data, s->passwd.len); | |
1102 | |
1103 #if (NGX_DEBUG_MAIL_PASSWD) | |
1104 ngx_log_debug2(NGX_LOG_DEBUG_MAIL, c->log, 0, | |
1105 "imap login:\"%V\" passwd:\"%V\"", | |
1106 &s->login, &s->passwd); | |
1107 #else | |
1108 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, | |
1109 "imap login:\"%V\"", &s->login); | |
1110 #endif | |
1111 | |
1112 ngx_mail_do_auth(s); | |
1113 return; | |
1114 } | |
1115 | |
1116 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
1117 break; | |
1118 | |
1119 case NGX_IMAP_AUTHENTICATE: | |
1120 | |
1121 #if (NGX_MAIL_SSL) | |
1122 | |
1123 if (c->ssl == NULL) { | |
1124 sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module); | |
1125 | |
1126 if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) { | |
1127 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
1128 break; | |
1129 } | |
1130 } | |
1131 #endif | |
1132 | |
1133 if (s->args.nelts != 1) { | |
1136 | 1134 rc = NGX_MAIL_PARSE_INVALID_COMMAND; |
583 | 1135 break; |
1136 } | |
1323 | 1137 |
1138 arg = s->args.elts; | |
1139 | |
1140 if (arg[0].len == 5) { | |
1141 | |
1142 if (ngx_strncasecmp(arg[0].data, (u_char *) "LOGIN", 5) | |
1143 == 0) | |
1144 { | |
1145 | |
1146 s->mail_state = ngx_imap_auth_login_username; | |
1147 | |
1148 last_len = sizeof(pop3_username) - 1; | |
1149 last = pop3_username; | |
1150 tag = 0; | |
1151 | |
1152 break; | |
1153 | |
1154 } else if (ngx_strncasecmp(arg[0].data, (u_char *) "PLAIN", | |
1155 5) | |
1156 == 0) | |
1157 { | |
1158 | |
1159 s->mail_state = ngx_imap_auth_plain; | |
1160 | |
1161 last_len = sizeof(pop3_next) - 1; | |
1162 last = pop3_next; | |
1163 tag = 0; | |
1164 | |
1165 break; | |
1166 } | |
1167 | |
1168 } else if (arg[0].len == 8 | |
1169 && ngx_strncasecmp(arg[0].data, | |
1170 (u_char *) "CRAM-MD5", 8) | |
1171 == 0) | |
1172 { | |
1173 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); | |
1174 | |
1175 if (!(cscf->imap_auth_methods | |
1176 & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) | |
1177 || s->args.nelts != 1) | |
1178 { | |
1179 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
1180 break; | |
1181 } | |
1182 | |
1183 s->mail_state = ngx_imap_auth_cram_md5; | |
1184 | |
1185 last = ngx_palloc(c->pool, | |
1186 sizeof("+ " CRLF) - 1 | |
1187 + ngx_base64_encoded_length(s->salt.len)); | |
1188 if (last == NULL) { | |
1189 ngx_mail_session_internal_server_error(s); | |
1190 return; | |
1191 } | |
1192 | |
1193 last[0] = '+'; last[1]= ' '; | |
1194 salt.data = &last[2]; | |
1195 s->salt.len -= 2; | |
1196 | |
1197 ngx_encode_base64(&salt, &s->salt); | |
1198 | |
1199 s->salt.len += 2; | |
1200 last_len = 2 + salt.len; | |
1201 last[last_len++] = CR; last[last_len++] = LF; | |
1202 tag = 0; | |
1203 | |
1204 break; | |
1205 } | |
1206 | |
1207 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
1208 break; | |
1209 | |
1210 case NGX_IMAP_CAPABILITY: | |
1211 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); | |
1212 | |
1213 #if (NGX_MAIL_SSL) | |
1214 | |
1215 if (c->ssl == NULL) { | |
1216 sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module); | |
1217 | |
1218 if (sslcf->starttls == NGX_MAIL_STARTTLS_ON) { | |
1219 text_len = cscf->imap_starttls_capability.len; | |
1220 text = cscf->imap_starttls_capability.data; | |
1221 break; | |
1222 } | |
1223 | |
1224 if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) { | |
1225 text_len = cscf->imap_starttls_only_capability.len; | |
1226 text = cscf->imap_starttls_only_capability.data; | |
1227 break; | |
1228 } | |
1229 } | |
583 | 1230 #endif |
1231 | |
1323 | 1232 text_len = cscf->imap_capability.len; |
1233 text = cscf->imap_capability.data; | |
1234 break; | |
1235 | |
1236 case NGX_IMAP_LOGOUT: | |
1237 s->quit = 1; | |
1238 text = imap_bye; | |
1239 text_len = sizeof(imap_bye) - 1; | |
1240 break; | |
1241 | |
1242 case NGX_IMAP_NOOP: | |
1243 break; | |
1244 | |
1245 #if (NGX_MAIL_SSL) | |
1246 | |
1247 case NGX_IMAP_STARTTLS: | |
1248 if (c->ssl == NULL) { | |
1249 sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module); | |
1250 if (sslcf->starttls) { | |
1251 c->read->handler = ngx_mail_starttls_handler; | |
1252 break; | |
1253 } | |
1254 } | |
1255 | |
1256 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
1257 break; | |
1258 #endif | |
1259 | |
1260 default: | |
1261 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
1262 break; | |
1263 } | |
1264 | |
1265 break; | |
1266 | |
1267 case ngx_imap_auth_login_username: | |
569 | 1268 arg = s->args.elts; |
1323 | 1269 s->mail_state = ngx_imap_auth_login_password; |
1270 | |
1271 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, | |
1272 "imap auth login username: \"%V\"", &arg[0]); | |
1273 | |
1274 s->login.data = ngx_palloc(c->pool, | |
1275 ngx_base64_decoded_length(arg[0].len)); | |
1276 if (s->login.data == NULL){ | |
1277 ngx_mail_session_internal_server_error(s); | |
1278 return; | |
1279 } | |
1280 | |
1281 if (ngx_decode_base64(&s->login, &arg[0]) != NGX_OK) { | |
1282 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
1283 "client sent invalid base64 encoding " | |
1284 "in AUTH LOGIN command"); | |
1285 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
1286 break; | |
1287 } | |
1288 | |
1289 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, | |
1290 "imap auth login username: \"%V\"", &s->login); | |
1291 | |
1292 last_len = sizeof(pop3_password) - 1; | |
1293 last = pop3_password; | |
1294 tag = 0; | |
1295 | |
1296 break; | |
1297 | |
1298 case ngx_imap_auth_login_password: | |
1299 arg = s->args.elts; | |
527 | 1300 |
1136 | 1301 #if (NGX_DEBUG_MAIL_PASSWD) |
1323 | 1302 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, |
1303 "imap auth login password: \"%V\"", &arg[0]); | |
547 | 1304 #endif |
527 | 1305 |
1323 | 1306 s->passwd.data = ngx_palloc(c->pool, |
1307 ngx_base64_decoded_length(arg[0].len)); | |
1308 if (s->passwd.data == NULL){ | |
1309 ngx_mail_session_internal_server_error(s); | |
1310 return; | |
1311 } | |
1312 | |
1313 if (ngx_decode_base64(&s->passwd, &arg[0]) != NGX_OK) { | |
1314 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
1315 "client sent invalid base64 encoding " | |
1316 "in AUTH LOGIN command"); | |
1317 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
1318 break; | |
1319 } | |
1320 | |
1321 #if (NGX_DEBUG_MAIL_PASSWD) | |
1322 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, | |
1323 "imap auth login password: \"%V\"", &s->passwd); | |
1324 #endif | |
1325 | |
1326 ngx_mail_do_auth(s); | |
1327 return; | |
1328 | |
1329 case ngx_imap_auth_plain: | |
1330 arg = s->args.elts; | |
1331 | |
1332 rc = ngx_mail_decode_auth_plain(s, &arg[0]); | |
1333 | |
1334 if (rc == NGX_OK) { | |
1136 | 1335 ngx_mail_do_auth(s); |
527 | 1336 return; |
1337 } | |
1338 | |
1323 | 1339 if (rc == NGX_ERROR) { |
1340 ngx_mail_session_internal_server_error(s); | |
1341 return; | |
1342 } | |
1343 | |
1344 /* rc == NGX_MAIL_PARSE_INVALID_COMMAND */ | |
1345 | |
527 | 1346 break; |
1347 | |
1323 | 1348 case ngx_imap_auth_cram_md5: |
1349 arg = s->args.elts; | |
1350 | |
1351 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, | |
1352 "imap auth cram-md5: \"%V\"", &arg[0]); | |
1353 | |
1354 s->login.data = ngx_palloc(c->pool, | |
1355 ngx_base64_decoded_length(arg[0].len)); | |
1356 if (s->login.data == NULL){ | |
1357 ngx_mail_session_internal_server_error(s); | |
1358 return; | |
1359 } | |
1360 | |
1361 if (ngx_decode_base64(&s->login, &arg[0]) != NGX_OK) { | |
1362 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
1363 "client sent invalid base64 encoding " | |
1364 "in AUTH CRAM-MD5 command"); | |
1365 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
1366 break; | |
1367 } | |
1368 | |
1369 p = s->login.data; | |
1370 last = p + s->login.len; | |
1371 | |
1372 while (p < last) { | |
1373 if (*p++ == ' ') { | |
1374 s->login.len = p - s->login.data - 1; | |
1375 s->passwd.len = last - p; | |
1376 s->passwd.data = p; | |
583 | 1377 break; |
1378 } | |
1379 } | |
1323 | 1380 |
1381 if (s->passwd.len != 32) { | |
1382 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
1383 "client sent invalid CRAM-MD5 hash " | |
1384 "in AUTH CRAM-MD5 command"); | |
1385 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
1386 break; | |
583 | 1387 } |
1388 | |
1323 | 1389 ngx_log_debug2(NGX_LOG_DEBUG_MAIL, c->log, 0, |
1390 "imap auth cram-md5: \"%V\" \"%V\"", | |
1391 &s->login, &s->passwd); | |
1392 | |
1393 s->auth_method = NGX_MAIL_AUTH_CRAM_MD5; | |
1394 | |
1395 ngx_mail_do_auth(s); | |
1396 return; | |
527 | 1397 } |
1398 | |
1399 } else if (rc == NGX_IMAP_NEXT) { | |
1400 last = imap_next; | |
1401 last_len = sizeof(imap_next) - 1; | |
1402 tag = 0; | |
1403 } | |
1404 | |
1136 | 1405 if (rc == NGX_MAIL_PARSE_INVALID_COMMAND) { |
1323 | 1406 s->mail_state = ngx_imap_start; |
1407 s->state = 0; | |
527 | 1408 last = imap_invalid_command; |
1409 last_len = sizeof(imap_invalid_command) - 1; | |
1410 } | |
1411 | |
1412 if (tag) { | |
543 | 1413 if (s->tag.len == 0) { |
1414 s->tag.len = sizeof(imap_star) - 1; | |
1415 s->tag.data = (u_char *) imap_star; | |
1416 } | |
1417 | |
539 | 1418 if (s->tagged_line.len < s->tag.len + text_len + last_len) { |
1419 s->tagged_line.len = s->tag.len + text_len + last_len; | |
1420 s->tagged_line.data = ngx_palloc(c->pool, s->tagged_line.len); | |
1421 if (s->tagged_line.data == NULL) { | |
1136 | 1422 ngx_mail_close_connection(c); |
527 | 1423 return; |
1424 } | |
1425 } | |
1426 | |
539 | 1427 s->out.data = s->tagged_line.data; |
1428 s->out.len = s->tag.len + text_len + last_len; | |
1429 | |
1430 p = s->out.data; | |
527 | 1431 |
1432 if (text) { | |
1433 p = ngx_cpymem(p, text, text_len); | |
1434 } | |
1435 p = ngx_cpymem(p, s->tag.data, s->tag.len); | |
1436 ngx_memcpy(p, last, last_len); | |
1437 | |
1438 | |
1439 } else { | |
539 | 1440 s->out.data = last; |
1441 s->out.len = last_len; | |
527 | 1442 } |
1443 | |
539 | 1444 if (rc != NGX_IMAP_NEXT) { |
1445 s->args.nelts = 0; | |
1323 | 1446 |
1447 if (s->state) { | |
1448 /* preserve tag */ | |
1449 s->arg_start = s->buffer->start + s->tag.len; | |
1450 s->buffer->pos = s->arg_start; | |
1451 s->buffer->last = s->arg_start; | |
1452 | |
1453 } else { | |
1454 s->buffer->pos = s->buffer->start; | |
1455 s->buffer->last = s->buffer->start; | |
1456 s->tag.len = 0; | |
1457 } | |
527 | 1458 } |
1459 | |
1136 | 1460 ngx_mail_send(c->write); |
521 | 1461 } |
1462 | |
1463 | |
527 | 1464 void |
1136 | 1465 ngx_smtp_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
|
1466 { |
1136 | 1467 u_char *p, *last, *text, ch; |
527 | 1468 ssize_t size; |
1469 ngx_int_t rc; | |
1136 | 1470 ngx_str_t *arg, salt, l; |
1471 ngx_uint_t i; | |
527 | 1472 ngx_connection_t *c; |
1136 | 1473 ngx_mail_session_t *s; |
1474 ngx_mail_core_srv_conf_t *cscf; | |
1322 | 1475 #if (NGX_MAIL_SSL) |
1476 ngx_mail_ssl_conf_t *sslcf; | |
1477 #endif | |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
1478 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
1479 c = rev->data; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
1480 s = c->data; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
1481 |
1136 | 1482 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "smtp auth state"); |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
1483 |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1484 if (rev->timedout) { |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1485 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); |
577 | 1486 c->timedout = 1; |
1136 | 1487 ngx_mail_close_connection(c); |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1488 return; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1489 } |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
1490 |
539 | 1491 if (s->out.len) { |
1136 | 1492 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "smtp send handler busy"); |
539 | 1493 s->blocked = 1; |
1494 return; | |
1495 } | |
1496 | |
1497 s->blocked = 0; | |
1498 | |
1136 | 1499 rc = ngx_mail_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
|
1500 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
1501 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
|
1502 return; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
1503 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
1504 |
1136 | 1505 text = NULL; |
1506 size = 0; | |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
1507 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
1508 if (rc == NGX_OK) { |
1136 | 1509 switch (s->mail_state) { |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
1510 |
1136 | 1511 case ngx_smtp_start: |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
1512 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
1513 switch (s->command) { |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
1514 |
1136 | 1515 case NGX_SMTP_HELO: |
1516 case NGX_SMTP_EHLO: | |
1517 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); | |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
421
diff
changeset
|
1518 |
1136 | 1519 if (s->args.nelts != 1) { |
1520 text = smtp_invalid_argument; | |
1521 size = sizeof(smtp_invalid_argument) - 1; | |
1522 s->state = 0; | |
809 | 1523 break; |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
1524 } |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
1525 |
1136 | 1526 arg = s->args.elts; |
583 | 1527 |
1136 | 1528 s->smtp_helo.len = arg[0].len; |
800 | 1529 |
1136 | 1530 s->smtp_helo.data = ngx_palloc(c->pool, arg[0].len); |
1531 if (s->smtp_helo.data == NULL) { | |
1532 ngx_mail_session_internal_server_error(s); | |
800 | 1533 return; |
809 | 1534 } |
800 | 1535 |
1136 | 1536 ngx_memcpy(s->smtp_helo.data, arg[0].data, arg[0].len); |
1537 | |
1538 if (s->command == NGX_SMTP_HELO) { | |
1539 size = cscf->smtp_server_name.len; | |
1540 text = cscf->smtp_server_name.data; | |
1541 | |
1542 } else { | |
1543 s->esmtp = 1; | |
1322 | 1544 |
1545 #if (NGX_MAIL_SSL) | |
1546 | |
1547 if (c->ssl == NULL) { | |
1548 sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module); | |
1549 | |
1550 if (sslcf->starttls == NGX_MAIL_STARTTLS_ON) { | |
1551 size = cscf->smtp_starttls_capability.len; | |
1552 text = cscf->smtp_starttls_capability.data; | |
1553 break; | |
1554 } | |
1555 | |
1556 if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) { | |
1557 size = cscf->smtp_starttls_only_capability.len; | |
1558 text = cscf->smtp_starttls_only_capability.data; | |
1559 break; | |
1560 } | |
1561 } | |
1562 #endif | |
1563 | |
1136 | 1564 size = cscf->smtp_capability.len; |
1565 text = cscf->smtp_capability.data; | |
1566 } | |
1567 | |
809 | 1568 break; |
1569 | |
1136 | 1570 case NGX_SMTP_AUTH: |
809 | 1571 |
1322 | 1572 #if (NGX_MAIL_SSL) |
1573 | |
1574 if (c->ssl == NULL) { | |
1575 sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module); | |
1576 | |
1577 if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) { | |
1578 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
1579 break; | |
1580 } | |
1581 } | |
1582 #endif | |
1583 | |
809 | 1584 if (s->args.nelts == 0) { |
1136 | 1585 text = smtp_invalid_argument; |
1586 size = sizeof(smtp_invalid_argument) - 1; | |
810 | 1587 s->state = 0; |
809 | 1588 break; |
1589 } | |
1590 | |
1591 arg = s->args.elts; | |
1592 | |
1593 if (arg[0].len == 5) { | |
1594 | |
1107
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
1025
diff
changeset
|
1595 if (ngx_strncasecmp(arg[0].data, (u_char *) "LOGIN", 5) |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
1025
diff
changeset
|
1596 == 0) |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
1025
diff
changeset
|
1597 { |
894
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1598 |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1599 if (s->args.nelts != 1) { |
1136 | 1600 rc = NGX_MAIL_PARSE_INVALID_COMMAND; |
894
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1601 break; |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1602 } |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1603 |
1136 | 1604 s->mail_state = ngx_smtp_auth_login_username; |
809 | 1605 |
1136 | 1606 size = sizeof(smtp_username) - 1; |
1607 text = smtp_username; | |
809 | 1608 |
1609 break; | |
1610 | |
1107
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
1025
diff
changeset
|
1611 } else if (ngx_strncasecmp(arg[0].data, (u_char *) "PLAIN", |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
1025
diff
changeset
|
1612 5) |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
1025
diff
changeset
|
1613 == 0) |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
1025
diff
changeset
|
1614 { |
1136 | 1615 if (s->args.nelts == 1) { |
1616 s->mail_state = ngx_smtp_auth_plain; | |
894
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1617 |
1136 | 1618 size = sizeof(smtp_next) - 1; |
1619 text = smtp_next; | |
894
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1620 |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1621 break; |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1622 } |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1623 |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1624 if (s->args.nelts == 2) { |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1625 |
1136 | 1626 rc = ngx_mail_decode_auth_plain(s, &arg[1]); |
894
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1627 |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1628 if (rc == NGX_OK) { |
1136 | 1629 ngx_mail_do_auth(s); |
894
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1630 return; |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1631 } |
809 | 1632 |
894
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1633 if (rc == NGX_ERROR) { |
1136 | 1634 ngx_mail_session_internal_server_error(s); |
894
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1635 return; |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1636 } |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1637 |
1136 | 1638 /* rc == NGX_MAIL_PARSE_INVALID_COMMAND */ |
894
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1639 |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1640 break; |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1641 } |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1642 |
1136 | 1643 rc = NGX_MAIL_PARSE_INVALID_COMMAND; |
809 | 1644 break; |
1645 } | |
1646 | |
1647 } else if (arg[0].len == 8 | |
1107
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
1025
diff
changeset
|
1648 && ngx_strncasecmp(arg[0].data, |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
1025
diff
changeset
|
1649 (u_char *) "CRAM-MD5", 8) |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
1025
diff
changeset
|
1650 == 0) |
809 | 1651 { |
1286
a9c361479430
fix segfault when CRAM-MD5 is not enabled but client tries it
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
1652 cscf = ngx_mail_get_module_srv_conf(s, |
a9c361479430
fix segfault when CRAM-MD5 is not enabled but client tries it
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
1653 ngx_mail_core_module); |
a9c361479430
fix segfault when CRAM-MD5 is not enabled but client tries it
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
1654 |
a9c361479430
fix segfault when CRAM-MD5 is not enabled but client tries it
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
1655 if (!(cscf->smtp_auth_methods |
a9c361479430
fix segfault when CRAM-MD5 is not enabled but client tries it
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
1656 & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) |
a9c361479430
fix segfault when CRAM-MD5 is not enabled but client tries it
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
1657 || s->args.nelts != 1) |
a9c361479430
fix segfault when CRAM-MD5 is not enabled but client tries it
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
1658 { |
1136 | 1659 rc = NGX_MAIL_PARSE_INVALID_COMMAND; |
1660 break; | |
1661 } | |
1662 | |
1663 s->mail_state = ngx_smtp_auth_cram_md5; | |
809 | 1664 |
1665 text = ngx_palloc(c->pool, | |
1136 | 1666 sizeof("334 " CRLF) - 1 |
1667 + ngx_base64_encoded_length(s->salt.len)); | |
809 | 1668 if (text == NULL) { |
1136 | 1669 ngx_mail_session_internal_server_error(s); |
809 | 1670 return; |
1671 } | |
1672 | |
1136 | 1673 text[0] = '3'; text[1]= '3'; text[2] = '4'; text[3]= ' '; |
1674 salt.data = &text[4]; | |
809 | 1675 s->salt.len -= 2; |
1676 | |
1677 ngx_encode_base64(&salt, &s->salt); | |
1678 | |
1679 s->salt.len += 2; | |
1136 | 1680 size = 4 + salt.len; |
809 | 1681 text[size++] = CR; text[size++] = LF; |
1682 | |
1683 break; | |
1684 } | |
1685 | |
1136 | 1686 rc = NGX_MAIL_PARSE_INVALID_COMMAND; |
800 | 1687 break; |
1688 | |
1136 | 1689 case NGX_SMTP_QUIT: |
539 | 1690 s->quit = 1; |
1136 | 1691 text = smtp_bye; |
1692 size = sizeof(smtp_bye) - 1; | |
527 | 1693 break; |
1694 | |
1136 | 1695 case NGX_SMTP_MAIL: |
1696 | |
1697 if (s->connection->log->log_level >= NGX_LOG_INFO) { | |
1166 | 1698 l.len = s->buffer->last - s->buffer->start; |
1699 l.data = s->buffer->start; | |
1136 | 1700 |
1166 | 1701 for (i = 0; i < l.len; i++) { |
1702 ch = l.data[i]; | |
1136 | 1703 |
1166 | 1704 if (ch != CR && ch != LF) { |
1705 continue; | |
1706 } | |
583 | 1707 |
1166 | 1708 l.data[i] = ' '; |
1709 } | |
1136 | 1710 |
1166 | 1711 while (i) { |
1712 if (l.data[i - 1] != ' ') { | |
1713 break; | |
1714 } | |
1136 | 1715 |
1166 | 1716 i--; |
1717 } | |
1136 | 1718 |
1166 | 1719 l.len = i; |
1136 | 1720 |
1166 | 1721 ngx_log_error(NGX_LOG_INFO, s->connection->log, 0, |
1722 "client was rejected: \"%V\"", &l); | |
583 | 1723 } |
1724 | |
1136 | 1725 text = smtp_auth_required; |
1726 size = sizeof(smtp_auth_required) - 1; | |
583 | 1727 break; |
1728 | |
1136 | 1729 case NGX_SMTP_NOOP: |
1730 case NGX_SMTP_RSET: | |
1731 text = smtp_ok; | |
1732 size = sizeof(smtp_ok) - 1; | |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
1733 break; |
1322 | 1734 |
1735 #if (NGX_MAIL_SSL) | |
1736 | |
1737 case NGX_SMTP_STARTTLS: | |
1738 if (c->ssl == NULL) { | |
1739 sslcf = ngx_mail_get_module_srv_conf(s, | |
1740 ngx_mail_ssl_module); | |
1741 if (sslcf->starttls) { | |
1742 c->read->handler = ngx_mail_starttls_handler; | |
1743 | |
1744 /* | |
1745 * RFC3207 requires us to discard any knowledge | |
1746 * obtained from client before STARTTLS. | |
1747 */ | |
1748 | |
1749 s->smtp_helo.len = 0; | |
1750 s->smtp_helo.data = NULL; | |
1751 | |
1752 text = smtp_ok; | |
1753 size = sizeof(smtp_ok) - 1; | |
1754 | |
1755 break; | |
1756 } | |
1757 } | |
1758 | |
1759 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
1760 break; | |
1761 #endif | |
1762 | |
1763 default: | |
1764 rc = NGX_MAIL_PARSE_INVALID_COMMAND; | |
1765 break; | |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
1766 } |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
1767 |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
1768 break; |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
1769 |
1136 | 1770 case ngx_smtp_auth_login_username: |
1771 arg = s->args.elts; | |
1772 s->mail_state = ngx_smtp_auth_login_password; | |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
1773 |
1136 | 1774 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, |
1775 "smtp auth login username: \"%V\"", &arg[0]); | |
809 | 1776 |
1777 s->login.data = ngx_palloc(c->pool, | |
1778 ngx_base64_decoded_length(arg[0].len)); | |
1779 if (s->login.data == NULL){ | |
1136 | 1780 ngx_mail_session_internal_server_error(s); |
809 | 1781 return; |
1782 } | |
1783 | |
1784 if (ngx_decode_base64(&s->login, &arg[0]) != NGX_OK) { | |
1785 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
1786 "client sent invalid base64 encoding " | |
1787 "in AUTH LOGIN command"); | |
1136 | 1788 rc = NGX_MAIL_PARSE_INVALID_COMMAND; |
810 | 1789 break; |
809 | 1790 } |
1791 | |
1136 | 1792 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, |
1793 "smtp auth login username: \"%V\"", &s->login); | |
809 | 1794 |
1136 | 1795 size = sizeof(smtp_password) - 1; |
1796 text = smtp_password; | |
809 | 1797 |
1798 break; | |
1799 | |
1136 | 1800 case ngx_smtp_auth_login_password: |
809 | 1801 arg = s->args.elts; |
1802 | |
1136 | 1803 #if (NGX_DEBUG_MAIL_PASSWD) |
1804 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, | |
1805 "smtp auth login password: \"%V\"", &arg[0]); | |
809 | 1806 #endif |
1807 | |
1808 s->passwd.data = ngx_palloc(c->pool, | |
1809 ngx_base64_decoded_length(arg[0].len)); | |
1810 if (s->passwd.data == NULL){ | |
1136 | 1811 ngx_mail_session_internal_server_error(s); |
809 | 1812 return; |
1813 } | |
1814 | |
1815 if (ngx_decode_base64(&s->passwd, &arg[0]) != NGX_OK) { | |
1816 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
1817 "client sent invalid base64 encoding " | |
1818 "in AUTH LOGIN command"); | |
1136 | 1819 rc = NGX_MAIL_PARSE_INVALID_COMMAND; |
810 | 1820 break; |
809 | 1821 } |
1822 | |
1136 | 1823 #if (NGX_DEBUG_MAIL_PASSWD) |
1824 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, | |
1825 "smtp auth login password: \"%V\"", &s->passwd); | |
809 | 1826 #endif |
1827 | |
1136 | 1828 ngx_mail_do_auth(s); |
809 | 1829 return; |
1830 | |
1136 | 1831 case ngx_smtp_auth_plain: |
809 | 1832 arg = s->args.elts; |
1833 | |
1136 | 1834 rc = ngx_mail_decode_auth_plain(s, &arg[0]); |
809 | 1835 |
894
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1836 if (rc == NGX_OK) { |
1136 | 1837 ngx_mail_do_auth(s); |
894
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1838 return; |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1839 } |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1840 |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1841 if (rc == NGX_ERROR) { |
1136 | 1842 ngx_mail_session_internal_server_error(s); |
809 | 1843 return; |
1844 } | |
1845 | |
1136 | 1846 /* rc == NGX_MAIL_PARSE_INVALID_COMMAND */ |
809 | 1847 |
894
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1848 break; |
809 | 1849 |
1136 | 1850 case ngx_smtp_auth_cram_md5: |
809 | 1851 arg = s->args.elts; |
1852 | |
1136 | 1853 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, |
1854 "smtp auth cram-md5: \"%V\"", &arg[0]); | |
809 | 1855 |
1856 s->login.data = ngx_palloc(c->pool, | |
1857 ngx_base64_decoded_length(arg[0].len)); | |
1858 if (s->login.data == NULL){ | |
1136 | 1859 ngx_mail_session_internal_server_error(s); |
809 | 1860 return; |
1861 } | |
1862 | |
1863 if (ngx_decode_base64(&s->login, &arg[0]) != NGX_OK) { | |
1864 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
1865 "client sent invalid base64 encoding " | |
810 | 1866 "in AUTH CRAM-MD5 command"); |
1136 | 1867 rc = NGX_MAIL_PARSE_INVALID_COMMAND; |
810 | 1868 break; |
809 | 1869 } |
1870 | |
1871 p = s->login.data; | |
1872 last = p + s->login.len; | |
1873 | |
1874 while (p < last) { | |
1875 if (*p++ == ' ') { | |
1876 s->login.len = p - s->login.data - 1; | |
1877 s->passwd.len = last - p; | |
1878 s->passwd.data = p; | |
1879 break; | |
1880 } | |
1881 } | |
1882 | |
810 | 1883 if (s->passwd.len != 32) { |
1884 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
1885 "client sent invalid CRAM-MD5 hash " | |
1886 "in AUTH CRAM-MD5 command"); | |
1136 | 1887 rc = NGX_MAIL_PARSE_INVALID_COMMAND; |
810 | 1888 break; |
1889 } | |
1890 | |
1136 | 1891 ngx_log_debug2(NGX_LOG_DEBUG_MAIL, c->log, 0, |
1892 "smtp auth cram-md5: \"%V\" \"%V\"", | |
809 | 1893 &s->login, &s->passwd); |
1894 | |
1136 | 1895 s->auth_method = NGX_MAIL_AUTH_CRAM_MD5; |
809 | 1896 |
1136 | 1897 ngx_mail_do_auth(s); |
809 | 1898 return; |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
1899 } |
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
1900 } |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
1901 |
1136 | 1902 if (rc == NGX_MAIL_PARSE_INVALID_COMMAND) { |
1903 s->mail_state = ngx_smtp_start; | |
810 | 1904 s->state = 0; |
1136 | 1905 text = smtp_invalid_command; |
1906 size = sizeof(smtp_invalid_command) - 1; | |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
1907 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
1908 |
421
01456a419cf9
nginx-0.0.10-2004-09-10-18:32:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
420
diff
changeset
|
1909 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
|
1910 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
|
1911 s->buffer->last = s->buffer->start; |
539 | 1912 |
810 | 1913 if (s->state) { |
1914 s->arg_start = s->buffer->start; | |
1915 } | |
1916 | |
539 | 1917 s->out.data = text; |
1918 s->out.len = size; | |
1919 | |
1136 | 1920 ngx_mail_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
|
1921 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
1922 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
1923 |
894
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1924 static ngx_int_t |
1136 | 1925 ngx_mail_decode_auth_plain(ngx_mail_session_t *s, ngx_str_t *encoded) |
894
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1926 { |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1927 u_char *p, *last; |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1928 ngx_str_t plain; |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1929 |
1136 | 1930 #if (NGX_DEBUG_MAIL_PASSWD) |
1931 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, | |
1932 "mail auth plain: \"%V\"", encoded); | |
894
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1933 #endif |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1934 |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1935 plain.data = ngx_palloc(s->connection->pool, |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1936 ngx_base64_decoded_length(encoded->len)); |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1937 if (plain.data == NULL){ |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1938 return NGX_ERROR; |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1939 } |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1940 |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1941 if (ngx_decode_base64(&plain, encoded) != NGX_OK) { |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1942 ngx_log_error(NGX_LOG_INFO, s->connection->log, 0, |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1943 "client sent invalid base64 encoding " |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1944 "in AUTH PLAIN command"); |
1136 | 1945 return NGX_MAIL_PARSE_INVALID_COMMAND; |
894
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1946 } |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1947 |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1948 p = plain.data; |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1949 last = p + plain.len; |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1950 |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1951 while (p < last && *p++) { /* void */ } |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1952 |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1953 if (p == last) { |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1954 ngx_log_error(NGX_LOG_INFO, s->connection->log, 0, |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1955 "client sent invalid login in AUTH PLAIN command"); |
1136 | 1956 return NGX_MAIL_PARSE_INVALID_COMMAND; |
894
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1957 } |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1958 |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1959 s->login.data = p; |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1960 |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1961 while (p < last && *p) { p++; } |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1962 |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1963 if (p == last) { |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1964 ngx_log_error(NGX_LOG_INFO, s->connection->log, 0, |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1965 "client sent invalid password in AUTH PLAIN command"); |
1136 | 1966 return NGX_MAIL_PARSE_INVALID_COMMAND; |
894
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1967 } |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1968 |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1969 s->login.len = p++ - s->login.data; |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1970 |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1971 s->passwd.len = last - p; |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1972 s->passwd.data = p; |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1973 |
1136 | 1974 #if (NGX_DEBUG_MAIL_PASSWD) |
1975 ngx_log_debug2(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, | |
1976 "mail auth plain: \"%V\" \"%V\"", | |
894
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1977 &s->login, &s->passwd); |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1978 #endif |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1979 |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1980 return NGX_OK; |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1981 } |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1982 |
4f7dca9c37f0
workaround for Eudora for Mac: it sends
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
1983 |
855
b006f30d6a2f
count s->login_attempt for POP3, minimize code
Igor Sysoev <igor@sysoev.ru>
parents:
851
diff
changeset
|
1984 static void |
1136 | 1985 ngx_mail_do_auth(ngx_mail_session_t *s) |
855
b006f30d6a2f
count s->login_attempt for POP3, minimize code
Igor Sysoev <igor@sysoev.ru>
parents:
851
diff
changeset
|
1986 { |
b006f30d6a2f
count s->login_attempt for POP3, minimize code
Igor Sysoev <igor@sysoev.ru>
parents:
851
diff
changeset
|
1987 s->args.nelts = 0; |
b006f30d6a2f
count s->login_attempt for POP3, minimize code
Igor Sysoev <igor@sysoev.ru>
parents:
851
diff
changeset
|
1988 s->buffer->pos = s->buffer->start; |
b006f30d6a2f
count s->login_attempt for POP3, minimize code
Igor Sysoev <igor@sysoev.ru>
parents:
851
diff
changeset
|
1989 s->buffer->last = s->buffer->start; |
b006f30d6a2f
count s->login_attempt for POP3, minimize code
Igor Sysoev <igor@sysoev.ru>
parents:
851
diff
changeset
|
1990 s->state = 0; |
b006f30d6a2f
count s->login_attempt for POP3, minimize code
Igor Sysoev <igor@sysoev.ru>
parents:
851
diff
changeset
|
1991 |
b006f30d6a2f
count s->login_attempt for POP3, minimize code
Igor Sysoev <igor@sysoev.ru>
parents:
851
diff
changeset
|
1992 if (s->connection->read->timer_set) { |
1025 | 1993 ngx_del_timer(s->connection->read); |
855
b006f30d6a2f
count s->login_attempt for POP3, minimize code
Igor Sysoev <igor@sysoev.ru>
parents:
851
diff
changeset
|
1994 } |
b006f30d6a2f
count s->login_attempt for POP3, minimize code
Igor Sysoev <igor@sysoev.ru>
parents:
851
diff
changeset
|
1995 |
b006f30d6a2f
count s->login_attempt for POP3, minimize code
Igor Sysoev <igor@sysoev.ru>
parents:
851
diff
changeset
|
1996 s->login_attempt++; |
b006f30d6a2f
count s->login_attempt for POP3, minimize code
Igor Sysoev <igor@sysoev.ru>
parents:
851
diff
changeset
|
1997 |
1136 | 1998 ngx_mail_auth_http_init(s); |
855
b006f30d6a2f
count s->login_attempt for POP3, minimize code
Igor Sysoev <igor@sysoev.ru>
parents:
851
diff
changeset
|
1999 } |
b006f30d6a2f
count s->login_attempt for POP3, minimize code
Igor Sysoev <igor@sysoev.ru>
parents:
851
diff
changeset
|
2000 |
b006f30d6a2f
count s->login_attempt for POP3, minimize code
Igor Sysoev <igor@sysoev.ru>
parents:
851
diff
changeset
|
2001 |
521 | 2002 static ngx_int_t |
1136 | 2003 ngx_mail_read_command(ngx_mail_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
|
2004 { |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2005 ssize_t n; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2006 ngx_int_t rc; |
1108
109e8c7d7cc1
return error for too long commands
Igor Sysoev <igor@sysoev.ru>
parents:
1107
diff
changeset
|
2007 ngx_str_t l; |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2008 |
539 | 2009 n = s->connection->recv(s->connection, s->buffer->last, |
2010 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
|
2011 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2012 if (n == NGX_ERROR || n == 0) { |
1136 | 2013 ngx_mail_close_connection(s->connection); |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2014 return NGX_ERROR; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2015 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2016 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2017 if (n > 0) { |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2018 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
|
2019 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2020 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2021 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
|
2022 if (ngx_handle_read_event(s->connection->read, 0) == NGX_ERROR) { |
1136 | 2023 ngx_mail_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
|
2024 return NGX_ERROR; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2025 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2026 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2027 return NGX_AGAIN; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2028 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2029 |
1136 | 2030 switch (s->protocol) { |
2031 case NGX_MAIL_POP3_PROTOCOL: | |
527 | 2032 rc = ngx_pop3_parse_command(s); |
1136 | 2033 break; |
2034 | |
2035 case NGX_MAIL_IMAP_PROTOCOL: | |
527 | 2036 rc = ngx_imap_parse_command(s); |
1136 | 2037 break; |
2038 | |
2039 default: /* NGX_MAIL_SMTP_PROTOCOL */ | |
2040 rc = ngx_smtp_parse_command(s); | |
2041 break; | |
527 | 2042 } |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2043 |
1108
109e8c7d7cc1
return error for too long commands
Igor Sysoev <igor@sysoev.ru>
parents:
1107
diff
changeset
|
2044 if (rc == NGX_AGAIN) { |
109e8c7d7cc1
return error for too long commands
Igor Sysoev <igor@sysoev.ru>
parents:
1107
diff
changeset
|
2045 |
109e8c7d7cc1
return error for too long commands
Igor Sysoev <igor@sysoev.ru>
parents:
1107
diff
changeset
|
2046 if (s->buffer->last < s->buffer->end) { |
109e8c7d7cc1
return error for too long commands
Igor Sysoev <igor@sysoev.ru>
parents:
1107
diff
changeset
|
2047 return rc; |
109e8c7d7cc1
return error for too long commands
Igor Sysoev <igor@sysoev.ru>
parents:
1107
diff
changeset
|
2048 } |
109e8c7d7cc1
return error for too long commands
Igor Sysoev <igor@sysoev.ru>
parents:
1107
diff
changeset
|
2049 |
109e8c7d7cc1
return error for too long commands
Igor Sysoev <igor@sysoev.ru>
parents:
1107
diff
changeset
|
2050 l.len = s->buffer->last - s->buffer->start; |
109e8c7d7cc1
return error for too long commands
Igor Sysoev <igor@sysoev.ru>
parents:
1107
diff
changeset
|
2051 l.data = s->buffer->start; |
109e8c7d7cc1
return error for too long commands
Igor Sysoev <igor@sysoev.ru>
parents:
1107
diff
changeset
|
2052 |
109e8c7d7cc1
return error for too long commands
Igor Sysoev <igor@sysoev.ru>
parents:
1107
diff
changeset
|
2053 ngx_log_error(NGX_LOG_INFO, s->connection->log, 0, |
109e8c7d7cc1
return error for too long commands
Igor Sysoev <igor@sysoev.ru>
parents:
1107
diff
changeset
|
2054 "client sent too long command \"%V\"", &l); |
109e8c7d7cc1
return error for too long commands
Igor Sysoev <igor@sysoev.ru>
parents:
1107
diff
changeset
|
2055 |
1111
b0fc4af1f196
close connection for too long commands
Igor Sysoev <igor@sysoev.ru>
parents:
1108
diff
changeset
|
2056 s->quit = 1; |
b0fc4af1f196
close connection for too long commands
Igor Sysoev <igor@sysoev.ru>
parents:
1108
diff
changeset
|
2057 |
1136 | 2058 return NGX_MAIL_PARSE_INVALID_COMMAND; |
1108
109e8c7d7cc1
return error for too long commands
Igor Sysoev <igor@sysoev.ru>
parents:
1107
diff
changeset
|
2059 } |
109e8c7d7cc1
return error for too long commands
Igor Sysoev <igor@sysoev.ru>
parents:
1107
diff
changeset
|
2060 |
1136 | 2061 if (rc == NGX_IMAP_NEXT || rc == NGX_MAIL_PARSE_INVALID_COMMAND) { |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2062 return rc; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2063 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2064 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2065 if (rc == NGX_ERROR) { |
1136 | 2066 ngx_mail_close_connection(s->connection); |
420
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2067 return NGX_ERROR; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2068 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2069 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2070 return NGX_OK; |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2071 } |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2072 |
33a8253115b4
nginx-0.0.10-2004-09-09-22:55:39 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
2073 |
521 | 2074 void |
1136 | 2075 ngx_mail_session_internal_server_error(ngx_mail_session_t *s) |
525 | 2076 { |
539 | 2077 s->out = internal_server_errors[s->protocol]; |
2078 s->quit = 1; | |
525 | 2079 |
1136 | 2080 ngx_mail_send(s->connection->write); |
525 | 2081 } |
2082 | |
2083 | |
2084 void | |
1136 | 2085 ngx_mail_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
|
2086 { |
479 | 2087 ngx_pool_t *pool; |
2088 | |
1136 | 2089 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, |
2090 "close mail connection: %d", c->fd); | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
2091 |
1136 | 2092 #if (NGX_MAIL_SSL) |
539 | 2093 |
2094 if (c->ssl) { | |
2095 if (ngx_ssl_shutdown(c) == NGX_AGAIN) { | |
1136 | 2096 c->ssl->handler = ngx_mail_close_connection; |
539 | 2097 return; |
2098 } | |
2099 } | |
2100 | |
2101 #endif | |
2102 | |
583 | 2103 c->destroyed = 1; |
543 | 2104 |
479 | 2105 pool = c->pool; |
2106 | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
415
diff
changeset
|
2107 ngx_close_connection(c); |
479 | 2108 |
501 | 2109 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
|
2110 } |
539 | 2111 |
2112 | |
541 | 2113 static u_char * |
1136 | 2114 ngx_mail_log_error(ngx_log_t *log, u_char *buf, size_t len) |
541 | 2115 { |
567 | 2116 u_char *p; |
1136 | 2117 ngx_mail_session_t *s; |
2118 ngx_mail_log_ctx_t *ctx; | |
541 | 2119 |
2120 if (log->action) { | |
2121 p = ngx_snprintf(buf, len, " while %s", log->action); | |
2122 len -= p - buf; | |
2123 buf = p; | |
2124 } | |
577 | 2125 |
541 | 2126 ctx = log->data; |
2127 | |
2128 p = ngx_snprintf(buf, len, ", client: %V", ctx->client); | |
2129 len -= p - buf; | |
2130 buf = p; | |
2131 | |
2132 s = ctx->session; | |
2133 | |
2134 if (s == NULL) { | |
2135 return p; | |
2136 } | |
2137 | |
641 | 2138 p = ngx_snprintf(buf, len, ", server: %V", s->addr_text); |
541 | 2139 len -= p - buf; |
2140 buf = p; | |
2141 | |
2142 if (s->login.len == 0) { | |
2143 return p; | |
2144 } | |
2145 | |
2146 p = ngx_snprintf(buf, len, ", login: \"%V\"", &s->login); | |
2147 len -= p - buf; | |
2148 buf = p; | |
2149 | |
2150 if (s->proxy == NULL) { | |
2151 return p; | |
2152 } | |
2153 | |
884 | 2154 p = ngx_snprintf(buf, len, ", upstream: %V", s->proxy->upstream.name); |
541 | 2155 |
2156 return p; | |
2157 } |