diff options
Diffstat (limited to 'src/imap')
-rw-r--r-- | src/imap/ngx_imap_auth_http_module.c | 13 | ||||
-rw-r--r-- | src/imap/ngx_imap_handler.c | 87 | ||||
-rw-r--r-- | src/imap/ngx_imap_proxy_module.c | 63 |
3 files changed, 89 insertions, 74 deletions
diff --git a/src/imap/ngx_imap_auth_http_module.c b/src/imap/ngx_imap_auth_http_module.c index 85728f46a..d39c29502 100644 --- a/src/imap/ngx_imap_auth_http_module.c +++ b/src/imap/ngx_imap_auth_http_module.c @@ -182,7 +182,10 @@ ngx_imap_auth_http_init(ngx_imap_session_t *s) rc = ngx_event_connect_peer(&ctx->peer); if (rc == NGX_ERROR || rc == NGX_BUSY || rc == NGX_DECLINED) { - ngx_close_connection(ctx->peer.connection); + if (ctx->peer.connection) { + ngx_close_connection(ctx->peer.connection); + } + ngx_destroy_pool(ctx->pool); ngx_imap_session_internal_server_error(s); return; @@ -489,10 +492,10 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s, ctx->errmsg.data = ctx->header_start; if (s->protocol == NGX_IMAP_POP3_PROTOCOL) { - size = sizeof("-ERR") - 1 + len + sizeof(CRLF) - 1; + size = sizeof("-ERR ") - 1 + len + sizeof(CRLF) - 1; } else { - size = s->tag.len + sizeof("NO") - 1 + len + size = s->tag.len + sizeof("NO ") - 1 + len + sizeof(CRLF) - 1; } @@ -1039,7 +1042,9 @@ ngx_imap_auth_http_create_request(ngx_imap_session_t *s, ngx_pool_t *pool, len = sizeof("GET ") - 1 + ahcf->uri.len + sizeof(" HTTP/1.0" CRLF) - 1 + sizeof("Host: ") - 1 + ahcf->host_header.len + sizeof(CRLF) - 1 - + sizeof("Auth-Method: plain" CRLF) - 1 + + sizeof("Auth-Method: ") - 1 + + ngx_imap_auth_http_method[s->auth_method].len + + sizeof(CRLF) - 1 + sizeof("Auth-User: ") - 1 + login.len + sizeof(CRLF) - 1 + sizeof("Auth-Pass: ") - 1 + passwd.len + sizeof(CRLF) - 1 + sizeof("Auth-Salt: ") - 1 + s->salt.len diff --git a/src/imap/ngx_imap_handler.c b/src/imap/ngx_imap_handler.c index 26513940b..2b3d29cbc 100644 --- a/src/imap/ngx_imap_handler.c +++ b/src/imap/ngx_imap_handler.c @@ -12,6 +12,7 @@ static void ngx_imap_init_session(ngx_connection_t *c); static void ngx_imap_init_protocol(ngx_event_t *rev); +static void ngx_imap_do_auth(ngx_imap_session_t *s); static ngx_int_t ngx_imap_read_command(ngx_imap_session_t *s); static u_char *ngx_imap_log_error(ngx_log_t *log, u_char *buf, size_t len); @@ -537,18 +538,7 @@ ngx_imap_auth_state(ngx_event_t *rev) "imap login:\"%V\"", &s->login); #endif - s->args.nelts = 0; - s->buffer->pos = s->buffer->start; - s->buffer->last = s->buffer->start; - - if (rev->timer_set) { - ngx_del_timer(rev); - } - - s->login_attempt++; - - ngx_imap_auth_http_init(s); - + ngx_imap_do_auth(s); return; } @@ -789,16 +779,7 @@ ngx_pop3_auth_state(ngx_event_t *rev) s->auth_method = NGX_IMAP_AUTH_APOP; - s->args.nelts = 0; - s->buffer->pos = s->buffer->start; - s->buffer->last = s->buffer->start; - - if (rev->timer_set) { - ngx_del_timer(rev); - } - - ngx_imap_auth_http_init(s); - + ngx_imap_do_auth(s); return; } @@ -922,16 +903,7 @@ ngx_pop3_auth_state(ngx_event_t *rev) "pop3 passwd: \"%V\"", &s->passwd); #endif - s->args.nelts = 0; - s->buffer->pos = s->buffer->start; - s->buffer->last = s->buffer->start; - - if (rev->timer_set) { - ngx_del_timer(rev); - } - - ngx_imap_auth_http_init(s); - + ngx_imap_do_auth(s); return; } @@ -1021,16 +993,7 @@ ngx_pop3_auth_state(ngx_event_t *rev) "pop3 auth login password: \"%V\"", &s->passwd); #endif - s->args.nelts = 0; - s->buffer->pos = s->buffer->start; - s->buffer->last = s->buffer->start; - - if (rev->timer_set) { - ngx_del_timer(rev); - } - - ngx_imap_auth_http_init(s); - + ngx_imap_do_auth(s); return; case ngx_pop3_auth_plain: @@ -1092,16 +1055,7 @@ ngx_pop3_auth_state(ngx_event_t *rev) &s->login, &s->passwd); #endif - s->args.nelts = 0; - s->buffer->pos = s->buffer->start; - s->buffer->last = s->buffer->start; - - if (rev->timer_set) { - ngx_del_timer(rev); - } - - ngx_imap_auth_http_init(s); - + ngx_imap_do_auth(s); return; case ngx_pop3_auth_cram_md5: @@ -1151,16 +1105,7 @@ ngx_pop3_auth_state(ngx_event_t *rev) s->auth_method = NGX_IMAP_AUTH_CRAM_MD5; - s->args.nelts = 0; - s->buffer->pos = s->buffer->start; - s->buffer->last = s->buffer->start; - - if (rev->timer_set) { - ngx_del_timer(rev); - } - - ngx_imap_auth_http_init(s); - + ngx_imap_do_auth(s); return; } } @@ -1187,6 +1132,24 @@ ngx_pop3_auth_state(ngx_event_t *rev) } +static void +ngx_imap_do_auth(ngx_imap_session_t *s) +{ + s->args.nelts = 0; + s->buffer->pos = s->buffer->start; + s->buffer->last = s->buffer->start; + s->state = 0; + + if (s->connection->read->timer_set) { + ngx_del_timer(s->connection->read); + } + + s->login_attempt++; + + ngx_imap_auth_http_init(s); +} + + static ngx_int_t ngx_imap_read_command(ngx_imap_session_t *s) { diff --git a/src/imap/ngx_imap_proxy_module.c b/src/imap/ngx_imap_proxy_module.c index 6ab225b0c..fd4e41b84 100644 --- a/src/imap/ngx_imap_proxy_module.c +++ b/src/imap/ngx_imap_proxy_module.c @@ -13,6 +13,7 @@ typedef struct { ngx_flag_t enable; + ngx_flag_t pass_error_message; size_t buffer_size; ngx_msec_t timeout; } ngx_imap_proxy_conf_t; @@ -25,6 +26,7 @@ static void ngx_imap_proxy_dummy_handler(ngx_event_t *ev); static ngx_int_t ngx_imap_proxy_read_response(ngx_imap_session_t *s, ngx_uint_t state); static void ngx_imap_proxy_handler(ngx_event_t *ev); +static void ngx_imap_proxy_upstream_error(ngx_imap_session_t *s); static void ngx_imap_proxy_internal_server_error(ngx_imap_session_t *s); static void ngx_imap_proxy_close_session(ngx_imap_session_t *s); static void *ngx_imap_proxy_create_conf(ngx_conf_t *cf); @@ -55,6 +57,13 @@ static ngx_command_t ngx_imap_proxy_commands[] = { offsetof(ngx_imap_proxy_conf_t, timeout), NULL }, + { ngx_string("proxy_pass_error_message"), + NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_flag_slot, + NGX_IMAP_SRV_CONF_OFFSET, + offsetof(ngx_imap_proxy_conf_t, pass_error_message), + NULL }, + ngx_null_command }; @@ -204,7 +213,7 @@ ngx_imap_proxy_imap_handler(ngx_event_t *rev) } if (rc == NGX_ERROR) { - ngx_imap_proxy_internal_server_error(s); + ngx_imap_proxy_upstream_error(s); return; } @@ -349,7 +358,7 @@ ngx_imap_proxy_pop3_handler(ngx_event_t *rev) } if (rc == NGX_ERROR) { - ngx_imap_proxy_internal_server_error(s); + ngx_imap_proxy_upstream_error(s); return; } @@ -452,9 +461,10 @@ ngx_imap_proxy_dummy_handler(ngx_event_t *wev) static ngx_int_t ngx_imap_proxy_read_response(ngx_imap_session_t *s, ngx_uint_t state) { - u_char *p; - ssize_t n; - ngx_buf_t *b; + u_char *p; + ssize_t n; + ngx_buf_t *b; + ngx_imap_proxy_conf_t *pcf; s->connection->log->action = "reading response from upstream"; @@ -523,9 +533,23 @@ ngx_imap_proxy_read_response(ngx_imap_session_t *s, ngx_uint_t state) } } - *(b->last - 2) = '\0'; - ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, - "upstream sent invalid response: \"%s\"", p); + pcf = ngx_imap_get_module_srv_conf(s, ngx_imap_proxy_module); + + if (pcf->pass_error_message == 0) { + *(b->last - 2) = '\0'; + ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, + "upstream sent invalid response: \"%s\"", p); + return NGX_ERROR; + } + + s->out.len = b->last - p - 2; + s->out.data = p; + + ngx_log_error(NGX_LOG_INFO, s->connection->log, 0, + "upstream sent invalid response: \"%V\"", &s->out); + + s->out.len = b->last - b->pos; + s->out.data = b->pos; return NGX_ERROR; } @@ -698,6 +722,27 @@ ngx_imap_proxy_handler(ngx_event_t *ev) static void +ngx_imap_proxy_upstream_error(ngx_imap_session_t *s) +{ + if (s->proxy->upstream.connection) { + ngx_log_debug1(NGX_LOG_DEBUG_IMAP, s->connection->log, 0, + "close imap proxy connection: %d", + s->proxy->upstream.connection->fd); + + ngx_close_connection(s->proxy->upstream.connection); + } + + if (s->out.len == 0) { + ngx_imap_session_internal_server_error(s); + return; + } + + s->quit = 1; + ngx_imap_send(s->connection->write); +} + + +static void ngx_imap_proxy_internal_server_error(ngx_imap_session_t *s) { if (s->proxy->upstream.connection) { @@ -738,6 +783,7 @@ ngx_imap_proxy_create_conf(ngx_conf_t *cf) } pcf->enable = NGX_CONF_UNSET; + pcf->pass_error_message = NGX_CONF_UNSET; pcf->buffer_size = NGX_CONF_UNSET_SIZE; pcf->timeout = NGX_CONF_UNSET_MSEC; @@ -752,6 +798,7 @@ ngx_imap_proxy_merge_conf(ngx_conf_t *cf, void *parent, void *child) ngx_imap_proxy_conf_t *conf = child; ngx_conf_merge_value(conf->enable, prev->enable, 0); + ngx_conf_merge_value(conf->pass_error_message, prev->pass_error_message, 0); ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, (size_t) ngx_pagesize); ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 24 * 60 * 60000); |