NAME

pmx-policy - Interface to the PureMessage policy engine


SYNOPSIS

pmx-policy <command> [options]


DESCRIPTION

The pmx-policy command provides an interface to the PureMessage policy engine.

Note: As of PureMessage 5.2.1, the policy.siv file supports UTF-8 characters beyond the Latin1 range. As a result, certain areas of the policy now accept Japanese characters. See the PureMessage 5.2.1 release notes for details.

Commands

The following subcommands are recognized by the pmx-policy script:

tests
Print the test commands supported by the policy engine. See Tests.

actions
Print the action commands supported by the policy engine. See Actions.

check
Check the syntax of the Sieve script (by default policy.siv). For an overview of the Sieve language see Policy Script.

edit
Edit the Sieve script.

list listname
Print the configuration for the specified list.

lists
Print the lists available to policy engine.

inject files
Inject messages from the specified file(s). If a file is in ``mbox'' format, all the messages contained in the file are processed. Otherwise the file is interpreted as a single message.

Messages are delivered or quarantined as if they are regular 'live' messages received by the PureMessage milter (unless the --dry-run option is specified). If the delivery action of a policy rule is pmx_tempfail, discard or reject, the message is discarded. When complete, a report is generated that describes the actions taken for each message.

If the --dry-run option is specified, messages are processed according to the policy script, but is not delivered, discarded or quarantined.

qinject --where condition
qinject id1 id2 id3 ...
Similar to ``inject'', qinject injects messages from the PureMessage quarantine. The --dry-run option can be specified, and has the same effect as those described in the inject action.

Messages are not deleted from the quarantine unless the --delete option is specified, which causes messages to be moved to the trash after being injected. The --delete option is useful for re-processing quarantined messages with a newly modified policy script; messages are deleted from the quarantine, but are re-quarantined if they trigger that action in the policy script.

The --where option is used to specify the messages in the quarantine that should be processed. Alternatively, the quarantine database ids can be listed explicitly. The syntax of the --where condition can be found in PureMessage::MessageStore.

repo command
Execute the specified repository command. For a full explanation of the possible commands see Repository

Options

The following options are recognized:

--script path
Specify a script other than the default policy.siv.

--quarantine dir:path
Specify a quarantine other than the one specified in the quarantine_dir option in the pmx.conf configuration file.

--verbose
Print more information about what the program is doing.

--dry-run
When using inject or qinject, do not deliver or quarantine any messages. Just print out the action that would have been taken.

--no-index
This option suppresses indexing of the messages in the test message store, which is used when the --dry-run option is specified. The --no-index option has no effect unless the --dry-run option is specified as well. This option is mainly useful for profiling the filtering engine.

--delete
When using qinject, delete the original messages after processing.

--relay hostname
--fur ip
--to email-addr[,email-addr,email-addr,...]
--from email-addr
Simulate the hostname of the connecting MTA, or the envelope sender/recipient. When used in conjunction with qinject, the default is to read these values from the quarantine information (although you can still override them using these options). Multiple recipients can be specified using a comma-separated list with the --to option.


Policy Script

The policy script is executed for each message that is processed. The policy script can test various characteristics of the message, and perform a variety of actions based on the results of those tests. The default policy script is policy.siv and is located in the /opt/pmx/etc directory.

The PureMessage policy script is expressed in Sieve, a mail-filtering language defined by RFC 3028. Sieve is a command-based language; its syntax somewhat resembles C or Perl, but it has no variables or looping constructs. And, like those languages, Sieve is case sensitive. Sieve commands can be either tests, actions or controls. Tests check whether some condition is met. Actions modify the routing or content of the message. Controls modify the control flow in the script.

Commands can have three different kinds of arguments: positional, optional and tagged. Tagged arguments begin with a colon and can appear in any order after a command. Tagged arguments can have zero or more parameters that appear after them.

Positional arguments must appear in order, and must appear after any tagged arguments. Optional arguments are exactly like tagged arguments except that they are optional.

Here is an example policy script:

    # Filter out badly formatted mail
    # and mail from unwanted senders.
    if anyof (not exists ["From", "Date"],
              header :contains "From" "unwanted@foo.com") {
        discard;
        stop;
    }

Things to note about this example:

Global Tags

The following tags are used by many of the tests and actions described in this document.

ADDRESS-PART
In address-related tests, the ADDRESS-PART tag specifies the portion of the address to match against.
:all
Match the whole address (default)

:localpart
Match the local part of the address

:domain
Match the domain of the address

:detail
By default, if PureMessage encounters a message containing a sub-address, it removes the ``+'' sign and everything else preceding the ``@'' sign prior to processing the message. So, by default, user+box1@example.com is processed as user@example.com. You can override this default behavior by specifying the <:detail> option. This option can be used in conjunction with <:localpart>.

COMPARATOR
When matching, the comparator tag can be used to specify whether or not the search should be case insensitive. The syntax is
    :comparator <comparator-name: string>

Where comparator name can be one of:

i;octet
Match the bytes of the strings exact (case sensitive)

i;ascii-casemap
Treat uppercase and lowercase ASCII characters as equal (case insensitive). This is the default if the :comparator is left unspecified.

MATCH-TYPE
When a test is doing a matching operation on some feature of a message, the MATCH-TYPE tag specifies what kind of match to do.

The <key-list: string-list> parameter, which matches data, is interpreted differently, depending on the MATCH_TYPE specified.

There are five possible match types:

:is
Exact match. This is the default if this parameter is not specified.

:contains
Substring match.

:matches
Wildcard match. The '?' character will match against any single character, and the '*' character will match any group of characters.

:re
Regular Expression match. Match using a Perl Regular Expression. See the Regular Expression Primer section of the Administrator's Reference for more about regular expressions.

The :re match is a PureMessage specific Sieve extension.

:memberof
List match. Match against a named list. The list must have a configuration defined in lists.conf. See the lists.conf manpage, and PureMessage::List for more information. The :memberof match is a PureMessage-specific Sieve extension.

NUMERIC-COMP
Used to specify a numeric comparison. Note that :over and :under can be combined with the not test to compare 'at-least' and 'at-most' the given number, respectively.
:over
True if the message feature is over the given number.

:under
True if the message feature is under the given number.

DATA-TYPE
Used to specify if a command should interpret a parameter as string data, or as the name of a file from which data should be read.
:data
Interpret parameter verbatim, as string data.

:file
Interpret parameter as a filename. The file is opened at runtime and the data is read from the file.

Controls

if
Syntax:
    if <test1: test> <block1: block>
    elsif <test2: test> <block2: block>
    else <block>

Description:

The semantics are similar to other languages that use these control commands. When the interpreter sees an 'if', it evaluates the test associated with it. If the test is true, it executes the block associated with it.

If the test of the 'if' is false, it evaluates the test of the first ``elsif'' (if any). If the test of 'elsif' is true, it runs the 'elsif''s block. An 'elsif' may be followed by additional 'elsif' statements, in which case, the interpreter repeats this process until each 'elsif' has been evaluated.

