On Tue, Aug 14, 2012 at 12:46:46PM -0400, Wietse Venema wrote:

> > May be you should look at the source for bounce service daemon.
> 
> Or look for Victor's description of a mail stream duplicator.  The
> purpose was to archive all mail. It was implemented (I think with
> Net::SMTP) as a content filter that duplicated all input lines to
> a secondary stream for archival.

The implementation was in Perl, but I did not use Net::SMTP, I
wanted something cleaner and more robust, so I ultimately wrote
my own SMTP I/O interface for Perl. A trivial example was:

  my $s = MS::SMTP::Connect($addr, $port, 30);
  eval {
    # Wait for 2XX banner or throw 4XX/5XX exception
    my $banner = $s->Hear(2);
    $s->Timeout(300);
    $s->Say("EHLO $hostname\r\n");
    my $ehlo_resp = $s->Hear(2);
    # Assume pipelining
    $s->Say("MAIL FROM:<$sender>\r\n");
    $s->Say("RCPT TO:<$rcpt>\r\n");
    $s->Say("DATA\r\n");
    $s->Hear(2); # 2XX
    $s->Hear(2); # 2XX
    $s->Hear(3); # 3XX
    $s->Xfer($msgbody);
    $s->Say(".\r\n");
    $s->Say("QUIT");
    $s->Timeout(600);
    $s->Hear(2);
  };
  if ($@) {
        # Handle exception
  }
  # Delivery is complete

I found this much easier to work with than Net::SMTP, but the idea
is the same.

> The trick was to send the final
> "." to the primary stream only after delivery to the secondary
> stream was successful, otherwise it would report a temporary error.
> 
> Such a content filter might even be deployed as smtpd_proxy_filter;
> it should not be more than a few dozen lines of code.

Indeed an archive-only filter is fairly short. In my case it MIME
encapsulates the archive copy with the original message as an 
attachment and the envelope as the body. This is easy since a message
attachment is just:

|       Outer-Headers:
|       Content-Type: multipart/mixed; boundary = mumble
|
|       --mumble
|       Content-Type: text/plain; charset=us-ascii
|
|       Message envelope here
|
|       --mumble
|       Content-Type: message/rfc822
|
        Original-Message-Headers-Here:

        Original Message body here.
|
|       --mumble--
        .

Thus all that is required is to send the lines marked with a leading
"|" just before and just after the unmodified message. The envelope
is naturally also different for the archive stream, the recipient
is the archive destination and the sender is either empty or a
special mailbox for processing archive bounces (that should never
happen) since I always ensure archive deliveries soft-bounce.

-- 
        Viktor.

Reply via email to