Hello everyone,
OK so I have this spam scanner configured as transport:
spamcheck_transport:
driver = pipe
batch_max = 100
command = /usr/sbin/exim -oMr spam-scanned -bS
current_directory = "/tmp"
group = mail
home_directory = "/tmp"
log_output
message_prefix =
message_suffix =
return_fail_output
no_return_path_add
transport_filter = /usr/bin/spamc -u ${lookup{$domain}lsearch*{/etc/virtual/domainowners}{$value}}
use_bsmtp
user = mail
It works great. So I wanted to add the feature of archiving the mail
(some customers of ours requested it). Simple, one would think,
replacing spamc above with custom script that would save incoming and
outgoing mail plus it would in turn call spamc (of course some
variables would have to be added as arguments of the script, like
$sender_address, $local_part, etc).
However, it works only until a message has more than one recipient.
$local_part becomes empty, but $recipients is empty as well in
an Exim router.
Spec says:
"You can use $recipients only in these cases:
1. In a system filter file.
2. In the ACLs associated with the DATA command and with non-SMTP messages, that is, the ACLs defined by acl_smtp_predata, acl_smtp_data, acl_smtp_mime, acl_not_smtp_start, acl_not_smtp, and acl_not_smtp_mime.
3. From within a local_scan() function."
Just great. That means that $recipients cannot be passed to
transport_filter or command in a transport.
I DO understand the rationale:
"However, the variable is not generally available, to prevent exposure
of Bcc recipients in unprivileged users’ filter files".
But is it really not possible to hide $recipients in user filters, but
still expose it in Exim routers and transports?!
I don't like doing all of the mail filtering in system filter. Reasons:
1. It's brittle - system filter config file is not as stable as main
configuration. It's easier to accidentally screw something up in a
system filter than in the main Exim config.
2. Too many variables get changed, like $local_part is always
"system-filter", $domain is always host's FQDN, etc. Sure, necessary
variables can be worked out in a script from other variables (like
particular local parts and domains can be computed using value of
$recipients), but why do it in a script if it's available in Exim?
This also has to be parsed in script every time the mail is processed
which adds overhead, it's error prone, you have to code it yourself,
etc.
3. Many Exim niceties are not available in system filter, e.g. in this
call:
if $received_protocol is not "spam-scanned" then
unseen pipe "/usr/local/bin/mailfilter -d $domain -l
$local_part -s $message_size -a \"$sender_address\" -m
$message_id -c $rcpt_count -r \"$recipients\" -t
$received_protocol -u
${lookup{$domain}lsearch*{/etc/virtual/domainowners}{$value}}"
endif
The local user lookup ( -u ) fails in system filter, while it works
perfectly well in a transport. The end result is that it has to be looked
up twice: first in Exim config (for other reasons), then the script
has to compute the username in a way that mimics Exim. When you're
processing high volumes of mail, it all adds up.
Am I really limited to hand-coding local_scan() extension in C if I
want to do it the right way?
--
Marcin Krol