]> git.madduck.net Git - etc/mailfilter.git/commitdiff

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

initial checkin
authormartin f. krafft <madduck@seamus.madduck.net>
Thu, 9 Aug 2007 16:53:49 +0000 (18:53 +0200)
committermartin f. krafft <madduck@seamus.madduck.net>
Thu, 9 Aug 2007 16:53:49 +0000 (18:53 +0200)
51 files changed:
autoreplies/Makefile [new file with mode: 0644]
autoreplies/tnef [new file with mode: 0644]
bin/kill-from [new file with mode: 0755]
bin/kill-thread [new symlink]
bin/retrain [new file with mode: 0755]
bin/send-outgoing [new file with mode: 0755]
bin/train [new file with mode: 0755]
config/debian-packages [new file with mode: 0644]
config/dsn-subjects [new file with mode: 0644]
config/eqdomains [new file with mode: 0644]
config/ignore [new file with mode: 0644]
config/ignore-lists [new file with mode: 0644]
config/justme-address-exceptions [new file with mode: 0644]
config/justme-addresses [new file with mode: 0644]
config/justme-keyword-exceptions [new file with mode: 0644]
config/skip-spamchecks [new file with mode: 0644]
config/spammers [new file with mode: 0644]
config/spamtraps [new file with mode: 0644]
crm114/.gitignore [new file with mode: 0644]
crm114/mailfilter.cf [new file with mode: 0644]
crm114/priolist.mfp [new file with mode: 0644]
crm114/rewrites.mfp [new file with mode: 0644]
procmail/autoreplies [new file with mode: 0644]
procmail/defer [new file with mode: 0644]
procmail/defines [new file with mode: 0644]
procmail/duplicates [new file with mode: 0644]
procmail/eqdomains [new file with mode: 0644]
procmail/get-msgid [new file with mode: 0644]
procmail/handlespam [new file with mode: 0644]
procmail/ignore [new file with mode: 0644]
procmail/justme [new file with mode: 0644]
procmail/logging [new file with mode: 0644]
procmail/lurker [new file with mode: 0644]
procmail/marknew [new file with mode: 0644]
procmail/normalise [new file with mode: 0644]
procmail/pre-spam-cleanup [new file with mode: 0755]
procmail/procmailrc [new file with mode: 0755]
procmail/rules/admin [new file with mode: 0644]
procmail/rules/all [new file with mode: 0644]
procmail/rules/debian [new file with mode: 0644]
procmail/rules/feeds [new file with mode: 0644]
procmail/rules/mass [new file with mode: 0644]
procmail/rules/sudetia [new file with mode: 0644]
procmail/smsmail [new file with mode: 0644]
procmail/spamfilter [new file with mode: 0755]
procmail/spammers [new file with mode: 0644]
procmail/spamtraps [new file with mode: 0644]
procmail/spool-all [new file with mode: 0644]
procmail/to-albatross [new file with mode: 0644]
procmail/to-gmail [new file with mode: 0644]
spamassassin/user_prefs [new file with mode: 0644]

