Anyone going to fix RT::Interface::Email::Filter::SpamAssassin

I’m still not able to use this module as part of my MailPlugins because it
overwrites $_ inside of the gateway function where it gets called casuing
it to mulch up the MailPlugin list the first time it detects a SPAM.

I saw soemone post some solutions quite a while back, but they don’t seem
to work for me – I get an ‘ever expanding’ entry instead of a blank one so
it ends up saying Filter::SpamAssassin like 2-3 times.

Anyone? OR am I just SOL if I actually want to protect my queues with SA?

Undocumented Features quote of the moment…
“It’s not the one bullet with your name on it that you
have to worry about; it’s the twenty thousand-odd rounds
labeled `occupant.’”
–Murphy’s Laws of Combat

I’m still not able to use this module as part of my MailPlugins because it
overwrites $_ inside of the gateway function where it gets called casuing
it to mulch up the MailPlugin list the first time it detects a SPAM.

I just rewrote it but haven’t had time to submit a patch to Jesse yet.
I’ll append it below. Been using it with RT 3.0.10 on Solaris/MySQL/FastCGI,
not tested in any other configuration but it shouldn’t matter.

I was going to modify the plugin driver to protect $_ but it was simpler
to just do it in the SpamAssassin plugin instead, so it only patches the one file.

It’s been running with SA 2.63 for a couple weeks now, no problems.

-- Larry

This is the final version of my fix to the SpamAssassin filter plugin.
It takes two new configuration options:

$SpamAssassinRejectFactor - factor by which to multiply the spam threshold
to reach the threshold for deleting or filing messages so they don’t
become tickets.
$SpamAssassinRejectMailbox - pathname of mailbox in which to file rejected
spams; by default they are just dropped on the floor. Must be writable
by user running RT.

This version does not require any changes to the Email.pm driver, it
localizes $_ since something in SpamAssassin apparently munges it.

*** SpamAssassin.pm Fri Jan 2 17:55:55 2004
— SpamAssassin.pm Wed May 26 00:28:53 2004
*** 24,41 ****
package RT::Interface::email::Filter::SpamAssassin;

use Mail::SpamAssassin;
my $spamtest = Mail::SpamAssassin->new();

sub GetCurrentUser {
! my $item = shift;
! my $status = $spamtest->check ($item);
! return (undef, 0) unless $status->is_spam();
! eval { $status->rewrite_mail() };
! if ($status->get_hits > $status->get_required_hits()*1.5) {
! # Spammy indeed
! return (undef, -1);
}
! return (undef, 0);
}

=head1 NAME
— 24,74 ----
package RT::Interface::email::Filter::SpamAssassin;

use Mail::SpamAssassin;

  • use POSIX qw(strftime);

  • use Fcntl ‘:flock’; # import LOCK_* constants
    my $spamtest = Mail::SpamAssassin->new();

    sub GetCurrentUser {
    ! # magic: localize $_ because something in spamassassin munges it, breaks caller.
    ! local $;
    ! my $result = 0;
    ! my %args = ( Message => undef,
    ! @
    );
    ! my $status = $spamtest->check_message_text($args{‘Message’}->as_string());
    ! my $hits = $status->get_hits();
    ! my $factor = defined($RT::SpamAssassinRejectFactor) ? $RT::SpamAssassinRejectFactor : 1.5;
    ! if ($status->is_spam() &&
    ! $hits > $status->get_required_hits() * $factor) {
    ! # Spammy indeed, file in mailbox or drop it.
    ! my $mid = $args{‘Message’}->head()->get(‘Message-Id’);
    ! if (defined $RT::SpamAssassinRejectMailbox) {
    ! if (open(MBOX, “>> $RT::SpamAssassinRejectMailbox”)) {
    ! flock(MBOX,LOCK_EX);
    ! # in case it got appended to while we waited:
    ! seek(MBOX, 0, 2);
    ! # mbox header “from” line, reduced to single word:
    ! my ($from) = $args{‘Message’}->head()->get(‘From’);
    ! $from = ($from =~ m/<(\S+)>/) ? $1 : ‘some-spammer’;
    ! print MBOX “From $from “. strftime(”%a %b %e %H:%M:%S %Y\n”, localtime);
    ! $args{‘Message’}->print(MBOX);
    ! flock(MBOX,LOCK_UN);
    ! close(MBOX);
    ! $RT::Logger->info(“Filter::SpamAssassin: Filing message $mid in spambox because spam score = $hits”);
    ! } else {
    ! $RT::Logger->error(“Filter::SpamAssassin: Could not open mbox for appending: $RT::SpamAssassinRejectMailbox : $!”);
    ! }
    ! } else {
    ! $RT::Logger->info(“Filter::SpamAssassin: Dropping message $mid because spam score = $hits”);
    ! }
    ! $result = -1;
    ! } else {
    ! $args{‘Message’}->head()->replace(‘X-RT-SpamAssassin-Score’, sprintf(“%.3f”, $hits));
    ! $args{‘Message’}->head()->replace(‘X-RT-SpamAssassin-Flag’, ($status->is_spam() ? “YES” : “NO”));
    ! $args{‘Message’}->head()->replace(‘X-RT-SpamAssassin-Level’, ‘*’ x ($hits >= 0 ? int($hits): 0));
    }
    ! $status->finish();
    ! return (undef, $result);
    }

    =head1 NAME

Anyone? OR am I just SOL if I actually want to protect my queues with SA?

I posted a pre-filter a while ago and actually here at Best Practical,
we’ve been much happier filtering out spam before it gets anywhere
near RT.

Jesse

Anyone? OR am I just SOL if I actually want to protect my queues with
SA?

I posted a pre-filter a while ago and actually here at Best Practical,
we’ve been much happier filtering out spam before it gets anywhere
near RT.

Yeah we do a lot of frontline stuff too, I just don’t want to complicate
the injection process any. It’s a pain in the butt to shell out to pass
off messages via ‘spamassassin’ or ‘spamc/spamd’.

I’ll dig back in the archives but i guess that’s going to be the only way
is to write some script around spamc. Last time I did this though you had
to run the damned message through SA 2x if you wanted header changes done
because spamc wouldn’t give an exit code AND header munching. I’m hoping
someone got out the clue bat and fixed that one.

Undocumented Features quote of the moment…
“It’s not the one bullet with your name on it that you
have to worry about; it’s the twenty thousand-odd rounds
labeled `occupant.'”
–Murphy’s Laws of Combat

