SMTPサーバーのユーザー・パスワードが正しいかを確認する

# はじめに

メール関連で問題が発生した場合に、疑いがかかる部分がサーバー側のユーザー情報の不一致がある。 今までは動作していても、誰かのオペレーションによって削除されていたり、定期パスワードの変更にあって、利用者までその情報が降りてきていないといったことが考えられる。

今回、与えられたユーザー情報でメールの送信が行えないということがあったので、実際にそのユーザー情報が正しいかどうかをコマンドで確認する方法を調査した。

# 検証環境

さくらのメールサーバーを契約しているので、これを使って検証。

検証用ユーザー: `authtest` を作成。 利用するパスワードは `password` とする。
この時、SMTP のポートや、ユーザー名の付け方は[こちらの記事を参考](https://help.sakura.ad.jp/206054182/) にして、以下の様な値になる。

| コンテンツ | 内容 |
| -----------+------ |
| SMTPサーバー | `********.sakura.ne.jp` (個別ユーザーに紐づくサーバー名) |
| STMPポート | 587 |
| SSL | STARTTLS |
| ユーザー名 | `authtest@********.sakura.ne.jp` (あるいは独自に割り振ったドメイン) |
| パスワード | `password` |

# ログイン認証

Base64 でやり取りする部分があるため、ユーザー名、パスワードの Base64 表現を取得する。

```bash
$ printf "authtest@********.sakura.ne.jp" | base64
YXV0aHRlc3RAKioqKioqKiouc2FrdXJhLm5lLmpw
$ printf "password" | base64
cGFzc3dvcmQ=
````

その後、`openssl` コマンドで接続して、`AUTH LOGIN` を実施する。 以下が具体例だが `>` が先頭の部分がコマンド内での入力部分 (実際には表示されず、入力待ちになる点に注意)。

```bash
$ openssl s_client -quiet -connect ********.sakura.ne.jp:587 -starttls smtp
depth=2 C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
verify return:1
depth=1 C = JP, ST = Tokyo, L = Chiyoda-ku, O = Gehirn Inc., CN = Gehirn Managed Certification Authority - RSA DV
verify return:1
depth=0 CN = *.sakura.ne.jp
verify return:1
250 HELP
> AUTH LOGIN
334 VXNlcm5hbWU6
> YXV0aHRlc3RAKioqKioqKiouc2FrdXJhLm5lLmpw
334 UGFzc3dvcmQ6
> cGFzc3dvcmQ=
235 2.0.0 OK Authenticated
```

この流れで認証が成功するか否かを確認できる。 一方、失敗した場合は `535 5.7.0 authentication failed` が返る。

この方法で SMTP サーバーに接続可能な認証情報の確認を行える。


# 追記: office365サーバーの場合 - 追加のオプションが必要

Office365 でログインを試してみようと上記と同じ流れでコマンドを入力したのだが、何も表示が返ってこない事象に遭遇した。 SMTP サーバー設定については以下から

https://docs.microsoft.com/ja-jp/exchange/mail-flow-best-practices/how-to-set-up-a-multifunction-device-or-application-to-send-email-using-microsoft-365-or-office-365

```bash
$ openssl s_client -quiet -connect smtp.office365.com:587 -starttls smtp
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, CN = DigiCert Cloud Services CA-1
verify return:1
depth=0 C = US, ST = Washington, L = Redmond, O = Microsoft Corporation, CN = outlook.com
verify return:1
250 SMTPUTF8
AUTH LOGIN
(いくら待ってもなにも返答が返らない...)
```

色々探してみたのだが、オプション `-crlf` が必要だった。 コマンドに `-crlf` オプションを付けて上記の通りに実行すると、

> AUTH LOGIN
> 503 5.5.2 Send hello first [TY2PR02CA0019.apcprd02.prod.outlook.com]

として、最初に HELLO ( `EHLO` ) を送らなければいけなかった。
以上をまとめて、サーバーによっては以下のようにする必要があることが分かった。

```bash
$ openssl s_client -quiet -connect smtp.office365.com:587 -crlf -starttls smtp
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, CN = DigiCert Cloud Services CA-1
verify return:1
depth=0 C = US, ST = Washington, L = Redmond, O = Microsoft Corporation, CN = outlook.com
verify return:1
250 SMTPUTF8
EHLO
250-TYCPR01CA0060.outlook.office365.com Hello [202.126.28.177]
250-SIZE 157286400
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-AUTH LOGIN XOAUTH2
250-8BITMIME
250-BINARYMIME
250-CHUNKING
250 SMTPUTF8
AUTH LOGIN
334 VXNlcm5hbWU6
...(以下同様なので省略)
```

# 参考

https://fsck.jp/?p=808