おっと wanderlust と gmail の悪口はそこまでだ
久しぶりに wanderlust で gmail を読もうとしたら、
Cannot open: elmo-network-initialize-session
なんてエラーが表示され、メールが取得できなくなってしまっていた。
色々調べる内に、原因と対策が判明したので、以下に記録する。
以下のページがとても役に立った。感謝します。
[riwablo: さくらインターネットとimapとopensslとwl]
http://riwablo.blogspot.com/2008/04/imapopensslwl.html
原因
imap.gmail.com へ SSL/TLS で接続する際、
imap.gmail.com のサーバ証明書の検証に失敗するため、
wanderlust (elmo) がセッション確立の途中でエラーを吐いて終了する。
サーバ証明書の検証に失敗してしまうのは、
証明書の発行者 (issuer) である "Equifax Secure Certificate Agency" のルート証明書が、
openssl から利用できていないため。
対策(1) (推奨)
openssl 用証明書ストア (ディレクトリ) の準備
openssl が証明書を読みにいくディレクトリを用意する。
bash-3.2$ mkdir -m 744 -p ~/.w3/certs bash-3.2$
ルート証明書の取得
openssl s_client で imap.gmail.com:993 へ接続してみると、
imap.gmail.com のサーバ証明書は Equifax Secure Certificate Agency によって
発行されていることが分かる。
bash-3.2$ openssl s_client -host imap.gmail.com -port 993 CONNECTED(00000006) depth=1 /C=US/O=Google Inc/CN=Google Internet Authority verify error:num=20:unable to get local issuer certificate verify return:0 --- Certificate chain 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=imap.gmail.com i:/C=US/O=Google Inc/CN=Google Internet Authority 1 s:/C=US/O=Google Inc/CN=Google Internet Authority i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority (以下略)
Equifax Secure Certificate Agency のルート証明書は、
firefox の証明書ストアなどに入っているので、そこから取得する。
環境設定→詳細→暗号化→証明書を表示...
で表示される証明書のリストから
"Equifax" の "Equifax Secure CA" をクリックし、
"書き出す..." ボタンをクリック。
ファイル形式は PEM を選択し、
上で作った ~/.w3/certs ディレクトリへ保存する。
シンボリックリンクの生成
openssl が適切に証明書を選択できるように、
subject のハッシュ値に ".0" を付加したシンボリックリンクを作る。
といってもやるのはコマンド c_rehash を実行するだけ。
bash-3.2$ c_rehash ~/.w3/certs bash-3.2$
これで ~/.w3/certs 内に証明書へのシンボリックリンクが作られる。
bash-3.2$ ls -l ~/.w3/certs total 16 lrwxr-xr-x 1 yamdan staff 19 4 7 00:09 594f1775.0 -> EquifaxSecureCA.pem -rw-r--r--@ 1 yamdan staff 1162 4 7 00:06 EquifaxSecureCA.pem
.wl の編集
.wl へ以下を追記する。
;; SSL/TLS 用証明書ストアのパス (setq ssl-certificate-directory "/Users/yamdan/.w3/certs")
ここでは必ず絶対パスを指定すること。
"~/.w3/certs" のような指定をするとディレクトリの読み込みに失敗する。
(ssl.el の内部では、openssl の実行に
start-process-shell-command ではなく start-process を利用しており、
シェルによる引数の展開 "~/.w3/certs" --> "/Users/yamdan/.w3/certs"
が行われないため)
完了
以上で imap.gmail.com への接続に成功するはず。
.wl は最終的に以下のようになる。
;; IMAP サーバの設定 (setq elmo-imap4-default-server "imap.gmail.com") (setq elmo-imap4-default-user "xxxxxxxxxxxx@gmail.com") (setq elmo-imap4-default-authenticate-type 'clear) (setq elmo-imap4-default-port '993) (setq elmo-imap4-default-stream-type 'ssl) (setq elmo-imap4-use-modified-utf7 t) ;; SMTP サーバの設定 (setq wl-smtp-connection-type 'starttls) (setq wl-smtp-posting-port 587) (setq wl-smtp-authenticate-type "plain") (setq wl-smtp-posting-user "xxxxxxxxxxxxx") (setq wl-smtp-posting-server "smtp.gmail.com") ;; SSL/TLS 用証明書ストアのパス (setq ssl-certificate-directory "/Users/yamdan/.w3/certs")
対策(2) (非推奨)
上の手順の代わりに、
(setq ssl-certificate-verification-policy 1)
のように、ssl-certificate-verification-policy の値に 0 以外を与えても、エラーが抑制される。
証明書の検証に失敗しているのには変わらないはずなんだが、
この挙動の違いはなんなのだろう?
ssl.el の中を見ると、ssl-certificate-verification-policy の値は、
openssl s_client の -verify オプションの値として利用されるようだ。
そしてどうも openssl s_client は
「-verify 0 オプションを付加したときだけ」
証明書検証失敗時の出力が変化するようだ。
bash-3.2$ openssl s_client -host imap.gmail.com -port 993 -verify 0 -CApath ~/.w3/certs verify depth is 0 CONNECTED(00000003) depth=1 /C=US/O=Google Inc/CN=Google Internet Authority verify error:num=20:unable to get local issuer certificate verify return:0 49965:error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed:s3_clnt.c:983:
-verify 0 オプションを付加したときだけは、
openssl s_client は error を吐いて途中終了する。
この error が ssl.el 経由で elmo へ伝わり、
Cannot open: elmo-network-initialize-session
のエラー出力へ繋がっていたようだ。
一方、-verify オプションを付加しない場合や、付加しても 0 以外の値を与えた場合には、
証明書検証に失敗しようが問答無用で、セッションの確立までは進んでしまう。
bash-3.2$ openssl s_client -host imap.gmail.com -port 993 -verify 1 -CApath ~/.w3/certs verify depth is 1 CONNECTED(00000003) depth=1 /C=US/O=Google Inc/CN=Google Internet Authority verify error:num=20:unable to get local issuer certificate verify return:1 depth=1 /C=US/O=Google Inc/CN=Google Internet Authority verify error:num=27:certificate not trusted verify return:1 depth=0 /C=US/ST=California/L=Mountain View/O=Google Inc/CN=imap.gmail.com verify return:1 --- Certificate chain 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=imap.gmail.com i:/C=US/O=Google Inc/CN=Google Internet Authority 1 s:/C=US/O=Google Inc/CN=Google Internet Authority i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority --- Server certificate -----BEGIN CERTIFICATE----- MIIDLzCCApigAwIBAgIKKNVg8QAAAAAHfzANBgkqhkiG9w0BAQUFADBGMQswCQYD VQQGEwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzEiMCAGA1UEAxMZR29vZ2xlIElu dGVybmV0IEF1dGhvcml0eTAeFw0wOTAzMTIyMDIzNDFaFw0xMDAzMTIyMDMzNDFa MGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1N b3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgSW5jMRcwFQYDVQQDEw5pbWFw LmdtYWlsLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAo1cDhDhgSN3M 9Do6D459nSNxZW1fTPJV5rmJctt12zZwDTBbHqWlZsK1ZvcV1ngj1nYgZ7RXZmgC sxEUSK/sw+/5Otl6BpK3OLFZI5U/FmMUTssG588Hsl21SBxeK7RoAgxxM2vB2Jgi 3KH+E13mlgUXlCyrehnbbTlwEosURyUCAwEAAaOCAQAwgf0wHQYDVR0OBBYEFNiX w7Ps6PWzF80VrxYbz63ucVArMB8GA1UdIwQYMBaAFL/AMOv1QxE+Z7qekfv8atrj axIkMEYGA1UdHwQ/MD0wO6A5oDeGNWh0dHA6Ly9jcmwuZXh0Lmdvb2dsZS5jb20v R29vZ2xlSW50ZXJuZXRBdXRob3JpdHkuY3JsMFAGCCsGAQUFBwEBBEQwQjBABggr BgEFBQcwAoY0aHR0cDovL2NhLmV4dC5nb29nbGUuY29tL0dvb2dsZUludGVybmV0 QXV0aG9yaXR5LmNydDAhBgkrBgEEAYI3FAIEFB4SAFcAZQBiAFMAZQByAHYAZQBy MA0GCSqGSIb3DQEBBQUAA4GBALo7fCzccb+0OeU+iGPJ/CEynTIegiqt/OkZPP4P aVy7a0MjwK7mDDYpMMu10r4oYSM8iI1BN2iIXRFDkuogp48yeh8P3In1A332XdW3 UoaoIhI8DunLXgfBEr2/TPUHtXDfJumu+wCojdjT2ywwud1hY8LSRR2zv27FWEAD OaRh -----END CERTIFICATE----- subject=/C=US/ST=California/L=Mountain View/O=Google Inc/CN=imap.gmail.com issuer=/C=US/O=Google Inc/CN=Google Internet Authority --- No client certificate CA names sent --- SSL handshake has read 1660 bytes and written 306 bytes --- New, TLSv1/SSLv3, Cipher is RC4-MD5 Server public key is 1024 bit Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1 Cipher : RC4-MD5 Session-ID: xxxxxxxx Session-ID-ctx: Master-Key: xxxxxxxx Key-Arg : None Start Time: 1241109692 Timeout : 300 (sec) Verify return code: 27 (certificate not trusted) --- * OK Gimap ready for requests from xxx.xxx.xxx.xxx
途中で verify error とか certificate not trusted とか出てるけど、
セッションは確立する。
elmo や wanderlust はこれをエラーと認識できないようだ。
ちなみに openssl のバージョンは 0.9.8i です。
bash-3.2$ openssl version OpenSSL 0.9.8i 15 Sep 2008