Let's start Scheme

2012-05-29

DONT_ADD_BYTE_AT_END

Yes, it's GC again. For some reason, GC_size did not return proper (means I wanted) value for pair pointer. It always returns 16 bytes instead of 8. I needed to figure it out why?

So I started to read Boehm GC's source code again. GC_size just returns header's size and the size is defined before allocation. So it must be in GC_init. (Well, it wasn't this easy to find out, first I needed to know how gran size came and so on...). In GC_init, there was a function named GC_init_size_map, ah, this is it.

So I stepped into the function and figured it out what's going on. Well, it's just calculating the gran size with extra byte. Now I have got other problem, how can I remove this without rebuilding gc library? GC_set_all_interior_pointer causes other problem. So far, I can't see any solution. Hmm...

2012-05-24

How to use FastCGI on Apache2 on Cygwin

I wanted to run FastCGI on Cygwin Apache2 server and I could not find specific article for it. If there is no documentation, then I would be the first one;)

So, the first step is downloading mod_fcgi from http://httpd.apache.org/mod_fcgid/. You can easily find the source code form the link 'your local mirror'.

Then next step is compiling and installing. I believe this step is the most difficult step to find a clue. Well, just the linker problem actually. The following command you need to run. And make sure you have all related Cygwin modules, such as libapr-1 and libuuid-devel.
$ APXS=/usr/sbin/apxs2 ./configure.apxs
$ make LDFLAGS="-lapr-1 -laprutil-1 -lhttpd"
$ make install
The point is LDFLAGS. Somehow created Makefile does not contain the necessary libraries.

