[Mimedefang] running mimedefang with a second instance of spamassassin

Fred Bacon fred.w.bacon at gmail.com
Thu Apr 19 19:59:56 EDT 2012

I could use some advice.  I'm running mimedefang 2.73, spamassassin
3.3.1 and perl 5.10.1 on a Red Hat 6.2 machine.

I'm putting the finishing touches on a project that I started a couple
of months ago.  The idea is to run a second instance of spamassassin
from my mimedefang filter with a special set of rules.  In my case,
I'm not trying to detect spam, I'm trying to detect certain types of
messages coming in to a specific address and route them to specific
people.  After testing my rules against a corpus of about 750
messages, I feel confident that that is working correctly.

To create a second instance of spamassassin, I copied the relevant
code from mimedefang.pl, changed the function names and put them into
my mimedefang-filter.   Instead of using SASpamTester, I create
another instance of spamassassin and use that within my filter.

Unfortunately, this is only working intermittently.  Maybe every fifth
or sixth message will be detected.  The remaining messages return no
matched rules at all!  I've attached a copy of my mimedefang-filter

When I run spamassassin from the command line with my rules, I use the
following options

spamassassin -C /etc/mail/journal -t -L < message

This recognizes even those messages which aren't recognized from my
mimedefang-filter.  Furthermore, it doesn't use the standard rules, so
that only my special rule set is used.

Within my filter, I've variously tried setting site_rules_filename,
rules_filename and both together equal to /etc/mail/journal, but the
results are not equivalent to what I get with the command line.
Usually (but not always!), no rules will match on the message
whatsoever.  Can someone tell me if I'm doing this wrong?

Thanks for any help that you can give me.

Fred Bacon

I'll pull out a few of the important sections from my filter.  First
is my initialization subroutine

sub sa_journal_init (;$) {
    my($config) = @_;
    my $LOCAL_SITE_RULES_DIR = '/etc/mail/journals';
    my $LOCAL_STATE_DIR = '/var/lib';

    unless ($Features{"SpamAssassin"}) {
        md_syslog('err', "Attempt to call SpamAssassin function, but
SpamAssassin is not installed.");
        return undef;

    if (!defined($SAToCTester)) {
        if (!defined($config)) {
            if (-r '/etc/mail/sa-mimedefang.cf') {
                $config = '/etc/mail/sa-mimedefang.cf';
            } else {
                return undef;

        my $sa_args = {
                local_tests_only    => 1,
                dont_copy_prefs     => 1,
                site_rules_filename => $LOCAL_SITE_RULES_DIR,
                userstate_dir       => $LOCAL_STATE_DIR,
                userprefs_filename  => $config,
                user_dir            => $Features{'Path:QUARANTINEDIR'},

        $SAToCTester = Mail::SpamAssassin->new( $sa_args );

    return $SAToCTester;

In my filter_end section, I've added the code:

    # First we want to deal with journals.
    # We require that SpamAssassin be installed, since our scheme is based
    # on SpamAssassin rules.
    if ($Features{"SpamAssassin"}) {
        # we want to search the list of recipients
        foreach $rcpt (@Recipients) {
            # We are only testing for TOCs in xxx and yyy's email
            if ( $rcpt =~ /^<?(xxx|yyy)\@example\.com>?$/i &&
!($Subject =~ /\[TOC\]/) ) {
                # first let's see if this is a journal.
                # We use a special instance of SpamAssassin with a limited
                # number of rules related to journals.
                my($hits, $req, $names, $report) = sa_journal_check();

                # Debugging help
                md_syslog ( 'warning', "Journal Names:  $names" );
                md_syslog ( 'warning', "Journal Subject: $Subject" );
                action_change_header ( "X-Journal-Rules", $names );

                # We should only have matched one journal,
                # but take precautions just in case
                @journals = split /,/, $names;
                foreach $jname (@journals) {
                    if ( exists %journal_list->{$jname} ) {
                        # Okay, this is a journal, we need to remove
the current
                        # addressee and redirect the message to the mailing list
                        action_change_header("To", '<who at example.com>');
                        add_recipient('<who at example.com>');

                        # we need to add the journal tag as a Keywords header
                        # so that GNU Mailman will recognize it.
                        action_change_header("Keywords", $jname );

                        # Since this was a journal table of contents,
let's return here.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mimedefang-filter
Type: application/octet-stream
Size: 26459 bytes
Desc: not available
URL: <https://lists.mimedefang.org/pipermail/mimedefang_lists.mimedefang.org/attachments/20120419/c975b12c/attachment.obj>

More information about the MIMEDefang mailing list