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