[Exim] empty line Cyrus' reject/vacation messages (was: Re: …

Page principale
Supprimer ce message
Répondre à ce message
Auteur: Bernhard Erdmann
Date:  
À: info-cyrus, exim users
CC: Ken Murchison
Sujet: [Exim] empty line Cyrus' reject/vacation messages (was: Re: Sieve writes an empty line in headers for reject/vacation)
Hi,

if Cyrus 2.1.13 sends reject or vacation messages generated by Sieve on
Exim 3.36 Linux systems and being filed back from Exim into Cyrus, a
blank line is added in the middle of the header lines causing the second
part of the header being treated as the body of the mail.

An example of an extra blank line in the header is shown in [4].

I debugged the process of sending and delivering a reject message. The
problem is caused in the end by using \r\r\n (!) as a line terminator in
the LMTP transport from Exim to Cyrus.

Exim 4.20 has an option drop_cr [5] but not Exim 3.36.

To my knowlegde, a locally generated mail given to sendmail should use
\n as the usual Unix line termination. The character pair \r\n is used
in SMTP communication.

Cyrus uses \r\n when calling sendmail (locally, not using SMTP) to send
a reject message.

Would it be advisable to
- patch Cyrus not to use \r\n as a line terminator
- patch Cyrus to use a wrapper for the sendmail binary stripping \r\n
down to \n
- upgrade to Exim 4.20 and use the option drop_cr?


Cyrus source code to generate reject messages (imap/lmtpd.c) [1]:

     smbuf[0] = "sendmail";
     smbuf[1] = "-i";        /* ignore dots */
     smbuf[2] = "-f";
     smbuf[3] = "<>";
     smbuf[4] = "--";
     smbuf[5] = rejto;
     smbuf[6] = NULL;
     sm_pid = open_sendmail(smbuf, &sm);
     if (sm == NULL) {
    return -1;
     }


     t = time(NULL);
     p = getpid();
     snprintf(buf, sizeof(buf), "<cmu-sieve-%d-%d-%d@%s>", p, (int) t,
         global_outgoing_count++, config_servername);


     namebuf = make_sieve_db(mailreceip);
     duplicate_mark(buf, strlen(buf), namebuf, strlen(namebuf), t);
     fprintf(sm, "Message-ID: %s\r\n", buf);


     rfc822date_gen(datestr, sizeof(datestr), t);
     fprintf(sm, "Date: %s\r\n", datestr);


     fprintf(sm, "X-Sieve: %s\r\n", SIEVE_VERSION);
     fprintf(sm, "From: Mail Sieve Subsystem <%s>\r\n", POSTMASTER);
     fprintf(sm, "To: <%s>\r\n", rejto);
     fprintf(sm, "MIME-Version: 1.0\r\n");
     fprintf(sm, "Content-Type: "
        "multipart/report; report-type=disposition-notification;"
        "\r\n\tboundary=\"%d/%s\"\r\n", (int) p, config_servername);
     fprintf(sm, "Subject: Automatically rejected mail\r\n");



The mail header in Exim's queue is shown in [2].

Very interesting is the line termination. 14 lines end on LF (\n, 0x0a)
and starting with "060I Message-ID" the lines terminate with CRLF (\r\n,
0x0d 0x0a).

"exim -Mvh 19dvc2-0000lu-00" [2]:

---- start ----
19dvc2-0000lu-00-H
cyrus 76 12
<>
1058636114 0
-ident cyrus
-received_protocol local
-body_linecount 46
XX
1
be@???

141P Received: from cyrus by ente.berdmann.de with local (Exim 3.36 #1)
     id 19dvc2-0000lu-00
     for be@???; Sat, 19 Jul 2003 19:35:14 +0200
060I Message-ID: <cmu-sieve-2906-1058636114-0@???>
039  Date: Sat, 19 Jul 2003 19:35:14 +0200
024  X-Sieve: CMU Sieve 2.2
041* From: Mail Sieve Subsystem <postmaster>
053F From: Mail Sieve Subsystem <postmaster@???>
022T To: <be@???>
019  MIME-Version: 1.0
106  Content-Type: multipart/report; report-type=disposition-notification;
     boundary="2906/ente.berdmann.de"
038  Subject: Automatically rejected mail
041  Auto-Submitted: auto-replied (rejected)
----- end -----



I configured Exim to deliver using LMTP over TCP/IP instead of using a
socket. Then I attached tcpdump/ethereal to their communication.

The lines up to and including "Received: ... +0200" are terminated using
\r\n. The following lines beginning with "Message-ID:" are terminated
using \r\r\n (not being visible here, but shown by using "od -ch" oder
emacs).

LMTP between Exim and Cyrus [3]:

220 ente.berdmann.de LMTP Cyrus v2.1.13 ready
LHLO ente.berdmann.de
250-ente.berdmann.de
250-8BITMIME
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-SIZE
250-AUTH EXTERNAL
250 IGNOREQUOTA
MAIL FROM:<> SIZE=3054
RCPT TO:<be@???>
DATA
250 2.1.0 ok
250 2.1.5 ok
354 go ahead
Received: from cyrus by ente.berdmann.de with local (Exim 3.36 #1)
     id 19dwYQ-0000uw-00
     for be@???; Sat, 19 Jul 2003 20:35:34 +0200
Message-ID: <cmu-sieve-3529-1058639734-0@???>
Date: Sat, 19 Jul 2003 20:35:34 +0200
X-Sieve: CMU Sieve 2.2
From: Mail Sieve Subsystem <postmaster@???>
To: <be@???>
MIME-Version: 1.0
Content-Type: multipart/report; report-type=disposition-notification;
     boundary="3529/ente.berdmann.de"
Subject: Automatically rejected mail
Auto-Submitted: auto-replied (rejected)
[...]



The mail source accessed with IMAP [4] (each line in Cyrus's spool on
disk is separated using \r\n):

reject mail source [4]:

Return-Path: <>
Received: from ente.berdmann.de (localhost [127.0.0.1])
    by ente.berdmann.de (Cyrus v2.1.13) with LMTP; Sat, 19 Jul 2003
20:36:27 +0200
X-Sieve: CMU Sieve 2.2
Received: from cyrus by ente.berdmann.de with local (Exim 3.36 #1)
    id 19dwYQ-0000uw-00
    for be@???; Sat, 19 Jul 2003 20:35:34 +0200
Message-ID: <cmu-sieve-3529-1058639734-0@???>


Date: Sat, 19 Jul 2003 20:35:34 +0200
X-Sieve: CMU Sieve 2.2
From: Mail Sieve Subsystem <postmaster@???>
To: <be@???>
MIME-Version: 1.0
Content-Type: multipart/report; report-type=disposition-notification;
    boundary="3529/ente.berdmann.de"
Subject: Automatically rejected mail
Auto-Submitted: auto-replied (rejected)
[...]



Exim 4.20 documentation on drop_cr
(http://www.exim.org/exim-html-4.20/doc/html/spec.html) [5]:

drop_cr
Type: boolean
Default: false

Setting drop_cr true affects non-SMTP messages that are submitted
locally. It causes every carriage return character that immediately
precedes a linefeed to be discarded. Other carriage returns are treated
as data. This action can be requested for individual messages by means
of the -dropcr command line option.