RFC 5825

Displaying Downgraded Messages for Email Address Internationalization

πŸ“… published April 2010, from ietf

Displaying Downgraded Messages for Email Address Internationalization πŸŽ€

Okay bestie, this is RFC 5825 πŸ¦‹ Written by K. Fujiwara (JPRS) and B. Leiba (Huawei Technologies), dated April 2010. It's an Experimental doc, so it's published for examination and experimenting, not as a full Internet Standard πŸ§ͺ The ISSN is 2070-1721. The header doesn't list any RFCs it obsoletes or updates, so it's doing its own thing πŸ’…

Abstract 🌸

This one describes a method for displaying downgraded messages that originally had internationalized email addresses or internationalized header fields 🌈

Status of This Memo πŸ“œ

So this doc is not an Internet Standards Track spec. It's published for examination, experimental implementation, and evaluation πŸ§ͺ

It defines an Experimental Protocol for the Internet community. It's a product of the Internet Engineering Task Force (IETF), it represents the IETF community's consensus, it got public review, and the Internet Engineering Steering Group (IESG) approved it for publication. Not every IESG-approved doc is a candidate for any level of Internet Standard, so check Section 2 of RFC 5741 if you're curious πŸ‘€

For the current status, any errata, and how to give feedback, go to http://www.rfc-editor.org/info/rfc5825 πŸ’–

Copyright (c) 2010 IETF Trust and the persons identified as the document authors. All rights reserved ✨

This doc is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as they were in effect on the publication date. Please actually read those, because they spell out your rights and restrictions for this doc πŸ“– Any Code Components pulled out of this doc must include Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they come with no warranty, as the Simplified BSD License describes πŸ”₯

Table of Contents πŸ—‚οΈ

1. Introduction ....................................................2
2. Terminology .....................................................2
3. Converting Downgraded Message Headers for Display ...............3
   3.1. Considerations .............................................3
   3.2. The Process ................................................3
        3.2.1. No Reconstruction of the Envelope
               Information Preservation ............................4
        3.2.2. Reconstructing the Address Header Fields'
               Preservation Header .................................4
        3.2.3. The Unknown Header Fields' Preservation
               Header Fields .......................................5
4. Security Considerations .........................................6
5. Acknowledgements ................................................6
6. References ......................................................6
   6.1. Normative References .......................................6
   6.2. Informative References .....................................7
Appendix A.  Examples ..............................................8
  A.1.  Displaying Example ........................................11

1. Introduction πŸ¦‹

So the Email Address Internationalization (UTF8SMTP) extension doc set [RFC4952] [RFC5336] [RFC5335] [RFC5337] expands email address structure, syntax, and email header format 🌷 To keep internationalized email messages from getting rejected, the downgrading mechanism [RFC5504] turns an internationalized message into a traditional email message whenever a server in the delivery path doesn't support the UTF8SMTP extension 🫧 The downgraded message is a traditional email message, except it has "Downgraded-" header fields πŸ’…

Here's the tea: a perfect reverse of downgrading doesn't exist 😭 The encoding defined in [RFC2047] isn't exactly reversible, and downgrading a "Received" header field may remove FOR clause information. The restoration should happen once, at the final destination of the downgraded message, like a Mail User Agent (MUA) or an IMAP server πŸ“¬ This doc describes the restoration methods for displaying downgraded messages in MUAs πŸŽ€

2. Terminology 🧚

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this doc are to be read as described in RFC 2119 [RFC2119] πŸ”‘

Specialized terms are defined in the EAI overview [RFC4952], or in [RFC5321], [RFC5322], or the MIME docs [RFC2045], [RFC2047], [RFC2183], and [RFC2231] πŸ“š

This doc depends on [RFC5335] and [RFC5504], so the key words used in those docs are used here too 🫢

The term "MIME decode" covers both "encoded-word" decoding, defined by [RFC2047], and MIME parameter value decoding, defined by [RFC2231] πŸ’œ

3. Converting Downgraded Message Headers for Display ✨

