[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