RFC 3887

Message Tracking Query Protocol

๐Ÿ“… published September 2004, from ietf

RFC 3887: Message Tracking Query Protocol ๐Ÿ’Œ๐ŸŽ€

Okay bestie, here's the deal. This is RFC 3887, titled Message Tracking Query Protocol ๐Ÿฆ‹. It's a Standards Track doc from the Network Working Group, written by T. Hansen of AT&T Laboratories and dated September 2004 ๐Ÿ“…. It doesn't obsolete or update anything (the title block doesn't list any), so it's a fresh spec ๐Ÿ’….

Status of this Memo โœจ

This doc is an Internet standards track protocol for the Internet community, and it's basically asking everyone to talk about it and suggest improvements ๐Ÿ—ฃ๏ธ. If you want to know where it sits in the standardization process, check the current edition of the "Internet Official Protocol Standards" (STD 1) ๐Ÿ“š. Distribution of this memo is unlimited ๐ŸŒˆ.

Copyright (C) The Internet Society (2004).

Abstract ๐Ÿ”ฅ

Okay so enterprise customers buying message systems always ask the same thing: can I track the messages? ๐Ÿ‘€ Message tracking is basically finding out the path a particular message took through a messaging system, plus its current routing status ๐Ÿ›ค๏ธ. This doc describes the Message Tracking Query Protocol, which works together with extensions to ESMTP to give a complete message tracking solution for the Internet ๐Ÿซถ.

1. Introduction ๐ŸŒธ

The Message Tracking Models and Requirements document [RFC-MTRK-MODEL] talks about the models message tracking solutions could follow, plus the requirements for a solution that works with the Internet-wide message infrastructure ๐Ÿง . This memo and its companions, [RFC-MTRK-ESMTP] and [RFC-MTRK-TSN], make up a complete message tracking solution that meets those requirements ๐Ÿ’œ. The memo [RFC-MTRK-ESMTP] defines an extension to the SMTP service that gives you the info you need to track messages ๐Ÿ“ฌ. This memo defines a protocol you can use to query the status of messages that have been sent across the Internet via SMTP ๐Ÿ”. The memo [RFC-MTRK-TSN] describes the message/tracking-status [RFC-MIME] media type, which is used to report tracking status info ๐Ÿงพ. Using the model document's terminology, this solution uses active enabling and active requests with both request and chaining referrals โญ.

1.1. Terminology ๐Ÿ“–

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 BCP 14, RFC 2119 [RFC-KEYWORDS] ๐ŸŽฏ.

All syntax descriptions use the ABNF specified by [RFC-ABNF]. Terminal nodes that aren't defined elsewhere in this document are defined in [RFC-ABNF], [RFC-URI], [RFC-MTRK-ESMTP], [RFC-SMTP], or [RFC-SMTPEXT] ๐Ÿงฉ.

2. Basic Operation ๐Ÿš€

The Message Tracking Query Protocol (MTQP) is giving the same vibe as other line-oriented Internet protocols, like [POP3] and [NNTP] ๐Ÿ’…. To start, the server host kicks off the MTQP service by listening on TCP port 1038 ๐ŸŽง.

When an MTQP client wants to use the message tracking service, it sets up a TCP connection with the server host ๐Ÿค. The server host is the one recorded from the initial message submission, or the one returned by a previous tracking request ๐Ÿ“. To find the server host, the MTQP client first does an SRV lookup using DNS SRV records, with a service name of "mtqp" and a protocol name of "tcp", like this: _mtqp._tcp.smtp3.example.com. ๐Ÿ”Ž (See the "Usage rules" section in [RFC-SRV] for details ๐Ÿ“š.) If the SRV records don't exist, the MTQP client then does an address record lookup for the server host instead ๐Ÿ™ƒ. Once the connection is set up, the MTQP server sends a greeting ๐Ÿ‘‹. After that, the MTQP client and MTQP server trade commands and responses (respectively) until the connection gets closed or aborted ๐Ÿซง.

2.1. Tracking Service DNS Considerations ๐Ÿ—บ๏ธ

Because of the way server host lookups work, a bunch of different tracking server host setups are supported ๐Ÿง.

A mail system that uses a single mail server host, and has the MTQP server host on that same server host, will most likely have one MX record pointing at the server host ๐ŸŽฏ. If it doesn't, it'll have an address record instead ๐Ÿ™‚. Both mail and MTQP clients will access that host directly ๐Ÿ’โ€โ™€๏ธ.

A mail system that uses a single mail server host, but wants tracking queries to run on a different machine, MUST have an SRV MTQP record pointing at that different machine ๐ŸŽ€.

A mail system that uses multihomed mail servers has two choices for providing tracking services ๐ŸŒˆ. Either all the mail servers have to be running tracking servers that can retrieve info on all messages, or the tracking service has to run on one (or more) machine(s) that can retrieve info on all messages ๐Ÿค“. In the first case, you don't need any extra DNS records beyond the MX records already in place for the mail system ๐Ÿ’…. In the second case, you need SRV MTQP records pointing at the machine(s) running the tracking service ๐Ÿงš. In both cases, the tracking service MUST be able to handle the queries for all messages accepted by that mail system ๐Ÿ˜ค.

