[rt-users] Anyone going to fix RT::Interface::Email::Filter::SpamAssassin
Larry Stone
lcs at MIT.EDU
Sat Jun 5 00:02:51 EDT 2004
> 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
More information about the rt-users
mailing list