POP Before Auth Tie in to MIMEDefang

by Kevin A. McGrail (kmcgrail@pccc.com)

Maintained at: http://www.pccc.com/downloads/

Changed on 5/20/04 based on comments from Ole Craig
Changed on 5/25/04 to change action_delete_header to action_delete_all_headers

Add (or modify) these four routines to your mimedefang subfilter.  They will utilize the POP before Auth 
database (see http://www.peregrinehw.com/downloads/sendmail/current-8.12.X/untarred/INSTALL).


sub filter_initialize {
  #INITIALIZE THE MODULES AND PARAMETERS NEEDED TO SETUP A TIE TO THE POP BEFORE SMTP AUTH DATABASE
  #Thanks to Ole Craig for comments on this functionality of this feature
  # 
  # NOTE: the database MUST BE READABLE BY THE DEFANG USER (try "chgrp defang /etc/mail/popauth.db" or
  #       even chmod 744 /etc/mail/popauth.db)
            
  use DB_File;
            
  use vars qw($popauthdbfile);
  $popauthdbfile = "/etc/mail/popauth.db";
}           

# FUNCTION TO TIE READONLY TO A DB_FILE
sub opendb_read($$) {
  my ($dbfile) = @_;
  my (%db);

  tie (%db, "DB_File", $dbfile, O_RDONLY, 0, $DB_HASH) || md_syslog('critical', "Could not tie to database: $dbfile!");              
  return \%db;
}

sub cleanup {
  #NO CURRENT CLEANUP FUNCTIONS
}

# FUNCTION TO CLOSE TO A TIED DB_FILE
sub closedb($) {
  my ($db) = @_;
  untie %$db;
}


These function will allow your mimedefang filter to detect whether an email was sent using POP Before SMTP 
Authentication.  I then used that information to add a header to the email and to set a variable $popauth 
to true in my filter_end routine.

    #ADD A POP BEFORE SMTP HEADER (& remove any pre-existing ones)
    my ($popauth, $popauthdb);
    $popauth = 0;
  
    $popauthdb = &opendb_read($popauthdbfile);
  
    action_delete_all_headers("X-Pop-Before-SMTP-Auth");
    if ($popauthdb->{$RelayAddr}) {
      action_change_header("X-Pop-Before-SMTP-Auth","$RelayAddr");
      $popauth++;
    } 
    &closedb($popauthdb);


Now, I use the existence of this header to bypass calling SpamAssassin.  If you are calling SpamAssassin 
from your filter, simply add a check for the variable $popauth:

   if ($Features{"SpamAssassin"} and $popauth < 1) {

Otherwise, you modify your procmail recipe.  For example, I use a server-wide procmailrc recipe 
in /etc/procmailrc.  The following recipe would pass emails to spamd that are less than 256K in size and
do not have the header we added above


    DROPPRIVS=yes
    
    :0fw
    * < 256000
    * !^X-Pop-Before-SMTP-Auth
          | /usr/bin/spamc -f
    
          :0e
          {
             EXITCODE=$?
          }