2.2. Commands โŒจ๏ธ

Commands in MTQP are a case-insensitive keyword, possibly followed by one or more parameters ๐Ÿ”ค. All commands get terminated by a CRLF pair ๐Ÿ. Keywords and parameters are made of printable ASCII characters ๐Ÿ”ก. They're separated by whitespace (one or more space or tab characters) โœจ. A command line is limited to 998 characters before the CRLF ๐Ÿ“.

2.3. Responses ๐Ÿ’ฌ

Responses in MTQP start with a status indicator that shows success or failure ๐Ÿšฆ. Successful commands can also be followed by extra lines of data ๐Ÿ“‘. All response lines get terminated by a CRLF pair and are limited to 998 characters before the CRLF ๐Ÿงต. There are several status indicators ๐Ÿซถ:

  • +OK means success ๐ŸŽ‰
  • +OK+ means a success followed by extra lines of data, a multi-line success response ๐Ÿ“œ
  • -TEMP means a temporary failure โณ
  • -ERR means a permanent failure ๐Ÿ’€
  • -BAD means a protocol error, like unrecognized commands ๐Ÿ™ˆ

A status indicator MAY be followed by a series of machine-parsable, case-insensitive response information giving more data about the errors ๐Ÿ”ง. These get separated from the status indicator, and from each other, by a single slash character (/, decimal code 47) โž—. After that, there MAY be white space and a human-readable text message ๐Ÿ’ญ. The human-readable text message isn't meant to be shown to the end user, but it should be fit for putting in a log for debugging problems ๐Ÿชต.

In a multi-line success response, each line after the first is terminated by a CRLF pair and limited to 998 characters before the CRLF ๐Ÿงถ. When all lines of the response have been sent, a final line gets sent that's made of a single period (., decimal code 046) and a CRLF pair ๐Ÿ›‘. If any line of the multi-line response begins with a period, that line is "dot-stuffed" by putting a second period in front of the period ๐Ÿฆท. When the client looks at a multi-line response, it checks whether the line begins with a period ๐Ÿ”. If it does, and octets other than CRLF follow, the first octet of the line (the period) gets stripped away โœ‚๏ธ. If it does, and CRLF comes right after the period, then the response from the MTQP server is ended, and the line containing the .CRLF isn't counted as part of the multi-line response ๐Ÿ.

An MTQP server MUST respond to an unrecognized, unimplemented, or syntactically invalid command by responding with a negative -BAD status indicator ๐Ÿšซ. A server MUST respond to a command issued when the session is in an incorrect state by responding with a negative -ERR status indicator โŒ.

2.4. Firewall Considerations ๐Ÿงฑ

A firewall mail gateway has two choices when it gets a tracking query for a host inside its domain ๐Ÿฐ. It MAY return a response saying the message has been passed on, but no further information is available ๐Ÿคทโ€โ™€๏ธ. Or it MAY do a chaining operation itself, gathering info on the message from the mail hosts behind the firewall ๐Ÿ”—. It can then return the info for each behind-the-firewall hop to the MTQP client, or possibly just the final hop info, and possibly disguise the names of any hosts behind the firewall ๐Ÿฅท. Which option gets picked is an administrative decision, and this document doesn't mandate it any further ๐Ÿ“‹.

If a server chooses to do a chaining operation itself, it MUST provide a response within 2 minutes โฑ๏ธ. It SHOULD return a "no further information is available" response if it can't come up with an answer by the end of that time limit ๐Ÿ˜ญ.

2.5. Optional Timers โฐ

An MTQP server MAY have an inactivity autologout timer ๐Ÿ˜ด. That timer MUST be at least 10 minutes long ๐Ÿ•™. Receiving any command from the client during that interval should be enough to reset the autologout timer ๐Ÿ”„. An MTQP server MAY limit the number of commands, unrecognized commands, or total connection time, or MAY use other criteria, to prevent denial of service attacks ๐Ÿ›ก๏ธ.

An MTQP client MAY have an inactivity autologout timer while it's waiting for a response from the server โณ. Since an MTQP server may be a firewall, and may be chaining info from other servers, that timer MUST be at least 2 minutes long ๐Ÿซ .

3. Initialization and Option Response ๐ŸŽฌ

Once the TCP connection has been opened by an MTQP client, the MTQP server sends an initial status response that shows it's ready ๐Ÿ™‹โ€โ™€๏ธ. If the status response is positive (+OK or +OK+), the client may move on to other commands ๐Ÿš€.

The initial status response MUST include the response information /MTQP ๐Ÿท๏ธ. Negative responses MUST include a reason code as response information ๐Ÿงพ. These reason codes are defined here, and unrecognized reason codes added in the future may be treated as equivalent to "unavailable" ๐Ÿ”ฎ:

"/" "unavailable"
"/" "admin"

The reason code /admin SHOULD be used when the service is unavailable for administrative reasons ๐Ÿ› ๏ธ. The reason code /unavailable SHOULD be used when the service is unavailable for other reasons ๐Ÿ™ƒ.