3.1. Considerations 🌈

The order of some header fields (like the "Resent-*" fields) matters a lot πŸ‘€ When you regenerate the original fields from the downgraded ones, you MUST NOT reorder the fields 🚫

To regenerate a field from a specific downgraded header field, you have to find the matching replacement in the current message. If the matching field can't be found, the downgraded header field can't be regenerated or used 😭

If reconstructing a particular downgraded header field fails, both header fields (the "downgraded-YYY" header field and the "YYY" header field) SHOULD be left in the message as they are 🌸 The MUA MAY choose to tell the user what happened (see the "Security Considerations" section) πŸ”₯

3.2. The Process πŸ”₯

A MUA MAY decode and regenerate the original header fields of the message. Mail Transport Agents (MTAs) and Mail Delivery Agents (MDAs) SHOULD NOT try this. It SHOULD be left to the MUA πŸ’… This procedure can approximately reverse the downgrade process, but it won't always rebuild the original header fields exactly 🫧

Section 3 of [RFC5504] describes three types of downgraded header fields πŸ¦‹

1. "Envelope Information Preservation Header Fields", described in RFC5504 Section 3.1 and in Section 3.2.1, below. 2. "Address Header Fields' Preservation Header Fields", described in RFC5504 Section 3.2 and in Section 3.2.2, below. 3. "Unknown Header Fields' Preservation Header Fields", described in RFC5504 Section 3.3 and in Section 3.2.3, below.

After you process the downgraded header fields, decode all header fields as described in [RFC2047] and [RFC2231] 🧠

3.2.1. No Reconstruction of the Envelope Information Preservation Header Fields πŸ™ˆ

Envelope information preservation header fields are new fields that might have been added by the downgrade process 🌱 They don't represent fields that appeared in the original message, so this process doesn't apply to them πŸ’–

3.2.2. Reconstructing the Address Header Fields' Preservation Header Fields πŸŽ€

Reconstructing address header fields' preservation header fields is OPTIONAL, and a decision MAY be made on each field individually 🫢 It might be less important to process the Resent-* header fields, so an implementation MAY choose to skip those 🌷

To build a displayable copy of a header field from one of these downgraded header fields, follow this procedure 🧁

  1. In an edit buffer, create a new header field:
    • (a) For the field name, remove the Downgraded- prefix from the downgraded field name. For example, Downgraded-From becomes From, and Downgraded-Resent-To becomes Resent-To.
    • (b) For the field value, decode the MIME-encoded value of the downgraded field according to [RFC2047].
  2. Apply "Email Header Fields Downgrading", defined in Section 5 of [RFC5504], to the field in the edit buffer. This generates two header fields: an ASCII header field and the Address Header Fields' Preservation Header Field. Put the generated ASCII header field into comparison buffer 1.
  3. Canonicalize the header field in comparison buffer 1:
    1. Unfold all header field continuation lines as described in [RFC5322].
    2. Make sure there's one space character before and one after the <mailbox-list> separator ",". If a space character is missing, insert one.
    3. Make sure there's one space character before and one after each <comment>. If a space character is missing, insert one.
    4. Decode each <encoded-word> whose charset is "UTF-8".
    5. Convert all sequences of one or more WSP characters to a single space character. WSP characters here include those before and after a line-folding boundary.
    6. Delete all WSP characters at the end of each unfolded header field value.
    7. Delete any WSP characters remaining before and after the colon separating the header field name from the header field value, keeping the colon separator.
  4. Find the first instance of the corresponding field in the message's headers.
  5. Canonicalize the located field as in step 3, and put the result into comparison buffer 2.
  6. Compare the header field in comparison buffer 1 with the header field in comparison buffer 2. If they match, go to step 8.
  7. Find the next instance of the corresponding field in the message's headers. If one is found, go to step 5. If none is found, stop: you can't use this downgraded field because you can't find its replacement in the message 😭
  8. Replace the located header field with the one in the edit buffer. You MUST NOT reorder the header fields when you do this. It's important to replace the field in the same place 🫧 Then remove the target downgraded header field from the message header ✨

