Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Message-ID #728

Open
patch-work opened this issue Apr 11, 2024 · 4 comments
Open

Message-ID #728

patch-work opened this issue Apr 11, 2024 · 4 comments
Assignees
Labels

Comments

@patch-work
Copy link

Hello,

JavaMail sends non-conformant Message-IDs that are catched by spam filters.

Be a good netizen and conform to the standard.

Thank you.

RFC-822 [pg. 30]

A domain-ref must be THE official name of a registry, network,
or host. It is a symbolic reference, within a name subdomain.

RFC-822 [pg. 23]
4.6.1. MESSAGE-ID / RESENT-MESSAGE-ID

This field contains a unique identifier (the local-part address
unit) which refers to THIS version of THIS message. The uniqueness
of the message identifier is guaranteed by the host which generates
it. This identifier is intended to be machine readable and
not necessarily meaningful to humans. A message identifier
pertains to exactly one instantiation of a particular message;
subsequent revisions to the message should each receive new message
identifiers.

RFC-822 [pp. 44-46]

addr-spec = local-part "@" domain ; global address
[...]
domain = sub-domain *("." sub-domain)
[...]
msg-id = "<" addr-spec ">" ; Unique message id optional-field = / "Message-ID" ":" msg-id[...]
sub-domain = domain-ref / domain-literal

@jmehrens
Copy link
Contributor

  1. What version of JavaMail or JakartaMail?
  2. What spam filter?
  3. What text is shown as to why it fails the spam filter rule?
  4. What are your mail session properties? You can redact the values just knowing the keys helps.

Let's create a test program to generate the Message-ID using JakartaMail 2.1.3:

public static void main(String[] args) throws Exception {
        //InetAddress.getCanonicalHostName if system property 
        //mail.mime.address.usecanonicalhostname is not forced to false
        //setting the mail.<protocol>.host does not change local address
        Properties props = new Properties();
        props.put("mail.smtp.host", "some.smtp.host");
        props.put("mail.smtps.host", "some.smtps.host");
        props.put("mail.imap.host", "some.imap.host");
        props.put("mail.imaps.host", "some.imaps.host");
        writeMessage(props);
        
        //mail.host controls the domain
        props.put("mail.host", "some.mail.host");
        writeMessage(props);
        
        //mail.from controls the domain over mail.host
        props.put("mail.from", "some@from.host");
        writeMessage(props);
    }
    
    private static void writeMessage(Properties props) throws Exception {
        MimeMessage m = new MimeMessage(Session.getInstance(props));
        m.setText("");
        m.saveChanges();
        m.writeTo(System.out);
        System.out.flush();
    }

On my machine this outputs:

Date: Sat, 13 Apr 2024 01:23:23 -0500 (CDT)
Message-ID: <429313384.0.1712989403934@devbox-VirtualBox>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Date: Sat, 13 Apr 2024 01:23:23 -0500 (CDT)
Message-ID: <1151020327.1.1712989403960@some.mail.host>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Date: Sat, 13 Apr 2024 01:23:23 -0500 (CDT)
Message-ID: <736709391.2.1712989403976@from.host>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

RFC-822 [pg. 39]

A.3.2 Using some of the additional fields
[snip]
Message-ID: some.string@SHOST

A.3.3 About as complex as you're going to get
[snip]
Message-ID: 4231.629.XYzi-What@Other-Host

From what I can tell JakartaMail matches the Appendix A.3.3 of RFC-822. If the spam rule is failing due to the domain not matching then that is a configuration problem on your sending machine where you need to correct the canonical hostname lookup or simply specify mail.host or mail.from.

More information is needed.

@jmehrens jmehrens added question Further information is requested Component: internet labels Apr 13, 2024
@jmehrens jmehrens self-assigned this Apr 13, 2024
@jmehrens
Copy link
Contributor

Related #460

@patch-work
Copy link
Author

patch-work commented Apr 16, 2024

This project changed ownership and name a few times, and old web pages are not in sync. As a result, users of the project are not necessarily using the latest version.

When I read JavaMail in the mid, then they are using an old version. Hard to say which one.

I see from your demo above that the new mid does not include a reference to the project. This makes it hard for us to help offending senders. If the name of the project is in the mid, then we know they are using a CMS of some sort, so the blame for misconfiguration is on the software house writing the CMS. If you hide the "JavaMail" or "JakartaMail" reference, it will be impossible to offer a reference like this.

Still on the new mid, it is still possible for a user to specify a non-conformant domain-ref. The software should include a runtime sanity check, and fail hard when the domain-ref is not a valid FQDN. Ideally, to solve the problem once and for all, the user should not specify any such parameter: the software ought to figure-out the public FQDN of the server and propose it to the user as sane default during initial configuration. Then the user can accept or improve the default. In this case, the configuration should mention the RFC, and include a runtime test to validate the user's value. Again, the software should fail hard in case of non compliance.

I would also put a big red notice on all old web pages of the project, pointing at the new page here.

@jmehrens
Copy link
Contributor

I see from your demo above that the new mid does not include a reference to the project. This makes it hard for us to help offending senders.

That is a ticket for the software using JakartaMail. They should be setting a User-Agent and or X-Mailer header on the MimeMessage to identify itself.

If you hide the "JavaMail" or "JakartaMail" reference, it will be impossible to offer a reference like this.

This is intentional to hide this information for security reasons:
Don't include user name in Message-ID. There still is one path that will write JakartaMail if things have gone wrong. This should be scrubbed too.

Still on the new mid, it is still possible for a user to specify a non-conformant domain-ref. The software should include a runtime sanity check, and fail hard when the domain-ref is not a valid FQDN.

There are improvements here but they are limited to syntax checking which seems reasonable. Name lookup will be avoided due to cost of the lookup which is a known problem.

Ideally, to solve the problem once and for all, the user should not specify any such parameter: the software ought to figure-out the public FQDN of the server and propose it to the user as sane default during initial configuration. Then the user can accept or improve the default.

That is a issue ticket for the software using JakartaMail. InternetAddress::getLocalAddress is what is used to compute the Message-ID. That method returns an object with a validation method. Consumers of JakartaMail can use that method to validate the Message-ID domain.

I'll look at making some of these changes.

@jmehrens jmehrens added enhancement New feature or request and removed question Further information is requested labels Apr 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants