[Greylist-users] Exim 4 ACL - not abusing the error case

William Blunn bill--greylist at blunn.org
Wed Mar 3 07:18:09 PST 2004


I was pondering some more on my ACL hook for doing greylisting.

So far, I had come up with this:

  deny  !hosts     = +relay_from_hosts
        !condition = ${run{ \
          /usr/local/lib/bagley/bagley \
            $sender_host_address \
            "${sg{$sender_address}{([\\\\"])}{\\\\\$1}}" \
            "${sg{${quote_local_part:$local_part}@$domain}{([\\\\"])}{\\\\\$1}}" \
        }}

Looking in the Exim 4 mainlog, I was seeing things like this:

  2004-03-03 14:46:49 H=your-av9l904ire.cpe.jspr.al.charter.com [68.184.56.111]
    F=<MBBPMTZFIQ at msn.com>
    temporarily rejected RCPT <dsimader at sseyo.com>: invalid "condition" value "tempreject"
    
which looks like an *error* rather than a log of a normal occurrence.

I knew that returning something other than "yes" or "no" to the
"condition" condition would cause an error, and would cause a 4xx
response to be sent back to the caller.

So what I was doing was causing an operational error to Exim 4, and
relying on the error processing to result in a 4xx response to be
sent.

Thinking about it, this can not really be considered best practice.
We should not have to (ab)use error cases to get the normal run of
things to work.

Also, we don't get the opportunity to set the message in the case of
temporary rejection.

I pondered on this and wondered at first if it would need a change to
Exim to get it to handle this three-way condition smoothly.

Then I realised we could do it like this:

  warn    !hosts     = +relay_from_hosts
          set acl_m0 = ${run{ \
            /usr/local/lib/bagley/bagley \
              $sender_host_address \
              "${sg{$sender_address}{([\\\\"])}{\\\\\$1}}" \
              "${sg{${quote_local_part:$local_part}@$domain}{([\\\\"])}{\\\\\$1}}" \
          }}

  defer   !hosts     = +relay_from_hosts
          condition  = ${if eq {$acl_m0}{tempreject}{yes}{no}}
          message    = Too busy - try again later

  deny    !hosts     = +relay_from_hosts
          condition  = ${if eq {$acl_m0}{no}{yes}{no}}
          message    = Permanent error

All we need to do is to run the greylister and save the result in an
ACL variable.  (I have used the variable acl_m0 here.  The choice of
which numbered variable to use will need to be fitted in with any
existing usage.)

Then we can test for each of the cases in turn.  We only need to test
for the temporary reject (defer) case and the reject (deny) case, and
accept will be the default.

This way we can also set different response messages for each case.

I have tried it out and it seems to be working.  I am now seeing
nice log entries like this for the temporary reject case:

  2004-03-03 15:08:27 H=130.228.184.48.ip.tele2adsl.dk [130.228.184.48]
    F=<users-billing07 at eBay.com>
    temporarily rejected RCPT <mytune at sseyo.com>: Too busy - try again later

and like this for the reject case:

  2004-03-03 14:49:30 H=1.2.3.4 (wibblecorp.com) [1.2.3.4]
    F=<bill at blunn.org>
    rejected RCPT <deo--2 at tao-group.com>: Permanent error

Cool.

Bill



More information about the Greylist-users mailing list