If the server has any options enabled, they're listed as the multi-line response of the initial status response, one per line ๐Ÿ“ƒ. An option specification is an identifier, optionally followed by option-specific parameters ๐Ÿ†”. An option specification can be continued onto additional lines by starting the continuation lines with white space ๐Ÿงต. The option identifier is case insensitive ๐Ÿ”ค. Option identifiers beginning with the characters vnd. are reserved for vendor use ๐Ÿ’ผ. (See below.)

One option specification is defined here ๐Ÿ’Ž:

STARTTLS [1*WSP "required"]

This capability MUST be listed if the optional STARTTLS command is enabled on the MQTP server and one or more certificates have been properly installed ๐Ÿ”.

It has one optional parameter: the word "required" (the parameters for STARTTLS are case-insensitive) ๐Ÿง. If the server requires that TLS be used for some of the domains the server handles, the server MUST specify the "required" parameter ๐Ÿซก.

3.1. Examples ๐ŸŒŸ

Example #1 (no options) ๐Ÿ’–:

S: +OK/MTQP MTQP server ready

Example #2 (service temporarily unavailable) โณ:

S: -TEMP/MTQP/admin Service down for admin, call back later

Example #3 (service permanently unavailable) ๐Ÿ’€:

S: -ERR/MTQP/unavailable Service down

Example #4 (alternative for no options) ๐Ÿฆ‹:

S: +OK+/MTQP MTQP server ready
S: .

Example #5 (options available) ๐ŸŒˆ:

S: +OK+/MTQP MTQP server ready
S: starttls
S: vnd.com.example.option2 with parameters private to example.com
S: vnd.com.example.option3 with a very long
S:  list of parameters
S: .

4. TRACK Command โœจ

okay bestie, the TRACK command is where the magic happens ๐Ÿ” here's the syntax:

track-command = "TRACK" 1*WSP unique-envid 1*WSP mtrk-secret CRLF
     mtrk-secret = base64

the unique-envid is defined in [RFC-MTRK-ESMTP] and the mtrk-secret is the secret A from that same doc, just base64 encoded ๐Ÿซถ

so when the client sends TRACK and the user gets validated, the MTQP server goes and grabs the tracking info for an email message ๐Ÿ“ฌ to validate the user, the mtrk-secret gets hashed with SHA1 (see [RFC-SHA1]) and then that hash is compared with the value that came along with the message when it was first sent. if they match, the user is validated. no cap, it's giving security ๐Ÿ”

a successful response MUST be multi-line and it MUST be a [RFC-MIME] body part. that body part MUST be type multipart/related, with subparts of message/tracking-status (as defined in [RFC-MTRK-TSN]). the response has the tracking info for the email that used the given tracking-id โœจ a negative response to TRACK may include these reason codes:

   "/" "tls-required"
   "/" "admin"
   "/" "unavailable"
   "/" "noinfo"
   "/" "insecure"

the /tls-required one SHOULD be used when the server has decided to require TLS ๐Ÿ”’ the /admin one SHOULD be used when the server became unavailable for administrative reasons since the connection was started ๐Ÿ› ๏ธ and /unavailable SHOULD be used when the server became unavailable for other reasons since the connection was started ๐Ÿ’€ the /insecure one is explained later on, so stay tuned ๐Ÿ‘€

now the tea: if the MTQP server has never seen a message, it MUST pick one of two options. it MAY send back a positive response with an action field of opaque in the tracking info, OR it MAY send back a negative response with a reason code of noinfo. the server gets to choose, which is kinda iconic honestly ๐Ÿ’…

4.1. Examples

in every example below, the unique-envid is <12345-20010101@example.com>, the secret A is abcdefgh, and the SHA1 hash B is (in hex) 734ba8b31975d0dbae4d6e249f4e8da270796c94. the message came from example.com and the MTQP server is example2.com ๐Ÿงš

Example #6 Message Delivered:

C: TRACK <12345-20010101@example.com> YWJjZGVmZ2gK
S: +OK+ Tracking information follows
S: Content-Type: multipart/related; boundary=%%%%; type=tracking-status
S:
S: --%%%%
S: Content-Type: message/tracking-status
S:
S: Original-Envelope-Id: 12345-20010101@example.com
S: Reporting-MTA: dns; example2.com
S: Arrival-Date: Mon, 1 Jan 2001 15:15:15 -0500
S:
S: Original-Recipient: rfc822; user1@example1.com
S: Final-Recipient: rfc822; user1@example1.com
S: Action: delivered
S: Status: 2.5.0
S:
S: --%%%%--
S: .

Example #7 Message Transferred:

C: TRACK <12345-20010101@example.com> YWJjZGVmZ2gK
S: +OK+ Tracking information follows
S: Content-Type: multipart/related; boundary=%%%%; type=tracking-status
S:
S: --%%%%
S: Content-Type: message/tracking-status
S:
S: Original-Envelope-Id: 12345-20010101@example.com
S: Reporting-MTA: dns; example2.com
S: Arrival-Date: Mon,  1 Jan 2001 15:15:15 -0500
S:
S: Original-Recipient: rfc822; user1@example1.com
S: Final-Recipient: rfc822; user1@example1.com
S: Action: transferred
S: Remote-MTA: dns; example3.com
S: Last-Attempt-Date: Mon, 1 Jan 2001 19:15:03 -0500
S: Status:2.4.0
S:
S: --%%%%--
S: .

Example #8 Message Delayed and a Dot-Stuffed Header:

C: TRACK <12345-20010101@example.com> YWJjZGVmZ2gK
S: +OK+ Tracking information follows
S: Content-Type: multipart/related; boundary=%%%%; type=tracking-status
S: ..Dot-Stuffed-Header: as an example
S:
S: --%%%%
S: Content-Type: message/tracking-status
S:
S: Original-Envelope-Id: 12345-20010101@example.com
S: Reporting-MTA: dns; example2.com
S: Arrival-Date: Mon, 1 Jan 2001 15:15:15 -0500
S:
S: Original-Recipient: rfc822; user1@example1.com
S: Final-Recipient: rfc822; user1@example1.com
S: Action: delayed
S: Status: 4.4.1 (No answer from host)
S: Remote-MTA: dns; example3.com
S: Last-Attempt-Date: Mon, 1 Jan 2001 19:15:03 -0500
S: Will-Retry-Until: Thu, 4 Jan 2001 15:15:15 -0500
S:
S: --%%%%--
S: .

Example #9 Two Users, One Relayed, One Failed:

C: TRACK <12345-20010101@example.com> YWJjZGVmZ2gK
S: +OK+ Tracking information follows
S: Content-Type: multipart/related; boundary=%%%%; type=tracking-status
S:
S: --%%%%
S: Content-Type: message/tracking-status
S:
S: Original-Envelope-Id: 12345-20010101@example.com
S: Reporting-MTA: dns; example2.com
S: Arrival-Date: Mon,  1 Jan 2001 15:15:15 -0500
S:
S: Original-Recipient: rfc822; user1@example1.com
S: Final-Recipient: rfc822; user1@example1.com
S: Action: relayed
S: Status: 2.1.9
S: Remote-MTA: dns; example3.com
S: Last-Attempt-Date: Mon, 1 Jan 2001 19:15:03 -0500
S:
S: Original-Recipient: rfc822; user2@example1.com
S: Final-Recipient: rfc822; user2@example1.com
S: Action: failed
S: Status 5.2.2 (Mailbox full)
S: Remote-MTA: dns; example3.com
S: Last-Attempt-Date: Mon, 1 Jan 2001 19:15:03 -0500
S:
S: --%%%%--
S: .

Example #10 Firewall:

C: TRACK <12345-20010101@example.com> YWJjZGVmZ2gK
S: +OK+ Tracking information follows
S: Content-Type: multipart/related; boundary=%%%%; type=tracking-status
S:
S: --%%%%
S: Content-Type: message/tracking-status
S:
S: Original-Envelope-Id: 12345-20010101@example.com
S: Reporting-MTA: dns; example2.com
S: Arrival-Date: Mon,  1 Jan 2001 15:15:15 -0500
S:
S: Original-Recipient: rfc822; user1@example1.com
S: Final-Recipient: rfc822; user1@example1.com
S: Action: relayed
S: Status: 2.1.9
S: Remote-MTA: dns; smtp.example3.com
S: Last-Attempt-Date: Mon, 1 Jan 2001 19:15:03 -0500
S:

S: --%%%%
S: Content-Type: message/tracking-status
S:
S: Original-Envelope-Id: 12345-20010101@example.com
S: Reporting-MTA: dns; smtp.example3.com
S: Arrival-Date: Mon,  1 Jan 2001 15:15:15 -0500
S:
S: Original-Recipient: rfc822; user2@example1.com
S: Final-Recipient: rfc822; user4@example3.com
S: Action: delivered
S: Status: 2.5.0
S:
S: --%%%%--
S: .

Example #11 Firewall, Combining Per-Recipient Blocks:

C: TRACK <12345-20010101@example.com> YWJjZGVmZ2gK
S: +OK+ Tracking information follows
S: Content-Type: multipart/related; boundary=%%%%; type=tracking-status
S:
S: --%%%%
S: Content-Type: message/tracking-status
S:
S: Original-Envelope-Id: 12345-20010101@example.com
S: Reporting-MTA: dns; example2.com
S: Arrival-Date: Mon,  1 Jan 2001 15:15:15 -0500
S:
S: Original-Recipient: rfc822; user1@example1.com
S: Final-Recipient: rfc822; user1@example1.com
S: Action: relayed
S: Status: 2.1.9
S: Remote-MTA: dns; smtp.example3.com
S: Last-Attempt-Date: Mon, 1 Jan 2001 19:15:03 -0500
S:
S: Original-Recipient: rfc822; user2@example1.com
S: Final-Recipient: rfc822; user4@example3.com
S: Action: delivered
S: Status:2.5.0
S:
S: --%%%%--
S: .

