Skip to content

Parse rfc6532 addresses - #3130

Open
chibenwa wants to merge 30 commits into
apache:masterfrom
chibenwa:parse-rfc6532-addresses
Open

Parse rfc6532 addresses#3130
chibenwa wants to merge 30 commits into
apache:masterfrom
chibenwa:parse-rfc6532-addresses

Conversation

@chibenwa

Copy link
Copy Markdown
Contributor

No description provided.

chibenwa and others added 26 commits September 3, 2026 10:56
This changes the handling of some noncompliant IMAP clients, which James
would not tolerate before.
Application-layer code often assumes that addresses can be compared using
String.equalsIgnoreCase(), and some also uses regular expressions or
substring matching on addresses. This commit provides addresses to
upper-layer code in their UTF8 form, so that kind of code continues to
work.

This might also have security implications: If upper-layer code can be
confused about whether two addresses are the same, that sounds as if an
attacker could exploit the confusion. This change should block the
possibility.
RFC 6532 says we SHOULD do this and JAMES is generally very careful, so I
did this as well.
…etc.

This should not make a difference, but a sufficiently inventive attacker
might combine it with something to confuse some code...
Once the server advertises UTF8=ACCEPT, angus-mail enables it and then takes
its supportsUtf8() branch in IMAPProtocol.search(), which passes a null charset
down to Argument.writeString(String) and encodes the search strings with
ASCIIUtility.getBytes() -- one truncated byte per char. "天天向上" reaches the
server as 29 29 11 0A, so the criterion is destroyed client-side before it hits
the wire and no server-side decoding can recover it. Same in angus-mail 2.0.5,
and there is no property to keep the client from enabling the capability.

Send the RFC 6855 wire form ourselves instead: UTF-8 octets in literals, plus a
quoted-string variant. These fail against consumeLiteral()'s former US-ASCII
decoding, so they cover the gap they were written for.
@chibenwa
chibenwa force-pushed the parse-rfc6532-addresses branch from 2a4b7ca to 1e8e1e4 Compare September 3, 2026 08:56
@chibenwa

chibenwa commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

(
Simple master rebase, no changes.
The ci failed with build compilation.
I suppose this is due to recent master changes causing compilation issue atop this branch: conflicts but without merge conflict.
)

Comment thread mailbox/opensearch/src/test/resources/eml/cve-2024-23184.eml Outdated
Comment thread core/src/test/java/org/apache/james/core/DomainTest.java Outdated
@chibenwa

chibenwa commented Sep 7, 2026

Copy link
Copy Markdown
Contributor Author

Please address your comments @Arsnael

@chibenwa

chibenwa commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

@arnt no objection with that one?

Also may I ask for a ICLA ? That's a major contribution, as per ASF rule we would need IP clearance.

https://www.apache.org/licenses/contributor-agreements.html

Thanks by advance

@arnt

arnt commented Sep 8, 2026

Copy link
Copy Markdown

I started the day with opening tabs for my open PRs, which are many and the James PR is big ;) The only reason I could write the james patches was that several colleagues were travelling so I had unexpected peace.

Not done with the PR catching-upping, today's my first pass since June. Still have a few tabs to read and close, and James is one.

I'll send the corporate CLA to the legal team at work; it should not be a problem (apart from the GPG invocations, which I am afraid the legal team will leave to me).

I need lunch now, will review this after lunch.

@@ -84,24 +101,59 @@ void receivedMessagesShouldContainDeliveredToHeaders() throws Exception {

@Test
void receivedMessagesShouldContainDeliveredToHeadersI8N() throws Exception {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that i8n instead of i18n?

* mime4j then falls back to us-ascii. Only the RFC 3798 form honours the
* declared charset.
*/
private static String reportCharset(Entity entity) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a comment. The code is correct, I think.

There a chance that an RFC will appear sometime in 2027/8 that deprecates message/global and says to use message/rfc822 for everything. Ditto text/globalheaders or whatever it was.

I think generating message/global is good, for now, but on the parse side I might lean towards accepting UTF8 in message/rfc822 already. Not 100% sure. I might be strict there too, it depends on the code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the notice. We will follow upcoming RFCs when published I presume.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

I think my brain has found an opinion: at this point it's best to always follow RFC 6533 when generating, and mostly when parsing (unless that's too complicated and requires too much code).

}

@Test
void asciiEmailWithSmtpUtf8ShouldBeReceived() throws Exception {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this test?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simply that we can use ascii addresses with SMTPUTF8

Maybe not the most useful of a test but defnitly harmless.

// Left alone for the ASCII envelopes that make up the bulk of the
// traffic, so they neither change behaviour nor trip Angus' "allowutf8
// set but server doesn't advertise SMTPUTF8" log line. The pool clears
// the property again when the session is passivated.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point.

Looking at all this, I wonder why the tests passed.

*
* UTF-8 is handled at {@link TestIMAPClient}'s own boundary instead: see
* {@link TestIMAPClient#asOctets(String)} and {@link TestIMAPClient#asText(String)}.
*/

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose it has to be like that. IMAP must read octets and decode to chars in a context-sensitive manner. While I find it difficult to name the octets "ISO-8859-1", given the legacy I suppose it makes sense.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, working around our own test dependencies o_o

@arnt

arnt commented Sep 8, 2026

Copy link
Copy Markdown

Lovely work. I really am puzzled that the test suite was green after my work, before yours @chibenwa

Thanks!

@chibenwa

chibenwa commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

You are very welcome!
Thanks for embarking us in this journey, I'm pretty sure we would not have been able to do it by our own.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants