From 5af333ca3b83425e5cb3aa704b37654d576856c1 Mon Sep 17 00:00:00 2001 From: "martin f. krafft" Date: Thu, 9 Aug 2007 18:53:49 +0200 Subject: [PATCH 1/1] initial checkin --- autoreplies/Makefile | 14 + autoreplies/tnef | 3 + bin/kill-from | 55 ++++ bin/kill-thread | 1 + bin/retrain | 64 +++++ bin/send-outgoing | 34 +++ bin/train | 90 +++++++ config/debian-packages | 23 ++ config/dsn-subjects | 36 +++ config/eqdomains | 3 + config/ignore | 9 + config/ignore-lists | 2 + config/justme-address-exceptions | 19 ++ config/justme-addresses | 13 + config/justme-keyword-exceptions | 5 + config/skip-spamchecks | 28 ++ config/spammers | 3 + config/spamtraps | 3 + crm114/.gitignore | 1 + crm114/mailfilter.cf | 423 +++++++++++++++++++++++++++++++ crm114/priolist.mfp | 0 crm114/rewrites.mfp | 0 procmail/autoreplies | 16 ++ procmail/defer | 9 + procmail/defines | 170 +++++++++++++ procmail/duplicates | 15 ++ procmail/eqdomains | 30 +++ procmail/get-msgid | 39 +++ procmail/handlespam | 89 +++++++ procmail/ignore | 18 ++ procmail/justme | 72 ++++++ procmail/logging | 27 ++ procmail/lurker | 9 + procmail/marknew | 9 + procmail/normalise | 19 ++ procmail/pre-spam-cleanup | 32 +++ procmail/procmailrc | 71 ++++++ procmail/rules/admin | 29 +++ procmail/rules/all | 7 + procmail/rules/debian | 13 + procmail/rules/feeds | 10 + procmail/rules/mass | 10 + procmail/rules/sudetia | 5 + procmail/smsmail | 9 + procmail/spamfilter | 209 +++++++++++++++ procmail/spammers | 20 ++ procmail/spamtraps | 10 + procmail/spool-all | 2 + procmail/to-albatross | 25 ++ procmail/to-gmail | 11 + spamassassin/user_prefs | 147 +++++++++++ 51 files changed, 1961 insertions(+) create mode 100644 autoreplies/Makefile create mode 100644 autoreplies/tnef create mode 100755 bin/kill-from create mode 120000 bin/kill-thread create mode 100755 bin/retrain create mode 100755 bin/send-outgoing create mode 100755 bin/train create mode 100644 config/debian-packages create mode 100644 config/dsn-subjects create mode 100644 config/eqdomains create mode 100644 config/ignore create mode 100644 config/ignore-lists create mode 100644 config/justme-address-exceptions create mode 100644 config/justme-addresses create mode 100644 config/justme-keyword-exceptions create mode 100644 config/skip-spamchecks create mode 100644 config/spammers create mode 100644 config/spamtraps create mode 100644 crm114/.gitignore create mode 100644 crm114/mailfilter.cf create mode 100644 crm114/priolist.mfp create mode 100644 crm114/rewrites.mfp create mode 100644 procmail/autoreplies create mode 100644 procmail/defer create mode 100644 procmail/defines create mode 100644 procmail/duplicates create mode 100644 procmail/eqdomains create mode 100644 procmail/get-msgid create mode 100644 procmail/handlespam create mode 100644 procmail/ignore create mode 100644 procmail/justme create mode 100644 procmail/logging create mode 100644 procmail/lurker create mode 100644 procmail/marknew create mode 100644 procmail/normalise create mode 100755 procmail/pre-spam-cleanup create mode 100755 procmail/procmailrc create mode 100644 procmail/rules/admin create mode 100644 procmail/rules/all create mode 100644 procmail/rules/debian create mode 100644 procmail/rules/feeds create mode 100644 procmail/rules/mass create mode 100644 procmail/rules/sudetia create mode 100644 procmail/smsmail create mode 100755 procmail/spamfilter create mode 100644 procmail/spammers create mode 100644 procmail/spamtraps create mode 100644 procmail/spool-all create mode 100644 procmail/to-albatross create mode 100644 procmail/to-gmail create mode 100644 spamassassin/user_prefs diff --git a/autoreplies/Makefile b/autoreplies/Makefile new file mode 100644 index 0000000..d4ea1bf --- /dev/null +++ b/autoreplies/Makefile @@ -0,0 +1,14 @@ +all: $(wildcard *.msg) + +.%.header: % + sed -e '/^$$/ q' $< | grep -v '^$$' | iconv -futf8 -tlatin1 > $@ + +.%.body: % + sed -e '1,/^$$/ d' $< | iconv -futf8 -tlatin1 > $@ + +%.msg: .%.header .%.body + cat .$(subst .msg,,$@).header > $@ + mime-construct --output \ + --type "text/plain; charset=latin1" \ + --file .$(subst .msg,,$@).body >> $@ + rm -f $^ diff --git a/autoreplies/tnef b/autoreplies/tnef new file mode 100644 index 0000000..ace1dd8 --- /dev/null +++ b/autoreplies/tnef @@ -0,0 +1,3 @@ +http://support.microsoft.com/support/kb/articles/q136/2/04.asp + +application/ms-tnef diff --git a/bin/kill-from b/bin/kill-from new file mode 100755 index 0000000..3444185 --- /dev/null +++ b/bin/kill-from @@ -0,0 +1,55 @@ +#!/bin/sh +set -eu + +IGNORE_FILE="${0%/*}/../config/ignore" +ME="${0##*/}" + +case "$ME" in + kill-from) + case "${1:-}" in + *@*) :;; + '') + echo "E: missing email address argument." >&2 + exit 1 + ;; + *) + echo "E: not an email address: $1" >&2 + exit 2 + ;; + esac + CHECKPREFIX='From: someone <' + CHECKPOSTFIX='>' + REPREFIX='^From:.*' + REPOSTFIX='' + ARG="$1" + ;; + kill-thread) + case "${1:-}" in + *@*) :;; + '') + echo "E: missing message ID argument." >&2 + exit 1 + ;; + *) + echo "E: not a message ID: $1" >&2 + exit 2 + ;; + esac + CHECKPREFIX='References: ' + CHECKPOSTFIX='>' + REPREFIX='^References:.*' + REPOSTFIX='' + ARG="${1#<}"; ARG="${ARG%>}" + ;; +esac + +if echo "$CHECKPREFIX$1$CHECKPOSTFIX" | egrep -qif $IGNORE_FILE; then + echo "I: already ignored: $1" >&2 + exit 0 +fi + +ARG_ESCAPED="$(echo "$ARG" | sed -re 's,([.+]),\\\1,g')" +cat <<_eof >> $IGNORE_FILE +$^# $(date +%Y.%m.%d.%H.%m.%S) added by ${0##*/} +$REPREFIX$ARG_ESCAPED$REPOSTFIX +_eof diff --git a/bin/kill-thread b/bin/kill-thread new file mode 120000 index 0000000..f2bdb5d --- /dev/null +++ b/bin/kill-thread @@ -0,0 +1 @@ +kill-from \ No newline at end of file diff --git a/bin/retrain b/bin/retrain new file mode 100755 index 0000000..a95fbc9 --- /dev/null +++ b/bin/retrain @@ -0,0 +1,64 @@ +#!/bin/sh +set -eu + +NICE='nice -20' +PROCMAIL="$HOME/.etc/mailfilter/procmail/procmailrc" + +PAUSETIME=10 + +HAM=0 +SPAM=0 +MAILDIR= + +for i in "$@"; do + case "$i" in + --ham) HAM=1;; + --spam) SPAM=1;; + *) + if [ -n "$MAILDIR" ]; then + echo "E: Maildir already specified: $i" >&2 + exit 1 + elif [ -d "$i"/cur ] && [ -d "$i"/new ] && [ -d "$i"/tmp ]; then + MAILDIR="$i" + else + echo "E: unknown argument: $i" >&2 + exit 255 + fi + ;; + esac +done + +ARG= +case "$HAM/$SPAM" in + 0/0) + echo "E: you need to specify either --ham or --spam." >&2 + exit 255 + ;; + 1/1) + echo "E: you cannot specify both --ham and --spam." >&2 + exit 255 + ;; + 0/1) ARG=--spam;; + 1/0) ARG=--ham;; +esac + +LOCKFILE="$MAILDIR/.retrain.lock" +trap "rm -f $LOCKFILE" 1 2 3 4 5 6 7 8 10 11 12 13 14 15 +if ! lockfile -0 -r0 -l 3600 "$LOCKFILE" 2>/dev/null; then + echo "E: another retrain process is already running over that Maildir." >&2 + exit 1 +fi + +find $MAILDIR/cur $MAILDIR/new -type f | while read msg; do + $NICE ${0%/*}/train $ARG "$msg" | $PROCMAIL || ret=$? + case "${ret:-0}" in + 0|75) :;; + esac + rm -f "$msg" + sleep $PAUSETIME +done + +rm -f "$LOCKFILE" +trap - 1 2 3 4 5 6 7 8 10 11 12 13 14 15 + +exit 0 diff --git a/bin/send-outgoing b/bin/send-outgoing new file mode 100755 index 0000000..244218f --- /dev/null +++ b/bin/send-outgoing @@ -0,0 +1,34 @@ +#!/bin/sh +set -eu + +OUTBOX=~/.maildir/.outgoing +DEFAULT_RECORD=~/.maildir/.store +DISCARD_RECORD=~/.maildir/.discard + +DONT_STORE=1 + +LOCKFILE="$OUTBOX/.sendmail.lock" +trap "rm -f $LOCKFILE" 1 2 3 4 5 6 7 8 10 11 12 13 14 15 +if ! lockfile -0 -r0 -l 3600 "$LOCKFILE" 2>/dev/null; then + echo "E: another sendmail process is already running over that Maildir." >&2 + exit 1 +fi + +find $OUTBOX/cur $OUTBOX/new -type f | while read msg; do + RECORD="$(sed -rne 's,^X-Record: ,,p' < $msg)" + case "$RECORD" in [Dd]iscard|[Nn]o|[Nn]one|[Nn]ull) RECORD=$DISCARD_RECORD;; esac + [ ! -d $RECORD/cur ] && RECORD=$DEFAULT_RECORD + if sed -e '/^X-Record: /d' $msg | /usr/lib/sendmail -oem -oi -t; then + if [ ${DONT_STORE:-0} -eq 1 ]; then + rm "$msg" + else + #TODO this is not okay to deliver to Maildirs, really. + mv "$msg" ${RECORD:-$DEFAULT_RECORD}/cur + fi + fi +done + +rm -f "$LOCKFILE" +trap - 1 2 3 4 5 6 7 8 10 11 12 13 14 15 + +exit 0 diff --git a/bin/train b/bin/train new file mode 100755 index 0000000..05a768f --- /dev/null +++ b/bin/train @@ -0,0 +1,90 @@ +#!/bin/sh +set -eu + +USER=${USER:-$LOGNAME} +DOMAIN=${DOMAIN:-$(hostname --fqdn)} + +NICE='/usr/bin/nice -20' +MAILFILTER=$HOME/.etc/mailfilter +SA_PREFS="$MAILFILTER/spamassassin/user_prefs" +MAILREAVER="$NICE $HOME/spamfilter/mailreaver.crm -u $MAILFILTER/crm114/" +SPAMASSASSIN="$NICE /usr/bin/spamassassin -p $SA_PREFS" +#SPAMC="$NICE /usr/bin/spamc -lxu ${USER}@${DOMAIN}" +SA_REPORT="$SPAMASSASSIN --report" +SA_REVOKE="$SPAMASSASSIN --revoke" +SA_LEARN="$NICE /usr/bin/sa-learn -p $SA_PREFS" +SA_LEARN_HAM="$SA_LEARN --ham" +SA_LEARN_SPAM="$SA_LEARN --spam" +PRE_CLEANUP="$MAILFILTER/procmail/pre-spam-cleanup" + +HAM=0 +SPAM=0 +FILE= + +for i in "$@"; do + case "$i" in + --ham) HAM=1;; + --spam) SPAM=1;; + *) + if [ -n "$FILE" ]; then + echo "E: input file already specified: $i" >&2 + exit 1 + elif [ -r "$i" ]; then + FILE="$i" + else + echo "E: unknown argument: $i" >&2 + exit 255 + fi + ;; + esac +done + +case "$HAM/$SPAM" in + 0/0) + echo "E: you need to specify either --ham or --spam." >&2 + exit 255 + ;; + 1/1) + echo "E: you cannot specify both --ham and --spam." >&2 + exit 255 + ;; +esac + +TMPFILE="$(tempfile -p mailtrainer)" +trap "rm -f $TMPFILE" 1 2 3 4 5 6 7 8 10 11 12 13 14 15 + +$PRE_CLEANUP < ${FILE:-/dev/stdin} > "$TMPFILE" + +cd $HOME/.var/crm114 + +case "$HAM/$SPAM" in + 1/0) + echo -n 'Training Spamassassin with ham: ' >&2 + $SA_LEARN_HAM < "$TMPFILE" >&2 + echo -n 'Revoking spam via Spamassassin: ' >&2 + $SA_REVOKE < "$TMPFILE" >&2 +# [ "${CRM114_STATUS:-}" = GOOD ] || { + echo -n 'Training crm114 with ham: ' >&2 + $MAILREAVER --good < "$TMPFILE" >/dev/null + echo 'done.' >&2 +# } + formail -I 'X-Trained-As: ham' < "$TMPFILE" + ;; + 0/1) + echo -n 'Training Spamassassin with spam: ' >&2 + $SA_LEARN_SPAM < "$TMPFILE" >&2 + echo -n 'Reporting spam via Spamassassin: ' >&2 + $SA_REPORT < "$TMPFILE" >&2 +# [ "${CRM114_STATUS:-}" = SPAM ] || { + echo -n 'Training crm114 with spam: ' >&2 + $MAILREAVER --spam < "$TMPFILE" >/dev/null + echo 'done.' >&2 +# } + formail -I 'X-Trained-As: spam' < "$TMPFILE" + ;; +esac + +rm -f $TMPFILE +trap - 1 2 3 4 5 6 7 8 10 11 12 13 14 15 + +exit 0 diff --git a/config/debian-packages b/config/debian-packages new file mode 100644 index 0000000..2d3e368 --- /dev/null +++ b/config/debian-packages @@ -0,0 +1,23 @@ +buffy +fluxbox +gjay +guessnet +hibernate +ipcalc +iprelay +jppy +libbuffy +libfactory++ +libhid +libkdtree++ +libphidgets +libtut +logcheck +mdadm +molly-guard +muttprofile +poppass-cgi +python-docutils +python-lightblue +rest2web +vimoutliner diff --git a/config/dsn-subjects b/config/dsn-subjects new file mode 100644 index 0000000..be698c1 --- /dev/null +++ b/config/dsn-subjects @@ -0,0 +1,36 @@ +.*- account closed +Address Incorrect +Archivo Prohibido: +Attachment Filtering Notification +automated response +Automatic message from +BANNED +Considered UNSOLICITED BULK EMAIL, apparently from you +Delivery failure +Delivery Notification +Delivery Status Notification +email delivery error +Error Condition +failed delivery +failure delivery +failure notice +Illegal IMail List Server Comand +Mail Delivery.*fail +Mail System Error - Returned Mail +message undeliverable +.*Message you sent blocked by our bulk email filter +Não foi possível enviar sua mensagem +Non delivery report +Nondeliverable mail +Out of Office AutoReply: +Please confirm your message +Policy Violation +Rejected +Returned mail +Undeliverable: +Undeliverable mail +Undelivered Mail +Unzustellbar: +Warning: E-mail viruses detected +Your email requires verification +Your email.*was blocked diff --git a/config/eqdomains b/config/eqdomains new file mode 100644 index 0000000..78d7620 --- /dev/null +++ b/config/eqdomains @@ -0,0 +1,3 @@ +^admin\.madduck\.net$ +^forward\.madduck\.net$ +^mass\.madduck\.net$ diff --git a/config/ignore b/config/ignore new file mode 100644 index 0000000..cbebb27 --- /dev/null +++ b/config/ignore @@ -0,0 +1,9 @@ +\ +\<(Opinions|HRNotices)@staffmail\.ul\.ie\> +\ +\ +\ +\ +^Subject: =\?ISO-8859-1\?Q\?Xing:_New_(members_in|group_articles) +^Subject: New Spam - (Explicit|Suspect) Summary Digest: [[:digit:]]+ Messages$ +^Subject: [^[:space:]]+ mailing list memberships reminder$ diff --git a/config/ignore-lists b/config/ignore-lists new file mode 100644 index 0000000..9d22f50 --- /dev/null +++ b/config/ignore-lists @@ -0,0 +1,2 @@ +^Sender: owner-mutt-users@mutt\.org$ +^Sender: owner-postfix-users@postfix\.org$ diff --git a/config/justme-address-exceptions b/config/justme-address-exceptions new file mode 100644 index 0000000..d504b9a --- /dev/null +++ b/config/justme-address-exceptions @@ -0,0 +1,19 @@ +=lists\.madduck\.net@mass\.madduck\.net$ +=lists\.ailab\.ch@mass\.madduck\.net$ +=ifi\.u(ni)?zh\.ch@mass\.madduck\.net$ +=sudetia\.de@mass\.madduck\.net$ +-announce=[^@]+@mass\.madduck\.net$ +^debian-private=lists\.debian\.org@mass.madduck.net$ +^jppy=zanu\.org\.uk@mass\.madduck\.net$ +^os-renet=insel\.cs\.tu-berlin\.de@mass\.madduck\.net$ +^community=opensource\.mit\.edu@mass\.madduck\.net$ +^debian\.ch=fortytwo\.ch@mass\.madduck\.net$ +^crm114-discuss=lists\.sourceforge\.net@mass\.madduck\.net$ +^logcheck-devel=lists\.alioth\.debian\.org@mass\.madduck\.net$ +^pkg-mdadm-devel=lists\.alioth\.debian\.org@mass\.madduck\.net$ +^debconf-(team|press)=lists\.debconf\.org@mass\.madduck\.net$ +^netconf-devel=lists\.alioth\.debian\.org@mass\.madduck\.net$ +^music=(yarn\.)?skein\.org@mass\.madduck\.net$ +^slug=sccs\.swarthmore\.edu@mass\.madduck\.net$ +^ip=v2\.listbox\.com@mass\.madduck\.net$ +^infodrom-fortunes=lists\.infodrom\.org@mass\.madduck\.net$ diff --git a/config/justme-addresses b/config/justme-addresses new file mode 100644 index 0000000..c21a792 --- /dev/null +++ b/config/justme-addresses @@ -0,0 +1,13 @@ +#^debian-.+=lists\.debian\.org@mass.madduck.net$ +#^dovecot=dovecot\.org@mass\.madduck\.net$ +#^users=spamassassin\.apache\.org@mass\.madduck\.net$ +#^xorg=lists\.freedesktop\.org@mass\.madduck\.net$ +#^css-d=lists\.css-discuss\.org@mass\.madduck\.net$ +#^accu-general=accu\.org@mass\.madduck\.net$ +#^trac-users=googlegroups\.com@mass\.madduck\.net$ +#^mailman-users=python\.org@mass\.madduck\.net$ +#^log4cxx-user=logging\.apache\.org@mass\.madduck\.net$ +#^plone-users=lists\.sourceforge\.net@mass\.madduck\.net$ +#^sare-users=maddoc\.net@mass\.madduck\.net$ +#^(linux-)?xfs=oss\.sgi\.com@mass\.madduck\.net$ +@mass\.madduck\.net$ diff --git a/config/justme-keyword-exceptions b/config/justme-keyword-exceptions new file mode 100644 index 0000000..d50b8cf --- /dev/null +++ b/config/justme-keyword-exceptions @@ -0,0 +1,5 @@ +mdadm +The Debian System +method diffusion +Z[üu]rich +logcheck diff --git a/config/skip-spamchecks b/config/skip-spamchecks new file mode 100644 index 0000000..560c55e --- /dev/null +++ b/config/skip-spamchecks @@ -0,0 +1,28 @@ +^X-Mailer: swaks v20[[:digit:].]+ jetmore\.org/john/code/#swaks$ +^User-Agent: rss2email$ +^X-madduck-test: yes$ +^From:.*\ +^To:.*\ +^To:.*\ +^To:.*\ +^To:.*\ +^To:.*\ +^To:.*\ +^To:.*\ +^To:.*\ +^To:.*\ +^To:.*\ +^To:.*\ +^To:.*\ +^To:.*\ +^To:.*\ +^To:.*\ +^To:.*\ +^To:.*\ +^To:.*\ +^From:.*\ +^From:.*\ +^From:.*\ +^From:.*\ +^From:.*\<(leader|secretary)@debian\.org\> diff --git a/config/spammers b/config/spammers new file mode 100644 index 0000000..67651bb --- /dev/null +++ b/config/spammers @@ -0,0 +1,3 @@ +^user@zodiac\.com$ +^newslog@intelog\.com\.br$ +^euridice@una\.br$ diff --git a/config/spamtraps b/config/spamtraps new file mode 100644 index 0000000..55c90c6 --- /dev/null +++ b/config/spamtraps @@ -0,0 +1,3 @@ +^[[:alpha:]]{2}[[:xdigit:]]+@(piper|lapse)\.madduck\.net$ +.+@(diamond|cirrus)\.madduck\.net$ +^mass@madduck\.net$ diff --git a/crm114/.gitignore b/crm114/.gitignore new file mode 100644 index 0000000..b3a5267 --- /dev/null +++ b/crm114/.gitignore @@ -0,0 +1 @@ +*.css diff --git a/crm114/mailfilter.cf b/crm114/mailfilter.cf new file mode 100644 index 0000000..84aeb14 --- /dev/null +++ b/crm114/mailfilter.cf @@ -0,0 +1,423 @@ +# mailfilter.cf -- Config file for mailfilter, mailreaver, mailtrainer +# +# You MUST edit the fileds for "Secret Password", "mime decoder", and +# "cache_dupe_command". Just those THREE things. +# +# Changes to all other values are optional. +# +# Many of the options here have two or three alternatives; for your +# convenience, we have put all of the reasonable alternatives +# on sequential lines. Uncomment the one you want, and leave the +# others commented out. If you leave more than one uncommented, the +# last one is the one that's used. Don't do that; it's ugly. +# +# After you edit this file, don't forget to edit 'rewrites.mfp' + +# --------->>> You MUST set the following correctly! <<<------- +# +# If you leave it as "DEFAULT-PASSWORD", you will not be able to +# access the mail-to-myself commanding system, as "DEFAULT-PASSWORD" +# is specifically _disabled_ as a legal password. Just pick something, eh? +# +:spw: /DEFAULT_PASSWORD/ + +# ----- If you want a verbose startup, turn this on. Note that this is +# ----- intentionally _after_ the password is set, so a verbose startup +# ----- will not reveal your password. +# +#:verbose_startup: /SET/ +:verbose_startup: // + +# +# --------->>> You MUST set the following correctly! <<<------- +# +# --- Some mail systems do mime decoding with "mimencode -d" or "-u". +# --- Others (such as Red Hat 8.0) use "mewdecode" . +# --- Yet others (such as Fedora Core 3) use "openssl base64 -d" . +# --- Yet Others (i.e. *BSDs) can use "base64" . +# --- See which one is on your system and use that one- comment +# --- the others out. If you can't figure out what your base64 mime +# --- decoder is, or don't want mime decoding, set :do_base64: to /no/ +# --- but expect a significant accuracy decrease if you do this. +# +#:do_base64: /no/ +:do_base64: /yes/ +# +#:mime_decoder: /mewdecode/ +#:mime_decoder: /mimencode -d/ +#:mime_decoder: /mimencode -u/ +#:mime_decoder: /base64 -d/ +:mime_decoder: /openssl base64 -d/ +#:mime_decoder: /normalizemime/ + + +# --------->>> You MUST set the following correctly! <<<------- +# +# --- Linux (and Unix) systems use "hardlinks" to make a file +# --- appear in more than one place, while not actually using up +# --- extra disk space. Sadly, it is the case that most +# --- Windows systems have no such feature. So, you must set the +# --- following for what kind of system you are actually using. +# -- Note to other developers: here's where to put other system-dependent +# -- syscall commands. +# +# --- Use the default /ln/ for LINUX and UNIX systems (does a hard-link, +# --- does not use up disk space or inodes). Change this to the /copy/ +# --- command for WINDOWS systems (95, 98, NT, XP) +# +# --- Mild security issue: to avoid a theoretical exploit where a user +# --- gets their commands re-aliased, make sure you use the fully qualified +# --- commandname (that is, starting in the root directory). +# +:cache_dupe_command: /\/bin\/ln/ +#:cache_dupe_command: /copy/ + + + +########################################################################### +# +# END of things you absolutely MUST set. Feel free +# to keep reading though... +# +########################################################################### + +########################################################################### +# +# START of things you might likely want to set. These +# are probably OK for you, but many users change these things. +# +########################################################################## + +# ----------- define an optional target for where to send spam, +# ----------- To NOT forward this to another account, just leave the +# ----------- address as the empty string, which is '//'. +# ----------- This works fine especially if your mail reader program +# ----------- can sort based on the ADV and UNS (or whatever you choose +# ----------- to use as flagging strings) in the "Subject:" field. +# ------- CAUTION- some systems are buggy and _REQUIRE_ a user@host.domain +# ----- in the following to forward spammy mail correctly. WTF??? :-( +# +#:general_fails_to: /somebody@somewhere.net/ +:general_fails_to: // + + +# -------- If you would prefer to send specific kinds of spam to +# -------- different mailboxes, here's where to do it. +# ----------(be sure to uncomment the line!) +# +# :fail_priority_mail_to: /where_priority_fails_go/ +# :fail_blacklist_mail_to: /where_blacklist_fails_go/ +# :fail_SSM_mail_to: /where_Classifier_fails_go_for_mailFILTER/ +# :fail_classify_mail_to: /where_classifier_fails_go_for_mailREAVER/ + + +# --------- Do we give nonspam, spam, and unsure an exitcode of 0 +# --------- (for most standalone apps) or something else? +# --------- Usually we use an exit code of 1 for "program fault", +# --------- but change it if you need to use 0/1 for good/spam +# --------- Don't use an exit code greater than 128 (it breaks BASH!) +# --------- If you use exit codes (procmail doesn't) change it here. +:rejected_mail_exit_code: /0/ +:accepted_mail_exit_code: /0/ +:unsure_mail_exit_code: /0/ +:program_fault_exit_code: /1/ + +####################################################################### +# +# END of things you are likely to want to change. +# +# Anything following is starting to approach true customization. +# Feel free to explore and poke around. +###################################################################### + +# -----------Do we want to add the optional headers to the mail? +# -----------If turned on, will add X-CRM114-Whatever: headers on each +# -----------incoming email. (note- this does NOT turn off the cache-id header +# +:add_headers: /yes/ +#:add_headers: /no/ + + +# --------- do we add the statistics report? +:add_verbose_stats: /no/ +#:add_verbose_stats: /no/ + + +# --------- do we add the mailtrainer report to the top of the message body +# --------- after training? +:add_mailtrainer_report: /no/ +#:add_mailtrainer_report: /no/ + + +# --------- Do we enable long-form explains (with lots of text)? +# -- you can have no extra stuff, add it as text, or add it as an attachment. +# -- (only available in mailfilter, not mailreaver) +# +:add_extra_stuff: /no/ +# :add_extra_stuff: /text/ +# :add_extra_stuff: /attachment/ + + +# --------- Do we want to insert a "flagging" string on the subject line, +# --------- perhaps to insert an 'ADV:' ? Whatever string we put here +# --------- will be inserted at the front of the subject if we think the +# --------- mail is spam. +# +# :spam_flag_subject_string: // +:spam_flag_subject_string: // + +# --------- Do we want to insert a "flagging" string on the subject line +# --------- for good email? Usually we don't.... so we set this to the +# --------- null string - that is, // +:good_flag_subject_string: // + +# ------------Similarly, do we want to insert a "flagging" string on +# -------------the subject line of an "unsure" email? This way we know +# --------------we need to train it even if "headers" is turned off. +# :unsure_flag_subject_string: // +:unsure_flag_subject_string: // + +# ------------- Do we want Training ConFirmation flags on the results of +# ------------- a message to be learned? Default is "TCF:". +:confirm_flag_subject_string: // +#:confirm_flag_subject_string: // + + +# --------- Do we want to do any "rewrites" to increase generality and +# ---------- (usually) accuracy? IF 'yes', be sure to edit rewrites.mfp! +# --------- NOTE: this option is somewhat slow. If your mailserver is +# --------- maxed out on CPU, you might want to turn this off. +# +:rewrites_enabled: /yes/ +#:rewrites_enabled: /no/ + + +# --------- Do we copy incoming text into allmail.txt ? default is yes, but +# --------- experienced users will probably set this to 'no' after testing +# --------- their configuration for functionality. +# +:log_to_allmail.txt: /no/ +# :log_to_allmail.txt: /no/ + +# ------- Another logging option - log all mail to somewhere else +# ------- entirely. Whatever pathname is given here will be prefixed +# ------- by :fileprefix: +# ------- To not use this, set it to the null string .. // +# ------- Remember to backslash-escape path slashes! +:log_all_mail_to_file: // +#:log_all_mail_to_file: /my_personal_mail_log_file_name.txt/ + +# +# ---------- Message Cacheing for retraining - do we keep a cache of +# ---------- messages we've classified recently "in the wild" as retrain +# ---------- texts? This uses up some disk space, but means that we can +# ---------- use mailtrainer.crm on these messages to autotune the classifier. +# ---------- Default is to cache into the directory reaver_cache ; +# ---------- if you don't want this, set it to // . If you don't use this, +# ---------- you can't really use mailtrainer.crm, and you must keep your +# ---------- headers scrupulously clean in all train messages. Recommended +# ---------- to leave this unchanged unless you are VERY short of disk. +# +:text_cache: /../../../.var/crm114/reaver_cache/ +# :text_cache: // + + +# ----- How do we invoke the trainer (as in, just the invocation +# ------ of CRM114 on mailtrainer.crm. Usually this is just obvious, +# ------- but if you don't have CRM114 installed in the search path, here's +# -------- where you can set trainer invocation to be via whatever path +# --------- you want it (the second example is if you haven't installed +# ---------- CRM114 at all, but are running the crm114_tre static binary +# ----------- right out of the local directory.) +# +# -- use this next one if you have installed CRM114 with "make install" +# -- (This is preferred and is the default) +:trainer_invoke_command: /\/usr\/share\/crm114\/mailtrainer.crm/ +# +# -- use this one if you can't do a "make install" and so must run the +# --- crm114_tre binary directly out of the current working directory. +# :trainer_invoke_command: /.\/crm114_tre mailtrainer.crm / + + +# ------ If we're cacheing for retraining, we're probably using +# ------ mailtrainer.crm or some other variant. In that case, +# ------ you will want a "randomizer" to present the training +# ------ examples to the classifier in some random but balanced order. +# ------ You have two choices - you can either use the "sort" +# ------ command on some random character in the filename (this +# ------ is NOT recommended) or use the "shuffle.crm" program. +# ------ We _strongly_ recommend using shuffle.crm; the default +# ------ options to shuffle.crm will work fine. Alternatively, +# ------ you can use the "sort --key 1.2" on date-named files to +# ----- achieve chronological training +:trainer_randomizer_command: / .\/shuffle.crm / +#:trainer_randomizer_command: / .\/crm114_tre shuffle.crm / +#:trainer_randomizer_command: /sort --key 1.2/ + + +# --------- Do we log rejected mail to a file? default yes, but most +# --------- users should set this to no after testing their +# --------- configuration to verify that rejected mail goes to the +# --------- reject address. Only works in mailfilter.crm +# +:log_rejections: /yes/ +#:log_rejections: /no/ + +# ------- alternate rejection logging - set this pathname to non-null +# ------ to log rejections elsewhere. Only for mailreaver.crm. +# ----- Set to NULL ( // ) to turn this off. +:log_rejections_to_file: // +#:log_rejections_to_file /this_is_my_rejected_email_log_file.txt/ + + +# ----------Do we want to enable "inoculation by email"? +# --------(leave this off unless you want RFC inoculations) +# +:inoculations_enabled: /no/ +#:inoculations_enabled: /yes/ + + +# --------- How many characters of the input do we really trust to be +# ---------- worthy of classification? Usually the first few thousand +# ----------- bytes of the message tell more than enough (though we've +# ------------ been "noticed" by spammers, who are now packing 4K of +# ------------- innocuous text into their headers. No problemo... :) ) +# +#:decision_length: /4096/ +#:decision_length: /64000/ +:decision_length: /16000/ +# ----- for entropy users ONLY - 4K is plenty! +#:decision_length: /4096/ + + + +# ------------ Do we want to expand URLs (that is, fetching the contents +# ------------- of a URL and inserting that after the url itself?) +# -------------- By default this is off, but turn it on if you want +# --------------- to experiment. +:expand_urls: /no/ +# :expand_urls: /yes/ +# +# WGET options - 30-second timeout, output to stdout. +# HACK - use the proper --user-agent="IEblahblah" for max effect! +:url_fetch_cmd: /wget -T 30 -O - / +# and trim the URL text to not more than 16bytes of text. +:url_trim_cmd: / head -c 16000 / + + +####################################################################### +# +# ------------------- YOU REALLY SHOULD STOP HERE ------------------- +# --------- values below this line are usually OK for almost all +# --------- users to use unchanged - Gurus only beyond this point. +# +####################################################################### +# +# If you want to change things here, go ahead, but realize you are +# playing with things that can really hurt accuracy. +# +# This being open source, if you don't *think* about changing it, +# what would be the use of it being open source? That said, this +# _is_ open source- you break it, you get to keep _both_ pieces! +# +# +# ------------ CLF - The Classifier Flags ---------- +# +# --------- Which classifier flags do we use? Default for 20060101 has +# --------- been changed to OSB UNIQUE MICROGROOM. +# +# --------- A null setting gets you straight Markovian, without +# --------- microgrooming. OSB uses less memory, is faster, +# --------- and is usually more accurate. Correlative matching is +# --------- 100x - 1000x slower, but can match anything (binaries, +# --------- wide chars, unicode, virii, _anything_. Winnow is a +# --------- non-statistical learning classificer with very nice +# --------- accuracy (up to 2x SBPH). Hyperspace is a pseudogaussian +# --------- KNN (K-nearest-neighbor) matcher. +# +# --------- This is also where we set whether to use microgrooming +# --------- or Arne optimization (they're currently mutually exclusive). +# --------- If you turn off microgrooming you get Arne optimization +# --------- automatically. +# +# --------- If you _change_ this, you _must_ empty out your .css or +# --------- .cow files and build fresh ones, because these +# --------- classifiers do NOT use compatible data storage formats! +# +#:clf: /microgroom/ +#:clf: /osb/ +#:clf: /osb microgroom/ +:clf: /osb unique microgroom/ +#:clf: /correlate/ +#:clf: /winnow/ +#:clf: /osbf/ +#:clf: /osbf microgroom/ +#:clf: /hyperspace/ +#:clf: /hyperspace unique/ +# +# +# + +# --------- If you are using thick-threshold training of any sort, +# ---------- (for OSBF or otherwise) put the threshold here. +# ----------- Remember, the polarity of the thick threshold value +# ------------ is that anything scoring less than this value +# ------------- should be considered a trainable error, and it "flips over" +# -------------- so that both good mail and spam have the right symmetrical +# ---------------- polarity. + +# ------ a very small thick threshold (or zero!) works for Markovian. +#:thick_threshold: /0/ +#:thick_threshold: /.001/ +# ----- a thick threshold of 5 to 20 seems good for OSB, OSBF, +# Hyperspace, Bit-Entropy, and Winnow +#:thick_threshold: /5.0/ +:thick_threshold: /10.0/ +#:thick_threshold: /20.0/ +# + +# ---- What regex do we use for LEARN/CLASSIFY? the first is the +# ---- "old standard". Other ones are handy for different spam +# ---- mixes. The last one is for people who get a great deal of +# ---- packed HTML spam, which is almost everybody in 2003, so it +# ---- used to be the default. But since spammers have shifted away +# ---- from this, it isn't the default any longer. IF you change +# ---- this, you MUST rebuild your .css files with roughly equal +# ---- amounts of locally-grown spam and nonspam ( if you've been +# ---- following instructions and using the "reaver" cache, this is +# ---- easily done! ) +# +:lcr: /[[:graph:]]+/ +#:lcr: /[[:alnum:]]+/ +#:lcr: /[-.,:[:alnum:]]+/ +#:lcr: /[[:graph:]][-[:alnum:]]*[[:graph:]]?/ +#:lcr: /[[:graph:]][-.,:[:alnum:]]*[[:graph:]]?/ +# +# this next one is pretty incomprehensible, and probably wrong... +#:lcr: /[[:print:]][/!?\#]?[-[[:alnum:]][[:punct:]]]*(?:[*'=;]|/?>|:/*)? +# +# +# Expansions for antispamming. You almost _always_ want these on, +# unless you're debugging something really bizarre. + +# --------- Do we enable spammus interruptus undo? +:undo_interruptus: /no/ +#:undo_interruptus: /yes/ +# +# +# +# ------------ HIGHLY EXPERIMENTAL - automatic training! +# enable this only if you really want to live VERY dangerously! +# "Do you feel lucky today, punk? Well, do ya?" +# +:automatic_training: /no/ +# +# ---- if you are living dangerously and have turned on autotraining, +# you should also set the following to point to an address that +# will get read on a quick basis, becuause this is where autotrain +# verifications will go. +# +#:autotrain_address: /root/ + + +:datadir: /..\/..\/.var\/.crm114/ diff --git a/crm114/priolist.mfp b/crm114/priolist.mfp new file mode 100644 index 0000000..e69de29 diff --git a/crm114/rewrites.mfp b/crm114/rewrites.mfp new file mode 100644 index 0000000..e69de29 diff --git a/procmail/autoreplies b/procmail/autoreplies new file mode 100644 index 0000000..f414af8 --- /dev/null +++ b/procmail/autoreplies @@ -0,0 +1,16 @@ +:0 +*$ !$OLD_MESSAGE +{ + :0 c + * ^To:.*\ + { + LOG="autoreply: replying to wohnung@sudetia.de mail$NL" + + REPLY=$REPLIES/sudetia-wohnung.msg + :0 + |($SED -e '/^$/,$d' $REPLY; \ + $FORMAIL -R Reply-To From -U From -r -t; \ + $SED -e '1,/^$/d' $REPLY) \ + |$SENDMAIL $SENDMAILFLAGS -t + } +} diff --git a/procmail/defer b/procmail/defer new file mode 100644 index 0000000..ece2ae2 --- /dev/null +++ b/procmail/defer @@ -0,0 +1,9 @@ +:0 +* ? test -e $HOME/procmail.defer +* !SKIP_DEFER ?? . +{ + EX_DEFER=75 + EXITCODE=$EX_DEFER + LOG="local delivery intentionally deferred by $LOGNAME" + HOST +} diff --git a/procmail/defines b/procmail/defines new file mode 100644 index 0000000..4fec548 --- /dev/null +++ b/procmail/defines @@ -0,0 +1,170 @@ +### basic settings + +SHELL=/bin/sh +PATH=$HOME/bin:/usr/local/bin:/usr/bin:/bin + +COMSAT=no + +LINEBUF=16384 +UMASK=0077 + +PMVAR=$HOME/.var/procmail +MAILFILT=$HOME/.etc/mailfilter +PMRULES=$PMDIR/rules +CONF=$MAILFILT/config +REPLIES=$MAILFILT/autoreplies + +LOGFILE=${LOGFILE:-$PMVAR/log} +LOGABSTRACT=no + +NICE='/usr/bin/nice -20' + +PROCMAIL="$NICE /usr/bin/procmail -p $PMDIR/procmailrc" +FORMAIL="$NICE /usr/bin/formail -f" +EGREP="$NICE /bin/egrep" +SED="$NICE /bin/sed" + +CRM114="$NICE /usr/share/crm114/mailreaver.crm -u $MAILFILT/crm114/" +SA_PREFS="$MAILFILT/spamassassin/user_prefs" +SPAMASSASSIN="$NICE /usr/bin/spamassassin -p $SA_PREFS" +#SPAMC="$NICE /usr/bin/spamc -lxu $ID" +SPAMC="$SPAMASSASSIN" +TRAINER="$MAILFILT/bin/train" + +OURDATE=`date -R` +OURDATE_SHORT=`date +%Y.%m.%d.%H.%m.%N` + +INBOX=$HOME/.maildir + +DEFAULT=$INBOX/ +ORGMAIL=$HOME/BOUNCED-MAIL + +# maximum message size for spam checking +SPAMCHECK_MAX_MESSAGE_SIZE=2500000 + +# if crm114 is unsure and SA returns a score less-than-or-equal to this, +# autotrain crm114 with ham +CRM_UNSURE_SA_AUTOTRAIN_LIMIT_HAM=2.0 +# if crm114 classifies a message as spam but SA returns a score +# less-than-or-equal to this, retrain crm114 +CRM_MISCLASSIFY_SA_AUTOTRAIN_LIMIT_HAM=-1.0 +# if crm114 is unsure and SA returns a score greater than this, autotrain +# crm114 with spam +CRM_UNSURE_SA_AUTOTRAIN_LIMIT_SPAM=8.0 +# if crm114 classifies a message as ham but SA returns a score +# greate than this, retrain crm114 +CRM_MISCLASSIFY_SA_AUTOTRAIN_LIMIT_SPAM=11 + +### constants used in rules +NL=" +" +RE_MYDOMAIN="(.+\.)?madduck\.net" +RE_MAILRELAYS="(seamus|clegg)\.madduck\.net" +RE_SPACE_NEWLINE="(^|[ ])" +RE_FIRSTNAME="martin($RE_SPACE_NEWLINE+f(\.?|elix))?" +RE_LASTNAME="kraff?t" +RE_EXTRACT_HEADER_VALUE="[ ]*\/[^ ].*" + +NULL=/dev/null +DISCARD=$INBOX/.discard/ + +### variables from the message + +### local recipient data +# user+foobar@my.domain.org +# < > $USER +# < > $EXTENSION +# < > $LOCAL +# < > $DOMAIN +# < > $RECIPIENT +USER="${USER:-$LOGNAME}" +EXTENSION="${EXTENSION:-}" +LOCAL="${LOCAL:-$USER${EXTENSION:++$EXTENSION}}" +HOSTNAME="`hostname --fqdn`" +DOMAIN="${DOMAIN:-$HOSTNAME}" +RECIPIENT="${RECIPIENT:-$LOCAL@$DOMAIN}" +ID="$LOGNAME@$HOSTNAME" + +# message-id +INCLUDERC=$PMDIR/get-msgid + +# if $SENDER is undefined or not an email address, get it from the message +:0 +* !SENDER ?? @ +*$ ^Sender:$RE_EXTRACT_HEADER_VALUE +{ SENDER="$MATCH" } + +:0 +*$ ^Date:$RE_EXTRACT_HEADER_VALUE +{ DATE="$MATCH" } + +:0 +*$ ^From:$RE_EXTRACT_HEADER_VALUE +{ FROM="$MATCH" } + +:0 +*$ ^Subject:$RE_EXTRACT_HEADER_VALUE +{ SUBJECT="$MATCH" } + +# TODO: can be removed as soon as albatross is out of the loop +:0 fw +* ^X-Original-To-Saved: \/.* +|$FORMAIL -R X-Original-To-Saved X-Original-To + +:0 +*$ ^X-Original-To:$RE_EXTRACT_HEADER_VALUE +{ ORIGINAL_TO="$MATCH" } +:0 E +{ LOG="NO ORIGINAL_TO: $MSGID" } + +# fix variable values for special cases +INCLUDERC=$PMDIR/normalise + +:0 +* ORIGINAL_TO ?? ^\/[^@]+ +{ ORIG_LOCAL="$MATCH" } + +:0 +* ORIGINAL_TO ?? .+@\/.+ +{ ORIG_DOMAIN="$MATCH" } + +### run-time variables + +# OLD_MESSAGE +# a procmail-style flag, which is true if unset and false if set (to !). +# unset by marknew if the message has already been seen by the filter (according +# to the X-Been-There header). +OLD_MESSAGE=! + +# SKIP_SPAMCHECKS +# if set, cuases spamchecks to be skipped, value lists reason +SKIP_SPAMCHECKS + +# SPAMTRAPPED +# set by spamtrapped and eqdomains and used to bypass spamchecks and handle as +# spam immediately. The value identifies who unset the variable. +SPAMTRAPPED + +# IS_SPAM +# if set, then the mailfilter is as sure as it gets that the message is spam. +# The value identifies who set the variable. +IS_SPAM + +# SPAM_DISAGREE +# if set, then the various spamchecks disagree about spaminess of the mail. +# The value can hold additional information. +SPAM_DISAGREE + +# SPAM_UNSURE +# if set, then the various spamchecks are unsure about spaminess of the mail. +# The value can hold additional information. +SPAM_UNSURE + +# SPAM_UNKNOWN +# if set, the spamchecks were skipped. The value gives the reason for +# skipping. +SPAM_UNKNOWN + +# CRM_RETRAIN +# if set, causes crm114 to be retrained, according to the variable's value +CRM_RETRAIN diff --git a/procmail/duplicates b/procmail/duplicates new file mode 100644 index 0000000..8b3c00b --- /dev/null +++ b/procmail/duplicates @@ -0,0 +1,15 @@ +MID_CACHE_FILE = $PMVAR/msgid.cache + +LOCKFILE = $MID_CACHE_FILE$LOCKEXT +:0 +*$ !SKIP_DUP ?? . +*$ !$OLD_MESSAGE +* ^Message-ID: +* ? $FORMAIL -D 16384 $MID_CACHE_FILE +{ + LOG="duplicate: drop duplicate message $MSGID$NL" + + :0 + $NULL +} +LOCKFILE # unlock diff --git a/procmail/eqdomains b/procmail/eqdomains new file mode 100644 index 0000000..d1f3960 --- /dev/null +++ b/procmail/eqdomains @@ -0,0 +1,30 @@ +:0 +* ? echo "$ORIG_DOMAIN" | $EGREP -qif $CONF/eqdomains +{ + :0 + * !ORIGINAL_TO ?? =.+@.+ + { + LOG="eqdomain: spamtrap message due to missing = in localpart ($ORIGINAL_TO)$NL" + :0 fw + |$FORMAIL -A"X-Spamtrapped: missing equal sign in eqdomain ($ORIGINAL_TO)" + SPAMTRAPPED=eqdomain + } + + :0 E + { + :0 + * ORIG_LOCAL ?? ^\/[^=]+ + { EQ_LOCAL="$MATCH" } + + :0 + * ORIG_LOCAL ?? .+=\/.+ + { EQ_DOMAIN="$MATCH" } + + LOG="eqdomain: message to $EQ_LOCAL@$EQ_DOMAIN via $ORIG_DOMAIN$NL" + + :0 fw + |$FORMAIL -A"X-EqDomain: $ORIG_DOMAIN" -A"X-EqTo: $EQ_LOCAL@$EQ_DOMAIN" + } +} + +# vim:ft=procmail diff --git a/procmail/get-msgid b/procmail/get-msgid new file mode 100644 index 0000000..e859f2d --- /dev/null +++ b/procmail/get-msgid @@ -0,0 +1,39 @@ +:0 +* ^Message-Id:[ ]*\/[^ ]+ +{ MSGID="$MATCH" } + +:0 +* MSGID ?? ^[ ]*$|^<>$ +{ + TMPFILE="`tempfile -p msgid`" + LOG="get-msgid: LACKING MSGID header, DUMPING to $TMPFILE$NL" + + :0 ifw + |cat > $TMPFILE + + EX_DEFER=75 + EXITCODE=$EX_DEFER + HOST +} + +:0 +* ! MSGID ?? ^<[^>]+>$ +{ + LOG="get-msgid: message-id '$MSGID' not enclosed in <>, fixing it...$NL" + MSGID="<$MSGID>" +} + +:0 +*$ MSGID ?? .+@$RE_MAILRELAYS> +*$ !^Return-Path: .+@$RE_MAILRELAYS\> +*$ !^Received: by $RE_MAILRELAYS \(postfix, from userid +{ + LOG="get-msgid: missing message ID added by one of our mail relays$NL" + + :0 fw + |$SED -re "s/^([Mm]essage-[Ii][Dd]:[^@]+@$RE_MAILRELAYS)\>/\1.MSGID-ADDED/" + + :0 + * ^Message-Id:[ ]*\/[^ ]+ + { MSGID="$MATCH" } +} diff --git a/procmail/handlespam b/procmail/handlespam new file mode 100644 index 0000000..4095f60 --- /dev/null +++ b/procmail/handlespam @@ -0,0 +1,89 @@ +# we are called from spamfilter and the following cases could be: +# +# 1. spamfilters are unsure +# symptom: $SPAM_UNSURE is set (sa-unsure) +# reaction: file as unsure +# +# 2. spamfilters disagree +# symptom: $SPAM_DISAGREE is set (sa-ham or sa-spam) +# reaction: file as disagreed +# +# 3. message is spam for sure +# symptom: $IS_SPAM is set +# reaction: file as spam +# +# 4a. message needs to be retrained as spam +# symptom: $CRM_RETRAIN is set to spam +# reaction: retrain filters, report, and file as spam +# +# 4b. message is spamtrapped +# symptom: $SPAMTRAPPED is set +# reaction: train filters, report, and file as spam +# +# 5. message needs to be retrained as ham +# symptom: $CRM_RETRAIN is set to ham +# reaction: retrain crm114 and resubmit the message to the spamfilter +# +# 6. spam degree is unknown: +# symptom: $SPAM_UNKNOWN contains the reason for skipping the checks +# reaction: pass the message +# +# 7. message is not spam +# symptom: none of the above +# reaction: pass the message +# + +:0 +* SPAM_UNSURE ?? . +{ + LOG="spamfilter: filing as unsure$NL" + :0 + $INBOX/.retrain.unsure/ +} + +:0 E +* SPAM_DISAGREE ?? . +{ + LOG="spamfilter: filing as disagreed$NL" + :0 + $INBOX/.retrain.disagree/ +} + +:0 E +* 1^0 CRM_RETRAIN ?? spam +* 1^0 SPAMTRAPPED ?? . +{ + LOG="spamfilter: (re)training as spam$NL" + :0 fw + |$TRAINER --spam 2>/dev/null + IS_SPAM=trained +} + +:0 E +* CRM_RETRAIN ?? ham +{ + LOG="spamfilter: retraining as ham$NL" + :0 fw + |$TRAINER --ham 2>/dev/null +# :0 +# |$TRAINER --ham 2>/dev/null | $PROCMAIL +} + +# not using flag E because IS_SPAM could have been set further up +:0 +* IS_SPAM ?? . +{ + LOG="spamfilter: filing as spam$NL" + :0 + $INBOX/.spam/ +} + +:0 +{ LOG="spamfilter: allowed to pass$NL" } + +#:0 E +#*$ $SPAM_UNKNOWN +#{ do nothing } + +#:0 E +#{ do nothing} diff --git a/procmail/ignore b/procmail/ignore new file mode 100644 index 0000000..b207b04 --- /dev/null +++ b/procmail/ignore @@ -0,0 +1,18 @@ +:0 BH +* ? $EGREP -qif $CONF/ignore +{ + LOG="ignore: discarding ignored message $MSGID from $FROM to $ORIGINAL_TO$NL" + :0 + $DISCARD +} + +:0 H +* ORIGINAL_TO ?? madduck@(madduck\.net|debian\.org) +* ? $EGREP -qif $CONF/ignore-lists +{ + LOG="ignore: dropping list message $MSGID$NL" + :0 + $NULL +} + +# vim:ft=procmail diff --git a/procmail/justme b/procmail/justme new file mode 100644 index 0000000..af7db20 --- /dev/null +++ b/procmail/justme @@ -0,0 +1,72 @@ +:0 +* ? echo "$ORIGINAL_TO" | $EGREP -qif $CONF/justme-addresses +{ + :0 H + *$ MSGID ?? <.+@$RE_MYDOMAIN> + { + LOG="justme: passing; from machine in my domain$NL" + :0 fw + |$FORMAIL -I'X-Justme: from machine in my domain' + SKIP_SPAMCHECKS=from-mydomain + } + + :0 EH + *$ ^(References|In-Reply-To):.*<.+@$RE_MYDOMAIN> + { + LOG="justme: passing; in-reply-to/referenced$NL" + :0 fw + |$FORMAIL -I'X-Justme: in-reply-to/referenced' + SKIP_SPAMCHECKS=in-reply-to/referenced + } + + :0 E + * ? echo "$ORIGINAL_TO" | $EGREP -qif $CONF/justme-address-exceptions + { + LOG="justme: passing; explicitly excepted address$NL" + :0 fw + |$FORMAIL -I'X-Justme: in-reply-to/referenced' + } + + :0 EBH + *$ 1^0 B ?? $RE_FIRSTNAME$RE_SPACE_NEWLINE+$RE_LASTNAME + *$ 1^0 B ?? $RE_LASTNAME[,]?$RE_SPACE_NEWLINE*$RE_FIRSTNAME + { + LOG="justme: passing; full name reference$NL" + :0 fw + |$FORMAIL -I'X-Justme: full name reference' + } + + :0 EBH + *$ B ?? $RE_LASTNAME + { + LOG="justme: passing; last name reference$NL" + :0 fw + |$FORMAIL -I'X-Justme: last name reference' + } + + :0 EBH + * 1^0 B ?? madduck + * -1^0 B ?? mass\.madduck\.net + { + LOG="justme: passing; nickname reference$NL" + :0 fw + |$FORMAIL -I'X-Justme: nickname reference' + } + + :0 EBH + *$ ? $EGREP -qif $CONF/justme-keyword-exceptions + { + LOG="justme: passing; keyword reference$NL" + :0 fw + |$FORMAIL -I'X-Justme: keyword reference' + } + + :0 E + { + LOG="justme: discarding$NL" + :0 + $DISCARD + } +} + +# vim:ft=procmail diff --git a/procmail/logging b/procmail/logging new file mode 100644 index 0000000..04e03b6 --- /dev/null +++ b/procmail/logging @@ -0,0 +1,27 @@ +LOGABSTRACT=no + +MSGIDDIR=$PMVAR/msgid + +:0 +* MSGID ?? ^<\/[^>]+ +{ + THISLOGFILE_REL=`echo $MATCH | tr -d "'\"?[:cntrl:]" | tr ' /*' '__+'`%$OURDATE_SHORT + THISLOGFILE="$MSGIDDIR/$THISLOGFILE_REL" +} + +MASTERLOGFILE="$LOGFILE" +LOGFILE="$THISLOGFILE" + +LOG="============================================================================== +msgid: $MSGID +logfile: $THISLOGFILE_REL +date: $DATE (@$OURDATE) +from: $FROM +original-to: $ORIGINAL_TO +subject: $SUBJECT$NL" + +TRAP="echo \"delivered: \${LASTFOLDER#$INBOX/}\" >> '$THISLOGFILE'; + echo >> '$THISLOGFILE'; + egrep -v '^(procmail:)?[[:space:]\"]' '$THISLOGFILE' >> $MASTERLOGFILE" + +#VERBOSE=yes diff --git a/procmail/lurker b/procmail/lurker new file mode 100644 index 0000000..b856bbc --- /dev/null +++ b/procmail/lurker @@ -0,0 +1,9 @@ +:0 c +{ + LOG="lurker: archiving message $MSGID with lurker$NL" + TRAP="" + LURKER_CONF=$HOME/.etc/lurker/lurker.conf + + :0 + |$NICE lurker-index -c $LURKER_CONF -l foo -m +} diff --git a/procmail/marknew b/procmail/marknew new file mode 100644 index 0000000..3b94c51 --- /dev/null +++ b/procmail/marknew @@ -0,0 +1,9 @@ +:0 +*$ ^X-Been-There: $ID +{ + LOG="marknew: re-processing message $MSGID$NL" + OLD_MESSAGE +} + +:0 Efw +|$FORMAIL -A"X-Been-There: $ID" diff --git a/procmail/normalise b/procmail/normalise new file mode 100644 index 0000000..b205694 --- /dev/null +++ b/procmail/normalise @@ -0,0 +1,19 @@ +# add hostname if missing +:0 +* ! ORIGINAL_TO ?? @ +{ ORIGINAL_TO="$ORIGINAL_TO@$HOSTNAME" } + +# rewrite local admin mail to admin.madduck.net domain +:0 +*$ ORIGINAL_TO ?? .+@$HOSTNAME$ +*$ ^Delivered-To: $LOGNAME\+admin@$HOSTNAME$ +{ ORIGINAL_TO="`echo $ORIGINAL_TO | tr @ =`@admin.madduck.net" } + +# transform root@ to proper localpart +# http://marc.info/?t=118495181500014&r=1&w=2 +:0 +* ORIGINAL_TO ?? ^root=\/[^@]+ +*$ ^Delivered-To: \/.+@$MATCH$ +{ ORIGINAL_TO="`echo $MATCH | tr @ =`@admin.madduck.net" } + +# vim:ft=procmail diff --git a/procmail/pre-spam-cleanup b/procmail/pre-spam-cleanup new file mode 100755 index 0000000..cb19128 --- /dev/null +++ b/procmail/pre-spam-cleanup @@ -0,0 +1,32 @@ +#!/usr/bin/procmail + +PMDIR=${PMDIR:-$HOME/.etc/mailfilter/procmail} + +:0 +* !PMVAR ?? . +{ + # PMVAR is not defined, so we are being called as filter + # thus source the standard defines + INCLUDERC=$PMDIR/defines + # prevent feeding back to procmail and delete the leading From line + PROCMAIL='/bin/cat' + # and tell the fucking procmail piece-of-shit to continue to be a filter + DEFAULT='|$PROCMAIL' +} + +# unpack SA report_safe mails +:0 +* B ?? ^Content-Type: message/rfc822; x-spam-type=original$ +{ + LOG="cleanup: unpacking SA MIME-wrapped spam mail$NL" + :0 fw + |$SPAMASSASSIN -d +} + +# remove other unwanted headers from all messages +:0 fw +|$FORMAIL -IX-Virus-Scanned -IX-SenderIP -IX-ASN -IX-CIDR -IX-UID -IX-OfflineIMAP- \ + -IX-Status -IStatus -IX-Keywords -IX-Greylist \ + -IX-Spam -IX-CRM114 -IX-Auto -IX-Trained-As -IX-EqDomain -IX-EqTo + +# now should be idempotent diff --git a/procmail/procmailrc b/procmail/procmailrc new file mode 100755 index 0000000..55565ef --- /dev/null +++ b/procmail/procmailrc @@ -0,0 +1,71 @@ +#!/usr/bin/procmail -t + +#LOGFILE=$HOME/.var/procmail/log +#LOGABSTRACT=no +#VERBOSE=yes + +PMDIR=$HOME/.etc/mailfilter/procmail + +INCLUDERC=$PMDIR/defer + +FROM_ALBATROSS=! +:0 +* ^X-Been-There: madduck@albatross +{ + M=$MATCH + :0 + * M ?? ^\+.+\+\/[^@]+ + { + # we have two +, so it's a virtual domain + L=$MATCH + + :0 + * M ?? ^\+\/[^+]+ + { D=$MATCH } + + OT="$L@$D" + L + D + } + + :0 E + * M ?? ^\/\+?[^@]* + { OT="madduck$MATCH@madduck.net" } + M + + :0 fw + |formail -I "X-Original-To: $OT" -A'X-From-Albatross: yes' + OT + + FROM_ALBATROSS + LOG="log: *** received $MSGID from albatross$NL" +} + +INCLUDERC=$PMDIR/defines + +INCLUDERC=$PMDIR/ignore + +INCLUDERC=$PMDIR/smsmail + +#VERBOSE=yes + +INCLUDERC=$PMDIR/logging + +INCLUDERC=$PMDIR/marknew +INCLUDERC=$PMDIR/eqdomains + +INCLUDERC=$PMDIR/duplicates + +INCLUDERC=$PMDIR/to-gmail + +INCLUDERC=$PMDIR/justme + +INCLUDERC=$PMDIR/spamtraps +INCLUDERC=$PMDIR/spammers +INCLUDERC=$PMDIR/spamfilter + +#INCLUDERC=$PMDIR/autoreplies + +INCLUDERC=$PMDIR/lurker + +INCLUDERC=$PMRULES/all diff --git a/procmail/rules/admin b/procmail/rules/admin new file mode 100644 index 0000000..6d8f0ed --- /dev/null +++ b/procmail/rules/admin @@ -0,0 +1,29 @@ +:0 +* ORIG_DOMAIN ?? ^admin\.madduck\.net$ +{ + # require that messages sent to foo=bar@admin.madduck.net have passed the + # machine at bar, meaning have been Delivered-To there. + :0 + *$ !^Delivered-To: .+@$EQ_DOMAIN + { + LOG="spamtrap message as it was never delivered to $EQ_DOMAIN +" + :0 fw + |$FORMAIL -A'X-Spamtrapped: not delivered to eqdomain' + SPAMTRAPPED + } + + DESTDIR="$INBOX/.admin.`echo $EQ_DOMAIN | tr . _" + + :0 + { + :0 + * EQ_LOCAL ?? (logcheck|apticron) + ${DESTDIR}.$EQ_LOCAL/ + + :0 + ${DESTDIR}/ + } +} + +# vim:ft=procmail diff --git a/procmail/rules/all b/procmail/rules/all new file mode 100644 index 0000000..73a5f78 --- /dev/null +++ b/procmail/rules/all @@ -0,0 +1,7 @@ +INCLUDERC=$PMRULES/admin +INCLUDERC=$PMRULES/mass +INCLUDERC=$PMRULES/feeds +INCLUDERC=$PMRULES/debian +INCLUDERC=$PMRULES/sudetia + +# vim:ft=procmail diff --git a/procmail/rules/debian b/procmail/rules/debian new file mode 100644 index 0000000..022db93 --- /dev/null +++ b/procmail/rules/debian @@ -0,0 +1,13 @@ +:0 +* ORIGINAL_TO ?? ^madduck=debian\.org@forward\.madduck\.net$ +{ + :0 + * ^X-Debian-PR-Source: \/.+ + * ? grep -q "^${MATCH}$" $CONF/debian-packages + $INBOX/.debian.$MATCH/ + + :0 E + $INBOX/.debian/ +} + +# vim:ft=procmail diff --git a/procmail/rules/feeds b/procmail/rules/feeds new file mode 100644 index 0000000..945fe55 --- /dev/null +++ b/procmail/rules/feeds @@ -0,0 +1,10 @@ +:0 +* ORIG_DOMAIN ?? ^r2e\.madduck\.net$ +{ + DESTDIR=$INBOX/.feeds + + :0 + ${DESTDIR}/ +} + +# vim:ft=procmail diff --git a/procmail/rules/mass b/procmail/rules/mass new file mode 100644 index 0000000..5fcb61d --- /dev/null +++ b/procmail/rules/mass @@ -0,0 +1,10 @@ +:0 +* ORIG_DOMAIN ?? ^mass\.madduck\.net$ +{ + DESTDIR=$INBOX/.mass + + :0 + ${DESTDIR}/ +} + +# vim:ft=procmail diff --git a/procmail/rules/sudetia b/procmail/rules/sudetia new file mode 100644 index 0000000..229ba1f --- /dev/null +++ b/procmail/rules/sudetia @@ -0,0 +1,5 @@ +:0 +* ORIGINAL_TO ?? ^madduck=sudetia.de@forward\.madduck\.net$ +$INBOX/.sudetia/ + +# vim:ft=procmail diff --git a/procmail/smsmail b/procmail/smsmail new file mode 100644 index 0000000..9702f8a --- /dev/null +++ b/procmail/smsmail @@ -0,0 +1,9 @@ +:0 +* ORIGINAL_TO ?? .+@sms.madduck.net +{ + :0 W + |$HOME/.bin/proc_smsmail + + EXITCODE=$? + HOST +} diff --git a/procmail/spamfilter b/procmail/spamfilter new file mode 100755 index 0000000..a882087 --- /dev/null +++ b/procmail/spamfilter @@ -0,0 +1,209 @@ +#!/usr/bin/procmail + +#TODO: rewrite to use SPAM variable, and do not autotrain spam here, only ham + +PMDIR=${PMDIR:-$HOME/.etc/mailfilter/procmail} + +:0 +* !PMVAR ?? . +{ + # PMVAR is not defined, so we are being called as filter + # thus source the standard defines + INCLUDERC=$PMDIR/defines + # prevent feeding back to procmail and delete the leading From line + PROCMAIL='/bin/cat' + # and tell the fucking procmail piece-of-shit to continue to be a filter + DEFAULT='|$PROCMAIL' +} + +#VERBOSE=yes + +INCLUDERC=$PMDIR/pre-spam-cleanup + +# no need to reprocess messages that went into a spamtrap +:0 +* SPAMTRAPPED ?? . +{ + LOG="spamfilter: skipping checks for spamtrapped message$NL" + :0 fw + |$FORMAIL -I"X-Spam: spamtrapped" +} + +# let earlier parts of the mailfilter cause bypassing the checks +:0 E +* SKIP_SPAMCHECKS ?? . +{ + LOG="spamfilter: skipping checks as requested: $SKIP_SPAMCHECKS$NL" + :0 fw + |$FORMAIL -I"X-Spam: unknown (skip requested)" + SPAM_UNKNOWN=skip-requested +} + +# honour skip-spamchecks to exclude certain messages from spam checks +# altogether +:0 EBH +* ? $EGREP -qif $CONF/skip-spamchecks +{ + LOG="spamfilter: skipping checks as per skip-spamchecks$NL" + :0 fw + |$FORMAIL -I"X-Spam: unknown (check skipped)" + SPAM_UNKNOWN=skip-match +} + +# sanity check on message size +:0 E +* > $SPAMCHECK_MAX_MESSAGE_SIZE +{ + LOG="spamfilter: skipping check because message size exceeds $SPAMCHECK_MAX_MESSAGE_SIZE bytes$NL" + :0 fw + |$FORMAIL -I"X-Spam: unknown (message larger than $SPAMCHECK_MAX_MESSAGE_SIZE bytes)" + SPAM_UNKNOWN=too-large +} + +# now run the spamfilters +:0 E +{ + # crm114 + CRM_SPAM=UNKNOWN + CRM_SCORE=0 + :0 + * !SKIP_CRM ?? . + { + :0 fw + |$CRM114 + + :0 + * ^X-CRM114-Status: \/[A-Z]+ + { CRM_SPAM=$MATCH } + + :0 + * ^X-CRM114-Status: .+\([ ]*\/-?[.0-9]+ + { CRM_SCORE=$MATCH } + + LOG="crm114: $CRM_SPAM/$CRM_SCORE$NL" + } + + # spamassassin + SA_STATUS=Unknown + SA_SCORE=0 + SA_TESTS=none + :0 + * !SKIP_SA ?? . + { + :0 fw + |$SPAMC + + :0 + * ^X-Spam-Status: \/[A-Za-z]+ + { SA_SPAM=$MATCH } + + :0 + * ^X-Spam-Status: .+score=\/-?[.0-9]+ + { SA_SCORE=$MATCH } + + :0 + * ^X-Spam-Status: .+tests=\/[^ ]+ + { SA_TESTS=$MATCH } + + LOG="SA: $SA_SPAM/$SA_SCORE/$SA_TESTS$NL" + } + + ## CASE 0: crm114 is unsure/untrained + :0 + * CRM_SPAM ?? UNSURE + { + # retrain as ham + :0 + * ? perl -e "$SA_SCORE <= $CRM_UNSURE_SA_AUTOTRAIN_LIMIT_HAM || exit 1" + { + LOG="spamfilter: scheduling crm114 retraining with HAM (score $SA_SCORE <= $CRM_UNSURE_SA_AUTOTRAIN_LIMIT_HAM)$NL" + :0 fw + |$FORMAIL -A "X-CRM114-Autotrain: ham, according to SA (score $SA_SCORE <= $CRM_UNSURE_SA_AUTOTRAIN_LIMIT_HAM)" + CRM_RETRAIN=ham + } + + # retrain as spam + :0 E + * ? perl -e "$SA_SCORE > $CRM_UNSURE_SA_AUTOTRAIN_LIMIT_SPAM || exit 1" + { + LOG="spamfilter: scheduling crm114 retraining with SPAM (score $SA_SCORE > $CRM_UNSURE_SA_AUTOTRAIN_LIMIT_SPAM)$NL" + :0 fw + |$FORMAIL -A "X-CRM114-Autotrain: spam, according to SA (score $SA_SCORE > $CRM_UNSURE_SA_AUTOTRAIN_LIMIT_SPAM)" + CRM_RETRAIN=spam + } + + # skip retraining if SA is not convinced + :0 E + { + LOG="spamfilter: will not autotrain crm114 because SA is not convinced ($CRM_UNSURE_SA_AUTOTRAIN_LIMIT_HAM <= $SA_SCORE < $CRM_UNSURE_SA_AUTOTRAIN_LIMIT_SPAM)$NL" + :0 fw + |$FORMAIL -A "X-CRM114-Autotrain: SA is unsure ($CRM_UNSURE_SA_AUTOTRAIN_LIMIT_HAM <= $SA_SCORE < $CRM_UNSURE_SA_AUTOTRAIN_LIMIT_SPAM)" + SPAM_UNSURE=sa-unsure + } + } + + ## CASE 1: disagreement, SA sees ham + :0 E + * CRM_SPAM ?? SPAM + * SA_SPAM ?? No + { + # SA is convincing, so retrain crm114 + :0 + * ? perl -e "$SA_SCORE <= $CRM_MISCLASSIFY_SA_AUTOTRAIN_LIMIT_HAM || exit 1" + { + LOG="spamfilter: crm114 found spam ($CRM_SCORE), but SA is more convincing ($SA_SCORE <= $CRM_MISCLASSIFY_SA_AUTOTRAIN_LIMIT_HAM)$NL" + CRM_RETRAIN=ham + :0 fw + |$FORMAIL -A "X-CRM114-Retrain: ham, according to SA (score $SA_SCORE <= $CRM_MISCLASSIFY_SA_AUTOTRAIN_LIMIT_HAM)" + } + + # SA is not convincing, mark as disagreement + :0 E + { + LOG="spamfilter: crm114 found spam ($CRM_SCORE), but SA thinks it's ham ($SA_SCORE)$NL" + SPAM_DISAGREE=sa-ham + :0 fw + |$FORMAIL -I "X-Spam: disagree (crm114:spam/$CRM_SCORE SA:ham/$SA_SCORE)" + } + } + + ## CASE 1: disagreement, SA sees spam + :0 E + * CRM_SPAM ?? GOOD + * SA_SPAM ?? Yes + { + # SA is convincing, so retrain crm114 + :0 + * ? perl -e "$SA_SCORE > $CRM_MISCLASSIFY_SA_AUTOTRAIN_LIMIT_SPAM || exit 1" + { + LOG="spamfilter: crm114 found ham ($CRM_SCORE), but SA is more convincing ($SA_SCORE > $CRM_MISCLASSIFY_SA_AUTOTRAIN_LIMIT_SPAM)$NL" + CRM_RETRAIN=spam + :0 fw + |$FORMAIL -A "X-CRM114-Retrain: spam, according to SA (score $SA_SCORE > $CRM_MISCLASSIFY_SA_AUTOTRAIN_LIMIT_SPAM)" + } + + # SA is not convincing, mark as disagreement + :0 E + { + LOG="spamfilter: crm114 found ham ($CRM_SCORE), but SA thinks it's spam ($SA_SCORE)$NL" + SPAM_DISAGREE=sa-spam + :0 fw + |$FORMAIL -I "X-Spam: disagree (crm114:ham/$CRM_SCORE SA:spam/$SA_SCORE)" + } + } + + :0 E + * CRM_SPAM ?? SPAM + * SA_SPAM ?? Yes + { + IS_SPAM=sa+crm + :0 fw + |$FORMAIL -I"X-Spam: yes (crm114:$CRM_SCORE SA:$SA_SCORE)" + } + + :0 Efw + |$FORMAIL -I"X-Spam: no (crm114:$CRM_SCORE SA:$SA_SCORE)" +} + +INCLUDERC=$PMDIR/handlespam +#VERBOSE=no diff --git a/procmail/spammers b/procmail/spammers new file mode 100644 index 0000000..b5dd34b --- /dev/null +++ b/procmail/spammers @@ -0,0 +1,20 @@ +SPAMMER +:0 +* ? echo "$FROM" | $EGREP -qif $CONF/spammers +{ SPAMMER="$FROM" } + +:0 E +* ? echo "$SENDER" | $EGREP -qif $CONF/spammers +{ SPAMMER="$SENDER" } + +:0 +* SPAMMER ?? @ +{ + LOG="spammers: message from known spam sender$NL" + :0 fw + |$FORMAIL -A"X-Spamtrapped: from known spammer ($SPAMMER)" + SPAMTRAPPED=known-spammer +} +SPAMMER + +# vim:ft=procmail diff --git a/procmail/spamtraps b/procmail/spamtraps new file mode 100644 index 0000000..adb1087 --- /dev/null +++ b/procmail/spamtraps @@ -0,0 +1,10 @@ +:0 +* ? echo "$ORIGINAL_TO" | $EGREP -qif $CONF/spamtraps +{ + LOG="spamtraps: message to known spamtrap$NL" + :0 fw + |$FORMAIL -A"X-Spamtrapped: message to known spamtrap ($ORIGINAL_TO)" + SPAMTRAPPED=known-spamtrap +} + +# vim:ft=procmail diff --git a/procmail/spool-all b/procmail/spool-all new file mode 100644 index 0000000..ebfb1c9 --- /dev/null +++ b/procmail/spool-all @@ -0,0 +1,2 @@ +:0 c +$INBOX/.spool/ diff --git a/procmail/to-albatross b/procmail/to-albatross new file mode 100644 index 0000000..5ba4a2c --- /dev/null +++ b/procmail/to-albatross @@ -0,0 +1,25 @@ +:0 c +*$ ! $FROM_ALBATROSS +* !^X-Mailer: swaksDISABLED +{ + :0 f + |$FORMAIL -R X-Original-To X-Original-To-Saved + + :0 + * ^Return-Path: *<\/[^>]* + { SENDMAILFLAGS="$SENDMAILFLAGS -f $MATCH" } + + LOG="log: *** bouncing message $MSGID to albatross$NL" + TRAP="" + + :0 + ! madduck${EXTENSION:++$EXTENSION}@albatross.madduck.net +} + +:0 E +{ + LOG="log: *** received $MSGID from albatross$NL" + + :0 fw + |$FORMAIL -A'X-From-Albatross: yes' +} diff --git a/procmail/to-gmail b/procmail/to-gmail new file mode 100644 index 0000000..4909c0c --- /dev/null +++ b/procmail/to-gmail @@ -0,0 +1,11 @@ +:0 c +* ORIG_DOMAIN ?? ^(mass|r2e)\.madduck\.net$ +* !^X-Mailer: swaks +{ + LOG="gmail: archiving message $MSGID with gmail$NL" + SENDMAILFLAGS="$SENDMAILFLAGS -f $ID" + TRAP="" + + :0 + ! martin.krafft@gmail.com +} diff --git a/spamassassin/user_prefs b/spamassassin/user_prefs new file mode 100644 index 0000000..3ddf363 --- /dev/null +++ b/spamassassin/user_prefs @@ -0,0 +1,147 @@ +# SpamAssassin user preferences file. See 'perldoc Mail::SpamAssassin::Conf' +# for details of what can be tweaked. +########################################################################### + +# How many points before a mail is considered spam. +# required_score 5 + +# Whitelist and blacklist addresses are now file-glob-style patterns, so +# "friend@somewhere.com", "*@isp.com", or "*.domain.net" will all work. +# whitelist_from someone@somewhere.com + +# Add your own customised scores for some tests below. The default scores are +# read from the installed spamassassin rules files, but you can override them +# here. To see the list of tests and their default scores, go to +# http://spamassassin.apache.org/tests.html . +# +# score SYMBOLIC_TEST_NAME n.nn + +# Speakers of Asian languages, like Chinese, Japanese and Korean, will almost +# definitely want to uncomment the following lines. They will switch off some +# rules that detect 8-bit characters, which commonly trigger on mails using CJK +# character sets, or that assume a western-style charset is in use. +# +# score HTML_COMMENT_8BITS 0 +# score UPPERCASE_25_50 0 +# score UPPERCASE_50_75 0 +# score UPPERCASE_75_100 0 +# score OBSCURED_EMAIL 0 + +# Speakers of any language that uses non-English, accented characters may wish +# to uncomment the following lines. They turn off rules that fire on +# misformatted messages generated by common mail apps in contravention of the +# email RFCs. + +# score SUBJ_ILLEGAL_CHARS 0 + +use_auto_whitelist 0 + +focr_timeout 30 + +report_safe 0 +report_safe_copy_headers X-CRM114-Status X-CRM114-Notice +report_safe_copy_headers X-Greylist + +rewrite_header SUBJECT + +bayes_path ~/.var/spamassassin/bayes +bayes_auto_learn 1 +bayes_ignore_header X-Original-To +bayes_ignore_header X-Original-To-Saved # +bayes_ignore_header X-EqDomain +bayes_ignore_header X-EqTo +bayes_ignore_header X-Been-There +bayes_ignore_header X-Delivered-To +bayes_ignore_header X-Greylist +bayes_ignore_header X-Virus-Scanned +bayes_ignore_header X-CRM114-Status +bayes_ignore_header X-CRM114-CacheID +bayes_ignore_header X-CRM114-Notice +bayes_ignore_header X-CRM114-Version +bayes_ignore_header X-Sender-IP # +bayes_ignore_header X-CIDR # +bayes_ignore_header X-ASN # +bayes_ignore_header X-Spam-Relays-External +bayes_ignore_header X-Spam-Relays-Internal +bayes_ignore_header X-Spam-Relays-Trusted +bayes_ignore_header X-Spam-Relays-Untrusted +bayes_ignore_header X-Spam-Status +bayes_ignore_header X-Spam-Bayes +bayes_ignore_header X-Spam-Level +bayes_ignore_from add@ress.com # +bayes_learn_to_journal 1 + +add_header all Status _YESNO_, score=_SCORE_/_REQD_ tests=_TESTS_ autolearn=_AUTOLEARN_ +add_header all Bayes score=_BAYES_ sum=_TOKENSUMMARY_ ham=_HAMMYTOKENS_ spam=_SPAMMYTOKENS_ +add_header all Level _STARS(-)_ +#add_header all Relays-Trusted _RELAYSTRUSTED_ +add_header all Relays-Untrusted _RELAYSUNTRUSTED_ +#add_header all Relays-Internal _RELAYSINTERNAL_ +#add_header all Relays-External _RELAYSEXTERNAL_ + +# the local host +trusted_networks 127. +# madduck.net +trusted_networks 130.60.75.72 82.197.162.59 213.203.238.82 +# debian: gluck master murphy spohr rietz +trusted_networks 192.25.206.10 70.103.162.29 70.103.162.31 192.25.206.33 140.211.166.43 +# debian: alioth +trusted_networks 217.196.43.134 +# ifi: bela miraculix +trusted_networks 130.60.156.10 130.60.156.214 +# ailab: gaia +trusted_networks 130.60.75.60 +# fortytwo +trusted_networks 193.138.215.60 +# aerasec: all of MNET-AERASEC +trusted_networks 212.18.21.160/26 +# swat: osprey.sccs +trusted_networks 130.58.218.6 +# acm +trusted_networks 63.118.7.109 +# skynet: calculon gir +trusted_networks 193.1.99.88 193.1.99.77 +# ul: marshal4 +trusted_networks 193.1.100.137 +# ieee: ruebert +trusted_networks 140.98.193.10 +# vger.kernel.org +trusted_networks 209.132.176.167 + +whitelist_from *master@*.madduck.net +whitelist_from *master@madduck.net +whitelist_from logcheck@*.madduck.net +whitelist_from root@*.madduck.net +whitelist_from root@madduck.net +whitelist_from *-owner@lists.madduck.net +whitelist_to *-owner@lists.madduck.net +whitelist_from *-owner@lists.ailab.ch +whitelist_to *-owner@lists.ailab.ch + +ok_locales en +ok_languages en de + +header MADDUCK_IN_REFERENCES References =~ /madduck\.net/ +tflags MADDUCK_IN_REFERENCES nice +describe MADDUCK_IN_REFERENCES madduck.net appears in References header +score MADDUCK_IN_REFERENCES -100.0 + +# more obfuscated drugs +# see http://issues.apache.org/SpamAssassin/show_bug.cgi?id=4875 +replace_tag WS ( [a-z] ) +body __L_rp_drug_ws1 /(?!xanax)XANAX/i +body __L_rp_drug_ws2 /(?!ambien)AMBIEN/i +body __L_rp_drug_ws3 /(?!viagra)VIAGRA/i +body __L_rp_drug_ws4 /(?!soma)SOMA/i +body __L_rp_drug_ws5 /(?!cialis)CIALIS/i +body __L_rp_drug_ws6 /(?!valium)VALIUM/i +body __L_rp_drug_ws7 /(?!meridia)MERIDIA/i +replace_rules __L_rp_drug_ws1 __L_rp_drug_ws2 __L_rp_drug_ws3 __L_rp_drug_ws4 __L_rp_drug_ws5 __L_rp_drug_ws6 __L_rp_drug_ws7 +meta L_drug_ws_obfu (__L_rp_drug_ws1 + __L_rp_drug_ws2 + __L_rp_drug_ws3 + __L_rp_drug_ws4 + __L_rp_drug_ws5 + __L_rp_drug_ws6 + __L_rp_drug_ws7) > 3 +score L_drug_ws_obfu 3 + +# http://marc.info/?t=118544884300001&r=1&w=2 +rcore BAYES_60 0.0001 0.0001 1.5 1.5 +score BAYES_80 0.0001 0.0001 2.5 2.5 +score BAYES_95 0.0001 0.0001 4.0 4.0 +score BAYES_99 0.0001 0.0001 5.0 5.0 -- 2.39.2