Example #12 Firewall, Hiding System Names Behind the Firewall:

C: TRACK <12345-20010101@example.com> YWJjZGVmZ2gK
S: +OK+ Tracking information follows
S: Content-Type: multipart/related; boundary=%%%%; type=tracking-status
S:
S: --%%%%
S: Content-Type: message/tracking-status
S:
S: Original-Envelope-Id: 12345-20010101@example.com
S: Reporting-MTA: dns; example2.com
S: Arrival-Date: Mon,  1 Jan 2001 15:15:15 -0500
S:
S: Original-Recipient: rfc822; user1@example1.com
S: Final-Recipient: rfc822; user1@example1.com
S: Action: relayed
S: Status: 2.1.9
S: Remote-MTA: dns; example2.com
S: Last-Attempt-Date: Mon, 1 Jan 2001 19:15:03 -0500
S:
S: --%%%%
S: Content-Type: message/tracking-status
S:
S: Original-Envelope-Id: 12345-20010101@example.com
S: Reporting-MTA: dns; example2.com
S: Arrival-Date: Mon,  1 Jan 2001 15:15:15 -0500
S:
S: Original-Recipient: rfc822; user2@example1.com
S: Final-Recipient: rfc822; user4@example1.com
S: Action: delivered
S: Status: 2.5.0
S:
S: --%%%%--
S: .

5. COMMENT Command ๐Ÿ’ฌ

the COMMENT command is the chill one, bestie ๐ŸŒธ here's the syntax:

  comment-command =  "COMMENT" opt-text CRLF
         opt-text = [WSP *(VCHAR / WSP)]

when the client sends COMMENT, the MTQP server MUST send back a successful response (+OK or +OK+) ๐Ÿซถ any optional text that comes with the COMMENT command gets ignored, so you can say whatever you want in there and the server just vibes โœจ

6. STARTTLS Command ๐Ÿ”’

okay this one is so important, it's basically the bodyguard of the whole protocol ๐Ÿ’ช here's the syntax:

  starttls-command = "STARTTLS" 1*WSP domain *WSP CRLF
            domain = (sub-domain 1*("." sub-domain))

so TLS [TLS] is a super popular way to make TCP connections confidential and authenticated ๐Ÿ” all MTQP servers MUST implement TLS, no exceptions, periodt ๐Ÿ’… HOWEVER, a server admin MAY turn TLS off, either on purpose or just by not installing any certificates for it to use ๐Ÿ™ƒ and if an MTQP server supports TLS and has one or more certificates available, it MUST include "STARTTLS" in the option specifications list when the protocol starts up โœจ

Note: TLS SHOULD be enabled on MQTP servers whenever possible. ๐Ÿฅบ

the parameter MUST be a fully qualified domain name (FQDN) ๐Ÿ“ a client MUST tell the server which hostname it thinks it's talking to, so the server can send back the right TLS certificate. this is super useful for virtual servers that do message tracking for multiple domains (aka virtual hosting) ๐Ÿงš

if the server sends a negative response, it MAY use one of these response codes:

   "/" "unsupported"
   "/" "unavailable"
   "/" "tls-in-progress"
   "/" "bad-fqdn"

if TLS isn't supported, a /unsupported response code SHOULD be used ๐Ÿ’€ if TLS isn't available for some other reason, then /unavailable SHOULD be used ๐Ÿ™ˆ if a TLS session is already in progress, that's a protocol error, so -BAD MUST be returned with a /tls-in-progress response code ๐Ÿ˜ญ and if the supplied FQDN doesn't match the FQDN found in the dNSName field of the subjectAltName extension of the server's certificate [RFC-X509], that's also a protocol error, so -BAD MUST be returned with a /bad-fqdn response code ๐Ÿšซ

after the server sends a positive response to STARTTLS, the client MUST start the TLS negotiation before it sends any other MTQP commands ๐Ÿ”ฅ

and if the MTQP client is pipelining (see below), the STARTTLS command MUST be the last command in the group, no cap ๐Ÿซถ

6.1. Processing After the STARTTLS Command ๐Ÿง 

if the TLS handshake fails, the server SHOULD abort the connection ๐Ÿ’”

once the TLS handshake is done, both sides MUST immediately decide whether to keep going, based on the authentication and confidentiality they actually got ๐Ÿค” the MTQP client and server MAY decide to move ahead even if the TLS negotiation ended with no authentication and/or no confidentiality, because most MTQP services are done with no authentication and no confidentiality ๐ŸŒˆ but some clients or servers may only want to continue if a particular level of authentication and/or confidentiality was achieved, and that's valid too ๐Ÿ’œ

if the MTQP client decides the level of authentication or confidentiality isn't high enough, it SHOULD send an MTQP QUIT command right after the TLS negotiation is complete ๐Ÿ‘‹

if the MTQP server decides the level of authentication or confidentiality isn't high enough, it MAY abort the connection โœจ if it decides that and does NOT abort the connection, it SHOULD reply to every MTQP command from the client (other than QUIT) with a negative -ERR response and a response code of /insecure ๐Ÿ™…โ€โ™€๏ธ

