Archive for March, 2009

mantis无法发送邮件至gmail的解决办法

March 13th, 2009

1. gmail采用的是SSL,在config.inc.php里配置

$g_phpMailer_method = 2;
$g_smtp_host = ’ssl://smtp.gmail.com:465′;
$g_smtp_username = ‘address@mydomain.com’;
$g_smtp_password = ‘myPassword’;

2. 更新class.phpmailer.php, SmtpConnect() function fixed to deal with both the protocol and port being in the host string (it assumes only one colon in the host string)

3. 确认php开启openssl扩展,重新开启扩展的话记得重启web server

参考http://www.mantisbt.org/bugs/view.php?id=8369

  • Share/Save/Bookmark

MSN Messenger协议 原作:bhw98

March 5th, 2009

前 言

MSN Messenger 是Microsoft开发的聊天工具,目前在国内拥有很大的用户群。使用MSN Messenger可以与他人进行文字聊天,语音对话,视频会议等即时交流,还可以通过此软件来查看联系人是否联机等。该软件的最新版本是6.1。

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. 连 接

MSN Messenger协议建立在TCP/IP之上。除了文件传输和语音聊天是直接的”点对点”通信之外,其它所有的情形全部通过服务器进行。

在逻辑上,一共有三种类型的服务器,各司其职:

 

  • 派遣服务器(Dispatch Server, DS) – 客户端最初连接的服务器。负责给客户端分配合适的通知服务器。域名是messenger.hotmail.com,标准服务端口是1863。完成派遣任务后,切断TCP连接。
  • 通知服务器(Notification Server, NS) – 客户端需要一直保持连接的服务器。很多任务要在这个会话内完成,包括登录、改变状态、获取用户列表、修改用户信息、发起聊天、接受呼叫、邮件通知、退出等等。服务端口由派遣服务器指定,通常也是1863。
  • 接线服务器(Switchboard Server, SS) – 客户端之间聊天使用的中转服务器。每开一个聊天窗口,客户端和服务器就建立一个TCP会话。当客户端之间需要进行文件传输或语音聊天时,发送系统消息,建 立”点对点”会话通道(可能转为使用UDP)。服务端口通常也是1863。”点对点” 通信使用的端口由客户端自动协商决定,如文件传输通常使用6891端口。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

    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是一个不存在的账号。

    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请求的应答。

    MSN Messenger协议–错误代码一览

    代码 含义 可能的命令 错误示例 备注
    200 非法命令   ABC 18\r\n
    200 18\r\n
     
    201 非法参数   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 已经登录 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 用户已经在相反的列表中 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 非法组号 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 组名太长 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 缺少必要的参数      
    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协议输入账号和密码,认证通过后,才能取得“入场券”。

    真正意义上的身份认证,发生在客户端与通知服务器(NS)之间。客户端登陆NS时,首先交换版本信息。双方均支持MSNP8以上版本时,才能进行认证过程。如果客户端版本较低,不支持TWN,咋办?服务器会将你一脚揣出去,信不信?

    好了,废话少说,现在拿一个成功认证的例子看看。在下面的例子中,账号是“example@passport.com”,密码是“password”。

    VER 4 MSNP10 MSNP9 CVR0 \r\n
    VER 4 MSNP9 CVR0 \r\n
    CVR 5 0×0804 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
    (此时通过SSL进行身份认证,获得“入场券”)
    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),双方协商MSN版本号。客户端说“我能支持MSNP9和MSNP10”,NS说“行,就MSNP9吧”。

    第二回合(TrID=5),客户端报告本机信息:OS = Windows 2000 (NT 5.0), 语言 = 简体中文,MSN Messenger版本 = 6.1.0203, 账号 = example@passport.com。NS给出了推荐的版本号,能够使用的最老的版本号,新版本下载地址,官方网站地址等信息。

    第三回合(TrID=6),客户端要求身份认证(I = Initial),NS则给出所需要的一长串信息(S = Subsequent)。其中tpf相当于challenge,参与Hash运算,能保证每次认证返回的串是不同的。

    第四回合(TrID=7),客户端出示从认证服务器得到的“入场券”,NS放行(OK)。

    第三、四回合之间,通过SSL的认证过程如下:

    首先在HTTPS端口443向login.passport.com发送一个GET请求,将账号、密码和NS给定的一长串信息送出

    GET /login2.srf HTTP/1.1 \r\n
    Authorization: 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根据情况,会重定向到不同的URL。本例中,重定向到”https://loginnet.passport.com/login2.srf?lc=1033″,服务器应答

    HTTP/1.1 302 Found \r\n Server: Microsoft-IIS/5.0 \r\n
    Date: 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发出请求,得到如下响应

    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

    开始时直接向loginnet.passport.com发出正确的请求,也是可以的。不难看出,在服务器认证成功的返回信息中,Authentication-Info字段的from-PP串值,就是所谓的“入场券”。

    如果认证失败,服务器返回401错误

    HTTP/1.1 401 Unauthorized \r\n … …这样,就无法拿到“入场券”,自然不能在第四回合中输入合法的串。       

    • Share/Save/Bookmark

    php syntax exam

    March 3rd, 2009

    http://www.blueshoes.org/en/developer/syntax_exam/

    在php手册中看到类型比较的时候发现的这个exam,正好测试了下基础,错了几个记录下来

    21. $x = (array(’a'=>’foo’) == array(’b'=>’foo’));
    what is $x?
    you said: TRUE
    right is: FALSE
    好吧,我以为这两个数组比较时值都是ARRAY的说,其实两个数组在比较时并不是转换成字符进行比较的
    array与array的比较,具有较少成员的数组较小,如果运算数 1 中的键不存在于运算数 2 中则数组无法比较,否则挨个值比较

    22.$arrOne = array(”=>”);
    $arrTwo = array(’9′=>’apple’, ‘15′=>’banana’, ‘20′=>’grapefruit’);
    $x = array_merge($arrOne, $arrTwo);
    what is $x?
    1) array(”=>”, 0=>’apple’, 1=>’banana’, 2=>’grapefruit’);
    2) array(”=>”, 9=>’apple’, 15=>’banana’, 20=>’grapefruit’);
    you said: 2
    right is: 1
    具体见array_merge函数
    如果只给了一个数组并且该数组是数字索引的,则键名会以连续方式重新索引。
    如果你想完全保留原有数组并只想新的数组附加到后面,用 + 运算符。

    50. $x = (bool)(”hello” == TRUE);
    what is $x?
    you said: FALSE
    right is: TRUE
    result: wrong
    恩,比较运算符里有详细说明:
    string,resource 或 number与string,resource 或 number比较时, 将字符串和资源转换成数字,按普通数学比较。

    59. $a = “hello”;
    $b = &$a;
    unset($b);
    $b = “world”;
    what is $a?
    you said: world
    right is: hello

    60. $a = “hello”;
    $b = &$a;
    unset($b);
    what is $a?
    you said: null
    right is: hello

    61. $a = “hello”;
    $b = &$a;
    $b = “world”;
    unset($b);
    what is $a?
    you said: null
    right is: world

    好吧,引用后的变量unset不会影响到被引用的变量恩,我一直以为是$b指向$a,实际上是$b和$a指向了同一个地方(即变量内容)而已
    在 PHP 中引用意味着用不同的名字访问同一个变量内容。这并不像 C 的指针,替代的是,引用是符号表别名。注意在 PHP 中,变量名和变量内容是不一样的,因此同样的内容可以有不同的名字。
    当 unset 一个引用,只是断开了变量名和变量内容之间的绑定。这并不意味着变量内容被销毁了。

    66. $a = ‘foo’;
    $b = isSet($a['bar']);
    what is $b?
    you said: FALSE
    right is: TRUE
    result: wrong
    ‘bar’ in $a['bar'] evaluates to int 0 (see the PHP Cheat Sheet at http://www.blueshoes.org/en/developer/php_cheat_sheet/). Then it is $a[0] and now each character in the string $a (foo) can be accessed with its char number, like an array. So that is an ‘f’. And that thing is set.
    这个我以前是真的没注意。。。记下了

    其实对于字符串和字符串的比较,觉得文档上的有点问题,字符串和字符串比较时并不会转换成数字进行比较,只有当其中这两个字符串都为数字字符串时才会作为证书比较。不过对于66中的转换以前还真没注意TAT

    • Share/Save/Bookmark

    驾校考试秘笈,不用看书就能通过

    March 2nd, 2009

    速记方法!
    1、题目里有“口”的选50米,有“站”的选30米,叫“口五站三” 剩下的全选150米,没有150的选最大。判断题全对。

    2、有关公里的题目:城市街道选50公里,其余有30的全选30。 高速最高70,高速最低60。判断题全对。

    3、吊销机动车证的为二年,撤消机动车证的为三年,以醉酒吊销五年,因逃跑而吊销是终身,叫“吊二撤三醉五逃终身”。

    4、伤员急救知识:选择题:A、B、C、“选字最多的”。 判断题:只有“远心端”和“软质担架”是错的,其余都是对的。

    5、危险知识:题目里找“不需要” “不受” “可以” “三层” “坚固无损” 是错的,其余都是对的。

    6、 扣分题:扣1分: “未带证件”判断题:有 “灯光” 和 ”倒车“ 是对的,其余全错。扣2分: 匝道超车(高速),未达20%,打手机,违反标志,超4小时,没有划中心线,实习期,交叉路口 。判断题: ”未与前保持安全距离“ 是对的。其余全错。扣3分: 灯光、信号灯、号牌、高速、挂车,判断题全错。扣6分: 饮酒、超过50%、超过30%,学习驾车(高速),不按规定停车(高速)。判断题全对。扣12分:醉酒、扣证驾车、逃逸、借证驾车,超过三个月未缴罚款, 驾不符合车型的,强行通过。判断题全对。

    7、罚款题:有 ”2000“ 选 ”2000“ ,没 ”2000“ 选 ”500“ ,没有 ”2000以上” 的和没有 ”1000“的罚款。其它全选最大题。考罚款金额的判断题全选正确。

    8、有关天数的题目:只要记住一个调解的选10天,其余有15天选15天,没有15天的选3或90。

    9、有关高度的:出现 ”集装箱“ 选最大,其余选小。

    10、关于作用的 ”变、离、柴、行“ 4个字后有作用全错,其余有作用全对。

    • Share/Save/Bookmark