[Mimedefang] Rejecting e-mails with blank CC: and Reply-To:

Scott Nelson sbnelson at thermeon.com
Wed Apr 11 15:13:44 EDT 2012


On Apr 11, 2012, at 1:49 PM, David F. Skoll wrote:

> You need to
> post your filter code if you expect any help.

I thought I posted enough, but here is the full thing, only some comments removed to make it smaller:

# -*- Perl -*-
$AdminAddress = 'postmaster at thermeon.com';
$AdminName = "Thermeon Postmaster";
$DaemonAddress = 'mimedefang at thermeon.com';
$AddWarningsInline = 0;
md_graphdefang_log_enable('mail', 1);
$Stupidity{"NoMultipleInlines"} = 0;
$ClamdSock = "/var/run/clamav/clamd.sock";
detect_and_load_perl_modules();

sub filter_bad_filename  {
    my($entity) = @_;
    my($bad_exts, $re);

    return 0; # pretend all is well but bypass checking files.

    # Bad extensions
    $bad_exts = '(ade|adp|app|asd|asf|asx|bas|bat|chm|cmd|com|cpl|crt|dll|exe|fxp|hlp|hta|hto|inf|ini|ins|isp|jse?|lib|lnk|mdb|mde|msc|msi|msp|mst|ocx|pcd|pif|prg|reg|scr|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;
}

sub has_spam_words {
    my $text = shift;
    return $text =~ /eprospector|groupon|priceline|nytimes|recycle|diversity|cincom|grainger|casino|techrepublic|ientry\.com|businesscards|barkoff|swiss|refinance|b21pubs\.com|directbuy|pharma|flyzik|coupon|<dating>|watches|harte-hanks|lorman|ocmetro|pills|viagra|wallstreet|pimsleur|jupiter|x10|lasik|visiontoamerica|RX-Store|prevention\.delivery\.net|patriotupdate|investmentu|internationalliving|healthiernews|earlytorise|conservativeactionalerts|personalliberty|secretsline|penis|\.info>/i;
}

sub filter_sender {
    my ($sender, $ip, $hostname, $helo) = @_;

    if (has_spam_words($sender)) {
        return ('REJECT', 'Message rejected.');
    }

    return ('CONTINUE', "ok");
}

sub filter_begin {
    my($entity) = @_;

    if ($SuspiciousCharsInHeaders) {
        md_graphdefang_log('suspicious_chars');
	# action_quarantine_entire_message("Message quarantined because of suspicious characters in headers");
	# Do NOT allow message to reach recipient(s)
	return action_discard();
    }

    if (open(HEADERS, "<HEADERS")) {
        while(<HEADERS>) {
            next unless /^(To|From|Cc|Subject):/i;
            if (has_spam_words($_)) {
                md_syslog('notice',"$1: header had a spam word in it: $_\n");
                return action_discard();
            }
        }
        close(HEADERS);
    } else {
        md_syslog('err',"couldn't open HEADERS temp file: $!\n");
    }

    md_copy_orig_msg_to_work_dir_as_mbox_file();

    my($code, $category, $action) = message_contains_virus();

    $FoundVirus = ($category eq "virus");

    if ($FoundVirus) {
	md_graphdefang_log('virus', $VirusName, $RelayAddr);
	md_syslog('warning', "Discarding because of virus $VirusName");
	return action_discard();
    }
}

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

    return if message_rejected(); # Avoid unnecessary work

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

    if (filter_bad_filename($entity)) {
        md_graphdefang_log('bad_filename', $fname, $type);
	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");
    }

    return action_accept();
}

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");
    }

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

    return action_accept();
}


sub defang_warning {
    my($oldfname, $fname) = @_;
    return
	"An attachment named '$oldfname' was converted to '$fname'.\n" .
	"To recover the file, right-click on the attachment and Save As\n" .
	"'$oldfname'\n";
}

sub filter_end {
    my($entity) = @_;

    return if message_rejected();

    if ($Features{"SpamAssassin"}) {
	if (-s "./INPUTMSG" < 100*1024) {
	    my($hits, $req, $names, $report) = spam_assassin_check();

	    my $stars = "*" x (($hits < 40) ? int($hits) : 40);
	    action_change_header("X-Spam-Score", "$hits ($stars) $names");


	    if ($hits >= $req) {
		action_bounce("Message looks like spam: $hits ($stars) $names");
                md_graphdefang_log('spam', $hits, $RelayAddr);
	    }
	}
    }

    md_graphdefang_log('mail_in');
}

1;




More information about the MIMEDefang mailing list