changeset 570:9773720b845e

Merge with 0.8.16.
author Maxim Dounin <mdounin@mdounin.ru>
date Sat, 26 Sep 2009 01:25:07 +0400
parents 1e91f9968443 (diff) b8ac674b0ec9 (current diff)
children 5938746e70c2
files .hgtags auto/lib/pcre/patch.config.in auto/lib/pcre/patch.pcre.c auto/lib/pcre/patch.pcre.in auto/lib/pcre/patch.pcre.in.owc auto/modules src/event/modules/ngx_kqueue_module.h src/mail/ngx_mail.h src/mail/ngx_mail_auth_http_module.c src/mail/ngx_mail_core_module.c src/mail/ngx_mail_handler.c src/mail/ngx_mail_proxy_module.c src/mail/ngx_mail_smtp_handler.c src/os/unix/ngx_aio.h src/os/unix/ngx_sunpro_x86.map
diffstat 6 files changed, 104 insertions(+), 75 deletions(-) [+]
line wrap: on
line diff
--- 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
--- a/auto/modules
+++ b/auto/modules
@@ -417,6 +417,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
 
 
--- 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) {
--- 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,9 +839,21 @@ 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;
 }
 
@@ -831,6 +862,7 @@ ngx_int_t
 ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c)
 {
     ngx_str_t                 *arg;
+    ngx_uint_t                 nelts;
 
 #if (NGX_MAIL_SSL)
     if (ngx_mail_starttls_only(s, c)) {
@@ -839,16 +871,22 @@ ngx_mail_auth_parse(ngx_mail_session_t *
 #endif
 
     arg = s->args.elts;
+    nelts = s->args.nelts;
+
+    if (s->protocol == NGX_MAIL_SMTP_PROTOCOL) {
+        arg++;
+        nelts--;
+    }
 
     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 +895,13 @@ 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,
+                              (s->protocol == NGX_MAIL_SMTP_PROTOCOL) ? 2 : 1);
             }
         }
 
@@ -871,7 +910,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;
         }
 
--- a/src/mail/ngx_mail_proxy_module.c
+++ b/src/mail/ngx_mail_proxy_module.c
@@ -658,7 +658,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;
 
--- a/src/mail/ngx_mail_smtp_handler.c
+++ b/src/mail/ngx_mail_smtp_handler.c
@@ -321,6 +321,7 @@ ngx_mail_smtp_invalid_pipelining(ngx_eve
 
         s->out.len = sizeof(smtp_invalid_pipelining) - 1;
         s->out.data = smtp_invalid_pipelining;
+        s->quit = 1;
     }
 
     ngx_mail_send(c->write);
@@ -489,6 +490,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:
@@ -510,11 +515,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);
@@ -528,7 +536,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) {
         s->out.len = sizeof(smtp_invalid_argument) - 1;
         s->out.data = smtp_invalid_argument;
         s->state = 0;
@@ -537,14 +545,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);
 
     s->smtp_from.len = 0;
     s->smtp_from.data = NULL;
@@ -598,7 +606,7 @@ ngx_mail_smtp_auth(ngx_mail_session_t *s
     }
 #endif
 
-    if (s->args.nelts == 0) {
+    if (s->args.nelts < 2) {
         s->out.len = sizeof(smtp_invalid_argument) - 1;
         s->out.data = smtp_invalid_argument;
         s->state = 0;
@@ -623,7 +631,7 @@ ngx_mail_smtp_auth(ngx_mail_session_t *s
         s->out.data = 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:
 
@@ -664,9 +672,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);
@@ -688,37 +694,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);
@@ -733,9 +722,7 @@ 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) {
         s->out.len = sizeof(smtp_bad_sequence) - 1;
@@ -743,37 +730,20 @@ ngx_mail_smtp_rcpt(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_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);