diff --git a/test/admin.cgi b/test/admin.cgi
index 728d85c..13149f4 100755
--- a/test/admin.cgi
+++ b/test/admin.cgi
@@ -13,7 +13,8 @@ use open IO => ':encoding(cp932)';
use warnings;
no warnings 'once';
use CGI::Carp qw(fatalsToBrowser warningsToBrowser);
-
+use JSON;
+use LWP::UserAgent;
# CGIの実行結果を終了コードとする
exit(AdminCGI());
@@ -29,6 +30,11 @@ exit(AdminCGI());
sub AdminCGI
{
require './module/constant.pl';
+
+ # IP
+ $ENV{'REMOTE_ADDR'} = $ENV{'HTTP_CF_CONNECTING_IP'} if $ENV{'HTTP_CF_CONNECTING_IP'};
+ require './module/data_utils.pl';
+ $ENV{'REMOTE_HOST'} = DATA_UTILS::reverse_lookup($ENV{'REMOTE_ADDR'});
# システム初期設定
my $CGI = {};
@@ -58,9 +64,15 @@ sub AdminCGI
my $sid = $Form->Get('SessionID', '');
$Form->Set('PassWord', '');
#$Form->Set('SessionID', '');
+ my $capt = Certification_Captcha($Sys,$Form) if ($pass && $Sys->Get('ADMINCAP'));
my ($userID, $SID) = $CGI->{'SECINFO'}->IsLogin($name, $pass, $sid);
- $CGI->{'USER'} = $userID;
- $Form->Set('SessionID', $SID);
+ unless($capt){
+ $CGI->{'USER'} = $userID;
+ $Form->Set('SessionID', $SID);
+ if ($CGI->{'SECINFO'}->IsAuthority($userID,$ZP::AUTH_SYSADMIN,'*')){
+ $Sys->Set('LASTMOD',time);
+ }
+ }
# バージョンチェック
my $upcheck = $Sys->Get('UPCHECK', 1) - 0;
@@ -95,6 +107,58 @@ sub AdminCGI
return 0;
}
+#------------------------------------------------------------------------------------------------------------
+#
+# Captcha検証
+# -------------------------------------------------------------------------------------
+#
+#------------------------------------------------------------------------------------------------------------
+sub Certification_Captcha {
+ my ($Sys,$Form) = @_;
+ my ($captcha_response,$url);
+
+ my $captcha_kind = $Sys->Get('CAPTCHA');
+ my $secretkey = $Sys->Get('CAPTCHA_SECRETKEY');
+ if($captcha_kind eq 'h-captcha'){
+ $captcha_response = $Form->Get('h-captcha-response');
+ $url = 'https://api.hcaptcha.com/siteverify';
+ }elsif($captcha_kind eq 'g-recaptcha'){
+ $captcha_response = $Form->Get('g-recaptcha-response');
+ $url = 'https://www.google.com/recaptcha/api/siteverify';
+ }elsif($captcha_kind eq 'cf-turnstile'){
+ $captcha_response = $Form->Get('cf-turnstile-response');
+ $url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
+ }else{
+ return 0;
+ }
+
+ my $ua = LWP::UserAgent->new();
+ my $response = $ua->post($url,{
+ secret => $secretkey,
+ response => $captcha_response,
+ remoteip => $ENV{'REMOTE_ADDR'},
+ });
+
+ if ($response->is_success()) {
+ my $json_text = $response->decoded_content();
+ my $out = decode_json($json_text);
+
+ if ($out->{success} eq 'true') {
+ return 0;
+ }elsif ($out->{error_codes} =~ /(missing-input-secret|invalid-input-secret|sitekey-secret-mismatch)/){
+ # 管理者側の設定ミス
+ return 0;
+ }else{
+ return 1;
+ }
+ } else {
+ # Captchaを素通りする場合、HTTPS関連のエラーの疑いあり
+ # LWP::Protocol::httpsおよびNet::SSLeayが入っているか確認
+ # このエラーの場合、スルーしてログインする
+ return 0;
+ }
+}
+
#------------------------------------------------------------------------------------------------------------
#
# 管理システム設定
diff --git a/test/admin/admin_cgi_base.pl b/test/admin/admin_cgi_base.pl
index 9388e8c..967c315 100644
--- a/test/admin/admin_cgi_base.pl
+++ b/test/admin/admin_cgi_base.pl
@@ -177,6 +177,12 @@ sub PrintCSS
my ($data);
$data = $Sys->Get('DATA');
+
+ if($Sys->Get('ADMINCAP')){
+ $Page->Print('') if ($Sys->Get('CAPTCHA') eq 'h-captcha');
+ $Page->Print('') if ($Sys->Get('CAPTCHA') eq 'g-recaptcha');
+ $Page->Print('') if ($Sys->Get('CAPTCHA') eq 'cf-turnstile');
+ }
$Page->Print(<
diff --git a/test/admin/bbs.setting.pl b/test/admin/bbs.setting.pl
index a234036..61f0caa 100644
--- a/test/admin/bbs.setting.pl
+++ b/test/admin/bbs.setting.pl
@@ -333,7 +333,7 @@ sub PrintBaseSetting
$Page->Print("
");
$Page->Print("DAT落ちスレッド保存先 ");
$Page->Print("");
- $Page->Print("プール(外部からのアクセス不可)");
+ $Page->Print(" プール(外部からのアクセス不可) ");
foreach my $listid (@bbsSet) {
next if ($BBS->Get('DIR', $listid) eq $Sys->Get('BBS'));
$category = $Category->Get('NAME', $BBS->Get('CATEGORY', $listid));
@@ -618,9 +618,9 @@ sub PrintLimitSetting
$Page->Print(" ");
$Page->Print("掲示板書き込み制限 ");
- $Page->Print("読取専用");
- $Page->Print(" キャップのみ可能");
- $Page->Print(" 書き込み可能");
+ $Page->Print(" 読取専用 ");
+ $Page->Print("キャップのみ可能 ");
+ $Page->Print("書き込み可能 ");
$Page->Print(" ");
$Page->Print("DNSBLチェック ");
$Page->Print(" $setInfo ");
@@ -635,11 +635,11 @@ sub PrintLimitSetting
$Page->Print("同一スレッド名を禁止 ");
$Page->Print(" 有効 ");
$Page->Print("逆引き不可のIPからの投稿を制限 ");
- $Page->Print(" ");
+ $Page->Print(" 有効");
$Page->Print("プロキシ規制 ");
$Page->Print(" $setInfo2 ");
$Page->Print("??? ");
- $Page->Print(" ");
+ $Page->Print(" 有効");
$Page->Print("");
$Page->Print(" ");
@@ -768,7 +768,7 @@ sub PrintCommandSetting
$Page->Print("不落(!nopool) ");
$Page->Print(" 有効 ");
$Page->Print("");
- $Page->Print("忍法帖レベル制限 ※要忍法帖(!ninLv:[レベル]) ");
+ $Page->Print(" 忍法帖レベル制限 ※要忍法帖(!ninlv:[レベル]) ");
$Page->Print(" 有効 ");
$Page->Print(" ");
@@ -919,7 +919,6 @@ sub PrintOtherSetting
my $setConfirm = $Setting->Get('BBS_NEWSUBJECT');
my $setWeek = $Setting->Get('BBS_YMD_WEEKS');
my $setTripColumn = $Setting->Get('BBS_TRIPCOLUMN');
- my $setImgur = $Setting->Get('BBS_IMGUR');
my $setTwitter = $Setting->Get('BBS_TWITTER');
my $setMovie = $Setting->Get('BBS_MOVIE');
my $setURLtoTitle = $Setting->Get('BBS_URL_TITLE');
@@ -986,14 +985,11 @@ sub PrintOtherSetting
$Page->Print("スレッド作成確認画面 ");
$Page->Print(" 確認あり ");
- $Page->Print("");
+ $Page->Print(" ");
$Page->Print(" ");
$Page->Print("一般画像埋め込み表示 ");
$Page->Print(" システム設定に依存 ");
$Page->Print("");
- $Page->Print("Imgur 埋め込み表示 ");
- $Page->Print(" 有効 ");
- $Page->Print("");
$Page->Print("X(旧Twitter) 埋め込み表示 ");
$Page->Print(" 有効 ");
$Page->Print("");
@@ -1426,7 +1422,6 @@ sub FunctionOtherSetting
$Setting->Set('BBS_SLIP', $Form->Get('BBS_SLIP'));
$Setting->Set('BBS_NINJA', ($Form->Equal('BBS_NINJA', 'on') ? 'checked' : ''));
$Setting->Set('BBS_HIDENUSI', ($Form->Equal('BBS_HIDENUSI', 'on') ? 'checked' : ''));
- $Setting->Set('BBS_IMGUR', ($Form->Equal('BBS_IMGUR', 'on') ? 'checked' : ''));
$Setting->Set('BBS_MOVIE', ($Form->Equal('BBS_MOVIE', 'on') ? 'checked' : ''));
$Setting->Set('BBS_TWITTER', ($Form->Equal('BBS_TWITTER', 'on') ? 'checked' : ''));
$Setting->Set('BBS_URL_TITLE', ($Form->Equal('BBS_URL_TITLE', 'on') ? 'checked' : ''));
diff --git a/test/admin/bbs.thread.pl b/test/admin/bbs.thread.pl
index e303ad8..25f4977 100644
--- a/test/admin/bbs.thread.pl
+++ b/test/admin/bbs.thread.pl
@@ -368,13 +368,13 @@ sub PrintThreadList
if ($isStop) {
$Page->Print("属性: ");
- $Page->Print("浮上");
- $Page->Print(" 不落");
- $Page->Print(" sage進行");
- $Page->Print(" ID無し");
- $Page->Print(" ID変更");
- $Page->Print(" 名無し強制");
- $Page->Print(" 実況モード");
+ $Page->Print(" 浮上 ");
+ $Page->Print("不落 ");
+ $Page->Print("sage進行 ");
+ $Page->Print("ID無し ");
+ $Page->Print("ID変更 ");
+ $Page->Print("名無し強制 ");
+ $Page->Print("実況モード ");
$Page->Print(" ");
$Page->Print(" ");
$Page->Print(" ");
@@ -463,9 +463,10 @@ sub PrintThreadCopy
$Page->Print("$text\先: ");
if(@bbsSet <= 1){
- $Page->Print("選択可能な掲示板がありません");
+ $Page->Print(" 選択可能な掲示板がありません ");
+ $Page->Print(" ");
}else{
- $Page->Print("選択してください");
+ $Page->Print(" 選択してください ");
foreach my $listid (@bbsSet) {
next if ($BBS->Get('DIR', $listid) eq $SYS->Get('BBS'));
$category = $Category->Get('NAME', $BBS->Get('CATEGORY', $listid));
@@ -473,14 +474,14 @@ sub PrintThreadCopy
foreach $belongID (@belongBBS) {
if ($listid eq $belongID) {
$name = $BBS->Get('NAME', $listid);
- $Page->Print("$name");
+ $Page->Print(" $name ");
}
}
}
+ $Page->Print(" ");
+ $Page->Print(" 同名のファイルがあればリネーム");
+ $Page->Print(' ");
}
- $Page->Print(" ");
- $Page->Print(" 同名のファイルがあればリネーム");
- $Page->Print(' ");
$Page->Print(" \n");
$Page->Print(" ");
}
@@ -864,9 +865,6 @@ sub FunctionThreadCopy
$Threads->Load($Sys);
$Info->Load($Sys);
-
- @threadList = $Form->GetAtArray('THREADS');
- return 1 if (!@threadList);
$tobbs = $Form->Get('TOBBS');
$rename = $Form->Get('RENAME');
@@ -875,6 +873,9 @@ sub FunctionThreadCopy
$path = $Sys->Get('BBSPATH') . "/$bbs";
$topath = $Sys->Get('BBSPATH') . "/".$Info->Get('DIR',$tobbs);
+ @threadList = $Form->GetAtArray('THREADS');
+ return 1 if (!@threadList || !$tobbs);
+
my $text = $mode ? 'コピー':'移動';
foreach $id (@threadList) {
diff --git a/test/admin/login.pl b/test/admin/login.pl
index 158fad9..b13631f 100644
--- a/test/admin/login.pl
+++ b/test/admin/login.pl
@@ -55,7 +55,7 @@ sub DoPrint
$Page = $BASE->Create($Sys, $Form);
- PrintLogin($Page, $Form);
+ PrintLogin($Sys, $Page, $Form);
$BASE->PrintNoList('LOGIN', 0);
}
@@ -75,10 +75,6 @@ sub DoFunction
my $this = shift;
my ($Sys, $Form, $pSys) = @_;
my ($host, $Security, $Mod);
- $ENV{'REMOTE_ADDR'} = $ENV{'HTTP_CF_CONNECTING_IP'} if $ENV{'HTTP_CF_CONNECTING_IP'};
-
- require './module/data_utils.pl';
- $host = DATA_UTILS::reverse_lookup($ENV{'REMOTE_ADDR'});
# ログイン情報を確認
if ($pSys->{'USER'}) {
@@ -107,7 +103,12 @@ sub DoFunction
#------------------------------------------------------------------------------------------------------------
sub PrintLogin
{
- my ($Page, $Form) = @_;
+ my ($Sys, $Page, $Form) = @_;
+
+ my $sitekey = $Sys->Get('CAPTCHA_SITEKEY');
+ my $classname = $Sys->Get('CAPTCHA');
+ my $Captcha = $Sys->Get('ADMINCAP') ? "
" : '';
+ my $text = $sitekey && $classname && $Captcha ? 'Captcha認証に失敗したか、' : "" ;
$Page->Print(<
@@ -115,7 +116,7 @@ sub PrintLogin
HTML
if ($Form->Get('FALSE') == 1) {
- $Page->Print(" ユーザ名もしくはパスワードが間違っています。
\n");
+ $Page->Print(" ${text}ユーザ名もしくはパスワードが間違っています。
\n");
}
$Page->Print(<
+ $Captcha
diff --git a/test/admin/sys.ninja.pl b/test/admin/sys.ninja.pl
index 6a5d279..40915cf 100644
--- a/test/admin/sys.ninja.pl
+++ b/test/admin/sys.ninja.pl
@@ -72,6 +72,9 @@ sub DoPrint
elsif ($subMode eq 'SEARCH') { # 忍法帖検索
PrintNinjaSearch($Page, $Sys, $Form);
}
+ elsif ($subMode eq 'NIN_SEARCH') { # 忍法帖検索
+ PrintNinjaSearchResult($Page, $Sys, $Form);
+ }
elsif ($subMode eq 'SID_SEARCH') { # セッションID検索
PrintNinjaSidSearch($Page, $Sys, $Form);
}
@@ -336,58 +339,58 @@ sub PrintNinjaEdit
$Page->Print("ID:$sid\の忍法帖を確認します。(${SESSION_ATIME}時点) ");
$Page->Print(" \n");
- $Page->Print("■User Description \n");
- $Page->Print("説明 ");
+ $Page->Print("■User Description (Key) \n");
+ $Page->Print("説明 (user_desc) ");
$Page->Print(" \n");
- $Page->Print("■User Information \n");
- $Page->Print("忍法帖ID $ninID \n");
- $Page->Print("忍法帖Lv $lv \n");
- $Page->Print("前回LvUP日時 $lvuptime \n");
- $Page->Print("作成日時 $SESSION_CTIME \n");
- $Page->Print("作成時の書き込み $newmes \n");
- $Page->Print("作成時のIP $c_addr \n");
- $Page->Print("作成時のHOST $c_host \n");
- $Page->Print("作成時のUA $c_ua \n");
- $Page->Print("ユーザー認証 $is_auth \n");
- $Page->Print("最終認証日時 $auth_time \n");
- $Page->Print("最終スレ立て日時 $last_makethread_time \n");
- $Page->Print("最新書き込み日時 $last_wtime \n");
- $Page->Print("最新書き込み $last_message \n");
- $Page->Print("最新IP $last_addr \n");
- $Page->Print("最新HOST $last_host \n");
- $Page->Print("最新UA $last_ua \n");
- $Page->Print("パスワード(Hash) $password \n");
- $Page->Print("最新ロード時刻 $load_time \n");
- $Page->Print("ロード元の忍法帖ID $load_from \n");
- $Page->Print("ロード時の書き込み $load_message \n");
- $Page->Print("最新ロードIP $load_addr \n");
- $Page->Print("最新ロードHOST $load_host \n");
- $Page->Print("最新ロードUA $load_ua \n");
-
- $Page->Print("■Statistics \n");
- $Page->Print("書き込み数 $count \n");
- $Page->Print("スレ立て数 $thread_count \n");
- $Page->Print("忍法帖ロード回数 $load_count \n");
-
- $Page->Print("■Regulation \n");
- $Page->Print("書き込み禁止 ");
+ $Page->Print("■User Information (Key) \n");
+ $Page->Print("忍法帖ID (ninID) $ninID \n");
+ $Page->Print("忍法帖Lv (ninLv) $lv \n");
+ $Page->Print("前回LvUP日時 (lvuptime) $lvuptime \n");
+ $Page->Print("作成日時 (_SESSION_CTIME) $SESSION_CTIME \n");
+ $Page->Print("作成時の書き込み (new_message) $newmes \n");
+ $Page->Print("作成時のIP (c_addr) $c_addr \n");
+ $Page->Print("作成時のHOST (c_host) $c_host \n");
+ $Page->Print("作成時のUA (c_ua) $c_ua \n");
+ $Page->Print("ユーザー認証 (auth) $is_auth \n");
+ $Page->Print("最終認証日時 (auth_time) $auth_time \n");
+ $Page->Print("最終スレ立て日時 (last_mthread_time) $last_makethread_time \n");
+ $Page->Print("最新書き込み日時 (last_wtime) $last_wtime \n");
+ $Page->Print("最新書き込み (last_message) $last_message \n");
+ $Page->Print("最新IP (last_addr) $last_addr \n");
+ $Page->Print("最新HOST (last_host) $last_host \n");
+ $Page->Print("最新UA (last_ua) $last_ua \n");
+ $Page->Print("パスワードのハッシュ (password) $password \n");
+ $Page->Print("最新ロード時刻 (load_time) $load_time \n");
+ $Page->Print("ロード元の忍法帖ID (load_from) $load_from \n");
+ $Page->Print("ロード時の書き込み (load_message) $load_message \n");
+ $Page->Print("最新ロードIP (load_addr) $load_addr \n");
+ $Page->Print("最新ロードHOST (load_host) $load_host \n");
+ $Page->Print("最新ロードUA (load_ua) $load_ua \n");
+
+ $Page->Print("■Statistics (Key) \n");
+ $Page->Print("書き込み数 (count) $count \n");
+ $Page->Print("スレ立て数 (thread_count) $thread_count \n");
+ $Page->Print("忍法帖ロード回数 (load_count) $load_count \n");
+
+ $Page->Print("■Regulation (Key) \n");
+ $Page->Print("書き込み禁止 (ban) ");
$Page->Print("");
$Page->Print("無効 ");
$Page->Print("有効 ");
$Page->Print("スレッド作成のみ禁止 ");
$Page->Print(" \n");
- $Page->Print("コマンド禁止 ");
+ $Page->Print("コマンド禁止 (ban_command) ");
$Page->Print(" \n");
- $Page->Print("URL禁止 ");
+ $Page->Print("URL禁止 (ban_url) ");
$Page->Print(" \n");
- $Page->Print("強制sage ");
+ $Page->Print("強制sage (force_sage) ");
$Page->Print(" \n");
- $Page->Print("Captcha強制 ");
+ $Page->Print("Captcha強制 (force_captcha) ");
$Page->Print(" \n");
- $Page->Print("名無し強制 ");
+ $Page->Print("名無し強制 (force_774) ");
$Page->Print(" \n");
- $Page->Print("強制コテ(名無し強制優先、名前欄用コマンド使用可) ");
+ $Page->Print("強制コテ (force_kote)(名無し強制優先、名前欄用コマンド使用可) ");
$Page->Print(" \n");
}else{
$Page->Print("ID:$sid\の忍法帖データは存在しません。 ");
@@ -403,12 +406,19 @@ sub PrintNinjaEdit
$Page->Print(" ");
}
+
+#------------------------------------------------------------------------------------------------------------
+#
+# 忍法帖検索画面 - PrintNinjaSearch
+# ------------------------------------------------
+# 引 数:なし
+# 戻り値:なし
+#
+#------------------------------------------------------------------------------------------------------------
sub PrintNinjaSearch
{
my ($Page, $SYS, $Form, $BBS) = @_;
- my ($common);
- my ($name, $dir);
- my ($sMODE, $sBBS, $sKEY, $sWORD, @sTYPE, @cTYPE, $types, $BBSpath, @bbsSet, $id);
+ my ($sKEY, $sWORD);
my $sanitize = sub {
$_ = shift;
@@ -419,45 +429,29 @@ sub PrintNinjaSearch
return $_;
};
- $sMODE = "BBS";#&$sanitize($Form->Get('SMODE', ''));
- $sBBS = &$sanitize($Form->Get('SBBS', ''));
$sKEY = &$sanitize($Form->Get('KEY', ''));
$sWORD = &$sanitize($Form->Get('WORD'));
- @sTYPE = $Form->GetAtArray('TYPE', 0);
- $id = $Form->Get('TARGET_BBS', '');
- $types = ($sTYPE[0] || 0) | ($sTYPE[1] || 0) | ($sTYPE[2] || 0);
- $cTYPE[0] = ($types & 1 ? 'checked' : '');
- $cTYPE[1] = ($types & 2 ? 'checked' : '');
- $cTYPE[2] = ($types & 4 ? 'checked' : '');
$SYS->Set('_TITLE', 'Ninpocho Search');
$Page->Print("
@@ -477,13 +471,133 @@ sub PrintNinjaSearch
}
$Page->Print("");
}
+
+#------------------------------------------------------------------------------------------------------------
+#
+# 忍法帖検索結果出力 - PrintNinjaSearchResult
+# ------------------------------------------------
+# 引 数:なし
+# 戻り値:なし
+#
+#------------------------------------------------------------------------------------------------------------
+sub PrintNinjaSearchResult
+{
+ my ($Page, $Sys, $Form) = @_;
+ my ($Search, $Mode, $Result, @elem, $BBS, $n, $base, $word, $id, $key);
+ my (@types, $Type);
+ my (@resList, %bbsCount, %threadCount);
+
+ $Sys->Set('_TITLE','Ninpocho Search');
+
+ my $sanitize = sub {
+ $_ = shift;
+ s/&/&/g;
+ s/</g;
+ s/>/>/g;
+ s/"/"/g;#"
+ return $_;
+ };
+
+ require './module/admin_search.pl';
+ $Search = ADMIN_SEARCH->new;
+ require './module/bbs_info.pl';
+ $BBS = BBS_INFO->new;
+ $BBS->Load($Sys);
+ $word = &$sanitize($Form->Get('WORD'));
+ $key = &$sanitize($Form->Get('KEY'));
+
+
+ # 検索オブジェクトの設定と検索の実行
+ $Search->Create($Sys, 3);
+ $Page->Print("");
+ $Page->Print("Key:[$key] Word:[$word] の忍法帖検索結果 ");
+ if ($@ ne '') {
+ PrintSystemError($Page, $@);
+ return;
+ }
+
+ # 検索結果セット取得
+ if($key ne 'ninID' && $word){
+ $Result = $Search->NinSearch($Form->Get('KEY'),$Form->Get('WORD'),undef);
+ }elsif((!$key && $word =~ /[0-9a-f]{32}/) || ($key eq 'ninID' && length($word) == 13)){
+ $Result = $Search->NinSearch(undef,undef,$Form->Get('WORD'));
+ }
+
+ $n = $Result ? @$Result : 0;
+ my $res = $Result->[0];
+ # 検索ヒットが1件以上あり
+ if ($n > 0) {
+ my $dispNum = $Form->Get('DISPNUM', 10);
+ my $dispSt = $Form->Get('DISPST', 0) || 0;
+ $dispSt = ($dispSt < 0 ? 0 : $dispSt);
+ my $infoDir = $Sys->Get('INFO');
+ my $ninDir = ".$infoDir/.ninpocho/";
+ my @session_files = @$Result;
+ my $dispEd = (($dispSt + $dispNum) > $n ? $n : ($dispSt + $dispNum));
+
+ # ヘッダ部分の表示
+ my $common = "DoSubmit('sys.ninja','DISP','NIN_SEARCH');";
+
+ $Page->Print("\n");
+ return;
+ }
+ $Page->HTMLInput('hidden', 'DISPST', '');
+ $Page->HTMLInput('hidden', 'NINJA_ID', '');
+ $Page->HTMLInput('hidden', 'KEY', $Form->Get('KEY'));
+ $Page->HTMLInput('hidden', 'WORD', $Form->Get('WORD'));
+ if($Sys->Get('ADMIN')->{'SECINFO'}->IsAuthority($Sys->Get('ADMIN')->{'USER'}, $ZP::AUTH_RESDELETE, $Sys->Get('BBS'))){
+ $Page->Print(<
+
+
+
+
+
+
+HTML
+ }
+ $Page->Print("
\n");
+}
+
#------------------------------------------------------------------------------------------------------------
#
-# 検索結果出力 - Search
+# 書き込み履歴検索結果出力 - PrintNinjaSidSearch
# ------------------------------------------------
# 引 数:なし
# 戻り値:なし
diff --git a/test/admin/sys.setting.pl b/test/admin/sys.setting.pl
index 09bc833..fb9699f 100644
--- a/test/admin/sys.setting.pl
+++ b/test/admin/sys.setting.pl
@@ -487,7 +487,7 @@ sub PrintOtherSetting
{
my ($Page, $SYS, $Form) = @_;
my ($urlLink, $linkSt, $linkEd, $pathKind, $headText, $headUrl, $FastMode, $BBSGET, $upCheck, $imageTag);
- my ($linkChk, $pathInfo, $pathQuery, $fastMode, $bbsget, $imgtag, $CSP, $CSPSet, $ninLvmax, $cookieExp);
+ my ($linkChk, $pathInfo, $pathQuery, $fastMode, $bbsget, $imgtag, $CSP, $CSPSet, $ninLvmax, $cookieExp, $admCap, $srcCap);
my ($common,$nin_exp,$pass_exp);
$SYS->Set('_TITLE', 'System Other Setting');
@@ -672,12 +672,16 @@ sub PrintPlusSecSetting
my $Captcha_sitekey = $SYS->Get('CAPTCHA_SITEKEY');
my $Captcha_secretkey = $SYS->Get('CAPTCHA_SECRETKEY');
my $Proxy_apikey = $SYS->Get('PROXYCHECK_APIKEY');
+ my $admCap = $SYS->Get('ADMINCAP');
+ my $srcCap = $SYS->Get('SEARCHCAP');
$kakiko = ($Kakiko == 1 ? 'checked' : '');
$trip12 = ($Trip12 == 1 ? 'checked' : '');
$torexit = ($TOREXIT == 1 ? 'checked' : '');
$s5h = ($SYS->Get('DNSBL_S5H') == 1 ? 'checked' : '');
$dronebl = ($SYS->Get('DNSBL_DRONEBL') == 1 ? 'checked' : '');
+ $admCap = ($admCap == 1 ? 'checked' : '');
+ $srcCap = ($srcCap == 1 ? 'checked' : '');
$common = "onclick=\"DoSubmit('sys.setting','FUNC','SEC');\"";
@@ -729,6 +733,14 @@ sub PrintPlusSecSetting
$Page->Print("ProxyCheck APIキー ");
$Page->Print(" \n");
+ $Page->Print("Captchaを課すCGI \n");
+ $Page->Print("admin.cgi ");
+ $Page->Print(" \n");
+ $Page->Print("search.cgi ");
+ $Page->Print(" \n");
+ $Page->Print("bbs.cgi ");
+ $Page->Print("各掲示板の設定で有効化してください \n");
+
$Page->Print(" \n");
$Page->Print("");
$Page->Print(" \n");
@@ -1269,6 +1281,8 @@ sub FunctionPlusSecSetting
$SYSTEM->Set('CAPTCHA_SITEKEY', $Form->Get('CAPTCHA_SITEKEY'));
$SYSTEM->Set('CAPTCHA_SECRETKEY', $Form->Get('CAPTCHA_SECRETKEY'));
$SYSTEM->Set('PROXYCHECK_APIKEY', $Form->Get('PROXYCHECK_APIKEY'));
+ $SYSTEM->Set('ADMINCAP', ($Form->Equal('ADMINCAP', 'on') ? 1 : 0));
+ $SYSTEM->Set('SEARCHCAP', ($Form->Equal('SEARCHCAP', 'on') ? 1 : 0));
$SYSTEM->Save();
{
@@ -1281,6 +1295,8 @@ sub FunctionPlusSecSetting
push @$pLog, ' Captchaサイトキー:' . $SYSTEM->Get('CAPTCHA_SITEKEY');
push @$pLog, ' Captchaシークレットキー:' . $SYSTEM->Get('CAPTCHA_SECRETKEY');
push @$pLog, ' ProxyChecker APIキー:' . $SYSTEM->Get('PROXYCHECK_APIKEY');
+ push @$pLog, ' admin.cgiへのCaptcha:' . $SYSTEM->Get('ADMINCAP');
+ push @$pLog, ' search.cgiへのCaptcha:' . $SYSTEM->Get('SEARCHCAP');
}
return 0;
}
diff --git a/test/bbs.cgi b/test/bbs.cgi
index 84f9f93..4827812 100755
--- a/test/bbs.cgi
+++ b/test/bbs.cgi
@@ -146,6 +146,9 @@ sub Initialize
if(!defined $ENV{'REMOTE_HOST'} || $ENV{'REMOTE_HOST'} eq '') {
$ENV{'REMOTE_HOST'} = $Conv->reverse_lookup($ENV{'REMOTE_ADDR'});
}
+ if($ENV{'REMOTE_ADDR'} =~ /:/){
+ $ENV{'REMOTE_ADDR'} = $Conv->expand_ipv6($ENV{'REMOTE_ADDR'});
+ }
$Form->Set('HOST', $ENV{'REMOTE_HOST'});
my $client = $Conv->GetClient();
@@ -228,7 +231,7 @@ sub Initialize
}
#改竄をチェック
- if($sid && $sec){
+ if($sid =~ /^[0-9a-fA-F]{32}$/ && $sec){
my $ctx = Digest::MD5->new;
$ctx->add($Sys->Get('SECURITY_KEY'));
$ctx->add(':', $sid);
diff --git a/test/module/admin_search.pl b/test/module/admin_search.pl
index 6cadfae..b23920d 100644
--- a/test/module/admin_search.pl
+++ b/test/module/admin_search.pl
@@ -152,6 +152,7 @@ sub Run
return $this->{'RESULTSET'};
}
+# セッションIDから書き込み検索
sub Run_LogS
{
my $this = shift;
@@ -168,6 +169,16 @@ sub Run_LogS
}
return $this->{'RESULTSET'};
}
+
+# キーとワードから忍法帖検索
+sub Run_LogN
+{
+ my $this = shift;
+ my ($key,$word,$f) = @_;
+ $this->{'RESULTSET'} = [] if ($f);
+ $this->NinSearch($key, $word,);
+ return $this->{'RESULTSET'};
+}
#------------------------------------------------------------------------------------------------------------
#
# 検索結果取得
@@ -309,6 +320,45 @@ sub LogSearch
}
}
}
+sub NinSearch
+{
+ my $this = shift;
+ my ($key, $word, $sid) = @_;
+ my $ninDir = ".".$this->{'SYS'}->Get('INFO')."/.ninpocho/";
+ my $pResultSet = $this->{'RESULTSET'};
+
+ if($sid){
+ if(length($sid) == 32){
+ my $set = glob($ninDir.'cgisess_'.$sid);
+ $set =~ s/${ninDir}cgisess_//m;
+ @$pResultSet = $set;
+ }else{
+ my $allSid = [];
+ @$allSid = sort { (stat($b))[9] <=> (stat($a))[9] } glob($ninDir.'cgisess_*');
+ foreach my $id (@$allSid){
+ $id =~ s/${ninDir}cgisess_//m;
+ if(crypt($id,$id) eq $sid){
+ push @$pResultSet,$id;
+ }
+ }
+ }
+ }else{
+ my $allSid = [];
+ @$allSid = sort { (stat($b))[9] <=> (stat($a))[9] } glob($ninDir.'cgisess_*');
+ if($key){
+ require './module/ninpocho.pl';
+ my $Ninja = NINPOCHO->new;
+ foreach my $id (@$allSid){
+ $id =~ s/${ninDir}cgisess_//m;
+ $Ninja->LoadOnly($this->{'SYS'},$id);
+ if($Ninja->Get($key) =~ /\Q$word\E/i){
+ push @$pResultSet,$id;
+ }
+ }
+ }
+ }
+ return $pResultSet;
+}
#============================================================================================================
# Module END
#============================================================================================================
diff --git a/test/module/bbs_service.pl b/test/module/bbs_service.pl
index a4535d8..9d28749 100644
--- a/test/module/bbs_service.pl
+++ b/test/module/bbs_service.pl
@@ -269,7 +269,6 @@ sub PrintIndexHead
HEAD
$Page->Print('') if ($this->{'SET'}->Get('BBS_TWITTER'));
- $Page->Print('') if ($this->{'SET'}->Get('BBS_IMGUR'));
if($this->{'SET'}->Get('BBS_CAPTCHA')){
$Page->Print('') if ($this->{'SYS'}->Get('CAPTCHA') eq 'h-captcha');
$Page->Print('') if ($this->{'SYS'}->Get('CAPTCHA') eq 'g-recaptcha');
@@ -585,7 +584,13 @@ sub PrintIndexFoot
# footの表示
$Caption->Load($Sys, 'FOOT');
$Caption->Print($Page, $Set);
- $Page->Print("");
+ $Page->Print("");
+
+ my ($sec,$min,$hour,$day,$mon,$year) = localtime($Sys->Get('LASTMOD'));
+ $mon ++;
+ $year += 1900;
+ my $lastMod = sprintf("Last modified : %d/%02d/%02d %02d:%02d:%02d",$year,$mon,$day,$hour,$min,$sec);
+ $Page->Print("$lastMod
");
$Page->Print(<
@@ -747,7 +752,6 @@ sub PrintResponse
my $aa='';
# URLと引用個所の適応
- $Conv->ConvertImgur(\$elem[3])if($Set->Get('BBS_IMGUR') eq 'checked');
$Conv->ConvertMovie(\$elem[3])if($Set->Get('BBS_MOVIE') eq 'checked');
$Conv->ConvertTweet(\$elem[3])if($Set->Get('BBS_TWITTER') eq 'checked');
$Conv->ConvertURL($Sys, $Set, 0, \$elem[3])if($Sys->Get('URLLINK') eq 'TRUE');
diff --git a/test/module/data_utils.pl b/test/module/data_utils.pl
index 6c55b44..50b1a5f 100644
--- a/test/module/data_utils.pl
+++ b/test/module/data_utils.pl
@@ -212,19 +212,6 @@ sub ConvertURL
}
return $text;
}
-#Imgur埋め込み
-sub ConvertImgur
-{
- my $this = shift;
- my ($text) = @_ ;
-
- my $reg = '(?$1 |g;
-
- return $text;
-
-}
=pod
sub ConvertVideo
{
@@ -1791,6 +1778,31 @@ sub reverse_lookup {
# 逆引きが成功した場合はホスト名を、失敗した場合はIPアドレスを返す
return $host ? $host : $ip;
}
+
+# IPv6展開
+sub expand_ipv6 {
+ my $this = shift;
+ my ($ip) = @_;
+ # "::" が含まれているか確認し、省略部分を展開する
+ if ($ip =~ /::/) {
+ my ($left, $right) = split /::/, $ip, 2;
+ my @left_parts = split /:/, $left;
+ my @right_parts = split /:/, $right;
+ my $left_size = scalar @left_parts;
+ my $right_size = scalar @right_parts;
+ my $missing = 8 - ($left_size + $right_size); # 展開すべき0のブロック数
+ my $expanded = join(':', (@left_parts, ('0') x $missing, @right_parts));
+ $ip = $expanded;
+ }
+ # 各ブロックを4桁に展開する
+ my @blocks = split /:/, $ip;
+ foreach my $i (0 .. $#blocks) {
+ $blocks[$i] = sprintf("%04s", $blocks[$i]);
+ $blocks[$i] =~ s/ /0/g; # 空白を0で埋める
+ }
+ return join(':', @blocks);
+}
+
#============================================================================================================
# モジュール終端
#============================================================================================================
diff --git a/test/module/ninpocho.pl b/test/module/ninpocho.pl
index 053e551..d781f16 100644
--- a/test/module/ninpocho.pl
+++ b/test/module/ninpocho.pl
@@ -43,17 +43,16 @@ sub new
# 忍法帖ロード
# -------------------------------------------------------------------------------------
# @param $Sys SYSTEM
+# @param $slip slip文字列
# @param $isAnon 匿名化されてるかどうか
# @param $password あればパスワードで忍法帖をロード。無ければ通常ロード
-# @param $sid あればセッションIDで忍法帖をロード。無ければ通常ロード
-# @param $mode 1なら忍法帖を作らない(セッションIDのみ利用したい場合)
# @return パスワードがあり、かつセッションIDが見つからない場合0
#
#------------------------------------------------------------------------------------------------------------
sub Load
{
my $this = shift;
- my ($Sys,$isAnon,$password) = @_;
+ my ($Sys,$slip,$isAnon,$password) = @_;
my ($sid,$sid_saved,$sid_before,$sec,$auth);
my $Cookie = $Sys->Get('MainCGI')->{'COOKIE'};
@@ -65,18 +64,24 @@ sub Load
$this->{'ANON_FLAG'} = $isAnon eq '8' ? 1 : 0;
$sid = $Sys->Get('SID');
+ my $addr = $ENV{'REMOTE_ADDR'};
+ my $ctx3 = Digest::MD5->new;
+ $ctx3->add('ex0ch ID Generation');
+ $ctx3->add(':', $Sys->Get('SERVER'));
+ $ctx3->add(':', $addr);
+ my $ip_hash = $ctx3->b64digest;
+ my $ctx = Digest::MD5->new;
+ $ctx->add('ex0ch ID Generation');
+ $ctx->add(':', $Sys->Get('SERVER'));
+ $ctx->add(':', $slip);
+ my $slip_hash = $ctx->b64digest;
+
#cookieにsessionIDが保存されていない場合
if (!$sid && !$this->{'ANON_FLAG'}){
- my $addr = $ENV{'REMOTE_ADDR'};
- my $ctx = Digest::MD5->new;
- my $expiry = 60*60*24;
- $ctx->add('ex0ch ID Generation');
- $ctx->add(':', $Sys->Get('SERVER'));
- $ctx->add(':', $addr);
-
- $sid = GetHash($ctx->b64digest,$expiry,$ninDir.'hash/ip_addr.cgi');
+ my $expiry = 60*60*24; # 紐付け有効期限は24h
+ $sid = GetHash($ip_hash,$expiry,$ninDir.'hash/ip_addr.cgi');
if(!$sid) {
- $sid = GetHash(MakeUserInfo($Sys),$expiry,$ninDir.'hash/user_info.cgi');
+ $sid = GetHash($slip_hash,$expiry,$ninDir.'hash/user_info.cgi');
}
}
@@ -141,16 +146,8 @@ sub Load
$Sys->Set('SID',$sid);
# Hashテーブルを設定
if(!$this->{'ANON_FLAG'}){
- my $addr = $ENV{'REMOTE_ADDR'};
- my $ctx3 = Digest::MD5->new;
- $ctx3->add('ex0ch ID Generation');
- $ctx3->add(':', $Sys->Get('SERVER'));
- $ctx3->add(':', $addr);
- my $ip_hash = $ctx3->b64digest;
- my $user = MakeUserInfo($Sys);
-
SetHash($ip_hash,$sid,time,$ninDir.'hash/ip_addr.cgi');
- SetHash($user,$sid,time,$ninDir.'hash/user_info.cgi');
+ SetHash($slip_hash,$sid,time,$ninDir.'hash/user_info.cgi');
}
return $sid;
@@ -197,6 +194,16 @@ sub Get
return $val;
}
+sub isNew
+{
+ my $this = shift;
+ return $this->{'CREATE_FLAG'};
+}
+sub isLoad
+{
+ my $this = shift;
+ return $this->{'LOAD_FLAG'};
+}
#------------------------------------------------------------------------------------------------------------
#
# 忍法帖情報設定
@@ -396,37 +403,6 @@ sub DeleteHashValue {
}
}
-sub MakeUserInfo
-{
- my $Sys = shift;
- my $addr = $ENV{'REMOTE_ADDR'};
- my @ip = split(/\./,$addr);
- my $ua = $ENV{'HTTP_SEC_CH_UA'} // $ENV{'HTTP_USER_AGENT'};
-
- my $provider;
- my $HOST = $ENV{'HTTP_HOST'};
-
- # プロバイダのドメインを取得
- if ($HOST) {
- $HOST =~ s/ne\.jp/nejp/g;
- $HOST =~ s/ad\.jp/adjp/g;
- $HOST =~ s/or\.jp/orjp/g;
-
- my @d = split(/\./, $HOST); # リモートホストからドメイン部分を取り出す
- if (@d) {
- my $c = scalar @d;
- $provider = $d[$c - 2] . $d[$c - 1];
- }
- }
- my $ctx = Digest::MD5->new;
- $ctx->add('ex0ch ID Generation');
- $ctx->add(':', $Sys->Get('SERVER'));
- $ctx->add(':', $ip[0].$ip[1].$provider);
- $ctx->add(':', $ua);
- my $user = $ctx->b64digest;
-
- return $user;
-}
#============================================================================================================
# Module END
#============================================================================================================
diff --git a/test/module/post_service.pl b/test/module/post_service.pl
index 2b94fd9..dccd795 100644
--- a/test/module/post_service.pl
+++ b/test/module/post_service.pl
@@ -171,14 +171,31 @@ sub Write
my $noNinja = $Sec->IsAuthority($Sys->Get('CAPID'), $ZP::CAP_REG_NONINJA, $Form->Get('bbs'));
my $noCaptcha = $Sec->IsAuthority($Sys->Get('CAPID'), $ZP::CAP_REG_NOCAPTCHA, $Form->Get('bbs'));
- # BBS_SLIP付加とID末尾取得
+ # BBS_SLIPとID末尾取得
my $chid = substr($Sys->Get('SECURITY_KEY'),0,8);
- my ($slip_result,$idEnd) = $slip->BBS_SLIP($Sys, $bbsSlip, $chid) if (!$handle || !$noAttr);
+ my ($slip_nickname,$slip_aa,$slip_bb,$slip_cccc,$idEnd) = $slip->BBS_SLIP($Sys, $chid);
+
+ # slip文字列とID末尾
+ my $slip_result = '';
+ my $ipAddr = $ENV{'REMOTE_ADDR'};
+ if($bbsSlip eq 'vvv'){
+ $slip_result = ${slip_nickname};
+ }
+ elsif($bbsSlip eq 'vvvv'){
+ $slip_result = "${slip_nickname} [$ipAddr]";
+ }
+ elsif($bbsSlip eq 'vvvvv'){
+ $slip_result = "${slip_nickname} ${slip_aa}${slip_bb}-${slip_cccc}";
+ }
+ elsif($bbsSlip eq 'vvvvvv'){
+ $slip_result = "${slip_nickname} ${slip_aa}${slip_bb}-${slip_cccc} [${ipAddr}]";
+ }
$idEnd = $Set->Get('BBS_SLIP') eq 'checked' ? $Sys->Get('AGENT') : $idEnd;
- my $sid = $Ninja->Load($Sys,$idEnd,undef);
+ # 忍法帖関連
+ my $sid = $Ninja->Load($Sys,${slip_aa}.${slip_bb}.${slip_cccc},$idEnd,undef);
# hCaptcha認証
- if (!$noCaptcha && $Set->Get('BBS_CAPTCHA')){
+ if (!$noCaptcha && $Set->Get('BBS_CAPTCHA') && $Sys->Get('CAPTCHA') && $Sys->Get('CAPTCHA_SECRETKEY') && $Sys->Get('CAPTCHA_SITEKEY')){
if (!$Ninja->Get('auth') || $Ninja->Get('force_captcha')){
$err = $this->Certification_Captcha($Sys,$Form);
return $err if $err;
@@ -200,7 +217,7 @@ sub Write
$password = $1;
$ninmail =~ s/!load:(.{10,30})//;
$Form->Set('mail',$ninmail);
- $sid = $Ninja->Load($Sys,$idEnd,$password); #ロード
+ $sid = $Ninja->Load($Sys,${slip_aa}.${slip_bb}.${slip_cccc},$idEnd,$password); #ロード
$password = '';
}
elsif($ninmail =~ /!save:(.{10,30})/ && $isNinja){
@@ -209,32 +226,10 @@ sub Write
$Form->Set('mail',$ninmail);
}
$Sys->Set('SID',$sid);
-
+ my $ninLv = $Ninja->Get('ninLv');
+
#BANチェック
return $ZP::E_REG_BAN if(!$noNinja&&($Ninja->Get('ban') eq 'ban'||($Ninja->Get('ban_mthread') eq 'thread' && $Sys->Equal('MODE', 1))));
-
- # レベル制限
- my $ninLv = $Ninja->Get('ninLv');
- my $write_min = $Set->Get('NINJA_WRITE_MESSAGE');
- my $lvLim = $Threads->GetAttr($threadid,'ninLv');
- my ($min_level, $factor) = split(/-/, $Set->Get('NINJA_MAKE_THREAD'));
- if($isNinja && !$noNinja){
- if($Sys->Equal('MODE', 1)){
- # スレ立てモード
- if($ninLv < $min_level){
- return $ZP::E_REG_NINLVLIMIT;
- }else{
- $Ninja->Set('ninLv',$ninLv - $factor);
- }
- }else{
- # 書き込みモード
- if ($ninLv < $write_min){
- return $ZP::E_REG_NINLVLIMIT;
- }else{
- return $ZP::E_REG_NINLVLIMIT if($ninLv < $lvLim && $write_min <= $lvLim && !$noAttr);
- }
- }
- }
my $nusisid = GetSessionID($Sys,$threadid,1);
if($sid ne $nusisid && $nusisid && $Threads->GetAttr($threadid,'ban') && !$noAttr){
@@ -262,13 +257,36 @@ sub Write
my $updown = 'top';
$updown = '' if ($Form->Contain('mail', 'sage'));
$updown = '' if ($Threads->GetAttr($threadid, 'sagemode'));
- $updown = '' if ($Ninja->Get('force_sage'));
- $updown = '' if ($Set->Get('NINJA_FORCE_SAGE') >= $ninLv && $isNinja);
+ $updown = '' if ($Ninja->Get('force_sage') && !$noNinja);
+ $updown = '' if ($Set->Get('NINJA_FORCE_SAGE') >= $ninLv && $isNinja && !$noNinja);
$Sys->Set('updown', $updown);
# 書き込み直前処理
$err = $this->ReadyBeforeWrite(DAT::GetNumFromFile($Sys->Get('DATPATH')) + 1,$Ninja->Get('ban_command'),$Ninja,$ninLv);
return $err if ($err != $ZP::E_SUCCESS);
+
+ # レベル制限
+ my $write_min = $Set->Get('NINJA_WRITE_MESSAGE');
+ my $lvLim = $Threads->GetAttr($threadid,'ninLv');
+ my ($min_level, $factor) = split(/-/, $Set->Get('NINJA_MAKE_THREAD'));
+ if($isNinja && !$noNinja){
+ if($Sys->Equal('MODE', 1)){
+ # スレ立てモード
+ if($ninLv < $min_level){
+ return $ZP::E_REG_NINLVLIMIT;
+ }else{
+ $Ninja->Set('ninLv',$ninLv - $factor);
+ }
+ }else{
+ # 書き込みモード
+ if ($ninLv < $write_min){
+ return $ZP::E_REG_NINLVLIMIT;
+ }else{
+ return $ZP::E_REG_NINLVLIMIT if($ninLv < $lvLim && $write_min <= $lvLim && !$noAttr);
+ }
+ }
+ }
+
# 忍法帖
if($Set->Get('BBS_NINJA')){
my $ninerr = $this->Ninpocho($Sys,$Set,$Form,$Ninja,$sid);
@@ -281,7 +299,7 @@ sub Write
my $mail = $Form->Get('mail', '');
my $text = $Form->Get('MESSAGE', '');
#SLIPがあった場合は付加する
- $name .= " (${slip_result})" if ($slip_result && !$noslip);
+ $name .= " (${slip_result})" if (($slip_result && !$noslip) && (!$handle || !$noAttr));
$datepart = $Form->Get('datepart', '');
$idpart = $Form->Get('idpart', '');
@@ -328,9 +346,7 @@ sub Write
# レス数が最大数を超えたらover設定をする
$resNum = DAT::GetNumFromFile($datPath);
my $MAXRES = $AttrResMax ? $AttrResMax : $Sys->Get('RESMAX');
- if ($resNum > $MAXRES){
- return $ZP::E_LIMIT_OVERMAXRES;
- }elsif ($resNum == $MAXRES) {
+ if ($resNum >= $MAXRES) {
# datにOVERスレッドレスを書き込む
Get1001Data($Sys, \$line,$MAXRES);
DAT::DirectAppend($Sys, $datPath, $line);
@@ -537,12 +553,17 @@ sub ReadyBeforeWrite
my $threadid = $Sys->Get('KEY');
my $commandAuth = $Sec->IsAuthority($capID, $ZP::CAP_REG_COMMAND, $Form->Get('bbs'));
my $noAttr = $Sec->IsAuthority($capID, $ZP::CAP_REG_NOATTR, $Form->Get('bbs'));
+ my $noNinja = $Sec->IsAuthority($Sys->Get('CAPID'), $ZP::CAP_REG_NONINJA, $Form->Get('bbs'));
#スレ立て時用コマンド
my ($min_level, $factor) = split(/-/, $Set->Get('NINJA_USE_COMMAND'));
- if($com ne 'on' && (($Set->Get('BBS_NINJA') && $ninLv >= $min_level) || !$Set->Get('BBS_NINJA'))){
+ if($com ne 'on' && (($Set->Get('BBS_NINJA') && $ninLv >= $min_level) || !$Set->Get('BBS_NINJA') || $commandAuth)){
+
+ # Capの権限があった場合すべて許可
+ $CommandSet = oct("0b11111111111111111111111") if $commandAuth;
+
if($Sys->Equal('MODE', 1)){
- Command($Sys,$Form,$Set,$Threads,$Ninja,$CommandSet,1);
+ Command($Sys,$Form,$Set,$Threads,$Ninja,$CommandSet,$noNinja,1);
}
else{
if($Form->Get('mail') =~ /!pass:(.{1,30})/){
@@ -561,11 +582,11 @@ sub ReadyBeforeWrite
$Form->Set('mail',$mail);
if($inputPass eq $threadPass){
- Command($Sys,$Form,$Set,$Threads,$Ninja,$CommandSet,0);
+ Command($Sys,$Form,$Set,$Threads,$Ninja,$CommandSet,$noNinja,0);
}
}
elsif($commandAuth || GetSessionID($Sys,$threadid,1) eq $Sys->Get('SID')){
- Command($Sys,$Form,$Set,$Threads,$Ninja,$CommandSet,0);
+ Command($Sys,$Form,$Set,$Threads,$Ninja,$CommandSet,$noNinja,0);
}
}
}
@@ -607,10 +628,16 @@ sub GetSessionID
return $sid;
}
-#ユーザーコマンド
+
+#------------------------------------------------------------------------------------------------------------
+#
+# ユーザーコマンド
+# -------------------------------------------------------------------------------------
+#
+#------------------------------------------------------------------------------------------------------------
sub Command
{
- my ($Sys,$Form,$Set,$Threads,$Ninja,$setBitMask,$mode) = @_;
+ my ($Sys,$Form,$Set,$Threads,$Ninja,$setBitMask,$noNinja,$mode) = @_;
$Threads->LoadAttr($Sys);
my $threadid = $Sys->Get('KEY');
my $Command = '';
@@ -628,7 +655,6 @@ sub Command
my $pass = $ctx->b64digest;
$Threads->SetAttr($threadid, 'pass',$pass);
- $Threads->SaveAttr($Sys);
my $mail = $Form->Get('mail');
$mail =~ s/!pass:(.{1,30})//;
@@ -649,7 +675,6 @@ sub Command
$Command .= '値が過小 ';
}
}
- $Threads->SaveAttr($Sys);
}
#extendコマンド
if ($Form->Get('MESSAGE') =~ /^!extend:(|on|default|none|checked):(|none|default|checked|feature|verbose|v{3,6}):([1-9][0-9]*):([1-9][0-9]*)( |$)/ && ($setBitMask & 1048576)) {
@@ -659,7 +684,6 @@ sub Command
my $slip = $2;
my $line = $3;
my $size = $4;
- $Threads->SaveAttr($Sys);
}
}
@@ -669,9 +693,9 @@ sub Command
if($Form->Get('MESSAGE') =~ /(^| )!delcmd:([0-9a-zA-Z&;]{4,20})( |$)/ && ($setBitMask & 256)){
my $delCommand = $2;
$delCommand =~ s/^sage$/sagemode/;
- #BAN取り消し用
if($Threads->GetAttr($threadid, $delCommand)){
if($delCommand =~ /ban>>([1-9][0-9]*)/ ){
+ #BAN取り消し用
my @banuserAttr = split(/,/ ,$Threads->GetAttr($threadid,'ban'));
my $bannum = @banuserAttr;
my $bansid = GetSessionID($Sys,$threadid,$1);
@@ -696,7 +720,6 @@ sub Command
}
else{
$Threads->SetAttr($threadid, $delCommand,'');
- $Threads->SaveAttr($Sys);
$delCommand =~ s/^sagemode$/sage/;
$Command .= '※'.$delCommand.'取り消し ';
}
@@ -710,11 +733,10 @@ sub Command
if($Form->Get('MESSAGE') =~ /(^| )!stop( |$)/ && ($setBitMask & 128)){
my $ninLv = $Ninja->Get('ninLv');
my ($min_level, $factor) = split(/-/, $Set->Get('NINJA_THREAD_STOP'));
- if(($NinStat && $ninLv >= $min_level)||!$NinStat){
+ if(($NinStat && $ninLv >= $min_level)||!$NinStat||$noNinja){
$Threads->SetAttr($threadid, 'stop',1);
- $Threads->SaveAttr($Sys);
$Command .= '※スレスト ';
- $Ninja->Set('ninLv',$ninLv - $factor);
+ $Ninja->Set('ninLv',$ninLv - $factor) unless $noNinja;
}else{
$Command .= '※レベル不足 ';
}
@@ -722,7 +744,6 @@ sub Command
#過去ログ送り
if($Form->Get('MESSAGE') =~ /(^| )!pool( |$)/ && ($setBitMask & 512)){
$Threads->SetAttr($threadid, 'pool',1);
- $Threads->SaveAttr($Sys);
$Command .= '※過去ログ送り ';;
}
#スレタイ変更
@@ -775,7 +796,7 @@ sub Command
if($Dat->Load($Sys,$Path,0)){
if($target2 && $target < $target2){
my $cost = $factor * ($target2 - $target + 1);
- if(($NinStat && $ninLv >= $min_level && $ninLv - $min_level >= $cost) || !$NinStat){
+ if(($NinStat && $ninLv >= $min_level && $ninLv - $min_level >= $cost) || !$NinStat || $noNinja){
my $li = $Dat->Get($target2-1);
$li = $$li;
my $count = 0;
@@ -784,7 +805,8 @@ sub Command
for($i = $target-1;$i <= $target2-1;$i++){
my $line = $Dat->Get($i);
$line = $$line;
- if ((split(/<>/,chomp($line)))[4] eq ''){
+ chomp($line);
+ if ((split(/<>/,$line))[4] eq ''){
if($line){
my $deleteMessage = "$del<>$del<>$del<>$del<>$del\n";
$Dat->Set($i,$deleteMessage);
@@ -803,7 +825,7 @@ sub Command
}else{
$Command .= "※>>${target}-${target2}は削除済み ";
}
- $Ninja->Set('ninLv',$ninLv - $factor*$count);
+ $Ninja->Set('ninLv',$ninLv - $factor*$count) unless $noNinja;
}else{
$Command .= "※範囲指定が変 ";
}
@@ -812,17 +834,18 @@ sub Command
}
}else{
- if(($NinStat && $ninLv >= $min_level)||!$NinStat){
+ if(($NinStat && $ninLv >= $min_level)||!$NinStat||$noNinja){
my $line = $Dat->Get($target-1);
$line = $$line;
- if ((split(/<>/,chomp($line)))[4] eq ''){
+ chomp($line);
+ if ((split(/<>/,$line))[4] eq ''){
if($line){
- my $deleteMessage = "$del<>$del<>$del<>$del<>$del\n";
- $Dat->Set($target-1,$deleteMessage);
- $Dat->Save($Sys);
- $Command .= "※>>${target}を削除 ";
+ my $deleteMessage = "$del<>$del<>$del<>$del<>$del\n";
+ $Dat->Set($target-1,$deleteMessage);
+ $Dat->Save($Sys);
+ $Command .= "※>>${target}を削除 ";
- $Ninja->Set('ninLv',$ninLv - $factor);
+ $Ninja->Set('ninLv',$ninLv - $factor) unless $noNinja;
}else{
$Command .= "※存在しません ";
}
@@ -881,45 +904,38 @@ sub Command
#強制sage
if($Form->Get('MESSAGE') =~ /(^| )!sage( |$)/ && ($setBitMask & 4)){
$Threads->SetAttr($threadid, 'sagemode',1);
- $Threads->SaveAttr($Sys);
$Command .= '※強制sage ';
}
#強制age
if($Form->Get('MESSAGE') =~ /(^| )!float( |$)/ && ($setBitMask & 131072)){
$Threads->SetAttr($threadid, 'float',1);
- $Threads->SaveAttr($Sys);
$Command .= '※強制age ';
}
#不落
if($Form->Get('MESSAGE') =~ /(^| )!nopool( |$)/ && ($setBitMask & 262144)){
$Threads->SetAttr($threadid, 'nopool',1);
- $Threads->SaveAttr($Sys);
$Command .= '※不落 ';
}
#BBS_SLIP
if($Form->Get('MESSAGE') =~ /(^| )!slip:(v{3,6})( |$)/ && ($setBitMask & 2048)){
$Threads->SetAttr($threadid, 'slip',$2);
- $Threads->SaveAttr($Sys);
$Command .= '※BBS_SLIP='.$2.' ';
}
#名無し強制
if($Form->Get('MESSAGE') =~ /(^| )!force774( |$)/ && ($setBitMask & 32)){
$Threads->SetAttr($threadid, 'force774',1);
- $Threads->SaveAttr($Sys);
$Command .= '※強制名無し ';
- $Form->Set('FROM','');
+ #$Form->Set('FROM','');
}
#実況モード
if($Form->Get('MESSAGE') =~ /(^| )!live( |$)/ && ($setBitMask & 1024)){
$Threads->SetAttr($threadid, 'live',1);
- $Threads->SaveAttr($Sys);
$Command .= '※実況スレ ';
}
#スレ主非表示
if($Form->Get('MESSAGE') =~ /(^| )!hidenusi( |$)/ && ($setBitMask & 32768)){
if(!$Set->Get('BBS_HIDENUSI')){
$Threads->SetAttr($threadid, 'hidenusi',1);
- $Threads->SaveAttr($Sys);
$Command .= '※スレ主非表示 ';
}
}
@@ -933,7 +949,7 @@ sub Command
my $ninLv = $Ninja->Get('ninLv');
my ($min_level, $factor) = split(/-/, $Set->Get('NINJA_USER_BAN'));
- if(($NinStat && $ninLv >= $min_level) || !$NinStat){
+ if(($NinStat && $ninLv >= $min_level) || !$NinStat ||$noNinja){
if($bansid){
if($bansid ne $nusisid){
# grepを使って$bansidが@banuserAttrに存在するかをチェック
@@ -946,9 +962,8 @@ sub Command
push(@banuserAttr, $bansid); # 新しい要素を配列の末尾に追加
shift @banuserAttr if ($bannum+1 > $Sys->Get('BANMAX'));
$Threads->SetAttr($threadid, 'ban', join(',', @banuserAttr));
- $Threads->SaveAttr($Sys);
$Command .= "※BAN:>>$2 ";
- $Ninja->Set('ninLv',$ninLv - $factor);
+ $Ninja->Set('ninLv',$ninLv - $factor) unless $noNinja;
}
} else {
$Command .= "※スレ主はBAN不可 ";
@@ -968,7 +983,6 @@ sub Command
my $new774 = $1;
$new774 = HTML::Entities::encode_entities($new774);
$Threads->SetAttr($threadid, 'change774',$new774);
- $Threads->SaveAttr($Sys);
$new774 = HTML::Entities::decode($new774);
$Command .= '※名無し:'.$new774.' ';
}else{
@@ -978,12 +992,10 @@ sub Command
#ID無し若しくはIDをスレッドで変更(!noidと!changeidがあった場合は!noid優先)
if($Form->Get('MESSAGE') =~ /(^| )!noid( |$)/ && ($setBitMask & 8)){
$Threads->SetAttr($threadid, 'noid',1);
- $Threads->SaveAttr($Sys);
$Command .= '※ID無し ';
}
if(!$Threads->GetAttr($threadid, 'noid') && $Form->Get('MESSAGE') =~ /(^| )!changeid( |$)/ && ($setBitMask & 16)){
$Threads->SetAttr($threadid, 'changeid',1);
- $Threads->SaveAttr($Sys);
$Command .= '※ID変更 ';
}
@@ -996,7 +1008,6 @@ sub Command
if($2 <= $lvmax){
if($2 >= $write_min){
$Threads->SetAttr($threadid, 'ninLv',$2);
- $Threads->SaveAttr($Sys);
$Command .= "※忍法帖Lv$2未満は書き込み不可 ";
}else{
$Command .= "※${write_min}未満は設定不可 ";
@@ -1007,6 +1018,7 @@ sub Command
}
}
if($Command){
+ $Threads->SaveAttr($Sys);
$Command =~ s/ $//;
$Form->Set('MESSAGE',$Form->Get('MESSAGE')."$Command ");
}
@@ -1207,13 +1219,13 @@ sub IsRegulation
$Sys->Set('IPCOUNTRY','abroad');
}
# PROXYチェック
- if ($this->{'CONV'}->IsProxyDNSBL($this->{'SYS'}, $this->{'FORM'}, $from, $mode)) {
+ if ($this->{'CONV'}->IsProxyDNSBL($this->{'SYS'}, $this->{'FORM'}, $from, $mode)) { # DNSBLによるチェック
#$this->{'FORM'}->Set('FROM', " [—\{}\@{}\@{}-] $from");
if (!$Sec->IsAuthority($capID, $ZP::CAP_REG_DNSBL, $bbs) && $Set->Equal('BBS_DNSBL_CHECK', 'checked')) {
return $ZP::E_REG_DNSBL;
}
$Sys->Set('ISPROXY','bl');
- }elsif($this->{'CONV'}->IsProxyAPI($this->{'SYS'},1) && $Sys->Get('PROXYCHECK_APIKEY')){
+ }elsif($Sys->Get('PROXYCHECK_APIKEY') && $this->{'CONV'}->IsProxyAPI($this->{'SYS'},1)){ # DNSBLに引っかからなかった場合に、設定されていたらProxy.ioへ
if (!$Sec->IsAuthority($capID, $ZP::CAP_REG_DNSBL, $bbs) && $Set->Equal('BBS_PROXY_CHECK', 'checked')) {
return $ZP::E_REG_DNSBL;
}
@@ -1548,8 +1560,9 @@ sub Certification_Captcha {
return $ZP::E_FORM_FAILEDCAPTCHA
}
} else {
- # HTTPS関連のエラーの疑いあり
+ # Captchaを素通りする場合、HTTPS関連のエラーの疑いあり
# LWP::Protocol::httpsおよびNet::SSLeayが入っているか確認
+ # このエラーの場合、スルーして書き込み
return $ZP::E_SYSTEM_CAPTCHAERROR;
}
}else{
@@ -1696,6 +1709,12 @@ sub SaveHost
}
}
+#------------------------------------------------------------------------------------------------------------
+#
+# 忍法帖に関する処理
+# -------------------------------------------------------------------------------------
+#
+#------------------------------------------------------------------------------------------------------------
sub Ninpocho
{
my $this = shift;
@@ -1706,6 +1725,7 @@ sub Ninpocho
# セッションから書き込み数を取得
my $count = $Ninja->Get('count') || 0;
+ my $today_count = $Ninja->Get('today_count') || 0;
my $thread = $Ninja->Get('thread_count') || 0;
# 書き込んだ時間を取得
@@ -1715,21 +1735,27 @@ sub Ninpocho
# セッションから前回レベルアップしたときの時間を取得
my $lvUpTime = $Ninja->Get('lvuptime') || $time23h;
- # 書き込み数をカウント
- $count++;
-
# レベルの上限
my $lvLim = $Sys->Get('NINLVMAX');
# 前回のレベルアップから23時間以上経過していればレベルアップ
- if ($resTime >= $lvUpTime && $ninLv < $lvLim) {
+ if ($resTime >= $lvUpTime && $ninLv < $lvLim) { # && $ninLv == $today_count
$ninLv++;
$lvUpTime = $time23h;
}
+ # 書き込み数をカウント
+ $count++;
+ unless(int(time/(60*60*24)) - int($Ninja->Get('last_wtime')/(60*60*24))){
+ $today_count++;
+ }else{
+ $today_count = 1;
+ }
+
# セッションに記録
if ($Ninja) {
$Ninja->Set('count', $count);
+ $Ninja->Set('today_count', $today_count);
$Ninja->Set('ninLv', $ninLv);
$Ninja->Set('lvuptime', $lvUpTime);
@@ -1792,9 +1818,16 @@ sub Ninpocho
return 0;
}
+
+#------------------------------------------------------------------------------------------------------------
+#
+# タイムラインにレス追加
+# -------------------------------------------------------------------------------------
+#
+#------------------------------------------------------------------------------------------------------------
sub AddTimeLine
{
- my $this=shift;
+ my $this = shift;
my ($Sys,$Set,$line) = @_;
require './module/dat.pl';
require './module/thread.pl';
@@ -1805,14 +1838,16 @@ sub AddTimeLine
$Threads->Load($Sys);
my $TLpath = $Sys->Get('BBSPATH') . '/' . $Sys->Get('BBS') . '/dat/2147483647.dat';
-
- my @lines = split(/<>/,chomp($line));
my $title = $Threads->Get('SUBJECT',$Sys->Get('KEY'));
my $url = $Conv->CreatePath($Sys, 0, $Sys->Get('BBS'), $Sys->Get('KEY'), 'l10');
- $lines[3] += "$title ";
+
+ chomp($line);
+ my @lines = split(/<>/, $line);
+ $lines[3] .= "$title ";
$lines[4] = "★タイムライン★\n";
$line = join('<>',@lines);
- $Dat->DirectAppend($Sys,$TLpath,$line);
+
+ my $err = $Dat->DirectAppend($Sys,$TLpath,$line);
my $resNum = DAT::GetNumFromFile($TLpath);
if($resNum > $Set->Get('TL_RES_MAX')){
@@ -1820,7 +1855,7 @@ sub AddTimeLine
$Dat->Delete(0);
$Dat->Save($Sys);
}
-
+ return $err;
}
#SPAMBLOCK
sub SpamBlock
diff --git a/test/module/setting.pl b/test/module/setting.pl
index 87f62a9..c380d54 100644
--- a/test/module/setting.pl
+++ b/test/module/setting.pl
@@ -373,7 +373,6 @@ sub InitSettingData
'BBS_SPAMKILLI_POINT' => 10,
'BBS_IMGTAG' => '',
- 'BBS_IMGUR' => '',
'BBS_TWITTER' => '',
'BBS_MOVIE' => '',
'BBS_URL_TITLE' => '',
diff --git a/test/module/slip.pl b/test/module/slip.pl
index 13ddbd5..15a6503 100644
--- a/test/module/slip.pl
+++ b/test/module/slip.pl
@@ -43,10 +43,9 @@ sub is_denied_ip {
return exists $denied_ips->{$ipAddr} ? 1 : 0;
}
-
# 匿名化判定
sub is_anonymous {
- my ($isFwifi, $country, $remoho, $ipAddr, $infoDir) = @_;
+ my ($isFwifi, $country, $remoho, $ipAddr) = @_;
my $isAnon = 0;
if (!$isFwifi && $country eq 'JP' && $remoho ne $ipAddr) {
@@ -97,7 +96,6 @@ sub is_public_wifi {
return $isFwifi;
}
-
# モバイル判定
sub is_mobile {
my ($country, $ipAddr, $remoho) = @_;
@@ -324,17 +322,14 @@ sub is_mobile {
#------------------------------------------------------------------------------------------------------------
# BBS_SLIP生成
# -------------------------------------------------------------------------------------
-# @param $bbsslip slip種別(/(undef)/vvv/vvvv/vvvvv/vvvvvv/)
-# @param $infoDir infoディレクトリ
# @param $chid SLIP_ID変更用
-# @param $checkKey プロキシチェックAPI問い合わせ用
# @return $slip_result
# @return $idEnd ID末尾
#------------------------------------------------------------------------------------------------------------
sub BBS_SLIP
{
my $this = shift;
- my ($Sys, $bbsslip, $chid) = @_;
+ my ($Sys, $chid) = @_;
my ($slip_ip, $slip_remoho, $slip_ua);
my $ipAddr = $ENV{'REMOTE_ADDR'};
@@ -343,17 +338,18 @@ sub BBS_SLIP
my $infoDir = $Sys->Get('INFO');
# 各種判定
- my $country = $Sys->Get('IPCOUNTRY') ne 'abroad' ? 'JP': 'ガイコーク';
- my $ismobile = is_mobile($country,$ipAddr,$remoho);
- my $isFwifi = is_public_wifi($country,$ipAddr,$remoho);
- my $isProxy = $Sys->Get('ISPROXY');
- my $isAnon = is_anonymous($isFwifi,$country,$ipAddr,$remoho,$infoDir);
+ my $country = $Sys->Get('IPCOUNTRY') ne 'abroad' ? 'JP': 'ガイコーク'; # post_service側での判定を流用
+ my $isProxy = $Sys->Get('ISPROXY'); # post_service側での判定を流用
+ my $ismobile = is_mobile($country,$ipAddr,$remoho); # モバイル判定
+ my $isFwifi = is_public_wifi($country,$ipAddr,$remoho); # 公衆wifi判定
+ my $isAnon = is_anonymous($isFwifi,$country,$ipAddr,$remoho); # 匿名化判定
+ #my $isDenied = is_denied_ip($ipAddr,$infoDir); # 拒否IP判定
# bbs_slipに使用する文字
my @slip_chars = (0..9, 'a'..'z', 'A'..'Z', '.', '/');
# 一週間で文字列変更
- my $week_number = int((time + 172800) / (60 * 60 * 24 * 7));# 水曜9時に
+ my $week_number = int((time + 172800) / (60 * 60 * 24 * 7)); # 水曜9時に変わる
my ($chnum1,$chnum2,$chnum3,$chnum4);
srand($week_number);
$chnum1 = int(rand(1000000));
@@ -370,9 +366,13 @@ sub BBS_SLIP
# slip_ip生成
my $fo = '';
my $so = '';
- $ipAddr =~ /^(\d{1,4})\.(\d{1,4})/;
- $fo = $1 + $chnum1 + $chid;
- $so = $2 + $chnum2 + $chid;
+ if ($ipAddr =~ /^(\d{1,3})\.(\d{1,3})/) {
+ $fo = $1 + $chnum1 + $chid;
+ $so = $2 + $chnum2 + $chid;
+ } elsif ($ipAddr =~ /^([\da-fA-F]{1,4}):([\da-fA-F]{1,4}):([\da-fA-F]{1,4}):([\da-fA-F]{1,4})/) {
+ $fo = hex($1) + hex($2) + $chnum1 + $chid;
+ $so = hex($3) + hex($4) + $chnum2 + $chid;
+ }
my $ip_char1 = $slip_chars[$fo % 64];
my $ip_char2 = $slip_chars[$so % 64];
@@ -441,9 +441,15 @@ sub BBS_SLIP
# 串判定
if ($isProxy) {
- $idEnd = '8';
- $slip_nickname = 'クシザシ';
- $slip_nickname .= $fixed_nickname_end;
+ if($isProxy eq 'proxy'){
+ $idEnd = '8';
+ $slip_nickname = 'クシザシ';
+ $slip_nickname .= $fixed_nickname_end;
+ }else{
+ $idEnd = '8';
+ $slip_nickname = 'ブロック';
+ $slip_nickname .= $fixed_nickname_end;
+ }
}else{
# 逆引き判定
if (!$slip_remoho || $ipAddr eq $remoho) { # 逆引きできない場合
@@ -545,352 +551,21 @@ sub BBS_SLIP
}
}
}
- }
-
- # slip文字列とID末尾
- my $slip_result = '';
- if($bbsslip eq 'vvv'){
- $slip_result = ${slip_nickname};
- }
- elsif($bbsslip eq 'vvvv'){
- $slip_result = "${slip_nickname} [${ipAddr}]";
- }
- elsif($bbsslip eq 'vvvvv'){
- $slip_result = "${slip_nickname} ${slip_aa}${slip_bb}-${slip_cccc}";
- }
- elsif($bbsslip eq 'vvvvvv'){
- $slip_result = "${slip_nickname} ${slip_aa}${slip_bb}-${slip_cccc} [${ipAddr}]";
- }
- # 匿名環境の場合は末尾が"8"になる
- return $slip_result,$idEnd;
-}
-
-# 旧式
-sub BBS_SLIP_OLD
-{
- my ($ip_addr, $remoho, $ua, $bbsslip) = @_;
- my ($slip_ip, $slip_remoho, $slip_ua);
-
- #bbs_slipに使用する文字
- my @slip_char = (0..9, "a".."z", "A".."Z", ".", "/");
- #slip_ip生成
- $ip_addr =~ /^(\d{1,4})\.(\d{1,4})/;
- my $ip_char1 = $slip_char[$1 % 64];
- my $ip_char2 = $slip_char[$2 % 64];
- $slip_ip = $ip_char1 . $ip_char2;
-
- #slip_remoho生成
- if ($remoho eq "") {
- $slip_remoho = "none";
- }else {
- $remoho =~ /^([a-zA-Z]+)[\d\-\.]*([a-zA-Z][a-zA-Z\d\.\-]+)$/;
- my $remoho_name = "$1 $2";
- my $remoho_dig = md5_hex($remoho_name);
- $remoho_dig =~ /^(.{2})(.{2})/;
- my $remoho_char1 = $slip_char[hex($1) % 64];
- my $remoho_char2 = $slip_char[hex($2) % 64];
- $slip_remoho = $remoho_char1 . $remoho_char2;
- }
-
- #slip_ua生成
- my $ua_dig = md5_hex($ua);
- $ua_dig =~ /^(.{2})(.{2})(.{2})(.{2})/;
- my $ua_char1 = $slip_char[hex($1) % 64];
- my $ua_char2 = $slip_char[hex($2) % 64];
- my $ua_char3 = $slip_char[hex($3) % 64];
- my $ua_char4 = $slip_char[hex($4) % 64];
- $slip_ua = $ua_char1 . $ua_char2 . $ua_char3 . $ua_char4;
-
- #スマホ・タブレット判定
- my $fixed_nickname_end = "";
- my $mobile_nickname_end = "";
- if ($ua =~ /.*(iphone|ipad|android|mobile).*/i) {
- $fixed_nickname_end = "W";
- $mobile_nickname_end = "M";
- }else {
- $mobile_nickname_end = "T";
- }
-
-
- #bbs_slipの初期設定
- my $slip_id = "";
- my $slip_nickname = "ワッチョイ${fixed_nickname_end}";
- my $slip_aa = $slip_ip;
- my $slip_bb = $slip_remoho;
- my $slip_cccc = $slip_ua;
-
-
- #モバイル回線判定用のリモホ・事業者名・IP
- my @mobile_remoho = (
- ".*\\.openmobile\\.ne\\.jp",
- ".*\\.panda-world\\.ne\\.jp",
- "KD027.*\\.au-net\\.ne\\.jp",
- "KD036.*\\.au-net\\.ne\\.jp",
- "KD106.*\\.au-net\\.ne\\.jp",
- "KD111.*\\.au-net\\.ne\\.jp",
- "KD119.*\\.au-net\\.ne\\.jp",
- "KD182.*\\.au-net\\.ne\\.jp",
- ".*\\.msa\\.spmode\\.ne\\.jp",
- ".*\\.msb\\.spmode\\.ne\\.jp",
- ".*\\.msc\\.spmode\\.ne\\.jp",
- ".*\\.msd\\.spmode\\.ne\\.jp",
- ".*\\.mse\\.spmode\\.ne\\.jp",
- ".*\\.msf\\.spmode\\.ne\\.jp",
- ".*\\.fix\\.mopera\\.net",
- ".*\\.air\\.mopera\\.net",
- ".*\\.vmobile\\.jp",
- ".*\\.bmobile\\.ne\\.jp",
- ".*\\.mineo\\.jp",
- ".*omed01\\.tokyo\\.ocn\\.ne\\.jp",
- ".*omed01\\.osaka\\.ocn\\.ne\\.jp",
- ".*mobac01\\.tokyo\\.ocn\\.ne\\.jp",
- ".*mobac01\\.osaka\\.ocn\\.ne\\.jp",
- ".*\\.mvno\\.rakuten\\.jp",
- ".*\\.nttpc\\.ne\\.jp",
- "UQ.*au-net\\.ne\\.jp",
- "dcm\\d(?:-\\d+){4}\\.tky\\.mesh\\.ad\\.jp",
- "neoau\\d(?:-\\d+){4}\\.tky\\.mesh\\.ad\\.jp",
- ".*\\.ap\\.dream\\.jp",
- ".*\\.ap\\.mvno\\.net",
- "fenics\\d+\\.wlan\\.ppp\\.infoweb\\.ne\\.jp"
- );
- my @mobile_whois = (
- "Plus One marketing",
- "LogicLinks",
- "SORASIM"
- );
- my @rakuten_mno_ip = (
- "101\\.102\\.(?:\\d|[1-5]\\d|6[0-3])\\.\\d{1,3}",
- "103\\.124\\.[0-3]\\.\\d{1,3}",
- "110\\.165\\.(?:1(?:2[89]|[3-9]\\d)|2\\d{2})\\.\\d{1,3}",
- "119\\.30\\.(?:19[2-9]|2\\d{2})\\.\\d{1,3}",
- "119\\.31\\.1(?:2[89]|[3-5]\\d)\\.\\d{1,3}",
- "133\\.106\\.(?:1(?:2[89]|[3-9]\\d)|2\\d{2})\\.\\d{1,3}",
- "133\\.106\\.(?:1[6-9]|2\\d|3[01])\\.\\d{1,3}",
- "133\\.106\\.(?:3[2-9]|[45]\\d|6[0-3])\\.\\d{1,3}",
- "133\\.106\\.(?:6[4-9]|[7-9]\\d|1(?:[01]\\d|2[0-7]))\\.\\d{1,3}",
- "133\\.106\\.(?:[89]|1[0-5])\\.\\d{1,3}",
- "157\\.192(?:\\.\\d{1,3}){2}",
- "193\\.114\\.(?:19[2-9]|2\\d{2})\\.\\d{1,3}",
- "193\\.114\\.(?:3[2-9]|[45]\\d|6[0-3])\\.\\d{1,3}",
- "193\\.114\\.(?:6[4-9]|[78]\\d|9[0-5])\\.\\d{1,3}",
- "193\\.115\\.(?:\\d|[12]\\d|3[01])\\.\\d{1,3}",
- "193\\.117\\.(?:[9][6-9]|1(?:[01]\\d|2[0-7]))\\.\\d{1,3}",
- "193\\.118\\.(?:\\d|[12]\\d|3[01])\\.\\d{1,3}",
- "193\\.118\\.(?:6[4-9]|[78]\\d|9[0-5])\\.\\d{1,3}",
- "193\\.119\\.(?:1(?:2[89]|[3-9]\\d)|2\\d{2})\\.\\d{1,3}",
- "193\\.82\\.1(?:[6-8]\\d|9[01])\\.\\d{1,3}",
- "194\\.193\\.2(?:2[4-9]|[34]\\d|5[0-5])\\.\\d{1,3}",
- "194\\.193\\.(?:6[4-9]|[78]\\d|9[0-5])\\.\\d{1,3}",
- "194\\.223\\.(?:[9][6-9]|1(?:[01]\\d|2[0-7]))\\.\\d{1,3}",
- "202\\.176\\.(?:1[6-9]|2\\d|3[01])\\.\\d{1,3}",
- "202\\.216\\.(?:\\d|1[0-5])\\.\\d{1,3}",
- "210\\.157\\.(?:19[2-9]|2(?:[01]\\d|2[0-3]))\\.\\d{1,3}",
- "211\\.133\\.(?:[6-8]\\d|9[01])\\.\\d{1,3}",
- "211\\.7\\.(?:[9][6-9]|1(?:[01]\\d|2[0-7]))\\.\\d{1,3}",
- "219\\.105\\.1(?:4[4-9]|5\\d)\\.\\d{1,3}",
- "219\\.105\\.(?:19[2-9]|2\\d{2})\\.\\d{1,3}",
- "219\\.106\\.(?:\\d{1,2}|1(?:[01]\\d|2[0-7]))\\.\\d{1,3}"
- );
-
- #モバイル回線のslip_id
- my @mobile_ids = (
- "Sr",
- "Sp",
- "Sa",
- "Sd",
- "SD",
- "MM"
- );
-
- #モバイル回線のニックネーム
- my @mobile_nicknames = (
- "オッペケ${mobile_nickname_end}",
- "ササクッテロ${mobile_nickname_end}",
- "アウアウアー${mobile_nickname_end}",
- "アウアウイー${mobile_nickname_end}",
- "アウアウウー${mobile_nickname_end}",
- "アウアウエー${mobile_nickname_end}",
- "アウアウオー${mobile_nickname_end}",
- "アウアウカー${mobile_nickname_end}",
- "スプー${mobile_nickname_end}",
- "スプッッ${mobile_nickname_end}",
- "スップ${mobile_nickname_end}",
- "スッップ${mobile_nickname_end}",
- "スププ${mobile_nickname_end}",
- "スフッ${mobile_nickname_end}",
- "ペラペラ${mobile_nickname_end}",
- "エアペラ${mobile_nickname_end}",
- "ブーイモ${mobile_nickname_end}",
- "ベーイモ${mobile_nickname_end}",
- "オイコラミネオ${mobile_nickname_end}",
- "ワントンキン${mobile_nickname_end}",
- "ワンミングク${mobile_nickname_end}",
- "バットンキン${mobile_nickname_end}",
- "バッミングク${mobile_nickname_end}",
- "ラクッペペ${mobile_nickname_end}",
- "ラクラッペ${mobile_nickname_end}",
- "アウアウクー${mobile_nickname_end}",
- "ドコグロ${mobile_nickname_end}",
- "ドナドナー${mobile_nickname_end}",
- "トンモー${mobile_nickname_end}",
- "アメ${mobile_nickname_end}",
- "ニャフニャ${mobile_nickname_end}",
- "イルクン${mobile_nickname_end}",
- "ゲマー${mobile_nickname_end}",
- "フリッテル${mobile_nickname_end}"
- );
-
- #公衆Wi-Fiのリモホ・ネットワーク名・IP
- my @fwifi_remoho = (
- ".*\\.m-zone\\.jp",
- "\\d+\\.wi-fi\\.kddi\\.com",
- ".*\\.wi-fi\\.wi2\\.ne\\.jp",
- ".*\\.family-wifi\\.jp"
- );
- my @fwifi_whois = (
- "INPLUS-FWIFI",
- "FON"
- );
- my $lawson_ip = "210\\.227\\.19\\.[67]\\d\$";
- #公衆Wi-FiのID
- my $fwifi_id = "FF";
- #公衆Wi-Fiのニックネーム
- my @fwifi_nicknames = (
- "エムゾネ${fixed_nickname_end}[公衆]",
- "アウウィフ${fixed_nickname_end}[公衆]",
- "ワイーワ2${fixed_nickname_end}[公衆]",
- "ファミマ${fixed_nickname_end}[公衆]",
- "フォンフォン${fixed_nickname_end}[公衆]",
- "マクド${fixed_nickname_end}[公衆]"
- );
-
- #逆引き判定
- if ($slip_remoho eq "none") { #逆引きできない場合
- my $isunknown = "yes";
- my $res = whois($ip_addr);
-
- #モバイル回線判定
- my $mobile_nickname_idx = -1;
- for my $name (@mobile_whois) {
- if ($res =~ /.*${name}.*/) {
- $slip_id = "MM";
- $slip_nickname = $mobile_nicknames[$mobile_nickname_idx];
- $slip_aa = $slip_id;
- $slip_bb = $slip_ip;
- $isunknown = "no";
- last;
- }
- $mobile_nickname_idx--;
- }
- #楽天モバイル(MNO)判定
- if ($isunknown eq "yes") {
- for my $name (@rakuten_mno_ip) {
- if ($ip_addr =~ /${name}/) {
- $slip_id = "MM";
- $slip_nickname = "テテンテンテンM";
- $slip_aa = $slip_id;
- $slip_bb = $slip_ip;
- $isunknown = "no";
- last;
- }
- }
- }
-
- #公衆判定
- if ($isunknown eq "yes") {
- my $fwifi_nickname_idx = -1;
- for my $name (@fwifi_whois) {
- if ($res =~ /.*${name}.*/) {
- $slip_id = $fwifi_id;
- $slip_nickname = $fwifi_nicknames[$fwifi_nickname_idx];
- $slip_aa = $slip_id;
- $slip_bb = $slip_ip;
- $isunknown = "no";
- last;
- }
- $fwifi_nickname_idx--;
- }
- }
- #ローソン判定
- if ($isunknown eq "yes") {
- if ($ip_addr =~ /${lawson_ip}/) {
- $slip_id = "FF";
- $slip_nickname = "ローソン${fixed_nickname_end}[公衆]";
- $slip_aa = $slip_id;
- $slip_bb = $slip_ip;
- $isunknown = "no";
- }
- }
-
- #逆引き不可能 アンタダレ
- if ($isunknown eq "yes") {
- $slip_id = "Un";
- $slip_nickname = "アンタダレ${fixed_nickname_end}";
+ # ローカル環境
+ if ($ipAddr eq '127.0.0.1'){
+ $slip_id = 'lc';
+ $idEnd = 'l';
+ $slip_nickname = "ローカル${fixed_nickname_end}";
$slip_aa = $slip_id;
$slip_bb = $slip_ip;
}
- }else{ #逆引きできる場合
- my $ismobile = 0;
- #モバイル回線判定
- my $mobile_id_idx = 0;
- my $mobile_nickname_idx = 0;
- for my $name (@mobile_remoho) {
- if ($remoho =~ /^${name}$/) {
- $slip_id = $mobile_ids[$mobile_id_idx];
- $slip_nickname = $mobile_nicknames[$mobile_nickname_idx];
- $slip_aa = $slip_id;
- $slip_bb = $slip_ip;
- $ismobile = 1;
- last;
- }
- if ($mobile_id_idx < 2 || $mobile_nickname_idx =~ /^(7|9|15)$/) {
- $mobile_id_idx++;
- }
- $mobile_nickname_idx++;
- }
-
- #公衆判定
- if ($ismobile == 0) {
- my $fwifi_nickname_idx = 0;
- for my $name (@fwifi_remoho) {
- if ($remoho =~ /^${name}$/) {
- $slip_id = $fwifi_id;
- $slip_nickname = $fwifi_nicknames[$fwifi_nickname_idx];
- $slip_aa = $slip_id;
- $slip_bb = $slip_ip;
- last;
- }
- $fwifi_nickname_idx++;
- }
- }
-
- #社畜判定
- if ($ismobile == 0) {
- if ($remoho =~ /^.+\.co\.jp$/) {
- $slip_nickname = "シャチーク${fixed_nickname_end}";
- }
- }
- }
-
- #bbs_slipを生成
- my $slip_result = '';
- if($bbsslip eq 'vvv'){
- $slip_result = ${slip_nickname};
- }
- elsif($bbsslip eq 'vvvv'){
- $slip_result = "${slip_nickname} [${ip_addr}]";
- }
- elsif($bbsslip eq 'vvvvv'){
- $slip_result = "${slip_nickname} ${slip_aa}${slip_bb}-${slip_cccc}";
- }
- elsif($bbsslip eq 'vvvvvv'){
- $slip_result = "${slip_nickname} ${slip_aa}${slip_bb}-${slip_cccc} [${ip_addr}]";
}
- return $slip_result;
+ # 匿名環境の場合は末尾が"8"になる
+ return $slip_nickname,$slip_aa,$slip_bb,$slip_cccc,$idEnd;
}
+
#============================================================================================================
# モジュール終端
#============================================================================================================
diff --git a/test/module/system.pl b/test/module/system.pl
index 702f67e..e92e819 100644
--- a/test/module/system.pl
+++ b/test/module/system.pl
@@ -255,7 +255,7 @@ sub InitSystemValue
'BBSPATH' => '..', # 掲示板設置パス
'SITENAME' => '', # サイトの名前
'DEBUG' => 0, # デバグモード
- 'VERSION' => 'ex0ch BBS 0.9.1 20240313', # CGIバージョン
+ 'VERSION' => 'ex0ch BBS 0.9.2 20240503', # CGIバージョン
'PM-DAT' => 0644, # datパーミション
'PM-STOP' => 0444, # スレストパーミション
'PM-TXT' => 0644, # TXTパーミション
@@ -297,16 +297,21 @@ sub InitSystemValue
# DNSBL設定
'DNSBL_TOREXIT' => 0, # torexit.dan.me.uk
- 'DNSBL_S5H' => 0, # all.s5h.net
+ 'DNSBL_S5H' => 0, # all.s5h.net
'DNSBL_DRONEBL' => 0, # dnsbl.dronebl.org
'SECURITY_KEY' => '', # セキュリティキー(初回起動時に自動設定されます)
'LAST_FLUSH' => '', # 定期的に動かす必要がある機能用
- 'CAPTCHA' => '', # キャプチャの種類
- 'CAPTCHA_SITEKEY' => '', # Captchaサイトキー
+ 'CAPTCHA' => '', # キャプチャの種類
+ 'CAPTCHA_SITEKEY' => '', # Captchaサイトキー
'CAPTCHA_SECRETKEY' => '', # Captchaシークレットキー
- 'PROXYCHECK_APIKEY' => '', # ProxyCheck.io APIキー
+ 'PROXYCHECK_APIKEY' => '', # ProxyCheck.io APIキー
+
+ 'ADMINCAP' => '',
+ 'SEARCHCAP' => '',
+
+ 'LASTMOD' => '',
'IMGTAG' => 0, # 画像リンクをIMGタグに変換
'CSP' => 0,
diff --git a/test/read.cgi b/test/read.cgi
index 32d76f3..37914a2 100755
--- a/test/read.cgi
+++ b/test/read.cgi
@@ -232,7 +232,6 @@ sub PrintReadHead
HTML
$Page->Print('') if ($Set->Get('BBS_TWITTER'));
- $Page->Print('') if ($Set->Get('BBS_IMGUR'));
if($Set->Get('BBS_CAPTCHA')){
$Page->Print('') if ($Sys->Get('CAPTCHA') eq 'h-captcha');
$Page->Print('') if ($Sys->Get('CAPTCHA') eq 'g-recaptcha');
@@ -616,7 +615,6 @@ sub PrintResponse
my $aa='';
# URLと引用個所の適応
- $Conv->ConvertImgur(\$elem[3])if($Set->Get('BBS_IMGUR') eq 'checked');
$Conv->ConvertMovie(\$elem[3])if($Set->Get('BBS_MOVIE') eq 'checked');
$Conv->ConvertTweet(\$elem[3])if($Set->Get('BBS_TWITTER') eq 'checked');
$Conv->ConvertURL($Sys, $Set, 0, \$elem[3])if($Sys->Get('URLLINK') eq 'TRUE');
@@ -748,83 +746,6 @@ HTML
}
-#------------------------------------------------------------------------------------------------------------
-#
-# read.cgi探索画面表示
-# -------------------------------------------------------------------------------------
-# @param $CGI
-# @param $Page
-# @return なし
-#
-#------------------------------------------------------------------------------------------------------------
-sub PrintReadSearch
-{
- my ($CGI, $Page) = @_;
-
- return if (PrintDiscovery($CGI, $Page));
-
- my $Sys = $CGI->{'SYS'};
- my $Set = $CGI->{'SET'};
- my $Conv = $CGI->{'CONV'};
- my $Dat = $CGI->{'DAT'};
-
- my $nameCol = $Set->Get('BBS_NAME_COLOR');
- my $var = $Sys->Get('VERSION');
- my $cgipath = $Sys->Get('CGIPATH');
- my $bbs = $Sys->Get('BBS_ABS') . '/';
- my $server = $Sys->Get('SERVER');
-
- # エラー用datの読み込み
- $Dat->Load($Sys, $Conv->MakePath('.'.$Sys->Get('DATA').'/2000000000.dat'), 1);
- my $size = $Dat->Size();
-
- # 存在しないので404を返す。
- $Page->Print("Status: 404 Not Found\n");
-
- PrintReadHead($CGI, $Page);
-
- $Page->Print("\n\n");
- $Page->Print("
■掲示板に戻る■ \n");
- $Page->Print("
\n");
-
- $Page->Print(" \n\n");
- $Page->Print("指定されたスレッドは存在しません \n\n");
-
- $Page->Print("\n\n");
-
- for my $i (0 .. $size - 1) {
- my $pDat = $Dat->Get($i);
- my @elem = split(/<>/, $$pDat);
- $Page->Print(' ' . ($i + 1) . ' :');
-
- # メール欄有り
- if ($elem[1] eq '') {
- $Page->Print("$elem[0] ");
- }
- # メール欄無し
- else {
- $Page->Print("$elem[0] ");
- }
- $Page->Print(":$elem[2] \n $elem[3] \n");
- }
- $Page->Print(" \n\n");
-
- $Dat->Close();
-
- $Page->Print(" \n\n");
-
- $Page->Print(<
-READ.CGI - $var
-EXぜろちゃんねる
-
-
-
-
-HTML
-
-}
-
#------------------------------------------------------------------------------------------------------------
#
# read.cgiエラー表示
diff --git a/test/search.cgi b/test/search.cgi
index 4233564..980fce2 100755
--- a/test/search.cgi
+++ b/test/search.cgi
@@ -16,6 +16,8 @@ use open IO => ':encoding(cp932)';
use warnings;
use CGI::Carp qw(fatalsToBrowser warningsToBrowser);
no warnings 'once';
+use JSON;
+use LWP::UserAgent;
BEGIN { use lib './perllib'; }
@@ -32,7 +34,7 @@ exit(SearchCGI());
#------------------------------------------------------------------------------------------------------------
sub SearchCGI
{
- my ($Sys, $Page, $Form, $BBS);
+ my ($Sys, $Page, $Form, $BBS, $capt);
require './module/system.pl';
require './module/buffer_output.pl';
@@ -46,10 +48,11 @@ sub SearchCGI
$Form->DecodeForm(1);
$Sys->Init();
$BBS->Load($Sys);
+ $capt = Certification_Captcha($Sys,$Form) if $Sys->Get('SEARCHCAP');
PrintHead($Sys, $Page, $BBS, $Form);
# 検索ワードがある場合は検索を実行する
- if ($Form->Get('WORD', '') ne '') {
+ if ($Form->Get('WORD', '') ne '' && !$capt) {
Search($Sys, $Form, $Page, $BBS);
}
PrintFoot($Sys, $Page);
@@ -110,7 +113,18 @@ sub PrintHead
検索@0chPlus
+HTML
+
+ if($Sys->Get('SEARCHCAP')){
+ $Page->Print('') if ($Sys->Get('CAPTCHA') eq 'h-captcha');
+ $Page->Print('') if ($Sys->Get('CAPTCHA') eq 'g-recaptcha');
+ $Page->Print('') if ($Sys->Get('CAPTCHA') eq 'cf-turnstile');
+ }
+ my $sitekey = $Sys->Get('CAPTCHA_SITEKEY');
+ my $classname = $Sys->Get('CAPTCHA');
+ my $Captcha = $Sys->Get('SEARCHCAP') ? "
" : '';
+ $Page->Print(<
@@ -202,6 +216,7 @@ HTML
+ $Captcha
@@ -456,3 +471,61 @@ sub PrintSystemError
HTML
}
+
+#------------------------------------------------------------------------------------------------------------
+#
+# 改造版で追加
+# Captchaの認証
+# -------------------------------------------------------------------------------------
+# @param なし
+# @return 規制通過なら0を返す
+# 規制チェックにかかったらエラーコードを返す
+#
+#------------------------------------------------------------------------------------------------------------
+sub Certification_Captcha {
+ my ($Sys,$Form) = @_;
+ my ($captcha_response,$url);
+
+ my $captcha_kind = $Sys->Get('CAPTCHA');
+ my $secretkey = $Sys->Get('CAPTCHA_SECRETKEY');
+ if($captcha_kind eq 'h-captcha'){
+ $captcha_response = $Form->Get('h-captcha-response');
+ $url = 'https://api.hcaptcha.com/siteverify';
+ }elsif($captcha_kind eq 'g-recaptcha'){
+ $captcha_response = $Form->Get('g-recaptcha-response');
+ $url = 'https://www.google.com/recaptcha/api/siteverify';
+ }elsif($captcha_kind eq 'cf-turnstile'){
+ $captcha_response = $Form->Get('cf-turnstile-response');
+ $url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
+ }else{
+ return 0;
+ }
+
+ if($captcha_response){
+ my $ua = LWP::UserAgent->new();
+ my $response = $ua->post($url,{
+ secret => $secretkey,
+ response => $captcha_response,
+ remoteip => $ENV{'REMOTE_ADDR'},
+ });
+ if ($response->is_success()) {
+ my $json_text = $response->decoded_content();
+
+ # JSON::decode_json関数でJSONテキストをPerlデータ構造に変換
+ my $out = decode_json($json_text);
+
+ if ($out->{success} eq 'true') {
+ return 0;
+ }else{
+ return 1;
+ }
+ } else {
+ # Captchaを素通りする場合、HTTPS関連のエラーの疑いあり
+ # LWP::Protocol::httpsおよびNet::SSLeayが入っているか確認
+ # このエラーの場合、スルー
+ return 0;
+ }
+ }else{
+ return 1;
+ }
+}