Chapter 20. Firtering

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

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

By default, these are defined

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), 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 using spamassassin by a fml8 hook.

Caution

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. HOOK to reject a message with danger attachment

fml8 analyzed the incoming message firstly and creates a chain of Mail::Message objects on the 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();
	}
    }
};

fml 8.0 (fml-devel) project homepage is www.fml.org/software/fml8/.
fml 4.0 project homepage is www.fml.org/fml/menu.ja.html.
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>.