3.2.3. The Unknown Header Fields' Preservation Header Fields 🌈

The unknown header fields' preservation header fields SHOULD be left as they are, unless the MUA has special knowledge of a particular field πŸ¦‹ An MUA with that knowledge MAY use a procedure similar to the one in Section 3.2.2, above, for the fields it knows about. (Heads up: the whitespace canonicalization rule might not apply to some header fields πŸ‘€)

4. Security Considerations ✨

Okay bestie, info in any email header should usually be treated with some suspicion 🧐, but email systems have a bunch of tricks to make it more trustworthy πŸ”. For example, an organization's boundary MTA can rewrite "From" lines so messages from outside the org are easily spotted πŸ‘€. Because of that rewriting, the "From" header field might not match the "Downgraded-From" header field πŸ™ƒ.

A MUA MAY emphasize bogus or broken address header fields' preservation header fields found in step 7 of Section 3.2.2 πŸ’….

Hiding the info from the actual header fields when using the "Downgraded-" header fields doesn't cause any loss of information, as long as generating MIME-decoded header fields in step 1 of Section 3.2.2 and the comparison done in step 7 both go through 🫢. To make sure nothing gets lost, a MUA SHOULD have a function that uses the actual message that was received (with or without MIME decoding) to render the message. No cap, that's the safety net you want 🌸.

We've been focusing here on the issues with displaying downgraded messages. For more on downgraded and internationalized messages in general, check the "Security Considerations" section in [RFC5504] and [RFC4952] πŸ“š.

5. Acknowledgements

This document was split off from [RFC5504] πŸ¦‹. Both were developed in the EAI WG, and they got some seriously iconic feedback from John Klensin, Harald Alvestrand, Chris Newman, Randall Gellens, Charles Lindsey, Marcos Sanz, Alexey Melnikov, Pasi Eronen, Frank Ellermann, Edward Lewis, S. Moonesamy, and JET members πŸ‘‘πŸ’œ.

6. References

6.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.

[RFC2183]  Troost, R., Dorner, S., and K. Moore, "Communicating
           Presentation Information in Internet Messages: The
           Content-Disposition Header Field", RFC 2183, August 1997.

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

[RFC4952]  Klensin, J. and Y. Ko, "Overview and Framework for
           Internationalized Email", RFC 4952, July 2007.

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

[RFC5335]  Abel, Y., "Internationalized Email Headers", RFC 5335,
           September 2008.

[RFC5504]  Fujiwara, K. and Y. Yoneya, "Downgrading Mechanism for
           Email Address Internationalization", RFC 5504, March 2009.

6.2. Informative References

[RFC5321]  Klensin, J., "Simple Mail Transfer Protocol", RFC 5321,
           October 2008.

[RFC5336]  Yao, J. and W. Mao, "SMTP Extension for Internationalized
           Email Addresses", RFC 5336, September 2008.

[RFC5337]  Newman, C. and A. Melnikov, "Internationalized Delivery
           Status and Disposition Notifications", RFC 5337,
           September 2008.

Appendix A. Examples πŸŽ€

This section shows an example of displaying a downgraded message. First up is the original UTF8SMTP message next to its downgraded version. The example comes from "Example 1" of [RFC5504], and three header fields, "Unknown-Field", "Resent-From", and "Resent-To", get added. The example UTF8SMTP message is in Figure 1 🌈.

Message-Id: MESSAGE_ID
Mime-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 8bit
Subject: NON-ASCII-SUBJECT
Unknown-Field: NON-ASCII-Unknown
From: DISPLAY-local <NON-ASCII-local@example.com
 <ASCII-local@example.com>>
To: DISPLAY-remote1 <NON-ASCII-remote1@example.net
 <ASCII-remote1@example.net>>
Cc: DISPLAY-remote2 <NON-ASCII-remote2@example.org>
Resent-From: DISPLAY-remote1 <NON-ASCII-remote1@example.net
 <ASCII-remote1@example.net>>
