qmailの付けるReceivedヘッダが奇妙であることは、受け取ったメールのヘッダをじっくりと眺めたことのある方ならご存じと思います。しかしながら、これがRFC違反かという点については、以下の記事で説明されているように、一応そうではないということになっていたようです。
The myth about qmail-queue’s Received: headers being non-standard
ところが、このたびSMTPの規格がRFC 2821・2822からRFC 5321・5322へと改正されました。なにぶん長大な規格ですので斜め読みですが、どうもこの改正後の規格では、Receivedヘッダの規則が厳しくなったようで、例えば次のような(おそらくqmail特有の)ReceivedヘッダはRFC違反(非準拠)となったように見えます。
Received: (qmail 42078 invoked by uid 1004); 4 Nov 2008 21:10:19 +0900
参考までに、RFC 5321・5322記載のReceivedヘッダ関連のBNFを引用しておきます。
Time-stamp-line = "Received:" FWS Stamp Stamp = From-domain By-domain Opt-info [CFWS] ";" FWS date-time ; where "date-time" is as defined in RFC 5322 [4] ; but the "obs-" forms, especially two-digit ; years, are prohibited in SMTP and MUST NOT be used. From-domain = "FROM" FWS Extended-Domain By-domain = CFWS "BY" FWS Extended-Domain Extended-Domain = Domain / ( Domain FWS "(" TCP-info ")" ) / ( address-literal FWS "(" TCP-info ")" ) TCP-info = address-literal / ( Domain FWS address-literal ) ; Information derived by server from TCP connection ; not client EHLO.
FWS = ([*WSP CRLF] 1*WSP) / obs-FWS ; Folding white space ctext = %d33-39 / ; Printable US-ASCII %d42-91 / ; characters not including %d93-126 / ; "(", ")", or "\" obs-ctext ccontent = ctext / quoted-pair / comment comment = "(" *([FWS] ccontent) [FWS] ")" CFWS = (1*([FWS] comment) [FWS]) / FWS
obs-FWS = 1*WSP *(CRLF 1*WSP)
domain = dot-atom / domain-literal / obs-domain domain-literal = [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS] dtext = %d33-90 / ; Printable US-ASCII %d94-126 / ; characters not including obs-dtext ; "[", "]", or "\"
address-literal = "[" ( IPv4-address-literal / IPv6-address-literal / General-address-literal ) "]"
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.
atext = ALPHA / DIGIT / ; Printable US-ASCII "!" / "#" / ; characters not including "$" / "%" / ; specials. Used for atoms. "&" / "'" / "*" / "+" / "-" / "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}" / "~" atom = [CFWS] 1*atext [CFWS] dot-atom-text = 1*atext *("." 1*atext) dot-atom = [CFWS] dot-atom-text [CFWS]
つまり、Received: のあとの「FROM ~」「BY ~」の記述はすべて必須になったわけです。
また、このような記述もあります(RFC 5322 4.)。
One important difference between the obsolete (interpreting) and the
current (generating) syntax is that in structured header field bodies
(i.e., between the colon and the CRLF of any structured header
field), white space characters, including folding white space, and
comments could be freely inserted between any syntactic tokens. This
allowed many complex forms that have proven difficult for some
implementations to parse.
つまり、改正後はスペースやコメントの入れ方が制限的になったということで、これにより、CFWSと書かれていない場所(例えばReceived: の直後)に、カッコで括って任意の文字列(例えば「(qmail 42078 invoked by uid 1004)」を挿入することもできなくなったわけです。
追記: qmail の RFC 違反
今回の話と直接の関係はないけれど。
追記2:
qmailに見られる
Received: from unknown (HELO vc3.example.jp) (210.233.64.45)
by mail.example.jp with SMTP; 4 Nov 2008 21:10:18 +0900
のようなヘッダは、新しいRFCの推奨事項に従うならば
Received: from vc3.example.jp ([210.233.64.45])
by mail.example.jp with SMTP; 4 Nov 2008 21:10:18 +0900
と表わすことになりますが、by~の前にはコメントが認められているため、前者もRFC違反とまでは言えません。