[Mimedefang] MIMEDefang not rejecting messages, etc.

Chris Gauch cgauch at digicon.net
Mon May 31 18:50:54 EDT 2004


I've recently configured our spamassassin gateway server to use MIMEDefang
for handling mail filtering (instead of spamass-milter or procmail, neither
of which worked reliably).  The spamassassin functionality is working fine
(using SA 2.63), I've added custom code to modify headers, subject, and
encapsulate original messages (if spam).  I do not use a virus filter
application in conjunction with MIMEDefang as we handle anti-virus on our
main mail server.  Our server generally receives in excess of 150,000
messages per day (average), and is used for filtering INCOMING mail only, it
does not handle outgoing.

My system config is as follows:
RedHat 9.0 Linux (latest kernel, etc.)
Perl 5.8.0
MIMEDefang 2.43
Sendmail 8.12.11
Spamassassin 2.63

Here's the issue -- the function below appears to do nothing, no attachments
with "bad file extensions" are ever dropped:

# This procedure returns true for entities with bad filenames.
sub filter_bad_filename ($) {
    my($entity) = @_;
    my($bad_exts, $re);

    # Bad extensions
    $bad_exts =
'(ade|adp|app|asd|asf|asx|bas|bat|chm|cmd|com|cpl|crt|dll|exe|fxp|hlp|hta|ht
o|inf|ini|ins|isp|jse?|lib|lnk|mdb|mde|msc|msi|msp|mst|ocx|pcd|pif|prg|reg|s
cr|sct|sh|shb|shs|sys|url|vb|vbe|vbs|vcs|vxd|wmd|wms|wmz|wsc|wsf|wsh|\{[^\}]
+\})';

    # Do not allow:
    # - CLSIDs  {foobarbaz}
    # - bad extensions (possibly with trailing dots) at end
    $re = '\.' . $bad_exts . '\.*$';

    return 1 if (re_match($entity, $re));

    # Look inside ZIP files
    if (re_match($entity, '\.zip$') and
        $Features{"Archive::Zip"}) {
        my $bh = $entity->bodyhandle();
        if (defined($bh)) {
            my $path = $bh->path();
            if (defined($path)) {
                return re_match_in_zip_directory($path, $re);
            }
        }
    }
    return 0;

I call the subroutine in sub filter:
if (filter_bad_filename($entity)) {
        md_graphdefang_log('bad_filename', $fname, $type);
        action_quarantine_entire_message;
        return action_drop_with_warning("An attachment named $fname was
removed from this document as it\nconstituted a security hazard.  If you
require this document, please contact\nthe sender and arrange an alternate
means of receiving it.\n");
    }

This function is also called subroutine filter multipart.  Why are NO
attachments dropped (no warning message is written to the email when a PIF,
SCR, etc.), the filter_bad_filename does not do anything.    

Another function, which I added to prevent spoofing and forging, does not
have an effect.

sub filter_multipart ($$$$) {
    my($entity, $fname, $ext, $type) = @_;

    return if message_rejected(); # Avoid unnecessary work

    if (filter_bad_filename($entity)) {
        md_graphdefang_log('bad_filename', $fname, $type);
	action_notify_administrator("A MULTIPART attachment of type $type,
named $fname was dropped.\n");
	return action_drop_with_warning("An attachment of type $type, named
$fname was removed from this document as it\nconstituted a security hazard.
If you require this document, please contact\nthe sender and arrange an
alternate means of receiving it.\n");


    }

    # eml is bad if it's not message/rfc822
    if (re_match($entity, '\.eml') and ($type ne "message/rfc822")) {
        md_graphdefang_log('non_rfc822',$fname);
	return action_drop_with_warning("A non-message/rfc822 attachment
named $fname was removed from this document as it\nconstituted a security
hazard.  If you require this document, please contact\nthe sender and
arrange an alternate means of receiving it.\n");
    }

    # Block message/partial parts
    if (lc($type) eq "message/partial") {
        md_graphdefang_log('message/partial');
	action_bounce("MIME type message/partial not accepted here");
	return;
    }

    return action_accept();
}

Do these functions need to be called somewhere else (such as filter_end) in
order to work?  I am fairly new to perl (but have an extensive C/C++/Java
background); some of this stuff does not seem logical to me. 

The last issue I have is getting the "autolearn" status to show up in the
header.  I found this snippet of code online:

$line .= "\tautolearn=";

  if (!defined($SASpamTester->{auto_learn_status})) {
    $line .= "no\n\t";
  } elsif ($SASpamTester->{auto_learn_status}) {
    $line .= "spam\n\t";
  } else {
    $line .= "ham\n\t";
  }  

This code is placed in a separate subroutine that builds the spamassassin
"X-Spam-Status" line.  It does not work, however.  Autolearn=no, no matter
what, and I know autolearn is working for spam/ham because I can see my
bayes databases updated quite regularly (mod date and file size always
changing, etc.).  

Other than that, MD is working quite well.  It is a memory/CPU hog, but
adding more RAM should reduce our server load (load averages are up above
the 5.x range, sometimes spiking above 10.x).

Any help/suggestions would be highly appreciated.  Thanks.

- Chris  





More information about the MIMEDefang mailing list