Now, it's time to configure the httpd.conf.
Add this line after your final line of LoadModule
LoadModule fcgid_module lib/apache2/mod_fcgid.so
And put a file end with .conf extension in conf.d directory. Then add this configuration in the file.
<Directory /home/*/public_html/fcgi-bin/>
  SetHandler fcgid-script
  Options +ExecCGI
</Directory>
I assume you are using the userdir_module.

When you finish it, then run Apache2. Before run it, make sure your cygserver is running otherwise Cygwin complains.
$ /usr/sbin/cygserver &
$ CYGWIN=server /usr/sbin/apachectl2 start
OK, let's test. Put this script into the directory 'fcgi-bin' in your public_html directory named hello.cgi.
#!/usr/bin/perl
use CGI::Fast;

while (my $q = CGI::Fast->new) {
  print("Content-Type: text/plain\n\n");
  foreach $var (sort(keys(%ENV))) {
    $val = $ENV{$var};
    $val =~ s|\n|\\n|g;
    $val =~ s|"|\\"|g;
    print "${var}=\"${val}\"\n";
  }
}
Make sure you have FCGI module in your platform. Then access http://locahost/~username/fcgi-bin/hello.cgi
You can see the environment variables if it successfully installed. Enjoy.

2012-05-22

CLOSのqualifierで遊んでみる

前にも書いたような気がするが、まぁいいか。

とりあえず、組み込みのprint関数の呼び出し前に与えられた引数をエラーポートに出力したいとする。ここではprintにしたけど、別に何でもいい。
そうすると、こう書ける。
(import (rnrs) (clos user))

(define org:print print)

(define-method print objs
  (apply org:print objs))

(define-method print ((num <integer>) . args)
  (format #t "~b" num)
  (apply print args))

(define-method print :before args
  (display args (current-error-port)) (newline (current-error-port)))

(print 1 2 3)
#|
(1 2 3) ;; これらがエラーポートに出力された引数
(2 3)   ;; printが呼ばれた回数だけ:beforeが呼ばれている
(3)
()      ;; もちろん'()もある
11011
|#
ついでに、先頭の引数が数字だったら2進数で出力するようにしてある。意味はない。オリジナルの名前を変えているのはqualifierがどのパターンでも適用されるようにするため。単にオリジナルと同じ引数を取る総称関数がほしいだけともいう。

なにが嬉しいか?Aspect指向的なことが簡単に出来そう。(多分前にも書いたな)。とりあえずこれを使って何か出来ないか考えたい。問題は、通常の呼び出しに比べて遅いことか・・・

2012-05-20

Transcoderがバッファを持つとこうなる

BOM関連のバグを直していて気づいた。Transcoderは状態もバッファも持ってはいけないということに。
以下が端的な不具合再現コード。
(import (rnrs))
(define tr (make-transcoder (utf-16-codec)))
(call-with-port 
 (open-file-input-port "utf16file.txt" (file-options) 'block tr)
 (lambda (in)
   (display (get-char in))(display (lookahead-char in)) (newline)))
(call-with-port 
 (open-file-input-port "utf16file2.txt" (file-options) 'block tr)
 (lambda (in)
   (display (get-char in))(display (lookahead-char in)) (newline)))
ファイルはUTF-16である必要は無いんだけど、このコードで、2つ目のcall-with-portは変な値を返す。なぜか、Transcoderが最初にlookahead-charで読んだ文字をバッファに溜め込んでいるので、2度目はバッファから返してくる。すると、2度目のlookahead-charのBOMチェックになって、ごにょごにょ。(詳しく理解してないorz)
コードを修正、最初にBOMチェックをさせてからバッファに溜め込まないと意味がない。

Transcoderはあくまで単なるプロセスでないとまずいはずので、 バッファ自体はポートが持つべきである。直す。

Moshにパッチを送った。

Moshにバグレポートしたら「時間が無いからパッチを送って」みたいなニュアンスでコメントが付いたので送ったった。僕も誰かからパッチを送ってほしいよ。こっちは開発人員一人だっつ~の!

っで、よく考えてみたらパッチの作り方とか全然知らないので、どうするのか調べてみた。以下のサイトが非常に分かりやすかった。(というか、まんま使い方)
パッチの作り方と当て方はこうするもんね - 檜山正幸のキマイラ飼育記

当てたパッチは、MoshのIssue 232にまるっと貼り付けた。githubのアカウントなんて持ってないし・・・賞味時間半の大作業であったw
しかし、MoshはCygwin上でテスト走らせると結構こける。これは僕のパッチが問題ではなく、もともとこけるみたい。 test/print.scmのテストは0.2.7では2テストこけて、そこでmake checkが終了する。メインのターゲットではないのだろうが、もう少しCygwinユーザをいたわってほしいものだ。

運がよければパッチが採用されて、いつリリースされるか分からない0.2.8でBOM周りのチェックが改善されているはず。
Sagittariusの初期の頃いろいろコードを参考にさせてもらったので、まぁ恩返し。

2012-05-19

Unicode変換処理の実行時間差

Larcenyのベンチマークにbv2stringという処理がある。名前の通りバイトベクターからストリングに変換する処理である。普通の処理と違うのは、これがあほかというくらい繰り返す点であろう。最近Transcoder周りを改善したのでちょっとチャレンジしてみた。

っで、標題の件である。この処理については意外なことにYpsilonが苦手としている。逆にSagittariusはかなり高速に処理をする。(moshはもっと速いんだけど、出てくる結果が不正確)。以下はbv2stringの中から抜粋して上記3つの処理系で速度を計ってみた結果。
(import (rnrs) (rnrs mutable-strings))

(define (test-char-range name lo hi tostring tobytevector)
  (let* ((n (+ 1 (- hi lo)))
  (s (make-string n))
  (replacement-character (integer->char #xfffd)))
    (do ((i lo (+ i 1)))
 ((> i hi))
      (let ((c (if (or (<= 0 i #xd7ff)
         (<= #xe000 i #x10ffff))
     (integer->char i)
     replacement-character)))
 (string-set! s (- i lo) c)))
    (string=? (tostring (tobytevector s)) s)))

(define (test-exhaustively name tostring tobytevector)
  (test-char-range name #x10000 #x1ffff tostring tobytevector))
(test-exhaustively "UTF-8" utf8->string string->utf8)
(test-exhaustively "UTF-16"
     (lambda (bv) (utf16->string bv 'big))
     string->utf16)
(test-exhaustively "UTF-32"
     (lambda (bv) (utf32->string bv 'big))
     string->utf32)
$ time sash test.scm
sash test.scm  0.73s user 0.12s system 94% cpu 0.906 total

$ time mosh test.scm
GC Warning: Repeated allocation of very large block (appr. size 524288):
        May lead to memory leak and poor performance.
mosh test.scm  0.52s user 0.12s system 97% cpu 0.656 total

$ time Ypsilon test.scm
Ypsilon test.scm  0.01s user 0.06s system 0% cpu 1:49.86 total
YpsilonはWindows版をCygwin上で走らせているのでトータルのタイムのみが出ている点に注意。

moshが最速なのだが、結果が不正確である。実際string=?の部分を出力するとUTF-8のテストで#fが返っている。 (これはbv2stringの一部なのでUTF-8だけなのだが、全部を走らせると鬼のように不正確な値を返す。恐らくUTF-16及びUTF-32に変換した後のチェックが省かれているのだろう)。

Sagittariusは実用的な速度で正確な結果を返す。ただし、開発版である。0.3.2以前は不正確な値を返す。これはmoshの項で記載したチェックが省かれていたため。

以外だったのはYpsilonである。今まで異次元の速さを誇っていたのがここにきて異次元の遅さになってしまっている。 Ypsilonのutf16->string、string->utf16、utf32->string及びstring->utf32はSchemeで実装されているのでそれが原因かと思ったのだが、utf8->stringとstring->utf8も遅かった。(ちなみに、この2つはC++で実装されている。見間違えていなければ)。ここからは推測になるのだが、これは内部エンコーディングの差ではないだろうか?moshとSagittariusは内部で文字列をUCS4で持っているが、Ypsilonはutf-8で持っている。なので、bv -> ucs4 -> utf8と2回変換が走ることになって、その分のオーバーヘッドが処理時間に如実に反映されているのではないだろうか?

なにはともあれ、一つでもYpsilonに勝ったと言える部分があるのは嬉しいことである。

2012-05-18

Unicode対応

Larcenyのベンチマークを走らせようとしているのだが、リーダーや走らせるたびに文字コード周りでテストが失敗する。よくも悪くもかなり厳しくテストが作られているようだ。(正直、リーダー周りは処理系が#!r6rsを付けた際にR6RSに準拠することを前提に作られているので結構厳しかった。)

Unicode周りはそんなに厳密に作っていなかったので、結構な修正を迫られた。おかげでかなり厳密にエンコード、デコードするようになった(と思う)。
UTF32やUTF16に関しては単に範囲のチェックを入れるだけだったのだが、UTF8が結構問題だった。
マルチバイト文字列というのは最初の途中のバイトが不正バイトでも、最初の1バイトのみを不正として扱わないといけないというのにはまった。まぁ、言われてみればそうだよなぁとは納得するのだが、読み取った数バイトをポートに戻すということが出来ないので、ポートから1バイトずつ読み込む場合は不正バイトを検出しても戻らないという糞仕様で回避。(Ypsilonも戻ってないように見えるし、ファイルを読み込むときはいいよね、ファイルを信用しても?)
utf8->stringみたいなすでにバッファに取ってあるバイトのみ不正バイトを検出するようにして、とりあえずベンチマークが要求する部分は解決した。

ただ、このベンチマーク、走らせる条件も厳しいけど、要求してる速度も厳しい。特にCygwinは相手にしてないみたいで、(というか、R6RSの処理系の多くはCygwin対応してない気がする)、一気に1M以上メモリを割り当ててみたり、テスト回数が5桁からだったりとセットで走らせるとしばらく応答がないということがしばしば。
これがあんまり待つことなくさくさく動いたら、多分最速の処理系だろうなぁ。とりあえずはmoshと速度比較かなぁ。

2012-05-17

Transcoderを改善したいのその2

書き出し側は昨日やったので今日は読み込み側。とりあえずUTF8だけで実装してみた。
検証コード:
(import (rnrs) (time))
 
(define times 10000)
(define test-data 
  (string->utf8 "12345678901235678901234567890123456790123456789\r\n"))
 
(define tr (make-transcoder (utf-8-codec) 'crlf))
 
(time
 (do ((i 0 (+ 1 i)))
     ((= i times) (display times)(newline))
   (let ((in #;(transcoded-port (open-bytevector-input-port test-data) tr)
   (open-file-input-port "test.scm" (file-options no-fail) 'block tr)))
     (get-string-n in 100)
     (close-input-port in)))
 )
実行結果:0.3.2、開発版の順。
$ time sash test.scm
10000

;;  7.765625 real    3.734000 user    3.235000 sys
sash test.scm  3.98s user 3.41s system 88% cpu 8.391 total

$ time ./build/sash.exe test.scm
10000

;;  4.062500 real    1.359000 user    2.235000 sys
./build/sash.exe test.scm  1.61s user 2.44s system 86% cpu 4.688 total

$ time Ypsilon test.scm
10000

;;  5.015625 real    0.65625 user    3.9375 sys
Ypsilon test.scm  0.03s user 0.06s system 1% cpu 5.312 total
およそ倍くらい速い。Ypsilonより多少速い。ただ、IOに関してはmoshが一番速かった。上記の検証コードの(time)を(mosh)に変更してmoshで実行。
$ time mosh test.scm
10000

;;3.765625 real 1.2029999999999998 user 2.265 sys
mosh test.scm  1.36s user 2.45s system 90% cpu 4.219 total
system時間はそんなに変わらないので計算に掛かっている時間の差なのだが、変換の処理自体にそんなに差はないと思うんだけどなぁ?moshのIOは遅いというのをどこかで見たのだが、嘘だったのだろうか?
ちなみに、上記のコードでblockをnoneに変更したら最速になった。というか、他の処理系が2倍程度遅くなって、Sagittariusの速度は変わらないだけ。

もう少し気になる点として、バイトベクタのポートにするとあほかと思うほど遅くなるんだけど、なんでだろう?それでも、0.3.2よりは速いので、今までどんだけ遅かったんだということにはなるのだが・・・

2012-05-16

Transcoderを改善したい

普通に使っているとテキストファイルのIOなんて(なぜか)そう使わないので気にならなかったのだが、httpsとか普通のhttpとかで一文字ずつ変換して流してると無駄だよなぁと思いはじめてきた。

とりあえずどれくらい違うのか試してみたいなぁと思い、utf8コーデック+put-stringだけの変更という形でベンチマーク。
ベンチーマークに使ったコードは以下。
(import (rnrs) (time) (sagittarius control))

(define times 10000)
(define test-string "12345678901235678901234567890123456790123456789\r\n")

(define tr (make-transcoder (utf-8-codec) 'crlf))

(time
 (let ((out (open-file-output-port "tmp.txt" (file-options no-fail) 'block tr)))
   (dotimes (i times)
     (put-string out test-string))
   (close-output-port out)))
これを0.3.2と開発版で比較。 結果は以下。
% ./build/sash.exe test.scm
;;  0.013002 real    0.016000 user    0.000000 sys

% sash test.scm
;;  0.312032 real    0.141000 user    0.172000 sys
上が開発版。びっくりするほど違う。これはやる価値ありだな。とりあえずやることにする。

Sagittarius version 0.3.2リリース

なんだかんだ言って、月1でリリースする。

Sagittarius Scheme 0.3.2をリリースしました。今回のリリースはメンテナンスリリースです。

修正された不具合
  • call-next-methodがsyntax-caseマクロ内で呼び出せない不具合が修正されました。
  • 特定のプロシージャ呼び出しが失敗する不具合が修正されました。
  • transcoded-portを使ってカスタムバイナリポートを変換するとput-string等のプロシージャでSEGVを起こす問題が修正されました。
  • R6RSで定義されていて、実装されていなかったマクロassertが追加されました。
  • portクラスの階層が修正されました。
  • ソケットポートを使用してget-bytevector-allを呼び出すと終了しない場合がある不具合が修正されました。
  • X.509証明書を読み込む際にmake-basic-constraintsがエラーを投げる不具合が修正されました。
  • open-inflating-input-portのreadプロシージャで読み込み数が1より大きい場合に例外を投げる不具合が修正されました。これは今回のカスタムポート改善で発覚したもので、0.3.1以前では発現しません。
  • X.509証明書をキーストアから読み込む際、秘密鍵のみを読み込んで証明書自体を読み込まない不具合が修正されました。
  • bytevector、stringアウトプットポートから出力されたデータを読み出した際に、ポート位置がリセットされていない不具合が修正されました。
改善点
  • カスタムバイナリアウトプットポートの出力の際に、ある程度のサイズのバッファを渡すように修正されました。パフォーマンスが改善されているはずです。
  • bytevector-copyがオプション引数startとendをとるように改善されました。
  • base64-decode-stringがオプショナル引数のtranscoderで#fを受け取った際に生のバイトベクタを返すように改善されました。
  • バイトベクタ及びストリングのアウトプットポートのパフォーマンスが改善されました。およそ2倍程度高速になっているはずです。
  • 擬似乱数クラスがハッシュやCipherと同様拡張可能になりました。
  • キャッシュ機構がScheme側からも制御できるようになりました。
  • 上記の改善により、正規表現パターンのリーダがS式ではなくパターンオブジェクトを返すようになりました。
 互換性の無い変更
  • 擬似乱数クラスの変更により、custom-prng?プロシージャが削除されました。
新たに追加されたライブラリ
  • OAuthライブラリ(net oauth)が追加されました。OAuth 1.0のコンシューマをサポートしています。
  • TLSプロトコルライブラリ(rfc tls)が追加されました。TLS1.0からTLS1.2までをサポートしていますが、1.2に関しては動作保障がありません。セキュリティホール等があるかもしれません。
  • (srfi :27 random-bits)が追加されました。
  • バリデーションメタクラスライブラリ(sagittaius mop validator)が追加されました。

2012-05-14

継続してリリースをするということ

ふと、moshにバグレポートをして思ったこと。軽くdisるので先に謝っておこう、ごめんなさい。

前提として、開発版は使わないとします。 なので、trunkからとってくれば直っているよっていうのは議論からは外します。

Sagittariusは意図していなかったのだが月1ペースでリリースをするという習慣になっている。いい悪いはとりあえず置いておくとしてだが。
っで、moshなのだが、最新版は0.2.7でリリースされたのが2011年6月7日とほぼ一年前。その前のバージョン0.2.6も2010年11月7日と半年以上の期間が空いている。もちろん製作者側がすでに「moshは十分に枯れていて、今後新しい機能を足すことも少なく、バグもほぼない」と判断しているならば問題ないのかもしれないのだが、メインで使っていない僕が3つほどバグレポートをし、そのうちの1つはクリティカル(mosh自体が止まる)ものだったりする。大多数はバグレポートにある使い方をしないだろうので、問題ないといえばそうなのだが、レポートにある使い方をする必要がある少数派の人間はいつ直ってリリースされるか分からない処理系を使う気にはならないだろう。

一方で僕は月1でリリースしている。正直必要性をあまり感じない上に、ユーザーもいない(更には自分以外のバグレポートはない)のだが、レポートした人はそれなりに速いうちにそのバグが直されてリリースされるだろうということが予測できる。もちろん弊害もあって、そんな頻繁に更新される処理系怖くて使えないという話にもなる。

もちろん、僕がリリースするということを甘く見ているだけなのかもしれない。WindowsとLinuxでテスト通して、ドキュメント整備してくらいにしか考えてない部分はある。moshと違ってFreeBSDのポート作ってとかないので。

月1でリリースするならそろそろ準備しないとなぁ・・・

2012-05-12

TLSを実装したった

ようやく動くものが出来た。まだまだ、作りこみが甘いので予期せぬ挙動が起きると直ぐエラーを投げるが、ある意味セキュアであろう。また、セッションの復元も行えない。
現状ではTLS 1.0と1.1に対応している。1.2もサポートをしたいのだが、動作を検証できる環境が簡単に構築できそうにないので、厳しいところではある。多くのサーバーは1.0もしくはで動作しているはずなので大きな問題になるとは思わないが、ハンドシェイクで0x0303を投げるので、1.2対応のサーバーが多くなると問題が起きそうではある。
また、現状ではクライアントソケットのみの対応である。サーバーソケットが必要な状況が当面僕にはないので、しばらくは対応する予定はない。

なぜわざわざ自前で実装したのか?
世の中にはOpenSSLとか優れた実装がたくさんあるのだから、それをおとなしく使えばいいではないか?実際そうしようかなぁと思ったのだけど、ビルド時の依存関係を極力減らしたいのと、暗号ライブラリが自前であるのにさらに他の実装に依存するのがイヤだったというだけ。ビルド時の依存関係は、現状Windowsでのビルドを極力簡便にするため。現状ではWindowsでのビルドはネットに繋がってさえ要れば何も用意することなくビルドが進むようになっている(もちろんCMakeとVCは要るけど)。この方針を崩したくなかった。
また、Cの実装はたくさんあるけど、Pure Scheme(Lispを含めても)な実装ってないのであってもいいかなぁと。

セキュアなの?
実装上のセキュリティーホールはまだまだあるだろうとは思う。サーバーの証明書を検証してないし。また、実装してて思ったことだが、TLSは暗号セッションが始まってしまえば現状安心して使えるプロトコルだと思うが、ハンドシェイクの段階から盗聴されていた場合はその限りではないと思う。理由はこの辺

急いで作った理由はOAuth使ってTwitterに呟いているときに、TwitterのAPIにはhttpsがあることに気づいたから。折角だし、セキュアなOAuthにしてしまいたかった。思いの他時間がかかったが、動くのそれまでの苦労が吹き飛ぶ。

2012-05-11

quicklispのインストールからcl-annotまで

Lisperになるつもりはあまりないのだが、試してみたいライブラリが結構あるのでquicklispをインストールしてみる。対象はclisp on Cygwin。
とりあえずquicklisp
手順に従ってquicklispをインストールしようとしたら、早速curlがないと怒られた・・・しょうがないのでインストール。
Installationにしたがって以下の用にquicklisp.lispのダウンロードと、clispの起動。上記サイトはsbclなので多少コマンドラインのオプションが違う。
$ curl -O http://beta.quicklisp.org/quicklisp.lisp
$ clisp -i quicklisp.lisp
  i i i i i i i       ooooo    o        ooooooo   ooooo   ooooo
  I I I I I I I      8     8   8           8     8     o  8    8
  I  \ `+' /  I      8         8           8     8        8    8
   \  `-+-'  /       8         8           8      ooooo   8oooo
    `-__|__-'        8         8           8           8  8
        |            8     o   8           8     o     8  8
  ------+------       ooooo    8oooooo  ooo8ooo   ooooo   8

Welcome to GNU CLISP 2.48 (2009-07-28) <http://clisp.cons.org/>

Copyright (c) Bruno Haible, Michael Stoll 1992, 1993
Copyright (c) Bruno Haible, Marcus Daniels 1994-1997
Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998
Copyright (c) Bruno Haible, Sam Steingold 1999-2000
Copyright (c) Sam Steingold, Bruno Haible 2001-2009

Type :h and hit Enter for context help.

;; Loading file quicklisp.lisp ...

  ==== quicklisp quickstart loaded ====

    To continue with installation, evaluate: (quicklisp-quickstart:install)

    For installation options, evaluate: (quicklisp-quickstart:help)

;; Loaded file quicklisp.lisp
っで、clispのREPL上でプロンプトに表示されている注意書きにしたがってインストールを続行。
[1]> (quicklisp-quickstart:install)
; Fetching #<URL "http://beta.quicklisp.org/quickstart/asdf.lisp">
; 159.59KB
==================================================
163,424 bytes in 0.89 seconds (180.28KB/sec)
; Fetching #<URL "http://beta.quicklisp.org/quickstart/quicklisp.tar">
; 210.00KB
==================================================
215,040 bytes in 0.16 seconds (1280.11KB/sec)
; Fetching #<URL "http://beta.quicklisp.org/quickstart/setup.lisp">
; 4.88KB
==================================================
4,995 bytes in 0.00 seconds (1625.43KB/sec)
; Fetching #<URL "http://beta.quicklisp.org/dist/quicklisp.txt">
; 0.40KB
==================================================
408 bytes in 0.01 seconds (56.90KB/sec)

  ==== quicklisp installed ====

    To load a system, use: (ql:quickload "system-name")

    To find systems, use: (ql:system-apropos "term")

    To load Quicklisp every time you start Lisp, use: (ql:add-to-init-file)

    For more information, see http://www.quicklisp.org/beta/

NIL
何か読み込まれた。本当はql:aproposとかで何があるか調べるんだろうけど、cl-annotがあることはすでに知っているのでそのままインストール。
[2]> (ql:quickload "cl-annot")
; Fetching #<URL "http://beta.quicklisp.org/dist/quicklisp/2012-04-07/systems.txt">
; 123.72KB
==================================================
126,685 bytes in 0.10 seconds (1236.79KB/sec)
; Fetching #<URL "http://beta.quicklisp.org/dist/quicklisp/2012-04-07/releases.txt">
; 175.60KB
==================================================
179,810 bytes in 0.15 seconds (1170.87KB/sec)
To load "cl-annot":
  Install 2 Quicklisp releases:
    alexandria cl-annot
; Fetching
#<URL
  "http://beta.quicklisp.org/archive/alexandria/2012-04-07/alexandria-20120407-git.tgz">
; 47.16KB
==================================================
48,296 bytes in 0.04 seconds (1274.98KB/sec)
; Fetching
#<URL
  "http://beta.quicklisp.org/archive/cl-annot/2011-12-03/cl-annot-20111203-git.tgz">
; 8.16KB
==================================================
8,356 bytes in 0.00 seconds (2720.05KB/sec)
; Loading "cl-annot"
[package alexandria.0.dev]........................
[package cl-annot.util]...........................
[package cl-annot.core]...........................
[package cl-annot.expand].........................
[package cl-annot.syntax].........................
[package cl-annot.helper].........................
[package cl-annot]................................
[package cl-annot.std]............................
[package cl-annot.eval-when]......................
[package cl-annot.doc]............................
[package cl-annot.class]..........................
[package cl-annot.slot]
("cl-annot")
パースに時間がかかるのか、落としてくるまでに結構時間がかかった。が、うまいこといっている感じがする。REPL上のコマンドは基本的にはどの処理系でも動くはずなので、後は省略。っで、cl-annot
[4]> (asdf:load-system :cl-annot)
0 errors, 0 warnings
T
[5]> (use-package :cl-annot)
T
[6]> (enable-annot-syntax)
T
[7]> @print 1

1
1
動いた。

2012-05-09

知る権利、個人情報保護

一つ前の投稿の続きである。武雄市図書館問題のごく1部、具体的には知る権利及び個人情報保護を扱ったものでもある。

注意書き。
  • 私は法律の専門家ではないので、下記の文章には誤りが含まれている可能性があります。
  • 断りがない限り下記の文章は武雄市図書館問題に置けるTwitter上の議論に対しての意見です。
  • 断定する形で書いていますが、すべて下記の資料に基づく私の個人的意見です。法律的正しさを証明するものではありません。

参照資料
  1. 表現の自由 (日本国憲法第21条第1項)
  2. 個人情報の保護に関する法律 
  3. 図書館法 
  4. 図書館の自由に関する宣言 
  5. 個人情報保護とプライバシー保護の違い(朝日中央インターネット法律相談)
はじめに知る権利について述べます。 Twitter上でTカードの導入は知る権利の侵害になるというツイートを見ました。この意見は、「貸出履歴と知る権利を混同している」と言えます。武雄市市長は図書館の利用は無料である、と名言しています。
https://twitter.com/#!/hiwa1118/status/200220121770373120
図書館の本は図書館法により無償です。 RT お疲れ様です。時々ツイート拝見させていただいています。武雄市図書館について質問です。業務委託後、図書館の本にレンタル料を課す可能性はありますか?
また、図書館法にも貸出に関しての記述は一切ありません。利用者は無料でいかなる図書をも閲覧可能であるため、知る権利の侵害にはなりません。ただし、Tカードなしでの図書館の利用については言及されていないので、図書館利用者はTカードに登録する必要があるということがあればこの限りではありません。

次に個人情報保護法についてです。この問題の焦点は武雄市市長のブログで言及されていた、
「5月6日20時40分、42歳の市内在住の男性が、「深夜特急」「下町ロケット」「善の研究」」
From 図書館貸出情報の扱い、ご安心ください!
という情報が個人情報保護法で保護されるべき個人情報に当たるかどうか、という点である。個人情報の保護に関する法律第二条によれば、
この法律において「個人情報」とは、生存する個人に関する情報であって、当該情報に含まれる氏名、生年月日その他の記述等により特定の個人を識別すること ができるもの(他の情報と容易に照合することができ、それにより特定の個人を識別することができることとなるものを含む。)をいう。
と定義されている。定義のみを見れば明確ではなく、読み手の裁量によって大きく範囲が動くものだ。ここでは、不特定多数の第三者によって容易に特定できる情報とする。その仮定に基づけば上記の情報には氏名、生年月日及び特定の個人を識別する情報は含まれていない。 となれば、上記の情報は個人情報保護法ではなくプライバシー保護に分類されるものである。(過去の判例があればその限りではない)。個人情報保護とプライバシー保護の違いについては参照情報の5を参照されたい。また、図書館の自由に関する宣言はあくまで宣言なので法的束縛はない。事実、第3条の1には裁判所の令状があれば情報を開示するとある。ただし、私が寡聞ゆえに誤認している可能性はある。

Twitter上でこの問題についてのハッシュタグを見た際に、知る権利の侵害及び個人情報保護法違反だという批判を見かけ、法律上だけ見ればそのようなことはないという旨の意見を比較的曖昧な表現を用いて書いたところ、複数の方から突込みが入ったので具体的に記載した。また、私はこの問題自体についてはいくつか批判または議論すべき点が多々あると思っているが、ここでは言及しない。

なおこの問題において、武雄市市長は個人情報保護法には抵触していないという旨を上記のブログで言及しているが、プライバシー保護については言及されていない。 Twitter上では現在個人情報保護ではなくプライバシー保護の観点から問題について言及しているようである。

以下、チラシの裏

図書館利用しないからあんまり関係ないけど

こんなツイートを見つけた。
https://twitter.com/#!/fmht7/status/200074782732075008
CCCとの提携の件白紙に戻し再検討が良いとお考えの方はRTを。 RT : 沢山いらっしゃる?何人ぐらい?そんな何の根拠もない言い方するから反対にしても上っ面にしかならないんだよ
(bloggerでTwitterの参照ってどうやるんだ?)
っで、何のことだろう?と思い、元ネタを探してみた。多分これ?
図書館貸出情報の扱い、ご安心ください!

あまり詳しく知らないのでなんともいえないが、貸し出し履歴って個人情報か?というか、管理される情報って
「5月6日20時40分、42歳の市内在住の男性が、「深夜特急」「下町ロケット」「善の研究」」
このレベルらしいのだが?(真偽の程は定かではないが)。噂では炎上しているらしい?もちろん、提携先のCCCという会社のセキュリティがどれほどかとか、その会社は取得した個人情報(上記の情報?)を悪用しない、または管理目的以外には使用しないということが保障されるのかというのは別の話だが。

そもそも、日本の図書館は大分優遇されていると思うのだが、どうだろう?カナダもそうだが、オランダの図書館は有料である。カード作ったことないので分からないけど、多分図書カードも有料じゃないかな?閲覧自体は無料。
正直Twitterの議論って的外れな感じではあるのだが、「知る権利」の保障と貸し出し履歴は関係ないだろう。また、図書の閲覧自体はTカードがなくてもできる(と仮定する)なら、保障されてるよね?自宅に持ち帰るということは、「その本が返却される、またはされなかった際になんらかの行動が取れる」状態にしておかないと、「他の人の知る権利の侵害」ならないかね?(もちろん、Tカード作らなきゃ閲覧も不可っていうなら話は違ってくるが)
ツイートを全部読んだわけじゃないし、何を問題視してるのかも漠然としてるんだけど、これが炎上することがいまいち不思議。
(時間がない、面倒くさいというのもあり)詳しく知らないので、賛否の意見は控えるけど(ずるいのは承知の上)、問題視する点が違わないかな?

https://twitter.com/#!/kuippa/status/200088650367774720
これをうまく収めることができるなら図書館だけじゃなくて炎上対策のモデルケースにもなるね・・・! (キリッ
これには激しく同意した。

まじめに意見を書いた。

2012-05-08

セキュリティについての考察

SSL/TLSのおけるセキュリティの考察。

実装がまったく行き詰っていて、息抜きにふと思いついたことをつらつら書いているとも言う。

以下に記載した内容に基づいて盗聴、改竄を行ったとしても当方は一切責任を取らない。また、この記事はそのような犯罪行為を推奨するものでもない。(お約束の免責事項)

ふと、ひょっとしたらハッキング(世間一般的に通じる言い方、本当はクラッキングと言う。一応)できるんじゃね?と思ったのでその手順。もちろん試してないし、僕にそのようなことが出来る技術はない。ただ仕様書を読んでいて出来そうだと思っただけ。

【用意するもの】
  • 偽のサーバー証明書
  • なりすまし用のルータ
  • SSL/TLSのパケットを作れる技術
【手順】
  1. クライアントが送ってきたCLIENT-HELLOのcipher suitesからDHなsuitesを取り除いてサーバーに送る。このときクライアントの乱数を記録しておく。
  2. サーバーが送ってくる情報のうち、決定したcipher suite、サーバーの乱数、サーバー証明書を抜き取る。また、サーバー証明を用意した偽の証明書と置き換えてクライアントに送る。
  3. クライアントがpre master secretを暗号化したものを送ってくるので、偽の証明書の秘密鍵で複合。master secretを作成する。また、送られてきたpre master secretを本物の証明書で暗号化してサーバーに送る。
  4. 以下、暗号化されたメッセージは手元のマスター鍵で複合したり、MACを合成したりしてなりすます。
【簡単な解説】
  1. Deffie-Hellmanを使われると現在のところ現実的な時間で鍵を手に入れることができないので、クライアントがサポートしているcipherから抜き取る必要がある。
  2. この時点でサーバーの証明書を抜き取ってしまえば、クライアントは成りすまし証明書を検出する方法はない。
  3. クライアントに対してはサーバーの振り、クライアントに対してはサーバーの振りをする。しないと不整合が起きるので。
3番が重要で、まともなクライアントなら偽の証明書にはルートCAがないということで警告を出すはず。でもユーザが構わずOKしたら、う~ん怖い。
もちろん、この程度のことはきっと議論され尽くしているはずなので基本的には問題にならないと思う。っが、RFCだけ見た感じだとそんなこと考えられてなかったので、どうなんだろう?

2012-05-06

プロトコルの実装とナンパ

なんとなく2つは似ている気がする。TLSの実装をしていてふとそう思った。

ナンパはしたことがないのでネットで読んだ知識になるのだが、以下の流れだろう。
  1. 異性に声をかける
  2. 交渉する
  3. 目的を達する
  4. バイバイする
っで、TLSはこんな感じ
  1. ハローってサーバーに言う
  2. 交渉する
  3. データ交換する
  4. バイバイする
ぶっちゃけ、HTTPでもFTPでも一緒だ。交渉の部分があるかどうかはプロトコルによるが。
並べてみただけだが、既にほとんど一緒だなぁ。どちらも成功するか失敗するかは声のかけ方、交渉の仕方による。(まぁ、ナンパはさらに顔面偏差値などもいるだろうが、これは声のかけ方に含める)

ただ一点絶対的に違うのは、手順さえきっちりしてればプロトコルの実装は失敗しないという点。サーバーに選択権はないけど、異性にはあるということだ。そういう意味ではサーバーを落とす方がはるかに簡単といえるだろう。

何書いてんるんだろう、俺・・・orz

2012-05-05

プログラマはキチガイじゃないよ

こんなのを見つけた。
プログラム板キチガイすぎワロタwwwwww
ム板とマ板は違うとあれほど(ryというのはほっといて。
内容は2004年に立てられた何かのスレに対してのコメント。そのスレの>>1が2進数で何か書いていて何言ってるんだろう?という話。
2進数なら単に2->16->変換でいけるだろうとこんなの書いてみた。文字コードの判別は面倒だったのでSJIS決め打ち。(2004年だとUTF-8はそんなに普及してなかったなぁ・・・遠い目)
#< (sagittarius regex) >
(import (rnrs) (getopt)
 (sagittarius)
 (sagittarius control)
 (sagittarius regex)
 (encoding sjis)
 (util file))

(define (sjis->string bv)
  (let1 tr (make-transcoder (sjis-codec))
    (bytevector->string bv tr)))

(define (main args)
  (with-args args
      ((i (#\i "input") #t (usage)))
    (let1 s (regex-replace-all #/\s/ (car (file->string i)) "")
      (print (sjis->string (integer->bytevector (string->number s 2)))))))
Sagittariusはこっそり拡張コーデックを持っているので、sjisとeuc-jpが使える。今回はsjisだけど。っで、満を持して元スレの>>1を解読したら、>>2になった。
元スレの>>1がEBCDICでも使っているのか、でたらめだったのかは知らないけど。朝の15分であんまり頑張りたくないのでやめた。

元ネタがなんて書いてあるか知りたい人は是非Sagittariusをダウンロードして
$ sash {スクリプト名} -i {2進数を貼り付けたファイル名}
コマンドラインから上記スクリプトでw

2012-05-03

SSL/TLSを実装したいの1

2があるかは知らない・・・ついでに、OpenSSL使えよという囁きが頭の中で木霊しているけど無視。

TLS1.1と1.2をSchemeで実装してhttpsとか使えるようにしたい、という願望の元とりあえず資料集めをしてみた。
基本はRFCを読めば全部書いてあるんだけど、分量が多いのと送信データが分かり辛い。2つ目のリンクは最初のネゴシエーションで使うデータが詳しく書いてあって参考になる。解説自体はSSL3.0のものだが、TLSでも基本的な部分は変わらない。違いはRFCを見て吸収。

CLIENT-HELLOを送ってSERVER-HELLOを受け取る事まではできた(データ送ればサーバが送り返してくるから当たり前だが)。っで、気づいたこと。
  • 生のバイトベクターをゴリゴリやるより、クラス作って抽象化した方が楽。
    • ASN.1(というかDER)と同じ方式。
    • パフォーマンスとコード量が気になるが、まぁいいか。
  • サーバーから返ってくるデータをどう処理しよう。
  • TLS1.2(SSL version 3.3)としてハローって言ったのに、TLS1.1でハローって返される。
    • 違いってCipherSuiteだけ?
まだ、最初のハンドシェイクさえクリアしてないからなぁ。先は長そうだ・・・

2012-05-02

Wicketが腐っているなぁと思った瞬間

Apache Wicketのことです。

事の発端はCheckGroupにAjaxFormComponentUpdatingBehaviorが渡せないということに昨日から1日悩んでいた話。サンプルはまったく見つからないし、Javadocにも特にその辺の説明はない。Google先生で検索をかけてもキーワードが悪かったので見つからない(今は解決した)。

っで、今日ちょっと頭を冷やして検索してみたらこんなスレッドを発見。
DropDownChoice, AjaxFormComponentUpdatingBehavior and dijit.form.FilteringSelect
最初に検索したときは使っているのがCheckGroupなので無視したのだが、藁にもすがる思いで覗いてみた。書いてある指摘としては、AjaxFormChoiceComponentUpdatingBehaviorを使えというもの。しかも、それがさも当たり前のように、「驚いた、実に驚いた、またこのスレだ・・・」みたいな回答がついてる。(まぁ、確かに過去ログ見ろというのも分かるが)
でも、一日3つも同様の質問が出るくらい頻繁に使われるものなのに、ドキュメントはないわ、サンプルはないわじゃ、あまり嫌味を言える立場ではないと思うのだが。 しかも、何このクラス名。混乱を招くに決まっている。せめて「このBehaviorは無視されます」、みたいなログ出してもいいだろうに、それもない。あほか!

単に、昨日一日無駄にしたので愚痴りたくなっただけ。どこかにあったなぁ、私がモダンフレームワークを嫌う理由みたいなネタ。そこからじゃないけど、「それってドキュメントあるんだよね?」って気分。