You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@spamassassin.apache.org by Massimiliano Giovine <ev...@gmail.com> on 2010/06/18 09:38:37 UTC

Writing Spamassassin plugin.

Hi all. I'm writing a simple spamassassin plugin that eval just
subject but it does not.

I place "new" function:

Code:

sub new {
	my ($class, $mailsa) = @_;

    # the usual perlobj boilerplate to create a subclass object
    $class = ref($class) || $class;
    my $self = $class->SUPER::new($mailsa);
    bless ($self, $class);


    # add header's token control
    $self->register_eval_rule ("check_header_token");

    # and return the new plugin object
    return $self;
}

Than i defined the function:
Code:

sub check_header_token
{
	
	my ($self, $pms) = @_;
	
	$subject = $pms->get('Subject');
	
	if($subject == 'HELLO')
	{
#bad message
		return 0;
	}
	
	return 1;
}

What i miss? I put log message on new and on rule and i saw that it
did the new function but if i telnet a mail message with "HELLO" as a
subject it write it into mailbox.

Can you help me?

Thanks in advance

--
-Massimiliano Giovine

Re: Writing Spamassassin plugin.

Posted by Karsten Bräckelmann <gu...@rudersport.de>.
On Fri, 2010-06-18 at 17:47 +0200, Massimiliano Giovine wrote:
> Well. That sounds more clear.
> 
> Now, where is mysite config dir for the custom cf file? I have to
> specify one to my spamassassin installation?

man spamassassin

