Re: [exim] control flow in check_content acl

Top Page
Delete this message
Reply to this message
Author: W B Hacker
Date:  
To: exim users
Subject: Re: [exim] control flow in check_content acl
Marcus Barczak wrote:

> Hi Guys,
>
> Am having a bit of a confusing time with control flow in my
> check_content ACL. I'm using the ACL for clam and sophos scanning
> however i'm trying to modify it to bail out if a particular header is
> present in the message being scanned.
>
> Basically does the ACL return on the first successful accept or does
> it terminate on the last line of the block?


That depends on the 'class' of verb.

accept, warn, and the 'rejection class' verbs (my own terminology for deny,
drop, discard, require) each have different behaviour, hence are sensitive to
sequence in two ways.

In the larger overview:

- a 'rejection-class' verb is 'final' in and of itself.
IOW - the first one satisfied aborts any further processing, both within the
smtp phase, and any subsequent smtp or delivery phase. Gone is gone.

- an 'accept' ('for-now' class verb?) on the other hand is final only within
the smtp phase in which it is located, and 'temporary' otherwise. Further acl
tests *within that phase* will be skipped over. OTOH, *subsequent* smtp phases,
routing, and delivery will be traversed until hitting a later 'rejection class'
verb or running to completion.

- A 'warn' ('label-class' verb?) doesn't affect either sort of flow. It just
lets you stick labels on the message, log remarks about the contents, or add
information for later handling as it goes past. The results of these must be
'actioned' later by testing those labels or scores (headers, acl-c/m variables,
db-insertions, etc.).

Within an acl clause:

- when more than one condition or action exist in an acl clause, their
ordering is important, as the different classes 'bail out' at different points.
IOW, log entries or headers you wish to add often need to be setup *before* the
test conditional(s), else are not traversed.

This is a necessary and important distinction that contributes to the power and
flexibility of Exim.

...and is well documented.


> Despite my header being
> present the ACL still falls through to the final accept. Am I
> misunderstanding here?


The first 'accept' satisfied skips all other tests, passes the traffic to the
next phase. If you want to know *which* of the two 'accepts' present here is
acting, make the changes I have added inline.

The first 'deny' satisfied tosses the traffic out of the room, so nothing beyond
it matters. See enhanced logging added inline.

>
> My check_content ACL looks a like this:
>
> acl_check_content:
>
>     # if X-Dont-Scan header is present we're done
>     accept

          logwrite = Looking for X-Dont-Scan
          log_message = X-Dont-Scan found
          condition = ${if def:header_X-Dont-Scan:  }

>
>     # Reject messages that have serious MIME errors.
>     deny

            logwrite = Looking for MIME defect
            log_message = IME defect found
            message = Serious MIME defect detected ($demime_reason)

>          demime = *
>          condition = ${if >{$demime_errorlevel}{2}{1}{0}}

>
>     # Reject virus infected messages.
>     deny

            logwrite = Looking for malware
            log_message = malware found
            message = This message contains malicious software ($malware_name)

>          set acl_m1 = sophie:/var/run/sophie.sock
>          condition = ${if eq {$acl_m0} {yes} {yes} {no}}
>          demime = *
>          malware = */defer_ok

>
>    warn

            logwrite = Engine 1 finished
            message = X-Virus-1: Scanned by Engine 1 (SO)

>
>    # ClamAV
>    deny

           logwrite = entering ClamAV scan
           log_message = found a ClamAV hit
           message = This message contains malicious software ($malware_name)

>          set acl_m1 = clamd:/var/run/clamav/clamd
>          condition = ${if eq {$acl_m0} {yes} {yes} {no}}
>          demime = *
>          malware = */defer_ok

>
>    warn

            logwrite = Engine 2 finished
            message = X-Virus-2: Scanned by Engine 2 (CL)

>
>

     # IF NOT already accepted AND NOT otherwise rejected, NOW accept


     accept logwrite = both scans survived. Passing to next phase.


>
> Cheers,
> Marcus
>


HTH,

Bill