ターミナルからSMTPを使ってGMailの送信機能を使う

SMTPの学習のために、MacのターミナルからSMTPのメール送信を行った際のメモ。
なお、MTAとしてGmailを使用した結果、認証周りがちょっとめんどくさいことになってます。

## Gmailの認証の準備
使いたいGmailアドレスに紐付いたGoogleアカウントで、ログインのための設定を行います。
二段階認証をオンにしているのは、App Passwordを取得するために必要だからです(2017年12月現在。二段階認証がオフの場合、App Passwordを生成出来ない)。

### 二段階認証をオンにする
![SS 2017-12-17 18.11.16.png](https://qiita-image-store.s3.amazonaws.com/0/162670/e6da3e43-82cb-7574-c861-35459df1dbce.png)

![2factorAuth.png](https://qiita-image-store.s3.amazonaws.com/0/162670/3dda0080-dcfb-3ffb-0b88-87e27966cace.png)

ここからガイドに従って２段階認証をオンにします。詳細は省略。

### App Passwordを取得する
![app_password.png](https://qiita-image-store.s3.amazonaws.com/0/162670/385a5f26-58d6-bf3f-d5cd-34d5c7bd0f69.png)

![app_password_setting.png](https://qiita-image-store.s3.amazonaws.com/0/162670/99f697a1-a13b-dc02-333e-e8adc7d83166.png)
ここでパスワードを使うアプリを設定してGenerateボタンを押せば、生成されたアプリパスワードが表示されます。

### 認証情報をエンコードする
使いたいGmailアドレスと、先程生成したアプリパスワードをエンコードします。
生成した文字列は後で使用します。

```
$ perl -MMIME::Base64 -e 'print encode_base64("\000<your address>\@gmail.com\000<your app password>")'
AGh1cmFpYm9hcmF3YXJ1QGdt**lsLmNvbQBub*******************
```

## ターミナルでSMTP/メール送信
ここからターミナル上での作業になります。

### ハンドシェイク
まずopensslで接続。

```
$ openssl s_client -connect smtp.gmail.com:465 -crlf -ign_eof
CONNECTED(00000003)
depth=1 /C=US/O=Google Trust Services/CN=Google Internet Authority G3
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=smtp.gmail.com
   i:/C=US/O=Google Trust Services/CN=Google Internet Authority G3
 1 s:/C=US/O=Google Trust Services/CN=Google Internet Authority G3
   i:/OU=GlobalSign Root CA - R2/O=GlobalSign/CN=GlobalSign
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIEgjCCA2qgAwIBAgIIdz
(中略)
Fz6gdcD8XCa659Y1LzeVP
KprrPbe/
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=Mountain View/O=Google Inc/CN=smtp.gmail.com
issuer=/C=US/O=Google Trust Services/CN=Google Internet Authority G3
---
No client certificate CA names sent
---
SSL handshake has read 2450 bytes and written 456 bytes
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : AES128-SHA
    Session-ID: D11458D54697952FC7A2B3E3D2F2D381BA8FB182********
    Session-ID-ctx: 
    Master-Key: E40FA261C28BFE0B7CD1C4B632D422F57CC378903D4668AFB1989F13BD*******
    Key-Arg   : None
    Start Time: 1513499273
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
220 smtp.gmail.com ESMTP y5sm20673604pfd.63 - gsmtp
```

### 認証まで
次に初めの挨拶をして、認証をかけます。 初めの挨拶を忘れると怒られます。挨拶重要。 ここで先程エンコードした認証情報を使います。

```
# 初めの挨拶
EHLO localhost
250-smtp.gmail.com at your service, [125.193.58.55]
250-SIZE 35882577
250-8BITMIME
250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8

# 認証
AUTH PLAIN AGh1cmFpYm9hcmF3YXJ1QGdt**lsLmNvbQBub*******************
235 2.7.0 Accepted
```

これで認証が完了です。ここからメール本文の入力に移ります。

### メール本文の入力

```
# ヘッダ
MAIL FROM: <your_address@gmail.com> 
250 2.1.0 OK y5sm20673604pfd.63 - gsmtp

RCPT TO: <your_addressée@domein.com>
250 2.1.5 OK y5sm20673604pfd.63 - gsmtp

#メールの内容の開始はDATAコマンド
DATA
354  Go ahead y5sm20673604pfd.63 - gsmtp

# メールの件名
Subject: test_smtp

# メタデータ
Mime-Version: 1.0;
Content-Type: text/plain; charset="ISO-8859-1";           
Content-Transfer-Encoding: 7bit;

# メール本文
test smtp
hello
.      # 本文の終了記号　メール本文には反映されない
250 2.0.0 OK 1513499865 y5sm20673604pfd.63 - gsmtp

# 終了するときはQUITコマンド
QUIT
221 2.0.0 closing connection y5sm20673604pfd.63 - gsmtp
read:errno=0
```

### 送信結果
Gmail上での表示結果
<img width="275" alt="SS 2017-12-17 18.09.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/162670/d46794e7-9cc7-28f2-454a-9c18249ae8f1.png">


## Reference
認証情報のエンコードはここの方法を使用。
[How to send email using simple SMTP commands via Gmail? - Stack Overflow](https://stackoverflow.com/questions/11046135/how-to-send-email-using-simple-smtp-commands-via-gmail)

手順はこのページを参照。
[Gmailにopensslで接続してhtmlメールを送る](https://qiita.com/taketon_/items/37e6c797ef8c901c2524)

その他
[SMTP の認証プロトコルを手作業で確認する](http://takuya-1st.hatenablog.jp/entry/2015/03/12/192435)
[telnetでメール送信](http://ash.jp/net/telnet_smtp.htm)
[SMTP認証](http://www.bnote.net/dataroom/smtp_auth.html)
[[Sy] MacからGmailのSMTPサーバ経由でメールを送信できるようにする手順](https://utano.jp/entry/2014/06/send_mail_from_local_mac/)
[お使いのGmailのsmtpを使って、macのメールコマンドでメール送信を許可する設定の方法](http://www.aipacommander.com/entry/2014/10/31/151649)
[携帯電話宛バウンスの仕組みを推測する | Sisimai: Mail Analyzing Interface](http://libsisimai.org/ja/docs/mechanism-of-email-bounce.html) (SMTPの知識の応用例)