### fdm configuration ### vim:ft=config:fdm=marker ### ### All in one replacement for {get,fetch}mail and procmail. ### ### ### Frank Terbeck ### ### Last-Modified: Mon Jul 27 22:29:20 2009 ### ########################################################################### ### The following strings are replaced in pipe commands and ### maildir/mbox paths: ### %a: account name ### %h: user's home directory ### %n: user's uid ### %t: action name if performing action ### %u: name of user ### %H: current hour (00-23) ### %M: current minute (00-59) ### %S: current second (00-59) ### %d: current day of the month (00-31) ### %m: current month (01-12) ### %y: current year ### %W: current day of the week (0-6, Sunday is 0) ### %Y: current day of the year (000-365) ### %Q: current quarter (1-4) ########################################################################### ### Some macros used below. ### where I keep my mail $path = "%h/Mail" ### where I keep my config files $cfgdir = "%h/etc/fdm" ### location of killfile $killfile = "%h/etc/mailnews/killfile" ### spam filter commands $com_spam_filter = "bogofilter -p -e -u" $com_train_good = "bogofilter -p -e -n" $com_train_spam = "bogofilter -p -e -s" $com_untrain_good = "bogofilter -p -e -S" $com_untrain_spam = "bogofilter -p -e -N" ### some filters use these unix commands: $com_sed = "sed" $com_awk = "awk" $com_perl = "perl" ### spam header expressions $header_spam = "X-JunkFilter" $header_trained = "X-JunkFilterTrained" $filtered_spam = "SPAM" $filtered_good = "GOOD" $filtered_unsure= "UNSURE" $filter_trained = " TRAINED" ### if do_catchall is "yes", all incoming mail will be saved ### to ${catchall_mbox}; useful for testing (so nothing gets lost). $do_catchall = "nope, thank you." $catchall_mbox = "%h/catchall.mbox" ### this is used by my archive action. ### Mails older than this (in days) are moved to the archive. %max_age = 30 ### zblog $com_zblog = "%h/bin/zblog" ### print from headers (Sender, From, From:, Reply-To:) ### used for killfiling. $com_pfh = "${com_awk} '/^(From|From:|Reply-To:|Sender)/{sub(/[^ \\t]*[ \\t]*/,\"\",$0);print};/^\$/{exit 0}'" ### list of headers I don't want. $ill_headers = "(" $ill_headers = "${ill_headers}X-Qmail-Scanner.*|X-SA-Exim.*|X-CR-.*|" $ill_headers = "${ill_headers}X-MIME-.*|X-Authentication-.*|" $ill_headers = "${ill_headers}X-Mailman-.*|X-Spam-.*|X-MimeOLE|" $ill_headers = "${ill_headers}X-Msmail-.*|X-Priority|X-MS-.*|" $ill_headers = "${ill_headers}Thread-Topic|Thread-Index|X-imss-.*|" $ill_headers = "${ill_headers}X-OriginalArrivalTime|" $ill_headers = "${ill_headers}X-Face|DKIM-Signature|" $ill_headers = "${ill_headers}X-IronPort-.*|DomainKey-Signature|" $ill_headers = "${ill_headers}X-Rc-.*|Authentication-Results" $ill_headers = "${ill_headers})" ### perl script that filters out unwanted headers $com_filter_headers = "${com_perl} -e '\$k=\$e=0;while(<>){if(\$e||m/^$/){\$e=1;print;next;}" $com_filter_headers = "${com_filter_headers}if(m/^[ \\t]+/&&\$k){next;}if(m/^${ill_headers}:/i)" $com_filter_headers = "${com_filter_headers}{\$k=1;next;}if(\$k){\$k=0;}print;}'" ########################################################################### ### This is used to set the maximum size of a mail. Mails larger than ### this limit are dropped and, if applicable, not deleted from the ### server. set maximum-size 128M ### If this option is specified, fdm(1) attempts to delete messages ### which exceed maximum-size, and continue.If it is not specified, ### oversize messages are a fatal error and cause fdm(1) to abort. #set delete-oversized ### If this option is specified, fdm(1) does not attempt to create a ### lock file and allows multiple instances to run simultaneously. #set allow-multiple ### This sets an alternative lock file. The default is ~/.fdm.lock ### for non-root users and /var/db/fdm.lock for root. set lock-file "${cfgdir}/fdm.lock" ### This specifies the locks to be used for mbox locking. Possible ### types are fcntl, flock, and dotlock. The flock and fcntl types ### are mutually exclusive. The default is flock. #set lock-types "flock" ### This sets the default user to change to before delivering mail, ### if fdmis running as root and no alternative user is specified as ### part of the action or rule. #set default-user "hawk" ### This specifies the domains to be used when looking for users with ### the from-headers keyword. The default is the computer's hostname. #set domain "bewatermyfriend.org" ### This allows the headers to be examined when looking for users to ### be set. The default is to look only at the "From" and "Cc" ### headers. The headers are case-insensitive. #set header ### This instructs fdm to proxy all connections through url. HTTP ### and SOCKS5 proxies are supported at present (URLs of the form ### http://host[:port] or socks://[user:pass@]host[:port]). ### No authentication is supported for HTTP. #set proxy ### This option controls what fdm does with mail that reaches the ### end of the ruleset (mail that matches no rules or matches only ### rules with the continue keyword). drop will cause such mail to ### be discarded, and keep will attempt to leave the mail on the ### server. The default is to keep the mail and log a warning that ### it reached the end of the ruleset. set unmatched-mail keep ### This option makes fdm attempt to purge deleted mail from the ### server (if supported) after count mails have been retrieved. set purge-after none ### If set, fdm will not insert a 'Received' header into each mail. #set no-received ### This specifies the umask(2) to use when creating files. 'user' ### means to use the umask set when fdm is started, or umask may be ### specified as a three-digit octal number. set file-umask 077 ### This option allows the default group ownership of files and ### directories created by fdm(1) to be specified. 'group' may be a ### group name string or a numeric gid. 'user' does nothing. set file-group user ### This controls the maximum time to wait for a server to send data ### before closing a connection. The default is 900 seconds. set timeout 900 ### Instructs fdm to verify SSL certificates for all SSL connections. set verify-certificates set queue-high 1 ########################################################################### ### include account information from seperate file. ### it contains lines that look like this: ### account "name" server pop3 "pop3.serv.tld" user "uname" pass "pwd" include "${cfgdir}/accounts.conf" ########################################################################### ### simple actions action "drop" drop action "keep" keep ### zblog action "zblog" pipe "${com_zblog} email" action "zcomm" pipe "${com_zblog} commentmode" ### killfiling action "killfile" maildir "${path}/Trash" ### a mailbox to rule them all action "catchall" mbox "${catchall_mbox}" ### spam actions action "spam" maildir "${path}/Spam" action "spam-unsure" maildir "${path}/Spam-unsure" action "spam-filter" rewrite "${com_spam_filter}" action "train-spam" rewrite "${com_train_spam}" action "train-good" rewrite "${com_train_good}" action "untrain-spam" rewrite "${com_untrain_spam}" action "untrain-good" rewrite "${com_untrain_good}" action "remove-spam-header" remove-header "${header_spam}" action "add-trained-good" add-header "${header_trained}" "${filtered_good}${filter_trained}" action "add-trained-spam" add-header "${header_trained}" "${filtered_spam}${filter_trained}" ### action for adding Lines: headers ### Current CVS versions can do this themselves. action "add-lines-header" add-header "Lines" "%[body_lines]" ### action to remove unneeded headers action "remove-ill-headers" rewrite "${com_filter_headers}" ### mark as read in maildirs. this requires /bin/sh to be somewhat POSIXly ### correct. ash, ksh, bash etc. will do; older bourne shells (like /bin/sh ### on OpenSolaris) will not. You'll need to use {base,dir}name with these. action "maildir-mark-as-read" exec "mf=\"%[mail_file]\" ; mv \"\${mf}\" \"\${mf%%/*}\"/../cur/\"\${mf##*/}:2,S\"" ### archiving action action "archive" mbox "${path}/archive/%[maildir]-%yq%Q" compress action "mbox-mark-as-read" add-header "Status" value "RO" ### handle mailinglists ### path actions #{{{ action "inbox" maildir "${path}/Inbox" action "debian-announce" maildir "${path}/debian-announce" action "debian-boot" maildir "${path}/debian-boot" action "debian-bsd" maildir "${path}/debian-bsd" action "debian-curiosa" maildir "${path}/debian-curiosa" action "debian-devel" maildir "${path}/debian-devel" action "debian-devel-announce" maildir "${path}/debian-devel-announce" action "debian-legal" maildir "${path}/debian-legal" action "debian-infrastructure-announce" maildir "${path}/debian-infrastructure-announce" action "debian-mentors" maildir "${path}/debian-mentors" action "debian-news-german" maildir "${path}/debian-news-german" action "debian-outbox" maildir "${path}/debian-outbox" action "debian-perl" maildir "${path}/debian-perl" action "debian-policy" maildir "${path}/debian-policy" action "debian-project" maildir "${path}/debian-project" action "debian-pts" maildir "${path}/debian-pts" action "debian-publicity" maildir "${path}/debian-publicity" action "debian-release" maildir "${path}/debian-release" action "debian-security" maildir "${path}/debian-security" action "debian-user" maildir "${path}/debian-user" action "debian-vote" maildir "${path}/debian-vote" action "debian-women" maildir "${path}/debian-women" action "openbsd-announce" maildir "${path}/openbsd-announce" action "openbsd-ipv6" maildir "${path}/openbsd-ipv6" action "openbsd-misc" maildir "${path}/openbsd-misc" action "openbsd-ports" maildir "${path}/openbsd-ports" action "openbsd-ports-bugs" maildir "${path}/openbsd-ports-bugs" action "openbsd-ports-security" maildir "${path}/openbsd-ports-security" action "openbsd-security-announce" maildir "${path}/openbsd-security-announce" action "openbsd-tech" maildir "${path}/openbsd-tech" action "openbsd-www" maildir "${path}/openbsd-www" action "openbsd-x11" maildir "${path}/openbsd-x11" action "perl-beginners" maildir "${path}/perl-beginners" action "perl-unicode" maildir "${path}/perl-unicode" action "perl-xs" maildir "${path}/perl-xs" action "mutt-dev" maildir "${path}/mutt-dev" action "mutt-ot" maildir "${path}/mutt-ot" action "mutt-users" maildir "${path}/mutt-users" action "fdm-users" maildir "${path}/fdm-users" action "tmux-users" maildir "${path}/tmux-users" action "fvwm" maildir "${path}/fvwm" action "fvwm-workers" maildir "${path}/fvwm-workers" action "geda-user" maildir "${path}/geda-user" action "git" maildir "${path}/git" action "grml" maildir "${path}/grml" action "grml-devel" maildir "${path}/grml-devel" action "taipan-mua" maildir "${path}/taipan-mua" action "zsh-users" maildir "${path}/zsh-users" action "zsh-workers" maildir "${path}/zsh-workers" action "cmus-devel" maildir "${path}/cmus-devel" action "libetpan-devel" maildir "${path}/libetpan-devel" action "libetpan-users" maildir "${path}/libetpan-users" action "leafnode" maildir "${path}/leafnode" action "remind-fans" maildir "${path}/remind-fans" action "screen-users" maildir "${path}/screen-users" action "slrn-users" maildir "${path}/slrn-users" action "tuhs" maildir "${path}/tuhs" action "vim-users" maildir "${path}/vim-users" action "linux-kernel" maildir "${path}/linux-kernel" action "bugtraq" maildir "${path}/bugtraq" action "full-disclosure" maildir "${path}/full-disclosure" action "pen-test" maildir "${path}/pen-test" action "schopppe" maildir "${path}/schopppe" action "xmms2" maildir "${path}/xmms2" #}}} ### rewrite actions (some mailinglist add tags to their subjects...) ### '1,/^$/...' only rewrites lines in the mail _headers_. #{{{ action "strip-full-disclosure" rewrite "${com_sed} '1,/^$/s/^\\(Subject:.*\\)\\[Full-disclosure\\] /\\1/'" action "strip-remind-fans" rewrite "${com_sed} '1,/^$/s/^\\(Subject:.*\\)\\[Remind-Fans\\] /\\1/'" action "strip-fvwm" rewrite "${com_sed} '1,/^$/s/^\\(Subject:\\) FVWM:/\\1/'" action "strip-grml" rewrite "${com_sed} '1,/^$/s/^\\(Subject:.*\\)\\[Grml\\] /\\1/'" action "strip-leafnode" rewrite "${com_sed} '1,/^$/s/^\\(Subject:.*\\)\\[leafnode-list\\] /\\1/'" action "strip-tuhs" rewrite "${com_sed} '1,/^$/s/^\\(Subject:.*\\)\\[TUHS\\] /\\1/'" #}}} ########################################################################### ### accounts for spam-training ### -asp-train-spam ### trains the message from stdin as spam; ### moves the mail to the appropriate folder ### -asp-train-good ### trains the message from stdin as ham; ### continues with normal rules to sort the message ### to the folder it belongs to. account "train-spam" disabled stdin account "train-good" disabled stdin ### sometimes you want to test new things by providing mails on stdin account "stdin" disabled stdin ########################################################################### ### Automatic archiving. ### This is a nice idea, I shamelessly stole from NicM's config. ### Mail is kept in Maildirs for 30 days. After that it is ### automatically moved to compressed mboxes, which in turn ### may by periodically removed (by cron for examples, or ### by hand). This (again) uses an account that is disabled, ### so it can be explicitly called by '-aarchive'. account "archive" disabled maildirs { #{{{ "${path}/Inbox" "${path}/cmus-devel" "${path}/debian-*" "${path}/fdm-users" "${path}/full-disclosure" "${path}/fvwm*" "${path}/geda-user" "${path}/grml*" "${path}/perl*" "${path}/git" "${path}/leafnode" "${path}/linux-*" "${path}/mutt-*" "${path}/openbsd-*" "${path}/remind-fans" "${path}/screen-users" "${path}/slrn-users" "${path}/tmux-users" "${path}/tuhs" "${path}/vim-users" "${path}/xmms2" "${path}/zsh-*" #}}} } match account "archive" and age > %{max_age} days actions { "mbox-mark-as-read" "archive" } match account "archive" action "keep" ########################################################################### ### handle mail ### do catchall as early as possible. match string "${do_catchall}" to "^yes$" action "catchall" continue ########## zblog messages ########## ### mails to blog -at- bewatermyfriend -dot- org are meant for zblog. match account "blog" action "zblog" match account "comments" action "zcomm" ########## killfiling ########## ### killfiling on From, From:, Reply-To: and Sender headers ### If your killfile is rather large, this will slow down fdm ### considerably. So do this only on people that really disturb you. match pipe "${com_pfh} | grep -Eqif ${killfile}" returns ( 0, ) actions { "killfile" "maildir-mark-as-read" } ########## spam handling ########## ### force message from stdin to spamfolder and train it as spam match account "train-spam" { match "^${header_spam}" in headers action "untrain-good" continue match all action "remove-spam-header" continue match all action "train-spam" continue match "^${header_spam}:[ \t]*${filtered_spam}" in headers action "spam" match all action "train-spam" continue match "^${header_spam}:[ \t]*${filtered_spam}" in headers action "spam" match all action "train-spam" continue match "^${header_spam}:[ \t]*${filtered_spam}" in headers action "spam" match all action "train-spam" continue match "^${header_spam}:[ \t]*${filtered_spam}" in headers action "spam" match all action "train-spam" continue match all action "spam" } ### train message from stdin as ham match account "train-good" { match "^${header_spam}: ${filtered_good}" in headers action "untrain-spam" continue match all action "remove-spam-header" continue match all action "train-good" continue } ### scan for spam match not "^${header_spam}" in headers action "spam-filter" continue ### move messages marked as spam to spamfolder match "^${header_spam}:[ \t]*${filtered_spam}" in headers action "spam" match "^${header_spam}:[ \t]*${filtered_unsure}" in headers action "spam-unsure" ########## modifying headers ########## ### add Lines: header if it is missing. match not "^Lines:" in headers action "add-lines-header" continue ### remove headers I don't care about match "^${ill_headers}:" in headers action "remove-ill-headers" continue ########## sorting ########## ### debian- mailinglists and pts match "^List-Id:[ \t]*