You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@spamassassin.apache.org by Darryl Bleau <da...@submersion.com> on 2004/02/18 23:36:02 UTC

SA 'Parts' Documentation *WIP*

After some research, I've come up with this documentation to describe
the different message 'parts' that SA uses to evaluate messages. This is
a work in progress, so please let me know of any corrections that need
to be made. The documentation is based on the behavior I have seen with
SA from SVN a few days old. If I have this documentation confirmed, I
will generate some test messages to display the behavior, then I'll work
on writing in tests for SA so that the tests can be included in future
SA versions to make sure the parts behavior doesn't change
inadvertently.

Full:
The 'Full' part of a message is the complete, un-decoded, RFC822
message. It includes all parts (textual or otherwise) and all headers,
including headers from all parts. Essentially, the 'Full' part of a
message is a text dump of the original message, except any \r\n
linebreaks are converted to \n.

Rawbody:
The 'Rawbody' part of a message is a concatenation of all the decoded
textual parts (parts with a Content-Type of 'text/') of the message, and
also includes the headers from message/rfc822 child parts. Any \r\n
linebreaks are converted to \n.

Body:
The 'Body' part of a message is a concatenation of all the decoded
textual parts of the message, including headers from any textual child
parts, just like the Rawbody part, with these exceptions: Single
linebreaks are removed, multiple whitespaces in a row are converted to
just one whitespace, and multiple linebreaks in a row are converted to a
single linebreak. HTML-like tags are removed (anything starting with <,
with at least one character in it, and ending with >. Tags like <>,
<<<>>>, < >, <.>, etc, are not removed). Anything that looked like a URI
in the text (in a HTML tag or not) will be listed as URI:uri. Then, the
value from the top-part Subject header is appended to the top of the
Body part.

