divert(-1) # # Copyright (c) 1996,1997 Claus Assmann # # In short: you can do whatever you want with this, but don't blame me! # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. #============================================================ # WARNING: this is an experimental version! # Don't use it on a production machine! # It is intended to provide new features, some of which violate RFCs! # It is supposed as a release for discussion and testing. # This version provides an option to check _all_ part of an address: # _CHECK_ALL_PARTS_ #============================================================ ifndef(`_ERR_MSG_DOM_',define(`_ERR_MSG_DOM_',`"550 This domain is banned, contact your local admin."') ifndef(`_ERR_MSG_USER_',define(`_ERR_MSG_USER_',`"550 You are banned, contact your local admin."') divert(0) VERSIONID(`@(#)check_mail-exp.m4 1.0.0 (Claus Assmann) 1997-12-07') PUSHDIVERT(6) ifdef(`_JUNK_DEFINED_RELAY',, # file containing full e-mail addresses of spammers (for check_mail): # spammer@address.domain "Error-Code Error-Text" # spammer@address.domain SPAMMER # or junk domains (for check_mail, check_relay): # junk.domain "Error-Code Error-Text" # junk.domain JUNK # or IP addresses (for check_relay): # D.X.Y.Z "Error-Code Error-Text" # C.X.Y "Error-Code Error-Text" # B.X "Error-Code Error-Text" # A "Error-Code Error-Text" Kjunk ifelse(_ARG_, `', `dbm -a@JUNK /etc/mail/junk', `_ARG_') define(`_JUNK_DEFINED_MAIL',1) ) ifdef(`_ACCEPT_SOME_', Kaccept ifelse(_ACCEPT_SOME_,`1',`dbm -o -a@ACCEPT /etc/mail/accept',`_ACCEPT_SOME_') ) POPDIVERT divert(2) LOCAL_RULESETS # check for junk domain/spammers Sjunk # lookup domain in database R$*<@$+> $:$1<@$(junk $2$)> # exists? return R$*<@JUNK@JUNK> $@$1<@ _ERR_MSG_DOM_ @JUNK> R$*<@$*@JUNK> $@$1<@$2@JUNK> # lookup address in database R$*<@$+> $:$1<@$(junk $1@$2 $:$2$)> # exists? return R$*<@SPAMMER@JUNK> $@$1<@ _ERR_MSG_USER_ @JUNK> R$*<@$*@JUNK> $@$1<@$2@JUNK> # remove one subdomain, try again ifdef(`_CHECK_TOPLEVEL_',dnl R$*<@$-.$+> $: $>junk $1<@$3>, R$*<@$-.$-.$+> $: $>junk $1<@$3.$4>) ifdef(`_CHECK_MAIL_IN_RCPT_',Scheckmail,Scheck_mail) # don't check these R<$*@$=w> $@ OK shortcut # idea from Steven Schultz R<> $: <$n @ $(dequote "" $&{client_name} $) > ifdef(`_ACCEPT_SOME_',dnl # accept some stupid stuff R<$*@$+> $:<$1@$(accept $2 $:$2$)> R<$*@$*@ACCEPT> $@ OK # addition from Yar Tikhiy R<$*@$+> $:<$1@$(accept $1@$2 $:$2$)> R<$*@$*@ACCEPT> $@ OK) ifdef(`_CHECK_FROM_',dnl # mark address R$* $:<@>$1 # is the syntax ok (uses <> and no dot at the end?) R<@><$*@$*$~.> $:<$1@$2$3> # mark still there: error... R<@>$* $#error $@ 5.1.8 $: 550 illegal MAIL FROM $1, # remove at least the dot... R<$*@$*.> <$1@$2>) R$* $: $>3 $1 canonify ifdef(`_CHECK_LOCAL_', # another proposal from Steven Schultz R$- $1 <@ $(dequote "" $&{client_name} $)>, R$- $@ OK) # check FROM part R$* $: $>checkfrom $>3 $1 canonify and check from define(`COMMENT', ifdef(`_DNSRELAY_', `', `#'))dnl # is client_name a real host name? COMMENT`'R$* $: $(dequote "" $&{client_name} $) COMMENT`'R[$+] $#error $@ 4.1.8 $: 451 unresolvable relay host name [$1], check your setup. undefine(`COMMENT')dnl ifdef(`_MAPS_RBL_', R$* $: $(dequote "" $&{client_addr} $) R$-.$-.$-.$- $: $[ $4.$3.$2.$1.rbl.maps.vix.com $] R$-.$-.$-.$-.rbl.maps.vix.com. $#error $@ 4.1.8 $: 451 no access from [$4.$3.$2.$1] see http://maps.vix.com/rbl/) Scheckfrom R$- $@ ok local host # no host without a . in the FQHN ? R$*<@$->$* $#error $@ 5.1.8 $: 551 invalid host name $2, check your configuration. undefine(`COMMENT')dnl define(`COMMENT', ifdef(`_IP_LOOKUP_', `', `#'))dnl # lookup IP address (reverse mapping available?) COMMENT`'R$*<@[$-.$-.$-.$-]>$* $: $1 < @ $[ [ $2.$3.$4.$5 ] $] > $6 ifdef(`_CHECKREGEX_', # check address against checkregex R$* $: $(checkregex $1 $) R@MATCH $#error $@ 5.1.8 $: 550 spam address. go away.) # copy the result of the lookup R$* $:$1 $| $1 # now remove the dot R$* $| $*<@$*.>$* $: $1 $| $2<@$3>$4 # and check the database R$* $| $*<@$*>$* $: $1 $| $>junk $2<@$3> # match: return given error code (rhs of map) R$* $| $*<@$*@JUNK>$* $#error $@ 5.7.1 $: $3 # restore original value (after canonicalization by ruleset 3) R$* $| $* $: $1 undefine(`COMMENT')dnl define(`COMMENT', ifdef(`_DNSVALID_', `', `#'))dnl # this is dangerous! no real name COMMENT`'R$*<@$*$~P>$* $#error $@ 4.1.8 $: 451 unresolvable host name $2$3, check your setup. undefine(`COMMENT')dnl ifdef(`_CHECK_ALL_PARTS_', # retry for the rest R<@$*>:$+ $: $>checkfrom $>3 $2 R$+<@$*>$* $: $(dequote "" $1 $)<@$2>$3 R$+$=O$+<@$*>$* $: $>checkfrom $>3 $1$2$3)