Resent-To: DISPLAY-reto <NON-ASCII-reto@example.net
 <ASCII-reto@example.net>>
Date: DATE

MAIL_BODY

                     Figure 1: Original message

A delivered downgraded message is in Figure 2 🧚. The final destination MTA adds a Return-Path header, and some "Received" header fields may get added too πŸ“¬.

Return-Path: <ASCII-local@example.com>
Received: ...
Downgraded-Mail-From: =?UTF-8?Q?<NON-ASCII-local@example.com_?=
 =?UTF-8?Q?<ASCII-local@example.com>>?=
Downgraded-Rcpt-To: =?UTF-8?Q?<NON-ASCII-remote1@example.net_?=
 =?UTF-8?Q?<ASCII-remote1@example.net>>?=
Message-Id: MESSAGE_ID
Mime-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 8bit
Subject: =?UTF-8?Q?NON-ASCII-SUBJECT?=
Downgraded-Unknown-Field: =?UTF-8?Q?NON-ASCII-Unknown?=
From: =?UTF-8?Q?DISPLAY-local?= <ASCII-local@example.com>
Downgraded-From: =?UTF-8?Q?DISPLAY-local_<NON-ASCII-local@example.com_?=
 =?UTF-8?Q?<ASCII-local@example.com>>?=
To: =?UTF-8?Q?DISPLAY-remote1?= <ASCII-remote1@example.net>
Downgraded-To: =?UTF-8?Q?DISPLAY-remote1_?=
 =?UTF-8?Q?<NON-ASCII-remote1@example.net_<ASCII-remote1@example.net>>?=
Cc: =?UTF-8?Q?DISPLAY-remote2?= Internationalized address
 =?UTF-8?Q?NON-ASCII-remote2@example.org?= removed:;
Downgraded-Cc: =?UTF-8?Q?DISPLAY-remote2_?=
 =?UTF-8?Q?<NON-ASCII-remote2@example.org>?=
Resent-From: =?UTF-8?Q?DISPLAY-remote1?= <ASCII-remote1@example.net>
Downgraded-Resent-From: =?UTF-8?Q?DISPLAY-remote1_?=
 =?UTF-8?Q?<NON-ASCII-remote1@example.net_<ASCII-remote1@example.net>>?=
Resent-To: =?UTF-8?Q?DISPLAY-reto?= <ASCII-reto@example.net>
Downgraded-Resent-To: =?UTF-8?Q?DISPLAY-reto_?=
 =?UTF-8?Q?<NON-ASCII-reto@example.net_<ASCII-reto@example.net>>?=
Date: DATE

MAIL_BODY

                    Figure 2: Downgraded message

Figure 3 shows the MIME-decoded version of Figure 2 🌸. The recipient can read the original "From", "To", "Cc", "Resent-From", "Resent-To", and "Unknown-Field" header fields as "Downgraded-From", "Downgraded-To", "Downgraded-Cc", "Downgraded-Resent-From", "Downgraded-Resent-To", and "Downgraded-Unknown-Field" header fields πŸ’–.

Return-Path: <ASCII-local@example.com>
Received: ...
Downgraded-Mail-From: <NON-ASCII-local@example.com
 <ASCII-local@example.com>>
Downgraded-Rcpt-To: <NON-ASCII-remote1@example.net
 <ASCII-remote1@example.net>>
Message-Id: MESSAGE_ID
Mime-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 8bit
Subject: NON-ASCII-SUBJECT
Downgraded-Unknown-Field: NON-ASCII-Unknown
From: DISPLAY-local <ASCII-local@example.com>
Downgraded-From: DISPLAY-local <NON-ASCII-local@example.com
 <ASCII-local@example.com>>
To: DISPLAY-remote1 <ASCII-remote1@example.net>
Downgraded-To: DISPLAY-remote1 <NON-ASCII-remote1@example.net
 <ASCII-remote1@example.net>>