URI:
The 'URI' part is a list of all the URIs collected from the Rawbody
part. Valid URIs are http://, https:// ftp:// mailto:// javascript://
and file://. URIs not in this valid list (such as news://) are not
included in the URI part. The URI collection will also include
schemeless URIs which have an obvious scheme, such as www.domain.com,
mail@domain.com and ftp.domain.com. Some will be added to the list as
both the original (www.domain.com, ftp.domain.com) and as they would be
schemed (http://www.domain.com, ftp://ftp.domain.com), except mailto://,
which is only added schemed (mailto://mail@domain.com). Also, URIs that
are malformed, such as http://www.domain.com?var are added to the list
'fixed', http://www.domain.com/?var. There are no duplicate entries in
the URI list.



Based on what I've seen, I've made a few assumptions as to reasoning for
the parts. Please let me know if these sound about right.

Full is the unaltered RFC822, other than \r\n to \n newlines. You would
write rules against this part to match against specific headers, message
boundaries, and any other normally not mail-client-visible text
(included encoded text that would normally be decoded by a client).

Rawbody is all of the undecoded body text from a message. You would
write rules against this part to match against HTML, relations between
HTML and text, and rules that are dependant on whitespace or linebreaks.

Body is all of the undecoded body text from a message, mostly as it
would be displayed in a mail client. You would write rules against this
part to match specific sentences, words, or sequences of either.

URI is all of the known-URIs in the message. You would write rules
against this part to match against a specific URI.


With that in mind, I have a few suggestions:

Full: is great as it is. Not removing parts (as 2.63 did) is a good
idea, in my opinion.

Rawbody: is good, not putting in the boundaries for missing parts as
2.63 did, though it only includes headers for some message parts. Would
it possibly be a good idea to make Rawbody exactly the same as full,
except with decoded textual parts and decoded headers, and non-textual
parts removed? That would mean rawbody would have all the headers for
each part (even top part), except any that were encoded would be
decoded.

Body: I don't understand why the value from the Subject header is
appending to the top of body. If you want to match the Subject header
against something, wouldn't you use Full? Also, I don't understand why
URIs are inserted as URI:uri, I thought perhaps to make the URI list
collection easier later, but from what I can see the URI collection is
done from Rawbody anyway. I can see having the URI:uri as not being
desirable, as it could interfere with a rule. (if the URI: part was
'hidden' in a client, and a rule was written for two words around it).
Removing the HTML is good too, and though Daniel mentioned the HTML was
'rendered' I can't see how. It would be a good idea, I think, to replace
specific tags with the 'rendered' equivalents. (<br>, <p>, etc).

URI: As is, some URIs are 'missed' in this list. (Try news://news.com,
or <img src=www.missed.com). I also think it would be a good idea to add
unschemed mailto:// as both schemed and unschemed to the URI list as
someone could write a rule to match start (^mail@domain\.com$, for
example). Also, I wonder why SA doesn't use the RFC 2396 regex to match
all the valid URIs. Seems it could grab all the valid URIs from a
message in one sweep, unless I'm missing something? Then one could go
through the list and scheme any URIs that needed it.

Please let me know of any comments/suggestions!


Re: SA 'Parts' Documentation *WIP*

Posted by Darryl Bleau <da...@submersion.com>.
On this same line, I was also going to suggest a 'virtual' part for eval tests, as the 'part' that is listed for the eval test doesn't necessarily have anything to do with where the eval test is applied.

So instead of something like:

body HTML_FORMACTION_MAILTO eval:html_test('form_action_mailto')

You'd have:

eval HTML_FORMACTION_MAILTO eval:html_test('form_action_mailto')

Or possibly (I don't know too much about how Perl eval works)

eval HTML_FORMACTION_MAILTO html_test('form_action_mailto')




Re: SA 'Parts' Documentation *WIP*

Posted by Theo Van Dinter <fe...@kluge.net>.
On Wed, Feb 18, 2004 at 07:28:44PM -0500, Theo Van Dinter wrote:
> In 3.0.0:
> full -> Raw -- the pristine message as passed to SA

Actually, that's not 100% accurate...

It's the pristine message body...  The message header is slightly cooked.
Namely that line continuations are removed and CRLF -> LF.  ie:

Received: from someone
	blarg blarg\r

becomes:

Received: from someone blarg blarg

Makes the header RE easier.

-- 
Randomly Generated Tagline:
"... one of the main causes of the fall of the Roman Empire was that,
 lacking zero, they had no way to indicate successful termination of their
 C programs."                  - Robert Firth

Re: SA 'Parts' Documentation *WIP*

Posted by Theo Van Dinter <fe...@kluge.net>.
On Thu, Feb 19, 2004 at 11:03:54AM -0700, Darryl Bleau wrote:
> Is this a suggestion or are these already decided upon new names? I
> would suggest that the 'body' and 'rawbody' parts be named differently
> from each other, rather than both being 'Text'.. :)

Well, those were the names they've always been, and are what are current
3.0.0.  As I said at the top of this thread, you can feel free to have
a discussion about renaming the different types, but I don't think it's
a hot enough issue to actually have any change come out.

I think the 3 names make sense.  "full" is the full/unaltered message.
"body" are the parts you'd see in an MUA, fully decoded and rendered.
"rawbody" are those same parts, just not rendered (ie: HTML bits won't
be removed, etc.)

-- 
Randomly Generated Tagline:
"G: And are you using Windows or a Mac?
  T: Neither, I'm using Linux.
  G: Oh, you're a power user."            - Theo and his ex-ISP

Re: SA 'Parts' Documentation *WIP*

Posted by Darryl Bleau <da...@submersion.com>.
On Wed, 2004-02-18 at 17:28, Theo Van Dinter wrote:
> > Full -> Raw (as this really is the 'raw' message)
> > Rawbody -> Decoded or RawDecoded (if this were just like the 'raw' message, but with decoded parts)
> > Body -> Text (just to make it more explicit that this is the text from the message)
> 
> In 3.0.0:
> 
> body -> Text -- fully decoded and HTML rendered into text
> rawbody -> Text -- fully decoded, but not rendered
> full -> Raw -- the pristine message as passed to SA

Is this a suggestion or are these already decided upon new names? I
would suggest that the 'body' and 'rawbody' parts be named differently
from each other, rather than both being 'Text'.. :)


Re: SA 'Parts' Documentation *WIP*

Posted by Theo Van Dinter <fe...@kluge.net>.
On Wed, Feb 18, 2004 at 09:15:51PM -0800, David Muir Sharnoff wrote:
> I made a mistake.  Based on what spammers are using, &#0x65; is not
> valid but &#x65; is.  There can be extra zeros: &#x0000065;

    $uri =~ s/\&\#0*(3[3-9]|[4-9]\d|1[01]\d|12[0-6]);/sprintf "%c",$1/e;

that's the RE.  So it'll do &#, any number of 0's, and the printable char values...
guess I'll have to add another one for the hex versions... :|

http://www.htmlhelp.com/reference/html40/entities/ is a good reference btw. :)

> I really don't like the names body, rawbody, and text.  They are
> most confusing.   Can we please deprecate them in favor of 
> new terms?

Feel free to bring it up in a new thread...  I don't think it's going
to get very far fwiw, but now's the time to talk about this stuff.

-- 
Randomly Generated Tagline:
"If you know the enemy and know yourself, you need not fear the result
 of a hundred battles.  If you know yourself but not the enemy, for every
 victory gained you will also suffer a defeat. If you know neither the
 enemy nor yourself, you will succumb in every battle." - Sun Tzu

Re: SA 'Parts' Documentation *WIP*

Posted by David Muir Sharnoff <mu...@idiom.com>.
That sounds great!

I made a mistake.  Based on what spammers are using, &#0x65; is not
valid but &#x65; is.  There can be extra zeros: &#x0000065;

I really don't like the names body, rawbody, and text.  They are
most confusing.   Can we please deprecate them in favor of 
new terms?

-Dave

* Just an fyi...  In 3.0.0, the URI list will contain the "raw" (as listed
* in the message) and "cooked" (decode things that don't need encoding,
* encode things that need encoding, etc) ...  So you can easily catch stuff
* like the above. :)  I don't think we currently support all the encoding
* methods above though...  Definitely the %## version, and &\####; ...
* 
* Is &\#0x####; valid?
* 
* > Full -> Raw (as this really is the 'raw' message)
* > Rawbody -> Decoded or RawDecoded (if this were just like the 'raw' messag=
* e, but with decoded parts)
* > Body -> Text (just to make it more explicit that this is the text from th=
* e message)
* 
* In 3.0.0:
* 
* body -> Text -- fully decoded and HTML rendered into text
* rawbody -> Text -- fully decoded, but not rendered
* full -> Raw -- the pristine message as passed to SA


