RFC 5703

Sieve Email Filtering: MIME Part Tests, Iteration, Extraction, Replacement, and Enclosure

๐Ÿ“… published October 2009, from ietf

Sieve Email Filtering: MIME Part Tests, Iteration, Extraction, Replacement, and Enclosure ๐ŸŽ€

Okay bestie, this one is RFC 5703 and it's giving email filtering glow-up ๐Ÿ’– Written by T. Hansen (AT&T Laboratories) and C. Daboo (Apple Inc.), it's on the Standards Track and dated October 2009 ๐Ÿ“… Its title block doesn't list anything it obsoletes or updates, so no drama there ๐ŸŒธ


Abstract โœจ

The big idea is that this doc adds new Sieve powers so your filters can poke at and manipulate the MIME body parts inside an email message ๐Ÿ“ฌ Main character energy for your inbox ๐Ÿ’…

Status of This Memo ๐Ÿ“œ

This is an Internet standards track protocol for the Internet community, and they're literally asking for discussion and suggestions for improvements ๐Ÿฆ‹ If you want the current standardization state and status, check STD 1, the "Internet Official Protocol Standards" ๐Ÿ“š Distribution of this memo is unlimited ๐ŸŒˆ

Copyright (c) 2009 IETF Trust and the persons identified as the document authors. All rights reserved. ๐Ÿซถ

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as they stand on the publication date. Please read these carefully, because they spell out your rights and restrictions ๐Ÿ“– Code Components pulled out of this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions, and they come without warranty as described in the BSD License โš–๏ธ

Heads up: this document may contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008. The people controlling the copyright in some of that material may not have granted the IETF Trust the right to allow modifications outside the IETF Standards Process. Without an adequate license from those copyright holders, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process. The only exceptions are formatting it for publication as an RFC or translating it into languages other than English ๐Ÿšซ

Table of Contents ๐Ÿ“‘

1. Introduction ....................................................2
2. Conventions Used in This Document ...............................3
3. Sieve Loops: Actions "foreverypart" and "break" .................3
4. Changes to Sieve Tests ..........................................4
   4.1. Test "header" ..............................................4
   4.2. Test "address" .............................................7
   4.3. Test "exists" ..............................................8
5. Action "replace" ................................................8
6. Action "enclose" ...............................................10
7. Action "extracttext" ...........................................11
8. Sieve Capability Strings .......................................11
9. Examples .......................................................12
   9.1. Example 1 .................................................12
   9.2. Example 2 .................................................12
   9.3. Example 3 .................................................13
10. Acknowledgements ..............................................13
11. Security Considerations .......................................14
12. IANA Considerations ...........................................14
   12.1. foreverypart capability ..................................15
   12.2. mime capability ..........................................15
   12.3. replace capability .......................................15
   12.4. enclose capability .......................................16
   12.5. extracttext capability ...................................16
13. References ....................................................16
   13.1. Normative References .....................................16
   13.2. Informative References ...................................17

1. Introduction ๐ŸŒท

MIME messages ([RFC2045]) are often complex objects, consisting of many parts and sub-parts ๐Ÿงฉ This Sieve ([RFC5228]) extension is the toolkit for it. It defines mechanisms for performing tests on MIME body parts, looping through the MIME body parts, extracting information from a MIME body part, changing the contents of a MIME body part, and enclosing the entire message within a wrapper ๐ŸŽ

2. Conventions Used in This Document ๐Ÿ’œ

Conventions for notations are as in [RFC5228], Section 1.1 ๐Ÿ“

Okay, the BCP 14 key words are the important bit ๐Ÿ”ฅ 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 [RFC2119] ๐Ÿซถ

3. Sieve Loops: Actions "foreverypart" and "break" ๐Ÿ”

Plain Sieve has no looping mechanism, which is kind of a vibe check when messages can have multiple parts ๐Ÿ˜ญ So to support filters that apply to any and all parts, this doc introduces a new control command called "foreverypart" โœจ It's an iterator that walks through every MIME part of a message, including nested parts, depth first, and applies the commands in the specified block to each one ๐Ÿงš