Cc: DISPLAY-remote2 Internationalized address
 NON-ASCII-remote2@example.org removed:;
Downgraded-Cc: DISPLAY-remote2 <NON-ASCII-remote2@example.org>
Resent-From: DISPLAY-remote1 <ASCII-remote1@example.net>
Downgraded-Resent-From: DISPLAY-remote1
 <NON-ASCII-remote1@example.net <ASCII-remote1@example.net>>
Resent-To: DISPLAY-reto <ASCII-reto@example.net>
Downgraded-Resent-To: DISPLAY-reto
 <NON-ASCII-reto@example.net <ASCII-reto@example.net>>
Date: DATE

MAIL_BODY

                   Figure 3: MIME-decoded message

A.1. Displaying Example πŸ”₯

This example shows how to display the message in Figure 2, above, using the process defined in Section 3. To keep things simple, we'll reconstruct all the applicable fields at once πŸ’….

Selecting all the Downgraded-* fields gives us this:

Downgraded-Mail-From: =?UTF-8?Q?<NON-ASCII-local@example.com_?=
 =?UTF-8?Q?<ASCII-local@example.com>>?=
Downgraded-Rcpt-To: =?UTF-8?Q?<NON-ASCII-remote1@example.net_?=
 =?UTF-8?Q?<ASCII-remote1@example.net>>?=
Downgraded-Unknown-Field: =?UTF-8?Q?NON-ASCII-Unknown?=
Downgraded-From: =?UTF-8?Q?DISPLAY-local_<NON-ASCII-local@example.com_?=
 =?UTF-8?Q?<ASCII-local@example.com>>?=
Downgraded-To: =?UTF-8?Q?DISPLAY-remote1_?=
 =?UTF-8?Q?<NON-ASCII-remote1@example.net_<ASCII-remote1@example.net>>?=
Downgraded-Cc: =?UTF-8?Q?DISPLAY-remote2_?=
 =?UTF-8?Q?<NON-ASCII-remote2@example.org>?=
Downgraded-Resent-From: =?UTF-8?Q?DISPLAY-remote1_?=
 =?UTF-8?Q?<NON-ASCII-remote1@example.net_<ASCII-remote1@example.net>>?=
Downgraded-Resent-To: =?UTF-8?Q?DISPLAY-reto_?=
 =?UTF-8?Q?<NON-ASCII-reto@example.net_<ASCII-reto@example.net>>?=

                  Figure 4: Downgraded header fields

Two of these fields, "Downgraded-Mail-From" and "Downgraded-Rcpt-To", are envelope information preservation header fields, so they won't be reconstructed πŸ™…β€β™€οΈ. "Downgraded-Unknown-Field" is an unknown header fields' preservation header field, so it won't be reconstructed either πŸ™ˆ. That leaves the address header fields' preservation header fields to be reconstructed ✨.

Downgraded-From: =?UTF-8?Q?DISPLAY-local_<NON-ASCII-local@example.com_?=
 =?UTF-8?Q?<ASCII-local@example.com>>?=
Downgraded-To: =?UTF-8?Q?DISPLAY-remote1_?=
 =?UTF-8?Q?<NON-ASCII-remote1@example.net_<ASCII-remote1@example.net>>?=
Downgraded-Cc: =?UTF-8?Q?DISPLAY-remote2_?=
 =?UTF-8?Q?<NON-ASCII-remote2@example.org>?=
Downgraded-Resent-From: =?UTF-8?Q?DISPLAY-remote1_?=
 =?UTF-8?Q?<NON-ASCII-remote1@example.net_<ASCII-remote1@example.net>>?=

Okay so we're picking up right where Figure 5 left off, bestie πŸ’– Here's the rest of the reconstruction:

Downgraded-Resent-To: =?UTF-8?Q?DISPLAY-reto_?=
 =?UTF-8?Q?<NON-ASCII-reto@example.net_<ASCII-reto@example.net>>?=

Figure 5: Header fields for the reconstruction πŸŽ€

