diff options
Diffstat (limited to 'doc/README.SIEVE')
-rw-r--r-- | doc/README.SIEVE | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/doc/README.SIEVE b/doc/README.SIEVE new file mode 100644 index 0000000..d36998f --- /dev/null +++ b/doc/README.SIEVE @@ -0,0 +1,343 @@ + Notes on the Sieve implementation for Exim + +Exim Filter Versus Sieve Filter + +Exim supports two incompatible filters: The traditional Exim filter and +the Sieve filter. Since Sieve is a extensible language, it is important +to understand "Sieve" in this context as "the specific implementation +of Sieve for Exim". + +The Exim filter contains more features, such as variable expansion, and +better integration with the host environment, like external processes +and pipes. + +Sieve is a standard for interoperable filters, defined in RFC 5228, +with multiple implementations around. If interoperability is important, +then there is no way around it. + + +Exim Implementation + +The Exim Sieve implementation offers the core as defined by RFC 5228, +the "encoded-character" extension (RFC 5228), the "envelope" test (RFC +5228), the "fileinto" action (5228), the "copy" parameter (RFC 3894), the +"vacation" action (5230), the "notify" action (draft-ietf-sieve-notify-12) +with mailto URIs (draft-ietf-sieve-notify-mailto-05), the +"i;ascii-numeric" comparator (RFC 2244) and the subaddress parameter +(RFC 5233). + +The Sieve filter is integrated in Exim and works very similar to the +Exim filter: Sieve scripts are recognized by the first line containing +"# sieve filter". When using "keep" or "fileinto" to save a mail into a +folder, the resulting string is available as the variable $address_file +in the transport that stores it. The following routers and transport +show a typical use of Sieve: + +begin routers + +localuser_verify: + driver = accept + domains = +localdomains + local_part_suffix = "-*" + local_part_suffix_optional + check_local_user + require_files = $home/.forward + verify_only = true + +localuser_deliver: + driver = redirect + domains = +localdomains + local_part_suffix = "-*" + local_part_suffix_optional + sieve_subaddress = "${sg{$local_part_suffix}{^-}{}}" + sieve_useraddress = "$local_part" + check_local_user + require_files = $home/.forward + file = $home/.forward + check_ancestor + allow_filter + file_transport = localuser + reply_transport = vacation + sieve_vacation_directory = $home/mail/vacation + verify = false + +begin transports + +localuser: + driver = appendfile + file = ${if eq{$address_file}{inbox} \ + {/var/mail/$local_part} \ + {${if eq{${substr_0_1:$address_file}}{/} \ + {$address_file} \ + {$home/mail/$address_file} \ + }} \ + } + delivery_date_add + envelope_to_add + return_path_add + mode = 0600 + +vacation: + driver = autoreply + +Absolute files are stored where specified, relative files are stored +relative to $home/mail and "inbox" goes to the standard mailbox location. +To enable "vacation", sieve_vacation_directory is set to the directory +where vacation databases are held (don't put anything else in that +directory) and point reply_transport to an autoreply transport. +Setting the Sieve useraddress and subaddress allows to use the subaddress +extension. + + +RFC Compliance + +Exim requires the first line to be "# sieve filter". Of course the RFC +does not enforce that line. Don't expect examples to work without adding +it, though. + +RFC 5228 requires using CRLF to terminate the end of a line. +The rationale was that CRLF is universally used in network protocols +to mark the end of the line. This implementation does not embed Sieve +in a network protocol, but uses Sieve scripts as part of the Exim MTA. +Since all parts of Exim use \n as newline character, this implementation +does, too. You can change this by defining the macro RFC_EOL at compile +time to enforce CRLF being used. + +The folder specified by "fileinto" must not contain the character +sequence ".." to avoid security problems. RFC 5228 does not specify the +syntax of folders apart from keep being equivalent to fileinto "INBOX". +This implementation uses "inbox" instead. + +Sieve script errors currently cause that messages are silently filed into +"inbox". RFC 5228 requires that the user is notified of that condition. +This may be implemented in future by adding a header line to mails that +are filed into "inbox" due to an error in the filter. + +The automatic replies generated by "vacation" do not contain an updated +"references" header field. + + +Semantics Of Keep + +The keep command is equivalent to fileinto "inbox": It saves the +message and resets the implicit keep flag. It does not set the +implicit keep flag; there is no command to set it once it has +been reset. + + +Semantics Of Fileinto + +RFC 5228 does not specify if "fileinto" tries to create a mail folder, +in case it does not exist. This implementation allows to configure +that aspect using the appendfile transport options "create_directory", +"create_file" and "file_must_exist". See the appendfile transport in +the Exim specification for details. + + +Allof And Anyof Test + +RFC 5228 does not specify if these tests use shortcut/lazy evaluation. +Exim uses shortcut evaluation. + + +Action Reordering + +RFC 5228 does not specify if actions may be executed out of order. +Exim may execute them out of order, e.g. messages may be filed to +folders or forwarded in a different order than specified, because +those actions only setup delivery, but do not execute it themselves. + + +Sieve Syntax And Semantics + +RFC 5228 uses a generic grammar as syntax for commands and tests and +performs many checks during semantic analysis. Syntax is specified +by grammar rules, semantics by natural language. The intention is to +provide a framework for the syntax that describes current commands as +well as future extensions, and describing commands by semantics. + +The following replacement for section 8.2 gives a grammar for specific +commands of this implementation, thus removing most of the semantic +analysis. Since the parser can not parse unsupported extensions, the +result is strict error checking of any executed and not executed code +until "stop" is executed or the end of the script is reached. + +8.2. Grammar + +The grammar is specified in ABNF with two extensions to describe tagged +arguments that can be reordered and grammar extensions: { } denotes a +sequence of symbols that may appear in any order. Example: + + options = a b c + start = { options } + +is equivalent to: + + start = ( a b c ) / ( a c b ) / ( b a c ) / ( b c a ) / ( c a b ) / ( c b a ) + +The symbol =) is used to append to a rule: + + start = a + start =) b + +is equivalent to + + start = a b + +The basic Sieve commands are specified using the following grammar, which +language is a subset of the generic grammar above. The start symbol is +"start". + + address-part = ":localpart" / ":domain" / ":all" + comparator = ":comparator" string + match-type = ":is" / ":contains" / ":matches" + string = quoted-string / multi-line + string-list = "[" string *("," string) "]" / string + address-test = "address" { [address-part] [comparator] [match-type] } + string-list string-list + test-list = "(" test *("," test) ")" + allof-test = "allof" test-list + anyof-test = "anyof" test-list + exists-test = "exists" string-list + false-test = "false" + true=test = "true" + header-test = "header" { [comparator] [match-type] } + string-list string-list + not-test = "not" test + relop = ":over" / ":under" + size-test = "size" relop number + block = "{" commands "}" + if-command = "if" test block *( "elsif" test block ) [ "else" block ] + stop-command = "stop" { stop-options } ";" + stop-options = + keep-command = "keep" { keep-options } ";" + keep-options = + discard-command = "discard" { discard-options } ";" + discard-options = + redirect-command = "redirect" { redirect-options } string ";" + redirect-options = + require-command = "require" { require-options } string-list ";" + require-options = + test = address-test / allof-test / anyof-test / exists-test + / false-test / true-test / header-test / not-test + / size-test + command = if-command / stop-command / keep-command + / discard-command / redirect-command + commands = *command + start = *require-command commands + +The extensions "envelope" and "fileinto" are specified using the following +grammar extension. + + envelope-test = "envelope" { [comparator] [address-part] [match-type] } + string-list string-list + test =/ envelope-test + + fileinto-command = "fileinto" { fileinto-options } string ";" + fileinto-options = + command =/ fileinto-command + +The extension "copy" is specified as: + + fileinto-options =) ":copy" + redirect-options =) ":copy" + + +The i;ascii-numeric Comparator + +RFC 2244 describes this comparator and specifies that non-numeric strings +are considered equal with an ordinal value higher than any numeric string. +Although not stated explicitly, this includes the empty string. A range +of at least 2^31 is required. This implementation does not limit the +range, because it does not convert numbers to binary representation +before comparing them. + + +The vacation extension + +The extension "vacation" is specified using the following grammar +extension. + + vacation-command = "vacation" { vacation-options } <reason: string> + vacation-options = [":days" number] + [":subject" string] + [":from" string] + [":addresses" string-list] + [":mime"] + [":handle" string] + command =/ vacation-command + + +Semantics Of ":mime" + +The draft does not specify how strings using MIME entities are used +to compose messages. As a result, different implementations generate +different mails. The Exim Sieve implementation splits the reason into +header and body. It adds the header to the mail header and uses the body +as mail body. Be aware, that other implementations compose a multipart +structure with the reason as only part. Both conform to the specification +(or lack thereof). + + +Semantics Of Not Using ":mime" + +Sieve scripts are written in UTF-8, so is the reason string in this +case. This implementation adds MIME headers to indicate that. This +is not required by the vacation draft, which does not specify how +the UTF-8 reason is processed to compose the resulting message. + + +Default Subject + +RFC 5230 specifies that the default message subject is "Auto: " plus +the old subject. Using this subject is dangerous, because many mailing +lists verify addresses by sending a secret key in the subject of a +message, asking to reply to the message for confirmation. Using the +default vacation subject confirms any subscription request of this kind, +allowing to subscribe a third party to any mailing list, either to annoy +the user or to declare spam as legitimate mail by proving to use opt-in. + + +Rate Limiting Responses + +In absence of a handle, this implementation hashes the reason, +":subject" option, ":mime" option and ":from" option and uses the hex +string representation as filename within the "sieve_vacation_directory" +to store the recipient addresses for this vacation parameter set. + +The draft specifies that sites may define a minimum ":days" value than 1. +This implementation uses 1. The maximum value MUST greater than 7, +and SHOULD be greater than 30. This implementation uses a maximum of 31. + +Vacation recipient address databases older than 31 days are automatically +removed. Users do not have to remove them manually when modifying their +scripts. Don't put anything but vacation databases in that directory +or you risk that it will be removed, too! + + +Global Reply Address Blacklist + +The draft requires that each implementation offers a global black list +of addresses that will never be replied to. Exim offers this as option +"never_mail" in the autoreply transport. + + +The enotify extension + +The extension "enotify" is specified using the following grammar +extension. + + notify-command = "notify" { notify-options } <method: string> + notify-options = [":from" string] + [":importance" <"1" / "2" / "3">] + [":options" 1*(string-list / number)] + [":message" string] + + command =/ notify-command + + valid_notify_method = "valid_notify_method" + <notification-uris: string-list> + + test =/ valid_notify_method + +Only the mailto URI scheme is implemented. |