telnetでSMTPコマンドを直打ちしてyahooメールを送信する方法


#実行環境
Windows10

#準備
###・yahooメールの設定
デフォルト設定ではtelnet接続できません。よって、yahooメールのページで設定を有効にしておく必要があります。
(参考)https://support.yahoo-net.jp/PccMail/s/article/H000007321

###・telnetの有効化
「win10 telnet 有効化」とかで検索すると画像付きの詳しい解説がたくさん出るのでそちらに任せます。

###・コマンドをまとめておく
解説を読みながらだとタイムアウトしてしまう。


#手順
##1.telnetでyahooのメールサーバーに接続

```
telnet smtp.mail.yahoo.co.jp 587
```

コマンドプロンプトを起動し、telnetコマンドを入力します。
yahooメールのサーバーのアドレスはyahooメールのヘルプに記載されています。
今回は送信なので、送信メールサーバー（SMTPサーバー）の「smtp.mail.yahoo.co.jp」となります。
(参考)https://support.yahoo-net.jp/PccMail/s/article/H000007321

yahooメールのヘルプにはSMTP-AUTHを使用した認証が行われていると記載されています。
よって、サブミッションポートの587で接続しています。
(参考)https://support.yahoo-net.jp/PccMail/s/article/H000011473

詳しくは以下のサイトで解説されています。
(参考)https://www.infraexpert.com/study/tcpip18.html

##2.サーバーにクライアントのドメイン名を知らせる

```cmd:送信コマンド
EHLO localhost
```
```cmd:受信データ
250-smtpgate501.mail.kks.ynwp.yahoo.co.jp
250-PIPELINING
250-8BITMIME
250-SIZE 20480000
250 AUTH PLAIN LOGIN XYMYCONNECT
```

EHLOコマンドを送信します。引数は(基本的には)自分のホスト名を入れます。
以下のサイトに記述されているように、実際には形式的にホスト名を記述しているようなので、「EHLO a」でも送信がうまくいきます。
(参考)http://solaris-user.com/sendmail/smtp-command.html

このコマンドを送信すると、使用できる拡張機能の一覧が返ってきます。
返ってきたデータの最終行が「250 AUTH PLAIN LOGIN XYMYCONNECT」となっています。
SMTP AUTHの認証方式は1つではありません。
EHLOコマンドで返ってきた情報から使える認証方式を知ることができます。
(参考)https://bb.watch.impress.co.jp/cda/bbword/8859.html

帰ってきたデータから、PLAINかLOGINで認証することができることがわかります(XYMYCONNECTの詳細は検索しても出てこないため不明)。
認証方式が事前にわかっているのであれば毎回入力する必要はないと思われます(このコマンドを飛ばしてもメール送信できました)。


##3.認証
PLAINとLOGINの両方の手法について記述します。好きなほうを採用してください。

###AUTH LOGINを使用する場合
```cmd:送信コマンド(LOGINの場合)
AUTH LOGIN
(ユーザー名をbase64でエンコードした値)
(パスワードをbase64でエンコードした値)
```

base64エンコードの方法は後述します。

AUTH LOGINを送信すると、「334 VXNlcm5hbWU6」が返ってきます。
これは「Username:」をbase64エンコードした値です。
これに続けてユーザー名をbase64でエンコードした値を打ち込みます。

その後、「334 UGFzc3dvcmQ6」が返ってきます。
これは「Password:」をbase64エンコードした値です。
これに続けてパスワードをbase64でエンコードした値を打ち込みます。

