Exim 4.69 (or 4.71) ACL for SpamAssassin

I was having trouble with Exim not adding headers to SpamAssassin-checked emails. One day, when I should have really been doing something else, I read Chapter 40 of Exim’s specification, and all became clear.

Here’s what my appropriate ACL (in /etc/mail/exim.conf) looks now, almost completely by-the-book:

  # ...
  # malware section
  # ...
  # Add headers to a message if it is judged to be spam. Before enabling this,
  # you must install SpamAssassin. You may also need to set the spamd_address  
  # option above.
  # spams are never big and spamassassin can die on big emails, so we  
  # limit its use under 100kb  
  accept  condition = ${if >={$message_size}{100k}{yes}{no}}

  # put headers in all messages (no matter if spam or not)
  warn  spam = spamd:true
        add_header = X-Spam-Score: $spam_score ($spam_bar)
        add_header = X-Spam-Report: $spam_report
  # add second subject line with *SPAM* marker when message
  # is over threshold
  warn  spam = spamd
        add_header = Subject: *SPAM* $h_Subject:

  # reject spam at high scores (> 20)
  deny  message = This message scored $spam_score spam points.
        spam = spamd:true
        condition = ${if >{$spam_score_int}{200}{1}{0}}

  # Accept the message.

Emacs with Tramp using zsh

First off, I recommend reading the relevant parts of the user manual, you might find the answer there.

Now, to the issue.

I installed tramp and added this to ~/.emacs:

(require 'tramp)
(setq tramp-default-method "scp")

Nothing special here, except it didn’t work. (The message was something like “waiting 60s for local shell”. Of course, I didn’t write it down, and it got lost in the browsing cache.)

So I turned on more verbose debugging, in ~/.emacs also:

(setq tramp-debug-buffer t)
(setq tramp-verbose 10)

The “logs”, mind you, are written into buffers: *debug/scp remotehost* are the messages and *tramp/scp remotehost* is the medium-rare (as compared to raw) data received.

If you open the latter and see characters like ^]]C4 or ^M, then it might be due to the shell prompt setting on the remote host. The manual advises wisely as to what should be considered.

One solution found floating on the internets is checking for the terminal type. Add this to the remote host’s .zshenv:

if [ "$TERM" = "dumb" ]
unsetopt zle
unsetopt prompt_cr
unsetopt prompt_subst
# unfunction precmd # these two are not
# unfunction preexec # working for me
PS1='$ '

Also, make sure you’re not re-setting it somewhere else later, say .zshrc. A check should be enough even if you do:

if [ "$TERM" != "dumb" ]; then
# Set prompts
PROMPT='%m%# '

Blocking some DIV ad boxes with Privoxy

If you want to block one of those shiny-ass ads (think workplace sanitation), here’s a few simple one-liners. (Everything’s in /etc/privoxy.)

FILTER: div-ads DIV ad blocks.
s/<div id="banner_box"/<div id="crap" style="display:none;"/g

{ +filter{div-ads} }

Don’t forget to uncomment that actionsfile user.action from your config file.

Info lifted from here.

Samsung ML-2015 with CUPS 1.4 on Arch Linux

As you might know (yeah, right), I am a proud owner of a Samsung ML-2015 laser printer, this paper-munching, smoke-exhausting hellish machine (which is, in fact, an ML-2010 re-branded for the russian and post-soviet states, so that Samsung can provide localised support).

Updating to CUPS 1.4 on Arch Linux kind of broke the printer. It’s still visible in the CUPS interface, but doesn’t print anything (the jobs are on hold, “waiting for the printer to become available”). The kernel is, usblp module disabled as per Arch newsfeed suggestion.

The solution was simple – getting to the “Printers” tab in the web interface and modifying the printer to use a different connection (the one without “usb://”).

How to determine raw (unmounted) disk file system type

sudo fdisk -ls

Analog Devices AD1984A (snd-hda-intel) on HP 6730s, Arch Linux

Here’s a great table for all your snd-hda-intel needs: Ubuntu Wiki audio_intel_da.

Making a GRUB boot floppy

mkfs -V -t msdos /dev/fd0
mount /dev/fd0 /media/floppy
cd /media/floppy
mkdir boot
mkdir boot/grub
cp -pa /boot/grub/* /media/floppy/boot/grub
umount /media/floppy
/sbin/grub --batch --device-map=/dev/null <<EOF
device (fd0) /dev/fd0
root (fd0)
setup (fd0)

Lifted from Linux-SXS and GNU Hurd FAQ.

Kiddies playing

Here’s what exim caught:

> 2009-09-15 23:59:31 SMTP protocol synchronization error (input sent without waiting for greeting):
+rejected connection from H=[] input="GET http://www.scanproxy.com:80/p-25.html
+HTTP/1.0\r\nContent-Type: text/html\r\nProxy-Connection: keep-alive\r\nHost: http://www.scanproxy.com\r\nAccept:
> 2009-09-15 23:59:32 SMTP protocol synchronization error (input sent without waiting for greeting):
+rejected connection from H=[] input="0401"
> 2009-09-15 23:59:33 SMTP protocol synchronization error (input sent without waiting for greeting):
+rejected connection from H=[] input="0501" is Chunghwa Telecom Co., Ltd. in Taiwan.

Common Lisp: how to split a program (project) into many files

This here is good if you move from other languages and wish to know fast.

SpamAssassin and Exim on Arch Linux: some config trouble

I had this happen – SA wasn’t reading user_prefs out of a proper home dir:

[12071] info: spamd: creating default_prefs: //.spamassassin/user_prefs
[12071] dbg: config: using "/.spamassassin" for user state dir
[12071] dbg: config: mkdir /.spamassassin failed: mkdir /.spamassassin: Permission denied at /usr/share/perl5/vendor_perl/Mail/SpamAssassin.pm line 1577
[12071] dbg: config: Permission denied
[12071] warn: config: cannot write to //.spamassassin/user_prefs: No such file or directory
[12071] info: spamd: failed to create readable default_prefs: //.spamassassin/user_prefs
[12071] dbg: config: read_scoreonly_config: cannot open "//.spamassassin/user_prefs": No such file or directory

I thought this was due to the way spamassassin was invoked, so I tried specifying the user and homedir explicitly. It didn’t work. I tried creating a ‘spamd’ user, a homedir, changing the invocation to that:

sudo spamd -c --max-children 3 --username spamd -H "/var/lib/spamassassin/" -s stderr -D

Didn’t help.

Then I RTFMed some. That reminded me of writing something about user ‘nobody’ in exim.conf. That’s the user for which spam filtering is invoked; so if you allow per-user configuration, it doesn’t really matter that you specify “/var/lib/spamassassin” as a homedir, that’s just for the parent spamd process. For every child, the directory will be changed; for ‘nobody’ it’s ‘/’.

So I changed that line to have ‘spamd’ instead, and voila!

[12071] info: spamd: creating default_prefs: /var/lib/spamassassin/.spamassassin/user_prefs
[12071] dbg: config: using "/var/lib/spamassassin/.spamassassin" for user state dir
[12071] warn: config: created user preferences file: /var/lib/spamassassin/.spamassassin/user_prefs
[12071] dbg: conf: finish parsing