LoginSignup
0
1

More than 1 year has passed since last update.

メールサーバやメールリーダが行うメール本文の書き換えについて

Last updated at Posted at 2021-06-29

はじめに

メールの文字化け対策について調査を行っていました。それで副次的に気がついたのですが、メールサーバやメールリーダーが「ヘッダ」だけでなくメールの「本文」の修正を行う事があるようです。

マジか!

修正内容について調査してみました。

初めにメールサーバによる書き換えを調査します.
(結論を先に述べると、Office365(クラウド)はHTMLのタグの改行空白の修正が入ります。)

続いてOffice2019(Win)による書き換えを調査します.
(結論を先に述べると、Plain/HTMLのAlternativeメールは、Office2019(Win+IMAP)でメールのコピー作業を行うと,IMAPサーバ上の元メールとコピーしたメールの内容が書き換わってます.HTMLの内容に合わせてPlainの内容が書き換わります。)

※注意: 無料版のOutlookのメールアカウントは単純な内容のメール(例えば本文が「テスト」一行のメールなど)を多数送受信するとアカウントロックされる事があるようです。ご注意ください。以下の調査は職場で契約しているOffice365を用いてます。(Office365は職場の管理者が色々設定している可能性があるため,無料版Outlookで試したかったのですが,断念しました.)

事前準備

職場のメールアドレス(CentOS7/Postfix)を用意しました.続いてOffice365のメールアドレスとgmail(クラウド)のメールアドレスを準備しました。

  • 職場のメール: 職場のアドレス@example.com (CentOS7/Postfix)
  • Gmailメール: テストアドレス@gmail.com
  • Office365メール: テストアドレス@outlook.com

Mewで上記の3つのアドレスを読み書きできるようにしてください.

Gmailは「安全性の低いアプリの許可」をオンにしないと読めないと思います.Office365は特になにもしないでもimapで読めましたが(職場で契約したものなので)無料版のOutlookでも同様かはわかりません.

サンプルメール1(PLAIN+HTML)

以下のようなファイルを用意しました.JISコードで作成したPLAINテキストおよび,ほぼ同じ内容のHTMLファイルです.

書換テストjis.txt
転送時にファイルが書き換えられるかのテスト(20210629)
*送信元(Mew6.8/JIS)*
書換テストjis.html
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-2022-jp">
  </head>
  <body>
    転送時にファイルが書き換えられるかのテスト(20210629)<BR>
    <b>送信元(Mew6.8/JIS)</b>
  </body>
</html>

サンプルメール2(内容差分)

以下のようなファイルを用意しました.JISコードで作成したPLAINテキストおよび,内容が異なるHTMLファイルです.Plainテキストの「差分txt」がHTMLでは「差分html」に修正しています.

書換テストdiff.txt
転送時にファイルが書き換えられるかのテスト(20210629)
*送信元(Mew6.8/JIS)/差分txt*
書換テストdiff.html
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-2022-jp">
  </head>
  <body>
    転送時にファイルが書き換えられるかのテスト(20210629)<BR>
    <b>送信元(Mew6.8/JIS)/差分html</b>
  </body>
</html>

Mewのマルチパートで送信

テストメールをMewで作成します.テストメールをOutlookやThunderbirdで作成すると,メールリーダーがどのようなメールを作成するか確認し辛いので,Mewで無理やり同等のマルチパートメールを作成します.

そのため,少々めんどくさい操作しています.

次の組み合わせでMewのマルチパートで送信してみます.

-サンプルメール1(PLAIN+HTML): 書換テストjis.txt / 書換テストjis.html
-サンプルメール2(内容差分): 書換テストdiff.txt / 書換テストdiff.html

ここでMewで送信時の注意点ですが、

  • Mewの本文にはなにも書かない.
  • Multipart/MixedからAlternativeしてください(Tで修正).
  • ファイル名を無しにしてください(Pで修正). ファイル名を消すと 「xxxx.txt」から「*xxxx.txt」に修正されます.

こんな感じです.

Mew送信例サンプルメール1(PLAIN+HTML)
To: テストアドレス@gmail.com, テストアドレス@outlook.com
Subject: 添付ファイルが書き換えられるかのテスト(20210629)/JIS
From: 職場のアドレス@example.com
Dcc: 職場のアドレス@example.com
X-Mailer: Mew version 6.8 on Emacs 24.3
----
(本文にはなにも書かない.)
------------------------------ attachments ------------------------------
      Multipart/Alternative   (←MixedからAlternativeに修正)     3/
     1  Text/Plain(guess)                                         *Cover.txt
     2  Text/Plain(guess)                                         *書換テストji.
     3  Text/Html(guess)                                          *書換テストji..
     4                                                            .
