[Index] [About] Computing: Docs
Author Simes
Created:  2005-05-07
Last changed:  2004-07-23
[Root]  [Prev] [Idx] [Next] http://www.bpfh.net/computing/docs/anti-spam/ 

Sendmail ruleset checks

The following are the sendmail rulesets I use. They are not perfect by any stretch of the imagination. However they work quite well for me. Feel free to stretch, attack, munge, merge, etc the following - just keep an attribution to me.

Get the sendmail.cf directly.

The following sendmail.cf fragment also makes use of a NDBM file to store its configuration data. The comments to that file are:


Comments to NDBM file
01   ##    
02   ## The Anti-Spam data. This file is made up of key-value pairs. The keys are    
03   ## values which can be matched against in the various rulesets. The values    
04   ## contain the data relating to how the key should be treated. Values are:    
05   ##    
06   ## +-------------+--------------+---------------------------------------------+   
07   ## |   Value     |   Ruleset    | The key is...                               |  
08   ## +-------------+--------------+---------------------------------------------+   
09   ## | BLOCK_IP    | check_relay  | IP address which should be blocked          |  
10   ## | BLOCK_HOST  | check_relay  | Hostname or domain which should be blocked  |   
11   ## | SPAM_EMAIL  | check_mail   | Spammer EMail address                       |  
12   ## | ALLOW_EMAIL | check_mail   | An EMail address which is allowed through   |  
13   ## | ALLOW_HOST  | check_mail   | A domain or host which is allowed through   |  
14   ## | KILL_EMAIL  | check_mail   | An EMAil address which is blocked           |  
15   ## +-------------+--------------+---------------------------------------------+   
16   ## | SPAM_CLIENT | check_mail   | Hostname or domain which is not allowed to  |   
17   ## |             |              | send mail as a client to server.            |   
18   ## +-------------+--------------+---------------------------------------------+   
19   ## | SPAM_IP     | check_mail   | IP address which is blocked for spamming    |   
20   ## |             | check_rcpt   |                                             |   
21   ## +-------------+--------------+---------------------------------------------+   
22   ## | SPAM_HOST   | check_mail   | Hostname or domain which is blocked for     |   
23   ## |             | check_rcpt   | spamming                                    |   
24   ## +-------------+--------------+---------------------------------------------+   
25   ## | RELAY       | check_mail   | Domain which we will relay to               |   
26   ## |             | check_rcpt   |                                             |   
27   ## |             | check_compat |                                             |   
28   ## |             | removelocal  |                                             |   
29   ## +-------------+--------------+---------------------------------------------+   
30   ## | NO_EXTRN    | check_mail   | Client does not get passed by the external  |   
31   ## |             |              | checks                                      |   
32   ## +-------------+--------------+---------------------------------------------+   
33   ## | LOCAL_IP    | check_mail   | Local IP addresses                          |   
34   ## |             | check_rcpt   |                                             |   
35   ## +-------------+--------------+---------------------------------------------+   
36   ## | LOCAL_HOST  | check_mail   | Local hostnames                             |   
37   ## |             | check_rcpt   |                                             |   
38   ## +-------------+--------------+---------------------------------------------+   
39   ## | RELAY_HOST  | check_rcpt   | Hostname or domain which can relay through  |  
40   ## |             |              | us                                          |   
41   ## +-------------+--------------+---------------------------------------------+   
42   ## | RELAY_IP    | check_rcpt   | IP address which can relay through us       |  
43   ## +-------------+--------------+---------------------------------------------+   
44   ##   

And finally we have the Anti-Spam sendmail.cf fragments