認証に成功すると「235 ok, go ahead (#2.0.0)」が返ってきます。

###AUTH PLAINを使用する場合
```cmd:送信コマンド(PLAINの場合)
AUTH PLAIN (認証用文字列)
```
認証用文字列は「(ユーザー名)(ヌル文字)(ユーザー名)(ヌル文字)(パスワード)」をbase64で符号化したものとなります。

###base64エンコードを行う方法
####符号化方法1: PowerShellを使う

```powershell:base64エンコード(PowerShell)
$txt = "username`0username`0password"
$byte = ([System.Text.Encoding]::Default).GetBytes($txt)
$b64enc = [Convert]::ToBase64String($byte)
echo $b64enc
```

windowsのデフォルト環境で使用できるのでおすすめです。

上記コードではユーザー名がusername、パスワードがpasswordの場合のPLAIN認証用の認証用文字列を生成する場合の例です。
1行目のGetBytesの引数の""の間に変換したい文字列を入力します。

・PLAIN認証の場合:「(ユーザー名)(ヌル文字)(ユーザー名)(ヌル文字)(パスワード)」
ヌル文字は「\0」ではなく「`0」であることに注意(アポストロフィーではなく、グレイヴ・アクセント([Shift + @]で入力))。

・LOGIN認証の場合:「(ユーザー名)」と「(パスワード)」の2種類

(参考)https://win.just4fun.biz/?PowerShell/PowerShell%E3%81%A7Base64%E3%81%AE%E3%82%A8%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%89%E3%81%A8%E3%83%87%E3%82%B3%E3%83%BC%E3%83%89
(参考)https://ufcpp.net/study/powershell/string.html

####符号化方法2: pythonを使う

```python:base64エンコード(python)
import base64
print(base64.b64encode('username\0username\0password'.encode()))
```

2行目のb64encodeの引数の' 'の間に変換したい文字列を入力します。

・PLAIN認証の場合:「(ユーザー名)(ヌル文字)(ユーザー名)(ヌル文字)(パスワード)」
こちらのヌル文字は「\0」です。

・LOGIN認証の場合:「(ユーザー名)」か「(パスワード)」

出力結果の' 'の間の文字列が変換後の値となります。
(参考)https://techacademy.jp/magazine/28860

####符号化方法3: base64エンコードツールを使う
検索するといくつか出てきます。ただし、ヌル文字に対応していないことがあるので、PLAIN方式の場合は上記の2つのどちらかの手法をおすすめします。

##4.送信元、送信先を送信
送信元には今回使うyahooメールのアドレスを入力します。
受信確認のため、送信先は自分のアドレス(今回のyahooメールのアドレスで良い)を入力します。

・送信元メールアドレス

```cmd:送信コマンド
MAIL FROM: (ユーザー名)@yahoo.co.jp
```


・送信先メールアドレス

```cmd:送信コマンド
RCPT TO: (ユーザー名)@yahoo.co.jp
```

複数の宛先に送信する場合はRCPT TOを宛先の分だけ送ります。

##5.本文

```cmd:送信コマンド
DATA
From: (ユーザー名)@yahoo.co.jp
To: (ユーザー名)@yahoo.co.jp
Subject: Test

test
.
```

DATAの送信後、本文を記入します。
「.」のみの行がメールの文の終了を表します。
この間に送信元アドレス(From:)、送信先アドレス(To:)、タイトル(Subject:)などのヘッダー情報を指定できます。
Fromが未設定の場合、Yahooメール側で弾かれますが、他は入力しなくても送信できます。

ヘッダーについて興味があれば下記のサイト等を確認してください。
(参考)http://www.ep.sci.hokudai.ac.jp/~inex/y2005/0127/jitsugi/index2.html

##6.終了

```cmd:送信コマンド
QUIT
```

QUITでホストとの接続を終了します。


#まとめ
送信するコマンドを以下にまとめます。自分の環境に合わせて書き換えてください。
ここではPLAIN認証の場合を記述しましたが、LOGIN認証の場合も試してみてください。



```cmd:送信コマンド(全体)
telnet smtp.mail.yahoo.co.jp 587

EHLO localhost 

AUTH PLAIN (認証用文字列)

MAIL FROM: (ユーザー名)@yahoo.co.jp
RCPT TO: (ユーザー名)@yahoo.co.jp

DATA
From: (ユーザー名)@yahoo.co.jp
To: (ユーザー名)@yahoo.co.jp
Subject: Test

test
.

QUIT
```