Mercurial > hg > nginx-quic
annotate src/mail/ngx_mail_auth_http_module.c @ 4964:2464ccebdb52
Upstream: fixed SIGSEGV with the "if" directive.
Configuration like
location / {
set $true 1;
if ($true) {
proxy_pass http://backend;
}
if ($true) {
# nothing
}
}
resulted in segmentation fault due to NULL pointer dereference as the
upstream configuration wasn't initialized in an implicit location created
by the last if(), but the r->content_handler was set due to first if().
Instead of committing a suicide by dereferencing a NULL pointer, return
500 (Internal Server Error) in such cases, i.e. if uscf is NULL. Better
fix would be to avoid such cases by fixing the "if" directive handling,
but it's out of scope of this patch.
Prodded by Piotr Sikora.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 13 Dec 2012 16:05:59 +0000 |
parents | 785ae4de268b |
children | eaf95350d75c |
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 { |
457 u_char *p; | |
547 | 458 time_t timer; |
527 | 459 size_t len, size; |
460 ngx_int_t rc, port, n; | |
3269
f0d596e84634
rename ngx_peer_addr_t to ngx_addr_t
Igor Sysoev <igor@sysoev.ru>
parents:
3267
diff
changeset
|
461 ngx_addr_t *peer; |
527 | 462 struct sockaddr_in *sin; |
525 | 463 |
1136 | 464 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
465 "mail auth http process headers"); | |
527 | 466 |
467 for ( ;; ) { | |
1136 | 468 rc = ngx_mail_auth_http_parse_header_line(s, ctx); |
527 | 469 |
470 if (rc == NGX_OK) { | |
471 | |
472 #if (NGX_DEBUG) | |
473 { | |
474 ngx_str_t key, value; | |
475 | |
476 key.len = ctx->header_name_end - ctx->header_name_start; | |
477 key.data = ctx->header_name_start; | |
478 value.len = ctx->header_end - ctx->header_start; | |
479 value.data = ctx->header_start; | |
480 | |
1136 | 481 ngx_log_debug2(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
482 "mail auth http header: \"%V: %V\"", | |
527 | 483 &key, &value); |
484 } | |
485 #endif | |
486 | |
487 len = ctx->header_name_end - ctx->header_name_start; | |
488 | |
489 if (len == sizeof("Auth-Status") - 1 | |
1107
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
490 && ngx_strncasecmp(ctx->header_name_start, |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
491 (u_char *) "Auth-Status", |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
492 sizeof("Auth-Status") - 1) |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
493 == 0) |
527 | 494 { |
495 len = ctx->header_end - ctx->header_start; | |
496 | |
497 if (len == 2 | |
498 && ctx->header_start[0] == 'O' | |
499 && ctx->header_start[1] == 'K') | |
500 { | |
501 continue; | |
502 } | |
503 | |
883 | 504 if (len == 4 |
505 && ctx->header_start[0] == 'W' | |
506 && ctx->header_start[1] == 'A' | |
507 && ctx->header_start[2] == 'I' | |
508 && ctx->header_start[3] == 'T') | |
509 { | |
510 s->auth_wait = 1; | |
511 continue; | |
512 } | |
513 | |
567 | 514 ctx->errmsg.len = len; |
515 ctx->errmsg.data = ctx->header_start; | |
516 | |
1136 | 517 switch (s->protocol) { |
518 | |
519 case NGX_MAIL_POP3_PROTOCOL: | |
854
1673f197bc62
fix segfault when many auth failures occurred
Igor Sysoev <igor@sysoev.ru>
parents:
809
diff
changeset
|
520 size = sizeof("-ERR ") - 1 + len + sizeof(CRLF) - 1; |
1136 | 521 break; |
527 | 522 |
1136 | 523 case NGX_MAIL_IMAP_PROTOCOL: |
854
1673f197bc62
fix segfault when many auth failures occurred
Igor Sysoev <igor@sysoev.ru>
parents:
809
diff
changeset
|
524 size = s->tag.len + sizeof("NO ") - 1 + len |
527 | 525 + sizeof(CRLF) - 1; |
1136 | 526 break; |
527 | |
528 default: /* NGX_MAIL_SMTP_PROTOCOL */ | |
529 ctx->err = ctx->errmsg; | |
530 continue; | |
527 | 531 } |
532 | |
2061
b0a1c84725cf
change useless ngx_pcalloc() to ngx_pnalloc()
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
533 p = ngx_pnalloc(s->connection->pool, size); |
527 | 534 if (p == NULL) { |
543 | 535 ngx_close_connection(ctx->peer.connection); |
547 | 536 ngx_destroy_pool(ctx->pool); |
1136 | 537 ngx_mail_session_internal_server_error(s); |
527 | 538 return; |
539 } | |
540 | |
541 ctx->err.data = p; | |
542 | |
1136 | 543 switch (s->protocol) { |
527 | 544 |
1136 | 545 case NGX_MAIL_POP3_PROTOCOL: |
546 *p++ = '-'; *p++ = 'E'; *p++ = 'R'; *p++ = 'R'; *p++ = ' '; | |
547 break; | |
548 | |
549 case NGX_MAIL_IMAP_PROTOCOL: | |
527 | 550 p = ngx_cpymem(p, s->tag.data, s->tag.len); |
1136 | 551 *p++ = 'N'; *p++ = 'O'; *p++ = ' '; |
552 break; | |
553 | |
554 default: /* NGX_MAIL_SMTP_PROTOCOL */ | |
555 break; | |
527 | 556 } |
557 | |
558 p = ngx_cpymem(p, ctx->header_start, len); | |
559 *p++ = CR; *p++ = LF; | |
560 | |
561 ctx->err.len = p - ctx->err.data; | |
562 | |
563 continue; | |
564 } | |
565 | |
566 if (len == sizeof("Auth-Server") - 1 | |
1107
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
567 && ngx_strncasecmp(ctx->header_name_start, |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
568 (u_char *) "Auth-Server", |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
569 sizeof("Auth-Server") - 1) |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
570 == 0) |
527 | 571 { |
572 ctx->addr.len = ctx->header_end - ctx->header_start; | |
573 ctx->addr.data = ctx->header_start; | |
574 | |
575 continue; | |
576 } | |
577 | |
578 if (len == sizeof("Auth-Port") - 1 | |
1107
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
579 && ngx_strncasecmp(ctx->header_name_start, |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
580 (u_char *) "Auth-Port", |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
581 sizeof("Auth-Port") - 1) |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
582 == 0) |
527 | 583 { |
584 ctx->port.len = ctx->header_end - ctx->header_start; | |
585 ctx->port.data = ctx->header_start; | |
586 | |
587 continue; | |
588 } | |
589 | |
590 if (len == sizeof("Auth-User") - 1 | |
1107
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
591 && ngx_strncasecmp(ctx->header_name_start, |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
592 (u_char *) "Auth-User", |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
593 sizeof("Auth-User") - 1) |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
594 == 0) |
527 | 595 { |
596 s->login.len = ctx->header_end - ctx->header_start; | |
567 | 597 |
2049 | 598 s->login.data = ngx_pnalloc(s->connection->pool, s->login.len); |
567 | 599 if (s->login.data == NULL) { |
600 ngx_close_connection(ctx->peer.connection); | |
601 ngx_destroy_pool(ctx->pool); | |
1136 | 602 ngx_mail_session_internal_server_error(s); |
567 | 603 return; |
604 } | |
605 | |
606 ngx_memcpy(s->login.data, ctx->header_start, s->login.len); | |
527 | 607 |
608 continue; | |
609 } | |
610 | |
800 | 611 if (len == sizeof("Auth-Pass") - 1 |
1107
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
612 && ngx_strncasecmp(ctx->header_name_start, |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
613 (u_char *) "Auth-Pass", |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
614 sizeof("Auth-Pass") - 1) |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
615 == 0) |
800 | 616 { |
617 s->passwd.len = ctx->header_end - ctx->header_start; | |
618 | |
2049 | 619 s->passwd.data = ngx_pnalloc(s->connection->pool, |
620 s->passwd.len); | |
800 | 621 if (s->passwd.data == NULL) { |
622 ngx_close_connection(ctx->peer.connection); | |
623 ngx_destroy_pool(ctx->pool); | |
1136 | 624 ngx_mail_session_internal_server_error(s); |
800 | 625 return; |
626 } | |
627 | |
628 ngx_memcpy(s->passwd.data, ctx->header_start, s->passwd.len); | |
629 | |
630 continue; | |
631 } | |
632 | |
527 | 633 if (len == sizeof("Auth-Wait") - 1 |
1107
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
634 && ngx_strncasecmp(ctx->header_name_start, |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
635 (u_char *) "Auth-Wait", |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
636 sizeof("Auth-Wait") - 1) |
db7c468c447d
ngx_strcasecmp()/ngx_strncasecmp()
Igor Sysoev <igor@sysoev.ru>
parents:
906
diff
changeset
|
637 == 0) |
527 | 638 { |
639 n = ngx_atoi(ctx->header_start, | |
640 ctx->header_end - ctx->header_start); | |
641 | |
642 if (n != NGX_ERROR) { | |
643 ctx->sleep = n; | |
644 } | |
645 | |
646 continue; | |
647 } | |
648 | |
1136 | 649 if (len == sizeof("Auth-Error-Code") - 1 |
650 && ngx_strncasecmp(ctx->header_name_start, | |
651 (u_char *) "Auth-Error-Code", | |
652 sizeof("Auth-Error-Code") - 1) | |
653 == 0) | |
654 { | |
655 ctx->errcode.len = ctx->header_end - ctx->header_start; | |
656 | |
2049 | 657 ctx->errcode.data = ngx_pnalloc(s->connection->pool, |
658 ctx->errcode.len); | |
1136 | 659 if (ctx->errcode.data == NULL) { |
660 ngx_close_connection(ctx->peer.connection); | |
661 ngx_destroy_pool(ctx->pool); | |
662 ngx_mail_session_internal_server_error(s); | |
663 return; | |
664 } | |
665 | |
666 ngx_memcpy(ctx->errcode.data, ctx->header_start, | |
667 ctx->errcode.len); | |
668 | |
669 continue; | |
670 } | |
671 | |
527 | 672 /* ignore other headers */ |
673 | |
674 continue; | |
675 } | |
676 | |
677 if (rc == NGX_DONE) { | |
1136 | 678 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
679 "mail auth http header done"); | |
527 | 680 |
681 ngx_close_connection(ctx->peer.connection); | |
682 | |
683 if (ctx->err.len) { | |
1136 | 684 |
567 | 685 ngx_log_error(NGX_LOG_INFO, s->connection->log, 0, |
686 "client login failed: \"%V\"", &ctx->errmsg); | |
687 | |
1136 | 688 if (s->protocol == NGX_MAIL_SMTP_PROTOCOL) { |
689 | |
690 if (ctx->errcode.len == 0) { | |
691 ctx->errcode = ngx_mail_smtp_errcode; | |
692 } | |
693 | |
694 ctx->err.len = ctx->errcode.len + ctx->errmsg.len | |
695 + sizeof(" " CRLF) - 1; | |
696 | |
2049 | 697 p = ngx_pnalloc(s->connection->pool, ctx->err.len); |
1166 | 698 if (p == NULL) { |
699 ngx_close_connection(ctx->peer.connection); | |
700 ngx_destroy_pool(ctx->pool); | |
701 ngx_mail_session_internal_server_error(s); | |
702 return; | |
703 } | |
1136 | 704 |
1166 | 705 ctx->err.data = p; |
1136 | 706 |
1166 | 707 p = ngx_cpymem(p, ctx->errcode.data, ctx->errcode.len); |
1136 | 708 *p++ = ' '; |
1166 | 709 p = ngx_cpymem(p, ctx->errmsg.data, ctx->errmsg.len); |
1136 | 710 *p++ = CR; *p = LF; |
711 } | |
712 | |
539 | 713 s->out = ctx->err; |
547 | 714 timer = ctx->sleep; |
527 | 715 |
547 | 716 ngx_destroy_pool(ctx->pool); |
717 | |
718 if (timer == 0) { | |
539 | 719 s->quit = 1; |
1136 | 720 ngx_mail_send(s->connection->write); |
541 | 721 return; |
722 } | |
539 | 723 |
1640 | 724 ngx_add_timer(s->connection->read, (ngx_msec_t) (timer * 1000)); |
527 | 725 |
1136 | 726 s->connection->read->handler = ngx_mail_auth_sleep_handler; |
527 | 727 |
728 return; | |
729 } | |
730 | |
883 | 731 if (s->auth_wait) { |
732 timer = ctx->sleep; | |
733 | |
734 ngx_destroy_pool(ctx->pool); | |
735 | |
736 if (timer == 0) { | |
1136 | 737 ngx_mail_auth_http_init(s); |
883 | 738 return; |
739 } | |
740 | |
1640 | 741 ngx_add_timer(s->connection->read, (ngx_msec_t) (timer * 1000)); |
883 | 742 |
1136 | 743 s->connection->read->handler = ngx_mail_auth_sleep_handler; |
883 | 744 |
745 return; | |
746 } | |
747 | |
527 | 748 if (ctx->addr.len == 0 || ctx->port.len == 0) { |
749 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, | |
541 | 750 "auth http server %V did not send server or port", |
884 | 751 ctx->peer.name); |
547 | 752 ngx_destroy_pool(ctx->pool); |
1136 | 753 ngx_mail_session_internal_server_error(s); |
527 | 754 return; |
755 } | |
756 | |
1487
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
757 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
|
758 && s->protocol != NGX_MAIL_SMTP_PROTOCOL) |
1136 | 759 { |
800 | 760 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, |
761 "auth http server %V did not send password", | |
884 | 762 ctx->peer.name); |
800 | 763 ngx_destroy_pool(ctx->pool); |
1136 | 764 ngx_mail_session_internal_server_error(s); |
800 | 765 return; |
766 } | |
767 | |
3269
f0d596e84634
rename ngx_peer_addr_t to ngx_addr_t
Igor Sysoev <igor@sysoev.ru>
parents:
3267
diff
changeset
|
768 peer = ngx_pcalloc(s->connection->pool, sizeof(ngx_addr_t)); |
884 | 769 if (peer == NULL) { |
547 | 770 ngx_destroy_pool(ctx->pool); |
1136 | 771 ngx_mail_session_internal_server_error(s); |
527 | 772 return; |
773 } | |
774 | |
2855
a96a8c916b0c
mail proxy listen IPv6 support
Igor Sysoev <igor@sysoev.ru>
parents:
2748
diff
changeset
|
775 /* AF_INET only */ |
a96a8c916b0c
mail proxy listen IPv6 support
Igor Sysoev <igor@sysoev.ru>
parents:
2748
diff
changeset
|
776 |
527 | 777 sin = ngx_pcalloc(s->connection->pool, sizeof(struct sockaddr_in)); |
778 if (sin == NULL) { | |
547 | 779 ngx_destroy_pool(ctx->pool); |
1136 | 780 ngx_mail_session_internal_server_error(s); |
527 | 781 return; |
782 } | |
783 | |
784 sin->sin_family = AF_INET; | |
785 | |
786 port = ngx_atoi(ctx->port.data, ctx->port.len); | |
4227 | 787 if (port == NGX_ERROR || port < 1 || port > 65535) { |
527 | 788 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, |
541 | 789 "auth http server %V sent invalid server " |
790 "port:\"%V\"", | |
884 | 791 ctx->peer.name, &ctx->port); |
547 | 792 ngx_destroy_pool(ctx->pool); |
1136 | 793 ngx_mail_session_internal_server_error(s); |
527 | 794 return; |
795 } | |
796 | |
797 sin->sin_port = htons((in_port_t) port); | |
798 | |
3267
fb4f7605505f
replace inet_addr() with ngx_inet_addr()
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
799 sin->sin_addr.s_addr = ngx_inet_addr(ctx->addr.data, ctx->addr.len); |
527 | 800 if (sin->sin_addr.s_addr == INADDR_NONE) { |
801 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, | |
541 | 802 "auth http server %V sent invalid server " |
803 "address:\"%V\"", | |
884 | 804 ctx->peer.name, &ctx->addr); |
547 | 805 ngx_destroy_pool(ctx->pool); |
1136 | 806 ngx_mail_session_internal_server_error(s); |
527 | 807 return; |
808 } | |
809 | |
884 | 810 peer->sockaddr = (struct sockaddr *) sin; |
811 peer->socklen = sizeof(struct sockaddr_in); | |
527 | 812 |
813 len = ctx->addr.len + 1 + ctx->port.len; | |
814 | |
884 | 815 peer->name.len = len; |
527 | 816 |
2049 | 817 peer->name.data = ngx_pnalloc(s->connection->pool, len); |
884 | 818 if (peer->name.data == NULL) { |
547 | 819 ngx_destroy_pool(ctx->pool); |
1136 | 820 ngx_mail_session_internal_server_error(s); |
527 | 821 return; |
822 } | |
823 | |
824 len = ctx->addr.len; | |
825 | |
884 | 826 ngx_memcpy(peer->name.data, ctx->addr.data, len); |
527 | 827 |
884 | 828 peer->name.data[len++] = ':'; |
527 | 829 |
884 | 830 ngx_memcpy(peer->name.data + len, ctx->port.data, ctx->port.len); |
527 | 831 |
547 | 832 ngx_destroy_pool(ctx->pool); |
1136 | 833 ngx_mail_proxy_init(s, peer); |
527 | 834 |
835 return; | |
836 } | |
837 | |
838 if (rc == NGX_AGAIN ) { | |
839 return; | |
840 } | |
841 | |
842 /* rc == NGX_ERROR */ | |
843 | |
844 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, | |
541 | 845 "auth http server %V sent invalid header in response", |
884 | 846 ctx->peer.name); |
527 | 847 ngx_close_connection(ctx->peer.connection); |
547 | 848 ngx_destroy_pool(ctx->pool); |
1136 | 849 ngx_mail_session_internal_server_error(s); |
527 | 850 |
851 return; | |
852 } | |
853 } | |
854 | |
521 | 855 |
527 | 856 static void |
1136 | 857 ngx_mail_auth_sleep_handler(ngx_event_t *rev) |
527 | 858 { |
543 | 859 ngx_connection_t *c; |
1136 | 860 ngx_mail_session_t *s; |
861 ngx_mail_core_srv_conf_t *cscf; | |
527 | 862 |
1136 | 863 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail auth sleep handler"); |
527 | 864 |
865 c = rev->data; | |
866 s = c->data; | |
867 | |
868 if (rev->timedout) { | |
869 | |
870 rev->timedout = 0; | |
871 | |
883 | 872 if (s->auth_wait) { |
873 s->auth_wait = 0; | |
1136 | 874 ngx_mail_auth_http_init(s); |
883 | 875 return; |
876 } | |
877 | |
1487
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
878 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); |
527 | 879 |
1487
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
880 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
|
881 |
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
882 s->mail_state = 0; |
1136 | 883 s->auth_method = NGX_MAIL_AUTH_PLAIN; |
800 | 884 |
543 | 885 c->log->action = "in auth state"; |
886 | |
1477 | 887 ngx_mail_send(c->write); |
543 | 888 |
583 | 889 if (c->destroyed) { |
543 | 890 return; |
891 } | |
892 | |
893 ngx_add_timer(rev, cscf->timeout); | |
894 | |
527 | 895 if (rev->ready) { |
1477 | 896 rev->handler(rev); |
527 | 897 return; |
898 } | |
899 | |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2310
diff
changeset
|
900 if (ngx_handle_read_event(rev, 0) != NGX_OK) { |
1477 | 901 ngx_mail_close_connection(c); |
527 | 902 } |
903 | |
904 return; | |
905 } | |
906 | |
907 if (rev->active) { | |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2310
diff
changeset
|
908 if (ngx_handle_read_event(rev, 0) != NGX_OK) { |
1477 | 909 ngx_mail_close_connection(c); |
527 | 910 } |
911 } | |
912 } | |
913 | |
914 | |
915 static ngx_int_t | |
1136 | 916 ngx_mail_auth_http_parse_header_line(ngx_mail_session_t *s, |
917 ngx_mail_auth_http_ctx_t *ctx) | |
527 | 918 { |
919 u_char c, ch, *p; | |
920 enum { | |
921 sw_start = 0, | |
922 sw_name, | |
923 sw_space_before_value, | |
924 sw_value, | |
925 sw_space_after_value, | |
577 | 926 sw_almost_done, |
527 | 927 sw_header_almost_done |
928 } state; | |
929 | |
577 | 930 state = ctx->state; |
527 | 931 |
932 for (p = ctx->response->pos; p < ctx->response->last; p++) { | |
933 ch = *p; | |
934 | |
935 switch (state) { | |
936 | |
937 /* first char */ | |
938 case sw_start: | |
939 | |
940 switch (ch) { | |
941 case CR: | |
577 | 942 ctx->header_end = p; |
527 | 943 state = sw_header_almost_done; |
944 break; | |
577 | 945 case LF: |
527 | 946 ctx->header_end = p; |
947 goto header_done; | |
948 default: | |
949 state = sw_name; | |
950 ctx->header_name_start = p; | |
951 | |
952 c = (u_char) (ch | 0x20); | |
953 if (c >= 'a' && c <= 'z') { | |
954 break; | |
955 } | |
956 | |
957 if (ch >= '0' && ch <= '9') { | |
958 break; | |
959 } | |
960 | |
961 return NGX_ERROR; | |
962 } | |
963 break; | |
964 | |
965 /* header name */ | |
966 case sw_name: | |
967 c = (u_char) (ch | 0x20); | |
968 if (c >= 'a' && c <= 'z') { | |
969 break; | |
970 } | |
971 | |
972 if (ch == ':') { | |
973 ctx->header_name_end = p; | |
974 state = sw_space_before_value; | |
975 break; | |
976 } | |
977 | |
978 if (ch == '-') { | |
979 break; | |
980 } | |
981 | |
982 if (ch >= '0' && ch <= '9') { | |
983 break; | |
984 } | |
985 | |
986 if (ch == CR) { | |
987 ctx->header_name_end = p; | |
988 ctx->header_start = p; | |
989 ctx->header_end = p; | |
990 state = sw_almost_done; | |
991 break; | |
992 } | |
993 | |
994 if (ch == LF) { | |
995 ctx->header_name_end = p; | |
996 ctx->header_start = p; | |
997 ctx->header_end = p; | |
998 goto done; | |
999 } | |
1000 | |
1001 return NGX_ERROR; | |
1002 | |
1003 /* space* before header value */ | |
1004 case sw_space_before_value: | |
1005 switch (ch) { | |
1006 case ' ': | |
1007 break; | |
1008 case CR: | |
1009 ctx->header_start = p; | |
1010 ctx->header_end = p; | |
1011 state = sw_almost_done; | |
1012 break; | |
1013 case LF: | |
1014 ctx->header_start = p; | |
1015 ctx->header_end = p; | |
1016 goto done; | |
1017 default: | |
1018 ctx->header_start = p; | |
1019 state = sw_value; | |
1020 break; | |
1021 } | |
1022 break; | |
1023 | |
1024 /* header value */ | |
1025 case sw_value: | |
1026 switch (ch) { | |
1027 case ' ': | |
1028 ctx->header_end = p; | |
1029 state = sw_space_after_value; | |
1030 break; | |
1031 case CR: | |
1032 ctx->header_end = p; | |
1033 state = sw_almost_done; | |
1034 break; | |
1035 case LF: | |
1036 ctx->header_end = p; | |
1037 goto done; | |
1038 } | |
1039 break; | |
1040 | |
1041 /* space* before end of header line */ | |
1042 case sw_space_after_value: | |
1043 switch (ch) { | |
1044 case ' ': | |
1045 break; | |
1046 case CR: | |
1047 state = sw_almost_done; | |
1048 break; | |
1049 case LF: | |
1050 goto done; | |
1051 default: | |
1052 state = sw_value; | |
1053 break; | |
1054 } | |
1055 break; | |
1056 | |
1057 /* end of header line */ | |
1058 case sw_almost_done: | |
1059 switch (ch) { | |
1060 case LF: | |
1061 goto done; | |
1062 default: | |
1063 return NGX_ERROR; | |
1064 } | |
1065 | |
1066 /* end of header */ | |
1067 case sw_header_almost_done: | |
1068 switch (ch) { | |
1069 case LF: | |
1070 goto header_done; | |
1071 default: | |
1072 return NGX_ERROR; | |
1073 } | |
1074 } | |
1075 } | |
1076 | |
1077 ctx->response->pos = p; | |
1078 ctx->state = state; | |
1079 | |
1080 return NGX_AGAIN; | |
1081 | |
1082 done: | |
1083 | |
1084 ctx->response->pos = p + 1; | |
1085 ctx->state = sw_start; | |
1086 | |
1087 return NGX_OK; | |
1088 | |
1089 header_done: | |
1090 | |
1091 ctx->response->pos = p + 1; | |
1092 ctx->state = sw_start; | |
1093 | |
1094 return NGX_DONE; | |
521 | 1095 } |
1096 | |
1097 | |
1098 static void | |
1136 | 1099 ngx_mail_auth_http_block_read(ngx_event_t *rev) |
521 | 1100 { |
1101 ngx_connection_t *c; | |
1136 | 1102 ngx_mail_session_t *s; |
1103 ngx_mail_auth_http_ctx_t *ctx; | |
521 | 1104 |
1136 | 1105 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, |
1106 "mail auth http block read"); | |
521 | 1107 |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2310
diff
changeset
|
1108 if (ngx_handle_read_event(rev, 0) != NGX_OK) { |
521 | 1109 c = rev->data; |
1110 s = c->data; | |
1111 | |
1136 | 1112 ctx = ngx_mail_get_module_ctx(s, ngx_mail_auth_http_module); |
521 | 1113 |
525 | 1114 ngx_close_connection(ctx->peer.connection); |
547 | 1115 ngx_destroy_pool(ctx->pool); |
1136 | 1116 ngx_mail_session_internal_server_error(s); |
521 | 1117 } |
1118 } | |
1119 | |
1120 | |
1121 static void | |
1136 | 1122 ngx_mail_auth_http_dummy_handler(ngx_event_t *ev) |
521 | 1123 { |
1136 | 1124 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, ev->log, 0, |
1125 "mail auth http dummy handler"); | |
521 | 1126 } |
1127 | |
1128 | |
1129 static ngx_buf_t * | |
1136 | 1130 ngx_mail_auth_http_create_request(ngx_mail_session_t *s, ngx_pool_t *pool, |
1131 ngx_mail_auth_http_conf_t *ahcf) | |
521 | 1132 { |
1487
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
1133 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
|
1134 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
|
1135 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
|
1136 ngx_mail_core_srv_conf_t *cscf; |
633 | 1137 |
1136 | 1138 if (ngx_mail_auth_http_escape(pool, &s->login, &login) != NGX_OK) { |
633 | 1139 return NULL; |
1140 } | |
1141 | |
1136 | 1142 if (ngx_mail_auth_http_escape(pool, &s->passwd, &passwd) != NGX_OK) { |
633 | 1143 return NULL; |
1144 } | |
521 | 1145 |
1487
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1478
diff
changeset
|
1146 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
|
1147 |
521 | 1148 len = sizeof("GET ") - 1 + ahcf->uri.len + sizeof(" HTTP/1.0" CRLF) - 1 |
1149 + 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
|
1150 + sizeof("Auth-Method: ") - 1 |
1136 | 1151 + 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
|
1152 + sizeof(CRLF) - 1 |
633 | 1153 + sizeof("Auth-User: ") - 1 + login.len + sizeof(CRLF) - 1 |
1154 + sizeof("Auth-Pass: ") - 1 + passwd.len + sizeof(CRLF) - 1 | |
800 | 1155 + 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
|
1156 + 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
|
1157 + sizeof(CRLF) - 1 |
527 | 1158 + sizeof("Auth-Login-Attempt: ") - 1 + NGX_INT_T_LEN |
1159 + sizeof(CRLF) - 1 | |
521 | 1160 + sizeof("Client-IP: ") - 1 + s->connection->addr_text.len |
1161 + sizeof(CRLF) - 1 | |
2309 | 1162 + sizeof("Client-Host: ") - 1 + s->host.len + sizeof(CRLF) - 1 |
1163 + sizeof("Auth-SMTP-Helo: ") - 1 + s->smtp_helo.len | |
1164 + sizeof("Auth-SMTP-From: ") - 1 + s->smtp_from.len | |
1165 + 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
|
1166 + ahcf->header.len |
521 | 1167 + sizeof(CRLF) - 1; |
1168 | |
547 | 1169 b = ngx_create_temp_buf(pool, len); |
521 | 1170 if (b == NULL) { |
1171 return NULL; | |
1172 } | |
1173 | |
1174 b->last = ngx_cpymem(b->last, "GET ", sizeof("GET ") - 1); | |
573 | 1175 b->last = ngx_copy(b->last, ahcf->uri.data, ahcf->uri.len); |
521 | 1176 b->last = ngx_cpymem(b->last, " HTTP/1.0" CRLF, |
1177 sizeof(" HTTP/1.0" CRLF) - 1); | |
1178 | |
1179 b->last = ngx_cpymem(b->last, "Host: ", sizeof("Host: ") - 1); | |
573 | 1180 b->last = ngx_copy(b->last, ahcf->host_header.data, |
521 | 1181 ahcf->host_header.len); |
1182 *b->last++ = CR; *b->last++ = LF; | |
1183 | |
800 | 1184 b->last = ngx_cpymem(b->last, "Auth-Method: ", |
1185 sizeof("Auth-Method: ") - 1); | |
1186 b->last = ngx_cpymem(b->last, | |
1136 | 1187 ngx_mail_auth_http_method[s->auth_method].data, |
1188 ngx_mail_auth_http_method[s->auth_method].len); | |
800 | 1189 *b->last++ = CR; *b->last++ = LF; |
521 | 1190 |
1191 b->last = ngx_cpymem(b->last, "Auth-User: ", sizeof("Auth-User: ") - 1); | |
633 | 1192 b->last = ngx_copy(b->last, login.data, login.len); |
521 | 1193 *b->last++ = CR; *b->last++ = LF; |
1194 | |
1195 b->last = ngx_cpymem(b->last, "Auth-Pass: ", sizeof("Auth-Pass: ") - 1); | |
633 | 1196 b->last = ngx_copy(b->last, passwd.data, passwd.len); |
521 | 1197 *b->last++ = CR; *b->last++ = LF; |
1198 | |
1136 | 1199 if (s->auth_method != NGX_MAIL_AUTH_PLAIN && s->salt.len) { |
800 | 1200 b->last = ngx_cpymem(b->last, "Auth-Salt: ", sizeof("Auth-Salt: ") - 1); |
1201 b->last = ngx_copy(b->last, s->salt.data, s->salt.len); | |
1202 | |
1203 s->passwd.data = NULL; | |
1204 } | |
1205 | |
521 | 1206 b->last = ngx_cpymem(b->last, "Auth-Protocol: ", |
1207 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
|
1208 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
|
1209 cscf->protocol->name.len); |
521 | 1210 *b->last++ = CR; *b->last++ = LF; |
1211 | |
527 | 1212 b->last = ngx_sprintf(b->last, "Auth-Login-Attempt: %ui" CRLF, |
1213 s->login_attempt); | |
1214 | |
521 | 1215 b->last = ngx_cpymem(b->last, "Client-IP: ", sizeof("Client-IP: ") - 1); |
573 | 1216 b->last = ngx_copy(b->last, s->connection->addr_text.data, |
2309 | 1217 s->connection->addr_text.len); |
521 | 1218 *b->last++ = CR; *b->last++ = LF; |
1219 | |
2309 | 1220 if (s->host.len) { |
1221 b->last = ngx_cpymem(b->last, "Client-Host: ", | |
1222 sizeof("Client-Host: ") - 1); | |
1223 b->last = ngx_copy(b->last, s->host.data, s->host.len); | |
1224 *b->last++ = CR; *b->last++ = LF; | |
1225 } | |
1226 | |
1227 if (s->auth_method == NGX_MAIL_AUTH_NONE) { | |
1228 | |
1229 /* HELO, MAIL FROM, and RCPT TO can't contain CRLF, no need to escape */ | |
1230 | |
1231 b->last = ngx_cpymem(b->last, "Auth-SMTP-Helo: ", | |
1232 sizeof("Auth-SMTP-Helo: ") - 1); | |
1233 b->last = ngx_copy(b->last, s->smtp_helo.data, s->smtp_helo.len); | |
1234 *b->last++ = CR; *b->last++ = LF; | |
1235 | |
1236 b->last = ngx_cpymem(b->last, "Auth-SMTP-From: ", | |
1237 sizeof("Auth-SMTP-From: ") - 1); | |
1238 b->last = ngx_copy(b->last, s->smtp_from.data, s->smtp_from.len); | |
1239 *b->last++ = CR; *b->last++ = LF; | |
1240 | |
1241 b->last = ngx_cpymem(b->last, "Auth-SMTP-To: ", | |
1242 sizeof("Auth-SMTP-To: ") - 1); | |
1243 b->last = ngx_copy(b->last, s->smtp_to.data, s->smtp_to.len); | |
1244 *b->last++ = CR; *b->last++ = LF; | |
1245 | |
1246 } | |
1247 | |
573 | 1248 if (ahcf->header.len) { |
1249 b->last = ngx_copy(b->last, ahcf->header.data, ahcf->header.len); | |
1250 } | |
1251 | |
521 | 1252 /* add "\r\n" at the header end */ |
1253 *b->last++ = CR; *b->last++ = LF; | |
1254 | |
1136 | 1255 #if (NGX_DEBUG_MAIL_PASSWD) |
521 | 1256 { |
1257 ngx_str_t l; | |
1258 | |
1259 l.len = b->last - b->pos; | |
1260 l.data = b->pos; | |
1136 | 1261 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
1262 "mail auth http header:\n\"%V\"", &l); | |
521 | 1263 } |
1264 #endif | |
1265 | |
1266 return b; | |
1267 } | |
1268 | |
1269 | |
633 | 1270 static ngx_int_t |
1136 | 1271 ngx_mail_auth_http_escape(ngx_pool_t *pool, ngx_str_t *text, ngx_str_t *escaped) |
633 | 1272 { |
1405
fdd064faf26a
escape " ", "%", and %00-%1F in login and password
Igor Sysoev <igor@sysoev.ru>
parents:
1392
diff
changeset
|
1273 u_char *p; |
fdd064faf26a
escape " ", "%", and %00-%1F in login and password
Igor Sysoev <igor@sysoev.ru>
parents:
1392
diff
changeset
|
1274 uintptr_t n; |
633 | 1275 |
1405
fdd064faf26a
escape " ", "%", and %00-%1F in login and password
Igor Sysoev <igor@sysoev.ru>
parents:
1392
diff
changeset
|
1276 n = ngx_escape_uri(NULL, text->data, text->len, NGX_ESCAPE_MAIL_AUTH); |
633 | 1277 |
1278 if (n == 0) { | |
1279 *escaped = *text; | |
1280 return NGX_OK; | |
1281 } | |
1282 | |
1283 escaped->len = text->len + n * 2; | |
1284 | |
2049 | 1285 p = ngx_pnalloc(pool, escaped->len); |
633 | 1286 if (p == NULL) { |
1287 return NGX_ERROR; | |
1288 } | |
1289 | |
1405
fdd064faf26a
escape " ", "%", and %00-%1F in login and password
Igor Sysoev <igor@sysoev.ru>
parents:
1392
diff
changeset
|
1290 (void) ngx_escape_uri(p, text->data, text->len, NGX_ESCAPE_MAIL_AUTH); |
633 | 1291 |
1405
fdd064faf26a
escape " ", "%", and %00-%1F in login and password
Igor Sysoev <igor@sysoev.ru>
parents:
1392
diff
changeset
|
1292 escaped->data = p; |
633 | 1293 |
1294 return NGX_OK; | |
1295 } | |
1296 | |
1297 | |
521 | 1298 static void * |
1136 | 1299 ngx_mail_auth_http_create_conf(ngx_conf_t *cf) |
577 | 1300 { |
1136 | 1301 ngx_mail_auth_http_conf_t *ahcf; |
577 | 1302 |
1136 | 1303 ahcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_auth_http_conf_t)); |
521 | 1304 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
|
1305 return NULL; |
521 | 1306 } |
1307 | |
1308 ahcf->timeout = NGX_CONF_UNSET_MSEC; | |
1309 | |
1392 | 1310 ahcf->file = cf->conf_file->file.name.data; |
1311 ahcf->line = cf->conf_file->line; | |
1312 | |
521 | 1313 return ahcf; |
1314 } | |
1315 | |
1316 | |
1317 static char * | |
1136 | 1318 ngx_mail_auth_http_merge_conf(ngx_conf_t *cf, void *parent, void *child) |
521 | 1319 { |
1136 | 1320 ngx_mail_auth_http_conf_t *prev = parent; |
1321 ngx_mail_auth_http_conf_t *conf = child; | |
521 | 1322 |
573 | 1323 u_char *p; |
1324 size_t len; | |
1325 ngx_uint_t i; | |
1326 ngx_table_elt_t *header; | |
1327 | |
884 | 1328 if (conf->peer == NULL) { |
1329 conf->peer = prev->peer; | |
521 | 1330 conf->host_header = prev->host_header; |
1331 conf->uri = prev->uri; | |
1392 | 1332 |
1333 if (conf->peer == NULL) { | |
1334 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
|
1335 "no \"auth_http\" is defined for server in %s:%ui", |
1392 | 1336 conf->file, conf->line); |
1337 | |
1338 return NGX_CONF_ERROR; | |
1339 } | |
521 | 1340 } |
1341 | |
1342 ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000); | |
1343 | |
573 | 1344 if (conf->headers == NULL) { |
1345 conf->headers = prev->headers; | |
1346 conf->header = prev->header; | |
1347 } | |
1348 | |
1349 if (conf->headers && conf->header.len == 0) { | |
1350 len = 0; | |
1351 header = conf->headers->elts; | |
1352 for (i = 0; i < conf->headers->nelts; i++) { | |
1353 len += header[i].key.len + 2 + header[i].value.len + 2; | |
1354 } | |
1355 | |
2049 | 1356 p = ngx_pnalloc(cf->pool, len); |
573 | 1357 if (p == NULL) { |
1358 return NGX_CONF_ERROR; | |
1359 } | |
1360 | |
1361 conf->header.len = len; | |
1362 conf->header.data = p; | |
1363 | |
1364 for (i = 0; i < conf->headers->nelts; i++) { | |
1365 p = ngx_cpymem(p, header[i].key.data, header[i].key.len); | |
1366 *p++ = ':'; *p++ = ' '; | |
1367 p = ngx_cpymem(p, header[i].value.data, header[i].value.len); | |
1368 *p++ = CR; *p++ = LF; | |
1369 } | |
1370 } | |
1371 | |
521 | 1372 return NGX_CONF_OK; |
1373 } | |
1374 | |
1375 | |
1376 static char * | |
1136 | 1377 ngx_mail_auth_http(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
577 | 1378 { |
1136 | 1379 ngx_mail_auth_http_conf_t *ahcf = conf; |
521 | 1380 |
805
8ee450f30c25
now the "auth_http" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
1381 ngx_str_t *value; |
8ee450f30c25
now the "auth_http" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
1382 ngx_url_t u; |
573 | 1383 |
521 | 1384 value = cf->args->elts; |
1385 | |
805
8ee450f30c25
now the "auth_http" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
1386 ngx_memzero(&u, sizeof(ngx_url_t)); |
521 | 1387 |
805
8ee450f30c25
now the "auth_http" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
1388 u.url = value[1]; |
906 | 1389 u.default_port = 80; |
805
8ee450f30c25
now the "auth_http" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
1390 u.uri_part = 1; |
884 | 1391 u.one_addr = 1; |
577 | 1392 |
1391
4eed21047e4d
allow "http://" in auth_http URL
Igor Sysoev <igor@sysoev.ru>
parents:
1390
diff
changeset
|
1393 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
|
1394 u.url.len -= 7; |
4eed21047e4d
allow "http://" in auth_http URL
Igor Sysoev <igor@sysoev.ru>
parents:
1390
diff
changeset
|
1395 u.url.data += 7; |
4eed21047e4d
allow "http://" in auth_http URL
Igor Sysoev <igor@sysoev.ru>
parents:
1390
diff
changeset
|
1396 } |
4eed21047e4d
allow "http://" in auth_http URL
Igor Sysoev <igor@sysoev.ru>
parents:
1390
diff
changeset
|
1397 |
1559
fe11e2a3946d
use pool instead of ngx_conf_t
Igor Sysoev <igor@sysoev.ru>
parents:
1487
diff
changeset
|
1398 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
|
1399 if (u.err) { |
8ee450f30c25
now the "auth_http" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
1400 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
|
1401 "%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
|
1402 } |
1390 | 1403 |
1404 return NGX_CONF_ERROR; | |
805
8ee450f30c25
now the "auth_http" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
1405 } |
521 | 1406 |
884 | 1407 ahcf->peer = u.addrs; |
521 | 1408 |
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
|
1409 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
|
1410 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
|
1411 |
a2a5812cf4f4
use "localhost" in "Host" header line, if unix socket is used in "auth_http"
Igor Sysoev <igor@sysoev.ru>
parents:
3269
diff
changeset
|
1412 } else { |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
3406
diff
changeset
|
1413 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
|
1414 } |
a2a5812cf4f4
use "localhost" in "Host" header line, if unix socket is used in "auth_http"
Igor Sysoev <igor@sysoev.ru>
parents:
3269
diff
changeset
|
1415 |
805
8ee450f30c25
now the "auth_http" directive uses ngx_parse_url()
Igor Sysoev <igor@sysoev.ru>
parents:
800
diff
changeset
|
1416 ahcf->uri = u.uri; |
521 | 1417 |
559 | 1418 if (ahcf->uri.len == 0) { |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
3406
diff
changeset
|
1419 ngx_str_set(&ahcf->uri, "/"); |
555 | 1420 } |
1421 | |
521 | 1422 return NGX_CONF_OK; |
1423 } | |
573 | 1424 |
1425 | |
1426 static char * | |
1136 | 1427 ngx_mail_auth_http_header(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
577 | 1428 { |
1136 | 1429 ngx_mail_auth_http_conf_t *ahcf = conf; |
573 | 1430 |
1431 ngx_str_t *value; | |
1432 ngx_table_elt_t *header; | |
1433 | |
1434 if (ahcf->headers == NULL) { | |
1435 ahcf->headers = ngx_array_create(cf->pool, 1, sizeof(ngx_table_elt_t)); | |
1436 if (ahcf->headers == NULL) { | |
1437 return NGX_CONF_ERROR; | |
1438 } | |
1439 } | |
1440 | |
1441 header = ngx_array_push(ahcf->headers); | |
1442 if (header == NULL) { | |
1443 return NGX_CONF_ERROR; | |
1444 } | |
1445 | |
1446 value = cf->args->elts; | |
1447 | |
1448 header->key = value[1]; | |
1449 header->value = value[2]; | |
1450 | |
1451 return NGX_CONF_OK; | |
1452 } |