flashmob / go-guerrilla

Mini SMTP server written in golang
MIT License
2.76k stars 361 forks source link

đź“Ś go-guerrilla cannot properly handle some valid addresses. #199

Closed issuefiler closed 4 years ago

issuefiler commented 4 years ago

https://github.com/flashmob/go-guerrilla/blob/51f7dda326b1e9878e5f679ccb34a134127951b0/mail/envelope.go#L32-L48

What this little structure can do is rather limited. Address.String() is and may be used in many places throughout the code (e.g. populating headers, storing into a database.), yet it sometimes screws things up; it is not reliable.

Test cases

Quoted Local-parts âś… VALID INPUTS

MAIL FROM: <"  yo-- man wazz'''up? surprise surprise, this is POSSIBLE@fake.com "@example.com>
250 2.1.0 OK

address-literal mailboxes âś… VALID INPUTS

MAIL FROM: <hi@[1.1.1.1]>
250 2.1.0 OK
MAIL FROM: <hi@[IPv6:2001:db8::8a2e:370:7334]>
250 2.1.0 OK
MAIL FROM: <hi@[IPv6:2001:DB8::8A2E:370:7334]>
250 2.1.0 OK

Null return-path and Postmaster recipient âś… VALID INPUTS

MAIL FROM: <>
250 2.1.0 OK
RCPT TO: <Postmaster>
250 2.1.5 OK

Null return-path (November 24, 2019.)


Notes

For the User part

  1. Minimize quoting, but preserve quotes if needed. This normalization can be done by getting the unquoted & unescaped form and quoting & escaping it if needed.
    • " al\ph\a "@grr.la should be " alpha "@grr.la.
    • "alpha"@grr.la should be alpha@grr.la.
    • "alp\h\a"@grr.la should be alpha@grr.la.

From RFC 5321:

For any purposes that require generating or comparing
   Local-parts (e.g., to specific mailbox names), all quoted forms MUST
   be treated as equivalent, and the sending system SHOULD transmit the
   form that uses the minimum quoting possible.
  1. The Postmaster mailbox is case-insensitive (by RFC). go-guerrilla may safely normalize it into Postmaster.

https://github.com/flashmob/go-guerrilla/blob/51f7dda326b1e9878e5f679ccb34a134127951b0/mail/rfc5321/parse.go#L96-L99

That’s the code doing that, but what’s inconsistent there is that it only does that when it has no host part: <posTMAstEr> → <Postmaster> but <pOstMastEr@example.com> → <pOstMastEr@example.com>. Postmaster is case-insensitive regardless of having a host. So why don’t we normalize it for the both cases? Hold on, what should we do for <"P\O\STMASTER"@example.com>?

For the Host part

If an address-literal is given, it should normalize it into bytes, and give them some appropriate brackets, [IPv6:……] or [……]. Such normalization also helps to resolve #197.

Considerations

issuefiler commented 4 years ago

Personally this is the number one priority for me. I can tackle everything else as I have my own set of processors, but this……, this, unfortunately, is a job of the core, which I have zero knowledge of. I need your insight and help on this if you don’t mind.

Unlike internationalized emails (SMTPUTF8) (#152), of which go-guerrilla lacks support to begin with, go-guerrilla doesn’t decline those addresses above (as they are valid), and it may cause some processors to malfunction.

flashmob commented 4 years ago

Thanks!

The evaluation of quoted/escaped strings in the todo list https://github.com/flashmob/go-guerrilla/issues/201 , so that one should be done first.

TODO

flashmob commented 4 years ago

Changes made in PR #202