Mercurial > hg > nginx-quic
annotate src/mail/ngx_mail_auth_http_module.c @ 5920:7420068c4d4b
Resolver: fixed use-after-free memory access.
In 954867a2f0a6, we switched to using resolver node as the
timer event data, so make sure we do not free resolver node
memory until the corresponding timer is deleted.
author | Ruslan Ermilov <ru@nginx.com> |
---|---|
date | Thu, 20 Nov 2014 15:24:40 +0300 |
parents | 0cbefdcf82a6 |
children | 62c098eb4509 |
rev | line source |
---|---|
521 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
521 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_event.h> | |
11 #include <ngx_event_connect.h> | |
1136 | 12 #include <ngx_mail.h> |
521 | 13 |
14 | |
15 typedef struct { | |
3269
f0d596e84634
rename ngx_peer_addr_t to ngx_addr_t
Igor Sysoev <igor@sysoev.ru>
parents:
3267
diff
changeset
|
16 ngx_addr_t *peer; |
521 | 17 |
527 | 18 ngx_msec_t timeout; |
521 | 19 |
527 | 20 ngx_str_t host_header; |
21 ngx_str_t uri; | |
573 | 22 ngx_str_t header; |
23 | |
24 ngx_array_t *headers; | |
1392 | 25 |
26 u_char *file; | |
27 ngx_uint_t line; | |
1136 | 28 } ngx_mail_auth_http_conf_t; |
521 | 29 |
30 | |
1136 | 31 typedef struct ngx_mail_auth_http_ctx_s ngx_mail_auth_http_ctx_t; |
527 | 32 |
1136 | 33 typedef void (*ngx_mail_auth_http_handler_pt)(ngx_mail_session_t *s, |
34 ngx_mail_auth_http_ctx_t *ctx); | |
527 | 35 |
1136 | 36 struct ngx_mail_auth_http_ctx_s { |
527 | 37 ngx_buf_t *request; |
38 ngx_buf_t *response; | |
39 ngx_peer_connection_t peer; | |
40 | |
1136 | 41 ngx_mail_auth_http_handler_pt handler; |
527 | 42 |
43 ngx_uint_t state; | |
44 | |
45 u_char *header_name_start; | |
46 u_char *header_name_end; | |
47 u_char *header_start; | |
48 u_char *header_end; | |
49 | |
50 ngx_str_t addr; | |
51 ngx_str_t port; | |
52 ngx_str_t err; | |
567 | 53 ngx_str_t errmsg; |
1136 | 54 ngx_str_t errcode; |
527 | 55 |
547 | 56 time_t sleep; |
527 | 57 |
547 | 58 ngx_pool_t *pool; |
527 | 59 }; |
521 | 60 |
61 | |
1136 | 62 static void ngx_mail_auth_http_write_handler(ngx_event_t *wev); |
63 static void ngx_mail_auth_http_read_handler(ngx_event_t *rev); | |
64 static void ngx_mail_auth_http_ignore_status_line(ngx_mail_session_t *s, | |
65 ngx_mail_auth_http_ctx_t *ctx); | |
66 static void ngx_mail_auth_http_process_headers(ngx_mail_session_t *s, | |
67 ngx_mail_auth_http_ctx_t *ctx); | |
68 static void ngx_mail_auth_sleep_handler(ngx_event_t *rev); | |
69 static ngx_int_t ngx_mail_auth_http_parse_header_line(ngx_mail_session_t *s, | |
70 ngx_mail_auth_http_ctx_t *ctx); | |
71 static void ngx_mail_auth_http_block_read(ngx_event_t *rev); | |
72 static void ngx_mail_auth_http_dummy_handler(ngx_event_t *ev); | |
73 static ngx_buf_t *ngx_mail_auth_http_create_request(ngx_mail_session_t *s, | |
74 ngx_pool_t *pool, ngx_mail_auth_http_conf_t *ahcf); | |
75 static ngx_int_t ngx_mail_auth_http_escape(ngx_pool_t *pool, ngx_str_t *text, | |
633 | 76 ngx_str_t *escaped); |
521 | 77 |
1136 | 78 static void *ngx_mail_auth_http_create_conf(ngx_conf_t *cf); |
79 static char *ngx_mail_auth_http_merge_conf(ngx_conf_t *cf, void *parent, | |
521 | 80 void *child); |
1136 | 81 static char *ngx_mail_auth_http(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); |
82 static char *ngx_mail_auth_http_header(ngx_conf_t *cf, ngx_command_t *cmd, | |
573 | 83 void *conf); |
521 | 84 |
85 | |
1136 | 86 static ngx_command_t ngx_mail_auth_http_commands[] = { |
521 | 87 |
88 { ngx_string("auth_http"), | |
1136 | 89 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, |
90 ngx_mail_auth_http, | |
91 NGX_MAIL_SRV_CONF_OFFSET, | |
521 | 92 0, |
93 NULL }, | |
94 | |
95 { ngx_string("auth_http_timeout"), | |
1136 | 96 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, |
521 | 97 ngx_conf_set_msec_slot, |
1136 | 98 NGX_MAIL_SRV_CONF_OFFSET, |
99 offsetof(ngx_mail_auth_http_conf_t, timeout), | |
521 | 100 NULL }, |
101 | |
573 | 102 { ngx_string("auth_http_header"), |
1136 | 103 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE2, |
104 ngx_mail_auth_http_header, | |
105 NGX_MAIL_SRV_CONF_OFFSET, | |
573 | 106 0, |
107 NULL }, | |
108 | |
521 | 109 ngx_null_command |
110 }; | |
111 | |
112 | |
1136 | 113 static ngx_mail_module_t ngx_mail_auth_http_module_ctx = { |
1487
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
114 NULL, /* protocol */ |
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
115 |
521 | 116 NULL, /* create main configuration */ |
117 NULL, /* init main configuration */ | |
118 | |
1136 | 119 ngx_mail_auth_http_create_conf, /* create server configuration */ |
120 ngx_mail_auth_http_merge_conf /* merge server configuration */ | |
521 | 121 }; |
122 | |
123 | |
1136 | 124 ngx_module_t ngx_mail_auth_http_module = { |
521 | 125 NGX_MODULE_V1, |
1136 | 126 &ngx_mail_auth_http_module_ctx, /* module context */ |
127 ngx_mail_auth_http_commands, /* module directives */ | |
128 NGX_MAIL_MODULE, /* module type */ | |
541 | 129 NULL, /* init master */ |
521 | 130 NULL, /* init module */ |
541 | 131 NULL, /* init process */ |
132 NULL, /* init thread */ | |
133 NULL, /* exit thread */ | |
134 NULL, /* exit process */ | |
135 NULL, /* exit master */ | |
136 NGX_MODULE_V1_PADDING | |
521 | 137 }; |
138 | |
139 | |
1136 | 140 static ngx_str_t ngx_mail_auth_http_method[] = { |
141 ngx_string("plain"), | |
809 | 142 ngx_string("plain"), |
2748
2477b28eaccb
fix Auth-Method, the bug has been introduced in r2496
Igor Sysoev <igor@sysoev.ru>
parents:
2388
diff
changeset
|
143 ngx_string("plain"), |
809 | 144 ngx_string("apop"), |
2309 | 145 ngx_string("cram-md5"), |
146 ngx_string("none") | |
800 | 147 }; |
521 | 148 |
1136 | 149 static ngx_str_t ngx_mail_smtp_errcode = ngx_string("535 5.7.0"); |
521 | 150 |
1477 | 151 |
521 | 152 void |
1136 | 153 ngx_mail_auth_http_init(ngx_mail_session_t *s) |
521 | 154 { |
155 ngx_int_t rc; | |
547 | 156 ngx_pool_t *pool; |
1136 | 157 ngx_mail_auth_http_ctx_t *ctx; |
158 ngx_mail_auth_http_conf_t *ahcf; | |
521 | 159 |
541 | 160 s->connection->log->action = "in http auth state"; |
161 | |
547 | 162 pool = ngx_create_pool(2048, s->connection->log); |
163 if (pool == NULL) { | |
1136 | 164 ngx_mail_session_internal_server_error(s); |
521 | 165 return; |
166 } | |
167 | |
1136 | 168 ctx = ngx_pcalloc(pool, sizeof(ngx_mail_auth_http_ctx_t)); |
547 | 169 if (ctx == NULL) { |
170 ngx_destroy_pool(pool); | |
1136 | 171 ngx_mail_session_internal_server_error(s); |
547 | 172 return; |
173 } | |
174 | |
175 ctx->pool = pool; | |
176 | |
1136 | 177 ahcf = ngx_mail_get_module_srv_conf(s, ngx_mail_auth_http_module); |
521 | 178 |
1136 | 179 ctx->request = ngx_mail_auth_http_create_request(s, pool, ahcf); |
521 | 180 if (ctx->request == NULL) { |
547 | 181 ngx_destroy_pool(ctx->pool); |
1136 | 182 ngx_mail_session_internal_server_error(s); |
521 | 183 return; |
184 } | |
185 | |
1136 | 186 ngx_mail_set_ctx(s, ctx, ngx_mail_auth_http_module); |
521 | 187 |
884 | 188 ctx->peer.sockaddr = ahcf->peer->sockaddr; |
189 ctx->peer.socklen = ahcf->peer->socklen; | |
190 ctx->peer.name = &ahcf->peer->name; | |
191 ctx->peer.get = ngx_event_get_peer; | |
521 | 192 ctx->peer.log = s->connection->log; |
193 ctx->peer.log_error = NGX_ERROR_ERR; | |
194 | |
195 rc = ngx_event_connect_peer(&ctx->peer); | |
196 | |
543 | 197 if (rc == NGX_ERROR || rc == NGX_BUSY || rc == NGX_DECLINED) { |
862
6044cea025fa
fix segfault when connect() failed
Igor Sysoev <igor@sysoev.ru>
parents:
856
diff
changeset
|
198 if (ctx->peer.connection) { |
6044cea025fa
fix segfault when connect() failed
Igor Sysoev <igor@sysoev.ru>
parents:
856
diff
changeset
|
199 ngx_close_connection(ctx->peer.connection); |
6044cea025fa
fix segfault when connect() failed
Igor Sysoev <igor@sysoev.ru>
parents:
856
diff
changeset
|
200 } |
6044cea025fa
fix segfault when connect() failed
Igor Sysoev <igor@sysoev.ru>
parents:
856
diff
changeset
|
201 |
547 | 202 ngx_destroy_pool(ctx->pool); |
1136 | 203 ngx_mail_session_internal_server_error(s); |
521 | 204 return; |
205 } | |
206 | |
207 ctx->peer.connection->data = s; | |
208 ctx->peer.connection->pool = s->connection->pool; | |
209 | |
1136 | 210 s->connection->read->handler = ngx_mail_auth_http_block_read; |
211 ctx->peer.connection->read->handler = ngx_mail_auth_http_read_handler; | |
212 ctx->peer.connection->write->handler = ngx_mail_auth_http_write_handler; | |
521 | 213 |
1136 | 214 ctx->handler = ngx_mail_auth_http_ignore_status_line; |
527 | 215 |
541 | 216 ngx_add_timer(ctx->peer.connection->read, ahcf->timeout); |
217 ngx_add_timer(ctx->peer.connection->write, ahcf->timeout); | |
218 | |
521 | 219 if (rc == NGX_OK) { |
1136 | 220 ngx_mail_auth_http_write_handler(ctx->peer.connection->write); |
521 | 221 return; |
222 } | |
223 } | |
224 | |
225 | |
226 static void | |
1136 | 227 ngx_mail_auth_http_write_handler(ngx_event_t *wev) |
521 | 228 { |
229 ssize_t n, size; | |
230 ngx_connection_t *c; | |
1136 | 231 ngx_mail_session_t *s; |
232 ngx_mail_auth_http_ctx_t *ctx; | |
233 ngx_mail_auth_http_conf_t *ahcf; | |
521 | 234 |
235 c = wev->data; | |
236 s = c->data; | |
237 | |
1136 | 238 ctx = ngx_mail_get_module_ctx(s, ngx_mail_auth_http_module); |
521 | 239 |
1136 | 240 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, wev->log, 0, |
241 "mail auth http write handler"); | |
521 | 242 |
577 | 243 if (wev->timedout) { |
521 | 244 ngx_log_error(NGX_LOG_ERR, wev->log, NGX_ETIMEDOUT, |
884 | 245 "auth http server %V timed out", ctx->peer.name); |
1478 | 246 ngx_close_connection(c); |
547 | 247 ngx_destroy_pool(ctx->pool); |
1136 | 248 ngx_mail_session_internal_server_error(s); |
521 | 249 return; |
250 } | |
251 | |
252 size = ctx->request->last - ctx->request->pos; | |
253 | |
254 n = ngx_send(c, ctx->request->pos, size); | |
255 | |
256 if (n == NGX_ERROR) { | |
1478 | 257 ngx_close_connection(c); |
547 | 258 ngx_destroy_pool(ctx->pool); |
1136 | 259 ngx_mail_session_internal_server_error(s); |
521 | 260 return; |
261 } | |
262 | |
263 if (n > 0) { | |
264 ctx->request->pos += n; | |
265 | |
266 if (n == size) { | |
1136 | 267 wev->handler = ngx_mail_auth_http_dummy_handler; |
521 | 268 |
269 if (wev->timer_set) { | |
270 ngx_del_timer(wev); | |
271 } | |
272 | |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2310
diff
changeset
|
273 if (ngx_handle_write_event(wev, 0) != NGX_OK) { |
1478 | 274 ngx_close_connection(c); |
799
9737d6fb1ac6
disable write level event while waiting auth server response
Igor Sysoev <igor@sysoev.ru>
parents:
633
diff
changeset
|
275 ngx_destroy_pool(ctx->pool); |
1136 | 276 ngx_mail_session_internal_server_error(s); |
799
9737d6fb1ac6
disable write level event while waiting auth server response
Igor Sysoev <igor@sysoev.ru>
parents:
633
diff
changeset
|
277 } |
9737d6fb1ac6
disable write level event while waiting auth server response
Igor Sysoev <igor@sysoev.ru>
parents:
633
diff
changeset
|
278 |
521 | 279 return; |
280 } | |
281 } | |
282 | |
283 if (!wev->timer_set) { | |
1136 | 284 ahcf = ngx_mail_get_module_srv_conf(s, ngx_mail_auth_http_module); |
521 | 285 ngx_add_timer(wev, ahcf->timeout); |
286 } | |
287 } | |
288 | |
289 | |
290 static void | |
1136 | 291 ngx_mail_auth_http_read_handler(ngx_event_t *rev) |
521 | 292 { |
525 | 293 ssize_t n, size; |
521 | 294 ngx_connection_t *c; |
1136 | 295 ngx_mail_session_t *s; |
296 ngx_mail_auth_http_ctx_t *ctx; | |
521 | 297 |
298 c = rev->data; | |
299 s = c->data; | |
300 | |
1136 | 301 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, |
302 "mail auth http read handler"); | |
521 | 303 |
1136 | 304 ctx = ngx_mail_get_module_ctx(s, ngx_mail_auth_http_module); |
525 | 305 |
577 | 306 if (rev->timedout) { |
525 | 307 ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT, |
884 | 308 "auth http server %V timed out", ctx->peer.name); |
1478 | 309 ngx_close_connection(c); |
547 | 310 ngx_destroy_pool(ctx->pool); |
1136 | 311 ngx_mail_session_internal_server_error(s); |
525 | 312 return; |
313 } | |
314 | |
315 if (ctx->response == NULL) { | |
547 | 316 ctx->response = ngx_create_temp_buf(ctx->pool, 1024); |
525 | 317 if (ctx->response == NULL) { |
1478 | 318 ngx_close_connection(c); |
547 | 319 ngx_destroy_pool(ctx->pool); |
1136 | 320 ngx_mail_session_internal_server_error(s); |
525 | 321 return; |
322 } | |
323 } | |
324 | |
527 | 325 size = ctx->response->end - ctx->response->last; |
525 | 326 |
327 n = ngx_recv(c, ctx->response->pos, size); | |
328 | |
527 | 329 if (n > 0) { |
330 ctx->response->last += n; | |
331 | |
332 ctx->handler(s, ctx); | |
333 return; | |
334 } | |
335 | |
336 if (n == NGX_AGAIN) { | |
525 | 337 return; |
338 } | |
339 | |
1478 | 340 ngx_close_connection(c); |
547 | 341 ngx_destroy_pool(ctx->pool); |
1136 | 342 ngx_mail_session_internal_server_error(s); |
527 | 343 } |
525 | 344 |
345 | |
527 | 346 static void |
1136 | 347 ngx_mail_auth_http_ignore_status_line(ngx_mail_session_t *s, |
348 ngx_mail_auth_http_ctx_t *ctx) | |
527 | 349 { |
350 u_char *p, ch; | |
351 enum { | |
352 sw_start = 0, | |
353 sw_H, | |
354 sw_HT, | |
355 sw_HTT, | |
356 sw_HTTP, | |
357 sw_skip, | |
358 sw_almost_done | |
359 } state; | |
360 | |
1136 | 361 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
362 "mail auth http process status line"); | |
527 | 363 |
364 state = ctx->state; | |
365 | |
366 for (p = ctx->response->pos; p < ctx->response->last; p++) { | |
367 ch = *p; | |
368 | |
369 switch (state) { | |
370 | |
371 /* "HTTP/" */ | |
372 case sw_start: | |
373 if (ch == 'H') { | |
374 state = sw_H; | |
375 break; | |
376 } | |
377 goto next; | |
378 | |
379 case sw_H: | |
380 if (ch == 'T') { | |
381 state = sw_HT; | |
382 break; | |
383 } | |
384 goto next; | |
385 | |
386 case sw_HT: | |
387 if (ch == 'T') { | |
388 state = sw_HTT; | |
389 break; | |
390 } | |
391 goto next; | |
392 | |
393 case sw_HTT: | |
394 if (ch == 'P') { | |
395 state = sw_HTTP; | |
396 break; | |
397 } | |
398 goto next; | |
399 | |
400 case sw_HTTP: | |
401 if (ch == '/') { | |
402 state = sw_skip; | |
403 break; | |
404 } | |
405 goto next; | |
406 | |
407 /* any text until end of line */ | |
408 case sw_skip: | |
409 switch (ch) { | |
410 case CR: | |
411 state = sw_almost_done; | |
412 | |
413 break; | |
577 | 414 case LF: |
527 | 415 goto done; |
416 } | |
417 break; | |
418 | |
419 /* end of status line */ | |
420 case sw_almost_done: | |
421 if (ch == LF) { | |
422 goto done; | |
423 } | |
424 | |
425 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, | |
541 | 426 "auth http server &V sent invalid response", |
884 | 427 ctx->peer.name); |
527 | 428 ngx_close_connection(ctx->peer.connection); |
547 | 429 ngx_destroy_pool(ctx->pool); |
1136 | 430 ngx_mail_session_internal_server_error(s); |
527 | 431 return; |
432 } | |
433 } | |
434 | |
435 ctx->response->pos = p; | |
436 ctx->state = state; | |
437 | |
438 return; | |
439 | |
440 next: | |
441 | |
442 p = ctx->response->start - 1; | |
443 | |
444 done: | |
445 | |
446 ctx->response->pos = p + 1; | |
447 ctx->state = 0; | |
1136 | 448 ctx->handler = ngx_mail_auth_http_process_headers; |
527 | 449 ctx->handler(s, ctx); |
450 } | |
525 | 451 |
452 | |
527 | 453 static void |
1136 | 454 ngx_mail_auth_http_process_headers(ngx_mail_session_t *s, |
455 ngx_mail_auth_http_ctx_t *ctx) | |
527 | 456 { |
5134
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
457 u_char *p; |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
458 time_t timer; |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
459 size_t len, size; |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
460 ngx_int_t rc, port, n; |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
461 ngx_addr_t *peer; |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
462 struct sockaddr_in *sin; |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
463 #if (NGX_HAVE_INET6) |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
464 struct sockaddr_in6 *sin6; |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
465 #endif |
525 | 466 |
1136 | 467 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
468 "mail auth http process headers"); | |
527 | 469 |
470 for ( ;; ) { | |
1136 | 471 rc = ngx_mail_auth_http_parse_header_line(s, ctx); |
527 | 472 |
473 if (rc == NGX_OK) { | |
474 | |
475 #if (NGX_DEBUG) | |
476 { | |
477 ngx_str_t key, value; | |
478 | |
479 key.len = ctx->header_name_end - ctx->header_name_start; | |
480 key.data = ctx->header_name_start; | |
481 value.len = ctx->header_end - ctx->header_start; | |
482 value.data = ctx->header_start; | |
483 | |
1136 | 484 ngx_log_debug2(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
485 "mail auth http header: \"%V: %V\"", | |
527 | 486 &key, &value); |
487 } | |
488 #endif | |
489 | |
490 len = ctx->header_name_end - ctx->header_name_start; | |
491 | |
492 if (len == sizeof("Auth-Status") - 1 | |
1107
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
493 && ngx_strncasecmp(ctx->header_name_start, |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
494 (u_char *) "Auth-Status", |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
495 sizeof("Auth-Status") - 1) |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
496 == 0) |
527 | 497 { |
498 len = ctx->header_end - ctx->header_start; | |
499 | |
500 if (len == 2 | |
501 && ctx->header_start[0] == 'O' | |
502 && ctx->header_start[1] == 'K') | |
503 { | |
504 continue; | |
505 } | |
506 | |
883 | 507 if (len == 4 |
508 && ctx->header_start[0] == 'W' | |
509 && ctx->header_start[1] == 'A' | |
510 && ctx->header_start[2] == 'I' | |
511 && ctx->header_start[3] == 'T') | |
512 { | |
513 s->auth_wait = 1; | |
514 continue; | |
515 } | |
516 | |
567 | 517 ctx->errmsg.len = len; |
518 ctx->errmsg.data = ctx->header_start; | |
519 | |
1136 | 520 switch (s->protocol) { |
521 | |
522 case NGX_MAIL_POP3_PROTOCOL: | |
854
1673f197bc62
fix segfault when many auth failures occurred
Igor Sysoev <igor@sysoev.ru>
parents:
809
diff
changeset
|
523 size = sizeof("-ERR ") - 1 + len + sizeof(CRLF) - 1; |
1136 | 524 break; |
527 | 525 |
1136 | 526 case NGX_MAIL_IMAP_PROTOCOL: |
854
1673f197bc62
fix segfault when many auth failures occurred
Igor Sysoev <igor@sysoev.ru>
parents:
809
diff
changeset
|
527 size = s->tag.len + sizeof("NO ") - 1 + len |
527 | 528 + sizeof(CRLF) - 1; |
1136 | 529 break; |
530 | |
531 default: /* NGX_MAIL_SMTP_PROTOCOL */ | |
532 ctx->err = ctx->errmsg; | |
533 continue; | |
527 | 534 } |
535 | |
2061
b0a1c84725cf
change useless ngx_pcalloc() to ngx_pnalloc()
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
536 p = ngx_pnalloc(s->connection->pool, size); |
527 | 537 if (p == NULL) { |
543 | 538 ngx_close_connection(ctx->peer.connection); |
547 | 539 ngx_destroy_pool(ctx->pool); |
1136 | 540 ngx_mail_session_internal_server_error(s); |
527 | 541 return; |
542 } | |
543 | |
544 ctx->err.data = p; | |
545 | |
1136 | 546 switch (s->protocol) { |
527 | 547 |
1136 | 548 case NGX_MAIL_POP3_PROTOCOL: |
549 *p++ = '-'; *p++ = 'E'; *p++ = 'R'; *p++ = 'R'; *p++ = ' '; | |
550 break; | |
551 | |
552 case NGX_MAIL_IMAP_PROTOCOL: | |
527 | 553 p = ngx_cpymem(p, s->tag.data, s->tag.len); |
1136 | 554 *p++ = 'N'; *p++ = 'O'; *p++ = ' '; |
555 break; | |
556 | |
557 default: /* NGX_MAIL_SMTP_PROTOCOL */ | |
558 break; | |
527 | 559 } |
560 | |
561 p = ngx_cpymem(p, ctx->header_start, len); | |
562 *p++ = CR; *p++ = LF; | |
563 | |
564 ctx->err.len = p - ctx->err.data; | |
565 | |
566 continue; | |
567 } | |
568 | |
569 if (len == sizeof("Auth-Server") - 1 | |
1107
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
570 && ngx_strncasecmp(ctx->header_name_start, |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
571 (u_char *) "Auth-Server", |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
572 sizeof("Auth-Server") - 1) |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
573 == 0) |
527 | 574 { |
575 ctx->addr.len = ctx->header_end - ctx->header_start; | |
576 ctx->addr.data = ctx->header_start; | |
577 | |
578 continue; | |
579 } | |
580 | |
581 if (len == sizeof("Auth-Port") - 1 | |
1107
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
582 && ngx_strncasecmp(ctx->header_name_start, |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
583 (u_char *) "Auth-Port", |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
584 sizeof("Auth-Port") - 1) |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
585 == 0) |
527 | 586 { |
587 ctx->port.len = ctx->header_end - ctx->header_start; | |
588 ctx->port.data = ctx->header_start; | |
589 | |
590 continue; | |
591 } | |
592 | |
593 if (len == sizeof("Auth-User") - 1 | |
1107
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
594 && ngx_strncasecmp(ctx->header_name_start, |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
595 (u_char *) "Auth-User", |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
596 sizeof("Auth-User") - 1) |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
597 == 0) |
527 | 598 { |
599 s->login.len = ctx->header_end - ctx->header_start; | |
567 | 600 |
2049 | 601 s->login.data = ngx_pnalloc(s->connection->pool, s->login.len); |
567 | 602 if (s->login.data == NULL) { |
603 ngx_close_connection(ctx->peer.connection); | |
604 ngx_destroy_pool(ctx->pool); | |
1136 | 605 ngx_mail_session_internal_server_error(s); |
567 | 606 return; |
607 } | |
608 | |
609 ngx_memcpy(s->login.data, ctx->header_start, s->login.len); | |
527 | 610 |
611 continue; | |
612 } | |
613 | |
800 | 614 if (len == sizeof("Auth-Pass") - 1 |
1107
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
615 && ngx_strncasecmp(ctx->header_name_start, |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
616 (u_char *) "Auth-Pass", |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
617 sizeof("Auth-Pass") - 1) |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
618 == 0) |
800 | 619 { |
620 s->passwd.len = ctx->header_end - ctx->header_start; | |
621 | |
2049 | 622 s->passwd.data = ngx_pnalloc(s->connection->pool, |
623 s->passwd.len); | |
800 | 624 if (s->passwd.data == NULL) { |
625 ngx_close_connection(ctx->peer.connection); | |
626 ngx_destroy_pool(ctx->pool); | |
1136 | 627 ngx_mail_session_internal_server_error(s); |
800 | 628 return; |
629 } | |
630 | |
631 ngx_memcpy(s->passwd.data, ctx->header_start, s->passwd.len); | |
632 | |
633 continue; | |
634 } | |
635 | |
527 | 636 if (len == sizeof("Auth-Wait") - 1 |
1107
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
637 && ngx_strncasecmp(ctx->header_name_start, |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
638 (u_char *) "Auth-Wait", |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
639 sizeof("Auth-Wait") - 1) |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
640 == 0) |
527 | 641 { |
642 n = ngx_atoi(ctx->header_start, | |
643 ctx->header_end - ctx->header_start); | |
644 | |
645 if (n != NGX_ERROR) { | |
646 ctx->sleep = n; | |
647 } | |
648 | |
649 continue; | |
650 } | |
651 | |
1136 | 652 if (len == sizeof("Auth-Error-Code") - 1 |
653 && ngx_strncasecmp(ctx->header_name_start, | |
654 (u_char *) "Auth-Error-Code", | |
655 sizeof("Auth-Error-Code") - 1) | |
656 == 0) | |
657 { | |
658 ctx->errcode.len = ctx->header_end - ctx->header_start; | |
659 | |
2049 | 660 ctx->errcode.data = ngx_pnalloc(s->connection->pool, |
661 ctx->errcode.len); | |
1136 | 662 if (ctx->errcode.data == NULL) { |
663 ngx_close_connection(ctx->peer.connection); | |
664 ngx_destroy_pool(ctx->pool); | |
665 ngx_mail_session_internal_server_error(s); | |
666 return; | |
667 } | |
668 | |
669 ngx_memcpy(ctx->errcode.data, ctx->header_start, | |
670 ctx->errcode.len); | |
671 | |
672 continue; | |
673 } | |
674 | |
527 | 675 /* ignore other headers */ |
676 | |
677 continue; | |
678 } | |
679 | |
680 if (rc == NGX_DONE) { | |
1136 | 681 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
682 "mail auth http header done"); | |
527 | 683 |
684 ngx_close_connection(ctx->peer.connection); | |
685 | |
686 if (ctx->err.len) { | |
1136 | 687 |
567 | 688 ngx_log_error(NGX_LOG_INFO, s->connection->log, 0, |
689 "client login failed: \"%V\"", &ctx->errmsg); | |
690 | |
1136 | 691 if (s->protocol == NGX_MAIL_SMTP_PROTOCOL) { |
692 | |
693 if (ctx->errcode.len == 0) { | |
694 ctx->errcode = ngx_mail_smtp_errcode; | |
695 } | |
696 | |
697 ctx->err.len = ctx->errcode.len + ctx->errmsg.len | |
698 + sizeof(" " CRLF) - 1; | |
699 | |
2049 | 700 p = ngx_pnalloc(s->connection->pool, ctx->err.len); |
1166 | 701 if (p == NULL) { |
702 ngx_destroy_pool(ctx->pool); | |
703 ngx_mail_session_internal_server_error(s); | |
704 return; | |
705 } | |
1136 | 706 |
1166 | 707 ctx->err.data = p; |
1136 | 708 |
1166 | 709 p = ngx_cpymem(p, ctx->errcode.data, ctx->errcode.len); |
1136 | 710 *p++ = ' '; |
1166 | 711 p = ngx_cpymem(p, ctx->errmsg.data, ctx->errmsg.len); |
1136 | 712 *p++ = CR; *p = LF; |
713 } | |
714 | |
539 | 715 s->out = ctx->err; |
547 | 716 timer = ctx->sleep; |
527 | 717 |
547 | 718 ngx_destroy_pool(ctx->pool); |
719 | |
720 if (timer == 0) { | |
539 | 721 s->quit = 1; |
1136 | 722 ngx_mail_send(s->connection->write); |
541 | 723 return; |
724 } | |
539 | 725 |
1640 | 726 ngx_add_timer(s->connection->read, (ngx_msec_t) (timer * 1000)); |
527 | 727 |
1136 | 728 s->connection->read->handler = ngx_mail_auth_sleep_handler; |
527 | 729 |
730 return; | |
731 } | |
732 | |
883 | 733 if (s->auth_wait) { |
734 timer = ctx->sleep; | |
735 | |
736 ngx_destroy_pool(ctx->pool); | |
737 | |
738 if (timer == 0) { | |
1136 | 739 ngx_mail_auth_http_init(s); |
883 | 740 return; |
741 } | |
742 | |
1640 | 743 ngx_add_timer(s->connection->read, (ngx_msec_t) (timer * 1000)); |
883 | 744 |
1136 | 745 s->connection->read->handler = ngx_mail_auth_sleep_handler; |
883 | 746 |
747 return; | |
748 } | |
749 | |
527 | 750 if (ctx->addr.len == 0 || ctx->port.len == 0) { |
751 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, | |
541 | 752 "auth http server %V did not send server or port", |
884 | 753 ctx->peer.name); |
547 | 754 ngx_destroy_pool(ctx->pool); |
1136 | 755 ngx_mail_session_internal_server_error(s); |
527 | 756 return; |
757 } | |
758 | |
1487
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
759 if (s->passwd.data == NULL |
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
760 && s->protocol != NGX_MAIL_SMTP_PROTOCOL) |
1136 | 761 { |
800 | 762 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, |
763 "auth http server %V did not send password", | |
884 | 764 ctx->peer.name); |
800 | 765 ngx_destroy_pool(ctx->pool); |
1136 | 766 ngx_mail_session_internal_server_error(s); |
800 | 767 return; |
768 } | |
769 | |
3269
f0d596e84634
rename ngx_peer_addr_t to ngx_addr_t
Igor Sysoev <igor@sysoev.ru>
parents:
3267
diff
changeset
|
770 peer = ngx_pcalloc(s->connection->pool, sizeof(ngx_addr_t)); |
884 | 771 if (peer == NULL) { |
547 | 772 ngx_destroy_pool(ctx->pool); |
1136 | 773 ngx_mail_session_internal_server_error(s); |
527 | 774 return; |
775 } | |
776 | |
5134
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
777 rc = ngx_parse_addr(s->connection->pool, peer, |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
778 ctx->addr.data, ctx->addr.len); |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
779 |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
780 switch (rc) { |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
781 case NGX_OK: |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
782 break; |
2855
a96a8c916b0c
mail proxy listen IPv6 support
Igor Sysoev <igor@sysoev.ru>
parents:
2748
diff
changeset
|
783 |
5134
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
784 case NGX_DECLINED: |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
785 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
786 "auth http server %V sent invalid server " |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
787 "address:\"%V\"", |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
788 ctx->peer.name, &ctx->addr); |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
789 /* fall through */ |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
790 |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
791 default: |
547 | 792 ngx_destroy_pool(ctx->pool); |
1136 | 793 ngx_mail_session_internal_server_error(s); |
527 | 794 return; |
795 } | |
796 | |
797 port = ngx_atoi(ctx->port.data, ctx->port.len); | |
4227 | 798 if (port == NGX_ERROR || port < 1 || port > 65535) { |
527 | 799 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, |
541 | 800 "auth http server %V sent invalid server " |
801 "port:\"%V\"", | |
884 | 802 ctx->peer.name, &ctx->port); |
547 | 803 ngx_destroy_pool(ctx->pool); |
1136 | 804 ngx_mail_session_internal_server_error(s); |
527 | 805 return; |
806 } | |
807 | |
5134
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
808 switch (peer->sockaddr->sa_family) { |
527 | 809 |
5134
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
810 #if (NGX_HAVE_INET6) |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
811 case AF_INET6: |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
812 sin6 = (struct sockaddr_in6 *) peer->sockaddr; |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
813 sin6->sin6_port = htons((in_port_t) port); |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
814 break; |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
815 #endif |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
816 |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
817 default: /* AF_INET */ |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
818 sin = (struct sockaddr_in *) peer->sockaddr; |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
819 sin->sin_port = htons((in_port_t) port); |
c788e54090de
Mail: IPv6 backends (ticket #323).
Ruslan Ermilov <ru@nginx.com>
parents:
4971
diff
changeset
|
820 break; |
527 | 821 } |
822 | |
823 len = ctx->addr.len + 1 + ctx->port.len; | |
824 | |
884 | 825 peer->name.len = len; |
527 | 826 |
2049 | 827 peer->name.data = ngx_pnalloc(s->connection->pool, len); |
884 | 828 if (peer->name.data == NULL) { |
547 | 829 ngx_destroy_pool(ctx->pool); |
1136 | 830 ngx_mail_session_internal_server_error(s); |
527 | 831 return; |
832 } | |
833 | |
834 len = ctx->addr.len; | |
835 | |
884 | 836 ngx_memcpy(peer->name.data, ctx->addr.data, len); |
527 | 837 |
884 | 838 peer->name.data[len++] = ':'; |
527 | 839 |
884 | 840 ngx_memcpy(peer->name.data + len, ctx->port.data, ctx->port.len); |
527 | 841 |
547 | 842 ngx_destroy_pool(ctx->pool); |
1136 | 843 ngx_mail_proxy_init(s, peer); |
527 | 844 |
845 return; | |
846 } | |
847 | |
848 if (rc == NGX_AGAIN ) { | |
849 return; | |
850 } | |
851 | |
852 /* rc == NGX_ERROR */ | |
853 | |
854 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, | |
541 | 855 "auth http server %V sent invalid header in response", |
884 | 856 ctx->peer.name); |
527 | 857 ngx_close_connection(ctx->peer.connection); |
547 | 858 ngx_destroy_pool(ctx->pool); |
1136 | 859 ngx_mail_session_internal_server_error(s); |
527 | 860 |
861 return; | |
862 } | |
863 } | |
864 | |
521 | 865 |
527 | 866 static void |
1136 | 867 ngx_mail_auth_sleep_handler(ngx_event_t *rev) |
527 | 868 { |
543 | 869 ngx_connection_t *c; |
1136 | 870 ngx_mail_session_t *s; |
871 ngx_mail_core_srv_conf_t *cscf; | |
527 | 872 |
1136 | 873 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail auth sleep handler"); |
527 | 874 |
875 c = rev->data; | |
876 s = c->data; | |
877 | |
878 if (rev->timedout) { | |
879 | |
880 rev->timedout = 0; | |
881 | |
883 | 882 if (s->auth_wait) { |
883 s->auth_wait = 0; | |
1136 | 884 ngx_mail_auth_http_init(s); |
883 | 885 return; |
886 } | |
887 | |
1487
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
888 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); |
527 | 889 |
1487
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
890 rev->handler = cscf->protocol->auth_state; |
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
891 |
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
892 s->mail_state = 0; |
1136 | 893 s->auth_method = NGX_MAIL_AUTH_PLAIN; |
800 | 894 |
543 | 895 c->log->action = "in auth state"; |
896 | |
1477 | 897 ngx_mail_send(c->write); |
543 | 898 |
583 | 899 if (c->destroyed) { |
543 | 900 return; |
901 } | |
902 | |
903 ngx_add_timer(rev, cscf->timeout); | |
904 | |
527 | 905 if (rev->ready) { |
1477 | 906 rev->handler(rev); |
527 | 907 return; |
908 } | |
909 | |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2310
diff
changeset
|
910 if (ngx_handle_read_event(rev, 0) != NGX_OK) { |
1477 | 911 ngx_mail_close_connection(c); |
527 | 912 } |
913 | |
914 return; | |
915 } | |
916 | |
917 if (rev->active) { | |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2310
diff
changeset
|
918 if (ngx_handle_read_event(rev, 0) != NGX_OK) { |
1477 | 919 ngx_mail_close_connection(c); |
527 | 920 } |
921 } | |
922 } | |
923 | |
924 | |
925 static ngx_int_t | |
1136 | 926 ngx_mail_auth_http_parse_header_line(ngx_mail_session_t *s, |
927 ngx_mail_auth_http_ctx_t *ctx) | |
527 | 928 { |
929 u_char c, ch, *p; | |
930 enum { | |
931 sw_start = 0, | |
932 sw_name, | |
933 sw_space_before_value, | |
934 sw_value, | |
935 sw_space_after_value, | |
577 | 936 sw_almost_done, |
527 | 937 sw_header_almost_done |
938 } state; | |
939 | |
577 | 940 state = ctx->state; |
527 | 941 |
942 for (p = ctx->response->pos; p < ctx->response->last; p++) { | |
943 ch = *p; | |
944 | |
945 switch (state) { | |
946 | |
947 /* first char */ | |
948 case sw_start: | |
949 | |
950 switch (ch) { | |
951 case CR: | |
577 | 952 ctx->header_end = p; |
527 | 953 state = sw_header_almost_done; |
954 break; | |
577 | 955 case LF: |
527 | 956 ctx->header_end = p; |
957 goto header_done; | |
958 default: | |
959 state = sw_name; | |
960 ctx->header_name_start = p; | |
961 | |
962 c = (u_char) (ch | 0x20); | |
963 if (c >= 'a' && c <= 'z') { | |
964 break; | |
965 } | |
966 | |
967 if (ch >= '0' && ch <= '9') { | |
968 break; | |
969 } | |
970 | |
971 return NGX_ERROR; | |
972 } | |
973 break; | |
974 | |
975 /* header name */ | |
976 case sw_name: | |
977 c = (u_char) (ch | 0x20); | |
978 if (c >= 'a' && c <= 'z') { | |
979 break; | |
980 } | |
981 | |
982 if (ch == ':') { | |
983 ctx->header_name_end = p; | |
984 state = sw_space_before_value; | |
985 break; | |
986 } | |
987 | |
988 if (ch == '-') { | |
989 break; | |
990 } | |
991 | |
992 if (ch >= '0' && ch <= '9') { | |
993 break; | |
994 } | |
995 | |
996 if (ch == CR) { | |
997 ctx->header_name_end = p; | |
998 ctx->header_start = p; | |
999 ctx->header_end = p; | |
1000 state = sw_almost_done; | |
1001 break; | |
1002 } | |
1003 | |
1004 if (ch == LF) { | |
1005 ctx->header_name_end = p; | |
1006 ctx->header_start = p; | |
1007 ctx->header_end = p; | |
1008 goto done; | |
1009 } | |
1010 | |
1011 return NGX_ERROR; | |
1012 | |
1013 /* space* before header value */ | |
1014 case sw_space_before_value: | |
1015 switch (ch) { | |
1016 case ' ': | |
1017 break; | |
1018 case CR: | |
1019 ctx->header_start = p; | |
1020 ctx->header_end = p; | |
1021 state = sw_almost_done; | |
1022 break; | |
1023 case LF: | |
1024 ctx->header_start = p; | |
1025 ctx->header_end = p; | |
1026 goto done; | |
1027 default: | |
1028 ctx->header_start = p; | |
1029 state = sw_value; | |
1030 break; | |
1031 } | |
1032 break; | |
1033 | |
1034 /* header value */ | |
1035 case sw_value: | |
1036 switch (ch) { | |
1037 case ' ': | |
1038 ctx->header_end = p; | |
1039 state = sw_space_after_value; | |
1040 break; | |
1041 case CR: | |
1042 ctx->header_end = p; | |
1043 state = sw_almost_done; | |
1044 break; | |
1045 case LF: | |
1046 ctx->header_end = p; | |
1047 goto done; | |
1048 } | |
1049 break; | |
1050 | |
1051 /* space* before end of header line */ | |
1052 case sw_space_after_value: | |
1053 switch (ch) { | |
1054 case ' ': | |
1055 break; | |
1056 case CR: | |
1057 state = sw_almost_done; | |
1058 break; | |
1059 case LF: | |
1060 goto done; | |
1061 default: | |
1062 state = sw_value; | |
1063 break; | |
1064 } | |
1065 break; | |
1066 | |
1067 /* end of header line */ | |
1068 case sw_almost_done: | |
1069 switch (ch) { | |
1070 case LF: | |
1071 goto done; | |
1072 default: | |
1073 return NGX_ERROR; | |
1074 } | |
1075 | |
1076 /* end of header */ | |
1077 case sw_header_almost_done: | |
1078 switch (ch) { | |
1079 case LF: | |
1080 goto header_done; | |
1081 default: | |
1082 return NGX_ERROR; | |
1083 } | |
1084 } | |
1085 } | |
1086 | |
1087 ctx->response->pos = p; | |
1088 ctx->state = state; | |
1089 | |
1090 return NGX_AGAIN; | |
1091 | |
1092 done: | |
1093 | |
1094 ctx->response->pos = p + 1; | |
1095 ctx->state = sw_start; | |
1096 | |
1097 return NGX_OK; | |
1098 | |
1099 header_done: | |
1100 | |
1101 ctx->response->pos = p + 1; | |
1102 ctx->state = sw_start; | |
1103 | |
1104 return NGX_DONE; | |
521 | 1105 } |
1106 | |
1107 | |
1108 static void | |
1136 | 1109 ngx_mail_auth_http_block_read(ngx_event_t *rev) |
521 | 1110 { |
1111 ngx_connection_t *c; | |
1136 | 1112 ngx_mail_session_t *s; |
1113 ngx_mail_auth_http_ctx_t *ctx; | |
521 | 1114 |
1136 | 1115 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, |
1116 "mail auth http block read"); | |
521 | 1117 |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2310
diff
changeset
|
1118 if (ngx_handle_read_event(rev, 0) != NGX_OK) { |
521 | 1119 c = rev->data; |
1120 s = c->data; | |
1121 | |
1136 | 1122 ctx = ngx_mail_get_module_ctx(s, ngx_mail_auth_http_module); |
521 | 1123 |
525 | 1124 ngx_close_connection(ctx->peer.connection); |
547 | 1125 ngx_destroy_pool(ctx->pool); |
1136 | 1126 ngx_mail_session_internal_server_error(s); |
521 | 1127 } |
1128 } | |
1129 | |
1130 | |
1131 static void | |
1136 | 1132 ngx_mail_auth_http_dummy_handler(ngx_event_t *ev) |
521 | 1133 { |
1136 | 1134 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, ev->log, 0, |
1135 "mail auth http dummy handler"); | |
521 | 1136 } |
1137 | |
1138 | |
1139 static ngx_buf_t * | |
1136 | 1140 ngx_mail_auth_http_create_request(ngx_mail_session_t *s, ngx_pool_t *pool, |
1141 ngx_mail_auth_http_conf_t *ahcf) | |
521 | 1142 { |
1487
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
1143 size_t len; |
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
1144 ngx_buf_t *b; |
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
1145 ngx_str_t login, passwd; |
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
1146 ngx_mail_core_srv_conf_t *cscf; |
633 | 1147 |
1136 | 1148 if (ngx_mail_auth_http_escape(pool, &s->login, &login) != NGX_OK) { |
633 | 1149 return NULL; |
1150 } | |
1151 | |
1136 | 1152 if (ngx_mail_auth_http_escape(pool, &s->passwd, &passwd) != NGX_OK) { |
633 | 1153 return NULL; |
1154 } | |
521 | 1155 |
1487
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
1156 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); |
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
1157 |
521 | 1158 len = sizeof("GET ") - 1 + ahcf->uri.len + sizeof(" HTTP/1.0" CRLF) - 1 |
1159 + sizeof("Host: ") - 1 + ahcf->host_header.len + sizeof(CRLF) - 1 | |
856
0197d6aae54e
use correct auth method length
Igor Sysoev <igor@sysoev.ru>
parents:
854
diff
changeset
|
1160 + sizeof("Auth-Method: ") - 1 |
1136 | 1161 + ngx_mail_auth_http_method[s->auth_method].len |
856
0197d6aae54e
use correct auth method length
Igor Sysoev <igor@sysoev.ru>
parents:
854
diff
changeset
|
1162 + sizeof(CRLF) - 1 |
633 | 1163 + sizeof("Auth-User: ") - 1 + login.len + sizeof(CRLF) - 1 |
1164 + sizeof("Auth-Pass: ") - 1 + passwd.len + sizeof(CRLF) - 1 | |
800 | 1165 + sizeof("Auth-Salt: ") - 1 + s->salt.len |
1487
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
1166 + sizeof("Auth-Protocol: ") - 1 + cscf->protocol->name.len |
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
1167 + sizeof(CRLF) - 1 |
527 | 1168 + sizeof("Auth-Login-Attempt: ") - 1 + NGX_INT_T_LEN |
1169 + sizeof(CRLF) - 1 | |
521 | 1170 + sizeof("Client-IP: ") - 1 + s->connection->addr_text.len |
1171 + sizeof(CRLF) - 1 | |
2309 | 1172 + sizeof("Client-Host: ") - 1 + s->host.len + sizeof(CRLF) - 1 |
1173 + sizeof("Auth-SMTP-Helo: ") - 1 + s->smtp_helo.len | |
1174 + sizeof("Auth-SMTP-From: ") - 1 + s->smtp_from.len | |
1175 + sizeof("Auth-SMTP-To: ") - 1 + s->smtp_to.len | |
1285
0c10dc6a8e74
fix memory allocation for auth_http_header
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
1176 + ahcf->header.len |
521 | 1177 + sizeof(CRLF) - 1; |
1178 | |
547 | 1179 b = ngx_create_temp_buf(pool, len); |
521 | 1180 if (b == NULL) { |
1181 return NULL; | |
1182 } | |
1183 | |
1184 b->last = ngx_cpymem(b->last, "GET ", sizeof("GET ") - 1); | |
573 | 1185 b->last = ngx_copy(b->last, ahcf->uri.data, ahcf->uri.len); |
521 | 1186 b->last = ngx_cpymem(b->last, " HTTP/1.0" CRLF, |
1187 sizeof(" HTTP/1.0" CRLF) - 1); | |
1188 | |
1189 b->last = ngx_cpymem(b->last, "Host: ", sizeof("Host: ") - 1); | |
573 | 1190 b->last = ngx_copy(b->last, ahcf->host_header.data, |
521 | 1191 ahcf->host_header.len); |
1192 *b->last++ = CR; *b->last++ = LF; | |
1193 | |
800 | 1194 b->last = ngx_cpymem(b->last, "Auth-Method: ", |
1195 sizeof("Auth-Method: ") - 1); | |
1196 b->last = ngx_cpymem(b->last, | |
1136 | 1197 ngx_mail_auth_http_method[s->auth_method].data, |
1198 ngx_mail_auth_http_method[s->auth_method].len); | |
800 | 1199 *b->last++ = CR; *b->last++ = LF; |
521 | 1200 |
1201 b->last = ngx_cpymem(b->last, "Auth-User: ", sizeof("Auth-User: ") - 1); | |
633 | 1202 b->last = ngx_copy(b->last, login.data, login.len); |
521 | 1203 *b->last++ = CR; *b->last++ = LF; |
1204 | |
1205 b->last = ngx_cpymem(b->last, "Auth-Pass: ", sizeof("Auth-Pass: ") - 1); | |
633 | 1206 b->last = ngx_copy(b->last, passwd.data, passwd.len); |
521 | 1207 *b->last++ = CR; *b->last++ = LF; |
1208 | |
1136 | 1209 if (s->auth_method != NGX_MAIL_AUTH_PLAIN && s->salt.len) { |
800 | 1210 b->last = ngx_cpymem(b->last, "Auth-Salt: ", sizeof("Auth-Salt: ") - 1); |
1211 b->last = ngx_copy(b->last, s->salt.data, s->salt.len); | |
1212 | |
1213 s->passwd.data = NULL; | |
1214 } | |
1215 | |
521 | 1216 b->last = ngx_cpymem(b->last, "Auth-Protocol: ", |
1217 sizeof("Auth-Protocol: ") - 1); | |
1487
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
1218 b->last = ngx_cpymem(b->last, cscf->protocol->name.data, |
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
1219 cscf->protocol->name.len); |
521 | 1220 *b->last++ = CR; *b->last++ = LF; |
1221 | |
527 | 1222 b->last = ngx_sprintf(b->last, "Auth-Login-Attempt: %ui" CRLF, |
1223 s->login_attempt); | |
1224 | |
521 | 1225 b->last = ngx_cpymem(b->last, "Client-IP: ", sizeof("Client-IP: ") - 1); |
573 | 1226 b->last = ngx_copy(b->last, s->connection->addr_text.data, |
2309 | 1227 s->connection->addr_text.len); |
521 | 1228 *b->last++ = CR; *b->last++ = LF; |
1229 | |
2309 | 1230 if (s->host.len) { |
1231 b->last = ngx_cpymem(b->last, "Client-Host: ", | |
1232 sizeof("Client-Host: ") - 1); | |
1233 b->last = ngx_copy(b->last, s->host.data, s->host.len); | |
1234 *b->last++ = CR; *b->last++ = LF; | |
1235 } | |
1236 | |
1237 if (s->auth_method == NGX_MAIL_AUTH_NONE) { | |
1238 | |
1239 /* HELO, MAIL FROM, and RCPT TO can't contain CRLF, no need to escape */ | |
1240 | |
1241 b->last = ngx_cpymem(b->last, "Auth-SMTP-Helo: ", | |
1242 sizeof("Auth-SMTP-Helo: ") - 1); | |
1243 b->last = ngx_copy(b->last, s->smtp_helo.data, s->smtp_helo.len); | |
1244 *b->last++ = CR; *b->last++ = LF; | |
1245 | |
1246 b->last = ngx_cpymem(b->last, "Auth-SMTP-From: ", | |
1247 sizeof("Auth-SMTP-From: ") - 1); | |
1248 b->last = ngx_copy(b->last, s->smtp_from.data, s->smtp_from.len); | |
1249 *b->last++ = CR; *b->last++ = LF; | |
1250 | |
1251 b->last = ngx_cpymem(b->last, "Auth-SMTP-To: ", | |
1252 sizeof("Auth-SMTP-To: ") - 1); | |
1253 b->last = ngx_copy(b->last, s->smtp_to.data, s->smtp_to.len); | |
1254 *b->last++ = CR; *b->last++ = LF; | |
1255 | |
1256 } | |
1257 | |
573 | 1258 if (ahcf->header.len) { |
1259 b->last = ngx_copy(b->last, ahcf->header.data, ahcf->header.len); | |
1260 } | |
1261 | |
521 | 1262 /* add "\r\n" at the header end */ |
1263 *b->last++ = CR; *b->last++ = LF; | |
1264 | |
1136 | 1265 #if (NGX_DEBUG_MAIL_PASSWD) |
521 | 1266 { |
1267 ngx_str_t l; | |
1268 | |
1269 l.len = b->last - b->pos; | |
1270 l.data = b->pos; | |
1136 | 1271 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
5685
0cbefdcf82a6
Style: use %N instead of '\n' where appropriate.
Ruslan Ermilov <ru@nginx.com>
parents:
5214
diff
changeset
|
1272 "mail auth http header:%N\"%V\"", &l); |
521 | 1273 } |
1274 #endif | |
1275 | |
1276 return b; | |
1277 } | |
1278 | |
1279 | |
633 | 1280 static ngx_int_t |
1136 | 1281 ngx_mail_auth_http_escape(ngx_pool_t *pool, ngx_str_t *text, ngx_str_t *escaped) |
633 | 1282 { |
1405
fdd064faf26a
escape " ", "%", and %00-%1F in login and password
Igor Sysoev <igor@sysoev.ru>
parents:
1392
diff
changeset
|
1283 u_char *p; |
fdd064faf26a
escape " ", "%", and %00-%1F in login and password
Igor Sysoev <igor@sysoev.ru>
parents:
1392
diff
changeset
|
1284 uintptr_t n; |
633 | 1285 |
1405
fdd064faf26a
escape " ", "%", and %00-%1F in login and password
Igor Sysoev <igor@sysoev.ru>
parents:
1392
diff
changeset
|
1286 n = ngx_escape_uri(NULL, text->data, text->len, NGX_ESCAPE_MAIL_AUTH); |
633 | 1287 |
1288 if (n == 0) { | |
1289 *escaped = *text; | |
1290 return NGX_OK; | |
1291 } | |
1292 | |
1293 escaped->len = text->len + n * 2; | |
1294 | |
2049 | 1295 p = ngx_pnalloc(pool, escaped->len); |
633 | 1296 if (p == NULL) { |
1297 return NGX_ERROR; | |
1298 } | |
1299 | |
1405
fdd064faf26a
escape " ", "%", and %00-%1F in login and password
Igor Sysoev <igor@sysoev.ru>
parents:
1392
diff
changeset
|
1300 (void) ngx_escape_uri(p, text->data, text->len, NGX_ESCAPE_MAIL_AUTH); |
633 | 1301 |
1405
fdd064faf26a
escape " ", "%", and %00-%1F in login and password
Igor Sysoev <igor@sysoev.ru>
parents:
1392
diff
changeset
|
1302 escaped->data = p; |
633 | 1303 |
1304 return NGX_OK; | |
1305 } | |
1306 | |
1307 | |
521 | 1308 static void * |
1136 | 1309 ngx_mail_auth_http_create_conf(ngx_conf_t *cf) |
577 | 1310 { |
1136 | 1311 ngx_mail_auth_http_conf_t *ahcf; |
577 | 1312 |
1136 | 1313 ahcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_auth_http_conf_t)); |
521 | 1314 if (ahcf == NULL) { |
2912
c7d57b539248
return NULL instead of NGX_CONF_ERROR on a create conf failure
Igor Sysoev <igor@sysoev.ru>
parents:
2855
diff
changeset
|
1315 return NULL; |
521 | 1316 } |
1317 | |
1318 ahcf->timeout = NGX_CONF_UNSET_MSEC; | |
1319 | |
1392 | 1320 ahcf->file = cf->conf_file->file.name.data; |
1321 ahcf->line = cf->conf_file->line; | |
1322 | |
521 | 1323 return ahcf; |
1324 } | |
1325 | |
1326 | |
1327 static char * | |
1136 | 1328 ngx_mail_auth_http_merge_conf(ngx_conf_t *cf, void *parent, void *child) |
521 | 1329 { |
1136 | 1330 ngx_mail_auth_http_conf_t *prev = parent; |
1331 ngx_mail_auth_http_conf_t *conf = child; | |
521 | 1332 |
573 | 1333 u_char *p; |
1334 size_t len; | |
1335 ngx_uint_t i; | |
1336 ngx_table_elt_t *header; | |
1337 | |
884 | 1338 if (conf->peer == NULL) { |
1339 conf->peer = prev->peer; | |
521 | 1340 conf->host_header = prev->host_header; |
1341 conf->uri = prev->uri; | |
1392 | 1342 |
1343 if (conf->peer == NULL) { | |
1344 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
4812
785ae4de268b
Corrected the directive name in the ngx_mail_auth_http_module error message.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
1345 "no \"auth_http\" is defined for server in %s:%ui", |
1392 | 1346 conf->file, conf->line); |
1347 | |
1348 return NGX_CONF_ERROR; | |
1349 } | |
521 | 1350 } |
1351 | |
1352 ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000); | |
1353 | |
573 | 1354 if (conf->headers == NULL) { |
1355 conf->headers = prev->headers; | |
1356 conf->header = prev->header; | |
1357 } | |
1358 | |
1359 if (conf->headers && conf->header.len == 0) { | |
1360 len = 0; | |
1361 header = conf->headers->elts; | |
1362 for (i = 0; i < conf->headers->nelts; i++) { | |
1363 len += header[i].key.len + 2 + header[i].value.len + 2; | |
1364 } | |
1365 | |
2049 | 1366 p = ngx_pnalloc(cf->pool, len); |
573 | 1367 if (p == NULL) { |
1368 return NGX_CONF_ERROR; | |
1369 } | |
1370 | |
1371 conf->header.len = len; | |
1372 conf->header.data = p; | |
1373 | |
1374 for (i = 0; i < conf->headers->nelts; i++) { | |
1375 p = ngx_cpymem(p, header[i].key.data, header[i].key.len); | |
1376 *p++ = ':'; *p++ = ' '; | |
1377 p = ngx_cpymem(p, header[i].value.data, header[i].value.len); | |
1378 *p++ = CR; *p++ = LF; | |
1379 } | |
1380 } | |
1381 | |
521 | 1382 return NGX_CONF_OK; |
1383 } | |
1384 | |
1385 | |
1386 static char * | |
1136 | 1387 ngx_mail_auth_http(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
577 | 1388 { |
1136 | 1389 ngx_mail_auth_http_conf_t *ahcf = conf; |
521 | 1390 |
805
8ee450f30c25
now the "auth_http" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
1391 ngx_str_t *value; |
8ee450f30c25
now the "auth_http" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
1392 ngx_url_t u; |
573 | 1393 |
521 | 1394 value = cf->args->elts; |
1395 | |
805
8ee450f30c25
now the "auth_http" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
1396 ngx_memzero(&u, sizeof(ngx_url_t)); |
521 | 1397 |
805
8ee450f30c25
now the "auth_http" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
1398 u.url = value[1]; |
906 | 1399 u.default_port = 80; |
805
8ee450f30c25
now the "auth_http" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
1400 u.uri_part = 1; |
577 | 1401 |
1391
4eed21047e4d
allow "http://" in auth_http URL
Igor Sysoev <igor@sysoev.ru>
parents:
1390
diff
changeset
|
1402 if (ngx_strncmp(u.url.data, "http://", 7) == 0) { |
4eed21047e4d
allow "http://" in auth_http URL
Igor Sysoev <igor@sysoev.ru>
parents:
1390
diff
changeset
|
1403 u.url.len -= 7; |
4eed21047e4d
allow "http://" in auth_http URL
Igor Sysoev <igor@sysoev.ru>
parents:
1390
diff
changeset
|
1404 u.url.data += 7; |
4eed21047e4d
allow "http://" in auth_http URL
Igor Sysoev <igor@sysoev.ru>
parents:
1390
diff
changeset
|
1405 } |
4eed21047e4d
allow "http://" in auth_http URL
Igor Sysoev <igor@sysoev.ru>
parents:
1390
diff
changeset
|
1406 |
1559
fe11e2a3946d
use pool instead of ngx_conf_t
Igor Sysoev <igor@sysoev.ru>
parents:
1487
diff
changeset
|
1407 if (ngx_parse_url(cf->pool, &u) != NGX_OK) { |
805
8ee450f30c25
now the "auth_http" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
1408 if (u.err) { |
8ee450f30c25
now the "auth_http" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
1409 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
8ee450f30c25
now the "auth_http" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
1410 "%s in auth_http \"%V\"", u.err, &u.url); |
8ee450f30c25
now the "auth_http" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
1411 } |
1390 | 1412 |
1413 return NGX_CONF_ERROR; | |
805
8ee450f30c25
now the "auth_http" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
1414 } |
521 | 1415 |
884 | 1416 ahcf->peer = u.addrs; |
521 | 1417 |
3406
a2a5812cf4f4
use "localhost" in "Host" header line, if unix socket is used in "auth_http"
Igor Sysoev <igor@sysoev.ru>
parents:
3269
diff
changeset
|
1418 if (u.family != AF_UNIX) { |
a2a5812cf4f4
use "localhost" in "Host" header line, if unix socket is used in "auth_http"
Igor Sysoev <igor@sysoev.ru>
parents:
3269
diff
changeset
|
1419 ahcf->host_header = u.host; |
a2a5812cf4f4
use "localhost" in "Host" header line, if unix socket is used in "auth_http"
Igor Sysoev <igor@sysoev.ru>
parents:
3269
diff
changeset
|
1420 |
a2a5812cf4f4
use "localhost" in "Host" header line, if unix socket is used in "auth_http"
Igor Sysoev <igor@sysoev.ru>
parents:
3269
diff
changeset
|
1421 } else { |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
3406
diff
changeset
|
1422 ngx_str_set(&ahcf->host_header, "localhost"); |
3406
a2a5812cf4f4
use "localhost" in "Host" header line, if unix socket is used in "auth_http"
Igor Sysoev <igor@sysoev.ru>
parents:
3269
diff
changeset
|
1423 } |
a2a5812cf4f4
use "localhost" in "Host" header line, if unix socket is used in "auth_http"
Igor Sysoev <igor@sysoev.ru>
parents:
3269
diff
changeset
|
1424 |
805
8ee450f30c25
now the "auth_http" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
1425 ahcf->uri = u.uri; |
521 | 1426 |
559 | 1427 if (ahcf->uri.len == 0) { |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
3406
diff
changeset
|
1428 ngx_str_set(&ahcf->uri, "/"); |
555 | 1429 } |
1430 | |
521 | 1431 return NGX_CONF_OK; |
1432 } | |
573 | 1433 |
1434 | |
1435 static char * | |
1136 | 1436 ngx_mail_auth_http_header(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
577 | 1437 { |
1136 | 1438 ngx_mail_auth_http_conf_t *ahcf = conf; |
573 | 1439 |
1440 ngx_str_t *value; | |
1441 ngx_table_elt_t *header; | |
1442 | |
1443 if (ahcf->headers == NULL) { | |
1444 ahcf->headers = ngx_array_create(cf->pool, 1, sizeof(ngx_table_elt_t)); | |
1445 if (ahcf->headers == NULL) { | |
1446 return NGX_CONF_ERROR; | |
1447 } | |
1448 } | |
1449 | |
1450 header = ngx_array_push(ahcf->headers); | |
1451 if (header == NULL) { | |
1452 return NGX_CONF_ERROR; | |
1453 } | |
1454 | |
1455 value = cf->args->elts; | |
1456 | |
1457 header->key = value[1]; | |
1458 header->value = value[2]; | |
1459 | |
1460 return NGX_CONF_OK; | |
1461 } |