openssl s_client で chat.facebook.com に STARTTLS で接続する ― 2012年09月04日
先日書いた「facebook のチャットをパソコンの専用のクライアントで」で XMPP で facebook のチャットに接続することを書いたのですが、これをちょっと手動でやってみたくなりました。
SSL/TLS でつなぎたいので、openssl の s_client で STARTTLS するように指示してつないでみます。openssl の s_client コマンドは -starttls
の後にプロトコルを指定すると、プロトコルごとの STARTTLS を実行し、SSL/TLS が開始されます。メールなら -startls smtp
などとしますが、XMPP なので、-starttls xmpp
とします。
$ openssl s_client -starttls xmpp -connect chat.facebook.com:5222 CONNECTED(00000003) --- no peer certificate available --- No client certificate CA names sent --- SSL handshake has read 400 bytes and written 122 bytes --- New, (NONE), Cipher is (NONE) Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE ---
あれ? SSL/TLS のハンドシェイクがうまくいってないようです。原因が知りたいので、TELNET で chat.facebook.com につないで確認します。
$ telnet chat.facebook.com 5222
(略)
クライアント→サーバー: <?xml version="1.0"?><stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client' to='chat.facebook.com' version='1.0'>↵
サーバー→クライアント: <?xml version="1.0"?><stream:stream id="BC39B9EB" from="chat.facebook.com" version="1.0" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" xml:lang="en"><stream:features><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>X-FACEBOOK-PLATFORM</mechanism><mechanism>DIGEST-MD5</mechanism></mechanisms></stream:features>
クライアント→サーバー: </stream:stream>↵
サーバー→クライアント: </stream:stream>
Connection closed by foreign host.
<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>
がサーバーからの応答にあるので、STARTTLS は使えるはずです (参考: RFC 3920 Section 5.1 等)。なぜ openssl が正常に動作しないのかわかんないので openssl のソースコードを見ます。
openssl.orgから 1.0.1c のソースコードを持ってきて apps/s_client.c を見てみます。
1475 while (!strstr(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'")) 1476 { 1477 if (strstr(mbuf, "/stream:features>")) 1478 goto shut;
えらく単純な文字列検索で判定しているようです。starttls
開始タグ内の xmlns
属性の値がシングルクォートで括られていることを前提としていますね。しかし chat.facebook.com の応答では xmlns="urn:ietf...
のように、ダブルクォートで括られています。うーん、ちゃんと XML を parse しないといけんかねぇ、と思って、openssl の request tracker を見てみます。ありました。
#2565: More tolerant detection of XMPP starttls sequence
ここにあるパッチを見ると、strstr
が strcasestr
に置き換えられ、かつ、シングルクォートだけでなくダブルクォートの候補についても検索されるようになってます。
パッチをあてて、コンパイルし、再度実行します。
$ ./openssl s_client -starttls xmpp -connect chat.facebook.com:5222 CONNECTED(00000003) depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance CA-3 verify error:num=20:unable to get local issuer certificate verify return:0 --- Certificate chain 0 s:/C=US/ST=California/L=Palo Alto/O=Facebook, Inc./CN=chat.facebook.com i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3 1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3 i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA --- Server certificate -----BEGIN CERTIFICATE----- MIIGqDCCBZCgAwIBAgIQDmU69yuszbx5RbMUTPVxADANBgkqhkiG9w0BAQUFADBm MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSUwIwYDVQQDExxEaWdpQ2VydCBIaWdoIEFzc3VyYW5j (以下略)
処理としてはまだ甘いコードですが、今回の目的は成功です。
最近のコメント