return
zddbbs.pl の関数リファレンス
zddbbs.pl version 0.98
目次
zddbbs.pl の関数は、ロック関係のものを除いては、それぞれ単独で使用可能です。
また、check_dup関数を使わないのであれば、zddbbs.datファイルは不要であり、rec_logfile関数を使わないのであれば、zddbbs.logファイルは不要です。
ただし、zddbbs.logのログファイルは、投稿者を特定し排除する上で非常に重要な情報獲得手段となるので、rec_logfile関数は必ず使用してください。しかも、ここでは投稿者のエラーコード($zddbbs'ReturnCode)も記録するので、他の関数による検査をすべて行った後に実行する方がよいでしょう。
各関数の引数は、右側から順に省略可能です。
省略した場合は、当該機能が無効になります。
左側の引数を省略する場合は、0 又は '' などを指定して下さい。
- check_size
- 機能 : 投稿メッセージの文字数を制限する。
- 形式 : &zddbbs'check_size( QUERYSTRINGS, MAXSIZE )
- 引数 :
- QUERYSTRINGS: FORMから受け取ったQUERY文字列を指定する。(デコード前のものに限る)
- MAXSIZE: 書き込みを許可する最大のバイト数を指定する。
FORMから送られてきたQUERY文字列に基づいて、これをデコードした場合の長さを検査します。
メッセージ本文に限らずタイトルなどの全ての入力欄の総文字数に基づいて判断します。また、NAME属性の名前や区切り文字も含めて数えるので、実際に許可する書き込み文字数よりも少し多い目のバイト数(minibs.cgiの場合には60バイト程度)に設定する必要があります(処理の手抜きのせいですが、普通はわずかなバイト数にすぎないので、ほとんど問題にならないでしょう)。
- 戻り値 :
- 0 : 指定バイト以内
- 1 : 指定バイトを超えた
- エラーコード :
- Sz0 : 指定バイト以上(デコード前)
- Sz1 : 指定バイト以上(デコード後)
- 投稿文字数が極端に多い場合には、他の関数での検査処理の負担が大きくなりすぎることがあります。このため、まずこの文字数の検査を最初に実行して、指定文字数を超えた場合に直ちにエラー終了とするようにして下さい。
- check_post
- 機能 : GET METHODによる投稿や外部からの投稿を禁止する。
- 形式 : &zddbbs'check_post( GET, URL )
- 引数 :
- GET: (1/0) 1 ならPOST METHOD以外による書き込みを禁止する。
METHODの検査が不要なら 0 にします。
- URL: CGIを設置したURLを指定すると、外部投稿を禁止する。
先頭から必要な長さだけ指定すれば足ります。
HTTP_REFERERのURLの検査が不要なら省略します。
- 戻り値 :
- 0 : 正規の投稿
- 1 : POST METHOD以外の書き込み又は外部投稿による書き込み
どちらが原因かはログファイルのエラーコードを見れば分かります。
- エラーコード :
- Get : POST METHOD以外による書き込み
- Rfr : 指定URLがHTTP_REFERERにマッチしない
- Rf0 : 環境変数HTTP_REFERERが設定されていない
- ブラウザやサーバーによっては、HTTP_REFERER が設定されない場合もあるので、外部投稿を禁止すると、正規の投稿者も排除されることがあります。
掲示板スクリプト側で同様の対策している場合は、この関数による検査は必要ありません。
たとえば、minibbs.cgi ver.8.8 で $ref_axs = 1; を設定してあれば、この関数による検査は不要です。
- check_user
- 機能 : 投稿者のドメインネームなどを検査をする
- 形式 : &zddbbs'check_user( HOST, PROXY1, PROXY2, JAPAN, *IPADDR, *VIA, *AGENT, *PERMISSION )
(なお、Ver.0.92 以降、*VIA が追加され、*IPADDR が普通の配列に変更されましたので、ご注意ください。)
(なお、Ver.0.93 以降、*VIA と *AGENT の禁止文字列の正規表現の取り扱いを統一しましたので、ご注意ください。)
(なお、Ver.0.96 以降、*PERMISSION が追加されました。)
- 引数 :
- HOST: (2/1/0) 1 又は 2 なら、IPアドレスからドメインネームの取得に失敗した場合に書き込みを禁止する。
たとえば、掲示板でのリモートホストの表示が数字だけになるような投稿者の書き込みを禁止できます。ただし、もしこのような人が正規の投稿者である場合には、この引数を 0 にしなければなりません。
2 にすると、プロキシサーバ経由で環境変数HTTP_X_FORWARDED_FORが設定されている場合に、ここで最初にリストアップされたIPアドレスに基づいてドメインネームが取得できなかった場合にも書き込みを禁止します。ただし、会社や学校などからのプロキシサーバー経由のアクセスの場合には、このIPアドレスがローカルである可能性もあるので、通常は 1 にします。
- PROXY1: (1/0) 1 ならプロキシサーバー経由の書き込みを禁止する。
ただし、会社や学校などからの投稿の場合には、正規の投稿者であってもプロキシサーバー経由となることがあるので、普通はこの引数は 0 にしておきます。
また、この引数を 1 にしても、プロキシサーバー特有の環境変数を調べるだけなので、プロキシサーバー経由の書き込みを全て確実に禁止できる訳ではありません(このようなプロキシサーバー経由の書き込みは、*IPADDR や *AGENT の引数を利用すれば排除できます)。
- PROXY2: (2/1/0) 1 又は 2 ならプロキシサーバ経由の場合の環境変数HTTP_X_FORWARDED_FORを検査する。
1 の場合は、この環境変数にIPアドレスがちゃんとリストアップされていない場合(たとえば空やunknownとなる場合)に書き込みを禁止します。
2 にすると、プロキシサーバ経由で環境変数HTTP_X_FORWARDED_FORが設定されなかった場合にも書き込みを禁止します。ただし、この環境変数を設定するプロキシサーバーの種類は限られるので、通常は 1 にします。
- JAPAN: (1/0) 1 ならドメインネームの末尾が.jpでない場合の書き込みを禁止する。
従って、外国からの書き込みがすべて禁止されます。しかし、この方法はどこまで有効なのかは分からないので、普通はこの引数は 0 にしておきます。
- *IPADDR: 書き込みを禁止したいIPアドレスの配列の型グロブを指定する。
REMOTE_ADDRがこの配列のいずれかのIPアドレスにマッチした場合は、書き込みを禁止します。
禁止するIPアドレスを配列 @ipaddr に格納した場合は、*ipaddr と指定します。
IPアドレスは、数字の先頭から記述し、後方は適当なところで省略できます。
正規表現は文字クラスなどが利用可能です( . は使えません。内部的には、この引数の先頭に^を付けて.を\でエスケープしてからREMOTE_ADDRとのパターンマッチを行います)
ここに不正なプロキシサーバーのIPアドレスを登録しておけば、これを経由する投稿を確実に禁止できます。
ただし、ISP(プロバイダ)などのIPアドレスである場合には、これを登録すると、そのアドレス範囲に含まれる全ての人(同じISPの同じアクセスポイントを利用する善意の人を含む)の書き込みまで禁止することになるので、十分に注意して使用してください。
たとえば、133.205.76.57 というIPアドレスの投稿者を排除する場合は、
push( @ipaddr, '133.205.76.57' ) # oosk6DU27.osk.mesh.ad.jp
と指定します。また、133.205.76.69 と 133.205.79.5 と 133.205.80.5 というIPアドレスの投稿者を排除する場合は、
push( @ipaddr, '133.205.[78]\\d.' ) # oosk?DU?.osk.mesh.ad.jp
というような指定をすることができます。あとの指定では、実際にはさらに多くのIPアドレスが排除されます。これは、都合がいい場合と悪い場合があるので、悪い方の場合には、各IPアドレスを個別に指定して下さい。(なお、このIPアドレスは例示なので、実際には指定しないで下さい…私が排除されます(^^;)
書き込み禁止の登録を行わない場合は、この引数を省略するか、右側にまだ引数がある場合は '' を指定します。
- *VIA: HTTP_VIA 中にある禁止したい文字列を格納した配列の型グロブを指定する。
禁止文字列には正規表現は使えません(←「この表現は正しくない」と突っ込まないで下さい。つまり、メタキャラクタもその文字そのものとして扱います)。ただし、大文字小文字は区別しません。
特定のプロキシサーバーなどを排除するために利用してください。
push( @via, 'ayasige.na.net' ); # 登録例
書き込み禁止の登録を行わない場合は、この引数を省略するか、右側にまだ引数がある場合は '' を指定します。
- *AGENT: HTTP_USER_AGENT 中にある禁止したい文字列を格納した配列の型グロブを指定する。
禁止文字列には、*VIAの場合と同様に、いわゆる正規表現は使えません。ただし、大文字小文字は区別しません。
特定のプロキシサーバーや自動書き込みツールなどを排除するために利用してください。
push( @agent, "(via " ); # 登録例
書き込み禁止の登録を行わない場合は、この引数を省略するか、右側にまだ引数がある場合は '' を指定します。
- *PERMISSION: 無条件に書き込みを許可するIPアドレスを格納した配列の型グロブを指定する。
REMOTE_ADDRがこの配列のいずれかのIPアドレスに一致した場合は、他を検査することなく無条件に書き込みを許可します。
IPアドレスにはいわゆる正規表現は使えません。
PROXY1を 1 にするなどしてプロキシサーバー経由の書き込みをすべて禁止した場合などに、会社や学校などからのプロキシサーバー経由の正規の書き込みを個別に許可したいときに使用します。
push( @permission, '123.45.67.8' ); # 登録例
書き込み許可の登録を行わない場合は、この引数を省略します。
- 戻り値 :
- 0=正当と思われる投稿者
- 1=不正と思われる投稿者
- エラーコード :
- Ua1 : REMOTE_ADDR が登録されたIPアドレス(*IPADDRの指定時)
- Ua2 : HTTP_X_FORWARDED_FOR のいずれかが登録されたIPアドレス(*IPADDRの指定時)
- Ug1 : REMOTE_ADDR がドメインネームに変換できない(HOST=1)
- Ug2 : HTTP_X_FORWARDED_FOR の先頭がドメインネームに変換できない(HOST=2)
- Up0 : プロキシサーバー特有の環境変数が設定されている(PROXY1=1)
- Up1 : HTTP_X_FORWARDED_FOR に unknown などがある(PROXY2=1)
- Up2 : HTTP_X_FORWARDED_FOR の先頭に IPアドレスが記録されていない(PROXY2=1)
- Up3 : プロキシサーバー経由であるにもかかわらず、環境変数 HTTP_X_FORWARDED_FOR が設定されていない(PROXY2=2)
- Uj1 : REMOTE_HOST のドメインネームの末尾が .jp ではない(JAPAN=1)
- Uj2 : HTTP_X_FORWARDED_FOR の先頭のドメインネームの末尾が .jp ではない(JAPAN=1)
- Uv0 : HTTP_VIA に禁止文字列が存在する(*VIA指定時)
- Uu0 : HTTP_USER_AGENT に禁止文字列が存在する(*AGENT指定時)
- check_frq
- 機能 : 使用文字種が異常に少ないメッセージの書き込みを禁止する。
指定した文字列に使用されるキャラクタの種類の数を数えて、全文字数に対する割合が異常に少ない場合の書き込みを禁止します。つまり、1種類の文字だけや同じ文字列の繰り返しだけからなるメッセージを排除します。
- 形式 : &zddbbs'check_frq( DST )
- 引数 :
- 戻り値 :
- 0 : 問題なし
- 1 : 使用文字種が少ない
- -1 : タグと改行しかない
- エラーコード :
- Fr0 : 使用文字種が少ない
- Fr1 : タグと改行しかない
- ★日本語文字コードがShift-JIS又はEUCの場合以外は、あまり有効な検査はできません。(日本語の文字コードの簡単な判定を行いますが、あまり正確ではありません(^^;)
- check_str
- 機能 : 登録した禁止文字列が含まれたメッセージの投稿を禁止する。
- 形式 : &zddbbs'check_str( DST, *ARRY, COUNT )
- 引数 :
- DST: 検査対象となる文字列を指定する。
- ARRY: 禁止文字列を格納した配列の型グロブを指定する。
push( @taboo, 'バカ野郎' );
などとして禁止文字列を登録します。
禁止文字列にはいわゆる正規表現は使えません(つまり、メタキャラクタもその文字そのものとして扱います)。また、大文字小文字も区別します(Shift-JIS対策のため、check_user関数の*VIAや*AGENTとは異なる)。
- COUNT: 禁止文字列がCOUNT数以上あるかどうかを検査する。
この引数を省略した場合は、COUNT==1 と解釈します。
- 戻り値 :
- 最初に発見した禁止文字列を返す。
- 禁止文字列が見つからなかった場合(COUNT数以上なかった場合)は '' を返す
- エラーコード :
- Tb0 : 禁止文字列が見つかった(COUNT数以上あった)
- ★日本語文字コードがShift-JIS又はEUCの場合以外は使用できません。
COUNTを指定しない場合、一個所でも禁止文字列があればメッセージの書き込みを禁止するので、偶然の一致によって普通のメッセージが排除されないように、禁止文字列は慎重に選択する必要があります。また、これにより書き込みを禁止する場合は、戻り値の文字列を投稿者に示して、悪意のない人に禁止した理由を明らかにした方がよいかも知れません。
COUNTを指定しておけば、悪意の投稿者が何度も同じ言葉を使わない限り書き込みは禁止できませんが、善意の投稿者のメッセージが誤って排除される不都合をある程度回避できるかも知れません。
禁止文字列の配列を複数用意して、各配列ごとにCOUNTの値を変えて検査することができます。
- check_dup
- 機能 : 同一内容の重複書き込みや同一人の短時間内の連続書き込みを禁止する。
- 形式 : &zddbbs'check_dup( FILE, STRINGS, LEVEL, ADDR, TIMER )
- 引数 :
- FILE: 前回の書き込みデータを保存するファイル名を設定する。
上記 'zddbbs.dat' を指定します。
- STRINGS: 今回の投稿メッセージを指定する。
- LEVEL: 0 なら改行を除いて完全一致した場合に禁止する。
1 なら前回とほぼ一致した場合にも禁止する。
- ADDR: 今回の投稿者のID(たとえば $ENV{'REMOTE_ADDR'} )を指定する。
- TIMER: 同一投稿者の連続書き込みを許可する時間間隔を秒単位で指定する。
- 戻り値 :
- 0 : 新規書き込み
- 1 : 同一内容の重複書き込み
- 2 : 同一人による指定時間内の連続書き込み
- 10 : 書き込みデータファイルのロックに失敗した
- エラーコード :
- Dp0 : 完全一致
- D34 : ほぼ一致(4分の3が一致)
- Wt0 : 指定時間内の連続書き込み
- 書き込みデータは、この関数内で $zddbbs'ReturnCode を調べて、今回の書き込みに問題がなければ更新するので、他の全ての検査が終了してから、この関数を呼び出すようにして下さい。
(この検査は、日本語文字コードに依存しないはずです)
- cleanup
- 機能 : 投稿者が書き直しを行うような場合に、重複書き込み検査用のデータを削除するために使用する。
- 形式 : &zddbbs'cleanup( FILE )
- 引数 :
- FILE: &zddbbs'check_dup と同じファイル名を指定する。
- check_dup関数の引数LEVELを 1 にすると、投稿者がメッセージの一部を修正して書き直しを行うような場合に重複書き込みとなって書き込みが禁止されてしまいます。そこで、掲示板スクリプトの削除ルーチンでこの関数を呼び出すようにして、まず先のメッセージを削除してもらい、この際に重複書き込み検査用のデータを削除するようにします。
- rec_logfile
- 機能 : 投稿者に関する情報や書き込みを拒否した場合のエラーコードをログファイルに記録する。
- 形式 : &zddbbs'rec_logfile( LOGFILE, MAX, HEADER )
- 引数 :
- LOGFILE: ログファイル名を設定する。
上記 'zddbbs.log' を指定します。
- MAX: ログの最大記録数を設定する。
- HEADER: ログの各行の最初に付加するヘッダ文字列を設定する。
ヘッダが不要な場合は省略します。
メッセージの書き込み時だけでなくメッセージの削除の際にも、check_user 関数を使用した後でこの関数を呼び出せば、不正な削除を監視することができます。このような場合、ログファイルに保存するデータの先頭にマークを付加して、書き込みと削除の区別をすることができます。
なお、書き込みや削除時だけでなく、読み出し時にも訪問者のログを記録することは可能ですが、検査結果に基づいて閲覧を拒否するようなことは、インターネット上ではあまり好ましいことではないと思われます。
- ログファイルには、$zddbbs'ReturnCode も記録するので、全ての検査が完了してからこの関数を呼び出すようにして下さい。
- check_symlink
- 機能 : システムが symlink を利用できるかどうかを検査する。
- 形式 : &zddbbs'check_symlink
- 設置の際に、最初に1回だけ実行します。
require './zddbbs.pl';
の直後に
&zddbbs'check_symlink;
の行を挿入して掲示板スクリプトを実行します。すると、検査結果をHTMLとして返すので、以降はこの行を削除するかコメントアウトしてください。
検査結果で「OK」が返れば、symlink が利用可能であり、ファイルのロックが使えます。
- setlock
- ファイルのロックを使用可能にする。
- 形式 : &zddbbs'setlock
- スクリプトの最初の方で呼び出します。たとえば、
require './zddbbs.pl';
の直後に
&zddbbs'setlock;
の行を挿入します。
- lockfile
- 機能 : ファイルをロックする。
- 形式 : &zddbbs'lockfile( LOCKFILE )
- 引数 :
- LOCKFILE: ロックの対象となるファイル名を指定する。
- 戻り値 :
- setlock 関数を呼び出している場合には、check_dup と rec_logfile の関数内で、'zddbbs.dat' と 'zddbbs.log' のロックに使用します。
この関数は、掲示板のデータファイルなどのロックにも利用できます。ただし、一度にロックできるのは1ファイルに限り、重複して使用することはできません。
- unlockfile
- 機能 : ロックを解除する。
- 形式 : &zddbbs'unlockfile
- lockfile 関数でロックしたファイルのロックを解除する場合に呼び出します。
- 参照可能な変数
- $zddbbs'ReturnCode : ログファイルに書き込むエラーコード文字列
- $zddbbs'DomainName : 投稿者のドメインネーム
プロキシサーバ経由の場合は、( )内に基点のドメインネームを付加します。
また、HTTP_FROMが設定された場合は、[ ]内にこれを付加します。