Re: [exim] Multi-line 5xx response (at DATA time)

Top Page
Delete this message
Reply to this message
Author: Edgar Lovecraft
Date:  
To: Exim users list
Subject: Re: [exim] Multi-line 5xx response (at DATA time)
Alan J. Flavell wrote:
>
> On Sat, 9 Apr 2005, Edgar Lovecraft wrote:
>
> > Over a year ago I moved everything to a single line http link.
>
> Do you mean that you link to static pages with a generic explanation for
> each of your various causes of rejection; or do you mean that a custom
> page is composed with details for each rejection (and if so, how long
> does that page persist before you garbage-collect?).


It is both custom and static, and right now I do not need to
garbage collect.

>

..[snip]...
>
> It needs for them to get at least this amount of information, if they're
> to stand any chance of locating the syntax error amongst the dozens of
> addresses in their addressee list. This is the dilemma.
> Just pointing them to a generic web page which explains that we reject
> header syntax errors as determined by the applicable RFCs, wouldn't
> really be of much help to them, in this kind of situation. Which is why
> I'm interested to know if anyone has successfully implemented web-based
> custom rejection notices.


Yes I have.

Here is how I do things.

I have a website setup that gives explanations for why certain rules
are enforced. This is the static side of the pages, explaining such
things as the RFC's, how to contact us, etc.

The dynamic side of things is what the client is actually pointed to
with the SMTP error message (same website just a dynamic portion).
I use this same message for the maillogs also. Now, at first, things
were kind-a messy because of needing to quote information that gets
returned in the SMTP error, that is why I submitted (and Phillip
incorporated, thnx Phillip :) a patch for the base64 encoding
(${str2b64:<string>}.

http://www.exim.org/mail-archives/exim-users/Week-of-Mon-
20040913/msg00122.html

So now, instead of my old macro:
    #
    #Define the expansion string to be added to the end of error messages
ERROR_INFO                       = \
${sg{\
     ${if def:sender_host_address{&ip=$sender_host_address}}\
     ${if def:sender_helo_name{&hlo=$sender_helo_name}}\
     ${if def:spam_score_int{&spl=$spam_score_int}}\
     ${if def:sender_address_local_part{&su=$sender_address_local_part}}\
     ${if def:sender_address_domain{&sd=$sender_address_domain}}\
     ${if def:local_part{&lu=$local_part}}\
     ${if def:domain{&ld=$domain}}\
     ${if def:message_id{&mid=$message_id}}\
     ${if def:found_extension{&ext=$found_extension}}\
     ${if def:malware_name{&vir=$malware_name}}\
    }\
    {\\s}\
    {%20}\
 }


I can do this instead and have much friendlier error message:
ERROR_INFO                       = \
${str2b64:\
     ${if def:sender_host_address{&ip=$sender_host_address}}\
     ${if def:sender_helo_name{&hlo=$sender_helo_name}}\
     ${if def:spam_score_int{&spl=$spam_score_int}}\
     ${if def:sender_address_local_part{&su=$sender_address_local_part}}\
     ${if def:sender_address_domain{&sd=$sender_address_domain}}\
     ${if def:local_part{&lu=$local_part}}\
     ${if def:domain{&ld=$domain}}\
     ${if def:message_id{&mid=$message_id}}\
     ${if def:found_extension{&ext=$found_extension}}\
     ${if def:malware_name{&vir=$malware_name}}\
 }


So if I want to reject a host during the SMTP EHLO phase that
gives a EHLO hostname that resolves to a private IP address
    #
    #Setup some DNSDB variables for later use
    #
  warn    hosts                  = *
          set acl_m5             = \
    ${lookup dnsdb{a=$sender_host_name}{$value}{}}
          set acl_m6             = \
    ${lookup dnsdb{a=$sender_helo_name}{$value}{}}
    #
    #DENY mail from host whos DNS A record is within the Privat Address 
    # Space AND that do not have either a DNS PTR record, or a DNS PTR 
    # record that also resolves to a private IP address, skip verified 
    # hosts done earlier.
    #    refernece RFC3330:
    #    0/8        10/8    14/8    39/8
    #    127/8        128.0/16    169.254/16     172.16/12  191.255/16
    #    192.0.0/24    192.0.2/24    192.88.99/24 192.168/16 198.18/15
    #    223.255.255/24    224/4        240/4
    #
  deny    message                = HELO/EHLO PRIVATE IP: \
    "http://www.website/smtp-errors/Error-<error#>.html?ERROR_INFO"
          !hosts                 = 10.0.0.0/8 : 172.16.0.0/12 : \
    192.168.0.0/16
          condition              = \
${if and{\
        {or{\
           {!def:sender_host_name}\
           {match{$acl_m5}\
                 {\N\
                  (^(0|10|14|39|127|2(2[4-9]|[3-5][0-9]))\.)|\
                  (^172\.(1[6-9]|2[0-9]|3[0-1])\.)|\
                  (^198\.(18|19)\.)|\
                  (^(128\.0|169\.254|191\.255)\.)|\
                  (^(192\.(0\.(0|2)|88\.99)|223\.225\.255)\.)\
                  \N\
                 }\
           }\
           }\
        }\
        {match{$acl_m6}\
              {\N\
               (^(0|10|14|39|127|2(2[4-9]|[3-5][0-9]))\.)|\
               (^172\.(1[6-9]|2[0-9]|3[0-1])\.)|\
               (^198\.(18|19)\.)|\
               (^(128\.0|169\.254|191\.255)\.)|\
               (^(192\.(0\.(0|2)|88\.99)|223\.225\.255)\.)\
               \N\
              }\
        }\
        }\
  {1}{0}\
 }


This returns something along the lines of this to the caller
550 HELO/EHLO PRIVATE IP "http://www.website/smtp-errors/Error-
<error#>.html?JmlwPTEuMi4zLjQmaGxvPWhvc3QuYmFkLkVITE8mbGQ9YmFkLkVITE8="

Decoded is: &ip=1.2.3.4&hlo=host.bad.EHLO&ld=bad.EHLO

It is trivial for any Perl or PHP, or other dynamic web language to
parse the base64 string that start after the '?' into something readable
and formatable by the client, or our staff.

I have had no problems in users not understanding the error
message, as most would not be able to understand anything
else that I return, and this gives a way for them to get
'complete' information on what happened.

There is nothing to garbage collect as all the important information
is given back to the client in the base64 string.

I have thought about, but not yet added, the DATE to the returned
information so that greping my logs when and if needed, is also
easily available.

I hope this helps in giving you something to think about ;)

--

--EAL--

--