Your site config dir (since you're on Ubuntu) is /etc/spamassassin, the
same location where you find your local.cf.

> Can i assign to my rule a so high score to don let the message delivery?

No. *sigh*

As I said in my previous post, SA does NOT deliver your mail, and it
does NOT prevent delivery. SA evaluates mail and returns a score
representing the confidence of the mail's spamminess.

Any action based on that score and/or headers SA adds to the processed
mail is the duty of other programs.

That said -- yes, you /can/ assign a really high score to your custom
rule, that basically will over-rule anything else. However, yet again,
performing the desired action based on the score is NOT within the scope
of SA.


> > OK then. However, is the custom header analysis going to be that
> > complex, that a bunch of header and probably meta rules would not do?
> It need a database interaction so i have to use a plugin-eval rule.

So the data changes frequently?

> > When the corresponding rule is being evaluated.
> So if i specify "HEADER" into cf file it will be calle for each
> incoming mail header analysis?

Err -- sorry, I don't mean to come across insulting, but...

Did you read the documentation? In particular the Conf docs, rule
definitions. Do you know what a header rule is?


You really should not get your feet wet with SA by writing a plugin. A
solid background, at the very least configuration and tweaking, is
required.


-- 
char *t="\10pse\0r\0dtu\0.@ghno\x4e\xc8\x79\xf4\xab\x51\x8a\x10\xf4\xf4\xc4";
main(){ char h,m=h=*t++,*x=t+2*h,c,i,l=*x,s=0; for (i=0;i<l;i++){ i%8? c<<=1:
(c=*++x); c&128 && (s+=h); if (!(h>>=1)||!t[s+h]){ putchar(t[s]);h=m;s=0; }}}


Re: Writing Spamassassin plugin.

Posted by Massimiliano Giovine <ev...@gmail.com>.
Well. That sounds more clear.

Now, where is mysite config dir for the custom cf file? I have to
specify one to my spamassassin installation?
Can i assign to my rule a so high score to don let the message delivery?

> OK then. However, is the custom header analysis going to be that
> complex, that a bunch of header and probably meta rules would not do?
It need a database interaction so i have to use a plugin-eval rule.

> When the corresponding rule is being evaluated.
So if i specify "HEADER" into cf file it will be calle for each
incoming mail header analysis?


Another important information i forgot, i'm on Gnu/Linux - Ubuntu.




2010/6/18 Karsten Bräckelmann <gu...@rudersport.de>:
> On Fri, 2010-06-18 at 16:38 +0200, Massimiliano Giovine wrote:
>> Thanks for the answer:
>> I also put 25_myplugin.cf where other plugin's confs are.
>
> Don't. This will be lost on the next successful sa-update run. Instead,
> use your site config dir for the custom cf file.
>
>> if loadplugin myplugin
>> header  MY_RULE eval:check_header_token()
>> endif
>
> That doesn't even lint. The loadplugin command is for actually loading
> the plugin, which must be done prior to using it in rules.
>
> The conditional should be ifplugin. Grep the stock rules for example
> usage. And btw, the conditional is only necessary, if the plugin might
> not be enabled -- if you know you load it, there isn't much need to
> guard the rules...
>
>
>> but it does not change spamassassin behaviour.
>> My plugin will be more complex and will do analysis of mail customized
>> headers. I'm trying to make just an example.
>
> OK then. However, is the custom header analysis going to be that
> complex, that a bunch of header and probably meta rules would not do?
>
>
>> I read that docs thousand times but i never found the answers i need.
>>  I have one more question:
>> when my eval rule is called?
>
> When the corresponding rule is being evaluated.
>
> Hint: dbg() lines in your plugin can help a lot. Observe your plugin's
> behavior by calling spamassassin -D.
>
>> i suppose this flow:
>> 1) telnet an email with particular header
>> 2) spamassassin(spamd not command line execution) calls my eval rule
>
> spamd must be restarted. And of course, your cf file must lint
> cleanly...
>
>> 3) the rule hitted (return 1) the message is deleted: the mail won't
>> be writed into /var/mail/mailbox.
>
> Wrong. SA does NOT deliver mail. SA does NOT prevent delivering mail,
> neither delete mail. SA evaluates a score. Any action whatsoever is the
> responsibility of other tools in your mail processing chain.
>
> Oh, and since you defined a single eval() rule, the resulting score will
> just be changed by the rule's score. Whether the overall score exceeds
> the spam threshold or not is another question.
>
> What you just outlined is a single-hit kill-switch. While you /can/ do
> that with SA, you will not find it in stock rules. SA is a scoring
> system. (And again, performing action based on the kill-switch rule is
> outside the scope of SA.)
>
>
> And since you just mentioned "return 1", but didn't get back to all my
> comments -- the logic in the OP still is reversed. The rule hits, when
> the Subject does not match your criteria.
>
>
> --
> char *t="\10pse\0r\0dtu\0.@ghno\x4e\xc8\x79\xf4\xab\x51\x8a\x10\xf4\xf4\xc4";
> main(){ char h,m=h=*t++,*x=t+2*h,c,i,l=*x,s=0; for (i=0;i<l;i++){ i%8? c<<=1:
> (c=*++x); c&128 && (s+=h); if (!(h>>=1)||!t[s+h]){ putchar(t[s]);h=m;s=0; }}}
>
>



-- 
-Massimiliano Giovine
Aksel Peter Jørgensen dice: "Why make things difficult, when it is
possible to make them cryptic and totally illogic, with just a little
bit more effort?"
Blog: http://opentalking.blogspot.com
"Linus Torvalds doesn't die, he simply returns zero."

Re: Writing Spamassassin plugin.

Posted by Karsten Bräckelmann <gu...@rudersport.de>.
On Fri, 2010-06-18 at 16:38 +0200, Massimiliano Giovine wrote:
> Thanks for the answer:
> I also put 25_myplugin.cf where other plugin's confs are.

Don't. This will be lost on the next successful sa-update run. Instead,
use your site config dir for the custom cf file.

> if loadplugin myplugin
> header  MY_RULE eval:check_header_token()
> endif

That doesn't even lint. The loadplugin command is for actually loading
the plugin, which must be done prior to using it in rules.

The conditional should be ifplugin. Grep the stock rules for example
usage. And btw, the conditional is only necessary, if the plugin might
not be enabled -- if you know you load it, there isn't much need to
guard the rules...


> but it does not change spamassassin behaviour.
> My plugin will be more complex and will do analysis of mail customized
> headers. I'm trying to make just an example.

OK then. However, is the custom header analysis going to be that
complex, that a bunch of header and probably meta rules would not do?


