jakartaee / mail-api

Jakarta Mail Specification project
https://jakartaee.github.io/mail-api
Other
244 stars 101 forks source link

Improve support for Email Address Internationalization (EAI) #589

Open j-bernard opened 2 years ago

j-bernard commented 2 years ago

EAI is defined in RFC6531 and is supported by Jakarta Mail with the SMTPUTF8 extension but some email addresses domains are considered invalid while they shouldn't when creating InternetAddress. To fully support EAI, InternetAddress.checkAddress should be fixed.

We made some tests with various valid email addresses and noticed the following elements:

The local part is correctly handled in our test cases.

In order to fix the domain part handling, InternetAddress.checkAddress should implement IDNA 2008 support as defined in RFC5891, an easy fix is to check the conversion of the domain to A-label with ICU4j that offers a good compliance with IDNA 2008.

Our test were done on Android and written in Kotlin with Jakarta version 2.0.1 but platform and language should not change anything here.

Here is a Kotlin snippet to check IDN conversion to A-label:

boolean isDomainValid(String domain) {
    int flags = IDNA.CHECK_BIDI | IDNA.CHECK_CONTEXTJ | IDNA.CHECK_CONTEXTO | IDNA.NONTRANSITIONAL_TO_ASCII | IDNA.USE_STD3_RULES;
    IDNA idna = IDNA.getUTS46Instance(flags);
    IDNA.Info info = new IDNA.Info();
    idna.nameToASCII(domain, new StringBuilder(), info);
    return !info.hasErrors();
}
j-bernard commented 2 years ago

Examples of valid internationalized domains names as per IDNA 2008 but rejected by InternetAddress.checkAddress:

jmehrens commented 1 year ago

We might be able to use the java.net.IDN class included with the JDK to improve this.

j-bernard commented 1 year ago

I didn't suggest using it because it implements an old IDNA standard (IDNA 2003), so ICU is better for conformance.

jmehrens commented 1 year ago

@lukasj The suggestion is to use icu4j as the validation. Looks like the license file is here: https://github.com/unicode-org/icu/blob/main/icu4c/LICENSE

What are your thoughts on referencing this library? Do we want to just make the InternetAddress have some sort of service lookup instead for validation?

lukasj commented 1 year ago

The only currently allowed dependency is Java SE or other jakarta API; dependency on 3rd party/non-jakarta library is not allowed

j-bernard commented 1 year ago

So it looks like, as you suggested, java.net.IDN would be your best option. It won't offer full compliance with the latest standard but IDNA 2003 is more permissive than IDNA 2008 and therefore would correctly handle valid Unicode domains where currently some are rejected.

jmehrens commented 1 year ago

Looks like we have to use the system property mail.mime.allowutf8 or create new system property should be created to deal with using old and new methods of address domain validation.