]> git.kaiwu.me - nginx.git/commitdiff
Mail: fixed backslash handling in IMAP literals.
authorMaxim Dounin <mdounin@mdounin.ru>
Wed, 19 May 2021 00:13:23 +0000 (03:13 +0300)
committerMaxim Dounin <mdounin@mdounin.ru>
Wed, 19 May 2021 00:13:23 +0000 (03:13 +0300)
Previously, s->backslash was set if any of the arguments was a quoted
string with a backslash character.  After successful command parsing
this resulted in all arguments being filtered to remove backslashes.
This is, however, incorrect, as backslashes should not be removed from
IMAP literals.  For example:

   S: * OK IMAP4 ready
   C: a01 login {9}
   S: + OK
   C: user\name "pass\"word"
   S: * BAD internal server error

resulted in "Auth-User: username" instead of "Auth-User: user\name"
as it should.

Fix is to apply backslash filtering on per-argument basis during parsing.

src/mail/ngx_mail_imap_handler.c
src/mail/ngx_mail_parse.c

index 5dfdd76016e728c5ad8be1c853ce8f8728c0fff9..ba66b898c42f151493a34416a6de80c373fbe74f 100644 (file)
@@ -101,10 +101,9 @@ ngx_mail_imap_init_protocol(ngx_event_t *rev)
 void
 ngx_mail_imap_auth_state(ngx_event_t *rev)
 {
-    u_char              *p, *dst, *src, *end;
-    ngx_str_t           *arg;
+    u_char              *p;
     ngx_int_t            rc;
-    ngx_uint_t           tag, i;
+    ngx_uint_t           tag;
     ngx_connection_t    *c;
     ngx_mail_session_t  *s;
 
@@ -158,27 +157,6 @@ ngx_mail_imap_auth_state(ngx_event_t *rev)
         ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, "imap auth command: %i",
                        s->command);
 
-        if (s->backslash) {
-
-            arg = s->args.elts;
-
-            for (i = 0; i < s->args.nelts; i++) {
-                dst = arg[i].data;
-                end = dst + arg[i].len;
-
-                for (src = dst; src < end; dst++) {
-                    *dst = *src;
-                    if (*src++ == '\\') {
-                        *dst = *src++;
-                    }
-                }
-
-                arg[i].len = dst - arg[i].data;
-            }
-
-            s->backslash = 0;
-        }
-
         switch (s->mail_state) {
 
         case ngx_imap_start:
index 299858c1469a214b70b8082ab3942ac1ac47c49d..cc5293093d3b747c6c76849dbc2e476d3f14c946 100644 (file)
@@ -227,7 +227,7 @@ invalid:
 ngx_int_t
 ngx_mail_imap_parse_command(ngx_mail_session_t *s)
 {
-    u_char      ch, *p, *c;
+    u_char      ch, *p, *c, *dst, *src, *end;
     ngx_str_t  *arg;
     enum {
         sw_start = 0,
@@ -470,6 +470,22 @@ ngx_mail_imap_parse_command(ngx_mail_session_t *s)
                 }
                 arg->len = p - s->arg_start;
                 arg->data = s->arg_start;
+
+                if (s->backslash) {
+                    dst = s->arg_start;
+                    end = p;
+
+                    for (src = dst; src < end; dst++) {
+                        *dst = *src;
+                        if (*src++ == '\\') {
+                            *dst = *src++;
+                        }
+                    }
+
+                    arg->len = dst - s->arg_start;
+                    s->backslash = 0;
+                }
+
                 s->arg_start = NULL;
 
                 switch (ch) {