--------0-1-2-3-4-5-6-7-8-9----------------------------------------------

Mew6.8(CentOS7.9)から職場のメールサーバ経由でOffice365/gmailのメールサーバに送信します。

Mew6.8 → SMTP → 職場のメールサーバ(CentOS7) → SMTP → (クラウド)Office365/Gmail

サンプルメール1(PLAIN+HTML)を送信して,続いてサンプルメール2(内容差分)を送信してください.

Mew送信例サンプルメール2(内容差分)
To: テストアドレス@gmail.com, テストアドレス@outlook.com
Subject: 添付ファイルが書き換えられるかのテスト(20210629)/diff
From: 職場のアドレス@example.com
Dcc: 職場のアドレス@example.com
X-Mailer: Mew version 6.8 on Emacs 24.3
----
(本文にはなにも書かない.)
------------------------------ attachments ------------------------------
      Multipart/Alternative                                      3/
     1  Text/Plain(guess)                                         *Cover.txt
     2  Text/Plain(guess)                                         *書換テストdi..
     3  Text/Html(guess)                                          *書換テストdi..
     4                                                            .
--------0-1-2-3-4-5-6-7-8-9----------------------------------------------

メールサーバによる修正

サンプルメール1(PLAIN+HTML)

GmailとOffice365に送ったメールをMewで取り込んでください.

オリジナルのメールとdiffを取ってみます.

  • Gmailは本文修正なしです.

  • Office365は本文のHTMLパートに以下の修正が入ります.HTMLの細かな修正がはいります.

$ diff -uwi jis_org.eml jis_office365.eml
(diffの出力は一部割愛)
 ----Next_Part(Tue_Jun_29_10_03_27_2021_939)--
 Content-Type: Text/Plain; charset=iso-2022-jp
@@ -31,8 +131,7 @@
 Content-Type: Text/Html; charset=iso-2022-jp
 Content-Transfer-Encoding: 7bit

-<html>
-  <head>
+<html><head>
     <meta http-equiv="Content-Type" content="text/html; charset=iso-2022-jp">
   </head>
   <body>

サンプルメール2(内容差分)の差分

Gmailは修正なし.Office365はサンプルメール1(JIS)とほぼ同じです.

メールリーダーによる修正

先ほど確認した書換はメールサーバによるものですが、次にメールリーダでの修正について確認します。

職場のメールサーバにOffice2019(Win10+IMAP)で接続します。Office2019での操作でサンプルメール1と2を別のフォルダにコピー作業を行ってみます.(移動では確認してません.)

こんな形になります.

Office2019(Win) → IMAP → 職場のメールサーバ(CentOS7)

IMAPのため,Office2019上でコピー作業すると,IMAPサーバ上のファイルのコピーが発生します.

コピー後,コピーしたメールを再びMewで取り込みます.

サンプルメール1(PLAIN+HTML)の差分

コピーしただけでは何も起きないと思いますよね.そんな事はなかったりします.

ヘッダ部分は読みにくいので文章で説明しますが,

  • Subjectの改行位置の修正
-Subject: =?iso-2022-jp?B?GyRCRTpJVSVVJSElJCVrJCw9cRsoQg==?=
- =?iso-2022-jp?B?GyRCJC00OSQoJGkkbCRrJCskThsoQg==?=
- =?iso-2022-jp?B?GyRCJUYlOSVIGyhCKDIwMjEwNjI5KS9KSVM=?=
+Subject: =?iso-2022-jp?B?GyRCRTpJVSVVJSElJCVrJCw9cSQtNDkkKCRpJGwkayQrJE4lRiU5GyhC?=
+       =?iso-2022-jp?B?GyRCJUgbKEIoMjAyMTA2MjkpL0pJUw==?=
  • From/Toなどのアドレス表記の修正。アドレスは多数あるので抜粋です。
修正前:
- 職場のメール <職場のアドレス@example.com>
- テストアドレス@outlook.com

修正後:
- "職場のメール" <職場のアドレス@example.com>
- <テストアドレス@outlook.com>
  • MIMEのboundaryの変更
 Content-Type: Multipart/Alternative;