When the interpreter runs out of 'elsif's, there may be an 'else' case. If there is, and none of the 'if' or 'elsif' tests were true, the interpreter runs the 'else' case.

require
Syntax:

require <capabilities: string-list>

The 'require' control states that a script makes use of a certain extension. It must be stated before anything other than a 'require' can be used. An error occurs if a 'require' is used after a command other than 'require'.

Example:

    require ["extension1", "extension2"];

Example:

    require "extension1";
    require "extension2";

To use any PureMessage specific extension tests or actions (which are prefixed with 'pmx_') in the script, the script must start with:

    require "PureMessage";

PureMessage also provides the standard extensions 'reject' and 'envelope' as specified in RFC 3028.

Note that if you 'require ``PureMessage''', you don't need to require 'reject' or 'envelope': they are included implicitly with the ``PureMessage'' extension.

stop
Syntax:
    stop

Description: Stop processing the message. When a message hits a stop command, it immediately stops processing and its 'delivery action' is executed. If no delivery action has been set on the message, the default action is 'keep'. If a message reaches the end of a policy script, the 'stop' command is implied.

Parameters: none

Tests

Logical Tests

Sieve has special tests that are used as logical operators.

allof
Syntax:
    allof <test-list>

Description: Returns true if all the tests in test-list return true.

anyof
Syntax:
    anyof <test-list>

Description: Returns true if any the tests in test-list return true. Returns immediately once a true test is found, evaluating left-to-right (known as 'short-circuit' operation).

false
Syntax:
    false

Description: Always returns false.

not
Syntax:
    not <test>

Description: Returns false if test returns true, and vice-versa.

true
Syntax:
    true

Description: Always returns true.

Routing Tests

address
Syntax:
    address
        [ADDRESS-PART]
        [COMPARATOR]
        [MATCH-TYPE]
        <header-list: string-list>
        <key-list: string-list>

Description: Returns true if any email address in the 'To','From','Cc' or 'Bcc' headers matches.

Parameters:

<header-list: string-list> - list of headers to match against. Can be any of ('To', 'From', 'Cc', 'Bcc').

<key-list: string-list> - match data, which will be interpreted differently depending on the MATCH_TYPE.

envelope
Syntax:
    envelope
        [COMPARATOR]
        [ADDRESS-PART]
        [MATCH-TYPE]
        <envelope-part: string-list>
        <key-list: string-list>

Description: Returns true if any either the envelope sender or any envelope recipients' addresses match.

Parameters:

<envelope-part: string-list> - list of envelope parts to match against.

Possible values:

'to' - match the envelope recipient

Note: When using this test in conjunction with email addresses that have been associated as part of a Recipient aliases map, you must ensure that the 'to' value specified here matches the ``Map To'' portion of the address map. For example, if service@example.com has been mapped to joe@example.com, then the 'to' address is joe@example.com. For more information, see 'Address Maps' in the Policy Rules section of the Administrator's Reference.

'from' - match the envelope sender

'group' - pick up the sender or recipient(s) group(s) based on message's direction and match them against the provided key-list

<key-list: string-list> - match data, which will be interpreted differently depending on the MATCH_TYPE.

exists
Syntax: exists <header-names: string-list>

Description: Returns true if any header in header-names exists within the message.

Parameters:

<header-names: string-list> - headers to look for

header
Syntax:
    header [COMPARATOR] [MATCH-TYPE] <header-names: string-list> <key-list: string-list>

Description: Returns true if the value of any header in header-names matches.

Parameters:

<header-names: string-list> - headers to match against

[MATCH-TYPE] <key-list: string-list> - see MATCH-TYPE section

pmx_relay
Syntax:
    pmx_relay [:fur] [MATCH_TYPE] <key-list: string-list>

Description: Returns true if IP or hostname of the connecting MTA/MUA matches.

Parameters:

:fur - If present, modifies the test to use first untrusted relay detection.

[MATCH-TYPE] <key-list: string-list> - see MATCH-TYPE section

Content Tests

pmx_8bit_percentage
Syntax: pmx_8bit_percentage [NUMERIC-COMP] <limit:number>

Description: Returns true if the proportion of 8bit (non-ASCII) characters in a message is over or under a certain number. This can be used to check whether a message is 7bit-clean (pure ASCII).

Parameters:

[NUMERIC-COMP] <limit:number> - see NUMERIC-COMP section. limit must be an integer between 0 and 100.

pmx_attachment_name
Syntax:
    pmx_attachment_name [:tft] [MATCH-TYPE] <key-list: string-list>

Description: Returns true if an attachment name matches a value in key-list. Searches the Content-Type and Content-Disposition headers as well as the files themselves for the filename(s) you have specified.

Archives are automatically expanded, so that files within other files can be tested. PureMessage will search as many levels as necessary (up to a configured maximum) to find specified file types. The maximum recursion depth is set in /opt/pmx/etc/tft.conf.

Can be used to do attachment-specific filtering. Expands the %%ATTACHMENT_NAMES%% template variable.

Note: Because this test also returns true whenever PureMessage is unable to scan a message, you should use the pmx_cantscan test within pmx_attachment_name to specify how unscannable messages are handled.

Parameters:

:tft - if present, modifies the test to use true file type detection. The file itself is examined in addition to the filename shown in the Content-Type and Content-Disposition headers.

Tests for document types should use the application-specific file extension (such as .doc or .xls). To view a list of extensions that PureMessage supports, run:

     pmx-list-true-filetypes --verbose

The following example uses pmx_attachment_name to detect Microsoft Excel documents:

    if pmx_attachment_name :tft :matches "*.xls" {
      pmx_mark1 "MSExcel";
    }

[MATCH-TYPE] <key-list: string-list> - see MATCH-TYPE section

pmx_attachment_size
Syntax:
    pmx_attachment_size [NUMERIC-COMP] <limit: number>

Description: Returns true if the size of any attachment (including text/plain and text/html message body parts) is over or under limit. Can be used to do attachment-specific filtering. If no size unit is specified, the default is bytes. To specify an alternate size unit, append 'K' (kilobytes), 'M' (megabytes) or 'G' (gigabytes) to the number. Expands the %%ATTACHMENT_NAMES%% template variable.

Parameters:

[NUMERIC-COMP] <limit: number> - see NUMERIC-COMP section

pmx_attachment_true_filetype
Syntax:
    pmx_attachment_true_filetype [MATCH-TYPE] <key-list: string-list>

Description: Returns true if file attachments match a file type specified in key-list. The advantage of using this test over similar tests (pmx_attachment_type and pmx_attachment_name) is that the action is not performed on a message unless the file type is a true match for one that is specified in this test.

For example, the pmx_attachment_type test will perform the action if there is a file type match in the message's Content-Type header, even if that does not represent the true identity of the file. So, it could be that a message appears to contain a Microsoft Word attachment, but the file extension has been falsified, and the message actually contains a .jpeg file instead.

