Hello,

it has been reported to this list earlier that moving messages from
local mailboxes into DBMail using IMAP does not work properly (even
when not using Evolution ;-). I can confirm this problem and I have
found the cause for that.

The function _ic_append() in imapcommands.c reads a literal string
(the message to be appended to the mailbox) from the client (the size
is given as the last argument on the command line of the APPEND
command and passed to _ic_append()).

Regarding literal strings RFC2060 states (section 7.5, third paragraph):

   [...] The remainder of the command, including the CRLF that
   terminates a command, follows the octets of the literal. If there
   are any additional command arguments the literal octets are
   followed by a space and those arguments.

Note that the rest of the command (including CRLF) is following the
literal string, i.e. the literal string is _not_ the end of the command.

The literal string argument to APPEND is the last argument, so a CRLF
has to follow it. _ic_append() does not take care of reading this
CRLF, so the next iteration of the command loop reads an empty line,
which in turn increments `nfaultyresponses' and terminates the IMAP
connection after MAX_FAULTY_RESPONSES (i.e. 5) APPEND commands.

I have attached a patch which fixes this by reading the CRLF in
_ic_append() (or returning an error if no CRLF is read). I think that
the "real" solution should be different: If I interpret RCF2060
correctly then literal strings can be used in a lot of places instead
of quoted strings, e.g. for mailbox names, user names or passwords
("astring" in the grammer in section 9 of RFC2060). I suggest
therefore to rewrite the command parsing code to handle literal
strings in the command parser, not in e.g. _ic_append(). It is
probably too late for that change before 1.0, but some sort of fix for
the APPEND command should go in.

I hope this helps to improve DBMail.


Regards,

Armin
--- dbmail/imapcommands.c       2002-11-12 18:56:18.000000000 +0100
+++ dbmail.append-crlf/imapcommands.c   2002-11-12 18:59:25.000000000 +0100
@@ -1450,30 +1450,45 @@
 
   msgdata[dataidx] = 0;   /* terminate (safety, this byte will not be stored) 
*/
 
+  /* the literal string MUST be followed by CRLF */
+  result = 0;
+  if (fgetc(ci->rx) != '\r')
+    result = 1;
+  else if (fgetc(ci->rx) != '\n')
+    result = 1;
+
   alarm(0); /* clear alarm */
 
-  /* insert this msg */
-  result = db_imap_append_msg(msgdata, dataidx, mboxid, ud->userid);
-  switch (result)
-    {
-    case -1:
-      trace(TRACE_ERROR,"ic_append(): error appending msg\n");
-      fprintf(ci->tx,"* BYE internal dbase error storing message\r\n");
-      break;
-      
-    case 1:
-      trace(TRACE_ERROR,"ic_append(): faulty msg\n");
-      fprintf(ci->tx,"%s NO invalid message specified\r\n", tag);
-      break;
-
-    case 2:
-      trace(TRACE_INFO,"ic_append(): quotum would exceed\n");
-      fprintf(ci->tx,"%s NO not enough quotum left\r\n", tag);
-      break;
-
-    case 0:
-      fprintf(ci->tx,"%s OK APPEND completed\r\n",tag);
-      break;
+  if (result != 0)
+    {
+      trace(TRACE_ERROR,"ic_append(): msg followed by CRLF\n");
+      fprintf(ci->tx,"%s BAD expected crlf after literal string\r\n", tag);
+    }
+  else
+    {
+      /* insert this msg */
+      result = db_imap_append_msg(msgdata, dataidx, mboxid, ud->userid);
+      switch (result)
+        {
+        case -1:
+         trace(TRACE_ERROR,"ic_append(): error appending msg\n");
+         fprintf(ci->tx,"* BYE internal dbase error storing message\r\n");
+         break;
+         
+        case 1:
+         trace(TRACE_ERROR,"ic_append(): faulty msg\n");
+         fprintf(ci->tx,"%s NO invalid message specified\r\n", tag);
+         break;
+         
+        case 2:
+         trace(TRACE_INFO,"ic_append(): quotum would exceed\n");
+         fprintf(ci->tx,"%s NO not enough quotum left\r\n", tag);
+         break;
+         
+        case 0:
+         fprintf(ci->tx,"%s OK APPEND completed\r\n",tag);
+         break;
+        }
     }
 
   my_free(msgdata);

Reply via email to