Fragments of sendmail.cf
001   ####  
002   ## The Anti-Spam and general blocking stuff  
003   ####  
004      
005   ## The NDBM file used for the blocking rulesets  
006   KSpam dbm -o /usr/local/mail/maps/AntiSpam  
007      
008   ## Web page for info on the rulesets  
009   D{WebPage}" - see http://www.bpfh.net/spam/"  
010      
011   ####  
012   ## Handle the -bt mode for rules which use $| as a separator. We need  
013   ## this as can't put in $| when using -bt.  
014   ##  
015   ##  % sendmail -bt -d21.12  
016   ##  ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)  
017   ##  Enter <ruleset> <address>  
018   ##  > Start,check_compat <sender> $| <recipient>  
019   ##  
020   ####  
021   SStart  
022   R$* $$| $*                      $: $1 $| $2  
023      
024      
025   #####  
026   ###  
027   ### The following are the anti-spam and general blocking rules.  
028   ### These use a single map (currently an NDBM file) which has hosts,  
029   ### domains and IP addresses as its key. The values are the action  
030   ### to be performed on the key value. These include things like  
031   ### allowing relaying to a domain, if the EMail is from a spammer, etc.  
032   ###  
033   #####  
034      
035   #####  
036   ###  
037   ### First we have the general utility functions used by some or all  
038   ### of the actual rulesets  
039   ###  
040   #####  
041      
042   ####  
043   ## Handle the anti-spam messages in one place. This ruleset takes  
044   ## the message type (see comp_value) and any args. The args depend  
045   ## on the message type.  
046   ####  
047   SSpamMsg  
048   RRELAY $| $*                    $#error $: " 550 we do not support relaying " $1 " " $(dequote "" $&{client_name} $) " [" $(dequote "" $&{client_addr} $) "] " $&{WebPage} " [RELAY]"  
049   RBLOCKED                        $#error $: " 550 Your site " $(dequote "" $&{client_name} $) " [" $(dequote "" $&{client_addr} $) "] is blocked " $&{WebPage} " [BLOCKED]"  
050   RSPAM_CLIENT                    $#error $: " 550 Your site " $(dequote "" $&{client_name} $) " [" $(dequote "" $&{client_addr} $) "] is blocked - use your ISP provided relay " $&{WebPage} " [SPAM_CLIENT]"  
051   RNOACCEPT                       $#error $: " 550 We do not accept mail from you "$(dequote "" $&{client_name} $) " [" $(dequote "" $&{client_addr} $) "] " $&{WebPage} " [NOACCEPT]"  
052   RDIALUP                         $#error $: " 550 We do not accept mail from you "$(dequote "" $&{client_name} $) " [" $(dequote "" $&{client_addr} $) "] as you appear to be a dialup host " $&{WebPage} " [DIALUP]"  
053   RSPAMMER $| $*                  $#error $: " 550 We do not accept mail from spammers " $1 " " $&{WebPage} " [SPAMMER]"  
054   RKILL_EMAIL $| $*               $#error $: " 550 We do not accept mail from you " $1 " for a reason other than spamming " $&{WebPage} " [KILL_EMAIL]"  
055   RSPAM $| $*                     $#error $: " 550 We do not accept mail from " $1 $(dequote "" $&{client_name} $) " [" $(dequote "" $&{client_addr} $) "] " $&{WebPage} " [SPAM]"  
056   RSPECIAL $| $* $| $*                    $#error $: " 550 Mail from " $1 " must come from a machine in the " $2 " domain, not from " $(dequote "" $&{client_name} $) " [" $(dequote "" $&{client_addr} $) "] " $&{WebPage} " [SPECIAL]"  
057   RNO_DNS $| $*                   $#error $: " 550 We do not accept mail from domains which do not resolve (domain: " $1 ") " $(dequote "" $&{client_name} $) " [" $(dequote "" $&{client_addr} $) "] " $&{WebPage} " [NO_DNS]"  
058   REXT_MAPS                       $#error $: 550 " Mail from " $(dequote "" $&{client_addr} $) " refused by MAPS, see http://mail-abuse.org/cgi-bin/lookup?" $&{client_addr} " " $&{WebPage} " [EXT_MAPS]"  
059   REXT_MAPS_DUL                   $#error $: 550 " Mail from " $(dequote "" $&{client_addr} $) " refused by MAPS DUL, see http://mail-abuse.org/dul/ " $&{WebPage} " [EXT_MAPS_DUL]"  
060   REXT_RSS                        $#error $: 550 " Mail from " $(dequote "" $&{client_addr} $) " refused by RSS, see http://www.mail-abuse.org/cgi-bin/nph-rss?" $&{client_addr} " " $&{WebPage} " [EXT_RSS]"  
061   REXT_ORBS                       $#error $: 550 " Mail from " $(dequote "" $&{client_addr} $) " refused by ORBS, see http://www.orbs.org/" " " $&{WebPage} " [EXT_ORBS]"  
062   REXT_IMRSS                      $#error $: 550 " Mail from " $(dequote "" $&{client_addr} $) " refused byt IMRSS, see http://www.imrss.org/error.html " $&{WebPage} " [EXT_IMRSS]"  
063   REXT_DSSL                       $#error $: 550 " Mail from " $(dequote "" $&{client_addr} $) " refused by IMRSS DSSL, see http://www.imrss.org/dssl/unblock.html " $&{WebPage} " [EXT_DSSL]"  
064   REXT_SPEWS                      $#error $: 550 " Mail from " $(dequote "" $&{client_addr} $) " refused by SPEWS, see http://www.spews.org/" " " $&{WebPage} " [EXT_SPEWS]"  
065   REXT_SPAMSITES                  $#error $: 550 " Mail from " $(dequote "" $&{client_addr} $) " refused by SpamSites, see http://www.spamsites.org/" " " $&{WebPage} " [EXT_SPAMSITES]"  
066   REXT_RSL                        $#error $: 550 " Mail from " $(dequote "" $&{client_addr} $) " refused by RSL, see http://relays.visi.com/" " " $&{WebPage} " [EXT_RSL]"  
067   REXT_SBL                        $#error $: 550 " Mail from " $(dequote "" $&{client_addr} $) " refused by SBL, see http://www.spamhaus.org/SBL" " " $&{WebPage} " [EXT_SBL]"  
068   REXT_ORDB                       $#error $: 550 " Mail from " $(dequote "" $&{client_addr} $) " refused by ORDB, see http://www.ordb.org/" " " $&{WebPage} " [EXT_ORDB]"  
069   REXT_MONKEY_FORM                        $#error $: 550 " Mail from " $(dequote "" $&{client_addr} $) " refused by Monkey FormMail, see http://www.monkeys.com/anti-spam/filtering/formmail.html" " " $&{WebPage} " [EXT_MONKEY_FORM]"  
070   REXT_MONKEY_PROXIES                     $#error $: 550 " Mail from " $(dequote "" $&{client_addr} $) " refused by Monkey proxie list, see http://www.monkeys.com/anti-spam/filtering/proxies.html" " " $&{WebPage} " [EXT_MONKEY_PROXIES]"  
071   REXT_DSBL_LIST                  $#error $: 550 " Mail from " $(dequote "" $&{client_addr} $) " refused by DSBL list, see http://www.dsbl.org/" " " $&{WebPage} " [EXT_DSBL_LIST]"  
072   REXT_DSBL_MULTIHOP                      $#error $: 550 " Mail from " $(dequote "" $&{client_addr} $) " refused by DSBL multi-hop list, see http://www.dsbl.org/" " " $&{WebPage} " [EXT_DSBL_MULTIHOP]"  
073   RBADARGS $| $*                  $#error $: 554 internal error in the $1 ruleset - contact postmaster@bpfh.net [BADARGS]  
074   R$*                             $#error $: 554 internal error in the SpamMsg ruleset was passed $1 - contact postmaster@bpfh.net [INTERNAL ERROR]  
075      
076   ####  
077   ## Compare values from the Anti-Spam rulesets. Yes, this *is* a  
078   ## kludge. If there is an easier way to do (foo == bar) then I'd  
079   ## like to hear it.  
080   ####  
081   Scomp_value  
082   RBLOCK_IP $| BLOCK_IP           $@ BLOCK_IP  
083   RBLOCK_HOST $| BLOCK_HOST       $@ BLOCK_HOST  
084   RSPAM_CLIENT $| SPAM_CLIENT     $@ SPAM_CLIENT  
085   RSPAM_EMAIL $| SPAM_EMAIL       $@ SPAM_EMAIL  
086   RSPAM_IP $| SPAM_IP             $@ SPAM_IP  
087   RSPAM_HOST $| SPAM_HOST         $@ SPAM_HOST  
088   RRELAY $| RELAY                 $@ RELAY  
089   RNO_EXTRN $| NO_EXTRN           $@ NO_EXTRN  
090   RLOCAL_IP $| LOCAL_IP           $@ LOCAL_IP  
091   RLOCAL_HOST $| LOCAL_HOST       $@ LOCAL_HOST  
092   RRELAY_HOST $| RELAY_HOST       $@ RELAY_HOST  
093   RRELAY_IP $| RELAY_IP           $@ RELAY_IP  
094   RALLOW_EMAIL $| ALLOW_EMAIL     $@ ALLOW_EMAIL  
095   RALLOW_HOST $| ALLOW_HOST       $@ ALLOW_HOST  
096   RKILL_EMAIL $| KILL_EMAIL       $@ KILL_EMAIL  
097   R$* $| $*                       $@ NO_COMPARE  
098      
099   ####  
100   ## Handle looking at domains within the AntiSpam map. This takes the  
101   ## domain and the required value as domain $| value. This returns  
102   ## either NO_COMPARE on failure or one of the results in comp_value  
103   ## if a match occurs. This performs a recursive check, ie the name  
104   ## foo.bar.com will match if the bar.com domain is in the map.  
105   ####  
106   Slookat_domain  
107   R$* . $| $*                     $: $1 $| $2  
108   R$*.dialup.$* $| DIALUP         $@ DIALUP  
109   Rdialup.$* $| DIALUP            $@ DIALUP  
110   R$* $| $*                       $: $(Spam $1 $:NOMATCH $| $1 $) $| $2  
111   RNOMATCH $| $+ . $* $| $*       $: $>lookat_domain $2 $| $3  
112   R$* $| $*                       $@ $>comp_value $1 $| $2  
113      
114   ####  
115   ## Handle looking at IP addresses within the AntiSpam map. This takes  
116   ## the IP and the required value as domain $| value. This returns  
117   ## either NO_COMPARE on failure or one of the results in comp_value if  
118   ## a match occurs. This performs a recursive check, ie the IP address  
119   ## "193.43.45.3" will match if the address "193" is in the map.  
120   ####  
121   Slookat_ip  
122   R$* $| $*                       $: $(Spam $1 $:NOMATCH $| $1 $) $| $2  
123   RNOMATCH $| $+.$+.$+.$+ $| $*   $: $>lookat_ip $1.$2.$3 $| $5  
124   RNOMATCH $| $+.$+.$+ $| $*      $: $>lookat_ip $1.$2 $| $4  
125   RNOMATCH $| $+.$+ $| $*         $: $>lookat_ip $1 $| $3  
126   R$* $| $*                       $@ $>comp_value $1 $| $2  
127      
128   ####  
129   ## Handle looking at an EMail address. This means taking off trailing  
130   ## "."s, surroundding "<" & ">", etc. Returns either NO_COMPARE on  
131   ## failure or one of the results of comp_value if a match occurs.  
132   ####  
133   Slookat_email  
134   R<$*> $| $*                     $: $1 $| $2  
135   R$* . $| $*                     $: $1 $| $2  
136   R$* $| $*                       $: $(Spam $1 $:NOMATCH $| $1 $) $| $2  
137   RNOMATCH $| $* $| $*            $@ NO_COMPARE  
138   R$* $| $*                       $@ $>comp_value $1 $| $2  
139      
140      
141   #####  
142   ###  
143   ### Now we have the actual rulesets which sendmail calls when doing  
144   ### things like:  
145   ###  
146   ###  o Having a host connection (check_relay)  
147   ###  o Getting a MAIL FROM: (check_mail)  
148   ###  o Getting an RCPT TO: (check_rcpt)  
149   ###  o After a message has been full received (check_compat)  
150   ###  
151   ### The above are in the order the checking occurs as well.  
152   ###  
153   #####  
154      
155   ####  
156   ## check_compat - this gets both the sender and recipient addresses  
157   ## as parameters. However this is called *after* the entire message  
158   ## has been recieved so its very much the ruleset of last resort.  
159   ##  
160   ## We also allow local hosts to send mail with any sender address  
161   ## from any recipient address. This is *only* done because I know  
162   ## the small number of people who use the local addresses personally  
163   ## I know that they will not spam. In situations where this is not  
164   ## the case (ie if there is doubt that the end lusers will spam or  
165   ## not) then you'll probably want to comment those lines out.  
166   ##  
167   ## Called as: check_compat <sender> $| <recipient>  
168   ## Test with: Start,check_compat <sender> $| <recipient>  
169   ##  
170   ## It should be noted that this ruleset doesn't deal with something like  
171   ##  
172   ##  check_compat <spammer%spam.net@mailhost> $| <victim%innocent.com@mailhost>  
173   ##  
174   ## However the above *is* dealt with by the check_rcpt ruleset correctly. I  
175   ## should probably rework this ruleset to also handle this. When I actually  
176   ## have free time that is (yeah, *right*. As if that will ever happen)  
177   ##  
178   ####  
179   Scheck_compat  
180   R$* $| $*                       $: <$1> $| <$2>  
181   R<<$*>> $| $*                   $: <$1> $| $2  
182   R$* $| <<$*>>                   $: $1 $| <$2>  
183   R<$* @ $*> $| $*                $: <$1@$2> $| $3 $| $>lookat_domain $2 $| RELAY  
184   R<> $| <$* @ $*>                $: <> $| <$1@$2> $| $>lookat_domain $2 $| RELAY  
185   R$* $| <$* @ $*> $| NO_COMPARE  $: $1 $| <$2@$3> $| $>lookat_domain $3 $| RELAY  
186   R$* $| $* $| RELAY              $@ OK  
187   R$* $| $* $| $*                 $: $1 $| $2  
188   R$+ $| $+                       $: $2 $| $>3 $1 canonicalize sender  
189   R$+ $| $+                       $: $2 $| $>3 $1 canonicalize recipient  
190   R$- $| $+                       $@ OK           from here  
191   R$+ $| $-                       $@ OK           to here  
192   R$+<@$=w.> $| $+                $@ OK           from here  
193   R$+ $| $*<@$=w.>                $@ OK           to here  
194   R$+<@$*> $| $*<@$*>             $: <$1@$2> $| <$3@$4>  
195   ##  
196   ## The following three lines enable local addresses to send mail using  
197   ## any sender or recipient address they wish to. See the notes above  
198   ## for the dangers of this.  
199   ##  
200   R$* $| $*                       $: $1 $| $2 $| $&{client_addr}  
201   R$* $| $* $| $*                 $: $1 $| $2 $| $>lookat_ip $3 $| LOCAL_IP  
202   R$* $| $* $| LOCAL_IP           $@ OK  
203   R$* $| $* $| $*                 $: $1 $| $2 $| $&{client_name}  
204   R$* $| $* $| $*                 $: $1 $| $2 $| $>lookat_domain $3 $| LOCAL_HOST  
205   R$* $| $* $| LOCAL_HOST         $@ OK  
206   ##   
207   ## If we're here then its a relay attempt - so block it. Without these  
208   ## lines the check_compat ruleset is essentially useless.  
209   ##  
210   R$* $| $* $| $*                 $@ $> SpamMsg RELAY $| $1  
211   R$* $| $*                       $@ $> SpamMsg RELAY $| $1  
212      
213   ####  
214   ## check_relay - this is called when a client connects to the server  
215   ## and is given the hostname and IP address of the client separated by a  
216   ## $|. Although the name suggests otherwise, this can not be used for  
217   ## stopping unauthorized relaying - check_rcpt and check_compat are used  
218   ## for that. It can be used for TCP Wrapper-like access controls. Any  
219   ## access (ie any bits of (E)SMTP protocol except for QUIT, HELO, EHLO and  
220   ## NOOP) will be refused with a "500 Access denied".  
221   ##  
222   ## Called as: check_relay client_name $| client_addr  
223   ####  
224   Scheck_relay  
225   R$* $| $*                       $: $1 $| $2 $| $>lookat_domain $1 $| BLOCK_HOST  
226   R$* $| $* $| BLOCK_HOST         $@ $> SpamMsg BLOCKED  
227   R$* $| $* $| $*                 $: $1 $| $2 $| $>lookat_ip $2 $| BLOCK_IP  
228   R$* $| $* $| BLOCK_IP           $@ $> SpamMsg BLOCKED  
229   R$*                             $@ OK  
230      
231   ####  
232   ## check_rcpt - called when an RCPT TO: <> is issued by the client. This  
233   ## gets the address given by the client. This is used to prevent  
234   ## unauthorized relaying by looking at the address and seeing if it is  
235   ## local or not. If the address is not and not in the RelayTo map then  
236   ## the address is disallowed.  
237   ##  
238   ## Called as: check_rcpt <recipient>  
239   ####  
240   Scheck_rcpt  
241   ####  
242   ## First things first - see if someone is trying to relay via us  
243   R$+                             $: $&{client_addr} $| $1  
244   R0 $| $*                        $@ OK  
245   ## Local IP address ?  
246   R$* $| $*                       $: $2 $| $>lookat_ip $1 $| LOCAL_IP  
247   R$* $| LOCAL_IP                 $@ OK  
248   R<$*@$*> $| $*                  $: $1@$2 $| $3  
249   R$*@$* $| $*                    $: <$1@$2> $| $3  
250   ## Do we accept this domain ?  
251   R<$*@$*> $| $*                  $: <$1@$2> $| $>lookat_domain $2 $| RELAY  
252   R$* $| RELAY                    $@ OK  
253   ## Hmmmm... not one we're explicitly relaying...  
254   R$* $| $*                       $: $>3 $1  
255   # Remove the local part  
256   R$+                             $:$>removelocal $1  
257   # If anything non-local is here then its a relay attempt  
258   # ... so we first see if an allowed host or network is doing it  
259   R$*<@$+>$*                      $: <$1@$2> $| $>lookat_domain $&{client_name} $| RELAY_HOST  
260   R<$*> $| RELAY_HOST             $@ OK  
261   R<$*> $| $*                     $: <$1> $| $>lookat_domain $&{client_name} $| RELAY_IP  
262   R<$*> $| RELAY_IP               $@ OK  
263   # We've got through that so anything non-local is a relay attempt  
264   R<$*> $| $*                     $@ $> SpamMsg RELAY $| "to <" $1 ">"  
265   # All is fine - accept the RCPT TO:  
266   # It should be noted that the host and IP address checks do not need to be  
267   # performed - they are done in check_mail  
268   R$*                             $@ OK  
269      
270   ####  
271   ## removelocal - remove any local bits of the address.  
272   ## Used by check_rcpt  
273   ####  
274   Sremovelocal  
275   R$*<@$=w.>$*                    $: $>removelocal $>3 $1 $3  
276   R$*<@$*>$*                      $@ $1<@$2>$3  
277   # dequote local part  
278   R$-                             $: $>3 $(dequote $1 $)  
279   R$*<@$*>$*                      $: $>removelocal $1<@$2>$3  
280      
281      
282   ####  
283   ## Special case for usa.com.  
284   ##  If it comes from usa.com mail servers then it passes  
285   ####  
286   SSpecialUsaCom  
287   R$* $| $*.usa.com               $@ OK  
288   R$* $| $*                       $@ $> SpamMsg SPECIAL $| $1 $| usa.com  
289      
290   ####  
291   ## Special case for Yahoo.com.  
292   ##  If it comes from yahoo.com mail servers then it passes  
293   ####  
294   SSpecialYahoo  
295   R$* $| $*.yahoo.com             $@ OK  
296   R$* $| onion.valueclick.com     $@ OK  
297   R$* $| $*                       $@ $> SpamMsg SPECIAL $| $1 $| yahoo.com  
298      
299   ####  
300   ## Special case for Hotmail.com.  
301   ##  If it comes from hotmail.com mail servers then it passes  
302   ####  
303   SSpecialHotmail  
304   R$* $| $*.hotmail.com           $@ OK  
305   R$* $| onion.valueclick.com     $@ OK  
306   R$* $| $*.parasolsolutions.com  $@ OK  
307   R$* $| $*                       $@ $> SpamMsg SPECIAL $| $1 $| hotmail.com  
308      
309   ####  
310   ## Special case for aol.com.  
311   ##  If it comes from hotmail.com mail servers then it passes  
312   ####  
313   SSpecialAol  
314   R$* $| $*.aol.com               $@ OK  
315   R$* $| $*                       $@ $> SpamMsg SPECIAL $| $1 $| aol.com  
316      
317   ####  
318   ## Special case for aol.co.uk.  
319   ##  If it comes from AOL mail servers then it passes  
320   ####  
321   SSpecialAolUk  
322   R$* $| $*.aol.co.uk             $@ OK  
323   R$* $| $*.aol.com               $@ OK  
324   R$* $| $*                       $@ $> SpamMsg SPECIAL $| $1 $| aol.co.uk  
325      
326   ####  
327   ## Special case for Lycos  
328   ##  If it comes from lycos.com mail servers then it passes  
329   ####  
330   SSpecialLycos  
331   R$* $| $*.lycos.com             $@ OK  
332   R$* $| $*                       $@ $> SpamMsg SPECIAL $| $1 $| lycos.com  
333      
334   ####  
335   ## check_mail - called when the client issues a MAIL FROM: <> command. This  
336   ## calls the external checks like MAPS RBL, ORBS, etc. It also blocks on the  
337   ## sender mail address.  
338   ##  
339   ## Called as: check_mail <sender>  
340   ####  
341   Scheck_mail  
342   # First we see if this is a local host - if so its always trusted  
343   R$*                             $: $1 $| $>lookat_ip $&{client_addr} $| LOCAL_IP  
344   R$* $| LOCAL_IP                 $@ OK  
345   R$* $| $*                       $: $1 $| $>lookat_domain $&{client_name} $| LOCAL_HOST  
346   R$* $| LOCAL_HOST               $@ OK  
347   # Now see if is it a short-circuit domain  
348   R$* $| $*                       $: $1 $| $>lookat_email $1 $| ALLOW_EMAIL  
349   R$* $| ALLOW_EMAIL              $@ OK  
350   # Now let us see if the sender is a known spammer  
351   R$* $| $*                       $: $1 $| $>lookat_email $1 $| SPAM_EMAIL  
352   R$* $| SPAM_EMAIL               $@ $> SpamMsg SPAMMER $| <$1>  
353   # Do we just kill this EMail ?  
354   R$* $| $*                       $: $1 $| $>lookat_email $1 $| KILL_EMAIL  
355   R$* $| KILL_EMAIL               $@ $> SpamMsg KILL_EMAIL $| <$1>  
356   R<> $| $*                       $: <<NULL>> $| $1  
357   R<$*> $| $*                     $: $1 $| $2  
358   ####  
359   ## Special cases  
360   ####  
361   R$*@usa.com $| $*               $@ $> SpecialUsaCom $1@usa.com $| $&{client_name}  
362   R$*@yahoo.com $| $*             $@ $> SpecialYahoo $1@yahoo.com $| $&{client_name}  
363   R$*@hotmail.com $| $*           $@ $> SpecialHotmail $1@hotmail.com $| $&{client_name}  
364   R$*@aol.com $| $*               $@ $> SpecialAol $1@aol.com $| $&{client_name}  
365   R$*@aol.co.uk $| $*             $@ $> SpecialAolUk $1@aol.co.uk $| $&{client_name}  
366   R$*@lycos.com $| $*             $@ $> SpecialLycos $1@lycos.com $| $&{client_name}  
367   ####  
368   ## Start to look at the domain  
369   R$*@$* $| $*                    $: $2  
370   # Do we allow the domain through ?  
371   R$*                             $: $1 $| $>lookat_domain $1 $| ALLOW_HOST  
372   R$* $| ALLOW_HOST               $@ OK  
373   # Is it a known spam domain ?  
374   R$* $| $*                       $: $1 $| $>lookat_domain $1 $| SPAM_HOST  
375   R$* $| SPAM_HOST                $@ $> SpamMsg SPAM $| $1  
376   # Does the DNS resolve - if it doesn't reject it. We try to resolve the name  
377   # a couple of times here to deal with slow resolution.  
378   R$* $| $*                       $: $1  
379   R$* .                           $: $1  
380   R$*                             $: $1 $| GOT_DOMAIN  
381   R$* $| GOT_DOMAIN               $: $[ $1 $] $| DNS_FAIL  
382   R$* . $| $*                     $: $1 $| DNS_OKAY  
383   R$* $| $*                       $: $[ $1 $] $| DNS_FAIL  
384   R$* . $| $*                     $: $1 $| DNS_OKAY  
385   R$* $| $*                       $: $[ $1 $] $| DNS_FAIL  
386   R$* . $| $*                     $: $1 $| DNS_OKAY  
387   R<NULL> $| $*                   $: <NULL> $| DNS_OKAY  
388   R$* $| DNS_FAIL         $@ $> SpamMsg NO_DNS $| $1  
389   ##  
390   ## We now switch from looking at the domain name given in the MAIL TO to  
391   ## looking at the name and network address of the client which actually sent  
392  &n