I’m still not able to use this module as part of my MailPlugins because
it overwrites $_ inside of the gateway function where it gets called
casuing it to mulch up the MailPlugin list the first time it detects a
SPAM.

I just rewrote it but haven’t had time to submit a patch to Jesse yet.
I’ll append it below. Been using it with RT 3.0.10 on
Solaris/MySQL/FastCGI, not tested in any other configuration but it
shouldn’t matter.

I was going to modify the plugin driver to protect $_ but it was simpler
to just do it in the SpamAssassin plugin instead, so it only patches the
one file.

Ooooo goody! Just what I wanted coz I’m lazy LOL :slight_smile: Thanks Larry, I’ll
patch it into a local SA filter module and give it a rip.

TYVM!

I posted a pre-filter a while ago and actually here at Best Practical,
we’ve been much happier filtering out spam before it gets anywhere
near RT.

It is such a universal problem that it would be nice if RT could
handle it internally. How about adding something that looks like
a queue from the UI but is really kept in separate tables until
manually deleted or accepted? Holding in the spam queue could
be triggered either by the contents of a header if you do
spam scanning at the system level or as an option, RT could
run SpamAssassin internally. Hmmm, I suppose every real queue
would have to have an optional matching spam holding queue so
the permissions to view it would match - maybe generalizing to
a ‘moderated’ queue would be a better idea, with spam tagging
being one thing that could trigger the requirement for a moderator
to manually make the choice to accept or not.

Les Mikesell
les@futuresource.com