| Current File : //var/dcc/libexec/hackmc |
#! /bin/sh -e
# This kludge of a shell script warps a sendmail.cf produced from a .mc file
# to report some spam to the Distributed Checksum Clearinghouse (DCC)
# in addition to rejecting it.
#
# Mail that is rejected by a sendmail access_db is reported via dccm to
# a DCC server as extremely bulky or spam. Error messages in the access_db
# file must start with "DCC:" or they will be ignored by this mechanism.
# This script should be run in the sendmail cf/cf directory, and given a list
# of .mc files, as in
# cd cf/cf
# .../misc/hackmc -AROT ../m4/cf.m4 local.mc > local.cf
# It seems to work on sendmail.cf generated for sendmail versions 8.11
# through 8.14.3. There is no guarantee that it will work with other
# versions. You must compare the result of this script with the unmodified
# sendmail.cf.
# This script "denatures" RCS keywords in its output so that revisions of
# the resulting sendmail.cf can be archived with RCS without losing
# the original RCS lines from the Sendmail organization.
# In addition to sending mail blacklisted by the sendmail access_db to DCC,
# the following can also be turned on:
# -x turn on debugging
# -A send mail with bogus Mail_From domain names to DCC with a count of
# "many" instead of only rejecting it. See -M.
# -R silently discard unauthorized relay attempts after reporting them
# to the DCC. This mechanism also implies -f to ensure that relay
# attempts do not leak if dccm is not running.
# -r reject unauthorized relay attempts after reporting them
# to the DCC. This mechanism also implies -f to ensure that relayed
# attempts do not leak if dccm is not running.
# -D add a local rule that rejects mail from SMTP clients without reverse
# DNS and reports the mail as spam to the DCC.
# This has a fairly high false positive rate.
# -O modify the sendmail rules to treat access_db "OK" and "RELAY"
# or "Spam:...FRIEND" entries as whitelisting the message.
# -M modify the sendmail rules generated by FEATURE(badmx), FEATURE(dnsbl),
# FEATURE(enhdnsbl), FEATURE(block_bad_helo) so that mail rejected by
# sendmail is reported via dccm to DCC with a count of "many".
# See -A.
# -T modify the sendmail rules to trust (whitelist) mail from users
# authenticated with an SMTP AUTH TRUST_AUTH_MECH() mechanism or from
# SMTP clients with certificates verified with START TLS. See -U
# If STMP-AUTH used, TRUST_AUTH_MECH must be set in the .mc file and
# sendmail must be built with SASL or otherwise have working SMTP auth.
# -U modify the sendmail rules to trust (whitelist) mail from users
# authenticated with an SMTP AUTH TRUST_AUTH_MECH() mechanism.
# SMTP clients with certificates verified with START TLS are not trusted
# See -T. TRUST_AUTH_MECH must be set in the .mc file and
# sendmail must be built with SASL or otherwise have working SMTP auth.
# -f if dccm fails, reject mail with a temporary failure status code
# instead of passing it. This changes the default FEATURE(dcc)
# parameters. See dcc.m4.
# -m m4
# specifies the path to the m4 program as well as any m4 args
# such as `hackmc -m "/usr/bin/m4 -D_CF_DIR_=/usr/share/sendmail/cf/"`
# Copyright (c) 2012 by Rhyolite Software, LLC
#
# This agreement is not applicable to any entity which sells anti-spam
# solutions to others or provides an anti-spam solution as part of a
# security solution sold to other entities, or to a private network
# which employs the DCC or uses data provided by operation of the DCC
# but does not provide corresponding data to other users.
#
# Permission to use, copy, modify, and distribute this software without
# changes for any purpose with or without fee is hereby granted, provided
# that the above copyright notice and this permission notice appear in all
# copies and any distributed versions or copies are either unchanged
# or not called anything similar to "DCC" or "Distributed Checksum
# Clearinghouse".
#
# Parties not eligible to receive a license under this agreement can
# obtain a commercial license to use DCC by contacting Rhyolite Software
# at sales@rhyolite.com.
#
# A commercial license would be for Distributed Checksum and Reputation
# Clearinghouse software. That software includes additional features. This
# free license for Distributed ChecksumClearinghouse Software does not in any
# way grant permision to use Distributed Checksum and Reputation Clearinghouse
# software
#
# THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE, LLC DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE, LLC
# BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
# ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# Rhyolite Software DCC 1.3.152-1.49 $Revision$
USAGE="`basename $0`: [-xfARrDOMTU] [-m m4] file1.mc file2.mc ..."
M4=m4
DNS1='#'
DNS2='#'
RELAY='#'
NOTSPAM='#'
TLS='#'
AUTH='#'
# fail temporarily if dccm is not running.
# Add F=T to reject mail when dccm is dead,
# but only if there is not already an F=x setting
TEMPFAIL='#'
TEMPFAIL0='/F=/!s/S=[^ ,]*/&, F=T/'
RDNS='#'
ISSPAM1='#'
ISSPAM2='#'
ISSPAM3='#'
while getopts "xm:fARrDOMTU" c; do
case $c in
x) set -x;;
m) M4="$OPTARG";;
f) TEMPFAIL=$TEMPFAIL0;;
A)
DNS1='s/$#error $@ \([.0-9]*\) $: "\(5.*[Dd]omain name required.*\)/$# $(macro {dcc_isspam} $@ "\1 \2" Sent to DCC" $) TODCC/'
DNS2='s/$#error $@ \([.0-9]*\) $: "\(5.*Domain of sender.*\)/$# $(macro {dcc_isspam} $@ "\1 \2" Sent to DCC" $) TODCC/'
;;
R)
# dccm expects to see "DISCARD: Relaying denied"
RELAY='s/$#error $@ [.0-9]* $: "5[.0-9 ]*\(Relaying denied.*\)/$# $(macro {dcc_isspam} $@ "DISCARD: \1" Sent to DCC" $) TODCC/'
TEMPFAIL=$TEMPFAIL0
;;
r)
# dccm expects to see "REJECT: Relaying denied"
RELAY='s/$#error $@ [.0-9]* $: "5[.0-9 ]*\(Relaying denied.*\)/$# $(macro {dcc_isspam} $@ "REJECT: \1" Sent to DCC" $) TODCC/'
TEMPFAIL=$TEMPFAIL0
;;
D) RDNS=
;;
M)
ISSPAM1='/^# DNS based IP address spam list/,/^$/s/$#error .* $: *"\(.*\)/$@ $(macro {dcc_isspam} $@ "\1" Sent to DCC" $) TODCC/'
ISSPAM2='s/$#error .* $: *"\(.*MX record.*\)/$@ $(macro {dcc_isspam} $@ "\1" Sent to DCC" $) TODCC/'
ISSPAM3='s/$#error .* $: *"\(.*bogus HELO.*\)/$: $(macro {dcc_isspam} $@ "\1" Sent to DCC" $) $1/'
;;
T) TLS=
;;
U) AUTH=
;;
O) NOTSPAM='s/^R<\$={Accept}> *<*\$\*>* *[^ ]*/& $(macro {dcc_notspam} $@ $1 $)/'
;;
*) echo 1>&2 "$USAGE"; exit 1;;
esac
done
ARGS="$0 $*"
shift `expr $OPTIND - 1 || true`
(
if test -z "$RDNS"; then
# add -D rules
cat <<'EOF'
LOCAL_RULESETS
# reject mail from clients without reverse DNS and report it as spam to DCC
SLocal_check_relay
R$* $: <$&{client_resolve}> $1
R<FAIL> $* $# $(macro {dcc_isspam} $@ "SMTP client "$&{client_addr}" has no reverse DNS name" $) TODCC
R<$*> $* $: $2
EOF
fi
if test -z "$AUTH" -o -z "$TLS"; then
# add -T or -U rules
cat <<'EOF'
LOCAL_RULESETS
SLocal_check_rcpt
EOF
if test -z "$TLS"; then
cat <<'EOF'
# mail from an SMTP client with a verified TLS cert is not spam for dccm
R$* $: <$&{verify}> $1
R<OK> $* $: $(macro {dcc_notspam} $@ "STARTTLS verified" $) <OK> $1
EOF
fi
cat <<'EOF'
# mail authenticated with SMTP AUTH is not spam for dccm
R<$*> $* $: <$&{auth_type}> $2
R<$={TrustAuthMech}> $* $: $(macro {dcc_notspam} $@ "SMTP AUTH by "$1 $) <$1> $2
R<$*> $* $: $2
EOF
fi
) | $M4 $* - \
| sed -e '# remove '$' from Id and Revision RCS keywords' \
-e 's/\$\(Id:.*\)\$/\1/' -e 's/\$\(Revision:.*\)\$/\1/' \
\
-e '# document ourself in the output' \
-e '/^#[ #]*dcc.m4/a\
##### built by: '"$ARGS" \
\
-e '# add -M rules for bogus Mail_From domain names' \
-e "${DNS1}" -e "${DNS2}" \
\
-e '# add -R and -R rules for bogus Mail_From domain names' \
-e "${RELAY}" \
\
-e '# add -O rules to honor access_db OK, Relay, etc. ' \
-e "${NOTSPAM}" \
\
-e '# add -M rules for badmx dnsbl enhdnsbl block_bad_helo' \
-e "${ISSPAM1}" -e "${ISSPAM2}" -e "${ISSPAM3}" \
\
-e "# adjust DCC milter flags for -r and -R" \
-e '/^Xdcc/{' -e "$TEMPFAIL" -e '}' \
\
-e '# add the access.db hook' \
-e '/^R<$={Accept}>/a\
R<DCC:$={Accept}> $* $@ $1 $(macro {dcc_notspam} $@ $1 $) \
R<DCC:$*> <$*> $# TODCC $(macro {dcc_isspam} $@ $1": Sent to DCC" $)' \
\
-e '# remove extra quotes' \
-e'/TODCC/s/""//'