Important: This test can be used to detect specific file types or groups of file types. Run pmx-list-true-filetypes to display a list of true filetype groupings. Run pmx-list-true-filetypes --verbose to also display the individual file extensions included in each group. When using this test, you should specify the appropriate true filetype definition (as displayed in the list of groupings) in the :contains argument.

For example, you could create a rule that applies to all Microsoft Word document files, ranging from Word 95 to the most recent Word document extensions:

    if pmx_attachment_true_filetype :contains "Document/Microsoft Word" {
      pmx_mark1 "MS Word Document";
      stop;
    }

To create a rule that detects only Word 2007 documents:

    if pmx_attachment_true_filetype :contains "Document/Microsoft Word-OPC" {
      pmx_mark1 "MS Word Document";
      stop;
    }

To create a rule that quarantines any message with an attached image:

    if pmx_attachment_true_filetype :contains "Image/" {
      pmx_mark1 "Image";
      pmx_quarantine "Image";
      stop;
    }

You can use pmx_attachment_true_filetype to target file types that PureMessage was not able to identify. This is done by specifying the ``Data/Binary'' group, as shown below:

    if pmx_attachment_true_filetype :contains "Data/Binary" {
      pmx_mark1 "UnknownFileType";
      pmx_quarantine "UnknownFileType";
      stop;
    }

Note: Because this test also returns true whenever PureMessage is unable to scan a the message, you should use the pmx_cantscan test within pmx_attachment_true_filetype to specify how unscannable messages are handled.

Expands the %%ATTACHMENT_NAMES%% template variable.

Parameters:

[MATCH-TYPE] - <key-list: string-list> - see MATCH-TYPE section

pmx_attachment_type
Syntax:
    pmx_attachment_type [:tft] [MATCH-TYPE] <key-list: string-list>

Description: Returns true if an attachment Content-Type header or the contents of a file itself match a value in key-list. Archives are automatically expanded, so that files within other files can be tested. PureMessage will search as many levels as necessary (up to a configured maximum) to find specified file types. The maximum recursion depth is set in /opt/pmx/etc/tft.conf.

Can be used to do attachment-specific filtering. Expands the %%ATTACHMENT_NAMES%% template variable.

Note: Because this test also returns true whenever PureMessage is unable to scan a message, you should use the pmx_cantscan test within pmx_attachment_type to specify how unscannable messages are handled.

Parameters:

:tft - if present, modifies the test to use true file type detection. The file itself is examined in addition to the Content-Type header.

Tests for attachment types should use the Mime file type. For a complete list of the Mime types that PureMessage supports, run:

    pmx-list-true-filetypes --verbose

To create a rule, for example, that detects Excel attachments:

    if pmx_attachment_type :tft :matches "application/ms-excel" {
      pmx_mark1 "MSExcel";
    }

[MATCH-TYPE] <key-list: string-list> - see C<MATCH-TYPE> section

pmx_body_size
Syntax:
    pmx_body_size [NUMERIC-COMP] <limit: number>

Description: Returns true if the size of the body is over or under the number given. If no size unit is specified, the default is bytes. To specify an alternate size unit, append 'K' (kilobytes), 'M' (megabytes) or 'G' (gigabytes) to the number.

Parameters:

[NUMERIC-COMP] <limit: number> - see NUMERIC-COMP section

pmx_cantscan
Syntax:
    pmx_cantscan

Description: Returns true if a message could not be scanned. Must be called after pmx_attachment_name, pmx_attachment_true_filetype, pmx_attachment_type, pmx_credit_card, pmx_phrase, or pmx_suspect_attachment to be effective.

This test is mainly used to differentiate between messages that cannot be scanned for some reason (e.g., an unrecognized file type), and messages that contain undesired content, since both will cause the various content tests to return true.

The kinds of unscannable content that PureMessage should allow or deny can be customized by editing the files in /opt/pmx/etc/scanlimit.d/. To configure unscannable content options for the pmx_phrase and pmx_credit_card tests, use /opt/pmx/etc/scanlimit.d/phrase.conf. For the attachment tests, use /opt/pmx/etc/scanlimit.d/tft.conf. See the tft.conf and phrase.conf man pages for more information.

Parameters:

None

pmx_credit_card
Syntax:
    pmx_credit_card [:attachments] [:scanall]

Description: Returns true if the message contains any numeric sequences that are common to major credit cards. This test is based on the Luhn algorithm, a checksum formula that performs the validation. Supported credit cards are American Express, MasterCard, Visa, Visa Electron, Discover Card, Diners Club, and China Union Pay.

The creditcard_number_limit setting in /opt/pmx/etc/creditcard.conf determines how many numeric sections PureMessage will scan in a given message. By default, PureMessage scans nine separate sections of numbers that might contain credit card numbers before proceeding to the next stage of processing.

You can configure the scan failure actions for this test in /opt/pmx/etc/scanlimit.d/phrase.conf.

Note: Because this test also returns true whenever PureMessage is unable to scan a message, you should use the pmx_cantscan test within pmx_credit_card to specify how unscannable messages are handled.

Parameters:

:attachments - If specified, pmx_credit_card also matches inside of attachments, including attachments contained in .tgz and .zip files. For example, it can detect a phrase that appears in an .xls file, which is embedded in a .doc file that is inside a .zip file.

:scanall - When specified together with the :attachments parameter, this test scans all attachments regardless of whether a match is found. If you only specify the :attachments parameter, the associated action is performed as soon as the first match is found, so any remaining attachments are not scanned. This is a concern if you are combining the pmx_credit_card test with actions such as pmx_drop_attachment because only the attachment in which the first match occurred would be dropped; the remainder would be delivered, regardless of their contents.

pmx_dkim_verify
Syntax:
    pmx_dkim_verify [MATCH-TYPE] pass none fail invalid

DomainKeys Identified Mail (DKIM) is an authentication framework used to sign and validate a message, based on the domain of the sender. This test performs the validation by verifying the origin of the sending address. To configure PureMessage to add a DKIM signature to some or all outgoing messages, see pmx_dkim_sign.

DKIM verification depends on access to public keys stored on an available DNS server. This must also be configured for this test to take affect. For general information, see www.dkim.org.

Important: To ensure the effectiveness of this test, it is recommended that you insert it ahead of spam tests in the policy. It is particularly crucial that this test be run before tests that modify message headers because such modifications could corrupt or remove the DKIM signature.

Description: When specified, PureMessage can verify the origin of messages that bear a DomainKeys Identified Mail (DKIM) signature. This test returns true if the message matches the value specified.

Create multiple tests to allow for the four possibilities described in the values below.

Configurable Values:

pass - A signature is detected and verified.

none - there is no DKIM signature.

fail - A DKIM signature is present but cannot be verified.

invalid - The message cannot be verified for some reason. For example, a DNS timeout or an invalid DNS hostname.

To create a rules for all of these values you could, for example, edit your policy as follows:

    # attr NAME=DKIM verified as "pass"
    if pmx_dkim_verify :is "pass" {
    }
    # attr NAME=DKIM verified as "none"
    elsif pmx_dkim_verify :is "none" {
    }
    # attr NAME=DKIM verified as "fail"
    elsif pmx_dkim_verify :is "fail" {
        pmx_quarantine "DKIM failed";
    }
    # attr NAME=DKIM verified as "invalid"
    else {
        pmx_quarantine "DKIM invalid";
    }

