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)

        #
        # debugging ...
        #
        warn    condition = ${if def:mime_filename {1}{0}}
                log_message = MIME: Check MIME filename: $mime_filename

        #
        # 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)

        #
        # debugging ...
        #
        warn    condition = ${if def:mime_content_type {1}{0}}
                log_message = MIME: Check MIME content-type: $mime_content_type

        #
        # Check MIME content type against the database blacklist
        #
        deny    condition = ${if def:mime_content_type {1}{0}}
                condition = ${lookup mysql{SELECT mime_type FROM blacklist_file_extensions \                         WHERE mime_type='${quote_mysql:$mime_content_type}' \
                        AND active=1}{yes}{no}}
                message = MIME content type $mime_content_type not acceptable here                 log_message = MIME: Rejected MIME content type: $mime_content_type

        #
        # accept if we get here
        #
        accept


The debugging bits are temporary while I watch the affect of my ACLs on traffic



Mike


--
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/

Reply via email to