Spam filter on header content instead of running spamassassin

Here is a patch to implement a spam filter using pattern matching on a
configurable header field, instead of running spamassassin. At our
university, the mail system already runs spamassassin, and set a
header with the current spam score. This mail plugin make it possible
for us to get RT to filter on this header, and throw away mails with
very high spam score, and put in a special RT queue the mails with a
lower spam score.

Please include this in a future version of RT, or let me know what
would need to change for it to be acceptable into RT.

— lib/RT/Interface/Email/Filter/SpamHeader.pm 2004-02-18 16:26:44.000000000 +0100
+++ lib/RT/Interface/Email/Filter/SpamHeader.pm 2004-08-31 08:28:53.000000000 +0200
@@ -0,0 +1,101 @@
+# BEGIN LICENSE BLOCK+# Copyright © 2004 Petter Reinholdtsen pere@hungry.com
+# This work is made available to you under the terms of Version 2 of
+# the GNU General Public License. A copy of that license should have
+# been provided with this software, but in any event can be snarfed
+# from www.gnu.org.
+# This work is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+# Unless otherwise specified, all modifications, corrections or
+# extensions to this work which alter its source code become the
+# property of Best Practical Solutions, LLC when submitted for
+# inclusion in the work.
+# END LICENSE BLOCK
+package RT::Interface::email::Filter::SpamHeader;
+use RT::EmailParser;
+sub GetCurrentUser {

  • my %args = ( Message => undef,
  •    CurrentUser => undef,
    
  •    AuthLevel   => undef,
    
  •    Queue       => undef,
    
  •    @_ );
    
  • Check configuration.

  • unless ($RT::SpamHeader) {
  • $RT::Logger->error(“SpamHeader: Content of $RT::SpamHeader is empty.”);
  • return ($args{‘CurrentUser’}, $args{‘AuthLevel’});
  • }
  • unless ($RT::SpamLowMatch) {
  • $RT::Logger->error(“SpamHeader: Content of $RT::SpamLowMatch is empty.”);
  • return ($args{‘CurrentUser’}, $args{‘AuthLevel’});
  • }
  • my $Message = $args{‘Message’};
  • unless ($Message) {
  • $RT::Logger->error(“SpamHeader: $Message is empty.”);
  • return ($args{‘CurrentUser’}, $args{‘AuthLevel’});
  • }
  • my $head = $Message->head;
  • my $spamtag = $head->get($RT::SpamHeader);
  • if (defined $RT::SpamHighMatch && $spamtag =~ m/$RT::SpamHighMatch/) {
  • if ($RT::SpamHighQueue) {
  •   # Move to spam queue
    
  •   $args{'Queue'}->Load( $RT::SpamHighQueue );
    
  • } else {
  •   # tell Gateway() to drop the mail
    
  •   $RT::Logger->info("SpamHeader: Dropping spam message!");
    
  •   return ($args{CurrentUser}, -1);
    
  • }
  • }
  • if ($spamtag =~ m/$RT::SpamLowMatch/) {
  • if ($RT::SpamLowQueue) {
  •   # Move to spam queue
    
  •   $args{'Queue'}->Load( $RT::SpamLowQueue );
    
  • } else {
  •   # tell Gateway() to drop the mail
    
  •   $RT::Logger->info("SpamHeader: Dropping spam message!");
    
  •   return ($args{CurrentUser}, -1);
    
  • }
  • }
  • $RT::Logger->debug(“SpamHeader: Accepting non-spam message.”);
  • return ($args{‘CurrentUser’}, $args{‘AuthLevel’});
    +}
    +=head1 NAME
    +RT::Interface::email::Filter::SpamHeader - Filter spam based on header tags
    +=head1 SYNOPSIS
  • Set($SpamHeader, “X-UiO-Spam-Score”); # Required
  • Set($SpamLowMatch, “ss+”); # Required
  • Set($SpamLowQueue, “spam”); # Optional
  • Set($SpamHighMatch, “ssssss+”); # Optional
  • Set($SpamHighQueue, undef); # Optional
  • @RT::MailPlugins = (“Filter::SpamHeader”, …); # Required
    +=head1 DESCRIPTION
    +This plugin checks to see if an incoming mail is spam by looking at
    +the header field given in $SpamHeader, matching it using the regex in
    +$SpamLowMatch and $SpamHighMatch. If the regex matches, it is
    +considered spam and dropped on the floor or moved to a spam queue if
    +the corresponding queue variable is set. Otherwise, it is handled as
    +normal.
    +=cut
    +1;