# HG changeset patch # User Maxim Dounin # Date 1303690937 -14400 # Node ID 0b460e61bdcdd5aaa2ec2b14c003156b9d975fa4 # Parent 06419a2298a9a0de0a54ad1f0951d549f8a06599# Parent 00d13b6d4ebd225f94a2e2a3afa7dbd3ddfe4ed7 Merge with nginx 1.0.0. diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -159,6 +159,10 @@ d5ec0be9c835834844c6d1661b36313413231a06 a6d84efa510670a5401fbd31ddd28f6931a88869 NGINX_0_6_2 fc223117327fbb2e852840dcb533ba5ff998d9ee NGINX_0_6_3 95183808f549b2d1c8d8004b704287025b4bf76b NGINX_0_6_4 +e2d916d7e50f07f94fa4bf0d0e99ba85225ea2fa PATCH_NGINX_MAIL_0_1 +f9e6413396d47def780cf9600bbe35b35ce09e6e PATCH_NGINX_MAIL_0_2 +98c752b41cbc0f0ecaafced85d906effa27e8fc9 PATCH_NGINX_MAIL_0_3 +05c02cbce7be96d0b5e5b9cc581f7752f8ea2e71 PATCH_NGINX_MAIL_0_4 d16d691432c9044f8b26ffccbd6ae68c11d0cde9 NGINX_0_6_5 f7cd062ee035392cb44b3ec340d31f94ce4d83de NGINX_0_6_6 9fc4ab6673f96b0d3eaefd820b6c2520dd8f103d NGINX_0_6_7 @@ -196,6 +200,7 @@ 6de24473fa708acc3b2f13611f5c44b0e3a292c9 0b6053502c552a3021db417cb2dc6caac7ba1bdd NGINX_0_7_7 34fb3a5735483bd22e77f90f305103307a813fc4 NGINX_0_7_8 05981f639d211e316c98ff3074a0f268fbde8bed NGINX_0_7_9 +03a69004d77d39856e192891cb7067605abbcd1b PATCH_NGINX_MAIL_0_5 349057ecf4d5d2886b08e6c61656548577243141 NGINX_0_7_10 9d81578d04bbc73636567e84ed5a48e86826eb1b NGINX_0_7_11 6ebbca3d5ed73b82e1e0aa14adff133b50bbb4ea NGINX_0_7_12 @@ -217,6 +222,8 @@ dac47e9ef0d5fc6ec8cd1e0ff433c86e96d1a358 fd759445d8a890a9db4ab645581358fdce277908 NGINX_0_7_28 49a0eb7ce20c1114dd25a73373b9ad5f77d02ed7 NGINX_0_7_29 dc98ed169c03366ef89869d49da3b21b4b6663fe NGINX_0_7_30 +2580fe1c5a9a300134ea707c5e27d871bc0237f0 PATCH_NGINX_MAIL_0_6 +2c989ee54dbd4bfa12b53f3b0ff59e5def929818 PATCH_NGINX_MAIL_0_7 ce4f9ff90bfa58834c5b0db35395fd980c8c4aa0 NGINX_0_7_31 6281966854a55e092674b01b6861bd025fe158ee NGINX_0_7_32 670af56a1158749e82d7b1fce1ce348f8e10472a NGINX_0_7_33 @@ -263,6 +270,7 @@ 1bc8c12d80ecec4f7f88c35359585ca5139248e3 80f7156c296569546cf57fa286749d84e0cc8b9d NGINX_0_8_14 0161f31978175e258b8bb4989262b2ccb5fa9207 NGINX_0_8_15 005a70f9573bc6bcf760786cb0573a62f1e570f3 NGINX_0_8_16 +5938746e70c2ae3e83fb402c030635f5ab459251 PATCH_NGINX_MAIL_0_8 4c5d2c627a6c0ad577b5e930782128fc7b082599 NGINX_0_8_17 f7ec98e3caeb844c9401027b092837eee63dccab NGINX_0_8_18 a52c99698e7f7001336116600d8bb40bdfdc59e0 NGINX_0_8_19 diff --git a/auto/modules b/auto/modules --- a/auto/modules +++ b/auto/modules @@ -428,6 +428,8 @@ if [ $MAIL = YES ]; then modules="$modules $MAIL_PROXY_MODULE" MAIL_SRCS="$MAIL_SRCS $MAIL_PROXY_SRCS" + + NGX_ADDON_DEPS="$NGX_ADDON_DEPS \$(MAIL_DEPS)" fi diff --git a/src/mail/ngx_mail.h b/src/mail/ngx_mail.h --- a/src/mail/ngx_mail.h +++ b/src/mail/ngx_mail.h @@ -380,7 +380,8 @@ ngx_int_t ngx_mail_auth_login_password(n ngx_int_t ngx_mail_auth_cram_md5_salt(ngx_mail_session_t *s, ngx_connection_t *c, char *prefix, size_t len); ngx_int_t ngx_mail_auth_cram_md5(ngx_mail_session_t *s, ngx_connection_t *c); -ngx_int_t ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c); +ngx_int_t ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c, + ngx_uint_t n); void ngx_mail_send(ngx_event_t *wev); ngx_int_t ngx_mail_read_command(ngx_mail_session_t *s, ngx_connection_t *c); diff --git a/src/mail/ngx_mail_auth_http_module.c b/src/mail/ngx_mail_auth_http_module.c diff --git a/src/mail/ngx_mail_core_module.c b/src/mail/ngx_mail_core_module.c diff --git a/src/mail/ngx_mail_handler.c b/src/mail/ngx_mail_handler.c --- a/src/mail/ngx_mail_handler.c +++ b/src/mail/ngx_mail_handler.c @@ -621,7 +621,9 @@ ngx_mail_read_command(ngx_mail_session_t return NGX_ERROR; } - return NGX_AGAIN; + if (s->buffer->pos == s->buffer->last) { + return NGX_AGAIN; + } } cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); @@ -662,8 +664,12 @@ void ngx_mail_auth(ngx_mail_session_t *s, ngx_connection_t *c) { s->args.nelts = 0; - s->buffer->pos = s->buffer->start; - s->buffer->last = s->buffer->start; + + if (s->buffer->pos == s->buffer->last) { + s->buffer->pos = s->buffer->start; + s->buffer->last = s->buffer->start; + } + s->state = 0; if (c->read->timer_set) { diff --git a/src/mail/ngx_mail_imap_handler.c b/src/mail/ngx_mail_imap_handler.c --- a/src/mail/ngx_mail_imap_handler.c +++ b/src/mail/ngx_mail_imap_handler.c @@ -351,7 +351,7 @@ ngx_mail_imap_authenticate(ngx_mail_sess } #endif - rc = ngx_mail_auth_parse(s, c); + rc = ngx_mail_auth_parse(s, c, 0); switch (rc) { diff --git a/src/mail/ngx_mail_imap_module.c b/src/mail/ngx_mail_imap_module.c diff --git a/src/mail/ngx_mail_parse.c b/src/mail/ngx_mail_parse.c --- a/src/mail/ngx_mail_parse.c +++ b/src/mail/ngx_mail_parse.c @@ -622,6 +622,8 @@ ngx_mail_smtp_parse_command(ngx_mail_ses ngx_str_t *arg; enum { sw_start = 0, + sw_command, + sw_invalid, sw_spaces_before_argument, sw_argument, sw_almost_done @@ -636,8 +638,14 @@ ngx_mail_smtp_parse_command(ngx_mail_ses /* SMTP command */ case sw_start: + s->arg_start = p; + state = sw_command; + + /* fall through */ + + case sw_command: if (ch == ' ' || ch == CR || ch == LF) { - c = s->buffer->start; + c = s->arg_start; if (p - c == 4) { @@ -715,6 +723,14 @@ ngx_mail_smtp_parse_command(ngx_mail_ses goto invalid; } + arg = ngx_array_push(&s->args); + if (arg == NULL) { + return NGX_ERROR; + } + arg->len = p - s->arg_start; + arg->data = s->arg_start; + s->arg_start = NULL; + switch (ch) { case ' ': state = sw_spaces_before_argument; @@ -734,6 +750,9 @@ ngx_mail_smtp_parse_command(ngx_mail_ses break; + case sw_invalid: + goto invalid; + case sw_spaces_before_argument: switch (ch) { case ' ': @@ -820,17 +839,30 @@ done: invalid: - s->state = sw_start; + s->state = sw_invalid; s->arg_start = NULL; + /* skip invalid command till LF */ + + for (p = s->buffer->pos; p < s->buffer->last; p++) { + if (*p == LF) { + s->state = sw_start; + p++; + break; + } + } + + s->buffer->pos = p; + return NGX_MAIL_PARSE_INVALID_COMMAND; } ngx_int_t -ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c) +ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c, ngx_uint_t n) { ngx_str_t *arg; + ngx_uint_t nelts; #if (NGX_MAIL_SSL) if (ngx_mail_starttls_only(s, c)) { @@ -839,16 +871,24 @@ ngx_mail_auth_parse(ngx_mail_session_t * #endif arg = s->args.elts; + nelts = s->args.nelts; + + if (nelts <= n) { + return NGX_MAIL_PARSE_INVALID_COMMAND; + } + + arg += n; + nelts -= n; if (arg[0].len == 5) { if (ngx_strncasecmp(arg[0].data, (u_char *) "LOGIN", 5) == 0) { - if (s->args.nelts == 1) { + if (nelts == 1) { return NGX_MAIL_AUTH_LOGIN; } - if (s->args.nelts == 2) { + if (nelts == 2) { return NGX_MAIL_AUTH_LOGIN_USERNAME; } @@ -857,12 +897,12 @@ ngx_mail_auth_parse(ngx_mail_session_t * if (ngx_strncasecmp(arg[0].data, (u_char *) "PLAIN", 5) == 0) { - if (s->args.nelts == 1) { + if (nelts == 1) { return NGX_MAIL_AUTH_PLAIN; } - if (s->args.nelts == 2) { - return ngx_mail_auth_plain(s, c, 1); + if (nelts == 2) { + return ngx_mail_auth_plain(s, c, n + 1); } } @@ -871,7 +911,7 @@ ngx_mail_auth_parse(ngx_mail_session_t * if (arg[0].len == 8) { - if (s->args.nelts != 1) { + if (nelts != 1) { return NGX_MAIL_PARSE_INVALID_COMMAND; } diff --git a/src/mail/ngx_mail_pop3_handler.c b/src/mail/ngx_mail_pop3_handler.c --- a/src/mail/ngx_mail_pop3_handler.c +++ b/src/mail/ngx_mail_pop3_handler.c @@ -456,7 +456,7 @@ ngx_mail_pop3_auth(ngx_mail_session_t *s return NGX_OK; } - rc = ngx_mail_auth_parse(s, c); + rc = ngx_mail_auth_parse(s, c, 0); switch (rc) { diff --git a/src/mail/ngx_mail_proxy_module.c b/src/mail/ngx_mail_proxy_module.c --- a/src/mail/ngx_mail_proxy_module.c +++ b/src/mail/ngx_mail_proxy_module.c @@ -656,7 +656,12 @@ ngx_mail_proxy_smtp_handler(ngx_event_t c->log->action = NULL; ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in"); - ngx_mail_proxy_handler(s->connection->write); + if (s->buffer->pos == s->buffer->last) { + ngx_mail_proxy_handler(s->connection->write); + + } else { + ngx_mail_proxy_handler(c->write); + } return; diff --git a/src/mail/ngx_mail_smtp_handler.c b/src/mail/ngx_mail_smtp_handler.c --- a/src/mail/ngx_mail_smtp_handler.c +++ b/src/mail/ngx_mail_smtp_handler.c @@ -320,6 +320,7 @@ ngx_mail_smtp_invalid_pipelining(ngx_eve } ngx_str_set(&s->out, smtp_invalid_pipelining); + s->quit = 1; } ngx_mail_send(c->write); @@ -484,6 +485,10 @@ ngx_mail_smtp_auth_state(ngx_event_t *re } } + if (s->buffer->pos < s->buffer->last) { + s->blocked = 1; + } + switch (rc) { case NGX_DONE: @@ -503,11 +508,14 @@ ngx_mail_smtp_auth_state(ngx_event_t *re case NGX_OK: s->args.nelts = 0; - s->buffer->pos = s->buffer->start; - s->buffer->last = s->buffer->start; + + if (s->buffer->pos == s->buffer->last) { + s->buffer->pos = s->buffer->start; + s->buffer->last = s->buffer->start; + } if (s->state) { - s->arg_start = s->buffer->start; + s->arg_start = s->buffer->pos; } ngx_mail_send(c->write); @@ -521,7 +529,7 @@ ngx_mail_smtp_helo(ngx_mail_session_t *s ngx_str_t *arg; ngx_mail_smtp_srv_conf_t *sscf; - if (s->args.nelts != 1) { + if (s->args.nelts != 2) { ngx_str_set(&s->out, smtp_invalid_argument); s->state = 0; return NGX_OK; @@ -529,14 +537,14 @@ ngx_mail_smtp_helo(ngx_mail_session_t *s arg = s->args.elts; - s->smtp_helo.len = arg[0].len; + s->smtp_helo.len = arg[1].len; - s->smtp_helo.data = ngx_pnalloc(c->pool, arg[0].len); + s->smtp_helo.data = ngx_pnalloc(c->pool, arg[1].len); if (s->smtp_helo.data == NULL) { return NGX_ERROR; } - ngx_memcpy(s->smtp_helo.data, arg[0].data, arg[0].len); + ngx_memcpy(s->smtp_helo.data, arg[1].data, arg[1].len); ngx_str_null(&s->smtp_from); ngx_str_null(&s->smtp_to); @@ -588,13 +596,13 @@ ngx_mail_smtp_auth(ngx_mail_session_t *s } #endif - if (s->args.nelts == 0) { + if (s->args.nelts < 2) { ngx_str_set(&s->out, smtp_invalid_argument); s->state = 0; return NGX_OK; } - rc = ngx_mail_auth_parse(s, c); + rc = ngx_mail_auth_parse(s, c, 1); switch (rc) { @@ -610,7 +618,7 @@ ngx_mail_smtp_auth(ngx_mail_session_t *s ngx_str_set(&s->out, smtp_password); s->mail_state = ngx_smtp_auth_login_password; - return ngx_mail_auth_login_username(s, c, 1); + return ngx_mail_auth_login_username(s, c, 2); case NGX_MAIL_AUTH_PLAIN: @@ -650,9 +658,7 @@ ngx_mail_smtp_auth(ngx_mail_session_t *s static ngx_int_t ngx_mail_smtp_mail(ngx_mail_session_t *s, ngx_connection_t *c) { - u_char ch; - ngx_str_t l; - ngx_uint_t i; + ngx_str_t *arg, *end, cmd; ngx_mail_smtp_srv_conf_t *sscf; sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module); @@ -670,37 +676,20 @@ ngx_mail_smtp_mail(ngx_mail_session_t *s return NGX_OK; } - l.len = s->buffer->last - s->buffer->start; - l.data = s->buffer->start; - - for (i = 0; i < l.len; i++) { - ch = l.data[i]; - - if (ch != CR && ch != LF) { - continue; - } - - l.data[i] = ' '; - } + arg = s->args.elts; + end = arg + s->args.nelts - 1; - while (i) { - if (l.data[i - 1] != ' ') { - break; - } + cmd.len = end->data + end->len - arg->data; + cmd.data = arg->data; - i--; - } + s->smtp_from.len = cmd.len; - l.len = i; - - s->smtp_from.len = l.len; - - s->smtp_from.data = ngx_pnalloc(c->pool, l.len); + s->smtp_from.data = ngx_pnalloc(c->pool, cmd.len); if (s->smtp_from.data == NULL) { return NGX_ERROR; } - ngx_memcpy(s->smtp_from.data, l.data, l.len); + ngx_memcpy(s->smtp_from.data, cmd.data, cmd.len); ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, "smtp mail from:\"%V\"", &s->smtp_from); @@ -714,46 +703,27 @@ ngx_mail_smtp_mail(ngx_mail_session_t *s static ngx_int_t ngx_mail_smtp_rcpt(ngx_mail_session_t *s, ngx_connection_t *c) { - u_char ch; - ngx_str_t l; - ngx_uint_t i; + ngx_str_t *arg, *end, cmd; if (s->smtp_from.len == 0) { ngx_str_set(&s->out, smtp_bad_sequence); return NGX_OK; } - l.len = s->buffer->last - s->buffer->start; - l.data = s->buffer->start; - - for (i = 0; i < l.len; i++) { - ch = l.data[i]; - - if (ch != CR && ch != LF) { - continue; - } - - l.data[i] = ' '; - } + arg = s->args.elts; + end = arg + s->args.nelts - 1; - while (i) { - if (l.data[i - 1] != ' ') { - break; - } + cmd.len = end->data + end->len - arg->data; + cmd.data = arg->data; - i--; - } + s->smtp_to.len = cmd.len; - l.len = i; - - s->smtp_to.len = l.len; - - s->smtp_to.data = ngx_pnalloc(c->pool, l.len); + s->smtp_to.data = ngx_pnalloc(c->pool, cmd.len); if (s->smtp_to.data == NULL) { return NGX_ERROR; } - ngx_memcpy(s->smtp_to.data, l.data, l.len); + ngx_memcpy(s->smtp_to.data, cmd.data, cmd.len); ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, "smtp rcpt to:\"%V\"", &s->smtp_to); diff --git a/src/mail/ngx_mail_smtp_module.c b/src/mail/ngx_mail_smtp_module.c