MSNP9协议[转]
1.1 MSN Messenger协议简介
原作者:汪俊杰
电子邮件:unicentre(at)gmail.com
QQ:10402488
MSN Messenger 是Microsoft开发的聊天工具,目前在国内拥有很大的用户群。使用MSN Messenger可以与他人进行文字聊天,语音对话,视频会议等即时交流,还可以通过此软件来查看联系人是否联机等。
1999年,Microsoft向IETF提交了一份"MSN Messenger Service 1.0 Protocol"草案,这是最初版本的MSN Messenger协议。在以后几年,该公司不再公开有关MSN Messenger协议的升级、修改细节的官方文档。但无论是开发第三方的聊天客户端软件(如Gaim, MyIM等),还是做协议分析,必须对其通信协议有深入了解。
MSN Messenger的协议的最新版为第10版,简称MSNP10,对应于MSN Messenger 6.1。MSN Messenger 6.0则使用MSNP9。现在Microsoft强迫MSN Messenger用户升级到6.0或6.1版,因为服务器对MSNP8以下的版本不再支持。本文及后续文章所描述的MSN Messenger协议主要针对MSNP9/MSNP10。
1.1.1 连接
MSN Messenger协议建立在TCP/IP之上。除了文件传输和语音聊天是直接的"点对点"通信之外,其它所有的情形全部通过服务器进行。
在逻辑上,一共有三种类型的服务器,各司其职:
· 派遣服务器(Dispatch Server, DS) - 客户端最初连接的服务器。负责给客户端分配合适的通知服务器。域名是messenger.hotmail.com,标准服务端口是1863。完成派遣任务后,切断TCP连接。
· 通知服务器(Notification Server, NS) - 客户端需要一直保持连接的服务器。很多任务要在这个会话内完成,包括登录、改变状态、获取用户列表、修改用户信息、发起聊天、接受呼叫、邮件通知、退出等等。服务端口由派遣服务器指定,通常也是1863。
· 接线服务器(Switchboard Server, SS) - 客户端之间聊天使用的中转服务器。每开一个聊天窗口,客户端和服务器就建立一个TCP会话。当客户端之间需要进行文件传输或语音聊天时,发送系统消息,建 立"点对点"会话通道(可能转为使用UDP)。服务端口通常也是1863。"点对点" 通信使用的端口由客户端自动协商决定,如文件传输通常使用6891端口。
1.1.2 命令
MSN Messenger命令使用纯ASCII码。对非ASCII码字符使用URL编码。命令的语法是
XXX[<SP>TrID<SP>PARAM1<SP>PARAM2…]<CRLF>
其中,<SP>是空白字符,<CRLF>是回车换行,XXX是一个3字符的命令串,TrID是一个流水号,PARAMx是参数,[ ]内是可选项。最简单的命令没有流水号和参数。为了方便起见,下面讨论时用" "代表<SP>,""r"n"代表<CRLF>,""x??"代表一个值为0x??字节。红色表示由客户端发出,蓝色表示由服务器发出。一个MSN Messenger命令的例子如下:
USR 18 TWN I example@hotmail.com"r"n
1.1.3 错误
无论是由于客户端发出的命令无效,参数无效,还是其他什么原因,服务器可以返回一个错误。格式为
XXX[<SP>TrID]<CRLF>
其中,XXX是一个3位数字的串。如
ADD 21 AL non_existent@passport.com non_existent@passport.com"r"n
205 21"r"n
上例中,non_existent@passport.com是一个不存在的账号。
1.1.4 消息
MSN Messenger消息符合MIME 1.0标准,由消息头与消息体组成。通常使用UTF-8编码,消息头中也需要URL编码格式,消息体则直接用二进制数据。
一个MSN Messenger消息的例子如下:
MIME-Version: 1.0"r"n
Content-Type: text/plain; charset=UTF-8"r"n
X-MMS-IM-Format: FN=%E5%AE%8B%E4%BD%93; EF=; CO=0; CS=86; PF=0"r"n
"r"n
bhw98"xE4"xBD"xA0"xE5"xA5"xBD"xEF"xBC"x81
经简单分析可知,"%E5%AE%8B%E4%BD%93"是"宋体"的UTF-8加URL编码,而"bhw98"xE4"xBD"xA0"xE5"xA5"xBD"xEF"xBC"x81"是"bhw98你好!"的UTF-8编码。
命令一览
命令 |
来源 |
去向 |
说明 |
备注 |
ACK |
SS |
Client |
确认,做出肯定回答。 |
acknowledgement |
ADD |
Client |
NS |
发出添加新联系人到列表的请求。 |
add user |
NS |
Client |
返回添加新联系人请求的应答。 |
||
ADG |
Client |
NS |
发出添加新联系人组请求。 |
add group |
NS |
Client |
返回添加新联系人组请求的应答。 |
||
ANS |
Client |
SS |
接受聊天连接请求。 |
answer |
BLP |
Client |
NS |
设置对尚未列入明确允许/禁止的联系人列表的保密策略。 |
block list privacy |
NS |
Client |
返回设置保密策略请求的应答。 |
||
BYE |
SS |
Client |
通知客户端结束会话。 |
bye |
CAL |
Client |
SS |
发出建立聊天连接的请求。 |
call |
SS |
Client |
返回建立聊天连接请求的应答。 |
||
CHG |
Client |
NS |
发出改变状态的请求。 |
change state |
NS |
Client |
返回改变状态的应答。 |
||
CHL |
NS |
Client |
服务器发出验证要求。 |
challenge |
SS |
Client |
|||
CVR |
Client |
NS |
发出客户端的OS、语言、MSN Messenger版本等信息。 |
client version |
Client |
SS |
|||
NS |
Client |
返回推荐的MSN Messenger版本、升级软件需要的下载地址等信息。 |
||
SS |
Client |
|||
FLN |
NS |
Client |
通知有联系人列表中的用户下线。 |
off-line |
GTC |
Client |
NS |
设置当有联系人列表中的用户状态改变时给出的提示。 |
greeting to changes? |
NS |
Client |
返回设置请求的应答。 |
||
INF |
Client |
NS |
询问服务器所支持的认证方式。 |
information? |
Client |
SS |
|||
NS |
Client |
返回服务器所支持的认证方式。 |
||
SS |
Client |
|||
ILN |
NS |
Client |
当客户端登录或添加联系人到列表时,通知列表中的联系人的状态。 |
initial online state |
IRO |
SS |
Client |
当有新用户加入聊天连接时,通知客户端该连接中的用户名单。 |
initial roster information |
JIO |
SS |
Client |
通知客户端已经同另外的用户建立了聊天连接。 |
jion |
LSG |
Client |
NS |
发出获取联系人组列表的请求。 |
list groups |
NS |
Client |
返回获取联系人组列表请求的应答。 |
||
LST |
Client |
NS |
发出获取联系人列表的请求。 |
list |
NS |
Client |
返回获取联系人列表请求的应答。 |
||
MSG |
Client |
SS |
发送消息到其他用户(聊天对象)。 |
message |
NS |
Client |
传递服务器(系统) 的消息到客户端。 |
||
SS |
Client |
传递其他用户(聊天对象)的消息到客户端。 |
||
NAK |
SS |
Client |
做出否定回答。 |
negative acknowledgement |
NLN |
NS |
Client |
通知客户端联系人上线或改变状态。 |
on-line |
OUT |
All |
All |
结束客户端-服务器的连接。 |
out |
PNG |
Client |
NS |
测试TCP连接状态。 |
ping |
Client |
SS |
|||
PRP |
Client |
NS |
发出设置个人电话号码的请求。 |
personal phone number |
NS |
Client |
返回设置请求的应答 |
||
PNG |
Client |
NS |
测试TCP连接状态。 |
ping |
Client |
SS |
|||
QNG |
NS |
Client |
返回测试TCP连接状态的应答。 |
quiz ping? |
SS |
Client |
|||
QRY |
Client |
NS |
客户端回答服务器的验证要求。 |
quiz reply? |
Client |
SS |
|||
REA |
Client |
NS |
发出修改用户昵称的请求。 |
rename nickname |
NS |
Client |
返回修改用户昵称请求的应答。 |
||
REG |
Client |
NS |
发出修改联系人组的请求。 |
rename group |
NS |
Client |
返回修改联系人组请求的应答。 |
||
REM |
Client |
NS |
发出从联系人列表中删除用户的请求。 |
rename user |
NS |
Client |
返回删除用户请求的应答。 |
||
RMG |
Client |
NS |
发出删除联系人组的请求。 |
remove group |
NS |
Client |
返回删除联系人组请求的应答。 |
||
RNG |
NS |
Client |
通知客户端有人要建立聊天连接。 |
ring |
SYN |
Client |
NS |
客户端-服务器同步。 |
synchronization |
NS |
Client |
|||
URL |
Client |
NS |
发出获取MSN服务URL的请求。 |
URL |
NS |
Client |
返回获取URL请求的应答。 |
||
USR |
All |
All |
声明、传递、鉴别用户身份。 |
user |
VER |
Client |
DS |
协商MSN Messenger协议版本。 |
version |
Client |
NS |
|||
DS |
Client |
|||
NS |
Client |
|||
XFR |
DS |
Client |
向客户端分配NS(通知客户端转向连接指定的NS)。 |
transfer |
Client |
NS |
发出分配SS的请求。 |
||
NS |
Client |
返回分配SS请求的应答。 |
错误代码一览
代码 |
含义 |
可能命令 |
错误示例 |
备注 |
200 |
非法命令 |
ABC 18"r"n |
||
201 |
非法参数 |
CHG 19 FLN 0"r"n |
||
205 |
用户不存在 |
ADD |
ADD 21 AL none@hotmail.com none@hotmail.com"r"n |
|
206 |
缺少域名 |
|||
207 |
已经登录 |
USR |
USR 20 TWN I example@hotmail.com"r"n |
|
208 |
非法用户名 |
CAL |
CAL 2 @@hotmail.com"r"n |
|
209 |
非法用户昵称 |
REA |
REA 18 one@hotmail.com kill%20microsoft"r"n |
|
210 |
用户太多 |
ADD |
ADD 23 FL one@hotmail.com one@hotmail.com 0"r"n |
最大150 |
215 |
用户已在列表中 |
ADD |
ADD 36 FL one@hotmail.com one@hotmail.com 2"r"n |
|
CAL |
CAL 5 two@hotmail.com"r"n |
|||
216 |
用户不在列表中 |
REM |
REM 14 FL three@hotmail.com"r"n |
|
REA |
REA 48 three@hotmail.com three"r"n |
|||
CAL |
CAL 2 three@hotmail.com"r"n |
|||
217 |
用户不在线 |
CAL |
CAL 2 two@hotmail.com"r"n |
|
218 |
已在指定模式 |
BLP |
BLP 17 BL"r"n |
|
GTC |
GTC 19 A"r"n |
|||
219 |
用户已经在相反的列表中 |
ADD |
ADD 15 AL four@hotmail.com four@hotmail.com"r"n |
|
223 |
用户组太多 |
ADG |
ADG 28 new%20group 0"r"n |
最大30 |
224 |
非法组号 |
ADD |
RMG 24 3"r"n |
|
REM |
RMG 24 3"r"n |
|||
REG |
RMG 24 3"r"n |
|||
RMG |
RMG 24 3"r"n |
|||
225 |
用户不在组中 |
REM |
REM 26 FL six@hotmail.com 3"r"n |
|
229 |
组名太长 |
ADG |
ADG 27 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 0"r"n |
最大60 |
230 |
不能删除组0 |
RMG |
RMG 28 0"r"n |
|
300 |
缺少必要的参数 |
|||
302 |
尚未登录 |
|||
500 |
服务器内部错误 |
|||
540 |
验证应答错误 |
|||
600 |
服务器忙 |
|||
707 |
无法建立连接 |
|||
910 |
服务器忙 |
|||
911 |
身份验证失败 |
过去的MSN Messenger版本(MSNP8以下),简单地使用MD5等Hash算法对用户身份进行认证。MSNP9/MSNP10使用一种TWN (Tweener)认证方式,通过SSL/TLS连接到login.passport.com和loginnet.passport.com等服务器,借助于HTTP协议输入账号和密码,认证通过后,才能取得“入场券”。