Re: SA 'Parts' Documentation *WIP*

Posted by Theo Van Dinter <fe...@kluge.net>.
On Wed, Feb 18, 2004 at 05:13:34PM -0700, Darryl Bleau wrote:
> > URIs should be HTML decoded.  I've run into a number of spammers who
> > write things like:
> > 
> > 	h&#116;&#0x00054;p://
> 
> This is a good idea. So if you wanted to match an encoded URI, you would
> match on Full, otherwise, you could match against URI.

Just an fyi...  In 3.0.0, the URI list will contain the "raw" (as listed
in the message) and "cooked" (decode things that don't need encoding,
encode things that need encoding, etc) ...  So you can easily catch stuff
like the above. :)  I don't think we currently support all the encoding
methods above though...  Definitely the %## version, and &\####; ...

Is &\#0x####; valid?

> Full -> Raw (as this really is the 'raw' message)
> Rawbody -> Decoded or RawDecoded (if this were just like the 'raw' message, but with decoded parts)
> Body -> Text (just to make it more explicit that this is the text from the message)

In 3.0.0:

body -> Text -- fully decoded and HTML rendered into text
rawbody -> Text -- fully decoded, but not rendered
full -> Raw -- the pristine message as passed to SA

:)

-- 
Randomly Generated Tagline:
OK, enough hype.
              -- Larry Wall in the perl man page

Re: SA 'Parts' Documentation *WIP*

Posted by Theo Van Dinter <fe...@kluge.net>.
On Wed, Feb 18, 2004 at 09:26:59PM -0800, David Muir Sharnoff wrote:
> I agree with:
> 	
> 	"raw"	-- the entire undecoded message

Well, "raw" is decoded but not rendered.

If you want to keep the names I've been giving to things, you'd have:

raw		like the current full -- pristine message
decoded		like the current raw -- all text + message parts, decoded
rendered	like the current body -- all text + message parts,
		decoded + rendered (html, etc.)

