DRAGON MAGAZINE と The Sneaker を買う。
The Sneaker に 7月の新刊情報が載っていたので買うと推測されるものを数えてみる。 ソノラマ文庫 1(おぉ、野尻抱介が。)、 ファミ通文庫 1、 ティーンズルビー文庫 1、 電撃文庫 1、 X文庫ホワイトハート 1(ついに「暁のアリエラ」が。)、 ファンタジア文庫 6、 計 11 冊てなところか。
ウィングス文庫のが新書で出た奴でないとすれば 1冊増えるだろうし、 気が向けばもっと買うこともあるだろうし、 発売延期になって減ることもあるだろうが...
コバルト文庫はすでに出ていたが買うものはなかった。 来月は楽園が出るようだが。
「龍神さまリターンズ まごころを、君に。」を読み、恋の成就に感動... しない。
match: 点の集合を...
「暁の娘アリエラ 上」を読む。ラクシア怪しすぎ。
CVSup の問題はこちらでは再現しません。
g3data: グラフ(位置で数値を表現する奴。(V, E) のほうではない。)から数値を復元するツール。
ふと、次期システム(なんの?)のための文字コード検出ルーチンを Ruby で書いてみる。 個々の文字コードの知識をいかにモジュール化するかがポイントであるが、 あるバイト列がある文字コードとして正しいかどうかという情報だけでは 実用的なものにならないのが難しいところである。 (つまり、正しいかどうかの判断以外の API も提供しなければならないが、 その API の設計が難しい。)
結局、正しい場合にそのバイト列の「ありがち」度を数値として評価し、 もっとも「ありがち」な解釈を選ぶことにした。 (一般に、 文字が割り当てられていないコードポイントがでてくるのはあきらかにありがちではないし、 怪しい制御文字や JIS X 0201 カタカナが出現するのも間違っているわけではないがありがちではない。)
数値化するのはあまりうまいやりかたではないだろうが、 すごくひどい目にあうことは少ないだろうとは思う。 具体的にその数値を求めるためには、 問題のバイト列を正規表現で照合し、 ありがちでない状態遷移を行なったかどうかを match data($~) から調べて適当に重みづけして一次結合した。 match data のこんな使い方は初めてで、 異様に怪しい使い方に思える。 それはともかく、問題の遷移を何回したかはわからないのがなんだが、あまり気にしないことにする。 (Perl 5.6 だとわかるのかもしれない。)
freshmeat に OBJ3 が。 (名前だけ見た時には同名の何か他のものだと思ったが...)
(推測の3倍ほど買ってしまった電撃文庫がどれもそれほどではなかったこともあり)気が向いてコバルト文庫の 「ウォーターソング」を読む。表題作にはとくに惹かれなかったが...
なお、来月買うと推測される電撃文庫は 2、コバルト文庫は 1。
fj.unix.shells にもうひとつ投稿しかけるがうまく書けなかったので結局やめる。
cvs の port については パッチのありかも含めて書き留めておいた覚えが...
CVS_CLIENT_PORT って効かなかったのか...
ltrace: Shows runtime library call information for dynamically linked executables
diffconvert: unified diff <-> context diff (と reverse)。 ネタもなかなかだが実装言語も...
古本屋で LOGOUT 1994/4 をみつける。 読み逃していた文庫本未収録な六覇国伝の短編が読めてちょっと嬉しい。
twin: (大幅に拡張された?) splitvt の類
Ruby で rescue の中で return した後に問題があると変な(とゆーか rescue ですでに捕まえたはずの)エラーが表示される気がする。
mergetrees: まぁ、cvs をつかってるかぎりは縁のないツールだが。
tcpdump 3.5/libpcap 0.5: やっと出たか...
スーパーダッシュ文庫を 60% ほど買う。
壊れる端から直していき、直る端から壊していく。 よくやるとは思うがバグ報告にもいーかげん飽きてくる。 design problem は見なかったことにしておくとしても、 いいかげん test suite を増やして手間を減らさないとな...
cvs protocol の proxy を作ってみる。
zlib が使えないと Gzip-stream 以降の中身が調べられないことに気がつく。 Ruby/zlib でも試すか。
cvs client の危うさに気がつく。 server は client に任意のファイルを任意の場所に作るよう指示できるようだ。
libmng: libmng - THE MNG library
interdiff: generates an incremental patch from two patches against a common source
Pliant: efficient, truly extendable, customizable programming language
Ruby/zlib はバッファの制御(フラッシュ)が甘いのが画竜点睛を欠くというやつだな。
例えば、次のようにすると確認できる。
% ls -l /tmp/foo ls: /tmp/foo: No such file or directory % cat crackers-cvs-server #!/bin/sh cat <<'End' Valid-requests Root Valid-responses valid-requests Repository Directory Max-dotdot Static-directory Sticky Checkin-prog Update-prog Entry Kopt Checkin-time Modified Is-modified UseUnchanged Unchanged Notify Questionable Case Argument Argumentx Global_option Gzip-stream wrapper-sendme-rcsOptions Set Kerberos-encrypt expand-modules ci co update diff log add remove update-patches gzip-file-contents status rdiff tag rtag import admin export history release watch-on watch-off watch-add watch-remove watchers editors init annotate noop ok Module-expansion tst ok Clear-sticky tst/ /cvsroot/tst/ Clear-static-directory tst/ /cvsroot/tst/ E cvs server: Updating tst Created /tmp/ /cvsroot/tst/foo /foo/1.1/// u=rw,g=rw,o=rw 4 abc ok End % CVS_RSH=./crackers-cvs-server cvs -f -d :ext:user@server:/cvsroot co tst cvs server: Updating tst cvs checkout: in directory /tmp: cvs checkout: cannot open CVS/Entries for reading: No such file or directory cvs checkout: cannot open CVS/Entries.Log: No such file or directory % ls -l /tmp/foo -rw-r--r-- 1 akr wheel 4 Jul 19 22:01 /tmp/foo % cat /tmp/foo abc % cvs -v Concurrent Versions System (CVS) 1.10.8 (client/server) Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, Jeff Polk, and other authors CVS may be copied only under the terms of the GNU General Public License, a copy of which can be found with the CVS distribution kit. Specify the --help option for further information about CVS %
server が伝えてくるパスを client が盲目的に信用してしまうのも何だが、 それ以前に client 側のパスを server が処理するようになっているプロトコルが論外。 さらにいえば、レスポンスの自由度が高すぎて、 server が好き勝手に client に指示を出せるというのが根本的な問題ではある。
予測はしていたものの、 1byte 毎に read(1) で読んで inflate 展開していくのはあまりに遅かった。 が、しかし、2bytes 以上を一度に読むと dead lock が生じるのでそういうわけにもいかない。 (deflate 圧縮のフォーマットを理解すればもうすこしたくさん読めるのかも知れないが。)
理想的には到着したデータを全て読み、それ以上は読まない、という動作ができればいいのだが、 標準入出力ライブラリを通して可能なのだろうか?
ふと、思いついて file descriptor を NONBLOCK にしてみると、なんとなくうまく動作するコードが書けた。 ポータビリティが微妙に心配だが、あまり気にしないことにする。 clearerr しないといけないのではないか、 という気もしないでもないが、Ruby からはできないようなのでこれも気にしないことにする。
require 'fcntl' class IO def read_available fl = self.fcntl(Fcntl::F_GETFL) self.fcntl(Fcntl::F_SETFL, File::NONBLOCK) data = begin self.read rescue Errno::EWOULDBLOCK "" end self.fcntl(Fcntl::F_SETFL, fl) return data end end
文字単位の diff は聞いたことがありませんが、 単語単位なら wdiff があります。
なお、(もちろん)日本語の単語は切り出せませんが、 昔、kakasi を使った次のような wrapper を使っていたことがあります。
#!/bin/sh tmp1=/tmp/jwdiff$$-1 tmp2=/tmp/jwdiff$$-2 trap "rm -f $tmp1 $tmp2" 0 1 2 3 15 cat "$1" |nkf -e|kakasi -s > $tmp1 cat "$2" |nkf -e|kakasi -s > $tmp2 wdiff $tmp1 $tmp2|tr -d ' '
どうしても文字単位にしたいのなら、一文字を一行に展開した後に diff をとるような wrapper を作ることになるのでしょう。(wdiff はそれを単語単位にやっているわけですが。)
あとは、perl の Algorithm::Diffを使うという手もあるかも知れません。 使ったことはありませんが。
べつに危険なのは pserver には限りませんがね。 pserver だろうと ext だろうと中身は(認証を除けば)同じなので、 サーバが危ない返事をする限りは同じことです。
まぁ、ext だと通信手段は謎なので、いきなりローカルで cvs server を実行するだけとかだと 安全かも知れませんが。
cvs には server 側の危険性 (Checkin.prog や Update.prog を使うと comitter は任意のコマンドを server 上で実行できてしまう)もあるのだが、 そっちの反応は今回よりも更に鈍かった気がする... なんでみんな気にしないんだろ?
The Dotfile Generator の作者が zsh ユーザだったとは知らなかったね。
proxy は問題なく動作して、server から送られてきたファイルを保存することはできた。 (ついでに rcs diff が送られてきた場合に、もとのやつが保存してあったらパッチを当てたものも保存する。)
そろそろ飽きてきたので、ここからどうするかは問題である。
まぁ、proxy は protocol の実験をするには便利だよな。 Valid-responses から Rcs-diff を抜いてみた (ら Patched が使われたが client がうまく扱えなかった)り、 Valid-requests から Gzip-stream を抜いてみた (ら gzip-file-contents が使われて file transmission ごとに圧縮がかかったのだが、 Rcs-diff の中身がそうなっていると client はそれを扱えなかった)り、 Copy-file を適当に挿入してみた(ら / 直下にファイルをコピーできることに気がついた)り。
いや、むろん最後のは client に root 権限が必要なわけで、 そもそも client を root 権限で動かすのがすでに論外であることが判明している以上 あまり意味はないといえばそうなのだが。 (それに / 直下には、(ものにもよるが)カーネルと root の設定ファイルくらいしかないし。)
しかし、cvs client を chroot することを本気で検討しようかと思わないでもない今日この頃。 可能だろうか?
fhist: a file history tool ``fhist'', a file comparison tool ``fcomp'', and a file merging tool ``fmerge''.
まぁ、client を chroot するよりは proxy を仕上げて危ない response をはねる方が現実的かな。
そーいや、server 側に proxy を設置して Checkin.prog/Update.prog を proxy で送り返すようにすれば client に依存しないようにできるんだよな... (そもそも server が毎回 modules を読めばいいのだというのはそのとおりなのだが...)
修正されたファイルを update するときには修正されたファイル全体が server に送られ、 merge されたものが返ってくる。 これはつまり個人的な変更を監視できてしまうということだな...
cvs を setuid するのは恐いので、 sshd を chroot jail 内で動かしたらどうかとアドバイスを受ける。
たしかにいいアイデアかも知れない。 ユーザや PermitEmptyPasswords を通常の設定とは別にできるし。 cvs と sshd を chroot jail 内におかなければならないというのがすこし気に食わないが...
いいアイデアかも知れないと思ったのも束の間、 sshd を chroot jail 内におくということは authorized_keys も chroot jail 内になるということに気がつく。 これはうまくない。
chroot 内の sshd に UID 0 なユーザに対して ssh させて、そこから更に chroot すればいい?
ふと、request - response 型の protocol では、 request と response を mix した列に対する文法が存在するということに思い至る。 というわけでパーザジェネレータで proxy を実装することを考える。
ここで、proxy をパーザとして実装するとすれば、 字句を要求した時点で次に来るべきものが request か response かがわからなければならないのが問題である。 再帰降下文法で実装するならこれはほとんど自明であるが、 LR では話は単純ではない。
request と response がまったく異なる字句から構成されていると仮定すると、 LR パーザのある状態において、 エラーにならない字句が request を構成する字句のみからなるか、あるいは response を構成する字句のみからなるか、 そのどちらであるかを判断しなければならない。 (どちらの字句もエラーにならない可能性がある場合には protocol が request - response 型ではないということを示している。) LR(1) であれば、各状態においてエラーにならない字句の集合を静的に求めることができるので、これは比較的簡単である。
しかし、LALR(1) だと何回か reduce が起きた後にエラーになる可能性があるため、 単純にエラーにならない字句の集合を求めることができない。 ここで疑問なのは request - response 型の protocol から LALR(1) で LR オートマトンを作った場合に、 各状態は次の字句が request か response かを判断するに足る情報を持っているのか、ということであり、 また、もし持っていないとすれば、 状態を分割して LR(1) に近づけることによりその判断を可能とすることは容易なのか、ということである。
protocol = | protocol request response request = reqkey1 qline | reqkey2 qline qline qline = qprintables qnewline
とすれば {qline = qprintables qnewline.} が reduce するときには次が request か response か 判断できない... でも lookahead 無しで reduce できるから問題ないか。
うぅむ。問題が出ることはあり得るのだろうか。
info -f xxx.info としただけでは xxx.info-1 とかをカレントディレクトリから読んでくれないことに気がつく。
bugtraq はなかなか強力だ。
ただし、vacation だのなんだのがいくつか返ってくる。 しかも、英語以外でかいてあるものが多く、読めないものが多い。
興味深いものとして encoded-word および本文で windows-1252 という charset が使われているのがあった。 (本文の先頭に Bonjour と書いてあるのでフランスあたりかもしれない?)
ほかには X400 関係なのか Message-Id: <054DB398210D200C*/c=de/admd=dbag/prmd=db/o=ln1/s=Kracht/g=Holger/@MHS> なんてのもあった。
CVSup でリポジトリをコピーしてコピーを anonymous cvs pserver で公開する、か... たとえ read-only だろうがそうする気になるほど cvs server は危険だってことですかねぇ。
なぜに素直に sjis を再定義しないのだろう。
(require 'pccl) (define-ccl-program true-sjis-decode `(2 (loop (read r0) (if (r0 < 127) (if (r0 < 93) (if (r0 < 92) (write-repeat r0) (write-repeat ,(make-char 'latin-jisx0201 92))) (if (r0 < 126) (write-repeat r0) (write-repeat ,(make-char 'latin-jisx0201 126)))) (if (r0 < 224) (if (r0 < 160) (if (r0 < 129) (write-repeat r0)) (if (r0 < 161) (write-repeat r0) ((write ,(charset-id 'katakana-jisx0201)) (write-repeat r0)))) (if (r0 >= 240) (write-repeat r0)))) (read r1) (r2 = (r0 de-sjis r1)) (r3 = r7) (r3 |= 128) (write ,(charset-id 'japanese-jisx0208)) (write (r2 | 128)) (write-repeat r3)))) (define-ccl-program true-sjis-encode `(1 (loop (read r0) (if (r0 < 128) (write-repeat r0) (if (r0 == ,(charset-id 'japanese-jisx0208)) ((read r1) (read r2) (r1 &= 127) (r2 &= 127) (r3 = (r1 en-sjis r2)) (r4 = r7) (write r3) (write-repeat r4)) (if (r0 == ,(charset-id 'katakana-jisx0201)) ((read r1) (write-repeat r1)) (if (r0 == ,(charset-id 'latin-jisx0201)) ((read r1) (r1 &= 127) (write-repeat r1)) (write-repeat r1)))))))) (make-ccl-coding-system 'true-sjis ?S "True SJIS" 'true-sjis-decode 'true-sjis-encode) (put 'sjis 'coding-system (get 'true-sjis 'coding-system))
まぁ、これだけだと改行コード関係の派生種で問題が出るような気もするが。
いや、本当に素直なのは sjis だろうが ccl だろうが translation table が効くようにして欲しいと頼むことかな。
リポジトリをコピーしなくても anonymous な時にはの uid を変えれば同等の防御になるか。 LockDir がない頃にはできなかっただろうが。 (ロック自体を問題にするならまだコピーの意味は残っている?)
cvs はデザイン上たとえ anonymous だろうが shell access を提供しかねないのだ、 という立場はいっそすがすがしくて憧れてしまう。
[latest]