gadfly 回復于:2003-05-27 10:00:45 |
干脆,我把這偏文章做的完善點,方便各位查閱。
轉自http://www.longen.org/S-Z/details~z/SMTPPipelineExtension.htm SMTP服務對命令流水的擴展 1.摘要 本文主要定義了一種SMTP服務擴展,使用這種服務擴展服務器可以說明它在一個TCP發送操作中可以接收多少個指令。在一個TCP發送指令中使用多個操作可以大大提高系統的運行效率。 2. 介紹 雖然SMTP服務已經廣泛使用了,效果也不錯,但是對它的擴展也是不可少的。如果某個網絡需要很長時間進行連接,那SMTP運行的效果可就比較差了。SMTP的時間就費在等待一個個的命令上了。如果能夠使SMTP客戶端進行命令流水,也就是一次發送許多指令,就會提高運行效率。但以前的協議中沒有說明這一條,客戶無法知道服務器能夠同時接收多少指令。因此產生了如下的一些問題: 連接過程中連接失控或緩沖區滿; 在SMTP命令失敗時清除TCP輸入緩沖區,有時這是沒有必要的; 對一些命令會不講道理地判斷它為失敗,例如一些服務器如果在上一個REPT TO 失敗后會再不接收DATA命令,而不管RCPT TO之前的命令是不是成功,而有些服務器則可以在RCPT TO命令失敗后接收DATA命令。 3. 命令流水擴展框架 它的定義如下: 此服務擴展的名稱為流水(Pipelining); 與EHLO相關聯的擴展值是PIPELINING; PIPELINING EHLO不再參數; MAIL FROM或RCPT TO命令不附加其它參數; 沒有附加其它SMTP命令; 4. 流水服務擴展 當客戶機希望使用流水時,它會發送EHLO命令到服務器,如果服務器以250響應(其中的響應包括PIPELINING)就表明服務器支持SMTP服務流水。 4.1. 客戶使用流水 在客戶知道服務器可以支持流水的時候,客戶可以傳輸多個命令(稱為命令組)到服務器,不用發送一條等待一下然后再發一條,特別的RSET,MAIL FROM,SEND FROM,SOML FROM,SAML FROM和RCPT TO可以出現在命令組的任何地方。EHLO,DATA,VRFY,EXPN,TURN,QUIT和NOOP只能出現在命令組中的最后位置,因為它們成功與否將改變SMTP命令所處的狀態。由其它SMTP擴展產生的命令只能出現在組中的最后位置。實際傳送的命令可以是組中的第一個命令。 客戶SMTP必須檢查與組中據有相關的狀態。如果RCPT TP接收地址未被接受,客戶端必須檢查DATA的狀態,客戶端不能假設因為沒有RCPT TO是成功的所以DATA就會失敗。如果DATA命令被正確拒絕,客戶端可以發出RSET,如果DATA命令沒有被正確拒絕,客戶端要發出一個點(dot)。命令所產生的狀態必須和分別發出每個命令時相同,必須支持多行(Multiline)響應??蛻鬝MTP可以選擇在非阻塞狀態運行,它在接收到服務器的響應時立即處理,即使還有數據需要發送也不能推遲對響應的處理。如果不支持非阻塞狀態,客戶端必須檢查TCP窗口的大小,TCP窗口的大小必須大于命令組的大小。窗口大小經常是4K,如果不能進行這樣的檢查,可能會導致死鎖。 4.2. 服務器對流水的支持 服務器應該提供下面的服務擴展: 在任何情況下不行將TCP輸入緩沖區的內容丟棄; 當且僅當接收到一個或多個有效的RCPT TO命令時,才對DATA命令應該主動發出響應; 因為DATA命令沒有合法的接收者,結果接收到空信息時,不要再發出消息給任何人(當然對DATA命令還要做一個響應); 對成組的RSET,MAIL FROM,SEND FROM,SOML FROM,SAML FROM和RCPT TO命令的響應先保存起來,然后一起發送; 不允許緩存對EHLO,DATA,VRFY,EXPN,TURN,QUIT和NOOP的響應; 不允許緩沖不可識別命令的響應; 在本地TCP輸入緩沖區為空時必須將據有未發出的響應全部發出; 不允許對未接收到的命令進行猜測;或假設它的存在; 在響應的文本信息中應該表時這是對哪個命令進行的響應; 5. 例子 下面是一個不支持流水的SMTP會話:其中S代表服務器,C代表客戶端; S: <等待打開連接> C: <打開連接> S: 220 innosoft.com SMTP service ready C: HELO dbc.mtview.ca.us S: 250 innosoft.com C: MAIL FROM:<mrose@dbc.mtview.ca.us> S: 250 sender <mrose@dbc.mtview.ca.us> OK C: RCPT TO:<ned@innosoft.com> S: 250 recipient <ned@innosoft.com> OK C: RCPT TO:<dan@innosoft.com> S: 250 recipient <dan@innosoft.com> OK C: RCPT TO:<kvc@innosoft.com> S: 250 recipient <kvc@innosoft.com> OK C: DATA S: 354 傳輸郵件內容,并以一個只有”.”的行結束郵件 ... C: . S: 250 message sent C: QUIT S: 221 goodbye 在上例中客戶需要9次等待服務器的響應,下面我們來看看在支持流水的情況下是什么樣子:其中S代表服務器,C代表客戶端; S: <等待打開連接> C: <打開連接> S: 220 innosoft.com SMTP service ready C: EHLO dbc.mtview.ca.us S: 250-innosoft.com S: 250 PIPELINING C: MAIL FROM:<mrose@dbc.mtview.ca.us> C: RCPT TO:<ned@innosoft.com> C: RCPT TO:<dan@innosoft.com> C: RCPT TO:<kvc@innosoft.com> C: DATA S: 250 sender <mrose@dbc.mtview.ca.us> OK S: 250 recipient <ned@innosoft.com> OK S: 250 recipient <dan@innosoft.com> OK S: 250 recipient <kvc@innosoft.com> OK S: 354 傳輸郵件內容,并以一個只有”.”的行結束郵件 ... C: . C: QUIT S: 250 message sent S: 221 goodbye 現在等待的次數由9次變為了4次,下面我們看一下當據有接收者均被拒絕時會是什么情況: S: <等待打開連接> C: <打開連接> S: 220 innosoft.com SMTP service ready C: EHLO dbc.mtview.ca.us S: 250-innosoft.com S: 250 PIPELINING C: MAIL FROM:<mrose@dbc.mtview.ca.us> C: RCPT TO:<nsb@thumper.bellcore.com> C: RCPT TO:<galvin@tis.com> C: DATA S: 250 sender <mrose@dbc.mtview.ca.us> OK S: 550 remote mail to <nsb@thumper.bellore.com> not allowed S: 550 remote mail to <galvin@tis.com> not allowed S: 554 no valid recipients given //未給出合法的接收者 C: QUIT S: 221 goodbye 客戶端也等待了4次,如果服務器在接收DATA命令當不檢查接收者的合法性,則是下面的情況: S: <等待打開連接> C: <打開連接> S: 220 innosoft.com SMTP service ready C: EHLO dbc.mtview.ca.us S: 250-innosoft.com S: 250 PIPELINING C: MAIL FROM:<mrose@dbc.mtview.ca.us> C: RCPT TO:<nsb@thumper.bellcore.com> C: RCPT TO:<galvin@tis.com> C: DATA S: 250 sender <mrose@dbc.mtview.ca.us> OK S: 550 remote mail to <nsb@thumper.bellore.com> not allowed S: 550 remote mail to <galvin@tis.com> not allowed S: 354 傳輸郵件內容,并以一個只有”.”的行結束郵件 C: . C: QUIT S: 554 no valid recipients //未給出合法的接收者 S: 221 goodbye |
laixi781211 回復于:2003-05-27 10:09:31 |
謝謝gadfly,收下 |
aaa2520 回復于:2003-05-28 07:38:43 |
呵呵 不錯,有沒有POP3 協議的? |
tutux 回復于:2003-05-28 08:00:19 |
[quote:5fa50b0871="aaa2520"]呵呵 不錯,有沒有POP3 協議的?[/quote:5fa50b0871]
唉~~~沒得救~~~這些公開的常用的協議怎么會沒有?自己搜索一下不就得了? |
居士 回復于:2003-07-02 13:59:07 |
好東西,正在消化中~~~ |
flytod 回復于:2003-07-02 15:22:08 |
SMTP協議中如何區分連接的是客戶端還是另一個SMTP服務器?? |
gadfly 回復于:2003-07-02 17:39:44 |
為什么要區分?從smtp服務本身來說,只要使用smtp服務的就是客戶端。
所以smtp服務器,既是服務器,也是客戶端。 |
startdd 回復于:2003-07-02 22:24:06 |
透徹! |
netkiller 回復于:2003-07-02 22:58:12 |
C: EHLO dbc.mtview.ca.us
c:AUTH LOGIN BASE64 后的用戶名 <cr> BASE64 后的密碼 <cr> C: MAIL FROM:<mrose@dbc.mtview.ca.us> C: RCPT TO:<nsb@thumper.bellcore.com> C: RCPT TO:<galvin@tis.com> C: DATA S: 250 sender <mrose@dbc.mtview.ca.us> OK S: 550 remote mail to <nsb@thumper.bellore.com> not allowed S: 550 remote mail to <galvin@tis.com> not allowed S: 354 傳輸郵件內容,并以一個只有”.”的行結束郵件 C: . C: QUIT 這里是有auth login認證的例子。。 POP,IMAP。。。。。 去網上查rfc 就可得到 |
flytod 回復于:2003-07-03 10:35:22 |
如果是客戶端的話,它要進行auth login 會話,就象netkiller 給出的例子一樣,那如果一個smtp服務器連接上來,肯定是不會進行auth login會話的。那么就不會允許這個smtp服務器來發信。
可以看看我的這個帖子:是我抓的客戶端連接smtp服務器A的auth login會話,還有smtp服務器B連接A的會話(沒有auth login). http://www.chinaunix.net/forum/viewtopic.php?t=104457 BTW: 我在sun的qmail的auth又不起作用了,TNND。難道又要鏟掉重來。 |
netkiller 回復于:2003-07-03 11:27:59 |
目前主流SMTP認證是cram-md5
我沒有做成功。 CRAM-MD5 LOGIN base64(user) base64(md5(passwd)) 不過我沒做成功:( base64(user md5(passwd)) 了沒成功:( |
gadfly 回復于:2003-07-03 11:42:18 |
??
你查過cram-md5確實是這樣的么? md5難道還可逆?我覺得不會這樣吧? 找找cram-md5的協議看看吧 |
netkiller 回復于:2003-07-03 11:57:04 |
to: gadfly
你先看看SMTP認證原理。 cram-md4 rfc 我看過了。。E文不太好??吹鸟R馬糊糊。。 xxxx login 是為了不讓其它用戶listen 得到你的密碼。和 實現沒有用戶發不了郵件。 你可以裝一個tcp抓包工具。抓一下看看。。用戶的所有過程全可以看看。。 包括auth login base64 base64 你可以debase64() 可以看看用戶密碼。。 cram-md5 就安全多了。。 注。認證不是原get user and pass 與 auth login 對比。。 你可以用腦想想。。 你的郵件用戶是放在ldap中。他是crypt or md5的。。但你們auth是明文的。為什么能認證成功呢?:) 但smtp認證時。auth login都可以通過。。 說明: smtp -->auth login -->enbase64(user and pass) ===>MTA debase64(crypt(user)  ![]() |
gadfly 回復于:2003-07-03 15:14:45 |
faint?
這怎么會一樣呢?你也可以用腦子想一想。 一個是明文的用戶名。當然可以用對比密碼加密后的方法了。 你看看你自己怎么寫的?用戶名都是加過密的(md5),服務器怎么知道是哪個用戶? |
flytod 回復于:2003-07-03 15:26:17 |
to:netkiller
你給的這個例子是客戶端軟件連接一個auth smtp服務器的例子。你能給我講講某個smtp服務器連接一個需要auth smtp服務器之間的應答情況嗎?我實在是弄不清楚了。 |
netkiller 回復于:2003-07-03 15:35:12 |
你先看看 rfc2554.txt 在說。。
用戶密碼的確被md5.后在認證。 Examples: S: 220 smtp.example.com ESMTP server ready C: EHLO jgm.example.com S: 250-smtp.example.com S: 250 AUTH CRAM-MD5 DIGEST-MD5 C: AUTH FOOBAR S: 504 Unrecognized authentication type. C: AUTH CRAM-MD5 S: 334 PENCeUxFREJoU0NnbmhNWitOMjNGNndAZWx3b29kLmlubm9zb2Z0LmNvbT4= C: ZnJlZCA5ZTk1YWVlMDljNDBhZjJiODRhMGMyYjNiYmFlNzg2ZQ== S: 235 Authentication suclearcase/" target="_blank" >ccessful. 注:仔細看 C: AUTH CRAM-MD5 S: 334 PENCeUxFREJoU0NnbmhNWitOMjNGNndAZWx3b29kLmlubm9zb2Z0LmNvbT4= 出這東東表。服務已經準備好??梢哉J證 C: ZnJlZCA5ZTk1YWVlMDljNDBhZjJiODRhMGMyYjNiYmFlNzg2ZQ== 用戶 <空格> md5(密碼) 發給服務器。。 S: 235 Authentication successful. 成功了。。 我將 ZnJlZCA5ZTk1YWVlMDljNDBhZjJiODRhMGMyYjNiYmFlNzg2ZQ== debase64后得出 fred 9e95aee09c40af2b84a0c2b3bbae786e fred用戶,后面是密碼。。 不信你自己看。。 我沒有測試過我是不會說的。。因為這樣會誤導其它人。。 |
gadfly 回復于:2003-07-03 15:46:59 |
//faint,你小子。
你之前的回答明明是md5(base64(user)) md5(base64(密碼)),我針對的疑問就是這個,是不是給你改掉了?還是我看錯了? ![]() ![]() 呵呵,沒試過這種方式。 |
gadfly 回復于:2003-07-03 16:02:37 |
你建一個和他例子一樣的用戶和密碼,手工試試看,有問題么? |
netkiller 回復于:2003-07-03 16:02:52 |
rfc里是
base64(user md5(pass)) 但我用了。不通 后來我又多次試驗也沒通。。 如: base64(md5(user)) base64(md5(pass)) 不行 base64(user) base64(md5(user)) 也不行。。 我在懷疑。是不是smtp不支持。。我就的是別人的qmail 163.com不支持。cram-md5 |
gadfly 回復于:2003-07-03 16:05:00 |
用戶名是肯定不能md5的。
qmail的auth patch中,nimh那個不支持cram方式 |
netkiller 回復于:2003-07-03 16:16:52 |
to:flytod
smtp <==握手 ---> 投遞 ==> smtp 應該是由MAILER-DAEMON 來完成的吧。 mailq可以看到隊列。 投遞是不用認證的。。就象。 你寫一封信,要填地址,郵編。(相當于SMTP認讓。如果不寫地址郵局是不給你發的。。)--->深圳的郵電局 ---將信或other 交給--> 北京郵局-->用戶手里。 你可在UNIX like下用mail -s test xxx@xxx.com </etc/passwd 就可以發郵件。但不用認證。 所以你可以用第三個SMTP server 用拔號IP發拉圾郵。:)它只提供SMTP ===> ISP SMTP。它沒有收的功能。只能發。。 以上只供參考。我說的也不一定就準確。大家還要自己查資料。 |
gadfly 回復于:2003-07-03 16:24:50 |
我看了三大門戶,沒有支持cram auth的 |
netkiller 回復于:2003-07-03 16:28:47 |
如果大家對這個些感興趣。
可以玩玩socket 編程。。 不要認為SOCKET很難。。說白了。就是對講機。 police:呼叫,0101,over 0101: 明白,請講.over 這就是握手,也就是helo過程。 police:這邊有小偷,over 0101:明白,地址,over pollice: 地址:深南中路,華強北,SEG廣場,\n 樓層:四樓 \n 位置:xxxx柜臺 \n . \n over 0101:明白,over quit 如果深入學習。會涉及到多線程,線程間同步/通信,挺好玩的。。 當你學會SMTP,POP,其它也是同樣實現的。。:) http://cvsweb.9812.net news Module 這是一個新聞組client程序,是socet寫的。。大家可以看看。。 |
gadfly 回復于:2003-07-03 16:41:54 |
呵呵,netkiller說得形象。
沒錯tcp協議就是這個樣子的。只要知道tcp的協議格式(通用協議都有rfc),就可以用telnet 手工測試 |