-- 
Randomly Generated Tagline:
I already have too much problem with people thinking the efficiency of
 a perl construct is related to its length.  On the other hand, I'm
 perfectly capable of changing my mind next week...  :-) --lwall

SA message parts discussion.

Posted by Darryl Bleau <da...@submersion.com>.
On Wed, 2004-02-18 at 22:26, David Muir Sharnoff wrote:
> For all of the decoded text, I suggest "alltext".  I don't like
> "decoded" as the main distinction from "body" or "text" is that it
> includes more parts.  I especially don't like "rawdecoded" as there
> is nothing raw about it. 

The reasoning I had behind 'Rawdecoded' was that it would make sense if
the part was exactly the same as Raw (current Full), with the exception
that all parts and headers that needed be were decoded. Currently, the
'rawbody' is not that way.

> Oh, and I have a suggestion for an addition one: "html" for decoded
> html portions.

I think this is a very good idea. The same text that is removed from the current 'Body' part would make the the 'HTML' part.

This would create the possibility of removing a large number of 'eval' rules (IMHO, the less 'eval' type rules the better, because rule writers typically aren't going to write eval rules).

Let's just take one for example, FORM_ACTION_MAILTO.

Currently, this is:

body HTML_FORMACTION_MAILTO eval:html_test('form_action_mailto')

With an 'HTML' part, this could be:

html HTML_FORMACTION_MAILTO /<\s{0,5}form[^>]*action\s{0,5}=\s{0,5}('|")?\s{0,5}mailto:/i

As far as I can see, all of the 'html_test' evals could be written in rule form like this, if there were a 'HTML' part. (Though, I suppose you could still write them in rule form, against the current Rawbody, but a HTML part would be more efficient).
I would also point out that while this rule is currently listed as a 'body' rule, it really isn't (hence the possible need for a 'eval' part).


Just to re-iterate what has already been said, but in this more descriptive thread:

1. The current message parts names aren't descriptive, new terms may possibly be a good idea.
2. New parts may also be a good idea. A virtual 'Eval' part (As the parts assigned to eval-type rules, as is, don't necessarily have any bearing on where the rule is applied), and a 'HTML' part containing all the HTML from the message.



Re: SA 'Parts' Documentation *WIP*

Posted by David Muir Sharnoff <sp...@trust.idiom.com>.
There is little cost to keeping the old names for backwards
compatability.

As for new names...

I agree with:
	
	"raw"	-- the entire undecoded message

That leaves two text rules -- one for the main body and one for
all of text components.

	"text" or "body" both seem fine for the main body.

For all of the decoded text, I suggest "alltext".  I don't like
"decoded" as the main distinction from "body" or "text" is that it
includes more parts.  I especially don't like "rawdecoded" as there
is nothing raw about it. 

Oh, and I have a suggestion for an addition one: "html" for decoded
html portions.

Thanks for listening,

-Dave

* I agree. I was going to suggest some sort of naming change to
* have the parts be more descriptive, but then you would have to worry
* about ruleset backward-compatibility. I suppose that's not a big
* deal, if SA were to treat both the old and new names as the same.
* Maybe this would be a good change for 3.0?
* 
* I would suggest something like:
* 
* Full -> Raw (as this really is the 'raw' message)
* Rawbody -> Decoded or RawDecoded (if this were just like the 'raw' message, but with decoded parts)
* Body -> Text (just to make it more explicit that this is the text from the message)
* 


Re: SA 'Parts' Documentation *WIP*

Posted by Darryl Bleau <da...@submersion.com>.
On Wed, 2004-02-18 at 15:48, David Muir Sharnoff wrote:
> As for URI's, I think it would be a mistake to include <img src=> 
> URIs as many of those point to innocent bystanders.

But if they are innocent bystanders you wouldn't have URI rules against
them anyway, would you?

> URIs should be HTML decoded.  I've run into a number of spammers who
> write things like:
> 
> 	h&#116;&#0x00054;p://

This is a good idea. So if you wanted to match an encoded URI, you would
match on Full, otherwise, you could match against URI.

> In terms of naming, "full" and "rawbody" don't have predictable meanings
> without reading the documentation.  (With 2.63 even with the documentation
> they aren't predictable).
> 
> I suggest that "full" and "rawbody" be deprecated in favor of:
> "alltext" and "raw" or "rawmessage".  In case it's not obvious, "alltext"
> would replace "rawbody" and "raw" would replace "full".

I agree. I was going to suggest some sort of naming change to have the parts be more descriptive, but then you would have to worry about ruleset backward-compatibility. I suppose that's not a big deal, if SA were to treat both the old and new names as the same. Maybe this would be a good change for 3.0?
I would suggest something like:

Full -> Raw (as this really is the 'raw' message)
Rawbody -> Decoded or RawDecoded (if this were just like the 'raw' message, but with decoded parts)
Body -> Text (just to make it more explicit that this is the text from the message)




Re: SA 'Parts' Documentation *WIP*

Posted by David Muir Sharnoff <sp...@trust.idiom.com>.
I'm currently using 2.63 and I wish that full, body & rawbody acted as 
you describe and suggest.  It would make it much easier for me to write rules!

As for URI's, I think it would be a mistake to include <img src=> 
URIs as many of those point to innocent bystanders.

URIs should be HTML decoded.  I've run into a number of spammers who
write things like:

	h&#116;&#0x00054;p://

HTML encoding of plain text should cause a high score all by itself.
HTML encoding of URIs should be even higher.

In terms of naming, "full" and "rawbody" don't have predictable meanings
without reading the documentation.  (With 2.63 even with the documentation
they aren't predictable).

I suggest that "full" and "rawbody" be deprecated in favor of:
"alltext" and "raw" or "rawmessage".  In case it's not obvious, "alltext"
would replace "rawbody" and "raw" would replace "full".

Thanks,

-Dave


*  ...
*
* Full:
* The 'Full' part of a message is the complete, un-decoded, RFC822
* message. It includes all parts (textual or otherwise) and all headers,
* including headers from all parts. Essentially, the 'Full' part of a
* message is a text dump of the original message, except any \r\n
* linebreaks are converted to \n.
* 
* Rawbody:
* The 'Rawbody' part of a message is a concatenation of all the decoded
* textual parts (parts with a Content-Type of 'text/') of the message, and
* also includes the headers from message/rfc822 child parts. Any \r\n
* linebreaks are converted to \n.
* 
* Body:
* The 'Body' part of a message is a concatenation of all the decoded
* textual parts of the message, including headers from any textual child
* parts, just like the Rawbody part, with these exceptions: Single
* linebreaks are removed, multiple whitespaces in a row are converted to
* just one whitespace, and multiple linebreaks in a row are converted to a
* single linebreak. HTML-like tags are removed (anything starting with <,
* with at least one character in it, and ending with >. Tags like <>,
* <<<>>>, < >, <.>, etc, are not removed). Anything that looked like a URI
* in the text (in a HTML tag or not) will be listed as URI:uri. Then, the
* value from the top-part Subject header is appended to the top of the
* Body part.
* 
* URI:
* The 'URI' part is a list of all the URIs collected from the Rawbody
* part. Valid URIs are http://, https:// ftp:// mailto:// javascript://
* and file://. URIs not in this valid list (such as news://) are not
* included in the URI part. The URI collection will also include
* schemeless URIs which have an obvious scheme, such as www.domain.com,
* mail@domain.com and ftp.domain.com. Some will be added to the list as
* both the original (www.domain.com, ftp.domain.com) and as they would be
* schemed (http://www.domain.com, ftp://ftp.domain.com), except mailto://,
* which is only added schemed (mailto://mail@domain.com). Also, URIs that
* are malformed, such as http://www.domain.com?var are added to the list
* 'fixed', http://www.domain.com/?var. There are no duplicate entries in
* the URI list.
* 
*  ...
* 
* URI: As is, some URIs are 'missed' in this list. (Try news://news.com,
* or <img src=www.missed.com). I also think it would be a good idea to add
* unschemed mailto:// as both schemed and unschemed to the URI list as
* someone could write a rule to match start (^mail@domain\.com$, for
* example). Also, I wonder why SA doesn't use the RFC 2396 regex to match
* all the valid URIs. Seems it could grab all the valid URIs from a
* message in one sweep, unless I'm missing something? Then one could go
* through the list and scheme any URIs that needed it.
* 
* Please let me know of any comments/suggestions!
*