If you plan to quarantine messages based on certain test results, you may want to create a quarantine digest informing end users that messages have been quarantined for this reason. For more information, see the pmx-qdigest.conf manpage or 'Managing Quarantine Digest Rules' in the Quarantine Tab section of the Manager Reference.


Parameters:

[MATCH-TYPE] pass, none, fail, or invalid

pmx_header_size
Syntax:
    pmx_header_size [NUMERIC-COMP] <limit: number>

Description: Returns true if the size of the header is over or under the number given. If no size unit is specified, the default is bytes. To specify an alternate size unit, append 'K' (kilobytes), 'M' (megabytes) or 'G' (gigabytes) to the number.

Parameters:

[NUMERIC-COMP] <limit: number> - see NUMERIC-COMP section

pmx_number_of_attachments
Syntax:
    pmx_number_of_attachments [NUMERIC-COMP] <limit: number>

Description: Returns true if the number of parts a message has is over or under the number given.

Parameters:

[NUMERIC-COMP] <limit: number> - see NUMERIC-COMP section

pmx_number_of_recipients
Syntax:
    pmx_number_of_recipients [NUMERIC-COMP] <limit: number>

Description: Returns true if the number of recipients for message is over, under or equal to the number specified.

Parameters:

[NUMERIC-COMP] <limit: number> - see NUMERIC-COMP section

pmx_offensive_word
Syntax:
    pmx_offensive_word

Description: Returns true if the message contains a word or phrase listed in the ``offensive-words'' list. This test will decode base64/quoted-printable encoded text and will strip out HTML markup before looking for a match.

Parameters: none

pmx_phrase
Syntax:
    pmx_phrase [:attachments] [:scanall] [MATCH-TYPE] <key-list: string-list>

Description: Returns true if the body, subject, or attachments match a value in key-list. This test will decode base64/quoted-printable encoded text and will strip out HTML markup before looking for a match. This test supports both ASCII and Latin 1 UTF-8 encodings.

Note: Because this test also returns true whenever PureMessage is unable to scan a message, you should use the pmx_cantscan test within pmx_phrase to specify how unscannable messages are handled.

Parameters:

:attachments - If specified, pmx_phrase also matches inside of attachments, including attachments contained in .tgz and .zip files. For example, it can detect a phrase that appears in an .xls file, which is embedded in a .doc file that is inside a .zip file.

:scanall - When specified together with the :attachments parameter, this test scans all attachments regardless of whether a match is found. If you only specify the :attachments parameter, the associated action is performed as soon as the first match is found, so any remaining attachments are not scanned. This is a concern if you are combining the pmx_phrase test with actions such as pmx_drop_attachment because only the attachment in which the first match occurred would be dropped; the remainder would be delivered, regardless of their contents.

Two variables are available for this test: %%MATCHED_TEXT%% and %%MATCHED_FILE%%. See Contextual Variables for more information.

You can set the maximum attachment size and the maximum time per message scanned in /opt/pmx/etc/phrase.conf.

[MATCH-TYPE] <key-list: string-list> - see MATCH-TYPE section

Of the the available match-types, only the contains and re match-types are recommended for this test. The is and matches tests will compare against the entire text of the message or attachment, which is usually not desirable when looking for a particular phrase.

pmx_spam_hit
Syntax:
    pmx_spam_hit [MATCH-TYPE] <key-list: string-list>

Description: Returns true if the name of a spam rule matches the given value. Examples of spam hits are 'RCVD_IN_RFCI', and 'SUSPICIOUS_RECIPS'.

Parameters:

[MATCH-TYPE] <key-list: string-list>

pmx_spam_prob
Syntax:
    pmx_spam_prob [NUMERIC-COMP] <limit:number>

Description: Returns true if the probability of the message being spam is over or under the given number. Even if a message passes through several pmx_spam_prob tests, the message is only scanned once, and its spam probability value is saved from the first test. This makes it possible to have different actions based on different spam probability ranges without having to scan the message multiple times.

Parameters:

[NUMERIC-COMP] <limit:number> - see the NUMERIC-COMP section

pmx_suspect_attachment
Syntax:
    pmx_suspect_attachment [:tft] [:inspect_archives]

Description: Returns true if the message contains an attachment whose filename matches the ``suspect-attachment-names'' list, or whose content-type matches the ``suspect-attachment-types'' list.

This test searches the attachment itself as well as the Content-Type and Content-Disposition headers for filenames.

The suspect attachment test can be used with the standard delivery actions (reject, discard, pmx_quarantine, etc.), to quarantine, reject or silently discard messages containing suspicious attachments.

Parameters:

:tft - if present, modifies the test to use true file type detection. The file itself is examined as well as the filename and file type as shown in the Content-Type and Content-Disposition headers. Archives (and archives within archives) are automatically inspected by this option.

Note: If the :tft parameter has been specified, the :inspect_archives parameter described below is not required.

:inspect_archives [deprecated] - if present, this test will attempt to inspect attached archives for filenames that match the suspect-attachment-names list. Only ZIP (plain and encrypted) archives are supported. Also, just the top-level archive is inspected - if the archive itself contains an archive, the contained archive is not inspected.

Note: Because this test also returns true whenever PureMessage is unable to scan a message, you should use the pmx_cantscan test within pmx_suspect_attachment to specify how unscannable messages are handled.

pmx_virus
Syntax:
    pmx_virus

Description: Returns true if a virus engine detects a virus.

Parameters: none

pmx_virus_id
Syntax:
    pmx_virus_id [MATCH-TYPE] <key-list: string-list>

Description: Returns true if the ID of one of the viruses in the message matches a given value.

Parameters:

[MATCH_TYPE] <key-list: string-list> - see the MATCH-TYPE section

pmx_virus_cantscan
Syntax:
    pmx_virus_cantscan

Description: Returns true if virus scanning failed for a message. Must be called after pmx_virus to be effective. This test is mainly used to differentiate between messages that cannot be scanned for some reason (e.g. encryption), and messages that contain viruses, since both will cause pmx_virus to return true. The kinds of unscannable content that PureMessage should allow or deny can be customized by editing the etc/virus.d/cantscan.conf file.

Type man cantscan.conf for more information about cantscan.conf.

Parameters:

None

size
Syntax:
    size [NUMERIC-COMP] <limit: number>

Description: Returns true if the size of the message is over or under the number given. If no size unit is specified, the default is bytes. To specify an alternate size unit, append 'K' (kilobytes), 'M' (megabytes) or 'G' (gigabytes) to the number.

Parameters:

[NUMERIC-COMP] <limit: number> - see NUMERIC-COMP section

Sender Reputation Tests

pmx_blocklist
Syntax: pmx_blocklist

