Re: [exim] Re-write email from fax2mail service

Top Page
Delete this message
Reply to this message
Author: Phil Pennock
Date:  
To: schmerold1@gmail.com
CC: exim-users
Subject: Re: [exim] Re-write email from fax2mail service
On 2008-09-20 at 09:51 -0500, schmerold1@??? wrote:
> Brother fax machines will print a tif attachment if the email body says:
>     Image data in TIFF-F format has been attached.
> and if the attachment name is:
>     image.tif
> and if there are no other attachments

>
> I want to exim to say if the sender is support@??? and the
> subject line contains "TrustFax Notification for", then the body should
> be replaced with "Image data in TIFF-F format has been attached.", the
> first tif attachment should be renamed image.tif and the rest of the
> attachments should be stripped off the message.
>
> What is the best way to do this?


Exim doesn't support replacing MIME attachments with new content.

At base, you need to use an external filter, which you write (Perl,
Python, whatever) and which unpacks the MIME, replaces the text, then
repacks it back into a MIME message.

One way to use this would be to have a dedicated Router/Transport for
handling mail going to the fax machine and then set 'transport_filter'
on the Transport, using your external commands as a content-replacement
transport filter. This just involves adding one line to the Transport.
It's easy, clean and what I'd do, but perhaps has less ability to track
down where things went wrong if your script ever fails badly.

The other main way would be for where you don't have a custom set-up for
the printer; here, you'd add a Router/Transport (again) but this time as
a generic "change these mails" pair, separated from the recipient
handling. For the Transport, use a "pipe" driver and have the external
command re-inject the mail with -oMr to set the received protocol.
You'd set no_verify on this Router, so that mail to this recipient still
needs to be accepted elsewhere for verification purposes. This approach
will add a second Received: header to the inbound mails, as you
re-inject, and will have additional log entries, provided that the mail
is re-injected.

# router:
brother_fax_munge:
  driver = accept
  domains = FILL_ME_IN
  # Note that this checks the SMTP Envelope Sender:
  senders = support@???
  condition = ${if and{\
      {match{$h_Subject}{^TrustFax Notification for}}\
    {!eq{$received_protocol}{brothermunge}}}}
  no_verify
  transport = brother_mime_filter


This relies upon the external filter using "-oMr brothermunge" to
re-inject the command, as the Router is using that as the hint to not go
into an infinite loop.

For the Transport, you have a couple of options. The base is:

# transport:
brother_mime_filter:
driver = pipe
command = MY_EXTERNAL_COMMAND
user = THE_USER_TO_RUN_AS

One addition to this would be to set shadow_transport, so that if the
delivery succeeds (ie, Exim hands off responsibility to your script)
then you also deliver to a mailbox somewhere, so that if something goes
wrong then you still have a copy of the mail and can take care of
re-injecting it manually. You won't have full protection to ensure that
this copy is always made, so you will want to avoid filling a disk --
the shadow transport failing won't cause a reject or other special
action.

Inherently, you want the external command, when it re-submits the mail,
to preserve the sender and recipient.  For this, your options are:
 * pass on command-line, with:
     command = MY_EXTERNAL_COMMAND $local_part@$domain $sender_address
 * pass in the mail, by setting on the transport:
     envelope_to_add
     return_path_add


If you use the latter, it's cleanest to remove before re-injection. I
recommend the former.

Other thoughts:

When re-injecting, or just passing the mail through if using a
transport_filter (hereafter, I'll just say "re-injecting"), add a status
header "X-Brother-MIME-Edit:" with a results summary.

If the content isn't in the expected format, have the command just
re-inject the mail almost as-is, but be sure to add the status header,
something like:
X-Brother-MIME-Edit: UNCHANGED (not in MIME format)

In a success case:
X-Brother-MIME-Edit: SUCCESS (original: att.name "foo1.tif", text.len 234)

Between them, those values of the header will be invaluable when
something goes wrong.

I was semi-tempted to write the script too, but my pager just went off,
so the mail ends here. :)

Regards,
-Phil