Here's how it goes: the iterator starts with the first MIME part as its current context and executes a command block (Sieve commands enclosed by {...}). When that block finishes, the iterator advances to the next MIME part as its current context and runs the same command block again ๐ŸŒˆ

The iterator can be terminated early by a new Sieve control command called "break" ๐Ÿ›‘

Here's the usage:

Usage:  foreverypart [":name" string] block

Usage:  break [":name" string];

Loops can nest, which is so iconic ๐Ÿ‘‘ "foreverypart" commands can be nested inside other "foreverypart" commands. When that happens, the nested "foreverypart" iterates over the MIME parts contained within the MIME part currently being targeted by the nearest enclosing "foreverypart" command. So the inner loop only works on the children of the bodypart the outer loop is currently accessing ๐Ÿช† If that MIME part is a terminal MIME part (meaning it doesn't contain other MIME parts), then the nested "foreverypart" loop is simply ignored ๐Ÿ™ˆ

Limits are a real thing here. Sieve implementations MAY limit the number of nested loops that occur within one another. However, they MUST support at least one nested loop inside another loop ๐Ÿ’–

Now for names. If a name is given to a "break" command, it terminates the closest enclosing loop with the identical matching name โœ‚๏ธ If a nested "foreverypart" has the same name as a "foreverypart" at an outer level, the outer level name gets hidden ๐Ÿซฅ And it's an error if there's no enclosing loop with that name ๐Ÿ’€

If there's no name in a "break" command (so the ":name" parameter is omitted), the break command just terminates the closest enclosing loop ๐Ÿฆ‹


4. Changes to Sieve Tests ๐Ÿงช

This spec extends the base Sieve "header", "address", and "exists" tests so they can target a specific MIME part, or all MIME parts in the enclosing scope ๐ŸŽฏ

4.1. Test "header"

okay bestie, the "header" test just got a glow-up ๐Ÿ’…โœจ It picks up two new tagged arguments, ":mime" and ":anychild", plus their own options. ๐ŸŽ€

Usage:

header [":mime"] [":anychild"] [MIMEOPTS]
   [COMPARATOR] [MATCH-TYPE]
   <header-names: string-list> <key-list: string-list>

The definition of [MIMEOPTS] is:

Syntax:  ":type" / ":subtype" / ":contenttype" /
   ":param" <param-list: string-list>

So when you add ":mime", the test parses the MIME header lines in the message so you can test specific bits of them ๐Ÿฆ‹ The ":anychild" argument only works if ":mime" is there too, and it just changes how ":mime" behaves. Using ":anychild" without ":mime" is an error, so don't do that ๐Ÿ™ˆ

Here's how the test looks at your message depending on where you use it:

  • Outside a foreverypart loop, without ":anychild", it only checks the outer top-level [RFC5322] headers. ๐Ÿ“ฌ
  • Inside a foreverypart loop, without ":anychild", it checks the headers for the current MIME part from the loop. ๐Ÿงš
  • Outside a foreverypart loop, with ":anychild", it checks every MIME body part and returns true if any one of them passes. ๐ŸŒˆ
  • Inside a foreverypart loop, with ":anychild", it checks the current MIME part and all its nested MIME body parts, and returns true if any of them passes. ๐Ÿ’œ

With ":mime", the test can poke at certain structured MIME headers in detail. Implementations SHOULD support desegmentation, decoding, and charset translation of parameter values encoded according to [RFC2231] as part of this test. ๐Ÿ“ Also, [RFC2047] explains how [RFC5322] headers can be encoded in different ways. That encoding isn't strictly allowed in MIME parameters, but honestly, lots of email implementations use it anyway ๐Ÿ’€ So Sieve implementations MAY decode [RFC2047]-encoded words in parameter values as part of this test.

These options are available:

  • :type: For a "Content-Type" MIME header field, it parses and tests the MIME type from the header. For a "Content-Disposition" MIME header field, it parses and tests the disposition from the header. For other MIME headers, it uses a blank string for the test. ๐ŸŽ€
  • :subtype: For a "Content-Type" MIME header field, it parses and tests the MIME subtype from the header. For a "Content-Disposition" MIME header field, it uses a blank string for the test. For other MIME headers, it also uses a blank string for the test. ๐ŸŒธ
  • :contenttype: For a "Content-Type" MIME header field, it parses and tests the combined MIME type and subtype from the header. For a "Content-Disposition" MIME header field, it behaves the same as the :type option. For other MIME headers, it uses a blank string for the test. ๐Ÿซถ
  • :param: Parses the header looking for MIME parameters. The string-list you pass in names the parameters to test. If any one named parameter value matches any of the test string values, the test returns true. โœจ

When the ":count" option from [RFC5231] is used, this is what happens:

a. For ":type", ":subtype", or ":contenttype", it returns a count of how many headers parsed successfully. ๐Ÿ”ข

b. For ":param", it returns a count of how many parameters with the given name were found. ๐Ÿงฎ

Example:

require ["mime", "fileinto"];

if header :mime :type "Content-Type" "image"
{
    fileinto "INBOX.images";
}

In this example, any message with a MIME image type part at the top level gets saved to the mailbox "INBOX.images". ๐Ÿ“ธ

Example:

require ["mime", "fileinto"];

if header :mime :anychild :contenttype
          "Content-Type" "text/html"
{
    fileinto "INBOX.html";
}

In this example, any message with any MIME part that has a content-type of "text/html" gets saved to the mailbox "INBOX.html". ๐Ÿ’…

Example:

require ["mime", "foreverypart", "fileinto"];

foreverypart
{
    if allof (
      header :mime :param "filename" :contains
         "Content-Disposition" "important",
      header :mime :subtype "Content-Type" "pdf",
      size :over "100K")
    {
        fileinto "INBOX.important";
        break;
    }
}

In this example, any message with a MIME part whose content-disposition has a filename parameter containing the text "important", a content-subtype of "pdf", and a size over 100 Kb gets saved to the mailbox "INBOX.important". ๐Ÿ˜ญ๐Ÿ”ฅ


4.2. Test "address"

The "address" test gets the same ":mime" and ":anychild" upgrade, with its own options ๐Ÿฆ‹

Usage:

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

When ":mime" is in the "address" test, it parses the MIME header lines as if they were standard address header lines in a message. That way you can test specific elements, bestie ๐Ÿ“ฌ

The ":anychild" argument and how it plays with the "foreverypart" iterator work exactly the same as in the extended "header" test in Section 4.1. So here's the breakdown:

  • Using "address" with both ":mime" and ":anychild" left out is the test defined in [RFC5228]. It will only operate on top-level header fields, whether or not it's inside "foreverypart". ๐ŸŽ€
  • Using "address" with ":mime" and no ":anychild" operates on the current MIME part only. If you're outside "foreverypart", it operates on the top-level header fields. ๐ŸŒธ
  • Using "address" with ":mime" and ":anychild" operates on the current MIME part and all of its descendants. ๐ŸŒˆ

Example:

require ["mime", "fileinto"];

if address :mime :is :all "content-from" "tim@example.com"
{
    fileinto "INBOX.part-from-tim";
}

In this example, any message with a MIME Content-From header at the top level that matches the text "tim@example.com" gets saved to the mailbox "INBOX.part-from-tim". ๐Ÿ’Œ


4.3. Test "exists"

The "exists" test also gets the new ":mime" and ":anychild" tagged arguments, along with their options ๐Ÿงš

Usage:

exists [":mime"] [":anychild"] <header-names: string-list>

When ":mime" is in the "exists" test, the test checks whether MIME headers exist in MIME parts. It's giving main character energy ๐Ÿ’–

The ":anychild" argument and its interaction with "foreverypart" are the same as in the extended "header" test Section 4.1. So:

  • Using "exists" with both ":mime" and ":anychild" left out is the test defined in [RFC5228]. It will only operate on top-level header fields, whether or not it's inside "foreverypart". ๐Ÿ“
  • Using "exists" with ":mime" and no ":anychild" operates on the current MIME part only. If you're outside "foreverypart", it operates on the top-level header fields. ๐Ÿซถ
  • Using "exists" with ":mime" and ":anychild" operates on the current MIME part and all of its descendants. ๐Ÿ‘‘

Example:

require ["mime", "fileinto"];

if exists :mime :anychild "content-md5"
{
    fileinto "INBOX.md5";
}

In this example, any message with a MIME Content-MD5 header in any MIME part gets saved to the mailbox "INBOX.md5". ๐Ÿ”ฅ


5. Action "replace"

Okay, the "replace" action is where things get spicy ๐ŸŒถ๏ธ๐Ÿ’€ It lets you swap a MIME part out for text you supply in the command.

Usage:

replace [":mime"] [":subject" string] [":from" string]
   <replacement: string>

The "replace" command is defined so a MIME part can be replaced with the text you give it in the command ๐Ÿฆ‹

When you use it inside a "foreverypart" iterator, the MIME part to replace is the "current" MIME part. If the current MIME context is a multipart MIME part, the whole multipart part gets replaced. That changes the message structure, because it wipes out all of the children of the multipart part ๐Ÿ˜ฑ (Replacing a non-multipart MIME part inside a "foreverypart" loop doesn't change the overall message structure, so you're safe there ๐Ÿซถ) If the MIME structure does change, the change takes effect right away. The "foreverypart" iterator that's running doesn't go into body parts that no longer exist, and any later "foreverypart" iterators use the new message structure ๐ŸŒˆ

When you use it outside a "foreverypart" loop, the MIME part to replace is the entire message ๐ŸŽ€

If you don't specify ":mime", the replacement string is a text/plain part in UTF-8 [RFC3629] ๐ŸŒธ

If you do specify ":mime", the replacement string is actually a MIME entity as defined in [RFC2045], Section 2.4. That includes both the MIME headers and the content ๐Ÿ’–

If the entire message is being replaced, the optional ":subject" parameter sets a subject line on the message that gets generated. You can use UTF-8 characters in the string argument, but implementations MUST convert the string to [RFC2047]-encoded words if and only if non-ASCII characters are present. If you use the ":subject" parameter, implementations MUST preserve any previous Subject header as an Original-Subject header. Implementations MUST also preserve all other header fields from the original message, except for the ones relating to the MIME structure being replaced. ๐Ÿซถ

Also, if the entire message is being replaced, the optional ":from" parameter can be used to show the message is no longer as created by the original author. It sets an alternate address for the From field of the generated message. The string must specify a valid [RFC5322] mailbox-list. Implementations SHOULD check the syntax and generate an error when a syntactically invalid ":from" parameter is specified. Implementations MAY also impose restrictions on which addresses can go in a ":from" parameter. It's suggested that values failing that validity check simply get ignored, instead of making the "replace" action fail ๐Ÿ™ˆ If the From header is changed, implementations MUST preserve the previous From header as an Original-From header. ๐Ÿ“

Implementations that support the "editheader" extension [RFC5293] MUST ensure that any Original-Subject or Orignal-From headers added by the system cannot be modified or removed. Implementations MAY prevent Original-Subject and Orignal-From headers from being added through the "editheader" extension. ๐Ÿ”’

If ":mime" is specified and either ":subject" or ":from" is specified too, the ":subject" or ":from" parameter MUST be ignored. This SHOULD be flagged as a compilation error. ๐Ÿšจ

6. Action "enclose" ๐Ÿ’Œ

Usage:

enclose <:subject string> <:headers string-list> string

okay so this is the action that wraps your WHOLE message up like a gift ๐ŸŽ A new Sieve action command lets you enclose an entire message as an attachment inside a brand new message. After the enclosure happens, any later actions that touch the message header or content, plus tests that look at the MIME structure or read MIME header fields, use the new message instead of the original one. So if you're gonna use a replace action or any similar actions, do them BEFORE enclose ๐Ÿ™ˆ ngl this order thing is so important.

If a script runs multiple enclose actions, the message gets enclosed multiple times ๐Ÿช† Like, nesting dolls, iconic. If your script wants to pick between different enclosures, or wants to put the enclosure off until the very end of the script, it can use variables with the right tests instead ([RFC5229]) โœจ

This action does not affect messages that get forwarded through a redirect action ๐Ÿฆ‹

Here's the breakdown: the original message turns into a multipart/mixed message with two parts. Part one is a text/plain portion whose body is the string argument. Part two is a message/rfc822 portion holding the original message, enclosed ๐Ÿ’… The Content-Type: header field becomes multipart/mixed. The optional Subject: header is set by the :subject argument. If that's not there, the subject gets taken from the enclosed message. Any headers listed in :headers get copied from the old message into the new one. And if :headers doesn't specify them, the Date: and From: headers should be synthesized to show the current date and the user who's running the Sieve action ๐ŸŒธ

7. Action "extracttext" ๐Ÿง

Usage:

extracttext [MODIFIER] [":first" number] <varname: string>

The extracttext action is used inside a foreverypart loop, and it stores text into a variable as defined by [RFC5229] ๐Ÿ“ Servers MUST support transcoding any textual body part into UTF-8 for use with this action ๐Ÿซถ That means decoding any transfer encoding AND transcoding from the indicated character set into UTF-8. It stores at most :first characters of the transcoded content of the current MIME body part in the variable named by varname. If :first isn't there, the WHOLE content of the current MIME body part gets stored. Either way, the stored data MAY be truncated to fit an implementation-specific limit on variable length and/or on MIME body part length. And if the transfer encoding or character set is unrecognized by the implementation, or recognized but invalid, you get an empty string ๐Ÿ’€

If extracttext is used OUTSIDE a foreverypart loop, the variable named by varname just gets set to the empty string. This SHOULD be flagged as a compilation error ๐Ÿšฉ

Modifiers get applied to the extracted text before it's stored in the variable โœจ

8. Sieve Capability Strings ๐ŸŽ€

A Sieve implementation that defines the foreverypart and break actions will advertise the capability string foreverypart ๐Ÿงš

A Sieve implementation that defines the :mime and :anychild tagged arguments for the header, address, and exists commands will advertise the capability string mime ๐ŸŒˆ

A Sieve implementation that defines the replace action will advertise the capability string replace ๐Ÿ”

A Sieve implementation that defines the enclose action will advertise the capability string enclose ๐Ÿ’Œ

A Sieve implementation that defines the extracttext action will advertise the capability string extracttext. Heads up, though: to actually be useful, extracttext ALSO needs the "variables" [RFC5229] and foreverypart capabilities ๐Ÿซ 


9. Examples ๐Ÿ“

9.1. Example 1

Let's look at a Sieve script that replaces some of the Windows executable attachments in a message ๐Ÿ’… (The real list of executable types and extensions is way longer and keeps changing, so the tests here are just an example.) A script like this might look something like:

require [ "foreverypart", "mime", "replace" ];
foreverypart
{
  if anyof (
         header :mime :contenttype :is
           "Content-Type" "application/exe",
         header :mime :param "filename"
           :matches ["Content-Type", "Content-Disposition"] "*.com" )
  {
    replace "Executable attachment removed by user filter";
  }
}

9.2. Example 2

Next, a Sieve script that warns the user about some of the executable attachment types โš ๏ธ (Same deal: the real list is longer and changing, so these tests are only an example.) A script like this might look like:

require [ "foreverypart", "mime", "enclose" ];

foreverypart
{
  if header :mime :param "filename"
     :matches ["Content-Type", "Content-Disposition"]
       ["*.com", "*.exe", "*.vbs", "*.scr",
        "*.pif", "*.hta", "*.bat", "*.zip" ]
  {
    # these attachment types are executable
    enclose :subject "Warning" :text
WARNING! The enclosed message contains executable attachments.
These attachment types may contain a computer virus program
that can infect your computer and potentially damage your data.

Before clicking on these message attachments, you should verify
with the sender that this message was sent by them and not a
computer virus.

.
;
    break;
  }
}

9.3. Example 3

Here's a Sieve script that pulls the subject and text out of messages from the boss ๐Ÿ‘‘

require ["mime", "variables", "extracttext"];

if header :contains "from" "boss@example.org"
{
  # :matches is used to get the value of the Subject header
  if header :matches "Subject" "*"
  {
    set "subject" "${1}";
  }

  # extract the first 100 characters of the first text/* part
  foreverypart
  {
    if header :mime :type :is "Content-Type" "text"
    {
      extracttext :first 100 "msgcontent";
      break;
    }
  }

  # if it's not a 'for your information' message
  if not header :contains "subject" "FYI:"
  {
    # do something using ${subject} and ${msgcontent}
    # such as sending a notification using a
    # notification extension
  }
}

10. Acknowledgements ๐Ÿซถ

Big thank-yous to the members of the MTA Filters Working Group, especially Ned Freed, Kjetil Torgrim Homme, Mark Mallett, Alexey Melnikov, Aaron Stone, and Nigel Swinson ๐Ÿ’– Your comments were so helpful!

11. Security Considerations ๐Ÿ”

Heads up, this section is SERIOUS ๐Ÿ˜ค

The enclose action creates an entirely new message, unlike just redirecting or forwarding the existing one ๐Ÿ“จ So any site policies that apply to message submission SHOULD be enforced.

The looping specification here makes it easier to get at information about the message contents, which you could also get through other Sieve tests. This is not believed to raise any additional security issues beyond those for the Sieve "envelope" and "body" [RFC5173] tests ๐Ÿ‘€

Any change in message content may interfere with digital signature mechanisms that include that content in the signed material ๐Ÿ–Š๏ธ In particular, using replace makes direct changes to the body content, and that will affect the body hash in DomainKeys Identified Mail (DKIM) signatures [RFC4871], or the message signature used for Secure MIME (S/MIME) [RFC3851], Pretty Good Privacy (PGP) [RFC1991], or OpenPGP [RFC4880].

It is not possible to examine the MIME structure of decrypted content in a multipart/encrypted MIME part ๐Ÿ™…

When enclose is used on a message containing a multipart/signed MIME part, the Sieve implementation MUST ensure that the original message is copied octet-for-octet, so the digital signature stays valid ๐Ÿ”

The system MUST be sized and restricted so that even malicious use of MIME part matching cannot deny service to other users of the host system ๐Ÿ›ก๏ธ

All of the security considerations given in the base Sieve specification also apply to these extensions ๐Ÿ’œ

12. IANA Considerations ๐Ÿ“‹

The Original-Subject and Original-From headers have been registered in the Permanent Message Header Fields registry โœจ

The templates below specify the IANA registrations of the Sieve extensions in this document. This information has been added to the IANA registry of Sieve Extensions (currently found at http://www.iana.org) ๐Ÿฆ‹

12.1. foreverypart capability

To: iana@iana.org
Subject: Registration of new Sieve extension

Capability name: foreverypart
Description: adds the "foreverypart" and "break" actions for
iterating through MIME parts of a message.

RFC number: RFC 5703
Contact address: The Sieve discussion list
<ietf-mta-filters@imc.org>.

12.2. mime capability

To: iana@iana.org
Subject: Registration of new Sieve extension

Capability name: mime
Description: adds the ":mime" and ":anychild" tagged arguments to the
"header", "address", and "exists" tests.  Adds the ":type",
":subtype", ":contenttype", and ":param" options when ":mime" is used
with the "header" test.

RFC number: RFC 5703
Contact address: The Sieve discussion list
<ietf-mta-filters@imc.org>.

12.3. replace capability

To: iana@iana.org
Subject: Registration of new Sieve extension

Capability name: replace
Description: adds the "replace" action for replacing a MIME body part
of a message.

RFC number: RFC 5703
Contact address: The Sieve discussion list
<ietf-mta-filters@imc.org>.

12.4. enclose capability

To: iana@iana.org
Subject: Registration of new Sieve extension

Capability name: enclose
Description: adds the "enclose" action for enclosing a message with a
wrapper.

RFC number: RFC 5703
Contact address: The Sieve discussion list
<ietf-mta-filters@imc.org>.

12.5. extracttext capability

To: iana@iana.org
Subject: Registration of new Sieve extension

Capability name: extracttext
Description: adds the "extracttext" action for extracting text from a

MIME body part.

RFC number: RFC 5703
Contact address: The Sieve discussion list
<ietf-mta-filters@imc.org>.

13. References ๐Ÿ“š

13.1. Normative References

[RFC2045]  Freed, N. and N. Borenstein, "Multipurpose Internet Mail
           Extensions (MIME) Part One: Format of Internet Message
           Bodies", RFC 2045, November 1996.

[RFC2047]  Moore, K., "MIME (Multipurpose Internet Mail Extensions)
           Part Three: Message Header Extensions for Non-ASCII Text",
           RFC 2047, November 1996.

[RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
           Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC2231]  Freed, N. and K. Moore, "MIME Parameter Value and Encoded
           Word Extensions:
           Character Sets, Languages, and Continuations", RFC 2231,
           November 1997.

[RFC3629]  Yergeau, F., "UTF-8, a transformation format of ISO
           10646", STD 63, RFC 3629, November 2003.

[RFC5173]  Degener, J. and P. Guenther, "Sieve Email Filtering: Body
           Extension", RFC 5173, April 2008.

[RFC5228]  Guenther, P. and T. Showalter, "Sieve: An Email Filtering
           Language", RFC 5228, January 2008.

[RFC5229]  Homme, K., "Sieve Email Filtering: Variables Extension",
           RFC 5229, January 2008.

[RFC5231]  Segmuller, W. and B. Leiba, "Sieve Email Filtering:
           Relational Extension", RFC 5231, January 2008.

[RFC5293]  Degener, J. and P. Guenther, "Sieve Email Filtering:
           Editheader Extension", RFC 5293, August 2008.

[RFC5322]  Resnick, P., Ed., "Internet Message Format", RFC 5322,
           October 2008.

13.2. Informative References ๐Ÿ“š

okay so these are the bonus reads, bestie ๐Ÿ’… they're not required to get the main spec working, but they're where the good background lives ๐Ÿง โœจ

  • [RFC1991] Atkins, D., Stallings, W., and P. Zimmermann, "PGP Message Exchange Formats", RFC 1991, August 1996. ๐Ÿ”
  • [RFC3851] Ramsdell, B., "Secure/Multipurpose Internet Mail Extensions (S/MIME) Version 3.1 Message Specification", RFC 3851, July 2004. ๐Ÿ’Œ
  • [RFC4871] Allman, E., Callas, J., Delany, M., Libbey, M., Fenton, J., and M. Thomas, "DomainKeys Identified Mail (DKIM) Signatures", RFC 4871, May 2007. ๐Ÿฆ‹
  • [RFC4880] Callas, J., Donnerhacke, L., Finney, H., Shaw, D., and R. Thayer, "OpenPGP Message Format", RFC 4880, November 2007. ๐ŸŒธ

Authors' Addresses ๐ŸŽ€

Meet the people who wrote this whole thing, iykyk ๐Ÿ’œ

Tony Hansen
AT&T Laboratories
200 Laurel Ave.
Middletown, NJ  07748
USA

EMail: tony+sieveloop@maillennium.att.com


Cyrus Daboo
Apple Inc.
1 Infinite Loop
Cupertino, CA  95014
USA

EMail: cyrus@daboo.name
URI:   http://www.apple.com/

That's a wrap on RFC 5703! ๐ŸŒˆ๐Ÿ‘‘ Go be iconic with your new knowledge, bestie ๐Ÿซถโœจ

๐Ÿ“ฆ where this page comes from