#!/usr/bin/perl #--- 必ずあなたの環境に合わせて書き替える項目 --------------------------------------------# @background = ('pana.jpg','jime.jpg','hoga3.jpg','kizupana.jpg'); srand; $background = $background[rand(@background)]; ################################################## # このスクリプトをURLで設定 $reload = './index.cgi'; ################################################## # 背景色と基本文字色等の設定(通常のBODYタグ) $body = "\n"; ################################### 表示関係の設定 ######################################## # この掲示板のトップタイトル $title = '歴史資料館伝言板'; # トップタイトルの文字色とサイズ $tcolor = ''; # 投稿者名・題名の文字色 $ncolor = ''; # @または@で始まる引用行の色 $renamecolor = ''; # >または>で始まる引用行の色 $revalucolor = ''; # #または#で始まる引用行の色 $shvalucolor = ''; # unknownの色 $unknowncolor = ''; # ページのソースにリモートホスト&アドレスを表示するかどうか(の形式) # 表示しない : 0 表示する: 1 $hyouji = 0; # メール画像のアドレス $letterimg = ''; # ホームページ画像のアドレス $browserimg = ''; ##################################### 記録ファイルの設定 ###################################### # パスワードの記録ファイルの設定 $pass = './pass.txt'; # 掲示板の内容が書き込まれる記録ファイルの設定と最大記録件数(ページ表示用) $file = './minibbs.dat'; $def = 20; # 1ページに表示する件数 $defmin = 1; # 1ページに表示する最小件数 $defmax = 999; # 1ページに表示する最大件数 $max = '10000'; # 最大記録件数 # アクセスログを記録するかどうか(記録しない: 1 記録する : 0) $alog = 0; $access_log = "log.dat"; $rescue = '3000'; # カウンターを表示するかどうか(表示しない: 1 表示する : 0) $log = 0; $countdate = '99.5.20'; # カウンター開始日付 # 指定ホスト排除機能のリスト記録ファイルの設定(排除するホスト名が書き込まれます) # リストへの書き込みはminibbsの最下部セキュリティ設定から書き込みページにいけます $hostlist = './a-men.dat'; # 投稿記事番号の記録ファイル $log_number = './log_number.dat'; # 投稿記事番号を使う場合の記録ファイルの設定 # 日本語コード変換ライブラリ # この jcode.pl を minibbs.cgi と違うディレクトリに設置する場合は相対的に設定すること require 'jcode.pl'; ####################################### 管理者設定 ######################################## # 騙り防止のため投稿者の認識IDを投稿日の後ろに表示する(by /../氏 mm氏) # (IDは、削除パスワードとハンドル名の組み合わせで暗号化され固定されます) # (管理者を明示したい場合は削除パスワード欄に管理パスワードを入れると[Master]と表示 by Yuumi氏) # 表示しない : 0 表示する: 1 $DispID = 0; # 管理者のハンドル名と使われたくない名前の設定(偽名拒否設定 by TTS氏) # これを設定した場合、管理者が自分のハンドル名で書き込む際は名前入力欄に管理者パスワードを入力 # することで自動的にハンドル名に変換。ハンドル名でそのまま書くと飛ばされます(笑) # 上記で「認識IDを表示する」にしている場合はあんまり意味ありません。 # 偽名拒否設定しない : 0 する: 1 $gimei = 1; # 偽名拒否設定する場合のあなたのハンドル名(管理パスワード入力で変換される) # 全角のーが入ったハンドル(パール、かーる等)はなぜか誤作動するので使えません。諦めて下さい(^^;; $master = "Captain"; # 偽名拒否設定するハンドル、名称の設定。(半角開けて複数指定可) # ここにあなたのハンドル名を上記と同じ名前で書いておかないと偽名拒否の意味ありません。 $admin = "Captain"; ######################################## 悪戯対策 ######################################### # 上記偽名を使った場合と排除指定したホストのジャンプするURL デフォは文部省(笑)<TTS氏 $jumpurl = "http://warez.com/"; ################################################## # プロクシ経由でのアクセス(閲覧)&書き込みの許可(by カール&dimdim氏) # 許可する : 0 書き込みのみ拒否する(閲覧は可): 1 閲覧、書き込み共に拒否: 2 $proxy = 0; # プロクシ制限する場合のレベル(弱 : 1 強 : 2) # 2にするとプロクシ変数をまったく吐かないIP串以外はほとんど拒否します。 $plevel = 1; # 上記プロクシ制限をした場合に善意のアクセス者(会社のFireWall等)を指定して許可する設定 # ホスト名を|で区切って複数指定可能。IPアドレスの場合は先頭の2つが適当? # 設定例:$kyoka = "biglobe.be.jp|3web.ne.jp|202.124.|abc.com"; $kyoka = ""; ################################################## # ダブルポスト(同一内容連続投稿&リロード)対策。何件前までチェックするか(by アリス氏) $check = 0; # 投稿内容の一部分を変えての連続投稿対策(例:...第1回目、...第2回目..) # 投稿内容の先頭から指定した文字数の範囲内で同一内容か判断する(単位=バイト) $checklength = 1000; ################################################## # 投稿内容に関わらず連続投稿を指定秒数内は拒否する設定(by カール) # 同一ホストの場合のみ時間制限 : 0 ホストに関わらず時間制限: 1 $ctimer = 0; # 制限する秒数(単位:秒) $rtimer = 60; # 上記調整用(上記$rtimerが60秒の場合は下記のまま、120秒以上は+80、という感じで60秒ごとに+40加算) $timer = $rtimer + 40; ################################################## # GabriDuke等のツール対策チェックコード生成用(100〜400までの3桁の任意の数字)※必ず変更すること $num = 249; # 生成されたチェックコードをさらにキーで暗号化(任意の文字列を暗号キーとする)※必ず変更すること $key = "k932759q6"; ################################################## # 書き込み容量制限(大量カキコ対策 全角は2バイトです) $max_s = 100; #タイトル文字数 $max_n = 100; #名前文字数 $max_e = 100; #メールアドレス文字数 $max_v = 100000; #投稿内容文字数 $max_url = 300; #URL文字数 $max_line = 1000; #投稿内容行数(上の文字数との兼ね合いを考えて) ################################################## # タグを使えるようにするかどうかの設定 # 使える:1 使えない:0 $tag = 1; ################################################## # CGI二重起動防止ロック処理(データファイル消失防止) # # 通常は 1 に設定しますが、symlinkの使えない極一部のサーバでは常に「BUSY」になりますので、 # その場合は 2 に設定してください. 1 よりも 2 の方が処理が甘くなります. # ※lockディレクトリのパーミッションを777に設定し忘れた場合も常に「BUSY」になります # ※サーバーエラーで読み込み途中にエラーになると以後、常に「BUSY」になります。この場合はFTPで # lockディレクトリ内のcount.lockという自動生成されるファイルを削除して下さい。 # 負荷の高いサーバーの場合、ロック処理はおすすめできません。 # # ロック処理しない:0 ロック処理(symlink):1 ロック処理(open):2 $lock_key = 0; ################################################## # 海外サーバ等で時差が生じる場合は修正します # 海外時間に+9時間する場合 = localtime(time + 9*60*60); # 海外時間に−9時間する場合 = localtime(time - 9*60*60); ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); ################################################## # 入力形式の設定 標準入力:1(post) その他:0(get) # 投稿ボタンを押して Method not implemented.. 等というエラーが出る場合は get で試すこと # getの場合は文字制限がありますので長い文章等は途中で切れる可能性があります. # POST:1 GET:0 $method = 1; ################################################## #--- 必ずあなたの環境に合わせて書き替える項目 ここまで --------------------------------------# @key = split(//,$key); $lockfile = 'lock/count.lock';#2重起動防止ファイル(自動生成されるのでアップ不要) $addr = $ENV{'REMOTE_ADDR'}; $host = $ENV{'REMOTE_HOST'}; if ($host eq $addr) { $host = gethostbyaddr(pack('C4',split(/\./,$host)),2) || $addr; } if ($kyoka eq ""){&hostcheck;} elsif(!($host=~ /$kyoka/)){&hostcheck;} $via = $ENV{'HTTP_VIA'}; $xfor = $ENV{'HTTP_X_FORWARDED_FOR'}; $for = $ENV{'HTTP_FORWARDED'}; $agent = $ENV{'HTTP_USER_AGENT'}; $trueip= &getip; if (($kyoka eq "") && ( $proxy eq '2')){ &proxy;} elsif((!($host=~ /$kyoka/)) && ( $proxy eq '2')){ &proxy;} if ($lock_key == 1) { &lock; } elsif ($lock_key == 2) { &lock2; } $month = ($mon + 1); if ($month < 10) { $month = " $month"; } if ($mday < 10) { $mday = " $mday"; } if ($sec < 10) { $sec = "0$sec"; } if ($min < 10) { $min = "0$min"; } if ($hour < 10) { $hour = "0$hour"; } $y0="日"; $y1="月"; $y2="火"; $y3="水"; $y4="木"; $y5="金"; $y6="土"; $youbi = ($y0,$y1,$y2,$y3,$y4,$y5,$y6) [$wday]; $date_now = "$month月$mday日($youbi)$hour時$min分"; $date_num = sprintf("%02d%02d%02d%02d%02d",$mon +1,$mday,$hour,$min,$sec); # <-変更禁止 if ($method eq '1' && $ENV{'QUERY_STRING'} ne '') { &error('x'); } if ($method eq '1') { $method = 'post'; read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'}); } else { $method = 'get'; $buffer = $ENV{'QUERY_STRING'}; } @pairs = split(/&/,$buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; &jcode'convert(*value,'sjis'); $value =~ s/(教え|おしえ|オシエ|ぉιぇ|oshie|osie)(.|\n)*/もらしてほしきゃ、\n下腹を押しながらピストンすりゃぁ、\nいくらでももらすぜ、女はよ。\nへへへ・・・\n「だめ〜オシッコ出ちゃう!」「だめ〜オシッコ出ちゃう!」「だめ〜オシッコ出ちゃう!」「だめ〜オシッコ出ちゃう!」「だめ〜オシッコ出ちゃう!」「だめ〜オシッコ出ちゃう!」「だめ〜オシッコ出ちゃう!」と言ってジョォ〜っと。暖かかったです。\nげへへへへへへへへ........ホントに良いねぇ。\n/gi; $value =~ s/,/,/g; $value =~ s//>/g; $value =~ s/\r\n/\r/g; $value =~ s/\n/\r/g; @tags = split( /]*)>(.*)/$1/; $tag =~s/^\/(.*)//; $tag =~s/^([^\s]*).*/$1/; } $value.='>' if($value=~/<\/$/); @tags = reverse( @tags ); foreach $tag ( @tags ){ next if($tag =~/(img|^hr$|^br$)/i); $value.="" if($tag); } $value =~ s/\r/
/g; if ($name eq "target") { push(@RM,$value); } else { $FORM{$name} = $value; } } if (!open(DB,"$pass")) { &error('0'); } @lines = ; close(DB); $password = shift(@lines); chop($password) if $password =~ /\n$/; ($header,$password) = split(/:/,$password); if ($password =~ /^\$1\$/) { $salt = 3; } else { $salt = 0; } if ($FORM{'action'} eq 'password') { &encode; } if ($FORM{'admin'} eq 'change' && crypt($FORM{'pwd'}, substr($password,$salt,2)) eq $password) { &password; } if ($FORM{'admin'} eq 'kick' && crypt($FORM{'pwd'}, substr($password,$salt,2)) eq $password) { &kickhost; } if ($header ne 'crypt_password') { $first = 1; &password; } # 表示記事数を決定する if ($FORM{'def'} ne '') { $def = $FORM{'def'}; } if ($def < $defmin) { $def = $defmin;} if ($def > $defmax) { $def = $defmax;} $defnext = $def; # 全体の流れを決定する(actionやpwdはフォーム入力されたデータを格納する名前) if ($FORM{'action'} eq 'sremove') { &sremove; } if ($FORM{'action'} eq 'remove' && crypt($FORM{'pwd'}, substr($password,$salt,2)) eq $password) { &remove2; &remove1; if (-e $lockfile) { unlink($lockfile); } exit; } elsif ($FORM{'action'} eq 'kickout' && crypt($FORM{'pwd'}, substr($password,$salt,2)) eq $password) { &kickhost; if (-e $lockfile) { unlink($lockfile); } exit; } elsif ($FORM{'admin'} eq 'cut' && crypt($FORM{'pwd'}, substr($password,$salt,2)) eq $password) { &remove1; if (-e $lockfile) { unlink($lockfile); } exit; } elsif ($FORM{'action'} eq 'regist') { ®ist; } &html; if (-e $lockfile) { unlink($lockfile); } exit; sub html { if ($alog eq "0") { &acount;} $dammy = $date_num * $num; $chcode = ($date_num + 1000000000) * $num;# 桁揃えのため 変更は絶対不可 $i = 0; $chcode=~ s/./sprintf("%02x",ord($&)^ord($key[$i++ % @key]))/ge; #--- 入力フォーム画面 --------------------------------# # CGIで出力されたデータをHTMLとして認識させるヘッダの出力 print "Content-type: text/html\n\n"; print "$title\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "$body\n"; print "
\n"; print "$tcolor

