2008/09/17(Wed)Set-Cookieのpathについて

2008/09/17 18:22 Languages::Perl
Kerosoft@webのアナウンスをRSS配信するため、ウェブにコンパネを作っていた時、セッション管理用にCookieを使ったのだが、その時のメモ。

設定するとき

Set-Cookieのときのpathには注意しなくてはならない。
スクリプトの設置位置が、http://path-to-server/hogehoge.cgiだった場合、
Set-Cookie: CGISESSID=60b725f10c9c85c70d97880dfe8191b3; expires=Wed, 17-Sep-2008 21:16:22 GMT;
などとすると、デフォルトではその階層以下全てのディレクトリに対してCookieを送信してしまうので、ユーザー領域/~User/にも送ってしまうことになる。これは非常にまずい。

調べてみると、スクリプトを置く位置を自分以外がアクセスできないよう、/~hoge/以下に動かして、path=/~hoge/;とすれば安全と書いてあったが、今回のようにルートディレクトリに置きたい場合はどうするか。


結果的にいえば、こんな感じでいいようだ。
Set-Cookie: CGISESSID=60b725f10c9c85c70d97880dfe8191b3; expires=Wed, 17-Sep-2008 21:16:22 GMT; path=/hogehoge.cgi;
こうすれば、/hogehoge.cgi以下にはCookieが送られ、それ以外のアクセス(たとえば、/favicon.icoや/~user/hoge.htmlなど)へは送信されない。
このpathには、ディレクトリを指定するというような書き方をしているページが多々あったので、使い方を誤っているのかもしれないが、試した限りでは意図した動作をしているのでいいことにしようか…。
なお、別のユーザーが、/hogehoge.cgi/*等に対してアクセス権限を持っているとしたら意味がないので注意。そんなことはないと思うが。
ちなみに、/hogehoge.cgi部分は、$ENV{'SCRIPT_NAME'}で良いと思う。

削除のとき

削除する場合はexpiresに過去の値、たとえばThu, 01-Jan-1970 00:00:00 GMTを指定するが、これに関しても、pathを設定せねばならない。
Set-Cookie: CGISESSID=; expires=Thu, 01-Jan-1970 00:00:00 GMT; path=/hogehoge.cgi;
指定しない場合は、削除されない
ここに10分ほどハマってしまった……。

2008/09/14(Sun)screenでデタッチできない 解決編

2008/09/14 21:21 Software::Linux
screenでデタッチできないというのを書いたが、解決法発見。
デタッチできないというよりも、むしろアタッチできないという方が正しい表現だったようだ。

これはscreenの問題ではなく、回線が切れたときにsshセッションが切れず、sshdプロセスが生きたままで、その応答待ちでscreenがattachedから変化しない模様。

以下、対処法。
$ ps x | grep pts | grep sshd
13819 ?        S      0:00 sshd: kero@pts/2
13985 ?        S      0:00 sshd: kero@pts/8
14595 pts/2    S+     0:00 grep sshd

grepが走っているpts/2が現在操作中のポートなので、pts/8を落とす。

$ kill -KILL 13985

$ screen -ls
There is a screen on:
        9120.pts-0.spinel       (Multi, detached)
1 Socket in /var/run/screen/S-kero.

$ screen -r
これで自動的にdetatchされ(autodetatchがonの場合)再アタッチ可能になる。


が、いちいちこんな事やるのが面倒なので、自分以外のsshセッションを片っ端から強制終了するスクリプトを書いてみた。
最近Perlの正規表現にハマってたりなので…。/bin/sh+sedかawk…と思いつつも、慣れてる方が書きやすい。
だいたい検証したけど、killのとこだけは検証してない…。たぶん大丈夫。ちゃんと動きました。
screenの内側から実行しないように注意。
#!/usr/bin/perl
use strict;

(my $tty = `echo -n \$SSH_TTY`) =~ s/\/dev\///;
my $dead = `ps x | grep pts | grep sshd | grep -v $tty | grep -v grep`;
foreach(split(/\n/, $dead)){
    $_ =~ s/^\s*(\d+).+$/$1/;
    print qq|Kill pid=$_...\n|;
    `kill -KILL $_`;
}

参考元:http://subtech.g.hatena.ne.jp/cho45/20070517/1179373075

2008/09/13(Sat)バッチファイルで時計表示

2008/09/13 17:56 Software::Windows
あるステータスをバッチファイルで延々流し続けたいときに、パッと見て、その行のレコードが何時何分何秒のデータかを分かりやすくしたかったので、バッチファイルで時計を表示するコードを書いてみた。

とまぁこれが、結構面倒で^^;
time /Tコマンドでは、秒まで出てきません。
秒は%time%という変数を使うことまで1/100秒単位までご丁寧に出てくれるのですが、はっきり言って無駄…

で、これを使わざるをえないことに。
結構XPだったり2000だったりで出力に差があるらしいのですが、ここはXP x64 SP2ベースで書きます。
自分の場合は、24時間制で0補完済みの2桁ごとで区切られた数が得られたので、「あぁ、substringかけるだけじゃん~」と思ったら……

実は厄介でした。0の扱いが。
先頭に0がついた、06といった数字は、8進数の6を表すような解釈をするらしく、秒の部分だけを切りだして変数に入れる(set /aでは式の評価が行われる)と、システムの時計が8秒と9秒のとき、"無効な数字です"と文句を言われます。

というわけで、結構苦肉の策。
@echo off
set n=-1
:LOOP
set /a t=%time:~6,1%
if %t% == 0 (set /a s=%time:~7,1%) else (set /a s=%time:~6,2%)
if %s% == %n% goto LOOP
set /a n=%s%
echo %time:~0,8%
goto LOOP
実行結果
17:53:40
17:53:41
17:53:42
17:53:43
17:53:44
17:53:45
17:53:46
17:53:47
17:53:48
17:53:49
…
もっとスマートに書けるのかもしれんが……。あぁ、とりあえず外部アプリのsleep.exeとか、JSを開く手はナシで。
ちなみに、ping -n [止めたい秒数] localhost >NULという書き方も紹介されてましたが、なんか1秒置きにうまく動いてくれませんでした。


まったくもって、Linuxのbashは賢すぎる。
あっちなら
echo -e "`date "+%Y/%m/%d %H:%M:%S"`"
なんて手軽に書ける。曜日や"1日前"、なんてのもお茶の子さいさい。
あぁ、こんな表現使うの久々…(笑)

2008/09/12(Fri)BSOD 0x35 NO_MORE_IRP_STACK_LOCATIONS with KIS 解決法

2008/09/12 21:20 Software::Windows
BSOD中間まとめで書いたが、このKaspersky Internet SecurityとWindowsファイル共有が相性悪くて、BSOD 0x35 NO_MORE_IRP_STACK_LOCATIONSで止まる件について解決法が分かった。
この話がマイナーな事を考えると、Windows XP x64 SP2限定の話で、x86には全く関係ないのかもしれない。

MSKBを探し回った結果

0x35エラーが引っかかったが、ドメイン参加ではないのでドメインにログオンしようとすると、「 STOP 0x00000035 NO_MORE_IRP_STACK_LOCATIONS」エラー メッセージを表示することがあります。は関係ない。
SP2も適応済みであり、mup.sysのバージョンは公開されているパッチよりもずっと新しかった。

mup.png


Kaspersky Laboを探しまわった結果

このエントリが引っかかって、
I should also mention, I tried changing HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Klif Start key to 2 (currently still set that way), and that did not help. I then added to HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanServer\Parameters an IRPStackSize key, started at 15, ran it up to 50, but that also did nothing.
というのがあったので、ダメ元で、
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\KLIF]
"Start"=dword:00000002
に変更。元々は、
"Start"=dword:00000001
でした。
このStartの値が何を示すかというのは、MSKBによると0x01の方が0x02よりローレベルな段階で起動する模様。
ゆえに、エラーが起こった時はKernel Panic=BSODとなるわけですか…。ふむ。

とりあえず、結果からいえば、これで直った。
この変更を加えても、一応Firewallは正常に動作しているようで、未定義のルールについてはちゃんと警告出してきているし、Sambaのやり取りも問題なくなった。


一件落着。
今回はBSOD系のエラーでも、すごくマイナーな物だったから余計に苦労したな…。

追記 2008/09/15

x86にKIS7をインストールしている場合でもStart=0x01だが、こちらはBSODにならない。
ということは、x64環境の場合だけの問題のようですね。

追記 2008/12/03

しばらく使ってたら、また青くなった。
今度は、ここを変更してみた。
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\kl1]
"Start"=dword:00000002
現状とりあえず安定しているようなので、↑でダメだった人はやってみてください。