Description: Returns true if the IP address of the sender is listed in the Blocklist data package from SophosLabs. pmx_blocklist traverses the message's ``Received'' headers looking for a match, skipping hosts listed in trusted-relays or internal-hosts. IP addresses in ip-blocking-exceptions are explicitly exempted.

Example:

    if pmx_blocklist {
        discard; 
    }

The pmx_blocklist test is a policy-level implementation of the MTA-level IP blocking provided by pmx-blocker. It allows more flexibility in handling messages from blocked IP addresses and can provide more information about those messages in the logs. By using the IP addresses in the ``Received'' headers rather than just the connecting IP address, pmx_blocklist is effective even if the PureMessage server is one or more hops behind the network gateway.

Actions

Routing Actions

These actions pertain to the routing of a message. Some actions affect the final destination of a message (deliver, discard, reject), some trigger another message to be delivered (pmx_notify, pmx_forward), and some alter the recipients of a message (pmx_add_recipient, pmx_map_recipients).

The most common routing actions tell PureMessage what 'delivery action' to take on the message. These are:

When a message encounters one of these actions, its delivery action is set and cannot be changed, but the message still progresses through the policy script until it reaches the end of the script or a stop command. When the message stops processing, PureMessage analyzes the delivery action of the message and determines how it should be handled.

discard
Syntax:
    discard

Description: Silently throw away the message.

Parameters: none

keep
Syntax:
    keep

Description: Deliver the message to its envelope recipients.

Parameters: None

pmx_add_recipient
Syntax:
    pmx_add_recipient <address: string-list>

Description: Add one or more recipients to the message envelope (as opposed to redirect, which replaces the envelope recipients).

Parameters:

<address: string-list> - addresses to add to the message envelope

pmx_deliver_for
Syntax:
    pmx_deliver_for [:except] [MATCH-TYPE] <key-list: string-list>

Description: Queue messages to specified recipients for delivery, skipping subsequent policy rules. For example:

    pmx_deliver_for :memberof ["anti-spam-optouts"];

This rule exempts messages to recipients in the anti-spam-optouts list from further policy processing and queues them for delivery.

If a message has matching and non-matching SMTP envelope recipients, a copy of the message for the matching recipients is queued for delivery, and another copy for the remaining (non-matching) recipients continues through subsequent policy rules.

Note: Queued messages are not delivered until the pmx-qindex and pmx-queue run scheduled jobs are executed.

Parameters:

[:except] - inverts the match. When present, the non-matching recipients are queued for delivery.

[MATCH-TYPE] <key-list: string-list> - see [MATCH-TYPE] section

pmx_file
Syntax:
    pmx_file <reason: string>

Description: File a copy of the message in the quarantine. pmx_file does not actually affect the delivery of the message. If called multiple times, multiple copies of the message are filed in the quarantine. The copy filed in the quarantine will incorporate any changes made to the message up to that point by previous actions. Quarantine reasons should be a single word or identifier; any whitespace is collapsed to single underscores (_).

Parameters:

<reason: string> - reason for filing the message

pmx_forward
Syntax:
    pmx_forward <address: string-list>

Description: Forward message to the specified addresses. pmx_forward does not affect the delivery of the message (like pmx_add_recipient does); instead, it writes a copy of the message to the outgoing queue, which is then delivered by pmx-queue.

Calling pmx_forward multiple times will cause multiple copies of the message to be written to the outgoing queue and delivered. pmx_forward is like a Bcc or ``blind carbon copy'' in that the original recipients of the message will not see that the message was forwarded. Note: queued messages are not delivered until pmx-qindex and pmx-queue run are executed.

Parameters:

<address: string-list> - recipient(s) to forward to.

pmx_map_recipients
Syntax:
    pmx_map_recipients <map-name: string>

Description: Maps the envelope recipients using a named list lookup. The envelope recipients are looked up in the list, and, if they match, they are replaced with the looked-up value.

Parameters:

<map-name: string> - name of the recipient map, which must be declared in etc/lists.conf.

pmx_notify
Syntax:
    pmx_notify
        <":sender" / ":recipients">
        [:map <map-name: string>]
        <":data" / ":file">
        <data: string>

Description: Queue a notification email for delivery to the sender or recipients of a message. Any template variables in the data are expanded. Any lines up to the first blank line are interpreted as headers. Note: queued messages are not delivered until pmx-qindex and pmx-queue run are executed.

Parameters:

:sender - send a notification to the mail sender

:recipients - send a notification to the recipients (default)

:data - indicates that 'data' should be used verbatim as the email

:file - indicates that 'data' should be interpreted as a filename, and the email text read from the specified file.

[:map <map-name: string>] - optional map specification. The tag :map followed by the name of a map that applies to the addresses where the notification is sent.

pmx_quarantine
Syntax:
    pmx_quarantine <reason: string>

Description: File a copy of the message in the quarantine and discard the original. pmx_quarantine is the equivalent of pmx_file, followed by discard. Quarantine reasons should be a single word or identifier; any whitespace is collapsed to single underscores (_).

Parameters:

<reason: string> - reason for quarantining the message

pmx_rename_attachment
    pmx_rename_attachment <data: string>

Description: Rename an attachment. The replacement string can use the %%ATTACHMENT_NAME%% template variable to provide the original filename in the replacement name. For example:

    if pmx_attachment_name :tft :matches "*.scr" {
      pmx_rename_attachment "%%ATTACHMENT_NAME%%.warning"
    }

Parameters:

<data: string> - see DATA-TYPE section

pmx_route
    pmx_route [<server: string-list>] [:copy] [:nobounce] <key-list: string-list>

Description: Route the message to a specified server or to multiple servers, usually for the purpose of archiving or encrypting. Enter the IP address(es) or fully qualified hostname(s) of the server(s) to which the message should be routed. For example, you could route all internal mail originating from a company's legal department to an encryption server, which would then deliver the message.

    # attr NAME=Encrypt all mail from Legal
    if envelope :comparator "i;ascii-casemap" :all :memberof ["from"] ["Legal"] {
        pmx_route ["EncryptionServer.example.com"];
    }

Note: When using pmx_route, make sure that the relay you specify here is not also a mail server that is delivering mail via the same server that performed the routing action. This would cause PureMessage to route mail in a continuous loop instead of delivering it.

Parameters:

:copy - In addition to processing the message and sending it to its intended destination, PureMessage also sends a copy of the message to the specified server(s). If this option is not used, the message will be routed to the specified server instead of the intended recipient(s).

:nobounce - If the specified routing server is not available, do not bounce the message. By default, the message is bounced to the original sender. The original sender receives a notification that is defined in the template /opt/pmx/etc/templates/Language_Dir/bounce-on-failure.tmpl.

Note: If, when upgrading to the latest version of PureMessage, an error message is displayed regarding the smtp_generic_maps setting in /opt/pmx/postfix/etc/main.cf, complete the following steps:

  1. Because policy routing only works with 'pcre' maps, ensure that the smtp_generic_maps setting is of the type pcre. For example:
        smtp_generic_maps=pcre:PathToMapFile

  2. In the pcre map file, add the following regular expression on a separate line at the end of the file:
        /(.*)%(.*)@.*/  $1@$2

  3. As the root user, in /opt/pmx/postfix/etc, run make.