6.2. Result of the STARTTLS Command โœจ

Okay so once the TLS handshake is done, MTQP gets a full reset ๐Ÿ”„ back to the initial state (the state MTQP is in when a server first starts up). The server MUST discard any knowledge it got from the client before the TLS negotiation itself. The client MUST discard any knowledge it got from the server, like the list of MTQP options, unless that knowledge came from the TLS negotiation itself. Clean slate, bestie ๐Ÿซง

At the end of the TLS handshake, the server acts like the connection just started ๐ŸŒธ and replies with an initial status response and, optionally, a list of server options. The list of MTQP server options received after the TLS handshake MUST be different from the list returned before it. In particular, a server MUST NOT return the STARTTLS option in its list of server options once a TLS handshake has been completed. No more STARTTLS, we already did it ๐Ÿ’…

Both the client and the server MUST know whether a TLS session is active. A client MUST NOT attempt to start a TLS session if one is already active. ๐Ÿšซ

7. QUIT Command ๐Ÿ‘‹

Syntax:

  quit-command = "QUIT" CRLF

When the client issues the QUIT command, the MTQP session terminates. The QUIT command has no parameters. The server MUST respond with a successful response. The client MAY close the session from its end immediately after issuing this command (if the client is on an operating system where this does not cause problems). ๐Ÿฆ‹

8. Pipelining ๐Ÿ“

The MTQP client may elect to transmit groups of MTQP commands in batches without waiting for a response to each individual command. The MTQP server MUST process the commands in the order received. Ordering is everything, periodt ๐Ÿ“‹

Specific commands may place further constraints on pipelining. For example, STARTTLS must be the last command in a batch of MTQP commands. Plan your batches accordingly ๐Ÿงš

8.1. Examples ๐Ÿง

The following two examples are identical:

Example #13 :

  C: TRACK <tracking-id> YWJjZGVmZ2gK
  S: +OK+ Tracking information follows
  S:
  S: ... tracking details #1      go here ...
  S: .
  C: TRACK <tracking-id-2> QUJDREVGR0gK
  S: +OK+ Tracking information follows
  S:
  S: ... tracking details #2      go here ...
  S: .

Example #14 :

  C: TRACK <tracking-id> YWJjZGVmZ2gK
  C: TRACK <tracking-id-2> QUJDREVGR0gK
  S: +OK+ Tracking information follows
  S:
  S: ... tracking details #1      go here ...
  S: .
  S: +OK+ Tracking information follows
  S:
  S: ... tracking details #2      go here ...
  S: .

9. The MTQP URI Scheme ๐Ÿ”—

9.1. Intended usage ๐ŸŽฏ

The MTQP URI scheme is used to designate MTQP servers on Internet hosts accessible using the MTQP protocol. It performs an MTQP query and returns tracking status information. So it's basically the address that goes and asks "where's my message?" ๐Ÿ“ฌ

9.2. URI Scheme Name ๐Ÿท๏ธ

The name of the URI scheme is mtqp.

9.3. URI Scheme Syntax ๐Ÿงฉ

An MTQP URI takes one of the following forms:

  mtqp://<mserver>/track/<unique-envid>/<mtrk-secret>
  mtqp://<mserver>:<port>/track/<unique-envid>/<mtrk-secret>

The first form is used to refer to an MTQP server on the standard port, while the second form specifies a non-standard port. Both of these forms specify that the TRACK command is to be issued using the given tracking id (unique-envid) and authorization secret (mtrk-secret). The path element "/track/" MUST BE treated case insensitively, but the unique-envid and mtrk-secret MUST NOT be. Casing matters for the secrets, so don't get cute with them ๐Ÿ™ˆ

9.3.1. Formal Syntax ๐Ÿ“

This is an ABNF description of the MTQP URI.

  mtqp-uri = "mtqp://" authority "/track/" unique-envid "/" mtrk-secret

9.4. Encoding Rules ๐Ÿ”

The encoding of unique-envid is discussed in [RFC-MTRK-ESMTP]. Mtrk-secret is required to be base64 encoded. If the "/", "?" and "%" octets appear in unique-envid or mtrk-secret, they are further required to be represented by a "%" followed by two hexadecimal characters. (The two characters give the hexadecimal representation of that octet.) Escaping is not optional drama, it's the rule ๐Ÿ’…

10. IANA Considerations ๐Ÿ›๏ธ

System port number 1038 has been assigned to the Message Tracking Query Protocol by the Internet Assigned Numbers Authority (IANA). Port 1038, it's giving official โœจ

The service name "MTQP" has been registered with the IANA.

The IANA has also registered the URI registration template found in Appendix A in accordance with [BCP35].

This document requests that IANA maintain one new registry: MTQP options. The registry's purpose is to register options to this protocol. Options whose names do not begin with "vnd." MUST be defined in a standards track or IESG approved experimental RFC. New MTQP options MUST include the following information as part of their definition:

  option identifier
  option parameters
  added commands
  standard commands affected
  specification reference
  discussion

