procmailspamassassin

Procmail recipe to match Spamassassin X-Spam-Status score or X-Spam-Level


Consider these mail headers:

X-Spam-Level: ***
X-Spam-Status: Yes, score=3.7 required=3.0 tests= (remaining truncated for brevity)

I simply want to match the headers

"X-Spam-Level: ***" (at least with more "*" okay)

or

"X-Spam-Status: Yes, score=3.7" (or a higher score)

I have this, which matches the X-Spam-Level header, but I'm seeing stuff slip through with a score of 3.7 or higher, making me believe the alternation is being skipped:

:0 H
    * ^X-Spam-Status: Yes
    * ^(X-Spam-Level: \*\*\*\*)|(^X-Spam-Status: Yes, score=3\.[7-9])
    { 
        do stuff
}

Procmail's regex implementation is just not quite the same as what I'm used to and can't get this to work, despite matching on sites like regex101.com

I'm perfectly fine with a solution just matching the score of 3.7 or higher and removing the X-Spam-Level condition completely.

Note: I am aware that the minimum score I've set in Spamassassin is 3.0 to flag as spam, however, I deliver stuff to the user's mailbox between 3 and 3.6 and move anything higher to a server spam mailbox. Presently, it's only getting delivered to the server's spam mailbox if 4.1 or higher, as denoted by the asterisks in X-Spam-Level.


Solution

  • I never could get this working. Instead, I modified the Spamassassin local.cf config to add a header line:

    add_header all Score _SCORE_
    

    This creates a new mail header of X-Spam-Score: n.n where n are digits.

    In the procmailrc file, I added this line to the top:

    # Change this value to be whatever threshold
    # you want
    # Spam scored between 3 and 3.6 will be delivered.
    # Spam scored over 3.6 won't.
    SPAMTHRESHOLD=3.6
    

    Later in the file, after spamc is called, I declare a variable to capture the score then check against it:

    # Create SCORE variable which contains the header I created in Spamassassin
    :0 # H flag is implicit
        * ^X-Spam-Score: \/.+
        { SCORE=$MATCH }
    
    # Check for Spam-Status: Yes, and 
    # $SCORE > $SPAMTHRESHOLD
    :0 H
        * ^X-Spam-Status: Yes
        * $ -${SPAMTHRESHOLD}^0
        * $ ${SCORE}^0
        { 
            # do stuff. in this case move the mail to 
            # /var/mail/spam
            :0:spam.lock
            /var/mail/spam
    }