procmail
[Top] [All Lists]

RE: Using procmail on mail relay

2007-10-23 02:09:09
Jack L. Stone [mailto:jacks(_at_)sage-american(_dot_)com] Tuesday, October 23, 
2007
2:54 AM:


At 02:24 AM 10.23.2007 +0200, Dallman Ross wrote:

 * ^X-Spam-Status:.*score=..\.

Here are the ones I'm using, but I still see some scores
matching below 10.0 and the other 9.0.

It would be much more helpful to you and us if you would include
log snippets, and also a true example of the line you are failing
to match properly on.  Without those, we end up having to reverse-
engineer what's wrong.

I'm matching on the midline string: score=xx.x (like 10.6) or 
score=9.3

Wonder what is wrong?

Your conditions are goofy, I'm afraid.

For ones to match 9.0 --> 9.9
## To spamcheck        
:0:
* ^X-Spam-Status:(.*\<)?Yes
* $(score=[9][.][0-9])
$DEFAULT

I don't regularly run SpamAssassin, so now I have to go dig up
a message with a SA header to see what the one looks like with
the "score=" line on it.  Again, it would be very helpful if
you would provide the actual header and actual log entries.

But your conditions are not optimal and the above seems like
it will result in something other than what you probably want.

First, do you really want scores of 9.x -- and only scores of
9.x! -- in your DEFAULT inbox?  Because that is what the above
will do (assuming X-Spam-Status is "yes" on them).

Let's break it down.  I found a sample SA header with a score
of 9.x:

  10:22am [~/Mail] 606[1]> grep ^X-Sp .myspam/msg.weZf
 X-Spam-Flag: YES
 X-Spam-Score: 9.308
 X-Spam-Level: *********
 X-Spam-Status: Yes, score=9.308 tagged_above=-999 required=5
 X-Spam-Snaggers: rx.datechain.hR:day_past 

(The last line is how I caught it.  That's my proprietary stuff.
Didn't need SA.)

The first point -- which goes to approach but not result -- is
that we always have one space before the "Yes" on the X-Spam-Status
line, so it doesn't make optimal sense to look for the regex
"(.*\<)?" in this case.

Normally I would say that we want to test as if we don't know what
the spacing will be like in a header.  But when you've just run SA
on your own servers, you control the header, and you control the
output, and if there's one space, well, there always will be one space --
until you change your setup (or perhaps until you upgrade SA one day
and get surprised). :-)  So I'd tend here to just do:

   * ^X-Spam-Status: Yes

or, if you want not ever to be surprised by my parenthetical scenario
in the penultimate sentence of the last paragraph:

   * $ ^X-Spam-Status:[$WS]*Yes

(Assumes you've defined WS already as a space and a tab.)

Now: why have a second condition that is not left-anchored
and that matches from later in that same line?  For one, it is terribly
inefficient without an anchor.  Procmail will try to match it against
every line in every header in your mail, from far left to far right.
These procmail-list headers, you'll note, have well over 100 lines in
them, by way of example.  That's a lot of grepping around that procmail
is having to do!  And there's no need for it.  Just combine your
conditions:

   :0
   * ^X-Spam-Status: Yes, score=\/[^ ]+
   { XSSScore = $MATCH }

Now you also have a variable you can use in the rest of your testing.
By the way, the score can be negative.  Just keep that in mind when
you formulate regexes, especially if you decide to use scoring.
But if the X-Spam-Status is yes, it's not very likely that the
score will be negative, is it?  :-)  Unless you set your SA threshold
to a (non-default) negative number, that is.

By the way, if your SA output creates an "X-Spam-Score:" header,
like mine does as shown above, that would perhaps even be easier to
use.  But let's go on.

You say you want under 10 in your DEFAULT?  Okay.

  :0:
  * ! XSSScore ?? ..[.]
  $DEFAULT

That will put anything under 10 there that's not a negative
number.  (Again, we're not expecting any negatives with the 
X-Spam-Status string of "yes" anyway.)


For the ones 10.0 --> 99.9 (or above)
## Redirect spams   
:0:                 
* ^X-Spam-Status:(.*\<)?Yes
* $(score=[1-9][1-9]|10([0-9]|[.][0-9]))
$REVIEW

Your bottom condition is wrong.  I had written:

 ([1-9][1-9]|10([0-9]|[.][1-9]))

You've put the left paren to the left of "score=",
and that won't work right.  You are now looking,
anywhere in any header in any message with a positive
X-Spam-Status, for either the string

    score=[1-9][1-9]

or the string

    10[0-9]

or the string

    10[.][0-9]

I would venture to say you'll catch many messages with a
match on, for example, an IP address in a Received: header
with those unanchored options.

What you wanted was:

 * ^X-Spam-Status: yes, score=([1-9][1-9]|10([0-9]|[.][1-9]))

(And you didn't need the $ on your condition line there.)

But recall that that was for 10.1 or above.  For just 10 
and above, we can do it more simply still.

      :0
      * ^X-Spam-Status: Yes, score=[^.][^.]
      { TEN_OR_ABOVE = TRUE }

By the way, we don't need to check for "X-Spam-Status: yes"
again and again.  We did that already once above.  So either
use nested braces or a variable such as my XSSScore (which
won't have been set unless we had a "yes", remember), or
both.  Assuming you go with the variable, then this here would
be simply:

      :0
      * XSSScore ?? ..[^.]
      { TEN_OR_ABOVE = TRUE }

You could alternatively use the stars.  I'm assuming anything
above ten is going to be a "yes" automatically, right?


    * ^X-Spam-Level: \*\*\*\*\*\*\*\*\*\*

The End!

But wait, there's a sequel.  You could use scoring, again, with
the XSSScore var, if you wanted:

   :0
   * $ $XSSScore ^0
   *         -10 ^0
   { ABOVE_10 = TRUE }

Not that 10.0000 will not match here.  It will have to be
*above* 10.  If you want to include 10.0000, you could
either add a miniscule "tipping" decimal to the score (as
another scored condition line) or do the reverse-logic trick.
We'd need to be double-sure XSSScore isn't a negative here,
though; hence my first condition:

   :0
   * ! XSSScore ?? -
   * $ -$XSSScore ^0
   *           10 ^0
   { }  # do nothing
   :0 E
   { ABOVE_10 = TRUE }

Finally, you could change "10" to a variable that you would
then easily alter at will up-top:

   THRESHOLD = 10   # (change at will)

   # . . . .

   :0
   * ! XSSScore ?? -
   * $  -$XSSScore ^0
   * $  $THRESHOLD ^0
   { }  # do nothing
   :0 E
   { ABOVE_THRESHOLD = TRUE }

The End (for real)

Dallman
____________________________________________________________
procmail mailing list   Procmail homepage: http://www.procmail.org/
procmail(_at_)lists(_dot_)RWTH-Aachen(_dot_)DE
http://MailMan.RWTH-Aachen.DE/mailman/listinfo/procmail

<Prev in Thread] Current Thread [Next in Thread>