One MTQP option is defined in this document, with the following registration definition:

  option identifier: STARTTLS
  option parameters: none
  added commands: STARTTLS
  standard commands affected: none
  specification reference: RFC 3887
  discussion: see RFC 3887

Additional vendor-specific options for this protocol have names that begin with "vnd.". After the "vnd." would appear the reversed domain name of the vendor, another dot ".", and a name for the option itself. For example, "vnd.com.example.extinfo" might represent a vendor-specific extension providing extended information by the owner of the "example.com" domain. These names MAY be registered with IANA. Naming your extension like a reverse-domain is very main character energy ๐Ÿ‘‘

11. Security Considerations ๐Ÿ›ก๏ธ

โš ๏ธ Bestie, this section is serious business. Please read every word of it, no skipping. Your tracking data and your users' privacy depend on it. ๐Ÿ˜ญ

If the originator of a message were to delegate his or her tracking request to a third party, this would be vulnerable to snooping over unencrypted sessions. The user can decide on a message-by-message basis if this risk is acceptable.

The security of tracking information is dependent on the randomness of the secret chosen for each message and the level of exposure of that secret. If different secrets are used for each message, then the maximum exposure from tracking any message will be that single message for the time that the tracking information is kept on any MTQP server. If this level of exposure is too much, TLS may be used to reduce the exposure further.

It should be noted that message tracking is not an end-to-end mechanism. Thus, if an MTQP client/server pair decide to use TLS confidentiality, they are not securing tracking queries with any prior or successive MTQP servers. So TLS only covers that one hop, not the whole journey ๐Ÿซฃ

Both the MTQP client and server must check the result of the TLS negotiation to see whether acceptable authentication or confidentiality was achieved. Ignoring this step completely invalidates using TLS for security. The decision about whether acceptable authentication or confidentiality was achieved is made locally, is implementation-dependent, and is beyond the scope of this document. Checking the result is not optional, it's the whole point ๐Ÿ’€

The MTQP client and server should note carefully the result of the TLS negotiation. If the negotiation results in no confidentiality, or if it results in confidentiality using algorithms or key lengths that are deemed not strong enough, or if the authentication is not good enough for either party, the client may choose to end the MTQP session with an immediate QUIT command, or the server may choose to not accept any more MTQP commands. Walk away when the vibes are unsafe ๐Ÿšช

A man-in-the-middle attack can be launched by deleting the "STARTTLS" option response from the server. This would cause the client not to try to start a TLS session. An MTQP client can protect against this attack by recording the fact that a particular MTQP server offers TLS during one session and generating an alarm if it does not appear in an option response for a later session. Someone sneaking in and deleting the STARTTLS line is giving villain behavior ๐Ÿ˜ค

Similarly, the identity of the server as expressed in the server's certificate should be cached, and an alarm generated if they do not match in a later session.

If TLS is not used, a tracking request is vulnerable to replay attacks, such that a snoop can later replay the same handshake again to potentially gain more information about a message's status. Replay attacks are not it ๐Ÿฅ€

Before the TLS handshake has begun, any protocol interactions are performed in the clear and may be modified by an active attacker. For this reason, clients and servers MUST discard any knowledge obtained prior to the start of the TLS handshake upon completion of the TLS handshake. Everything said in the clear before the handshake is basically public, so toss it once the lock clicks ๐Ÿ”’

If a client/server pair successfully performs a TLS handshake and the server does chaining referrals, then the server SHOULD attempt to negotiate TLS at the same (or better) security level at the next hop. In a hop-by-hop scenario, STARTTLS is a request for "best effort" security and should be treated as such. Keep the security level up the chain, or at least don't let it slip ๐Ÿ”—

SASL is not used because authentication is per message rather than per user. ๐Ÿ™…โ€โ™€๏ธ

12. Protocol Syntax ๐Ÿงพ

This is a collected ABNF description of the MTQP protocol. Here's the whole grammar in one place, bestie ๐Ÿ“œ

mtqp-uri = "mtqp://" authority "/track/" unique-envid "/" mtrk-secret

conversation = command-response *(client-command command-response)

; client side
client-command = track-command / starttls-command / quit-command
/comment-command

track-command = "TRACK" 1*WSP unique-envid 1*WSP mtrk-secret CRLF
mtrk-secret = base64

starttls-command = "STARTTLS" 1*WSP domain *WSP CRLF
domain = (sub-domain 1*("." sub-domain))

quit-command = "QUIT" CRLF

comment-command = "COMMENT" opt-text CRLF
; server side
command-response = success-response / temp-response / error-response /
bad-response

temp-response = "-TEMP" response-info opt-text CRLF

opt-text = [WSP *(VCHAR / WSP)]

error-response = "-ERR" response-info opt-text CRLF

bad-response = "-BAD" response-info opt-text CRLF

success-response = single-line-success / multi-line-success

single-line-success = "+OK" response-info opt-text CRLF

multi-line-success = "+OK+" response-info opt-text CRLF
                               *dataline dotcrlf

dataline = *998OCTET CRLF

dotcrlf = "." CRLF

NAMECHAR = ALPHA / DIGIT / "-" / "_"