- boundary="--Next_Part(Tue_Jun_29_10_03_27_2021_939)--"
+       boundary="----=_NextPart_000_002D_01D76CD0.721A1BB0"
  • ヘッダ部からの追加削除
削除:
Content-Transfer-Encoding: 7bit

追加:
(省略)

続いて本文への修正ですが、

  • (前述しましたが)boundary修正
  • 「This is a multipart message in MIME format.」追加
  • Plainテキストの修正
    「*」除去.← ちょっとこれなに

  • Encodeが7bit からquoted-printable修正.

$ diff -uwi jis_org.eml jis_office2019.eml
(diffの出力は一部割愛)

+This is a multipart message in MIME format.

-----Next_Part(Tue_Jun_29_10_03_27_2021_939)--
-Content-Type: Text/Plain; charset=iso-2022-jp
+------=_NextPart_000_002D_01D76CD0.721A1BB0
+Content-Type: text/plain;
+       charset="iso-2022-jp"
 Content-Transfer-Encoding: 7bit

 転送時にファイルが書き換えられるかのテスト(20210629)
-*送信元(Mew6.8/JIS)*
+送信元(Mew6.8/JIS)

-----Next_Part(Tue_Jun_29_10_03_27_2021_939)--
-Content-Type: Text/Html; charset=iso-2022-jp
-Content-Transfer-Encoding: 7bit
+------=_NextPart_000_002D_01D76CD0.721A1BB0
+Content-Type: text/html;
+       boundary="--Next_Part(Tue_Jun_29_10_03_27_2021_939)--";
+       charset="iso-2022-jp"
+Content-Transfer-Encoding: quoted-printable

 <html>
   <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=iso-2022-jp">
+    <meta http-equiv=3D"Content-Type" content=3D"text/html; =
+charset=3Diso-2022-jp">
   </head>
   <body>