These steps may also be necessary if you are using an external Postfix installation. Follow the same instructions, making adjustments for the different file locations.

pmx_tempfail
Syntax:
    pmx_tempfail

Description: Signal the MTA to return SMTP error code 421 - service not available.

Parameters: none.

redirect
Syntax:
    redirect <addresses: string-list>

Description: Redirect the message. The original envelope recipients are replaced.

Parameters:

<addresses: string-list> - the addresses of the new recipients

reject
Syntax:
    reject [:rcode <rcode:number> :xcode <xcode: string>] <reason: string>

Description: Reject the message.

Parameters:

<reason: string> - reason for rejecting. The message will be given to the connecting MTA and the sender will see this when the message 'bounces' back to them.

:rcode - optional SMTP rcode parameter for MTA response. Default is 550.

:xcode - optional SMTP xcode parameter for MTA response.

Content Actions

pmx_add_banner
Syntax:
    pmx_add_banner
        [:body]
        [:top]
        [:charset <charset:rx>]
        [:header <header-name: string>]
        [:groupfile <group multifile: string]
        [:recode]
        [:ignore <content-type: string>]
        [:use_html_pre]
        [DATA-TYPE]
        <data: string>

Description: Add a custom banner to the body or headers of a message.

If the body tag is specified, the banner is added to the end of a message (if the message contains a text part). For HTML parts, the banner is inserted just before the </BODY> tag. If there is no </BODY> tag, the banner is inserted just before the </HTML> tag.

If the top tag is specified, the banner is prepended to the beginning of a message. For HTML parts, the banner is inserted immediately after the <BODY> tag. If there is no <BODY> tag, the banner is inserted immediately after the <HTML> tag.

If the groupfile tag is specified, the banner is fetched based on the group(s) to which the message belongs and uses the default one assigned by data or file, if there is no group-specific banner(s).

If the message contains both an HTML and a plain text part, the banner is added to both (unless the ignore tag is used to ignore one of these types). If the message contains multiple text parts, the banner is added to the first one. If the message is multipart, and no text/plain or text/html part exists, the banner is added in a new text/plain part at the end of the message.

Banners can include Template Variables. Some template variables are only expanded after particular tests or within rules containing particular tests or actions.

Parameters:

[:body] - Add the banner to the end of the message body.

[:top] - Prepend the banner to the top of the message body.

Note: Choose either :body or :top, not both.

[:charset] - specify the character set of the banner so it is only added to matching message parts. This field can be a string or a regular expression that matches several aliases of a particular character set. The test is not case sensitive. For example, Big[_-]5.* would match and add a banner to message parts declared as big5, Big-5, and BIG5-HKSCS. If a character set is not specified, the banner text is added to all message parts. If the specified character set does not match any message parts, then no banner is added.

[:groupfile] - specify the group-specific multifile name.

[:header <header-name: string>] - add the banner to the message header

[:recode] - If a header contains encoded words, re-encode it when adding the banner. This option should be used if pmx_add_banner garbles the original encoded header when prepending text.

[:ignore <content-type: string>] - ignore a content-type. For example, to add banners to text/plain parts only, specify ':ignore ``text/html'''.

[:use_html_pre] - when adding the banner to an HTML part, put the banner in HTML <PRE> tags. This preserves text formatting (e.g. newlines and indentation) that would otherwise be lost in the rendered HTML.

[DATA-TYPE] <data: string> - see DATA-TYPE section

Note: When adding a banner by way of a file (:file), specify the full path and filename. The contents of the file must be text. The file must be of the same charset specified in the policy action.

If the banner is specified as 'verbatim' and charset is used, it will only be added successfully if:

  • iconv is enabled in utf8.conf

  • charset is one of:
    • UTF-8

    • iso-2022-jp

    • EUC-JP

    • Shift-JIS

    • iso-8859-1

Conversion from UTF-8 to iso-2022 does not work correctly for older versions of iconv (including versions shipped with Solaris 2.6). To work around this limitation, use an iso-2022-jp file for adding the banner.

pmx_add_header
Syntax:
    pmx_add_header <key: string> <value: string>

Description: Add a header 'key' with value 'value'. Note: the sendmail specification does not state where (prepended, appended, etc.) the new header will be added.

Parameters:

<key: string> - the header name

<value: string> - the header value

pmx_archive
Syntax:
    pmx_archive [:original] [:mstore] <filename: string>

Description: Archive the message. By default, a copy of the message is stored in 'mbox' format (compatible with many mail readers) in the specified directory and filename. If the :mstore option is specified, messages are stored using the PureMessage 'message store' directory and file architecture. The :mstore option is preferable on high-volume systems because archiving to a single file requires locking, which may slow down message processing.

Parameters:

:original - If specified, PureMessage archives the original, unmodified message, prior to any modifications made by the policy script. Otherwise, the archived message includes modifications made to the message by the policy script up to the current point in processing.

:mstore - If specified, the message is saved using the PureMessage message store directory and file architecture. The 'filename' argument should be a quarantine identifier in the following format:

    dir:/opt/pmx/var/myarchive

The message store directory is created if it does not already exist. Messages within a message store can be manipulated using the message store tools (the pmx-store-expire manpage, the pmx-store-import manpage, etc).

<filename: string> - The path to the archive. When storing a message in mbox format, any text that appears following the final forward slash (/) is interpreted as the filename; if the file already exists, it is overwritten. The directory must be writable by the PureMessage user. If an absolute path is not specified, the path is interpreted as relative to the home directory of the PureMessage user (/opt/pmx/home).

pmx_delete_header
Syntax:
    pmx_delete_header [:all / :index <n: number>] <key: string>

Description: Delete header 'key'. The optional :all parameter deletes all repeated headers for the given key and the optional :index parameter can be used to specify which header to delete if the header is repeated. The header indices are zero-based, meaning that the first header is referred to by index 0, the second by index 1, etc. For example, the third 'Received' header can be deleted by the command:

    pmx_delete_header :index 2 "Received"

Parameters:

<key: string> - the header name

[:all] - the all matched headers

[:index <n:number>] - the header index

pmx_attachment_log
Syntax:
    pmx_attachment_log

Description: Writes an entry to the message_log that includes the attachment type, attachment size and number of attachments. PureMessage uses this data to generate the Attachment Sizes and Attachment Types reports.

pmx_dkim_sign
Syntax:
    pmx_dkim_sign

Description: DomainKeys Identified Mail (DKIM) is a an authentication framework used to sign and validate a message, based on the domain of its sender. This action signs outgoing messages with a unique DKIM signature. To configure PureMessage to detect and verify DKIM signatures for incoming messages, see pmx_dkim_verify.

In order for this action to take effect, you must configure /opt/pmx/etc/dkim.conf. This configuration file contains the required signing options, and the location of the private key that is used to create the DKIM signature. If you want multiple PureMessage servers in the same domain to share one signature for delivered mail, you must also add the location of the private key to the DomainKeys-Identified-Mail publication, and distribute it to the servers in that domain. See the dkim.conf manpage for more information.

