# Blocking spam with an accept list, version 030131
# Info at
http://angel.net/~nic/spam-x.html
# Customize all these constants:
# Your e-mail address
MY_EMAIL=nic@angel.net
# Your name
MY_NAME="Nic Wolff"
# This should be either blank, or a regex that matches any addresses from which
# you get lots of mail that you want to archive but not read:
BOTS=(root@.*angel.net|domainA|domainB|domainC)
# This should be a regex that matches all domains from which you know you
# won't get spammed:
KNOWN_DOMAINS=(angel.net|domain1.com|domain2.com)$
# This should be either blank, or a regex that matches the To: headers of any
# mailing lists you're on:
LISTS=
# Customize this to change the autoreply sent to messages from addresses
# that are not in the accept list
AUTOREPLY="Hi!
Your message has been received, but it hasn't been delivered to me yet. Since I don't have any record of your sending me mail from this address before, I need to verify that you're not a spammer. Please just hit 'Reply' and send this message back to me, and your previous message will be delivered, as will all your future messages.
(If your mail server can run procmail and you'd like to avoid receiving spam, you can find out how at
http://angel.net/~nic/spam-x/.)
Thanks, and sorry for the inconvenience -"
# Customize these if they're not right on your system:
FORMAIL=/usr/bin/formail
GREP=/usr/bin/grep
HEAD=/usr/ucb/head
SENDMAIL=/usr/lib/sendmail
LS=/bin/ls
TR=/usr/bin/tr
# Customize these if you want to put addresses and pending messages elsewhere -
# make sure PENDING_DIR exists!
DB=$HOME/.accept-list
DENY_DB=$HOME/.deny-list
PENDING_DIR=$HOME/pending_messages
##############################
# Don't change anything else unless you know why you're doing it!
SHELL=/bin/sh
PATH
COMSAT
VERBOSE=on
LOGFILE=${LOGFILE-".procmail_log"}
:0 c
$HOME/.save_all
# You can mail yourself a request for the list of pending senders
:0
* ^Subject: List senders
{
:0 fbw
| $LS -t $PENDING_DIR
:0:
${DEFAULT}
}
# You can mail yourself to approve an address
:0 fw
* ^Subject: Accept \/.*
* ? echo $MATCH >> $DB
* ? test -e $PENDING_DIR/$MATCH
| ( cat $PENDING_DIR/$MATCH || true )
# You can mail yourself to deny an address
:0 fw
* ^Subject: Deny \/.*
* ? echo $MATCH >> $DENY_DB
/dev/null
# Get sender
:0 hw
FROM=|$FORMAIL -rzxTo:|$TR / _
# If message is from a local bot then archive it
:0
* BOTS ?? (.)
* $ FROM ?? $BOTS
notifications
# If message is an NDN then archive it
:0 h
* MAILER-DAEMON
NDNs
# If message is from a known domain then deliver it
:0
* KNOWN_DOMAINS ?? (.)
* $ FROM ?? $KNOWN_DOMAINS
$DEFAULT
# If message is to a list we're on then deliver it
:0
* LISTS ?? (.)
* $ ^TO_$LISTS
$DEFAULT
# If message is from a known non-spam UCE sender then dump it
:0 h
* ? $GREP -i ^$FROM $DENY_DB
/dev/null
# Else if message has chicken then register sender and deliver stored messages
:0 Efw
* $ ^Subject:.*Verify.*for.*$MY_EMAIL
* ? echo $FROM >> $DB
* ? test -e $PENDING_DIR/$FROM
| ( ( cat $PENDING_DIR/$FROM && rm $PENDING_DIR/$FROM ) || true )
# Else if sender isn't in DB then send request for chicken and store message
:0 E
* $ ! ^X-Loop: $MY_EMAIL
* ! ? $GREP -i ^$FROM $DB
{
:0 c
* ? test ! -e $PENDING_DIR/$FROM
| ( $FORMAIL -rt -I"To: $FROM" -A"X-Loop: $MY_EMAIL" -I"Subject: Verify $FROM for $MY_EMAIL"; echo "$AUTOREPLY"; echo; echo "$MY_NAME" ) | $SENDMAIL -t
:0:
$PENDING_DIR/$FROM
}
# Else deliver normally