> I read that docs thousand times but i never found the answers i need.
>  I have one more question:
> when my eval rule is called?

When the corresponding rule is being evaluated.

Hint: dbg() lines in your plugin can help a lot. Observe your plugin's
behavior by calling spamassassin -D.

> i suppose this flow:
> 1) telnet an email with particular header
> 2) spamassassin(spamd not command line execution) calls my eval rule

spamd must be restarted. And of course, your cf file must lint
cleanly...

> 3) the rule hitted (return 1) the message is deleted: the mail won't
> be writed into /var/mail/mailbox.

Wrong. SA does NOT deliver mail. SA does NOT prevent delivering mail,
neither delete mail. SA evaluates a score. Any action whatsoever is the
responsibility of other tools in your mail processing chain.

Oh, and since you defined a single eval() rule, the resulting score will
just be changed by the rule's score. Whether the overall score exceeds
the spam threshold or not is another question.

What you just outlined is a single-hit kill-switch. While you /can/ do
that with SA, you will not find it in stock rules. SA is a scoring
system. (And again, performing action based on the kill-switch rule is
outside the scope of SA.)


And since you just mentioned "return 1", but didn't get back to all my
comments -- the logic in the OP still is reversed. The rule hits, when
the Subject does not match your criteria.


-- 
char *t="\10pse\0r\0dtu\0.@ghno\x4e\xc8\x79\xf4\xab\x51\x8a\x10\xf4\xf4\xc4";
main(){ char h,m=h=*t++,*x=t+2*h,c,i,l=*x,s=0; for (i=0;i<l;i++){ i%8? c<<=1:
(c=*++x); c&128 && (s+=h); if (!(h>>=1)||!t[s+h]){ putchar(t[s]);h=m;s=0; }}}


Re: Writing Spamassassin plugin.

Posted by Massimiliano Giovine <ev...@gmail.com>.
I read also the first part of that slides with the attached notes. I
did exacly the same steps except the configuration parsing (i thought
i don't need it, was i wrong?)

I logged 2 messages 1 in the new funcion and one in eval rule function:

It prints all mesages at spamd restart but not when i send messages to
postfix via telnet.

Can it help for the solution?



2010/6/18 Michael Parker <pa...@pobox.com>:
> These might be starting to get dated a little but I think that if you look at the "Extending Apache SpamAssassin Using Plugin" slides and notes from here: http://people.apache.org/~parker/presentations/index.html
>
> That will give you a good idea on what you need to accomplish for your plugin.
>
> Michael
>
>



-- 
-Massimiliano Giovine
Aksel Peter Jørgensen dice: "Why make things difficult, when it is
possible to make them cryptic and totally illogic, with just a little
bit more effort?"
Blog: http://opentalking.blogspot.com
"Linus Torvalds doesn't die, he simply returns zero."

Re: Writing Spamassassin plugin.

Posted by Michael Parker <pa...@pobox.com>.
These might be starting to get dated a little but I think that if you look at the "Extending Apache SpamAssassin Using Plugin" slides and notes from here: http://people.apache.org/~parker/presentations/index.html

That will give you a good idea on what you need to accomplish for your plugin.

Michael


Re: Writing Spamassassin plugin.

Posted by Massimiliano Giovine <ev...@gmail.com>.
Thanks for the answer:
I also put 25_myplugin.cf where other plugin's confs are.
I wrote on it:

if loadplugin myplugin
header  MY_RULE eval:check_header_token()
endif

but it does not change spamassassin behaviour.
My plugin will be more complex and will do analysis of mail customized
headers. I'm trying to make just an example.
I read that docs thousand times but i never found the answers i need.
 I have one more question:
when my eval rule is called?

i suppose this flow:
1) telnet an email with particular header
2) spamassassin(spamd not command line execution) calls my eval rule
3) the rule hitted (return 1) the message is deleted: the mail won't
be writed into /var/mail/mailbox.

Is this idea right?
I read razor2 and sfd plugins code and i do the same into *.pm file.
Probably i miss something else.