DKIM signatures depend on access to a private key. This must also be configured in order for this action to take effect. For general information, www.dkim.org.

The action appends a signature to messages, and, therefore, should only be applied to rules in the 'Mail from internal hosts' section of the PureMessage policy.

Parameters: none

pmx_drop_attachment
Syntax:
    pmx_drop_attachment

Description: Drop an attachment. Must be used in the same rule as an attachment test, or it has no effect. See Attachment-Specific Filtering and Template Variables.

Parameters: none

pmx_virus_clean
Syntax:
    pmx_virus_clean <filename: string>

Description: Clean the message of any viruses. pmx_virus_clean will use all installed engines capable of cleaning to attempt to clean viruses from the message. After cleaning, the message is rescanned to ensure that the clean was successful. If the virus engines are not able to clean the message, the part containing the virus is replaced by data from a template file. The name of the template file is specified in the ``filename'' parameter, and must reside in the folder /opt/pmx/etc/virus.d. The default template included with PureMessage is called cantclean.tmpl.

Parameters:

<filename: string> - name of the template file to use if cleaning fails

pmx_replace_header
Syntax:
    pmx_replace_header [:all / :index <n:number>] <key: string> <value: string>

Description: Replace the header named key with value. The optional :all parameter replaces all repeated headers for the given key and the optional :index parameter can be used to specify which header to replace if the header is repeated (see pmx_delete_header for an example). If the header is not found in the message, the new header is added in a way similar to pmx_add_header. Like with pmx_delete_header, the header indices are zero-based.

Parameters:

<key: string> - the header name

<value: string> - the new header value

[:all] - the all matched headers

[:index <n:number>] - the header index

pmx_replace_body
Syntax:
    pmx_replace_body
        [:content_type <ct: string>]
        [:transfer_encoding <te: string>]
        [DATA_TYPE]
        <data: string>

Description: Replace an attachment, or the whole body of the message, with custom text or a file. If used in the same rule as an attachment-test, the matching attachment(s) are replaced. If it is used outside of this context, the entire body of the message is replaced.

Expands the %%ATTACHMENT_NAME%%, %%ATTACHMENT_TYPE%%, and %%ATTACHMENT_SIZE%% template variables. Can use the %%ATTACHMENT_NAMES%% template variable within rules using pmx_attachment_name, pmx_attachment_size, or pmx_attachment_type tests.

Parameters:

:content_type <ct: string> - content-type to use in the replaced part. Default is ``text/plain''.

:transfer_encoding <te:string> - transfer encoding to use in the replaced part. Default is ``7bit''. Supported transfer encodings: UTF-8, 7bit, 8bit, base64, quoted-printable, binary.

[DATA-TYPE] <data:string> - see DATA-TYPE section.

Logging Actions

pmx_custom_mark
Syntax:
    pmx_custom_mark <key: string> <value: string>

Description: Mark the message with a key-value pair. This action should only be used for custom policy reports. For more information, see 'Admimistrative Groups > Viewing and Managing Reports'. The message will accumulate marks as it is processed that are written to the message log (as specified in the <milter> section of the pmx.conf configuration file) when the message stops processing. These marks can be used to generate custom statistical reports.

Parameters:

<key: string> - mark key - can consist of alphanumeric characters and underscores.

<value: string> - mark value - arbitrary character string

:overwrite - If present, PureMessage adds a single mark to the message log per message, for any given key. Regardless of the number of actions associated with the key, only one mark is logged.

Important: The :overwrite parameter should be applied to all pmx_custom_mark actions for a specific key, or not at all. Inconsistent use will affect the accuracy of the custom report.

pmx_log
Syntax:
    pmx_log <priority: string> <message: string>