Okay, now it's time to run step 1 on those downgraded header fields from Figure 5 and make an edit buffer 🧚 Here's what that looks like:

From: DISPLAY-local <NON-ASCII-local@example.com
 <ASCII-local@example.com>>
To: DISPLAY-remote1 <NON-ASCII-remote1@example.net
 <ASCII-remote1@example.net>>
Cc: DISPLAY-remote2 <NON-ASCII-remote2@example.org>
Resent-From: DISPLAY-remote1
 <NON-ASCII-remote1@example.net <ASCII-remote1@example.net>>
Resent-To: DISPLAY-reto
 <NON-ASCII-reto@example.net <ASCII-reto@example.net>>

Figure 6: edit buffer: Output of step 1 πŸ’…

Next, we apply "Email Header Fields Downgrading" to that edit buffer πŸ¦‹ It spits out downgraded ASCII header fields AND the address header fields' preservation header fields. Fun fact: the preservation ones are the exact same as the downgraded header fields 🫢 So the downgraded ones go into "comparison buffer 1" and we're good to go:

From:DISPLAY-local <ASCII-local@example.com>
To:DISPLAY-remote1 <ASCII-remote1@example.net>
Cc:DISPLAY-remote2 Internationalized address
 NON-ASCII-remote2@example.org removed:;
Resent-From:DISPLAY-remote1 <ASCII-remote1@example.net>
Resent-To:DISPLAY-reto <ASCII-reto@example.net>

Figure 7: comparison buffer 1: Output of step 3 😭

Now we do steps 4 to 6, which is the comparison, one header field at a time πŸ‘‘ Five header fields, "From", "To", "Cc", "Resent-From" and "Resent-To", all match, so we jump straight to step 8. Step 7 (iteration) is giving "not needed here" energy, so we skip it πŸ™ˆ

Time for step 8! We replace all the applicable fields and keep them in the same order 🌈 After that, we run MIME decoding on everything so it's readable for display. Periodt ✨

Return-Path: <ASCII-local@example.com>
Received: ...
Downgraded-Mail-From: <NON-ASCII-local@example.com
 <ASCII-local@example.com>>
Downgraded-Rcpt-To: <NON-ASCII-remote1@example.net>
 <ASCII-remote1@example.net>
Message-Id: MESSAGE_ID
Mime-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 8bit
Subject: NON-ASCII-SUBJECT
Downgraded-Unknown-Field: NON-ASCII-Unknown
From: DISPLAY-local <NON-ASCII-local@example.com
 <ASCII-local@example.com>>
To: DISPLAY-remote1 <NON-ASCII-remote1@example.net
 <ASCII-remote1@example.net>>
Cc: DISPLAY-remote2 <NON-ASCII-remote2@example.org>
Resent-From: DISPLAY-remote1 <NON-ASCII-remote1@example.net
 <ASCII-remote1@example.net>>
Resent-To: DISPLAY-reto <NON-ASCII-reto@example.net
 <ASCII-reto@example.net>>
Date: DATE

Figure 8: The final result πŸ“

So in this simple example, some of the original header fields are back to showing their original form, which is so satisfying πŸ₯Ή If you compare Figure 1 with Figure 8, the differences are just Return-Path, Downgraded-Mail-From, Downgraded-Rcpt-To, and Downgraded-Unknown-Field. Everything else is restored, no cap πŸ’œ


Authors' Addresses

Kazunori Fujiwara
Japan Registry Services Co., Ltd.
Chiyoda First Bldg. East 13F, 3-8-1 Nishi-Kanda
Chiyoda-ku, Tokyo  101-0065
Japan

Phone: +81-3-5215-8451
EMail: fujiwara@jprs.co.jp


Barry Leiba
Huawei Technologies

Phone: +1 646 827 0648
EMail: barryleiba@computer.org
URI:   http://internetmessagingtechnology.org/

And that's the whole doc, bestie! Two legends who built this 🫢🌸

πŸ“¦ where this page comes from