Author: Mike Tubby Date: To: exim-users Subject: Re: [exim] Testing sender and recipient domains in MIME ACL
On 27/05/2020 20:58, Jeremy Harris via Exim-users wrote: > On 26/05/2020 07:53, Mike Tubby via Exim-users wrote:
>> I need to make business logic decisions in the MIME ACL on how to screen
>> MIME content based on the sender domain and recipient domain
> The message could have multiple recipients, having different domains.
> Therefore, in general, the recipient domain is not well-defined in
> any ACL apart from the RCPT ACL.
I hadn't considered the issue w.r.t. multiple recipients to be honest
... but my primary interest is the sender address as its the sender
domain that I want to whitelist.
So I can do things like no ZIP files unless sender's domain is
"special_customer.com".
>
> If you have coded the RCPT ACL to enforce single-recipient messages
> (destroying the efficiency of SMTP), by deferring and after the first,
> then you could use ${domain:$recipients}. You could do slightly better
> by permitting multiple recipients of a single recipient domain, but
> then you'd have to pick off the first one:
> ${domain:${extract {1}{,}{$recipients}}}
I was hoping to use the $sender_address / $sender_address_domain to
drive MIME checking business logic in the MIME ACL.
Right now I' doing this in the RCPT ACL:
acl_check_rcpt:
#
# Check if sender is whitelisted to disable MIME content checks, if
# so remember in a macro here for use in the MIME ACL later
#
warn set acl_m0 = 1
sender_domains = +whitelist_sender_domains
logwrite = RCPT: Sender $sender_address is
whitelisted disabling MIME content checks
warn set acl_m0 = 0
sender_domains = ! +whitelist_sender_domains
logwrite = RCPT: Sender $sender_address is not
whitelisted - MIME checks enabled
#
# Accept mail to postmaster in any local domain without
verifying the sender
#
accept local_parts = postmaster
domains = +local_domains
logwrite = RCPT: Accept postmaster always
... ... ...
where whitelist_sender_domains is a domain list from MySQL:
#
# whitelist_sender_domains - domains that are always allowed to
send to us, i.e. skip content checks
#
domainlist whitelist_sender_domains = ${lookup mysql{SELECT domain
FROM whitelist_sender_domains WHERE active='1'}{${sg{$value}{\\n}{ : }} }}
and this in the MIME ACL:
acl_check_mime:
#
# Debugging... ACL variable $acl_m0 = 1 if the sender address
is whitelisted to
# skip content or 0 for normal content checking
#
warn condition = ${if ={$acl_m0}{0}{true}{false}}
log_message = MIME: Content checks performed as sender
domain not whitelisted
#
# Accept mail if macro m1 is true - set in RCPT processing for
# whitelisted senders as we cannot test $sender_address here!
#
accept condition = ${if ={$acl_m0}{1}{true}{false}}
log_message = MIME: Content checks skipped as sender
domain whitelisted
#
# Decode MIME parts to disk. This will support virus scanners
later.
#
deny decode = default
condition = ${if > {$mime_anomaly_level}{2}{true}{false}}
message = This message contains a MIME error
($mime_anomaly_text)
log_message = MIME: Error in MIME attachment:
$mime_anomaly_text
#
# Too many MIME parts
#
deny condition = ${if >{$mime_part_count}{200}{yes}{no}}
message = Too many MIME encoded parts in message
log_message = MIME: Too many MIME parts:
$mime_part_count max: 200
#
# Excessive line length
#
deny regex = ^.{8000}
message = Line length in MIME message is too long
log_message = MIME: Maximum line length exceeded (8000
chars)
#
# Partial message
#
deny condition = ${if eq
{$mime_content_type}{message/partial}{yes}{no}}
message = MIME type message/partial not allowed
log_message = MIME type message/partial not allowed
#
# Filename length too short ( < 3 characters)
#
deny condition = ${if def:mime_filename {1}{0}}
condition = ${if <{${strlen:$mime_filename}}{3}{yes}{no}}
message = MIME attachment filename less than 3
characters
log_message = MIME: File name is too short (min 3 chars)
#
# Filename length too long ( > 255 characters)
#
deny condition = ${if def:mime_filename {1}{0}}
condition = ${if >{${strlen:$mime_filename}}{255}{yes}{no}} message = MIME attachment filename exceeds 255
characters
log_message = MIME: File name is too long (max 255 chars)
#
# MIME boundary length too long (> 1024)
#
deny condition = ${if >{${strlen:$mime_boundary}}{1024}{yes}{no}} message = MIME boundary length exceed 1024 characters
log_message = MIME: boundary length too long (max 1024)
#
# Check MIME filename/extension against the database blacklist, but
# only if the $mime_filename is set - won't be set for inline
#
deny condition = ${if def:mime_filename {1}{0}}
condition = ${lookup mysql{SELECT file_extension FROM
blacklist_file_extensions \
WHERE
file_extension=SUBSTRING_INDEX(LCASE('${quote_mysql:$mime_filename}'),
".", -1) \
AND active=1}{yes}{no}}
message = MIME filename/extension $mime_filename not
acceptable here
log_message = MIME: Rejected attachment $mime_filename
(bad file extension)