-    転送時にファイルが書き換えられるかのテスト(20210629)<BR>
-    <b>送信元(Mew6.8/JIS)</b>
+    =1B$BE>Aw;~$K%U%!%$%k$,=3Dq$-49$($i$l$k$+$N%F%9%H=1B(B(20210629)<BR>
+    <b>=1B$BAw?.85=1B(B(Mew6.8/JIS)</b>
   </body>
 </html>

-----Next_Part(Tue_Jun_29_10_03_27_2021_939)----
+------=_NextPart_000_002D_01D76CD0.721A1BB0--

サンプルメール2(内容差分)の差分

このサンプルはPlainテキストとHTMLで文章の内容が異なります.Plainテキストの「差分txt」がHTMLでは「差分html」に修正しています.

サンプルメール1と同じのは割愛しますが,

  • Plainテキストの修正。 「差分txt」が「差分html」に差し替え.← ちょっとこれなに
$ diff -uwi jis_org.eml jis_office2019.eml
(diffの出力は一部割愛)

+This is a multipart message in MIME format.

-----Next_Part(Tue_Jun_29_10_08_49_2021_742)--
-Content-Type: Text/Plain; charset=iso-2022-jp
+------=_NextPart_000_0026_01D76CD0.71D76D60
+Content-Type: text/plain;
+       charset="iso-2022-jp"
 Content-Transfer-Encoding: 7bit

 転送時にファイルが書き換えられるかのテスト(20210629)
-*送信元(Mew6.8/JIS)/差分txt*
+送信元(Mew6.8/JIS)/差分html

-----Next_Part(Tue_Jun_29_10_08_49_2021_742)--
-Content-Type: Text/Html; charset=iso-2022-jp
-Content-Transfer-Encoding: 7bit
+------=_NextPart_000_0026_01D76CD0.71D76D60
+Content-Type: text/html;
+       boundary="--Next_Part(Tue_Jun_29_10_08_49_2021_742)--";
+       charset="iso-2022-jp"
+Content-Transfer-Encoding: quoted-printable

 <html>
   <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=iso-2022-jp">
+    <meta http-equiv=3D"Content-Type" content=3D"text/html; =
+charset=3Diso-2022-jp">
   </head>
   <body>
-    転送時にファイルが書き換えられるかのテスト(20210629)<BR>
-    <b>送信元(Mew6.8/JIS)/差分html</b>
+    =1B$BE>Aw;~$K%U%!%$%k$,=3Dq$-49$($i$l$k$+$N%F%9%H=1B(B(20210629)<BR>
+    <b>=1B$BAw?.85=1B(B(Mew6.8/JIS)/=1B$B:9J,=1B(Bhtml</b>
   </body>
 </html>

-----Next_Part(Tue_Jun_29_10_08_49_2021_742)----
+------=_NextPart_000_0026_01D76CD0.71D76D60--

というようにPLAINテキストとHTMLのAlternative属性のメールはHTMLに準じてPlainテキスト部が修正されます.

その他の修正

上記以外にOutlook2019(Win+IMAP)でファイルのコピー作業をすると,以下の修正が入るようです.詳細は省略します.

  • (常に発生)添付ファイルのファイル名(Content-Disposition: filename)が RFC2231の場合は,Base64形式(=?charset?B?.....?=)に修正.

Mewで添付ファイル「一二三四五六七八.txt」を添付し,職場メールサーバに送信後Outlook2019(Win+IMAP)でファイルのコピー操作を実施した例です.

追記:よく見たら添付ファイルの「charset=iso-2022-jp」指令が無くなってるので確認したらBASE64をdecodeしたらこれShift-JISじゃないか。。

$ diff -uwi jp-filename-mew.eml jp-filename-office2019.eml
(diffの出力は一部割愛)

-----Next_Part(Tue_Jun_29_14_58_42_2021_099)--
-Content-Type: Text/Plain; charset=iso-2022-jp
+This is a multipart message in MIME format.
+
+------=_NextPart_000_000C_01D76CF7.585CFD10
+Content-Type: text/plain;
+       boundary="--Next_Part(Tue_Jun_29_14_58_42_2021_099)--";
+       charset="iso-2022-jp"
 Content-Transfer-Encoding: 7bit

 ファイル名命名規則の修正

-----Next_Part(Tue_Jun_29_14_58_42_2021_099)--
-Content-Type: Text/Plain; charset=iso-2022-jp;
- name="=?iso-2022-jp?B?GyRCMGxGczswO004Xk87PDdILBsoQi50eHQ=?="
-Content-Transfer-Encoding: 7bit
-Content-Disposition: inline;
- filename*=iso-2022-jp''%1B%24B0lFs%3B0%3BM8%5EO%3B%3C7H%2C%1B%28B%2Etxt
+------=_NextPart_000_000C_01D76CF7.585CFD10
+Content-Type: Text/Plain;
+       name="=?iso-2022-jp?B?GyRCMGxGczswO004Xk87PDdILBsoQi50eHQ=?="
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment;
+       filename="=?iso-2022-jp?B?GyRCMGxGczswO004Xk87PDdILBsoQi50eHQ=?="

-ファイル名: 一二三四五六七八.txt
+g3SDQINDg4uWvDogiOqT8Y5PjmyM3JhajrWUqi50eHQNCg==

-----Next_Part(Tue_Jun_29_14_58_42_2021_099)----
+------=_NextPart_000_000C_01D76CF7.585CFD10--
  • (まれに発生)添付ファイルのファイル名やSubjectがBase64(=?charset?B?.....?=)
    からQuoted Printable形式 (=?charset?Q?=16進数...?=)に修正.

  • base64の幅が72文字の場合は76文字に修正.(これがあるのでdiff取る時は注意)

補足:diffとる時は次のスクリプトが役にたつかも.BASE64の添付ファイル部分を削ります。ファイルを書換えるのでバックアップ後実施ください.

strip-base64.pl
#!/usr/bin/perl
#
# 頭が悪い実装.

#72文字-76文字の行が5行続いたらBASE64と判断

for my $i (@ARGV){
    next unless(-f $i);
    my $bakfile = $i . ".bak";
    rename ($i , $bakfile) or die;
    open(FILE, "< ", $bakfile) or die;
    my $tmp=join("",<FILE>);
    close(FILE);
    open(FILE, ">", $i) or die;
    #print $tmp;
    $tmp =~ s/\n[\da-zA-Z\+\/]{72,76}\n[\da-zA-Z\+\/]{72,76}\n[\da-zA-Z\+\/]{72,76}\n[\da-zA-Z\+\/]{72,76}\n[\da-zA-Z\+\/]{72,76}\n[\da-zA-Z\+\/\=\n]+/\nStripBASE64\n/g;

    print FILE $tmp;
    close(FILE);
}

以上です。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1