MSNP9協(xié)議分析
MSN Messenger協(xié)議
原作:bhw98
前 言
MSN Messenger 是Microsoft開發(fā)的聊天工具,目前在國(guó)內(nèi)擁有很大的用戶群。使用MSN Messenger可以與他人進(jìn)行文字聊天,語(yǔ)音對(duì)話,視頻會(huì)議等即時(shí)交流,還可以通過此軟件來(lái)查看聯(lián)系人是否聯(lián)機(jī)等。該軟件的最新版本是6.1。
1999年,Microsoft向IETF提交了一份"MSN Messenger Service 1.0
Protocol"草案,這是最初版本的MSN Messenger協(xié)議。在以后幾年,該公司不再公開有關(guān)MSN
Messenger協(xié)議的升級(jí)、修改細(xì)節(jié)的官方文檔。但無(wú)論是開發(fā)第三方的聊天客戶端軟件(如Gaim,
MyIM等),還是做協(xié)議分析,必須對(duì)其通信協(xié)議有深入了解。正因?yàn)槿绱耍幸恍┟耖g人士對(duì)這些協(xié)議開展了研究(見本文的"
當(dāng)我們還在感嘆"這世界,變化快"的時(shí)候,MSN Messenger的協(xié)議已經(jīng)到了第10版,簡(jiǎn)稱MSNP10,對(duì)應(yīng)于MSN
Messenger 6.1。MSN Messenger 6.0則使用MSNP9?,F(xiàn)在Microsoft強(qiáng)迫MSN
Messenger用戶升級(jí)到6.0或6.1版,因?yàn)榉?wù)器對(duì)MSNP8以下的版本不再支持。本文及后續(xù)文章所描述的MSN
Messenger協(xié)議主要針對(duì)MSNP9/MSNP10。 1. 連 接 MSN
Messenger協(xié)議建立在TCP/IP之上。除了文件傳輸和語(yǔ)音聊天是直接的"點(diǎn)對(duì)點(diǎn)"通信之外,其它所有的情形全部通過服務(wù)器進(jìn)行。 在邏輯上,一共有三種類型的服務(wù)器,各司其職:
命令 | 來(lái)源 | 去向 | 說(shuō)明 | 備注 |
ACK | SS | Client | 確認(rèn),做出肯定回答。 | acknowledgement |
ADD | Client | NS | 發(fā)出添加新聯(lián)系人到列表的請(qǐng)求。 | add user |
NS | Client | 返回添加新聯(lián)系人請(qǐng)求的應(yīng)答。 | ||
ADG | Client | NS | 發(fā)出添加新聯(lián)系人組請(qǐng)求。 | add group |
NS | Client | 返回添加新聯(lián)系人組請(qǐng)求的應(yīng)答。 | ||
ANS | Client | SS | 接受聊天連接請(qǐng)求。 | answer |
BLP | Client | NS | 設(shè)置對(duì)尚未列入明確允許/禁止的聯(lián)系人列表的保密策略。 | block list privacy |
NS | Client | 返回設(shè)置保密策略請(qǐng)求的應(yīng)答。 | ||
BYE | SS | Client | 通知客戶端結(jié)束會(huì)話。 | bye |
CAL | Client | SS | 發(fā)出建立聊天連接的請(qǐng)求。 | call |
SS | Client | 返回建立聊天連接請(qǐng)求的應(yīng)答。 | ||
CHG | Client | NS | 發(fā)出改變狀態(tài)的請(qǐng)求。 | change state |
NS | Client | 返回改變狀態(tài)的應(yīng)答。 | ||
CHL | NS | Client | 服務(wù)器發(fā)出驗(yàn)證要求。 | challenge |
SS | Client | |||
CVR | Client | NS | 發(fā)出客戶端的OS、語(yǔ)言、MSN Messenger版本等信息。 | client version |
Client | SS | |||
NS | Client | 返回推薦的MSN Messenger版本、升級(jí)軟件需要的下載地址等信息。 | ||
SS | Client | |||
FLN | NS | Client | 通知有聯(lián)系人列表中的用戶下線。 | off-line |
GTC | Client | NS | 設(shè)置當(dāng)有聯(lián)系人列表中的用戶狀態(tài)改變時(shí)給出的提示。 | greeting to changes? |
NS | Client | 返回設(shè)置請(qǐng)求的應(yīng)答。 | ||
INF | Client | NS | 詢問服務(wù)器所支持的認(rèn)證方式。 | information? |
Client | SS | |||
NS | Client | 返回服務(wù)器所支持的認(rèn)證方式。 | ||
SS | Client | |||
ILN | NS | Client | 當(dāng)客戶端登錄或添加聯(lián)系人到列表時(shí),通知列表中的聯(lián)系人的狀態(tài)。 | initial online state |
IRO | SS | Client | 當(dāng)有新用戶加入聊天連接時(shí),通知客戶端該連接中的用戶名單。 | initial roster information |
JIO | SS | Client | 通知客戶端已經(jīng)同另外的用戶建立了聊天連接。 | jion |
LSG | Client | NS | 發(fā)出獲取聯(lián)系人組列表的請(qǐng)求。 | list groups |
NS | Client | 返回獲取聯(lián)系人組列表請(qǐng)求的應(yīng)答。 | ||
LST | Client | NS | 發(fā)出獲取聯(lián)系人列表的請(qǐng)求。 | list |
NS | Client | 返回獲取聯(lián)系人列表請(qǐng)求的應(yīng)答。 | ||
MSG | Client | SS | 發(fā)送消息到其他用戶(聊天對(duì)象)。 | message |
NS | Client | 傳遞服務(wù)器(系統(tǒng)) 的消息到客戶端。 | ||
SS | Client | 傳遞其他用戶(聊天對(duì)象)的消息到客戶端。 | ||
NAK | SS | Client | 做出否定回答。 | negative acknowledgement |
NLN | NS | Client | 通知客戶端聯(lián)系人上線或改變狀態(tài)。 | on-line |
OUT | All | All | 結(jié)束客戶端-服務(wù)器的連接。 | out |
PNG | Client | NS | 測(cè)試TCP連接狀態(tài)。 | ping |
Client | SS | |||
PRP | Client | NS | 發(fā)出設(shè)置個(gè)人電話號(hào)碼的請(qǐng)求。 | personal phone number |
NS | Client | 返回設(shè)置請(qǐng)求的應(yīng)答 | ||
PNG | Client | NS | 測(cè)試TCP連接狀態(tài)。 | ping |
Client | SS | |||
QNG | NS | Client | 返回測(cè)試TCP連接狀態(tài)的應(yīng)答。 | quiz ping? |
SS | Client | |||
QRY | Client | NS | 客戶端回答服務(wù)器的驗(yàn)證要求。 | quiz reply? |
Client | SS | |||
REA | Client | NS | 發(fā)出修改用戶昵稱的請(qǐng)求。 | rename nickname |
NS | Client | 返回修改用戶昵稱請(qǐng)求的應(yīng)答。 | ||
REG | Client | NS | 發(fā)出修改聯(lián)系人組的請(qǐng)求。 | rename group |
NS | Client | 返回修改聯(lián)系人組請(qǐng)求的應(yīng)答。 | ||
REM | Client | NS | 發(fā)出從聯(lián)系人列表中刪除用戶的請(qǐng)求。 | rename user |
NS | Client | 返回刪除用戶請(qǐng)求的應(yīng)答。 | ||
RMG | Client | NS | 發(fā)出刪除聯(lián)系人組的請(qǐng)求。 | remove group |
NS | Client | 返回刪除聯(lián)系人組請(qǐng)求的應(yīng)答。 | ||
RNG | NS | Client | 通知客戶端有人要建立聊天連接。 | ring |
SYN | Client | NS | 客戶端-服務(wù)器同步。 | synchronization |
NS | Client | |||
URL | Client | NS | 發(fā)出獲取MSN服務(wù)URL的請(qǐng)求。 | URL |
NS | Client | 返回獲取URL請(qǐng)求的應(yīng)答。 | ||
USR | All | All | 聲明、傳遞、鑒別用戶身份。 | user |
VER | Client | DS | 協(xié)商MSN Messenger協(xié)議版本。 | version |
Client | NS | |||
DS | Client | |||
NS | Client | |||
XFR | DS | Client | 向客戶端分配NS(通知客戶端轉(zhuǎn)向連接指定的NS)。 | transfer |
Client | NS | 發(fā)出分配SS的請(qǐng)求。 | ||
NS | Client | 返回分配SS請(qǐng)求的應(yīng)答。 |
MSN Messenger協(xié)議--錯(cuò)誤代碼一覽
代碼 | 含義 | 可能的命令 | 錯(cuò)誤示例 | 備注 |
200 | 非法命令 | ? |
ABC 18\r\n 200 18\r\n |
? |
201 | 非法參數(shù) | ? |
CHG 19 FLN 0\r\n 201 19\r\n ADD 20 AL aaa@bbb@ccc aaa@bbb@ccc\r\n 201 20\r\n |
? |
205 | 用戶不存在 | ADD |
ADD 21 AL none@hotmail.com
none@hotmail.com\r\n 205 21\r\n |
? |
206 | 缺少域名 |
|
|
? |
207 | 已經(jīng)登錄 | USR |
USR 20 TWN I
example@hotmail.com\r\n 207 20\r\n USR 21 TWN S 8d30fc782aa25ec9e1293fdda13cab42\r\n 207 21\r\n |
? |
208 | 非法用戶名 | CAL |
CAL 2 @@hotmail.com\r\n 208 2\r\n |
? |
209 | 非法用戶昵稱 | REA |
REA 18 one@hotmail.com
kill%20microsoft\r\n 209 18\r\n |
? |
210 | 用戶太多 | ADD |
ADD 23 FL one@hotmail.com one@hotmail.com
0\r\n 210 23\r\n |
最大150 |
215 | 用戶已在列表中 | ADD |
ADD 36 FL one@hotmail.com one@hotmail.com
2\r\n ADD 36 825 FL one@hotmail.com one@hotmail.com 2\r\n ADD 37 FL one@hotmail.com one@hotmail.com 2\r\n 215 37\r\n |
|
CAL |
CAL 5 two@hotmail.com\r\n CAL 5 RINGING 213697\r\n CAL 6 two@hotmail.com\r\n 215 6\r\n |
|||
216 | 用戶不在列表中 | REM |
REM 14 FL
three@hotmail.com\r\n 216 14\r\n |
|
REA |
REA 48 three@hotmail.com
three\r\n 216 48\r\n |
|||
CAL |
CAL 2
three@hotmail.com\r\n 216 2\r\n |
|||
217 | 用戶不在線 | CAL |
CAL 2 two@hotmail.com\r\n 217 2\r\n |
|
218 | 已在指定模式 | BLP |
BLP 17 BL\r\n BLP 17 151 BL\r\n BLP 18 BL\r\n 218 18\r\n |
|
GTC |
GTC 19 A\r\n GTC 19 152 A\r\n GTC 20 A\r\n 218 20\r\n |
|||
219 | 用戶已經(jīng)在相反的列表中 | ADD |
ADD 15 AL four@hotmail.com
four@hotmail.com\r\n ADD 15 AL 56 four@hotmail.com four\r\n ADD 16 BL four@hotmail.com four@hotmail.com\r\n 219 16\r\n |
|
223 | 用戶組太多 | ADG |
ADG 28 new%20group 0\r\n 223 28\r\n |
最大30 |
224 | 非法組號(hào) | ADD |
RMG 24 3\r\n RMG 24 11506 3\r\n ADD 25 FL five@hotmail.com 3\r\n 224 25\r\n |
|
REM |
RMG 24 3\r\n RMG 24 11506 3\r\n REM 25 FL five@hotmail.com 3\r\n 224 25\r\n |
|||
REG |
RMG 24 3\r\n RMG 24 11506 3\r\n REG 25 3 New%20Name 0\r\n 224 25\r\n |
|||
RMG |
RMG 24 3\r\n RMG 24 11506 3\r\n RMG 25 3\r\n 224 25\r\n |
|||
225 | 用戶不在組中 | REM |
REM 26 FL six@hotmail.com
3\r\n 225 26\r\n |
|
229 | 組名太長(zhǎng) | ADG |
ADG 27
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
0\r\n 229 27\r\n |
最大60 |
230 | 不能刪除組0 | RMG |
RMG 28 0\r\n 230 28\r\n |
|
300 | 缺少必要的參數(shù) | ? | ? | ? |
302? | 尚未登錄 | ? | ? | ? |
500 | 服務(wù)器內(nèi)部錯(cuò)誤 | ? | ? | ? |
540 | 驗(yàn)證應(yīng)答錯(cuò)誤 | ? | ? | ? |
600 | 服務(wù)器忙 | ? | ? | ? |
707 | 無(wú)法建立連接 | ? | ? | ? |
910 | 服務(wù)器忙 | ? | ? | ? |
911 | 身份驗(yàn)證失敗 | ? | ? | ? |
過 去的MSN Messenger版本(MSNP8以下),簡(jiǎn)單地使用MD5等Hash算法對(duì)用戶身份進(jìn)行認(rèn)證。MSNP9/MSNP10使用一種TWN (Tweener)認(rèn)證方式,通過SSL/TLS連接到login.passport.com和loginnet.passport.com等服務(wù)器,借 助于HTTP協(xié)議輸入賬號(hào)和密碼,認(rèn)證通過后,才能取得“入場(chǎng)券”。
真正意義上的身份認(rèn)證,發(fā)生在客戶端與通知服務(wù)器(NS)之間??蛻舳说顷慛S時(shí),首先交換版本信息。雙方均支持MSNP8以上版本時(shí),才能進(jìn)行認(rèn)證過程。如果客戶端版本較低,不支持TWN,咋辦?服務(wù)器會(huì)將你一腳揣出去,信不信?
好了,廢話少說(shuō),現(xiàn)在拿一個(gè)成功認(rèn)證的例子看看。在下面的例子中,賬號(hào)是“example@passport.com”,密碼是“password”。
VER 4 MSNP10 MSNP9 CVR0 \r\nVER 4 MSNP9 CVR0 \r\n
CVR 5 0x0804 winnt 5.0 i386 MSNMSGR 6.1.0203 MSMSGS example@passport.com \r\n
CVR 5 6.0.0602 6.0.0602 5.0.0527 http://download.microsoft.com/download/d/4/f/d4f560d5-6dc6-4901-b149-a568415561d7/SETUPNT.EXE http://messenger.msn.com/cn \r\n
USR 6 TWN I example@passport.com \r\n
USR 6 TWN Slc=1033,id=507,tw=40,fs=1,ru=http%3A%2F%2Fmessenger%2Emsn%2Ecom,ct=1073355862,kpp=1,kv=5,ver=2.1.0173.1, tpf=ed1c2f217a21c191c61251eb8b73bb60 \r\n
(此時(shí)通過SSL進(jìn)行身份認(rèn)證,獲得“入場(chǎng)券”)
USR 7 TWN S t=4m1wWfEupDgUNb53qys5gJdw8OTJEtT82fcuDbS3U672gTymOOs6cgKeafj7WjgZNcufAQggxqHRRXko02DoflZA$$ &p=4QXNnX9rFDDgki9ZqvqPZGDGJa2Mrd5H13Zfl0NNjh4I78qPyfpzmkZPZEe0nxJTkzZSNDYtk!57cVqiYVfO86KgCRYWhi2kudS0M !7bdi82EDA1FYp3WboHD!sCQ17OZh7lPQI7fozrgsSMZwgSzRi2FNTPxf13oDNIfDCKCG!2guDvZKEpk78A$$ \r\n
USR 7 OK example@passport.com example@passport.com 1 0 \r\n
第一回合(TrID=4),雙方協(xié)商MSN版本號(hào)??蛻舳苏f(shuō)“我能支持MSNP9和MSNP10”,NS說(shuō)“行,就MSNP9吧”。
第二回合(TrID=5),客戶端報(bào)告本機(jī)信息:OS = Windows 2000 (NT 5.0), 語(yǔ)言 = 簡(jiǎn)體中文,MSN Messenger版本 = 6.1.0203, 賬號(hào) = example@passport.com。NS給出了推薦的版本號(hào),能夠使用的最老的版本號(hào),新版本下載地址,官方網(wǎng)站地址等信息。
第三回合(TrID=6),客戶端要求身份認(rèn)證(I = Initial),NS則給出所需要的一長(zhǎng)串信息(S = Subsequent)。其中tpf相當(dāng)于challenge,參與Hash運(yùn)算,能保證每次認(rèn)證返回的串是不同的。
第四回合(TrID=7),客戶端出示從認(rèn)證服務(wù)器得到的“入場(chǎng)券”,NS放行(OK)。
第三、四回合之間,通過SSL的認(rèn)證過程如下:
首先在HTTPS端口443向login.passport.com發(fā)送一個(gè)GET請(qǐng)求,將賬號(hào)、密碼和NS給定的一長(zhǎng)串信息送出
GET /login2.srf HTTP/1.1 \r\nAuthorization: Passport1.4 OrgVerb=GET,OrgURL=http%3A%2F%2Fmessenger%2Emsn%2Ecom,sign-in=example%40passport.com,pwd=password, lc=1033,id=507,tw=40,fs=1,ru=http%3A%2F%2Fmessenger%2Emsn%2Ecom,ct=1073355862,kpp=1,kv=5,ver=2.1.0173.1, tpf=ed1c2f217a21c191c61251eb8b73bb60 \r\n
Host: login.passport.com \r\n \r\n
根據(jù)情況,會(huì)重定向到不同的URL。本例中,重定向到"https://loginnet.passport.com/login2.srf?lc=1033",服務(wù)器應(yīng)答
HTTP/1.1 302 Found \r\n Server: Microsoft-IIS/5.0 \r\nDate: Mon, 22 Dec 2003 21:10:05 GMT \r\n
PPServer: H: LAWPPLOG5C006 \r\n
Connection: close \r\n
Content-Type: text/html \r\n
Expires: Mon, 22 Jun 2003 21:09:05 GMT \r\n
Cache-Control: no-cache \r\n
cachecontrol: no-store \r\n Pragma: no-cache \r\n
P3P: CP="DSP CUR OTPi IND OTRi ONL FIN" \r\n
Authentication-Info: Passport1.4 da-status=redir \r\n
Location: https://loginnet.passport.com/login2.srf?lc=1033 \r\n
\r\n ... ...
然后,重新向指定的URL發(fā)出請(qǐng)求,得到如下響應(yīng)
HTTP/1.1 200 OK \r\n
Server: Microsoft-IIS/5.0 \r\n
Date:
Mon, 22 Dec 2003 21:10:07 GMT \r\n
PPServer: H: LAWPPIIS6B061
\r\n
Connection: close \r\n Content-Type: text/html
\r\n
Expires: Mon, 22 Dec 2003 21:09:07 GMT
\r\n
Cache-Control: no-cache \r\n
cachecontrol: no-store \r\n
Pragma: no-cache \r\n
P3P: CP="DSP CUR OTPi IND OTRi ONL
FIN" \r\n
Set-Cookie: ... ... \r\n
Authentication-Info:
Passport1.4
da-status=success,tname=MSPAuth,tname=MSPProf,tname=MSPSec,
from-PP='t=4m1wWfEupDgUNb53qys5gJdw8OTJEtT82fcuDbS3U672gTymOOs6cgKeafj7WjgZNcufAQggxqHRRXko02DoflZA$$
&p=4QXNnX9rFDDgki9ZqvqPZGDGJa2Mrd5H13Zfl0NNjh4I78qPyfpzmkZPZEe0nxJTkzZSNDYtk!57cVqiYVfO86KgCRYWhi2kudS0M
!7bdi82EDA1FYp3WboHD!sCQ17OZh7lPQI7fozrgsSMZwgSzRi2FNTPxf13oDNIfDCKCG!2guDvZKEpk78A$$',
ru=http://messenger.msn.com \r\n
Content-Length: 0 \r\n
\r\n
開始時(shí)直接向loginnet.passport.com發(fā)出正確的請(qǐng)求,也是可以的。不難看出,在服務(wù)器認(rèn)證成功的返回信息中,Authentication-Info字段的from-PP串值,就是所謂的“入場(chǎng)券”。
如果認(rèn)證失敗,服務(wù)器返回401錯(cuò)誤
HTTP/1.1 401 Unauthorized \r\n ... ...這樣,就無(wú)法拿到“入場(chǎng)券”,自然不能在第四回合中輸入合法的串。