Windows 上の Apache でも動くパスワード変更 CGI の書き方

要約

 .htpasswd ファイルの内容をユーザーが自分で変更できるようにする CGI スクリプトを Windows 上の Apache で動かすには注意が必要です。 Perl で書くなら Apache::Htpasswd モジュールAuthen::Htpasswd モジュールを使いましょう。

問題と答え

 Apache の AuthUserFile に指定するファイル (通称 .htpasswd ファイル) の内容をユーザーが自分で変更するための CGI スクリプト (以下パスワード変更 CGI スクリプトと称す) は世の中にたくさんありますが、それらの多くは Unix に依存した方法を使っており、 Windows 上の Apache で正しく動くものはあまりありません。

 Windows でも動くようにするには、 Perl の Apache::Htpasswd モジュールAuthen::Htpasswd モジュールを使えばよいでしょう。 Windows の場合、これらのモジュールは自動的に Crypt::PasswdMD5 モジュールを使ってくれるので、問題は起きません。

 なお、 Apache::Htpasswd モジュールのバージョン 1.7 より前にはセキュリティ上の問題があるので使ってはいけません。

 Apache::Htpasswd モジュールは flock でロックをかけるので、 flock が機能する環境では同時に複数人がパスワードを変えようとしてもカタストロフィーにはならないはずです。 Authen::Htpasswd モジュールは詳しく見ていません。

多くのパスワード変更 CGI スクリプトが Windows で動かない原因

 セキュリティ上の問題を避けるため、 .htpasswd ファイルにはパスワードを直接書くのではなく、パスワードを暗号化した文字列が書かれています。この暗号化の際、 Unix 上の Apache では crypt 関数を使うのに対し、 Windows 上の Apache では自前で用意したルーチンを使います。多くのパスワード変更 CGI スクリプトではこの暗号化に crypt 関数を使っているため、 Windows では Apache が使う暗号化方式と食い違ってしまい、動きません。

パスワード変更 CGI スクリプトのサンプル

 Apache::Htpasswd モジュールを使って動くパスワード変更 CGI スクリプトのサンプルを示します。

見た目

 動作させると下のようなフォームが表示されます (下のフォーム自体は見た目だけであり、動作しません)。あとの使い方は自分で考えてください。

User:
Old:
New:
Retype:

注意とダウンロード

 やっつけ仕事であり、当然、無保証です。このサンプルコードに関し、著作権を放棄します。

 無保証であることを理解した上でダウンロードする場合はこちら

 なお、メッセージは全部英語のように見える文字列です。でも間違っている可能性が高いです。やっつけ仕事なので仕方がありません。

必要なもの・インストール方法

 Perl 5.8 で動きます。 Apache::Htpasswd モジュールが必要です。さらに、 Windows の場合は Apache::Htpasswd モジュールが必要とする Crypt::PasswdMD5 モジュールもインストールしておく必要があります。

 先頭行の perl のパスと、「### Configuration」から「### End of configuration」までの間を適宜変更してください。

セキュリティー

 通信路上での盗聴が心配な場合は https を使ってください。この文の意味がわからない人はこのスクリプトを使ってはいけません。

 繰り返しになりますが、Apache::Htpasswd モジュールのバージョン 1.7 より前にはセキュリティ上の問題があるので、必ず 1.7 以降のバージョンを使ってください。

 以上の点を除けば、セキュリティー的にとくに問題になるようなことはしていないつもりです。でも無保証です。

 恐ろしいことに use warnings しているので、このスクリプトにバグがあるとウェブサーバーのログファイルに大量の警告が吐かれる可能性があります。

バグ・非バグ

.htpasswd ファイルのパスワードの欄が空のとき、 Apache はパスワードなしで認証してくれますが、このスクリプトではどうやってもパスワードを変えられません。
 バグですが、たぶん Apache と Apache::Htpasswd モジュールの動作が違うのが原因で、僕のせいではありません。やっつけ仕事なので回避していません。
新パスワードを空にできません。
 バグではなく、わざとそうしてあります。新パスワードの欄が二つとも空だからといって、ユーザーが本当にパスワードを空にしようとしているとは思えず、ユーザーが何か間違えていると考えられるので、エラーになるようにしました。
ユーザー名と旧パスワードの組合せが間違っている場合と、ファイルが何らかの原因で書き込めなかった場合の区別が付きません。
 バグですが、やっつけ仕事なので仕方がありません。
ユーザー名が正しくて旧パスワードが間違っている場合と、ユーザー名が間違っている場合の区別が付きません。
 バグではありません。その区別が付くようにするとセキュリティホールらしいので、わざと区別が付かないようにしています。
設定したはずのパスワードを入れても認証されません。
 キーを押し間違えたか、 Caps Lock キーが入っていたか、英語キーボードだったりしたか、このスクリプトがバグっているか。バグであるかないかすらわかりません。

主な更新の記録

2006 年 10 月 17 日公開、 2006 年 11 月 16 日最終更新。著者: fcp / このサイトについて