Sieve Email Filtering: Include Extension
Extracted elements (27)
Recursive inclusion errors are detected only at execution time, not upload time, to avoid imposing an upload ordering requirement on script authors and generators. Similarly, missing-script errors are deferred to execution time so scripts can be uploaded in any order.
The ':once' parameter is RECOMMENDED only for scripts that perform general duties such as declaring global variables and making sanity checks of the environment. This prevents redundant re-execution when a library-style script is included from multiple places in a script hierarchy.
Variables defined in scripts are private by default to prevent unintended interactions between script authors who might choose the same variable name. The 'global' command is provided as an explicit opt-in mechanism for sharing state, avoiding implicit global scoping that would make large script collections fragile.
When 'include' is used with the MIME extension 'foreverypart' control structure, the included script MUST be presented with the current MIME part as though it were the entire message. A 'break' command in an included script cannot terminate a 'foreverypart' iteration in another script; 'return' should be used to transfer control back to the including script.
A 'stop' command in an included script MUST stop all script processing, including the processing of scripts that included it. By contrast, 'return' stops only the immediate script and returns control to the including script.
All variables defined in a script MUST be kept private to the immediate script by default and are not visible to other scripts. Implementations MUST allow a non-global variable to have the same name as a global variable with no interaction between them.
Each included script MUST be a valid Sieve script with its own 'require' statements for all optional capabilities it uses. The scope of a 'require' statement is the script in which it immediately appears and does not inherit from or propagate to other scripts.
If any of the 'include', 'return', or 'global' commands are used in a script, the 'include' capability MUST be listed in the 'require' statement in that script.
Implementations MUST generate an error at execution time if an included script does not exist, except when ':optional' is specified. Implementations MUST NOT generate errors for missing scripts at upload time to avoid forcing upload ordering.
Implementations MUST provide for a total of at least three levels of nested scripts including the top-level script. An error MUST be generated either at upload or execution time if any nesting limit is exceeded, and an implicit 'keep' action MUST be executed to prevent message loss.
References to the 'global' namespace without a prior require statement for the 'include' extension MUST cause an error. Unset global variables SHALL evaluate to an empty string, consistent with how the 'variables' extension handles unknown variables.
Sieve implementations MUST NOT allow recursive script inclusion (both direct and indirect). An error MUST be generated at execution time for recursive inclusions; implementations MUST NOT generate errors for recursive includes at upload time, as this would impose an upload ordering requirement.
The 'global' command is only available when the script has both 'include' and 'variables' in its require line. If 'global' appears with only one of them required, an error MUST be generated when the script is uploaded. If 'global' names a variable already defined with 'set' in the immediate script, an error MUST be generated.
The ':location' parameter MUST default to ':personal' if not specified and MUST NOT be specified more than once. ':personal' refers to the user's private repository; ':global' refers to a site-wide repository accessible to all users.
The script name argument to 'include' MUST be a constant string as defined in RFC 5229 Section 3; implementations MUST NOT expand variables in the script name argument. Script names MUST be restricted according to ManageSieve (RFC 5804) Section 1.6.
When 'include' is used with the 'editheader' extension, any changes made to headers in a script MUST be propagated both to and from included scripts: included scripts MUST NOT see removed headers and MUST see added headers, and vice versa upon return.
When ':optional' is specified, implementations MUST NOT generate an error for a missing script and MUST continue as if the 'include' command had not been present. Without ':optional', a missing included script MUST generate an execution-time error.
When the 'variables' extension is present, Sieve implementations MUST follow the scoping rules defined in Section 3.4 and support the 'global' command to prevent variable name conflicts between included scripts.
With ':once', if the named script has already been included at any point during script execution, processing continues without re-including it. Implementations MUST NOT generate an error if ':once' would cause recursive inclusion; the script MUST be treated as previously included.
The 'global' command (usage: 'global <string-list>') declares one or more variable names to be stored in the shared global variable space. Each name must be a constant string conforming to the variable-name syntax of RFC 5229 Section 3; match variables and namespace prefixes are not allowed.
The 'global' variables namespace allows accessing shared variables as 'global.<identifier>' (e.g., 'set "global.i_am_on_vacation" "1";'). The namespace has no sub-namespaces, and the variable-name part must be a valid identifier. Variables declared via 'global' command and accessed via the 'global' namespace are one and the same.
The 'include' control structure takes an optional LOCATION parameter (':personal' or ':global', defaulting to ':personal'), an optional ':once' parameter, an optional ':optional' parameter, and a constant string script name. It executes the named script inline at the point of the command.
The 'return' command (usage: 'return') stops processing of the immediately included script only and returns control to the including script. If used in the main (non-included) script, it behaves identically to 'stop', including implicit 'keep' if no actions have executed.
This document registers the 'include' capability in IANA's 'Sieve Extensions' registry. The capability adds the 'include' command, the 'return' action, and the 'global' command and 'global' variables namespace for sharing variables among included scripts.
Implementations MUST ensure script names are safe for use with their storage system; an error MUST be generated for names that could be used as attack vectors. Path traversal attacks such as 'include "./../../etc/passwd"' and command injection such as 'include "foo$(`rm star`)"' MUST be rejected.
Sieve implementations MUST ensure adequate security for the global script repository to prevent unauthorized changes to global scripts. Sites are advised against allowing all users write access; only users with administrative privileges should be allowed to modify global scripts.
Sieve implementations MUST ensure that script names are checked for validity and proper permissions prior to inclusion, to prevent a malicious user from gaining access to files accessible to the mail server software that should not be accessible to the user.