2010/6/18 Karsten Bräckelmann <gu...@rudersport.de>:
> On Fri, 2010-06-18 at 09:38 +0200, Massimiliano Giovine wrote:
>> Hi all. I'm writing a simple spamassassin plugin that eval just
>> subject but it does not.
>
>>     $self->register_eval_rule ("check_header_token");
>
> It's an eval() rule. So you also need to define a SA rule, that calls
> the function. Please read the docs carefully. Also, looking at existing
> code and basing off of it likely is a good idea...
>
>  http://spamassassin.apache.org/full/3.2.x/doc/Mail_SpamAssassin_Plugin.html
>
>
>> sub check_header_token
>> {
>>       my ($self, $pms) = @_;
>>       $subject = $pms->get('Subject');
>>
>>       if($subject == 'HELLO')
>>       {
>>               #bad message
>>               return 0;
>>       }
>>       return 1;
>
> Your eval() rule claims a hit, if the Subject does *not* match. You
> reversed the logic.
>
>
>> What i miss? I put log message on new and on rule and i saw that it
>> did the new function but if i telnet a mail message with "HELLO" as a
>> subject it write it into mailbox.
>
> Anyway, I hope this is just meant as a first attempt, not a real plugin.
> It duplicates the existing WhiteListSubject plugin (which also handles
> blacklisting subjects).
>
> Moreover, for arbitrary scores, a simple header rule does the same, much
> more flexible than a plugin.
>
>  header FOO  Subject =~ /^bad subject$/
>
>
> --
> char *t="\10pse\0r\0dtu\0.@ghno\x4e\xc8\x79\xf4\xab\x51\x8a\x10\xf4\xf4\xc4";
> main(){ char h,m=h=*t++,*x=t+2*h,c,i,l=*x,s=0; for (i=0;i<l;i++){ i%8? c<<=1:
> (c=*++x); c&128 && (s+=h); if (!(h>>=1)||!t[s+h]){ putchar(t[s]);h=m;s=0; }}}
>
>



-- 
-Massimiliano Giovine
Aksel Peter Jørgensen dice: "Why make things difficult, when it is
possible to make them cryptic and totally illogic, with just a little
bit more effort?"
Blog: http://opentalking.blogspot.com
"Linus Torvalds doesn't die, he simply returns zero."

Re: Writing Spamassassin plugin.

Posted by Karsten Bräckelmann <gu...@rudersport.de>.
On Fri, 2010-06-18 at 09:38 +0200, Massimiliano Giovine wrote:
> Hi all. I'm writing a simple spamassassin plugin that eval just
> subject but it does not.

>     $self->register_eval_rule ("check_header_token");

It's an eval() rule. So you also need to define a SA rule, that calls
the function. Please read the docs carefully. Also, looking at existing
code and basing off of it likely is a good idea...

  http://spamassassin.apache.org/full/3.2.x/doc/Mail_SpamAssassin_Plugin.html


> sub check_header_token
> {	
> 	my ($self, $pms) = @_;	
> 	$subject = $pms->get('Subject');
> 	
> 	if($subject == 'HELLO')
> 	{
> 		#bad message
> 		return 0;
> 	}
> 	return 1;

Your eval() rule claims a hit, if the Subject does *not* match. You
reversed the logic.


> What i miss? I put log message on new and on rule and i saw that it
> did the new function but if i telnet a mail message with "HELLO" as a
> subject it write it into mailbox.

Anyway, I hope this is just meant as a first attempt, not a real plugin.
It duplicates the existing WhiteListSubject plugin (which also handles
blacklisting subjects).

Moreover, for arbitrary scores, a simple header rule does the same, much
more flexible than a plugin.

  header FOO  Subject =~ /^bad subject$/


-- 
char *t="\10pse\0r\0dtu\0.@ghno\x4e\xc8\x79\xf4\xab\x51\x8a\x10\xf4\xf4\xc4";
main(){ char h,m=h=*t++,*x=t+2*h,c,i,l=*x,s=0; for (i=0;i<l;i++){ i%8? c<<=1:
(c=*++x); c&128 && (s+=h); if (!(h>>=1)||!t[s+h]){ putchar(t[s]);h=m;s=0; }}}