Network Working Group D. Wilson Internet-Draft A. Melnikov Intended status: Standards Track Isode Limited February 13, 2009 Content Conversion and Checking Protocol (CCCP) draft-wilson-cccp-02 Status of this Memo By submitting this Internet-Draft, each author represents that any applicable patent or other IPR claims of which he or she is aware have been or will be disclosed, and any of which he or she becomes aware will be disclosed, in accordance with Section 6 of BCP 79. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF), its areas, and its working groups. Note that other groups may also distribute working documents as Internet- Drafts. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." The list of current Internet-Drafts can be accessed at http://www.ietf.org/ietf/1id-abstracts.txt. The list of Internet-Draft Shadow Directories can be accessed at http://www.ietf.org/shadow.html. This Internet-Draft will expire on August 17, 2009. Abstract This memo describes a simple protocol for performing content checking and conversions of RFC 5322 email messages, together with associated SMTP (RFC 5321) envelope. Wilson & Melnikov Expires August 17, 2009 [Page 1] Internet-Draft CCCP February 2009 Table of Contents 1. Protocol overview . . . . . . . . . . . . . . . . . . . . 3 1.1. Commands and Responses . . . . . . . . . . . . . . . . . . 3 1.1.1. Client Protocol Sender and Server Protocol Receiver . . . 3 1.1.2. Server Protocol Sender and Client Protocol Receiver . . . 3 1.2. Opening a connection . . . . . . . . . . . . . . . . . . . 4 1.3. Closing a connection . . . . . . . . . . . . . . . . . . . 5 1.4. Generic protocol syntax . . . . . . . . . . . . . . . . . 5 2. Supported commands . . . . . . . . . . . . . . . . . . . . 8 2.1. CAPABILITY command . . . . . . . . . . . . . . . . . . . . 8 2.2. QUIT command . . . . . . . . . . . . . . . . . . . . . . . 9 2.3. CONVERT command . . . . . . . . . . . . . . . . . . . . . 9 2.4. CAPABILITY Response . . . . . . . . . . . . . . . . . . . 12 2.5. BYE Response . . . . . . . . . . . . . . . . . . . . . . . 13 3. Security Considerations . . . . . . . . . . . . . . . . . 13 4. IANA Considerations . . . . . . . . . . . . . . . . . . . 13 5. Acknowledgements . . . . . . . . . . . . . . . . . . . . . 13 6. Normative References . . . . . . . . . . . . . . . . . . . 13 Authors' Addresses . . . . . . . . . . . . . . . . . . . . 13 Intellectual Property and Copyright Statements . . . . . . 15 Wilson & Melnikov Expires August 17, 2009 [Page 2] Internet-Draft CCCP February 2009 1. Protocol overview 1.1. Commands and Responses A CCCP connection consists of the establishment of a client/server network connection, an initial greeting from the server, and client/ server interactions. These client/server interactions consist of a client command, server data, and a server completion result response. All interactions transmitted by client and server are in the form of lines, that is, strings that end with a CRLF. The protocol receiver of a CCCP client or server is either reading a line, or is reading a sequence of octets with a known count followed by a line. 1.1.1. Client Protocol Sender and Server Protocol Receiver The client command begins an operation. Each client command is prefixed with an identifier (typically a short alphanumeric string, e.g., A0001, A0002, etc.) called a "tag". A different tag is generated by the client for each command. Note that "*" is not a valid tag. Clients MUST follow the syntax outlined in this specification strictly. It is a syntax error to send a command with missing or extraneous spaces or arguments. There is one case in which a line from the client does not represent a complete command: a command argument is quoted with an octet count (see the description of ). The protocol receiver of an CCCP server reads a command line from the client, parses the command and its arguments, and transmits server data and a server command completion result response. The client MAY send commands before the response has been received for a previous command (pipelining). The client is responsible for ensuring that communication with the server does not deadlock. Typically the server sends command responses in the order that the corresponding commands were received, however the server MAY send command responses out of order, as long as there are no data dependencies between commands (i.e. one command doesn't depend on results of another command). 1.1.2. Server Protocol Sender and Client Protocol Receiver Data transmitted by the server to the client come in three forms: command completion results, intermediate responses, and untagged (starting with "*") responses. Wilson & Melnikov Expires August 17, 2009 [Page 3] Internet-Draft CCCP February 2009 A command completion result indicates the success or failure of the operation. It is tagged with the same tag as the client command which began the operation. Thus, if more than one command is in progress, the tag in a server completion response identifies the command to which the response applies. There are three possible server completion responses: OK (indicating success), NO (indicating failure), or BAD (indicating protocol error such as unrecognized command or command syntax error). An intermediate response returns data which can only be interpreted within the context of a command in progress. It is tagged with the same tag as the client command which began the operation. Thus, if more than one command is in progress, the tag in an intermediate response identifies the command to which the response applies. A tagged response other than "OK", "NO", or "BAD" is an intermediate response. An untagged response returns data or status messages which may be interpreted outside the context of a command in progress. It is prefixed with the token "*". Untagged data may be sent as a result of a client command, or may be sent unilaterally by the server. There is no syntactic difference between untagged data that resulted from a specific command and untagged data that were sent unilaterally. The protocol receiver of an CCCP client reads a response line from the server. It then takes action on the response based upon the first token of the response, which may be a tag, a "*" as described above. A client MUST be prepared to accept any server response at all times. This includes untagged data that it may not have requested. 1.2. Opening a connection Once a CCCP client successfully open a connection to a CCCP server, the server would return a greeting. The greeting MUST be either an untagged CAPABILITY Section 2.4 response, or an untagged BYE Section 2.5 response. In the latter case the server announces that it can't server client's request and would immediately close the connection. Example: C: S: * CAPABILITY (VERSION 1.0) (CONVERT) Wilson & Melnikov Expires August 17, 2009 [Page 4] Internet-Draft CCCP February 2009 1.3. Closing a connection A server MUST NOT unilaterally close the connection without sending an untagged BYE response that contains the reason for having done so. A client SHOULD NOT unilaterally close the connection, and instead SHOULD issue a QUIT command. If the server detects that the client has unilaterally closed the connection, the server MAY omit the untagged BYE response and simply close its connection. 1.4. Generic protocol syntax Each request and response sent by the client matches the "message" ABNF production defined below. A protocol client sends "command"s and the server would respond with "response", which includes an arbitrary number of "s-response"s and "v-response"s (in any order), then it confirms command completion with an "f-response". Generic syntax of the protocol can be expressed using ABNF [RFC5234]: atom = 1*1024ATOM-CHAR ; Maximum of 1024 characters ATOM-CHAR = atom-specials = "(" / ")" / "{" / SP / CTL / list-wildcards / quoted-specials / resp-specials CHAR = %x21-%x7e ; ASCII excluding control characters CHAR8 = %x00-ff ; any OCTET including NUL CRLF = %x0d %x0a DIGIT = %x30-39 DQUOTE = %x22 list-end = ")" list-start = "(" list-wildcards = "%" / "*" literal = "{" number "}" CRLF *CHAR8 ; Number represents the number of CHAR8s ; Note that zero characters is allowed. Wilson & Melnikov Expires August 17, 2009 [Page 5] Internet-Draft CCCP February 2009 number = 1*DIGIT ; Unsigned 32-bit integer ; (0 <= n < 4,294,967,296) quoted = DQUOTE *QUOTED-CHAR DQUOTE ; Maximum of 1024 characters (including quotations) ; The value of a 'quoted' is the characters of the string ; with the outer DQUOTE removed and "\" CHAR replaced by ; CHAR. QUOTED-CHAR = / "\" quoted-specials quoted-specials = DQUOTE / "\" resp-specials = "]" SP = %x20 text = 1*TEXT-CHAR TEXT-CHAR = %x20-21 / %x23-5b/ %x5d-7e / %x80-ff ; ASCII excluding all control chars + '"' and '\' ; Allows UTF-8 sequences. list = list-start [ value *( SP value ) ] list-end named-value = list ; the first item names the list and is an atom ; the remaining values (if any) are defined by the atom string = quoted / literal astring = atom / string value = astring / list tag = atom stag = tag / "*" message = stag SP atom *(SP named-value) CRLF ; The atom is interpreted according to the context of the message ; The tag relate messages for the same command command = message ; Any request sent by the client matches this production Wilson & Melnikov Expires August 17, 2009 [Page 6] Internet-Draft CCCP February 2009 ; in the can't be "*". response = *( s-response / v-response ) f-response ; The server responds to a command with an arbitrary ; number of s-response and v-response (in any order), ; then confirms command completion with an f-response. s-response = tag SP atom SP status *( SP named-value ) CRLF ; syntactically a 'message' ; returns status for the item identified by 'atom' ; where the tag matches the command tag ; and the atom after the tag is not one found in f-response ; v-response = stag SP atom SP ( atom / quoted / list ) CRLF ; syntactically a 'message' ; returns a value to be referred to by some s-response ; The atom is the ID for the value. ; An unnamed value using literal or literals must be in a list ; This is to provide a check on the termination of the literal. f-response = tag SP ( "OK" / "NO" / "BAD" ) [SP status] [SP quoted] CRLF ; syntactically a 'message' ; where the tag matches the command tag ; ; "OK" implies overall command success. ; "NO" implies some problem in processing the command. ; In the absence of a status, this implies a transient problem. ; So the command can be retried after an interval. ; "BAD" implies that the command was malformed in some way. ; It may be followed by a giving some information for ; the reason for the failure. status = named-list ; The first element of the list MUST be an , ; which specifies type of the status information. ; This is followed by zero or more parameters. ; ; For example, the can be one of the values ; specified in , which may be followed by ; and/or a giving human readable ; information. ext-code = (%x32/%x34/%x35) "." 1*3DIGIT "." 1*3DIGIT ; Complies with syntax. status-atom = atom Wilson & Melnikov Expires August 17, 2009 [Page 7] Internet-Draft CCCP February 2009 ; Specific to a command, although values may be shared ; between different commands. ; New values may be added later. ;; The choice between s-response and v-response is made using the value ;; of the atom, and depends upon the command. ;; Atoms for naming values and responses have a structure like ;; domain names: name-atom = component *( "." component ) component = 1*comp-char comp-char = When creating a value in a message, the sender of the message can choose from 'atom', 'quoted' and 'literal' as long as the requirements are met. So, if the value is ASCII, contains no ATOM- SPECIALs and is not longer than 1024 bytes, it can be an 'atom'. If it does not contain any control characters, and the quoted result is not more than 1024 bytes, then it can be a 'quoted'. Otherwise it needs to be a literal. Strings used for commands, status values, and names are recognised ignoring the case of letters. 2. Supported commands 2.1. CAPABILITY command Arguments: protocol version Responses: CAPABILITY response Result: OK - CAPABILITY command completed successfully BAD - unrecognized syntax of an argument, unexpected extra argument, missing argument, etc. This command is typically the first command used by the client upon connecting to the server. It allows the client to discover server capabilities (and extensions, if any), and optionally let the server know client's capabilities. The command is optional for the client to use, as the client can discover server capabilities from the untagged CAPABILITY response returned upon initial connection to the server. Wilson & Melnikov Expires August 17, 2009 [Page 8] Internet-Draft CCCP February 2009 The server will respond with the untagged CAPABILITY response. See Section 2.4. Example: C: A0001 CAPABILITY (VERSION 1.0) S: * CAPABILITY (VERSION 1.0) (CONVERT) S: A0001 OK 2.2. QUIT command Arguments: None Responses: BYE untagged response Result: OK - QUIT command completed successfully, client and server can close connection now. BAD - unrecognized syntax of an argument, unexpected extra argument, missing argument, etc. This command is used to terminate a server session. The server responds to this command with an untagged BYE Section 2.5 response, followed by the tagged OK response ("f-response"). After that the server closes the connection. Use of this command is not essential if the communication channel can signal closure. Example: C: A0055 QUIT S: * BYE "See you later" S: A0055 OK 2.3. CONVERT command Arguments: OPTIONAL TYPE OPTIONAL SENDER OPTIONAL RECIP. (one or more) CONTENT.0 (message content) Responses: no specific response for this command Result: OK - CONVERT command completed successfully NO - CONVERT failed to process the client command. BAD - unrecognized syntax of an argument, unexpected extra argument, missing argument, etc. The purpose of this command is to enable the server to check the Wilson & Melnikov Expires August 17, 2009 [Page 9] Internet-Draft CCCP February 2009 message content, and, if required, change envelope addresses and/or the message content. A different converted content can be associated with different message recipients, if required. TYPE This specifies what kind of object is processed by the command. Currently 2 value are allowed: "822" - RFC 5322 content (full email message); "mime" - a single MIME body part. SENDER sender email address, optionally followed by ESMTP parameters to the MAIL FROM command encoded as "named-value"s. For example a MAIL FROM parameter "AUTH=sender@example.com" becomes "(AUTH sender@example.com)". Note that any "xtext" encoding used to encode a parameter value MUST be removed before representing it as a named-value. RECIP. -ths recipient email address, optionally followed by ESMTP parameters to the RCPT TO command encoded as "named-value"s. Note that any "xtext" encoding used to encode a parameter value MUST be removed before representing it as a named-value. CONTENT.0 the message content to check/convert. Can consist of one or more "literals". ABNF for the CONVERT command and its corresponding responses is described below: Convert-Command = Tag SP "CONVERT" [SP Type-Arg] [SP Sender-Info Recipients] SP Content-Info CRLF ; Conforms to generic syntax specified by ; the non-terminal. Type-Arg = "(" "TYPE" SP string ")" Sender-Info = "(" "SENDER" SP Address [Sender-Args] ")" Recipients = 1*(SP Recipient) Recipient = "(" "RECIP." number SP Address [Recip-Args] ")" ; above is the recipient number. All recipient ; numbers MUST be different in a CONVERT command. Address = string ; email address encoded as a Sender-Args = 1*(SP named-value) ; Sender specific ESMTP parameters ; Each specific parameter is "atom SP astring" Wilson & Melnikov Expires August 17, 2009 [Page 10] Internet-Draft CCCP February 2009 Recip-Args = 1*(SP named-value) ; Recipient specific ESMTP parameters ; Each specific parameter is "atom SP astring" Content-Info = "(" "CONTENT.0" 1*(SP Data-Chunk) ")" Data-Chunk = literal ;; Responses: returned-content = tag SP "CONTENT." number SP literal CRLF ; Conforms to "v-response" syntax returned-recip = tag SP "RECIP." number SP status *( SP returned-recip-param ) CRLF ; Conforms to "s-response" syntax returned-sender = tag SP "SENDER" SP status *(SP returned-mailfrom-param) CRLF ; Conforms to "s-response" syntax returned-mailfrom-param = named-value ; The value is a replacement MAIL FROM parameter. returned-recip-param = "(" out-recip-param ")" / rcptto-param out-recip-param = "CONTENT." number *(SP Data-Chunk) / "REDIR" SP Address / "EXPAND" 1*(SP Address) / rcptto-param ; Omitted s in CONTENT mean a reference to ; a previously transmitted response. rcptto-param = named-value ; Returned in the final OK/NO response: convert-status-token = "PASS" / "FAIL" / "DELETE" / "DELIVER" / "HOLD" / "QUARANTINE" / "REDIR" / "TEMP" ; This conforms to . ; ; PASS - Message is passed for further processing ; FAIL - The message is non-delivered ; TEMP - There is a transient problem in processing ; DELETE - Remove the message from the transfer system ; DELIVER - Treat the message as being delivered Wilson & Melnikov Expires August 17, 2009 [Page 11] Internet-Draft CCCP February 2009 ; REDIR - Redirect message to a new recipient ; HOLD - Hold the message in the queue ; QUARANTINE - Delete the message, moving to quarantined storage ; ; All but TEMP are returned in the OK response ; ; Note that redirection and expansion are handled by ; the returned values associated with the s-response Below is an example of the CONVERT command and relevant responses. Note that long lines are folded for readability (a line not starting with either C: or S: is a continuation of the previous line). C: A001 Convert (type 822) (sender sender@example.com (AUTH sender@example.com) (RET HDRS)) (recip.1 recip1@example.com) (recip.2 recip2@example.com) (content.0 {17} C: Subject: a test C: {9} C: C: Hello C: ) S: A001 Content.1 {28} S: Subject: a test S: S: Goodbye S: S: A001 Sender OK "" (REDIR new-sender@example.net) (AUTH <>) (RET FULL) S: A001 Recip.1 (PASS 2.5.0 "Message checked by wonder checker V1.0beta") (REDIR new-recip1@example.net) (CONTENT.1) S: A001 Recip.2 (PASS 2.5.0 "Message checked by wonder checker V1. 0beta") (REDIR new-recip2@example.net) (CONTENT.2 {29} S: Subject: a test S: S: Farewell S: S: ) S: A001 OK 2.4. CAPABILITY Response The CAPABILITY response is always untagged. It is returned on initial client connection or whenever the CAPABILITY command is issued. The response contains the protocol version number (VERSION 1.0, which MUST be the first pair returned), as well as commands it supports, where the initial atom is the name of the supported command. This may be followed by values representing command options supported. It is assumed that the server always supports the Wilson & Melnikov Expires August 17, 2009 [Page 12] Internet-Draft CCCP February 2009 CAPABILITY and the QUIT commands, so these are not advertised in the CAPABILITY response. Example: S: * CAPABILITY (VERSION 1.0) (CONVERT) 2.5. BYE Response The BYE response is always untagged, and indicates that the server is about to close the connection. The human-readable text that follows the BYE MAY be displayed to the user in a status report by the client. Example: S: * BYE "Server is shutting down" 3. Security Considerations [[anchor9: TBD.]] 4. IANA Considerations [[anchor10: TBD.]] 5. Acknowledgements The authors gratefully acknowledges the feedback provided by Steve Kille, Dave Cridland, Bruce Stephens and Mark Walker (Boldon James). 6. Normative References [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, January 2008. Wilson & Melnikov Expires August 17, 2009 [Page 13] Internet-Draft CCCP February 2009 Authors' Addresses David Wilson Isode Limited 5 Castle Business Village 36 Station Road Hampton, Middlesex TW12 2BX UK Email: david.wilson@isode.com Alexey Melnikov Isode Limited 5 Castle Business Village 36 Station Road Hampton, Middlesex TW12 2BX UK Email: alexey.melnikov@isode.com URI: http://www.melnikov.ca/ Wilson & Melnikov Expires August 17, 2009 [Page 14] Internet-Draft CCCP February 2009 Full Copyright Statement Copyright (C) The IETF Trust (2009). This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights. This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Intellectual Property The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the procedures with respect to rights in RFC documents can be found in BCP 78 and BCP 79. Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr. The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf-ipr@ietf.org. Wilson & Melnikov Expires August 17, 2009 [Page 15]