細田です。
GnuTLSを使用してドコモメールの送信をしようとすると
```
502 Command not implemented. This mail has been queued to +queue
```
と出てきて送信できないという事象があり、
原因と思われるものがわかったので報告しておきます。
ドコモメールの送信サーバ設定は
https://www.docomo.ne.jp/service/docomo_mail/other/
にある通り、
SMTPサーバ
smtp.spmode.ne.jp
ポート番号
465
となっていて、STARTTLS不要で最初から暗号化されているものです。
以下の設定で再現できます。
```.el
(setq mew-smtp-server "
smtp.spmode.ne.jp")
(setq mew-smtp-ssl 'native)
(setq mew-smtp-ssl-port 465)
(setq mew-smtp-user "
te...@example.com")
```
この設定で適当なメールを送信しようとするとMew-debugは以下のようになります。
```
<TLS proto=smtp, server=
smtp.spmode.ne.jp:465, starttlsp=nil>
verify-level=1, network-security-level=medium, nowait=nil, tlsparams=gnutls-x509pki :priority NORMAL:%DUMBFW :hostname
smtp.spmode.ne.jp :loglevel 0 :min-prime-bits 2048 :trustfiles (/etc/ssl/cert.pem) :crlfiles nil :keylist nil :verify-flags nil :verify-error nil :pass nil :flags nil :callbacks nil :priority-string NORMAL:%DUMBFW
<=SEND=>
EHLO localhost
<EHLO>
503 Bad sequence of commands
<=SEND=>
HELO localhost
<HELO>
502 Command not implemented
<=SEND=>
QUIT
<QUIT>
221 Service closing transmission channel
<SMTP SENTINEL>
connection broken by remote peer
```
EHLOに失敗してHELOも失敗してエラーが出たということがわかります。
一方、
gnutls-cli --port 465
smtp.spmode.ne.jp
のようにして普通に接続して手動でEHLOを発行してやると普通に成功します。
Mewから接続した場合とgnutls-cliで接続した場合で
何が違うのかかなり悩んだのですが、どうもMewが使っている
open-network-streamの中でEHLOを発行してcapabilitiesを取得しており、
戻ってきた後でMewが再度EHLOを発行し、2度目のEHLOに失敗している
のではないか、ということがわかりました。
Mew-debugをみてもEHLOは1回しか登場しませんが、
mitmproxyを使って通信内容をみたところ2回発行されています。
まず、Mewの設定を以下のように変更します。
```.el
(setq mew-smtp-server "localhost")
(setq mew-smtp-ssl 'native)
(setq mew-smtp-ssl-port 8080)
(setq mew-smtp-user "
te...@example.com")
```
次にmitmproxy (mitmdump)でキャプチャしながら
メール送信しようとすると以下のような内容が得られました。
(`--ssl-insecure`が無いとlegacy renegotiaionで失敗する)
```
$ mitmdump --mode reverse:tls://
smtp.spmode.ne.jp:465 --ssl-insecure --set flow_detail=3
[15:35:06.903] reverse proxy to tls://
smtp.spmode.ne.jp:465 listening at *:8080.
[15:35:27.816][[::1]:56308] client connect
[15:35:27.828][[::1]:56308] server connect
smtp.spmode.ne.jp:465 (
49.102.153.242:465)
[::1]:56308 <- tcp <-
smtp.spmode.ne.jp:465
220 ESMTP Server Ready
[::1]:56308 -> tcp ->
smtp.spmode.ne.jp:465
EHLO localhost
[::1]:56308 <- tcp <-
smtp.spmode.ne.jp:465
250-docomo.ne.jp
250-AUTH LOGIN PLAIN
250-AUTH=LOGIN PLAIN
250-SIZE 15727616
250 8BITMIME
[::1]:56308 -> tcp ->
smtp.spmode.ne.jp:465
EHLO localhost
[::1]:56308 <- tcp <-
smtp.spmode.ne.jp:465
503 Bad sequence of commands
[::1]:56308 -> tcp ->
smtp.spmode.ne.jp:465
HELO localhost
[::1]:56308 <- tcp <-
smtp.spmode.ne.jp:465
502 Command not implemented
[::1]:56308 -> tcp ->
smtp.spmode.ne.jp:465
QUIT
[::1]:56308 <- tcp <-
smtp.spmode.ne.jp:465
221 Service closing transmission channel
[15:35:31.185][[::1]:56308] server disconnect
smtp.spmode.ne.jp:465 (
49.102.153.242:465)
[15:35:31.185][[::1]:56308] client disconnect
```
上記のようにmitmproxyでみていると
1回目のEHLOは成功していますが2回目のEHLOは失敗しています。
この時のMew-debugも2回目のEHLO以降だけが見えていて、1回目のEHLOは見えません。
おそらく、世にある多くのSMTPサーバは
EHLOが2回発行されても普通に処理してくれるので発生しないが、
smtp.spmode.ne.jpは2回目がエラーになるため発生する事象なのかなと思います。
次になんでopen-network-streamが中でEHLOを発行しているのかというと、
STARTTLS用にcapabirities取得のためのパラメータを渡しており、
本来STARTTLS不要で最初から暗号化されている場合でも
capabilitiesを取得するためEHLOを発行する動作になっている、
のではないかと思います。
実際、返り値を確認してみるとcapabilitiesが得られていました。
以上、まずは事象のご報告をさせていただきました。
---
細田 真道 <
true...@trueroad.jp>