changeset 665:0b460e61bdcd default tip

Merge with nginx 1.0.0.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 25 Apr 2011 04:22:17 +0400
parents 06419a2298a9 (diff) 00d13b6d4ebd (current diff)
children
files .hgtags auto/modules src/mail/ngx_mail.h src/mail/ngx_mail_auth_http_module.c src/mail/ngx_mail_handler.c src/mail/ngx_mail_imap_handler.c src/mail/ngx_mail_pop3_handler.c src/mail/ngx_mail_proxy_module.c src/mail/ngx_mail_smtp_handler.c
diffstat 9 files changed, 112 insertions(+), 80 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
@@ -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
--- 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
 
 
--- 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);
--- 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_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) {
 
--- 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;
         }
 
--- 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) {
 
--- 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;
 
--- 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);