response-info = *(      "/" ( "admin" / "unavailable" / "unsupported"
/ "tls-in-progress" / "insecure" / "tls-required" / 1*NAMECHAR ) )

13. Acknowledgements ๐Ÿซถ

The description of STARTTLS is based on [RFC-SMTP-TLS]. Shoutout to the folks who came before ๐ŸŒˆ

14. References ๐Ÿ“š

14.1. Normative References ๐Ÿง 

  • [RFC-MIME] Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies", RFC 2045, November 1996.
  • [RFC-ABNF] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", RFC 2234, November 1997.
  • [RFC-SRV] Gulbrandsen, A., Vixie, P., and L. Esibov, "A DNS RR for specifying the location of services (DNS SRV)", RFC 2782, February 2000.
  • [RFC-SMTP] Klensin, J., "Simple Mail Transfer Protocol", RFC 2821, April 2001.
  • [RFC-SMTPEXT] Myers, J., "SMTP Service Extension for Authentication", RFC 2554, March 1999.
  • [RFC-MTRK-ESMTP] Allman, E. and T. Hansen, "SMTP Service Extension for Message Tracking", RFC 3885, September 2004.
  • [RFC-MTRK-MODEL] Hansen, T., "Message Tracking Models and Requirements", RFC 3885, September 2004.
  • [RFC-MTRK-TSN] Allman, E., "The Message/Tracking-Status MIME Extension", RFC 3886, September 2004.
  • [RFC-URI] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform Resource Identifiers (URI): Generic Syntax", RFC 2396, August 1998.
  • [TLS] Dierks, T. and C. Allen, "The TLS Protocol Version 1.0", RFC 2246, January 1999.

14.2. Informational References

okay bestie, these are the bonus reads ๐Ÿ“šโœจ You don't need them to implement anything, but the spec leans on them a lot, so they're worth knowing about ๐Ÿค“

[BCP35]            Petke, R. and I. King, "Registration Procedures
                   for URL Scheme Names", BCP 35, RFC 2717, November
                   1999.

[RFC-SHA1]         Eastlake, D. and P. Jones, "US Secure Hash
                   Algorithm 1 (SHA1)", RFC 3174, September 2001.

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

[RFC-SMTP-TLS]     Hoffman, P., "SMTP Service Extension for Secure
                   SMTP over Transport Layer Security", RFC 3207,
                   February 2002.

[RFC-X509]         Housley, R., Polk, W., Ford, W. and D. Solo,
                   "Internet X.509 Public Key Infrastructure
                   Certificate and Certificate Revocation List (CRL)
                   Profile", RFC 3280, April 2002.

[POP3]             Myers, J. and M. Rose, "Post Office Protocol -
                   Version 3", STD 53, RFC 1939, May 1996.

[NNTP]             Kantor, B. and P. Lapsley, "Network News Transfer
                   Protocol", RFC 977, February 1986.

Appendix A. MTQP URI Registration Template โœจ

this is the registration form for the mtqp URI scheme ๐ŸŽ€ Every field points back to a section of this document, so it's basically a cheat sheet ๐Ÿ’…

Scheme name: mtqp

Scheme syntax: see section 9.1

Character encoding considerations: see section 9.4

Intended usage: see section 9.3

Applications and/or protocols which use this scheme: MTQP

Interoperability considerations: as specified for MTQP

Security considerations: see section 11.0

Relevant publications: [RFC-MTRK-ESMTP], [RFC-MTRK-MODEL],
[RFC-MTRK-TSN]

Contact: MSGTRK Working Group

Author/Change Controller: IESG

Author's Address ๐Ÿงš

this is where you can find the author, Tony Hansen, over at AT&T Laboratories ๐Ÿ’œ

Tony Hansen
AT&T Laboratories
Middletown, NJ 07748
USA

Phone: +1.732.420.8934
EMail: tony+msgtrk@maillennium.att.com

the Internet Society owns the copyright here (2004) ๐Ÿ“œ This document is covered by the rights, licenses and restrictions in BCP 78, and except where BCP 78 says otherwise, the authors keep all their rights ๐Ÿ”’

Now the legal fine print, which I'm keeping complete because it matters ๐Ÿ™ˆ

This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/S HE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY 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 doesn't take a position on whether any patents or other rights covering this technology are valid or how wide they are, and it doesn't claim to have checked for any of them either ๐Ÿซถ You can find the IETF's rules about rights in IETF Documents in BCP 78 and BCP 79.

Copies of IPR disclosures sent to the IETF Secretariat, plus any promises of licenses, or the results of any attempt to get a general license for implementers or users, are available from the IETF's online IPR repository at http://www.ietf.org/ipr.

The IETF also invites anyone to point out any copyrights, patents, patent applications or other proprietary rights that might cover technology needed to implement this standard. Send that info to the IETF at ietf-ipr@ietf.org ๐Ÿ“ฌ

Acknowledgement ๐Ÿ’–

the RFC Editor function is currently funded by the Internet Society, and we love that for them ๐Ÿ‘‘

๐Ÿ“ฆ where this page comes from