flashmob / go-guerrilla

Mini SMTP server written in golang
MIT License
2.79k stars 366 forks source link

Quirky support for “address-literal” mailboxes. #197

Closed issuefiler closed 4 years ago

issuefiler commented 5 years ago

RFC 5321

4.1.3.  Address Literals

   Sometimes a host is not known to the domain name system and
   communication (and, in particular, communication to report and repair
   the error) is blocked.  To bypass this barrier, a special literal
   form of the address is allowed as an alternative to a domain name.
   For IPv4 addresses, this form uses four small decimal integers
   separated by dots and enclosed by brackets such as [123.255.37.2],
   which indicates an (IPv4) Internet Address in sequence-of-octets
   form.  For IPv6 and other forms of addressing that might eventually
   be standardized, the form consists of a standardized "tag" that
   identifies the address syntax, a colon, and the address itself, in a
   format specified as part of the relevant standards (i.e., RFC 4291
   [8] for IPv6).

   Specifically:

   IPv4-address-literal  = Snum 3("."  Snum)

   IPv6-address-literal  = "IPv6:" IPv6-addr

   General-address-literal  = Standardized-tag ":" 1*dcontent

   Standardized-tag  = Ldh-str
                     ; Standardized-tag MUST be specified in a
                     ; Standards-Track RFC and registered with IANA

   dcontent       = %d33-90 / ; Printable US-ASCII
                  %d94-126 ; excl. "[", "\", "]"

   Snum           = 1*3DIGIT
                  ; representing a decimal integer
                  ; value in the range 0 through 255

   IPv6-addr      = IPv6-full / IPv6-comp / IPv6v4-full / IPv6v4-comp

   IPv6-hex       = 1*4HEXDIG

   IPv6-full      = IPv6-hex 7(":" IPv6-hex)

   IPv6-comp      = [IPv6-hex *5(":" IPv6-hex)] "::"
                  [IPv6-hex *5(":" IPv6-hex)]
                  ; The "::" represents at least 2 16-bit groups of
                  ; zeros.  No more than 6 groups in addition to the
                  ; "::" may be present.

   IPv6v4-full    = IPv6-hex 5(":" IPv6-hex) ":" IPv4-address-literal

   IPv6v4-comp    = [IPv6-hex *3(":" IPv6-hex)] "::"
                  [IPv6-hex *3(":" IPv6-hex) ":"]
                  IPv4-address-literal
                  ; The "::" represents at least 2 16-bit groups of
                  ; zeros.  No more than 4 groups in addition to the
                  ; "::" and IPv4-address-literal may be present.
   address-literal  = "[" ( IPv4-address-literal /
                    IPv6-address-literal /
                    General-address-literal ) "]"
                    ; See Section 4.1.3

   Mailbox        = Local-part "@" ( Domain / address-literal )

A test for address-literal mailboxes

Preset

"allowed_hosts": ["1.1.1.1", "2001:db8::ff00:42:8329"]

Test cases

Case # 1 🆗

Parsed as an address-literal, accepted; good.

rcpt to: <hi@[1.1.1.1]>
250 2.1.5 OK

Case # 2 ❓

Parsed as a Domain, not an address-literal. Not sure if it’s valid. Related: Postfix’s resolve_numeric_domain configuration.

rcpt to: <hi@1.1.1.1>
250 2.1.5 OK

Case # 3 ❓

Parsed as an address-literal; accepted; okay, but not sure if the IPv6: prefix can be case-insensitive.

rcpt to: <hi@[ipv6:2001:DB8::FF00:42:8329]>
250 2.1.5 OK

Case # 4 ❌

Parsed as an address-literal; the same IPv6, but got refused due to its different form; bad.

rcpt to: <hi@[IPv6:2001:0db8:0000:0000:0000:ff00:0042:8329]>
454 4.1.1 Error: Relay access denied: 2001:0db8:0000:0000:0000:ff00:0042:8329
flashmob commented 5 years ago

For case 2, it's valid syntactically, but of course the domain is invalid. Looks like the Postfix option might be seldom-used bloat? (disabled by default).

Case 3: Yes, the RFC has mixed-case "IPv6". However, the case-insensitivity was added because for example, Go's Dial function is all lower case (although different syntax too) https://golang.org/src/net/dial.go?s=9799:9847#L306

Todo:

flashmob commented 4 years ago

Actually, this can be solved easier than written above. No need to use a separate allowsIP function, can reuse existing lookup, just normalize when an ip is detected...

flashmob commented 4 years ago

Fixed in #202