<< 2024/03 >> | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
|
IMAP4 コマンドとエンコード問題について
15/12/12 15:19 / PMailServer2
少し珍しいケースでのお問い合わせを頂いたので、その対策を行っているのですが、この問題は色々な仕様が絡み合って発生する問題で、お問い合わせを頂くまで想定もしていなかったこともあり、メモ代わりに記事にしておきます。
以下は IMAP4 サーバーを作っている人(殆ど居ないと思いますが)または IMAP4 クライアントを作っている人、メールの送信を行うプログラムを作成している方に、ホンのわずかーーーに有用かもしれない情報です。 まず文字コードの話からとなりますが、メールの件名などで日本語を扱う場合は、昔ながらの JISコード(ISO-2022-JPと言う奴です)が多く、最近では Unicode、UTF-8 / UTF-16 なども増えてきています。 そしてこの JIS コードなんですが、色々あるのですが 2byteコードの「、」を JIS コードに変換すると以下のようになります。 [0x1B]$B!"[0x1B](B [0x1B] は ASCII では無く、0x1B というバイナリで、いわゆるエスケープシーケンスという物でして「ここから変換するよ」とか「ここで変換は終わりだよ」などを指定する場合に利用します。 もう1個、メールの本文などは Content-Type で「メールの本文は、こういう形式でエンコードはこれを使っています」と指定できますが、件名の場合は、そのセクションのみで完結させる為に、MIME エンコードと言う方式を使います。 =?文字コード?エンコード方式?エンコードデータ?= みたいな奴です。上記だけではピンときませんが 上記の、[0x1B]$B!"[0x1B](B をこの形式にすると =?iso-2022-jp?Q?=1B$B!"=1B(B?= こんな風になります。メールヘッダを見たことがある人は、なんとなく見たことがあるよ!と思われると思います。 ちなみに、エンコード方式に B が指定されていると Base64 、Q が指定されていると Quoted-Printable という形式になります。 ここまでが前提となります。 さて IMAP4 のコマンドに FETCH というコマンドがありサーバー側にあるメールの情報などを取得します。 telnet で IMAP4 サーバーにログインしてから適当なメールボックスに移動した後に FETCH 1 ENVELOPE とやると「1番のメールのエンベロープを返せ」となります。 結果は(便宜省略と改行をしますが) * 1 FETCH (UID 228118 ENVELOPE ("Stu, 12 Dec 2015 11:42:50 +0900" "Test Mail" 〜(省略)〜)) と応答が返って来ます。(実際にはもっと複雑です) ENVELOPE コマンドはメールヘッダーの「解析結果」をエンベローブ構造体という形で返しています。 んで、構造体にもいくつかルール(データが無い場合は NIL を設定するとか)があるのですが「スペースを含む場合はダブルクォートで囲う」とあります。 上記の例でも日付部分や件名にスペースが含まれていますので「ダブルクォート」で囲っています。 というかダブルクォートで囲っておかないと一部メーラーは解析に失敗してくれます。(ダブルクォートで囲われているのが前提となっている) さて、ここで先ほど作った「、という件名を MIME に変換しエンコードタイプは Quoted-Printable にした」奴を当てはめてみます。 * 1 FETCH (UID 228118 ENVELOPE ("Stu, 12 Dec 2015 11:42:50 +0900" "=?iso-2022-jp?Q?=1B$B!"=1B(B?=" 〜(省略)〜)) もう一目瞭然ですが、途中にダブルクォートが含まれる為、誤認識します。 さて、誰が悪いんでしょう? まず「、」を JIS(ISO-2022-JP)でエンコードした際にダブルクォートが入るのはそのまんま「エンコードのルール」なので悪くありません。 ENVELOPE でダブルクォートを使うことですが「スペースが入らないのにダブルクォートで囲うほうが悪い」と思うかもしれませんが、実際、仕様上は問題ありませんし、むしろ囲わないと認識しないクライアントが現実問題として存在するので囲わざる得ません。 JIS と Quoted-Printable でエンコードして送信するクライアントが悪いんじゃない?ってとこに行き着くのですが、そもそも、JIS と Quoted-Printable の組み合わせはやってはいけない組み合わせではありません。 IMAP4 じゃなくて POP3 のようにメールヘッダ又は全体を受信してから単独でデコードすれば正常にデコードできる訳ですので。 つまり誰も悪くなく、組み合わせが悪かったということになります。 まぁ、しいて言えば、送信時に Quoted-Printable を使わずに Base64 でエンコードすれば問題ないのですが。 ちなみに Base64 でエンコードすると =?iso-2022-jp?B?GyRCISIbKEI=?= このようになります。 Base64 で利用される記号は /+= の3種類だけですので、問題の出ようがありません。 なにか RFC で見忘れている仕様があるのかもしれないと思い、RFC 読み返してみたり(見落としている可能性はあります・・・)、ダブルクォートを外してみたり、エスケープしてみたり、CSV のようにダブルクォートを重ねてみたりしてみましたが、認識しないクライアント続出なので、その辺りの問題では無い気もします。 で、最終的には PMail Server2 側で、Quoted-Printable で MIME エンコードされている場合にダブルクォートが含まれている場合は、Base64 で再エンコードしてから応答する。 というオプションをつけることにしました。 (FETCH の応答のみ再変換し、元データは加工しません。元データを加工すると POP3 で読み出した場合に元のデータと違うことになってしまいますし、DKIM 等で確認範囲に Subject が含まれている場合、偽装判定される可能性が出てくるからです。) 結論としては「メールの送信プログラムを作る場合は、Quoted-Printable は止めて、Base64 にしておけば確実だよ!」ってことです。 [更新日付:2015/12/12 16:44:51]
トラックバックを見る(0) Log Link [https://akisoftware.com/cgi-bin/blom.exe?akisoft+sl+c0291ca5e472738f610f010097bd73f593acfd63] TB Link [https://akisoftware.com/cgi-bin/blom.exe?akisoft+tb+c0291ca5e472738f610f010097bd73f593acfd63] 記事へのコメント コメントはありません |
@AKISoftOfficialをフォロー
掲示板 サポートBBS PMailServer BBS アクセスの多い記事
最新記事(カテゴリ別)
フリー版からの製品版移行時の MTA 並列数について
02/17 23:52 メールサーバーの開発を始めて20年 02/07 21:46 PMailServer2 Version 2.52a をリリースしました。 12/26 14:02 PMailServer2 Version 2.52 をリリースしました。 10/01 10:48 PMailServer2 Version 2.51b をリリースしました。 09/19 01:43 PMailServer2 Version 2.51b(仮) Memo 09/12 00:33 PMailServer2 Version 2.51a をリリース、及び脆弱性についてのお知らせ 09/05 01:15 PMailServer2 Version 2.51a Memo 08/21 00:48 アドレスV125(K5)のスターターリレーの交換 08/04 10:10 SanDisk ポータブルSSDを買ってみました。 08/04 09:41 最新コメント
コメントはありません
UUアクセス数
今日は 310回
昨日は 159回 トータル 301027回 3ヶ月記事別ランキング
プロフィール
Z80から68系、8086系を経由して
Pascalに移行。現在は Delphiをメインに C/C#も囓ってみたり。 「無い物は作れ」の精神で年がら年中なにかを作っています。 すぐ自前で作りたがるので無駄に工数が上がったりして自爆してみたりもします。 好きな物は麺類とお煎餅 Blom内検索
BLOM Version 1.39 ©2007-15 A.K.I Software all rights reserved. |