Pigeonhole Project S. Bosch June 30, 2011 Sieve Email Filtering: Piping Messages to External Programs Abstract The Sieve filtering language (RFC 5228) is explicitly designed to be powerful enough to be useful yet limited in order to allow for a safe filtering system. The base specification of the language makes it impossible for users to do anything more complex (and dangerous) than write simple mail filters. One of the consequences of this security- minded design is that users cannot execute programs external to the Sieve filter. However, this can be a very useful and flexible feature for situations where Sieve cannot provide some uncommon functionality by itself. This document updates the Sieve filtering language with an extension to support piping messages to a pre- defined set of external programs using a special new action command. Bosch [Page 1] Sieve Extension: Pipe June 2011 Table of Contents 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 2. Conventions Used in This Document . . . . . . . . . . . . . . . 3 3. Capability Identifier . . . . . . . . . . . . . . . . . . . . . 3 4. Naming of External Programs . . . . . . . . . . . . . . . . . . 4 5. Pipe Action . . . . . . . . . . . . . . . . . . . . . . . . . . 4 5.1. Pipe Tag ":args" . . . . . . . . . . . . . . . . . . . . . 5 5.2. Pipe Tag ":try" . . . . . . . . . . . . . . . . . . . . . . 5 5.3. Interactions with Other Sieve Actions . . . . . . . . . . . 5 5.4. Interaction with the Sieve "copy" Extension . . . . . . . . 6 6. Security Considerations . . . . . . . . . . . . . . . . . . . . 6 7. References . . . . . . . . . . . . . . . . . . . . . . . . . . 6 7.1. Normative References . . . . . . . . . . . . . . . . . . . 6 7.2. Informative References . . . . . . . . . . . . . . . . . . 7 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 7 Bosch [Page 2] Sieve Extension: Pipe June 2011 1. Introduction This is an extension to the Sieve filtering language defined by RFC 5228 [SIEVE]. It adds an action command for piping messages to a pre-defined set of external programs. The Sieve language is explicitly designed to be powerful enough to be useful yet limited in order to allow for a safe server-side filtering system. Therefore, the base specification of the language makes it impossible for users to do anything more complex (and dangerous) than write simple mail filters. One of the consequences of this security- minded design is that users cannot execute external programs from their Sieve script. Particularly for server-side filtering setups in which mail accounts have no corresponding system account, allowing the execution of arbitrary programs from the mail filter can be a significant security risk. However, such functionality can also be very useful, for instance to easily implement a custom action or external effect that Sieve normally cannot provide. This document updates the Sieve filtering language with an extension to support piping messages to a pre-defined set of external programs using a new action command. To mitigate the security concerns, the external programs cannot be chosen arbitrarily; the available programs are restricted through administrator configuration. This extension is specific to the Pigeonhole Sieve implementation for the Dovecot Secure IMAP server. It will therefore most likely not be supported by web interfaces and GUI-based Sieve editors. This extension is primarily meant for use in small setups or global scripts that are managed by the system's administrator. 2. Conventions Used in This Document The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [KEYWORDS]. Conventions for notations are as in [SIEVE] Section 1.1, including use of the "Usage:" label for the definition of action and tagged arguments syntax. 3. Capability Identifier The capability string associated with the extension defined in this document is "vnd.dovecot.pipe". Bosch [Page 3] Sieve Extension: Pipe June 2011 4. Naming of External Programs An external program is identified by a name. This MUST not correspond to a file system path or otherwise have the ability to point to arbitrary programs on the system. The list of valid program names MUST be limited, subject to administrator configuration. A program name is a sequence of Unicode characters encoded in UTF-8 [UTF-8]. A program name MUST comply with Net-Unicode Definition (Section 2 of [NET-UNICODE]), with the additional restriction of prohibiting the following Unicode characters: o 0000-001F; [CONTROL CHARACTERS] o 002F; SLASH o 007F; DELETE o 0080-009F; [CONTROL CHARACTERS] o 2028; LINE SEPARATOR o 2029; PARAGRAPH SEPARATOR Program names MUST be at least one octet (and hence Unicode character) long. Implementations MUST allow names of up to 128 Unicode characters in length (which can take up to 512 octets when encoded in UTF-8, not counting the terminating NUL), and MAY allow longer names. A server that receives a program name longer than its internal limit MUST reject the corresponding operation, in particular it MUST NOT truncate the program name. 5. Pipe Action Usage: "pipe" [":args" ] [":try"] The "pipe" action executes the external program identified by the "program-name" argument and pipes the message to it. The specified "program-name" argument MUST conform to the syntax defined in Section 4. A script MUST fail with an appropriate error if it attempts to use an invalid or unknown program name. Implementations MUST NOT allow variables to be expanded into the program names; in other words, the value MUST be a constant string as defined in [VARIABLES], Section 3. If the external program fails to execute or finishes execution with Bosch [Page 4] Sieve Extension: Pipe June 2011 an error, script execution MUST fail with an appropriate error (causing an implicit "keep" action to be executed), unless the ":try" tag is specified as explained in Section 5.2. 5.1. Pipe Tag ":args" The ":args" tag is used to specify arguments for the external program. The arguments are passed to the external program in sequence. Implementations SHOULD NOT impose any structure for these arguments; validity checks are the responsibility of the external program. However, implementations SHOULD limit the maximum number of arguments and the length of each argument. Implementations MUST accept at least 16 arguments with a length of at least 1024 octets each, and MAY allow more and longer arguments. Additionally, implementations MAY restrict the use of certain control characters such as CR and LF, if these can cause unexpected behaviour or raise security concerns. 5.2. Pipe Tag ":try" When the ":try" tag is specified, the "pipe" instruction will attempt execution of the external program, but failure will not cause the whole Sieve script execution to fail with an error. Instead, the Sieve processing continues as if the "pipe" action was never triggered. If the execution of the external program is unsuccessful, the "pipe" action MUST NOT cancel the implicit "keep" action. 5.3. Interactions with Other Sieve Actions By default, the "pipe" action cancels the implicit "keep", thereby handing the responsibility for the message over to the external program. This behavior can be overridden using the Sieve "copy" extension [RFC3894] as described in Section 5.4. The "pipe" action can only be executed once per script for a particular external program. A script MUST fail with an appropriate error if it attempts to "pipe" messages to the same program multiple times. The "pipe" action is incompatible with the Sieve "reject" and "ereject" actions [RFC5429]. Bosch [Page 5] Sieve Extension: Pipe June 2011 5.4. Interaction with the Sieve "copy" Extension The Sieve "copy" extension [RFC3894] adds an optional ":copy" tagged argument to the "fileinto" and "redirect" action commands. When this tag is specified, these commands do not cancel the implicit "keep". Instead, the requested action is performed in addition to whatever else is happening to the message. When the "vnd.dovecot.pipe" extension is active, the "copy" extension also adds the optional ":copy" tag to the "pipe" action command. This has the familiar effect that when the ":copy" tag is specified, the implicit "keep" will not be canceled by the "pipe" action. When the "copy" extension is active, the syntax of the "pipe" action is represented as follows: Usage: "pipe" [":args" ] [":copy"] [":try"] 6. Security Considerations Allowing users to execute programs external to the Sieve filter can be a significant security risk, therefore this extension must be implemented with great care. The external programs should execute with no more privileges than needed. Particularly the arguments passed to the external programs through the ":args" parameter of the "pipe" action need to be handled with care. These need to be checked for validity and SHOULD NOT be passed to system tools directly, as this may introduce the possibility of various kinds of insertion attacks. For improved security, implementations MAY restrict the use of this extension to administrator-controlled global Sieve scripts. 7. References 7.1. Normative References [KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997. [NET-UNICODE] Klensin, J. and M. Padlipsky, "Unicode Format for Network Interchange", RFC 5198, March 2008. Bosch [Page 6] Sieve Extension: Pipe June 2011 [RFC3894] Degener, J., "Sieve Extension: Copying Without Side Effects", RFC 3894, October 2004. [SIEVE] Guenther, P. and T. Showalter, "Sieve: An Email Filtering Language", RFC 5228, January 2008. [UTF-8] Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, November 2003. [VARIABLES] Homme, K., "Sieve Email Filtering: Variables Extension", RFC 5229, January 2008. 7.2. Informative References [RFC5429] Stone, A., "Sieve Email Filtering: Reject and Extended Reject Extensions", RFC 5429, March 2009. Author's Address Stephan Bosch Enschede NL Email: stephan@rename-it.nl Bosch [Page 7]