Filtering

fml 8 tutorial
Prev |  | Next

# Chapter 20. Filtering

1. Where the mail is sent back to when filter system rejects ?
2. Reject SPAM messages by using spamassassin.
3. Add X-Spam-Status: Yes header field if spamassassin determines the message as a spam.
4. How to write a hook to reject a message with danger attachment(s).

1. Where the mail is sent back to when filter system rejects ?

By default, It is defined as

    use_article_filter_reject_notice	=	yes
    article_filter_reject_notice_recipient	=	maintainer sender

When the filter system rejects the request, fml sends back it to both the ML maintainer and the sender.

To change the recipient to the sender (From: address) only, set

    article_filter_reject_notice_recipient	=	sender

To notify the rejection to both ML maintainer and the sender, set

    article_filter_reject_notice_recipient	=	maintainer sender

To disable notification of rejection, set

    use_article_filter_reject_notice	=	no

2. Reject SPAM messages by using spamassassin.

Case 1: use internal filter.

    use_article_spam_filter         =       yes
    article_spam_filter_drivers     =       spamassassin

Case 2: In this case, fml8 use not spamassassin internal filter but use a hook.

    $distribute_verify_request_end_hook = q{
            my $spamassassin = '/usr/pkg/bin/spamc -c';

            use FileHandle;
            my $wh  = new FileHandle "| $spamassassin";

            if (defined $wh) {
                    $wh->autoflush(1);
                    my $msg = $curproc->incoming_message();
                    $msg->print($wh);
                    $wh->close();
                    if ($?) {
                            $curproc->log("spam: (code = $?)");
                            $curproc->stop_this_process();
                    }
            }
    };

3. Add X-Spam-Status: Yes header field if spamassassin determines the message as a spam.

    $distribute_verify_request_end_hook = q{
    	my $spamassassin = '/usr/pkg/bin/spamc -c';

    	use FileHandle;
    	my $wh  = new FileHandle "| $spamassassin";

    	if (defined $wh) {
    		$wh->autoflush(1);
    		my $msg = $curproc->incoming_message();
    		$msg->print($wh);
    		$wh->close();
    		if ($?) {
    			$curproc->log("spam: (code = $?)");
    			my $hdr = $curproc->incoming_message_header();
    			$hdr->add('X-Spam-Status', 'Yes');
    		}
    	}
    };

This is a little tricky but it works well.

4. How to write a hook to reject a message with danger attachment(s).

fml8 analyzed the incoming message firstly and creates a chain of Mail::Message objects on memory. It is easy for fml8 to analyze the chain to check the message content.

The following examples uses hooks. In all cases, if matched, call stop_this_process() to stop further processing. Pay attension that these examples do not try to return error messsages.

If you need to return error messages, use reply_message(). It is better not to return it since this message must be a virus or a spam.

Here is an example to check attachment keywords e.g. .exe in mesages. Before fml8 2004/12/08 current, it follows:

    $distribute_verify_request_start_hook = q{
        my $msg = $curproc->incoming_message() || undef;
        for (my $m = $msg; $m ; $m = $m->{ next } ) {
    	my $hs = $m->message_fields() || '';
    	if ($hs =~ /filename=.*\.(com|vbs|vbe|wsh|wse|js|exe|doc|rtf)/o) {
    	    $curproc->log("attachment \.$1 found");
    	    $curproc->stop_this_process();
    	}
        }
    };

After fml8 2004/12/08 current, it follows:

    $distribute_verify_request_start_hook = q{
        my $msg  = $curproc->incoming_message() || undef;
        my $list = $msg->message_chain_as_array_ref();
        for my $m (@$list) {
    	my $hs = $m->message_fields() || '';
    	if ($hs =~ /filename=.*\.(com|vbs|vbe|wsh|wse|js|exe|doc|rtf)/o) {
    	    $curproc->log("[new] attachment \.$1 found");
    	    $curproc->stop_this_process();
    	}
        }
    };

Another solution is to trap

    Content-Disposition: attachment;

to detect the existence of attachments. Before fml8 2004/12/08 current, it follows:

    $distribute_verify_request_start_hook = q{
        my $msg = $curproc->incoming_message() || undef;
        for (my $m = $msg; $m ; $m = $m->{ next } ) {
    	my $hs = $m->message_fields() || '';
    	if ($hs =~ /Content-Disposition:.*attachment;/o) {
    	    $curproc->log("attachment \.$1 found");
    	    $curproc->stop_this_process();
    	}
        }
    };

After fml8 2004/12/08 current, it follows:

    $distribute_verify_request_start_hook = q{
        my $msg  = $curproc->incoming_message() || undef;
        my $list = $msg->message_chain_as_array_ref();
        for my $m (@$list) {
    	my $hs = $m->message_fields() || '';
    	if ($hs =~ /Content-Disposition:.*attachment;/o) {
    	    $curproc->log("[new] attachment \.$1 found");
    	    $curproc->stop_this_process();
    	}
        }
    };

Prev | Home | Next
Recipes | Up | Extend Message

fml 8.0 (fml-devel) project homepage is www.fml.org/software/fml8/.
fml 4.0 project homepage is www.fml.org/software/fml4/.
about one floppy bsd routers, see www.bsdrouter.org/.
other free softwares are found at www.fml.org/software/.

author's homepage is www.fml.org/home/fukachan/.
Also, visit nuinui's world :) at www.nuinui.net.

For questions about FML, e-mail <fml-bugs@fml.org>.