2010/05/07

property python

gnutls を使って SSL な server から証明書を取りたい話

gnutls python でサーバーの証明書は取ってきていましたが
python-gnutls にはその上の証明書を取る関数がありませんでした
で、とりあえずソース見てみると connection.py に
    @property
def peer_certificate(self):
if gnutls_certificate_type_get(self._c_object) != GNUTLS_CRT_X509:
return None
list_size = c_uint()
cert_list = gnutls_certificate_get_peers(self._c_object, byref(list_size))
if list_size.value == 0:
return None
cert = cert_list[0]
return X509Certificate(string_at(cert.data, cert.size), X509_FMT_DER)
とありました。
サーバの提示する証明書全部取って、頭だけ出している!!

で、何か decorator 付いてるけどその辺り慣れていないのでググりました
Pythonでプロパティ - crazy()for(;;)you();
なるほど! () を省略したいんだな!!

というわけで書いてみました
from gnutls.connection import (
ClientSession, GNUTLS_CRT_X509, X509Certificate, X509_FMT_DER,
byref, c_uint, string_at,
gnutls_certificate_type_get, gnutls_certificate_get_peers,
)

def peer_certificate_chain(self):
if gnutls_certificate_type_get(self._c_object) != GNUTLS_CRT_X509:
return []
list_size = c_uint()
cert_list = gnutls_certificate_get_peers(self._c_object, byref(list_size))
ders = []
for i in range(list_size.value):
cert = cert_list[i]
ders.append(X509Certificate(string_at(cert.data, cert.size), X509_FMT_DER))
return ders

ClientSession.peer_certificate_chain = property(peer_certificate_chain)

if __name__ == '__main__':
import socket
from gnutls import connection

cred = connection.X509Credentials()
sock = socket.socket()
session = connection.ClientSession(sock, cred)

session.connect(('www.google.com', 443))
session.handshake()

for i in session.peer_certificate_chain:
print("%s <- %s" % (i.subject, i.issuer))
で、動かすと
$ python chain.py
C=US,ST=California,L=Mountain View,O=Google Inc,CN=www.google.com <- C=ZA,O=Thawte Consulting (Pty) Ltd.,CN=Thawte SGC CA
C=ZA,O=Thawte Consulting (Pty) Ltd.,CN=Thawte SGC CA <- C=US,O=VeriSign\, Inc.,OU=Class 3 Public Primary Certification Authority
$
うん、動いた

でも場当たりでメソッド足したりだなんて Python 的と言えないのでは?
と悩んだりもしました
う〜ん

2010/05/04

rfc kindle

Kindle DX を借りることができました
考えていた用途に「RFC をゴロゴロしながら読む」というのがあったので
ここぞとばかりに、と思って思考停止しました

Kindle DX は mobi/azw/html/txt/pdf などの format が読めるそうです
RFC は txt で配布されています

txt はブラウザで見るような感じで表示されるのですが
RFC は等幅フォント? monospace? で表示されることを前提としている風で
若干文章ががちゃがちゃするうえに
ページのヘッダとフッタが定期的に入ってきて少し憂鬱になります

pdf は 1 ページ毎に文字がある領域めいっぱいに最大化して表示してくれます
といっても Kindle だったら小さくて「もっと大きくしてくれよ!」と思うところ
Kindle DX であれば大きいのでそれなりに読めるようになります
がしかしどうも IETF の pdf はフォントが薄い
Courier で表示されてると思うのですが何だか薄くてちょっと辛い感じでした
pdf で無理矢理フォント入れかえ? ん〜

Kindle で RFC や Internet Drafts を読む: 日誌
なるページをググって見つけてみましたが
RFC 2629 な形式で書かれた RFC に関するもので全てがというわけではありません
多分、これはちょっと試してみたんですが良く分からず
若しかしたらどれでも読めるのかもしれません

txt である RFC を今から色々と編集するというのも手間で嫌なので
HTML やら epub -> azw という手順を踏むのも嫌だったので
pdf で何かフォントを入れかえてやれば良いのではないかと思いました

a2ps/a2psj/u2ps/enscript など txt を ps にしてくれるのはあるんですが
どうもこいつらは Courier やその Bold 辺りで決め打ちらしく
というかどのフォントに変更すればいいのか決めていませんでした
ワードパッドか? ワードパッドでフォント変えて pdf にしたらいいのか??

とここで、LaTeX を思いだしました
LaTeX なら色々と等幅フォントがあるに違いなく
少なくとも Computer Modern に Typewriter がある!!
txt に関しては verb な何かで囲んでやればいいと思ったので
簡単な tex soucre 生成スクリプトを作成
import fileinput

print r'''\documentclass[12pt,a4paper]{article}

\addtolength{\topmargin}{-4cm}
\addtolength{\textheight}{100cm}
\addtolength{\textwidth}{3cm}
\addtolength{\oddsidemargin}{0cm}
\addtolength{\evensidemargin}{0cm}
\pagestyle{empty}

\begin{document}
\begin{verbatim}'''

lines = fileinput.input()
lines.next()
lines.next()

for line in lines:
line = line.rstrip("\n")
if line.find("\x0c") > -1:
print (r'''\end{verbatim}
\newpage
\begin{verbatim}''')
else:
print(line)

print r'''\end{verbatim}
\end{document}'''
プリアンブルとか出して
^L の度に verbatim を閉じて開いてるだけです

こんなのに rfc の txt 通してみたら
少なくとも IETF のよりは見易い pdf を得ることができました
ほんとは mobi とかで欲しいけど!
これでゴロゴロしてみようかと思います

2010/05/03

"chirpstream.twitter.com"

最新のTwitter API「ChirpUserStreams」をPythonから使う - ctrlshiftの日記
なんかそんな API 聞いたことある!
と思ってサンプルを動かそうとしたら上手くうごきませんでした

json の解釈に失敗してるっぽいんだけどそもそも
何が返ってくるかも分かってないので何だか良く分かりません
コピペに失敗したのかもしれません

で、楽な方向に流れてしまってそもそも何なのその API は、
とか調べようと思ったんですがとりあえず繋いでみました
http://chirpstream.twitter.com/2b/user.json
なんか、色々流れてくるじゃない

というわけで、とりあえず流れるものを書いてみた
import simplejson
import urllib2
import time

auth_handler = urllib2.HTTPBasicAuthHandler()
auth_handler.add_password(
realm='Firehose',
uri='http://chirpstream.twitter.com/',
user='あなたの id を入れるところ',
passwd='あなたの password を入れるところ')

opener = urllib2.build_opener(auth_handler)
urllib2.install_opener(opener)
u = urllib2.urlopen('http://chirpstream.twitter.com/2b/user.json')
u.readline()
u.readline()

while True:
try:
j = simplejson.loads(u.readline())
print "[%s] %s".encode('utf-8') % (j['user']['screen_name'], j['text'])
except:
time.sleep(0.5)
とりあえずダラダラと TL が流れはじめたので良しとします
これは便利そうだ!

もう少しググってみた
Twitterの新しいStreaming API「ChirpUserStreams」がすごすぎる件 - すぎゃーんメモ
あ、なるほど、TLよりも豊富な情報が流れてるのか、それは凄い
Twitter API Wiki / ChirpUserStreams
まだ beta だからあんま本気で使うなと、なるほど
"In Q3 2010, launch User Streams at scale." ということなので楽しみに待ちます

と、こんなもの書いてる間にもどんどん情報が流れてました
アイコン無いと誰だか認識するの難しいなぁ
おかしいなぁ、CUIの世界の人だったはずなんだけどなぁ...