Description: Log a message to the PureMessage log destination (specified by the 'log_to' parameter in pmx.conf. The priority string is one of the following::

  "DEBUG"
  "INFO"
  "NOTICE"
  "WARNING"
  "ERROR"   (can also be spelled "ERR")
  "CRIT"
  "ALERT"
  "EMERG"

Parameters:

<priority: string> - the priority string

<message: string> - the message to be logged

pmx_mark
Syntax:
    pmx_mark <key: string> <value: string>

Description: Mark the message with a key-value pair. The message will accumulate 'marks' as it is processed that are written to the message log (as specified in the <milter> section of the pmx.conf configuration file) when the message stops processing. If the policy includes pmx_mark entries with duplicate keys, only the last one that is processed will be recorded. These marks can be used to generate report data.

Parameters:

<key: string> - mark key - can consist of alphanumeric characters and underscores.

<value: string> - mark value - arbitrary character string

pmx_mark1
Syntax:
    pmx_mark1 <key: string>

Description: Mark the message with given key. The message will accumulate 'marks' as it is processed that are written to the message log (as specified in the <milter> section of the pmx.conf configuration file) when the message stops processing. If the policy includes duplicate pmx_mark1 keys, only the last one that is processed will be recorded. These marks can be used to generate report data.

Parameters:

<key: string> - mark key - can consist of alphanumeric characters and underscores, up to a maximum of 64 characters.

pmx_test_mark
Syntax:
    pmx_test_mark

Description: Forwards test IDs to the message log (as specified in the <milter> section of the pmx.conf configuration file) so that the pmx-test script can recognize the messages it injects.

Miscellaneous Actions

pmx_set_var
Syntax:
    pmx_set_var <template: string> <command: string>

Description: Initialize a template variable with a shell command. pmx_set_var will execute the command string, and put the output in a template variable that can be used in subsequent tests and actions. Use the %%MESSAGE_FILE%% template in the command string to determine the filename of a file containing a message.

Parameters:

<template: string> - a template variable name. Must consist of uppercase alphanumeric characters and underscores.

<command: string> - the shell command to run.

Template Variables

Template variables are used to access information specific to the message that is being processed. Template variables can be used inside any string value in the policy script. They have the form '%%WORD%%'. When the message is being processed, the variable value is substituted for the variables.

Example:

    if size :over 10M {
        pmx_log "INFO" "Found a big message - %%MESSAGE_SIZE%% bytes!";
    }

In this example, messages over 10 megabytes will trigger a log entry, and the %%MESSAGE_SIZE%% template variable will be converted to the size of the message, in bytes.

Global Variables

The following template variables are always available:

%%PMX_VERSION%%
The version of PureMessage.

%%SUBJECT%%
The subject of the message. If there are multiple Subject headers, only the last occurrence is used.

%%MESSAGE_SIZE%%
The size of the message, in bytes.

%%HEADER_SIZE%%
The size of the message header, in bytes.

%%BODY_SIZE%%
The size of the message body, in bytes.

%%QUEUE_ID%%
The sendmail queue id.

%%SENDER_IP%%
The IP of the connecting MTA.

%%DATETIME%%
A string containing the local date and time (eg. Thu Apr 24 12:49:28 2003).

%%DATETIME_GMT%%
A string containing the GMT date and time (eg. Thu Apr 24 12:49:28 2003).

%%ENVELOPE_TO%%
A comma-separated list of the envelope recipients.

%%ENVELOPE_FROM%%
The envelope sender.

%%HEADER_FROM%%
The From field of the message header.

%%HEADER_TO%%
The To field of the message header. All occurrences of the To field are returned in a comma-separated list.

%%HEADER_CC%%
The Cc field of the message header. All occurrences of the Cc field are returned in a comma-separated list.

%%HEADER_DATE%%
The Date field of the message header.

%%HOSTNAME%%
The server's hostname as returned by the system hostname command. Useful in multi-server deployments for identifying which server processed a given message.

Spam, Blocklist and Virus Test Variables

The following variables are available after the pmx_spam_prob test has been run on a message:

%%GAUGE%%
Subject-style gauge. At least one '#' is always appended, indicating that the message contains 0-50% spam. An extra '#' is added for every 10% above the argument that is given to pmx_spam_prob.

%%XGAUGE%%
Absolute gauge, one 'X'-sign for every 10% probability.

%%SGAUGE%%
Absolute gauge, one '*'-sign for every 10% probability.

%%IGAUGE%%
Absolute gauge, 'I' for every 1% after the XGAUGE level.

%%PROB%%
Spam probability (NN%).

%%HITS%%
A listing of all the anti-spam rule names that were triggered by the message. Custom rules names are appended with a plus symbol; modified default rule names are appended with an exclamation mark. For example:

MY_CUSTOM_RULE+ 4, OVERRIDDEN_RULE! 2, DEFAULT_RULE 1.1

%%SPAM_REPORT%%
A verbose report of the anti-spam rules triggered by the message. Custom rule names are appended with a plus symbol; modified default rule names are appended with an exclamation mark. For example:
  MY_CUSTOM_RULE+       4.000  Site rule
  OVERRIDDEN_RULE!      2.000  Default rule description
  DEFAULT_RULE          1.100  Default rule description

The following variables are available after pmx_blocklist and pmx_virus respectively.

%%BLOCKLIST_REASON%%
The reason string as determined by pmx_blocklist (taken from PureMessage::Blocklist::Data). It is the same as the reply string seen in the SMTP session. Available after a pmx_blocklist test.

%%VIRUS_IDS%%
IDs of viruses detected in the message (e.g. 'W32/Klez.h@MM'). Available after a pmx_virus test.

Contextual Variables

The following variables are available inside rules containing specific tests or actions:

%%ATTACHMENT_NAME%%
The name of the attachment. Available inside rules using the pmx_rename_attachment and pmx_replace_body actions.

%%ATTACHMENT_NAMES%%
A list of all attachments. Available inside rules using the pmx_attachment_name, pmx_attachment_size, pmx_attachment_type, or pmx_attachment_true_filetype tests or the pmx_rename_attachment action.

%%ATTACHMENT_SIZE%%
The size of the attachment. Only available for use inside of the pmx_replace_body action.

%%ATTACHMENT_TYPE%%
The content-type of the attachment (as given by the Content-Type header). Only available for use inside of the pmx_replace_body action.

%%MATCHED_FILE%%
The file type contained in the message body, message headers, or attachment. Only available for use inside the pmx_phrase test.

%%MATCHED_TEXT%%
The word or phrase to match in the message body, message headers, or attachment. Only available for use inside the pmx_phrase test.

Attachment-Specific Filtering

The pmx_attachment_size, pmx_attachment_name and pmx_attachment_type tests make it possible to filter on specific attachments in a message. Most tests return immediately after finding a ``match'', but these will scan the whole message for all attachments that meet the test criteria and save them. If any matching attachments are found, the test returns true, and the matching attachments can be acted upon within that rule (i.e. within the following ``if'' block). A simple example of this is:

    if pmx_attachment_size :over 10M {
        pmx_drop_attachment;
    }

Which will drop (delete) any attachment over 10 megabytes. For more complex filtering, rules should be nested:

    if pmx_attachment_size :over 10M {
      if pmx_attachment_name :matches "*.exe" {
        pmx_replace_body :data "No large executables allowed, sorry!";
      }
    }

This outermost block will match any attachments over 10 megabytes, and the inner block will match any attachments that are over 10 megabytes AND have an ``.exe'' extension. And so the test in the inner block matches only on the attachments that were matched by the outer block.

It is recommended that the attachment-specific tests are not combined using allof or anyof, as these may produce unexpected results. If the test is preceded by a not command, the attachments that don't match the test condition are selected.

If a message has attachments, the main part (not the body) is returned as a matching part or a non-matching part according to your test. That means a test as below:

    if pmx_attachment_type ["text/plain"] { ... }

on a message like this:

    Content-Type: multipart/mixed; boundary="foo"
    ...
    --foo
    Content-Type: text/plain
    ...
    --foo
    Content-Type: text/plain
    ...
    --foo--

always returns false for the existence of the main part's content-type.

So, the definition of 'attachment' in pmx_attachment_size, pmx_attachment_name and pmx_attachment_type commands includes the message's top level as well as any body parts that are not attachments.

Per-Recipient Tests and Lists

The envelope test can be used to selectively execute parts of the script, based on the recipient of the message. If the message has multiple recipients, PureMessage will split the message into copies and operate on those copies independently, to simulate one-recipient-per-message behavior. Here is an example of opting out of a header being added:

    if not envelope :is ["alice@example.com",
                         "bob@example.com",
                         "carol@example.com"] {
            pmx_add_header "X-Hello" "There";
    }

In this example, messages sent to anyone except Alice, Bob, and Carol will have an X-Hello header added.

Multidimensional lists (or multilists) can be used to make tests work on a per-recipient basis. They can be used in place of regular lists in any PureMessage policy test that accepts a :memberof tag for matching against lists. If a multilist is used in one of these tests, PureMessage will use a list belonging to the recipient of the message, rather than using a single ``global'' list for all recipients. Here is an example of using a multilist to implement a per-recipient sender whitelist:

    if envelope :memberof "from" "whitelisted-senders-per-user" {
        pmx_mark1 "Whitelisted";
        keep;
        stop;
    }

If the envelope sender's address belongs to the recipient's whitelist, this rule will cause the message to be delivered with no further checking.

Repository

The policy repository contains Sieve code, both complete scripts and special purpose snippets that can be used to implement your mail policy.

The available commands are:

repo names
Lists the names of policy code in the repository

repo list
Lists the filename of the the policy code in the repository

repo examine name
Displays detailed information about a repository file

repo rename name newname
Rename a file in the repository

repo inspect filename
Displays detailed information about a Sieve file that exists outside of the repository

repo add filename
Adds a Sieve script to the repository

repo delete name
Deletes the named Sieve file from the repository


COPYRIGHT

Copyright (C) 2000-2009 Sophos Group. All rights reserved. Sophos and PureMessage are trademarks of Sophos Plc and Sophos Group.


SEE ALSO

the pmx manpage, PureMessage::List, PureMessage::MessageStore, perlretut