$title


\n"; print "
MESSAGE
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
\n"; print "\n"; print "
\n"; print "\n"; print "\n"; print "
名前:
タイトル:
E-Mailアドレス:
ホームページ URL:
表\示する件数:
\n"; print "内容:
\n"; print "
\n"; print "
\n"; print "\n"; print "\n"; print "\n\n"; print "
\n\n"; #--- 記録記事の出力 ----------------------------------# if (!open(DB,"$file")) { &error('0'); } @lines = ; close(DB); if ($FORM{'page'} eq '') { $page = 0; } else { $page = $FORM{'page'}; } $accesses = @lines; $accesses--; $taccesses = $accesses + 1; $page_end = $page + $def - 1; if ($page_end > $accesses) { $page_end = $accesses; } foreach ($page .. $page_end) { # データを各変数に代入する ($number,$spwd,$date,$name,$email,$value,$subject,$link,$host,$addr,$via,$for,$trueip,$agent,$how,$checkcode,$homepage,$log_count) = split(/\,/,$lines[$_]); $value =~ s/\0/\,/g; @t_value = split(/
/,$value); $value = ""; for (@t_value) { if ($_ =~ /^@|^@/) { $value .= "$renamecolor$_

";} elsif ($_ =~ /^>|^>/) { $value .= "$revalucolor$_

";} elsif ($_ =~ /^#|^#/) { $value .= "$shvalucolor$_

";} else { $value .= "$_
"; } } print "$ncolor

[$log_count] "; if ($name ne '') { if ($email ne '') { print "名前:$name$letterimg\n"; } else { print "名前:$name\n"; } if (($homepage eq '') || ($homepage eq 'http://')) { print "\n"; } else { print " ホームページ$browserimg\n"; } } else { if ($email ne '') { print "名前:歴史資料館諜報部員$letterimg\n"; } else { print "名前:歴史資料館諜報部員\n"; } if (($homepage eq '') || ($homepage eq 'http://')) { print "\n"; } else { print " ホームページ$browserimg\n"; } } print " \n$date\n\n"; if ($subject ne '') { print "
題名:$subject"; } print "

\n"; print "

\n$value\n

\n
\n
\n"; } print "

\n"; $page_next = $page_end + 1; $i = $page + 1; $j = $page_end + 1; $p_now = $i + $def; if ($j + $def < $taccesses) {$p_next = $j + $def;} else {$p_next = $taccesses;} if ($page_end ne $accesses) { print "
\n"; print "\n"; print "\n"; print ""; print "
\n"; } else { print "投稿数 $taccesses 件\n"; } print "
\n"; print "
\n"; print ""; print "管理者モードへ移行>パスワード:\n"; print "\n"; print "
\n"; print "
\n"; print "RETURN

\n"; &count; print "

\n"; print "This board service has presented by MiniBBS
"; print "Powered by ProxyCheckerz v8.3
"; print "E-Mail: history\@scenecritique.com


"; print "
\n"; print "\n\n"; if (-e $lockfile) { unlink($lockfile); } exit; }#html end sub regist { if (($FORM{'value'} eq '')||($FORM{'value'} eq ' ')||($FORM{'value'} eq ' ')) { &html;} #内容が無い場合はリロード if (($kyoka eq "") && ( $proxy eq '1')){ &proxy;} elsif((!($host=~ /$kyoka/)) && ( $proxy eq '1')){ &proxy;} # 別のページからこのCGIへの投稿を排除する $ref = $ENV{'HTTP_REFERER'}; $ref_url = $reload; $ref_url =~ s/\~/.*/g; if (!($ref =~ /$ref_url/i)) { &error('form'); } if ($FORM{'checkcode'} eq '') { &error('x'); } $decheckcode= $FORM{'checkcode'}; $i = 0; $decheckcode=~ s/[\da-f]{2}/sprintf("%c",hex($&)^ord($key[$i++ % @key]))/ige; $dukecheck = $decheckcode / $num; if (($dukecheck - 1000000000) < 101000000) { &error('x'); } if (($dukecheck - 1000000000) >= $date_num) { &errorz('チェックコードエラー','再度掲示板を読み込みなおしてください.'); } if (($date_num - ($dukecheck - 1000000000)) < 100) { &errorz('チェックコードエラー','最初に掲示板にアクセスしてから実際に投稿するまでの間隔は60秒以上あけて下さい。<BR>ブラウザの[戻る]ボタンを押して前の画面に戻り少し時間をおいて投稿ボタンを押しなおしてください。.'); } $str1 = substr( "$dukecheck" , 0, 2); $str2 = substr( "$dukecheck" , 2, 2); $str3 = substr( "$dukecheck" , 4, 2); $str4 = substr( "$dukecheck" , 6, 2); if(($str1 - 10) > 12 ) { &error('x'); } if($str2 > 31 ) { &error('x'); } if($str3 > 59 ) { &error('x'); } if($str4 > 59 ) { &error('x'); } if ($FORM{'spwd'} =~ /\W/ || length($FORM{'spwd'}) > 9) { &errorz('入力ミス','削除パスワード欄は8文字以内の半角英数字で記入してください.<br>これは記事の削除時に利用するものです.'); } if ($FORM{'name'} =~ /歴史家|Captain/i) { $FORM{'name'} = '社会的に禁止された名前です'; } if ($FORM{'name'} =~ /しぱ/) { $FORM{'name'} = 'しは゜'; } if ($FORM{'name'} =~ /半魚人|Kenkesei/i) { $FORM{'name'} = '○田○宗'; } if ($FORM{'name'} =~ /slimepower|スライム|すらいむ|slime/i) { $FORM{'name'} = 'デフコンゼロの翻訳パクッた厨房'; } if ($FORM{'name'} =~ /ぴかちゅう|誰ちゃん|正治|天使がわんわん/) { $FORM{'name'} = 'バナークリック野郎'; } if ($FORM{'name'} =~ /yasu|犬神/i) { $FORM{'name'} = '直リン掲示板荒らしたあほ'; } if ($FORM{'name'} =~ /KOBA|Yusuke|紀柳|霧崎|七瀬/i) { $FORM{'name'} = '成敗された傲慢ワレザー'; } if ($FORM{'name'} =~ /初心|素人|beginner/i) { $FORM{'name'} = 'カル厨'; } if ($FORM{'name'} =~ /Thor/i) { $FORM{'name'} = 'スーパーハカー荒木'; } if ($FORM{'name'} =~ /Red Apple/i) { $FORM{'name'} = 'デフコンゼロに宣伝した厨房'; } if ($FORM{'name'} =~ /御堂岡|mido/) { $FORM{'name'} = '不死身の荒らし御堂岡'; $FORM{'subject'} = 'ミラーは直リンと同じです'; } if ($FORM{'name'} =~ /CompJapan|野坂|坂本/) { $FORM{'name'} = 'シェアウェア詐欺師野坂豪'; } if ($FORM{'name'} =~ /しば/) { $FORM{'name'} = '<small>しば</small>'; $FORM{'subject'} = '俺はうんこ漏らした 笑い'; } if ($FORM{'email'} =~ /,/) { &errorz('メールアドレスがっ(^^;',"メールアドレスが複数指定されています."); } if ($FORM{'email'} ne "") { if (!($FORM{'email'} =~ /(.*)\@(.*)\.(.*)/)) { &errorz('メールアドレスがっ(^^;',"メールアドレスが正しく記入されていません."); }} $FORM{'name'} =~ s/<//g; $FORM{'name'} =~ s/>//g; $FORM{'subject'} =~ s/</&lt;/g; $FORM{'subject'} =~ s/>/&gt;/g; $FORM{'email'} =~ s/<//g; $FORM{'email'} =~ s/>//g; $FORM{'homepage'} =~ s/http:\/\/http:\/\//http:\/\//g; if ($gimei eq "1") { @adminword = split( /\s+/ , $admin ); foreach $admin ( @adminword ){ if ( $FORM{'name'} =~ /$admin/i ) { &error('5'); } } if (crypt($FORM{'name'}, substr($password,$salt,2)) eq $password) { $FORM{'name'}= $master; } } # 記事削除パスワードの処理 if (crypt($FORM{'spwd'}, substr($password,$salt,2)) eq $password) { $spwd = "Master"; } elsif ( $FORM{'spwd'} ) { $spwd = crypt( $FORM{'spwd'}, &mkSalt($FORM{'name'}.$FORM{'spwd'}) ); } else { $spwd = ''; } # 書き込み内容の容量チェック(by カール) if ($max_s) { $value_size = length($FORM{'subject'}); if ($value_size > $max_s) { &errorz('タイトル長すぎっ(^^;',"タイトルが最大記録サイズ$max_sを超えています. 現在$value_sizeサイズです."); } } if ($max_n) { $value_size = length($FORM{'name'}); if ($value_size > $max_n) { &errorz('名前が長すぎっ(^^;',"お名前が最大記録サイズ$max_nを超えています. 現在$value_sizeサイズです."); } } if ($max_e) { $value_size = length($FORM{'email'}); if ($value_size > $max_e) { &errorz('メールアドレスが長すぎっ(^^;',"メールアドレスが最大記録サイズ$max_eを超えています. 現在$value_sizeサイズです."); } } if ($max_v) { $value_size = length($FORM{'value'}); if ($value_size > $max_v) { &errorz('内容が長すぎっ(^^;',"書き込み内容が最大記録サイズ$max_vを超えています. 現在$value_sizeサイズです."); } } if ($max_url) { $value_size = length($FORM{'homepage'}); if ($value_size > $max_url) { &errorz('ホームページアドレスが長すぎっ(^^;',"書き込み内容が最大記録サイズ$max_vを超えています. 現在$value_sizeサイズです."); } } if ($max_line) { $value_size = ($FORM{'value'} =~ tr/\r/\r/) + 1; # \r の数を数える if ($value_size > $max_line) { &errorz('行数が多すぎっ(^^;',"書き込み内容の行数が最大行数$max_lineを超えています. 現在$value_sizeサイズです."); } } $for =~ s/,/./g; $via =~ s/,/./g; $agent =~ s/<//g; $agent =~ s/>//g; $agent =~ s/,/./g; if (!open(DB,"$file")) { &error('0'); } @lines = <DB>; close(DB); #ダブルポスト禁止機能(by アリス氏&カール) # 最大保持記録数の処理 $i = 0; foreach $line (@lines) { $i++; if ($i == $max) { last; } push(@new,$line); } $i = 0; while ( $i < $check ){ ($number0,$spwd0,$date0,$name0,$email0,$value0,$subject0,$link0,$host0,$addr0,$via0,$for0,$trueip0,$agent0,$how0,$checkcode0,$homepage0,$log_count0) = split(/\,/,$lines[$i]); if (substr($FORM{'value'},0,$checklength) eq substr($value0,0,$checklength)){ &errorz('旦那!二重投稿ですぜ'); } if ($decheckcode == $checkcode0){ &errorz('チェックコードエラー',"もう一度アクセスしなおして下さい。."); } if ( $ctimer eq '0') { if ($host eq $host0 && ($date_num > $number0) && ($date_num - $number0 < $timer)){ &errorz('少しお待ち下さい(^^;',"悪戯対策のため同一ホストからの$rtimer秒以内の連続投稿はできなくなっています."); } } if ( $ctimer eq '1') { if ($date_num > $number0 && ($date_num - $number0 < $timer)){ &errorz('少しお待ち下さい(^^;',"悪戯対策のため直前の投稿から$rtimer秒以内の連続投稿はできなくなっています."); } } $i++; } if (!open(DB,"$log_number")) { &error('0'); } $log_count = <DB>; close(DB); $log_count++; if (!open(DB,">$log_number")) { &error('0'); } print DB $log_count; close(DB); if ($hyouji eq '1') { #ページのソースにホスト&アドレスを表示するかどうか $value = "$date_num\,$spwd\,$date_now\,$FORM{'name'}<!--remote_host:$host--><!--remote_addr:$addr-->\,$FORM{'email'}\,$FORM{'value'}\,$FORM{'subject'}\,$FORM{'link'}\,$host\,$addr\,$via\,$for\,$trueip\,$agent\,$FORM{'how'}\,$decheckcode\,$FORM{'homepage'}\,$log_count\,$FORM{'no'}\n"; }else { $value = "$date_num\,$spwd\,$date_now\,$FORM{'name'}\,$FORM{'email'}\,$FORM{'value'}\,$FORM{'subject'}\,$FORM{'link'}\,$host\,$addr\,$via\,$for\,$trueip\,$agent\,$FORM{'how'}\,$decheckcode\,$FORM{'homepage'}\,$log_count\,$FORM{'no'}\n"; } unshift(@new,$value); if (!open(DB,">$file")) { &error('0'); } print DB @new; close(DB); # 記録処理後、再読み込みする print "Location: $reload" . '?' . "\n\n"; if (-e $lockfile) { unlink($lockfile); } #ロック解除 exit; } sub error { # &error(xx); で呼び出されたルーチンは、()内の数字が $error に代入される。 $error = $_[0]; if ($error eq "0") { $error_msg = '記録ファイルの入出力にエラーが発生しました。<BR><BR>設置ファイルの名称、パーミッションを再確認して下さい。'; } elsif ($error eq "5") { $error_msg = &jump; } elsif ($error eq "tag") { $error_msg = '利用ができないタグが記述されていますので投稿できません。'; } elsif ($error eq "form") { $error_msg = "投稿画面のURLが<br>$reload<br>" . '以外からの投稿はできません。'; } elsif ($error eq "kusi") { $error_msg = '<FONT SIZE=+2>現在プロクシ制限中です!</FONT><br><br>プロクシ経由は許可されていません.<BR>掲示板管理者にメール等で該当ホストの許可設定を申\し出てください'; } elsif ($error eq "x") { $error_msg = '不正利用の可能性があります。'; } print "Content-type: text/html\n\n"; print "<html><head><title>$title</title></head>\n"; print "$body\n"; print "<h3>$error_msg</h3>\n"; print "</body>\n</html>\n<noembed>"; if ($_[0] ne 'Busy') { # 2重起動に引っかかった時はLOCKファイルを削除しないようにする if (-e $lockfile) { unlink($lockfile); } } exit; } sub errorz { print "Content-type: text/html\n\n"; print "<html><head><title>$title</title></head>\n"; print "$body\n"; print "<h1>$_[0]</h1>\n"; print "<h3>$_[1]</h3>\n"; print "ブラウザの[戻る]ボタンを押して前の画面に移動してください.<p>\n"; print "</body>\n</html>\n<noembed>"; if ($_[0] ne 'Busy') { # 2重起動に引っかかった時はLOCKファイルを削除しないようにする if (-e $lockfile) { unlink($lockfile); } } exit; } sub remove1 { if (!open(DB,"$file")) { &error('0'); } @lines = <DB>; close(DB); print "Content-type: text/html\n\n"; print "<html><head><title>$title</title></head>\n"; print "$body\n"; print "<font size=+2><b>投稿記事一覧モード(記事削除もできます)</b></font> [<a href=$reload>戻る</a>]<p>\n"; print "<form method=$method action=$reload>\n"; print "<input type=hidden name=action value=remove>\n"; print "<pre>"; print " 登録日 投稿者 認識ID タイトル 内容             アクセスデータ(REMOTE_HOST - REMOTE_ADDR - HTTP_VIA - HTTP_FORWARDED - TrueIP - USER_AGENT)<hr>\n"; foreach $line (@lines) { ($number,$spwd,$date,$name,$email,$value,$subject,$link,$host,$addr,$via,$for,$trueip,$agent,$how,$checkcode,$homepage,$log_count) = split(/\,/,$line); $value =~ s/\0/\,/g; chop($subject) if $subject =~ /\n/; $name =~ s/<!--.*-->//ig; $name =~ s/</&lt;/ig; $name =~ s/>/&gt;/ig; $value =~ s/\n/./g; $name =~ s/\r/./g; $value =~ s/<br>\r/./g; $value =~ s/\r/./g; $value =~ s/</&lt;/ig; $value =~ s/>/&gt;/ig; $i1 = length($subject); if ($i1 > 18) { $subject = substr($subject,0,16); $subject = $subject . '..'; } elsif ($i1 < 18) { $blank = ' ' x (18 - $i1); $subject = $subject . $blank; } $i2 = length($spwd); if ($i2 > 7) { $spwd = substr($spwd,2,11); $spwd = $spwd . ' '; } elsif ($i2 < 7) { $blank = ' ' x 7; $spwd = $spwd . $blank; } $i3 = length($name); if ($i3 > 14) { $name = substr($name,0,12); $name = $name . '..'; } elsif ($i3 < 14) { $blank = ' ' x (14 - $i3); $name = $name . $blank; } $i4 = length($value); if ($i4 > 30) { $value = substr($value,0,28); $value = $value . '..'; } elsif ($i4 < 30) { $blank = ' ' x (30 - $i4); $value = $value . $blank; } print "<input type=checkbox name=target value=\"$date\">"; $i5 = length($date); if ($i5 > 18) { $date = substr($date,0,16); $date = $date . '..'; } elsif ($i5 < 18) { $blank = ' ' x (18 - $i5); $date = $date . $blank; } print "$date $name $spwd $subject $value $host-$addr-$via-$for-$trueip-$agent\n"; } print "</pre><p><input type=hidden name=pwd value=$FORM{'pwd'}>\n"; print "<input type=submit value=\" remove \"><input type=reset value=\" reset \"></form><p>\n"; print "</body>\n</html>\n<noembed>"; } sub sremove { if (!open(DB,"$file")) { &error('0'); } @lines = <DB>; close(DB); foreach $line (@lines) { $del = 0; ($number,$spwd,$date,$name,$email,$value,$subject,$link,$host,$addr,$via,$for,$trueip,$agent,$how,$checkcode,$homepage,$log_count) = split(/\,/,$line); if ($spwd && ((crypt($FORM{'spwd'}, substr($password,$salt,2)) eq $password) || (crypt($FORM{'spwd'}, $spwd ) eq $spwd ))){ foreach $target (@RM) { if ($target eq $number) { $del = 1; } } } if ($del == 0) { push(@new,$line); } } if (!open(DB,">$file")) { &error('0'); } print DB @new; close(DB); @lines = @new; } sub remove2 { if (!open(DB,"$file")) { &error('0'); } @lines = <DB>; close(DB); foreach $line (@lines) { ($number,$spwd,$date,$name,$email,$value,$subject,$link,$host,$addr,$via,$for,$trueip,$agent,$how,$checkcode,$homepage,$log_count) = split(/\,/,$line); $del = 0; foreach $target (@RM) { if ($target eq $date) { $del = 1; } } if ($del == 0) { push(@new,$line); } } if (!open(DB,">$file")) { &error('0'); } print DB @new; close(DB); } sub password { print "Content-type: text/html\n\n"; print "<html><head><title>$title</title></head>\n"; print "$body\n"; print "<h1>管理パスワードの設定/変更</h1>\n"; if ($first && $message eq '') { print "記事を削除するための管理パスワードを登録します。<p>\n"; } else { print "$message<p>\n"; } print "<form method=$method action=$reload>\n"; print "<input type=hidden name=action value=password>\n"; if ($first != 1) { print "旧パスワード <input type=password name=password_old size=10><br>\n"; } print "新パスワード <input type=password name=password size=10><br>\n"; print "新パスワード <input type=password name=password2 size=10>(確認のためもう一度)<p>\n"; print "<input type=submit value=\" 登録 \"></form><p>\n"; print "</body>\n</html>\n<noembed>"; if (-e $lockfile) { unlink($lockfile); } exit; } sub encode { if ($header eq 'crypt_password') { if (crypt($FORM{'password_old'}, substr($password,$salt,2)) ne $password) { $message = '旧パスワードが認証されませんでした.'; &password; } } else { if (!open(DB,"$pass")) { &error('0'); } @lines = <DB>; close(DB); $first = 1; } if ($FORM{'password'} =~ /\W/ || $FORM{'password'} eq '') { $message = '新パスワードに英数字以外の文字が含まれているか空欄です.'; &password; } if ($FORM{'password'} ne $FORM{'password2'}) { $message = '確認のために入力された新パスワードが一致しません.'; &password; } $now = time; ($p1, $p2) = unpack("C2", $now); $wk = $now / (60*60*24*7) + $p1 + $p2 - 8; @saltset = ('a'..'z','A'..'Z','0'..'9','.','/'); $nsalt = $saltset[$wk % 64] . $saltset[$now % 64]; $pwd = crypt($FORM{'password'}, $nsalt); if (!open(DB,">$pass")) { &error('0'); } print DB "crypt_password:$pwd\n"; print DB @lines; close(DB); &html; } sub mkSalt { local($t, $sum, @salt ) = @_; @salt = split(//,'./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'); if ( $t ) { $sum = unpack("%12C*", $t); } else { return 'No'; } # ハンドルが空の場合 $salt[$sum % 64] . $salt[int($sum/64) % 64]; } #proxyの排除(by カール、dimdim氏、ひみこ氏) sub proxy { if ($plevel eq "1") { if(!($xfor =~s/^(\d+)\.(\d+)\.(\d+)\.(\d+)(\D*).*/$1.$2.$3.$4/ )){# IP漏れしている場合は許可 if($host =~ /squid|^firewall|proxy|cache|delegate|^dns|keeper|^mail|^www|^ns\d{0,2}\.|edu$|com$|org$|net$/i){ &error('kusi'); } if($via ne ""){ &error('kusi'); } if($xfor ne ""){ &error('kusi'); } if($for ne ""){ &error('kusi'); } if($agent=~ /via|squid|delegate|httpd|proxy|cache/i){ &error('kusi'); } } } else { if($host =~ /squid|^firewall|proxy|cache|delegate|^dns|keeper|^mail|^www|^ns\d{0,2}\.|us$|uk$|au$|fi$|ca$|de$|kr$|tw$|it$|edu$|com$|org$|net$/i){ &error('kusi'); } if($via ne ""){ &error('kusi'); } if($xfor ne ""){ &error('kusi'); } if($for ne ""){ &error('kusi'); } if($agent=~ /via|squid|delegate|httpd|proxy|cache/i){ &error('kusi'); } $CONNECTION = $ENV{'HTTP_PROXY_CONNECTION'}; if($CONNECTION ne ""){ &error('kusi'); } $INFO = $ENV{'HTTP_CACHE_INFO'}; if($INFO ne ""){ &error('kusi'); } } } sub hostcheck{ if (!open(DB,"$hostlist")) { &error('0'); } @lines = <DB>; close(DB); foreach $line (@lines) { next if(length($line)<4); chop $line; if( $host=~ /$line/ ){&jump;} } }#hostcheck END sub kickhost{ $hostdate = $FORM{'hostdate'}; print "Content-type: text/html\n\n"; print <<"_HTML_"; <HTML><HEAD><TITLE>拒否ホスト登録モード</TITLE></HEAD> <BODY BGCOLOR="snow"> <CENTER><BR><b><FONT size=5>拒否ホスト登録モード</FONT></b> <FONT SIZE=-1>※元ソ\ースは<A HREF="http://www.cup.com/yui/">YUI</A>さん</FONT></CENTER><BR><BR> 完全なホスト名(例:nsi0123.ppp.3web.ne.jp)またはホスト名の一部(例:3web.ne.jp、dti.ne.jp、go.jp)いずれでも拒否登録できます。(ホスト名の一部を登録した場合、その名前を含むすべてのホストを拒否します)<BR>登録には4文字以上必要ですので、jp、comだけでは登録できません。<BR><BR> ※設置サーバーの種類よってはドメイン名ではキックできない場合があります。(infoweb等)<BR> キックできない時はIPアドレス(例:202.235.202.57)で設定して下さい。<BR><BR> <form method=$method action="$reload"><input type=hidden name="action" value="kickout"> <input type=hidden name="pwd" value="$FORM{'pwd'}"> ホスト名:<input type=text name="hostdate" size="30"> <input type=submit value="登録"></FORM><BR> <FONT Color=red>※登録ファイルを初期化するには、ホスト名の欄に『clear』(英小文字のみ)と入力してください。</FONT> <FONT SIZE=+1>[<a href="$reload">戻る</a>]</FONT><BR><BR><HR> _HTML_ if($hostdate ne ""){ if($hostdate ne 'clear'){ if (!open(DB,">>$hostlist")) { &error('0'); } print DB "$hostdate\n"; close(DB); print "$hostdateを追加しました。<BR>"; }else{ if (!open(DB,">$hostlist")) { &error('0'); } close(DB); print "アクセス制限ファイルを初期化しました。<BR>"; } } if (!open(DB,"$hostlist")) { &error('0'); } @lines = <DB>; close(DB); $num=@lines; print "下記が現在アクセス制限がかけられているホストです。登録数:$num<br>"; foreach $line (@lines) { print "$line<br>"; } print <<"_HTML_"; <HR> <H5 align=right>あーめん(^^)/~.</H5> </BODY> </HTML> <NOEMBED> _HTML_ if (-e $lockfile) { unlink($lockfile); } exit; }#kickhost end # アクセス者のアクセスデータを取得する(これはアクセスログで参照できる byカール) sub acount { $href = $ENV{'HTTP_REFERER'}; if ($href =~ /kharakhorum|silkroad|file|bookmarks|unknown/i) { $href=''; } if ($href ne ''){ $href =~ s/</&lt;/g; $href =~ s/>/&gt;/g; $href =~ s/#.*//g; open(LOG,"$access_log"); @lines=<LOG>; close(LOG); $axs=@lines; $rescue2 = ($rescue - 2); if ($axs >= $rescue) { open(LOG,">$access_log"); print LOG "$href\n"; foreach $axs (0..$rescue2) { print LOG $lines[$axs]; } } else { open(LOG,">$access_log"); print LOG "$href\n"; foreach $log (@lines) { print LOG $log; } } close(LOG); } } sub getip{ $trueip=$ENV{'HTTP_SP_HOST'} if( $ENV{'HTTP_SP_HOST'} ne ""); $trueip=$via if( $via=~s/.*\s(\d+)\.(\d+)\.(\d+)\.(\d+)/$1.$2.$3.$4/ ); $trueip=$ENV{'HTTP_CLIENT_IP'} if( $ENV{'HTTP_CLIENT_IP'} ne ""); $trueip=$for if( $for=~s/.*\s(\d+)\.(\d+)\.(\d+)\.(\d+)/$1.$2.$3.$4/ ); $trueip=$xfor if( $xfor=~s/^(\d+)\.(\d+)\.(\d+)\.(\d+)(\D*).*/$1.$2.$3.$4/ ); $trueip=$ENV{'HTTP_FROM'} if( $ENV{'HTTP_FROM'} ne ""); return $trueip; }#getip END sub count { if (!open(IN,"counter1.dat")) { &error('0'); } $count1 = <IN>; close(IN); if (!open(IN,"counter2.dat")){&error('0');} $count2 = <IN>; close(IN); if ($count1 > $count2){$maxcount = $count1;$i = '2';} else {$maxcount = $count2;$i = '1';} $maxcount++; if (!open(OUT,">counter$i.dat")){&error('0');} flock(OUT,2); print OUT $maxcount; flock(OUT,8); close(OUT); @counter = split(//,$maxcount); foreach $key (@counter){print "<IMG SRC=count/$key.gif ALT=$key WIDTH=5 HEIGHT=7 BORDER=0>";} } sub lock { local($retry) = 3; while (!symlink(".", $lockfile)) { if (--$retry <= 0) { &errorz('Busy','ただ今混雑しております.<br>数秒をおいて再度実行してください.'); } sleep(2); } } sub lock2 { $c = 0; while(-f "$lockfile") { $c++; if ($c >= 3) { &errorz('Busy','ただ今混雑しております.<br>数秒をおいて再度実行してください.'); } sleep(2); } open(LOCK,">$lockfile"); close(LOCK); } sub jump { print "Content-type: text/html\n"; print "Location: $jumpurl\n\n"; if (-e $lockfile) { unlink($lockfile); } exit; } #end_of_script