http://www.cqinc.com.tw/coopermaa/932-DC/practice/SMTPCmds.htm
SMTP 指令說明
Summary
儘管 WWW 和 IM (Instant Messaging) 相繼起而流行,E-Mail
這個最為古老、行之有年的網路服務,還是公認為目前最有效的溝通工具。為了要發出一封信件,Mail Client 會與遠端的 Mail Server
建立起通信的管道,它們彼此之間你來我往資料傳送時,共同遵守著同一套規則: SMTP 協定 (Simple Mail Transfer Protocol)。
底下說明幾個常用的 SMTP 指令,還有 Mail Server 回傳代碼的意義。
註:其實可以利用 telnet 工具,讓 telnet 程式扮演
Mail Client 的角色來與 Mail Server 建立連線、溝通並發出信件,方便練習這邊所介紹的 SMTP 指令。可參考這份影片。
SMTP Commands
下列是 Mail Client 用來與 Server 溝通的指令。這些指令沒有大小寫的區別(not case
sensitive)。
HELO |
|
|
啟始與 Mail Server 之間的對話。一般來說,HELO 是 Mail client
送出的第一個指令,用途是告訴 Mail Server 來者為何,通常我們會把電腦的 domain name 告訴 Server。例如:
Helo mail.companyName.com
|
MAIL FROM |
|
|
告訴 Server 發信人是誰,例如:
MAIL FROM: google@yahoo.com
注意,這邊的發信人郵件地址並不會顯示在信件的寄件者欄中,當信件無法順利送到目的地時,退回的信件就會寄到這個地方。(寄件者欄、收件者欄、標題欄、副本、密件副本欄,這些是在
Message 的 Header 中指定的。有關 Mail Message 的格式,請參考
Email Service 投影片。) |
RCPT TO |
|
|
告訴 Server 收件人是誰,例如:
RCPT TO: yahoo@google.com
如果需要同時寄一封信給很多人,多下幾次 RCPT TO 指令即可。如果給的不是完整的 e-mail address,代表要寄信到該台
Mail Server 的指定信箱,例如:
RCPT TO: kimo
意思就是要寄信到連線中這台 Mail Server 的 kimo 這個信箱。有一點要注意的是,為了避免成為發垃圾信的工具,大部份 Mail
Server 是不允許你透過它寄信到其它地方的,除非先經過身份的確認。 |
DATA |
|
|
告訴 Server 你已經準備好要開始輸入信件的本文了(Mail Message, 包括 Message
Header 與 Message Body)。要結束 Message 的輸入時,在信件結尾輸入個 . 點符號即可。 |
NOOP |
|
|
NOOP 是『NO OPeration 』的縮寫,用途是請 Server 回應一下,藉此讓 Client
得以確定與 Server 的連線還在。 |
QUIT |
|
|
結束對話,關閉與 Server 間的連線。 |
SMTP Server Reply codes
每當 Mail Client 丟出一個指令,Server 這端就會回應一個固定格式的訊息:一個 3
位數的數字,然後緊接的一串文字描述,說明 Server 收到 client 端傳來的指令之後,Server 處理完後的情形,例如:
250 ok
或是
221 Bye bye
底下列出 Mail Server 回傳的各個代碼以及文字說明(只要下的 SMTP
指令正確,底下絕大部份的代碼應該都不會遇到的!):
221 |
|
|
A system status or help reply |
214 |
|
|
Help Message |
220 |
|
|
The server is ready. |
221 |
|
|
The server is ending the conversation. |
250 |
|
|
The requested action was completed |
251 |
|
|
The specified user is not local, but the server will
forward the mail message |
354 |
|
|
This is a reply to the DATA command. After getting
this, start sending the body of the mail message, ending with
"\r\n.\r\n." |
421 |
|
|
The mail server will be shut down. Save the mail
message and try again later |
450 |
|
|
The mailbox that you are trying to reach is busy.
Wait a little while and try again. |
451 |
|
|
The requested action was not done. Some error
occurmiles in the mail server |
452 |
|
|
The requested action was not done. The mail server
ran out of system storage. |
500 |
|
|
The last command contained a syntax error or the
command line was too long. |
501 |
|
|
The parameters or arguments in the last command
contained a syntax error. |
502 |
|
|
The mail server has not implemented the last command.
|
503 |
|
|
The last command was sent out of sequence. For
example, you might have sent DATA before sending RECV |
504 |
|
|
One of the parameters of the last command has not
been implemented by the server. |
550 |
|
|
The mailbox that you are trying to reach can't be
found or you don't have access rights. |
551 |
|
|
The specified user is not local; part of the text of
the message will contain a forwarding address. |
552 |
|
|
The mailbox that you are trying to reach has run out
of space. Store the message and try again tomorrow or in a few
days-after the user gets a chance to delete some messages. |
553 |
|
|
The mail address that you specified was not
syntactically correct |
554 |
|
|
The mail transaction has failed for unknown causes.
|
SMTP Authentication
由於 SMTP 協定極為簡單,任何人只要懂得 SMTP 指定,就有可能寫出自動發廣告信、垃圾信的程式。為了防堵這些日益氾濫的垃圾信件,後來就出現了加強版的 ESMTP 協定 (Enhanced SMTP ),支援 ESMTP 的 Mail Server
會對那些和它連線的 Mail Client 有較為嚴格的要求,在某些狀況下,例如要透過 Server
發信到其它地方,而非寄到本地的信箱時,限制他們必須先通過身份的驗證,才允許發信出去。(換句話說,如果你透過了身份的確認,要發信到什麼地方都是可以的!)
一般而言,現在網路上的 Mail Server 主要支援兩種驗證身份的方式: 1. 明碼驗證 和 2. base64
編碼驗證。
-
明碼驗證
明碼驗證指的是,當 Client 要跟 Server 進行身份驗證時,傳送的 username 和 password 不需要經過任何編碼,只要送給
Server 端 AUTH PLAIN 這個指令後,再直接將 username 和 password 傳給 Server 端,Server
就會進行身份的驗證。(註:大部份 Mail Server 甚至連明碼驗證都覺得不夠安全,因而捨棄這種方式只支援 base64 編碼驗證!)
-
base64 編碼驗證
當 Client 端送出 AUTH LOGIN 這個指令到 Server 端時,代表著要使用 base64
編碼的身份驗證。此時 Client 端就必須先將 username 和 password 以 base64 演算法編碼之後,再傳送給 Server
端,Server 這端在拿到編碼字串後先做解碼然後再進行驗證。底下是個 base64 編碼驗證成功的範例畫面,畫面上的 username 和 password 已經使用 base64 演算法編碼過。:
你可以不用自己撰寫 base64 演算法,有一些網站提供了線上
base64 編碼的服務,例如:http://www.motobit.com/util/base64-decoder-encoder.asp。在
ActiveTcl 中,也有 base64 的套件可供使用,底下是個 base64 編碼的範例:
# Load base64 package
package require base64
# encode username "maa", you'll get "bWFh"
base64::encode maa
# encode password "12345", you'll get "MTIzNDU="
base64::encode
12345