GnusでSTARTTLSが必要なSMTPサーバからメール送信ができない

最近、GnusでGmailを扱おうと試みています。
メール一覧が取得できたので、そのメールに対して返信しようとしたら、以下のエラーが表示されてしまいました。

smtpmail-send-it: Sending failed: 530 5.7.0 Must issue a STARTTLS command first. iu7sm33066021pbc.45 - gsmtp

ちなみに、メール送信の設定は以下のようにしています。

(setq message-send-mail-function    'smtpmail-send-it)
(setq smtpmail-starttls-credentials '(("smtp.gmail.com" 587 nil nil)))
(setq smtpmail-auth-credentials     "~/.authinfo.gpg")
(setq smtpmail-default-smtp-server  "smtp.gmail.com")
(setq smtpmail-smtp-server          "smtp.gmail.com")
(setq smtpmail-smtp-service         587)

調査

エラーメッセージをググってみると、以下のページが見つかりました。

英語は不得手なのですが、どうもgnutls-cliというプログラムの有無について言及されています。
gnutls-cliは、こちらのメール受信で起きた問題の調査をした時に、そういうものがあるというのは知っていました。
どうやらGnusから通信を行う時の手段を幾つか選択できるようになっているようで、私はOpenSSLを使うように設定することで解決していました。
にも関わらず、送信はOpenSSLじゃダメなんてのはないだろと。

で、調べてみると、GmailSMTPサーバを使ってOpenSSLでメール送信することはできるようでした。

なので、Gnusでもできるはずだと思い、ソースを見てみたところ解決しました。

対処

以下の設定を行うことで上手くいきました。

(setq smtpmail-stream-type 'ssl)

(defadvice smtpmail-send-it (around fix-using-openssl activate)
  (let ((tls-program (or (when (eq smtpmail-stream-type 'ssl)
                           '("openssl s_client -connect %h:%p -no_ssl2 -ign_eof -starttls smtp"))
                         tls-program)))
    ad-do-it))

※上記以外にこちらの対処も実施する必要があります。

対処内容について

上記のようにmessage-send-mail-functionを設定している場合、メール送信時、smtpmail-via-smtpという関数から open-network-streamが実行されます。
open-network-streamという関数は、受信時にも使われている関数で、typeスロットの指定によって接続処理が変わります。
受信時はsslが指定されていましたが、送信ではsmtpmail-stream-type変数の値を渡しているので、 smtpmail-stream-typeにsslを設定すればOpenSSLが使われるようになります。

なのですが、その場合実行されるのはtls-programという変数に定義されたプログラムで、それはデフォルトでは以下のようになっています。

(defcustom tls-program '("gnutls-cli --insecure -p %p %h"
                         "gnutls-cli --insecure -p %p %h --protocols ssl3"
                         "openssl s_client -connect %h:%p -no_ssl2 -ign_eof")
  "List of strings containing commands to start TLS stream to a host.
・・・

上記リストのコマンドを、接続が成功するまで順に試行するという処理になっており、opensslコマンドで成功するわけですが、 STARTTLSを使わないとGmailからメール送信できないようで(上記リンクでも言及されています)、送信処理が終わらずEmacsがフリーズしてしまいます。
そのため、smtpmail-send-itにアドバイスをかまし、tls-programの値をstarttlsオプションを付けてopensslを実行するように変更しています。

その他

  • Emacsは、GNU Emacs 24.2.1 (i386-mingw-nt5.1.2600) of 2012-12-08 on GNUPACK です。
  • Gnusは、Gnus v5.13 です。

あとがき

GnusのInfoも大して読んでないし、上記リンクの英語ページの記述も大して理解してないので、 もっとちゃんとした対処方法があるような気もします。
なので、あくまで一例としてご理解頂ければと思います。