diff --git a/autoreplies/Makefile b/autoreplies/Makefile
new file mode 100644 (file)
index 0000000..d4ea1bf
--- /dev/null
@@ -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 (file)
index 0000000..ace1dd8
--- /dev/null
@@ -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 (executable)
index 0000000..3444185
--- /dev/null
@@ -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: <something> '
+    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 (symlink)
index 0000000..f2bdb5d
--- /dev/null
@@ -0,0 +1 @@
+kill-from
\ No newline at end of file
diff --git a/bin/retrain b/bin/retrain
new file mode 100755 (executable)
index 0000000..a95fbc9
--- /dev/null
@@ -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 (executable)
index 0000000..244218f
--- /dev/null
@@ -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 (executable)
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 (file)
index 0000000..2d3e368
--- /dev/null
@@ -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 (file)
index 0000000..be698c1
--- /dev/null
@@ -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 (file)
index 0000000..78d7620
--- /dev/null
@@ -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 (file)
index 0000000..cbebb27
--- /dev/null
@@ -0,0 +1,9 @@
+\<lindows\.com@pobox\.madduck\.net\>
+\<(Opinions|HRNotices)@staffmail\.ul\.ie\>
+\<tjp@parvu\.net\>
+\<newsletter@e\.milesandmore\.com\>
+\<virusalert@aerasec\.de\>
+\<biendecider@emv2\.net\>
+^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 (file)
index 0000000..9d22f50
--- /dev/null
@@ -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 (file)
index 0000000..d504b9a
--- /dev/null
@@ -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 (file)
index 0000000..c21a792
--- /dev/null
@@ -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 (file)
index 0000000..d50b8cf
--- /dev/null
@@ -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 (file)
index 0000000..560c55e
--- /dev/null
@@ -0,0 +1,28 @@
+^X-Mailer: swaks v20[[:digit:].]+ jetmore\.org/john/code/#swaks$
+^User-Agent: rss2email$
+^X-madduck-test: yes$
+^From:.*\<logcheck@
+^To:.*\<ebay\.com@pobox\.madduck\.net\>
+^To:.*\<paypal\.com-(us|de)@pobox\.madduck\.net\>
+^To:.*\<myspace\.com@pobox\.madduck\.net\>
+^To:.*\<icegold\.com@pobox\.madduck\.net\>
+^To:.*\<e-gold\.com@pobox\.madduck\.net\>
+^To:.*\<comparis\.ch@pobox\.madduck\.net\>
+^To:.*\<immoscout24\.ch@pobox\.madduck\.net\>
+^To:.*\<homegate\.ch@pobox\.madduck\.net\>
+^To:.*\<lufthansa\.com@pobox\.madduck\.net\>
+^To:.*\<united\.com@pobox\.madduck\.net\>
+^To:.*\<easyjet\.com@pobox\.madduck\.net\>
+^To:.*\<airlingus\.com@pobox\.madduck\.net\>
+^To:.*\<pcp\.ch@pobox\.madduck\.net\>
+^To:.*\<irishrail\.ie@pobox\.madduck\.net\>
+^To:.*\<ieee\.org@pobox\.madduck\.net\>
+^To:.*\<acm\.org@pobox\.madduck\.net\>
+^To:.*\<immoscout24\.ch@pobox\.madduck\.net\>
+^To:.*\<amazon\.com@pobox\.madduck\.net\>
+^To:.*\<klarmobil.de@pobox\.madduck\.net\>
+^From:.*\<installer@ftp-master\.debian\.org\>
+^From:.*\<owner@bugs\.debian\.org\>
+^From:.*\<swsupport@pimlicosoftware\.com\>
+^From:.*\<root@.+[[:space:]]+\<Cron Daemon\>
+^From:.*\<(leader|secretary)@debian\.org\>
diff --git a/config/spammers b/config/spammers
new file mode 100644 (file)
index 0000000..67651bb
--- /dev/null
@@ -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 (file)
index 0000000..55c90c6
--- /dev/null
@@ -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 (file)
index 0000000..b3a5267
--- /dev/null
@@ -0,0 +1 @@
+*.css
diff --git a/crm114/mailfilter.cf b/crm114/mailfilter.cf
new file mode 100644 (file)
index 0000000..84aeb14
--- /dev/null
@@ -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 (file)
index 0000000..e69de29
diff --git a/crm114/rewrites.mfp b/crm114/rewrites.mfp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/procmail/autoreplies b/procmail/autoreplies
new file mode 100644 (file)
index 0000000..f414af8
--- /dev/null
@@ -0,0 +1,16 @@
+:0
+*$ !$OLD_MESSAGE
+{
+  :0 c
+  * ^To:.*\<wohnung@sudetia\.de\>
+  {
+    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 (file)
index 0000000..ece2ae2
--- /dev/null
@@ -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 (file)
index 0000000..4fec548
--- /dev/null
@@ -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 (file)
index 0000000..8b3c00b
--- /dev/null
@@ -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 (file)
index 0000000..d1f3960
--- /dev/null
@@ -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 (file)
index 0000000..e859f2d
--- /dev/null
@@ -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 (file)
index 0000000..4095f60
--- /dev/null
@@ -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 (file)
index 0000000..b207b04
--- /dev/null
@@ -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 (file)
index 0000000..af7db20
--- /dev/null
@@ -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 (file)
index 0000000..04e03b6
--- /dev/null
@@ -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 (file)
index 0000000..b856bbc
--- /dev/null
@@ -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 (file)
index 0000000..3b94c51
--- /dev/null
@@ -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 (file)
index 0000000..b205694
--- /dev/null
@@ -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 (executable)
index 0000000..cb19128
--- /dev/null
@@ -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 (executable)
index 0000000..55565ef
--- /dev/null
@@ -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 (file)
index 0000000..6d8f0ed
--- /dev/null
@@ -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 (file)
index 0000000..73a5f78
--- /dev/null
@@ -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 (file)
index 0000000..022db93
--- /dev/null
@@ -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 (file)
index 0000000..945fe55
--- /dev/null
@@ -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 (file)
index 0000000..5fcb61d
--- /dev/null
@@ -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 (file)
index 0000000..229ba1f
--- /dev/null
@@ -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 (file)
index 0000000..9702f8a
--- /dev/null
@@ -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 (executable)
index 0000000..a882087
--- /dev/null
@@ -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 (file)
index 0000000..b5dd34b
--- /dev/null
@@ -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 (file)
index 0000000..adb1087
--- /dev/null
@@ -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 (file)
index 0000000..ebfb1c9
--- /dev/null
@@ -0,0 +1,2 @@
+:0 c
+$INBOX/.spool/
diff --git a/procmail/to-albatross b/procmail/to-albatross
new file mode 100644 (file)
index 0000000..5ba4a2c
--- /dev/null
@@ -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 (file)
index 0000000..4909c0c
--- /dev/null
@@ -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 (file)
index 0000000..3ddf363
--- /dev/null
@@ -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)X<WS>A<WS>N<WS>A<WS>X/i
+body __L_rp_drug_ws2 /(?!ambien)A<WS>M<WS>B<WS>I<WS>E<WS>N/i
+body __L_rp_drug_ws3 /(?!viagra)V<WS>I<WS>A<WS>G<WS>R<WS>A/i
+body __L_rp_drug_ws4 /(?!soma)S<WS>O<WS>M<WS>A/i
+body __L_rp_drug_ws5 /(?!cialis)C<WS>I<WS>A<WS>L<WS>I<WS>S/i
+body __L_rp_drug_ws6 /(?!valium)V<WS>A<WS>L<WS>I<WS>U<WS>M/i
+body __L_rp_drug_ws7 /(?!meridia)M<WS>E<WS>R<WS>I<WS>D<WS>I<WS>A/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