「あなくつ」のおもちゃばこ

Laboratory

メールアドレス (RFCに基づく仕様を理解する)

今まで僕は、ネット上にあるいわゆる「メールアドレスチェックの正規表現」でメールアドレスのチェック・抽出を行っていたんだけど、それだといろいろ問題が起きてしまい、ちゃんとRFCに基づいてチェックしようということで調べてみました。

まずどのRFCを読むか。RFC 5321 (Simple Mail Transfer Protocol)またはRFC 5322 (Internet Message Format)が最新のようです。下記ではRFC5322の記述を元に読んでいきます。なお、RFC内の記載順ではなく、解釈の順番で引用します。

メールアドレスについては「3.4.1. Addr-Spec Specification」から記載されています。

   addr-spec       =   local-part "@" domain

   local-part      =   dot-atom / quoted-string / obs-local-part

   domain          =   dot-atom / domain-literal / obs-domain

上から順番に解読すると下記のようになります。

  • 「addr-spec」(メールアドレス)とは「local-part」と「domain」を「@」で接続したものである。
  • 「local-part」とは「dot-atom」または「quoted-string」または「obs-local-part」である。
  • 「domain」とは「dot-atom」または「domain-literal」または「obs-domain」である。

「local-part」と「domain」に含まれる「dot-atom」は「3.2.3. Atom」セクションで以下のように定義されています。

   dot-atom        =   [CFWS] dot-atom-text [CFWS]

   dot-atom-text   =   1*atext *("." 1*atext)

   atext           =   ALPHA / DIGIT /    ; Printable US-ASCII
                       "!" / "#" /        ;  characters not including
                       "$" / "%" /        ;  specials.  Used for atoms.
                       "&" / "'" /
                       "*" / "+" /
                       "-" / "/" /
                       "=" / "?" /
                       "^" / "_" /
                       "`" / "{" /
                       "|" / "}" /
                       "~"

   specials        =   "(" / ")" /        ; Special characters that do
                       "<" / ">" /        ;  not appear in atext
                       "[" / "]" /
                       ":" / ";" /
                       "@" / "\" /
                       "," / "." /
                       DQUOTE
  • 「dot-atom」とは「dot-atom-text」である。ただしその前後に「CFWS」を置くことができる。
  • 「dot-atom-text」とは1文字以上の「atext」で、その後に「.」と「atext」のセットが0個以上連結する。
  • 「atext」とは上記に列挙されている文字(印字可能で「specials」ではない文字)である。
  • 「specials」とは上記に列挙されている文字である。(DQUOTEはASCIIコード34「"」)

かつてdocomoとAUのメールアドレスでドットの連続したアドレスが設定できましたが、これがRFC違反と騒がれていた所以は「1*atext *("." 1*atext)」だからのようですね。ちなみに現在はdocomoもAUも新たに設定されるメールアドレスではドットを連続させることはできないようです。ドットの連続がアットマークの前に来る僕のメアドは貴重品です(笑)

「dot-atom」に含まれる「CFWS」は「3.2.2. Folding White Space and Comments」および「4.4. Obsolete Addressing」セクションで以下のように定義されています。

   CFWS            =   (1*([FWS] comment) [FWS]) / FWS

   FWS             =   ([*WSP CRLF] 1*WSP) /  obs-FWS
                                          ; Folding white space

   obs-FWS         =   1*WSP *(CRLF 1*WSP)

   comment         =   "(" *([FWS] ccontent) [FWS] ")"

   ccontent        =   ctext / quoted-pair / comment

   ctext           =   %d33-39 /          ; Printable US-ASCII
                       %d42-91 /          ;  characters not including
                       %d93-126 /         ;  "(", ")", or "\"
                       obs-ctext

   obs-ctext       =   obs-NO-WS-CTL

   obs-NO-WS-CTL   =   %d1-8 /            ; US-ASCII control
                       %d11 /             ;  characters that do not
                       %d12 /             ;  include the carriage
                       %d14-31 /          ;  return, line feed, and
                       %d127              ;  white space characters

   quoted-pair     =   ("\" (VCHAR / WSP)) / obs-qp

   obs-qp          =   "\" (%d0 / obs-NO-WS-CTL / LF / CR)
  • 「CFWS」とは、1個以上の「comment」または「FWS」である。ただし「comment」の前に「FWS」を置くことができ、最後の「comment」のあとには「FWS」を置くことができる。
  • 「FWS」とは、1個以上の「WSP」または「obs-FWS」である。ただし「WSP」の前に、0個以上の「WSP」と「CRLF」のセット、を置くことができる。(WSPはASCIIコード32「 」またはASCIIコード9「 」)
  • 「obs-FWS」とは、1個以上の「WSP」である。ただし「WSP」のあとに、「CRLF」と1個以上の「WSP」のセット、を置くことができる。
  • 「comment」とは、「(」と「)」で囲まれた、0個以上の「ccontent」である。ただし「ccontent」の前に「FWS」を置くことができ、最後の「ccontent」のあとには「FWS」を置くことができる。
  • 「ccontent」とは、「ctext」または「quoted-pair」また「comment」である。
  • 「ctext」とは、上記に列挙されている文字コードの範囲または「obs-ctext」である。
  • 「obs-ctext」とは、「obs-NO-WS-CTL」である。
  • 「obs-NO-WS-CTL」とは、上記に列挙されている文字コードの範囲である。
  • 「quoted-pair」とは、「\」に続く「VCHAR」または「WSP」、または「obs-qp」である。(VCHARは印字可能なASCII文字(0x21-0x7E))
  • 「obs-qp」とは、「\」に続くASCIIコード0または「obs-NO-WS-CTL」または「LF」または「CR」である。(LFはASCIIコード10、CRはASCIIコード13)

とりあえずここまでで読み取れるのは、「local-part」「domain」の前後、つまり「@」とメールアドレスの前後にはコメントやスペースなどを入れられるということですね。しかもコメントはネスト出来るという面倒な構造です。「dot-atom-text ( this is comment ) @ ana-kutsu.com」こーんなメールアドレスもRFC的にはOKということですね。

それと「quoted-pair」についてですが、面倒に定義されていますが結局は「\」に続けばASCII文字すべてを置くことができることになっていますね。

ところでこの「CFWS」ですが、「3.4. Address Specification」で述べられている通り、「@」の前後にコメントやスペースを入れるべきではない(SHOULD NOT)と書かれています。なので使わない方がいいですし、実際問題これをMTAが正確に考慮してくれるとは期待しない方がいいでしょう。

続いて、「local-part」に含まれる「quoted-string」は「3.2.4. Quoted Strings」および「4.4. Obsolete Addressing」セクションで以下のように定義されています。

   quoted-string   =   [CFWS]
                       DQUOTE *([FWS] qcontent) [FWS] DQUOTE
                       [CFWS]

   qcontent        =   qtext / quoted-pair

   qtext           =   %d33 /             ; Printable US-ASCII
                       %d35-91 /          ;  characters not including
                       %d93-126 /         ;  "\" or the quote character
                       obs-qtext

   obs-qtext       =   obs-NO-WS-CTL
  • 「quoted-string」とは、「DQUOTE」と「DQUOTE」で囲まれた、0個以上の「qcontent」である。ただし「qcontent」の前に「FWS」を置くことができ、最後の「qcontent」のあとには「FWS」を置くことができる。
  • 「qcontent」とは、「qtext」また「quoted-pair」である。
  • 「qtext」とは、上記に列挙されている文字コードの範囲または「obs-qtext」である。
  • 「obs-qtext」とは、「obs-NO-WS-CTL」である。

えーと、つまりダブルクォーテーションに囲まれいれば事実上すべてのASCII文字を置けるわけですねぇ。ドットが連続してもいいし、「\」でエスケープすれば改行コードとかもOKなワケです。

一応RFCでは「quoted-string」は使用すべきではない(SHOULD NOT)となっていますが、プログラムで直接MTAからメールを受け取るとき(.forward でメールを取り込むプログラムを動かすときなど)、まれに「quoted-string」をもったメールアドレスで配送されるので完全には無視できないですね。どうやらpostfixの設定によっては、docomoのドットの連続するメールアドレスのメールを転送するときなどにダブルクォーテーションを追加するようです。(一回これでハマりました)

「local-part」の3つ目、「obs-local-part」は「4.4. Obsolete Addressing」セクションで以下のように定義されています。

   obs-local-part  =   word *("." word)

   word            =   atom / quoted-string

   atom            =   [CFWS] 1*atext [CFWS]
  • 「obs-local-part」とは、「word」で、その後に「.」と「word」のセットが0個以上連結する。
  • 「word」とは、「atom」また「quoted-string」である。
  • 「atom」とは、1文字以上の「atext」である。ただしその前後に「CFWS」を置くことができる。

このあたりで古いRFCまでカバーできるようになっているようです。上記定義によると「dot.".."@ana-kutsu.com」のようなメールアドレスもOKということになりますね。

ふぅ、これで「local-part」の定義終わり。

「domain」に含まれる「domain-literal」は最初に挙げた「3.4.1. Addr-Spec Specification」および「4.4. Obsolete Addressing」セクションで以下のように定義されています。

   domain-literal  =   [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]

   dtext           =   %d33-90 /          ; Printable US-ASCII
                       %d94-126 /         ;  characters not including
                       obs-dtext          ;  "[", "]", or "\"

   obs-dtext       =   obs-NO-WS-CTL / quoted-pair
  • 「domain-literal」とは、0個以上の「dtext」である。ただし「dtext」の前に「FWS」を置くことができ、最後の「dtext」のあとには「FWS」を置くことができる。また、その前とあとに「[」「]」を置くことができ、さらにその前後に「CFWS」を置くことができる。
  • 「dtext」とは、上記に列挙されている文字コードの範囲または「obs-dtext」である。
  • 「obs-dtext」とは、「obs-NO-WS-CTL」または「quoted-pair」である。

「domain」に含まれる「obs-domain」は「4.4. Obsolete Addressing」セクションで以下のように定義されています。

   obs-domain      =   atom *("." atom)
  • 「obs-domain」とは、「atom」で、その後に「.」と「atom」のセットが0個以上連結する。

これで全部定義読んだかなぁ。

「domain」も自由度はありますが、名前解決可能なFQDN(RFC 5321)か、「[」と「]」でくくられたIPアドレスじゃないとダメなようです。このへんはWikipedia情報です。

RFC 5321により長さが、「local-part」は64オクテット、「domain」は255オクテット、「addr-spec」全体で256オクテットに制限されています。

タグ : RFC,メールアドレス

2011/08/11 22:15:27 | Trackbacks (0) | Comments (0)

Trackback

URL : https://www.ana-kutsu.com/mt/mt-tb.cgi/588

Comment

(Private)
Authentication
refresh captcha

画像の中に見える文字を入力してください。

« Cent OS 5 セットアップスクリプト | Top

Copyright © 2004-2023 Ana-Kutsu All Rights Reserved.