function plugin_pcomment_action() { global $vars, $_string; // if (PKWK_READONLY) die_message('PKWK_READONLY prohibits editing'); if (Auth::check_role('readonly')) { Utility::dieMessage(sprintf($_string['error_prohibit'], 'PKWK_READONLY')); } if (!isset($vars['msg']) || empty($vars['msg'])) { return array(); } // Validate if (is_spampost(array('msg'))) { Utility::dump(); return array('msg' => '', 'body' => ''); // Do nothing } $refer = isset($vars['refer']) ? $vars['refer'] : ''; if (!is_page($refer) && Auth::is_check_role(PKWK_CREATE_PAGE)) { Utility::dieMessage(sprintf($_string['error_prohibit'], 'PKWK_CREATE_PAGE')); } $retval = plugin_pcomment_insert(); if ($retval['collided']) { $vars['page'] = $refer; return $retval; } $hash = isset($vars['reply']) ? '#pcmt' . Utility::htmlsc($vars['reply']) : ''; Utility::redirect(get_page_location_uri($refer) . $hash); }
function honeypot_write() { Utility::dump(); }
function plugin_edit_honeypot() { if (isset($vars['ajax'])) { $headers = Header::getHeaders('application/json'); Header::writeResponse($headers, 200, Json::encode(array('posted' => false, 'message' => 'Sorry your post has been prohibited.', 'taketime' => Time::getTakeTime()))); exit; } // SPAM Logging Utility::dump(); // Same as "Cancel" action return plugin_edit_cancel(); }
/** * ページを書き込む * @param string $str 書き込むデーター * @param boolean $notimestamp タイムスタンプを更新するかのフラグ * @return void */ public function set($str, $keeptimestamp = false) { global $use_spam_check, $_string, $vars, $_title, $whatsnew, $whatsdeleted; // roleのチェック if (Auth::check_role('readonly')) { return; } // Do nothing if (Auth::is_check_role(PKWK_CREATE_PAGE)) { Utility::dieMessage(sprintf($_strings['error_prohibit'], 'PKWK_READONLY'), 403); } // 簡易スパムチェック(不正なエンコードだった場合ここでエラー) if (isset($vars['encode_hint']) && $vars['encode_hint'] !== PKWK_ENCODING_HINT) { Utility::dump(); Utility::dieMessage($_string['illegal_chars'], 403); } // ポカミス対策:配列だった場合文字列に変換 if (is_array($str)) { $str = join("\n", $str); } // 入力データーを整形(※string型です) $postdata = Rules::make_str_rules($str); // 過去のデーターを取得 $oldpostdata = self::has() ? self::get(TRUE) : ''; // 差分を生成(ここでの差分データーはAkismetでも使う) $diff = new Diff($oldpostdata, $postdata); $diffobj = new LineDiff(); $diffdata = $diffobj->str_compare($oldpostdata, $postdata); // ログイン済みもしくは、自動更新されるページである $has_not_permission = Auth::check_role('role_contents_admin'); // 未ログインの場合、S25Rおよび、DNSBLチェック if ($has_not_permission) { $ip_filter = new IpFilter(); //if ($ip_filter->isS25R()) Utility::dieMessage('S25R host is denied.'); // 簡易スパムチェック if (Utility::isSpamPost()) { Utility::dump(); Utility::dieMessage('Writing was limited. (Blocking SPAM)'); } if (isset($use_spam_check['page_remote_addr']) && $use_spam_check['page_remote_addr'] !== 0) { // DNSBLチェック $listed = $ip_filter->checkHost(); if ($listed !== false) { Utility::dump('dnsbl'); Utility::dieMessage(sprintf($_strings['prohibit_dnsbl'], $listed), $_title['prohibit'], 400); } } if (isset($use_spam_check['page_contents']) && $use_spam_check['page_contents'] !== 0) { // URLBLチェック $reason = self::checkUriBl($diff); if ($reason !== false) { Utility::dump($reason); Utility::dieMessage($_strings['prohibit_uribl'], $_title['prohibit'], 400); } } // 匿名プロクシ if ($use_spam_check['page_write_proxy'] && ProxyChecker::is_proxy()) { Utility::dump('proxy'); Utility::dieMessage($_strings['prohibit_proxy'], $_title['prohibit'], 400); } // Akismet global $akismet_api_key; if (isset($use_spam_check['akismet']) && $use_spam_check['akismet'] !== 0 && !empty($akismet_api_key)) { $akismet = new Akismet($akismet_api_key, Router::get_script_absuri()); if ($akismet->verifyKey($akismet_api_key)) { // 送信するデーターをセット $akismet_post = array('user_ip' => REMOTE_ADDR, 'user_agent' => $_SERVER['HTTP_USER_AGENT'], 'comment_type' => 'comment', 'comment_author' => isset($vars['name']) ? $vars['name'] : 'Anonymous', 'comment_content' => $postdata); // if ($use_spam_check['akismet'] === 1){ // // 差分のみをAkismetに渡す // foreach ($diff->getSes() as $key=>$line){ // if ($key !== $diff::SES_ADD) continue; // $added_data[] = $line; // } // $akismet_post['comment_content'] = join("\n",$added_data); // unset($added_data); // } if ($akismet->isSpam($akismet_post)) { Utility::dump('akismet'); Utility::dieMessage($_strings['prohibit_akismet'], $_title['prohibit'], 400); } } else { Utility::dieMessage('Akismet API key does not valied.', 500); } } // captcha check if (isset($use_spam_check['captcha']) && $use_spam_check['captcha'] !== 0) { Captcha::check(false); } } // 現時点のページのハッシュを読む $old_digest = $this->wiki->has() ? $this->wiki->digest() : 0; // オリジナルが送られてきている場合、Wikiへの書き込みを中止し、競合画面を出す。 // 現時点のページのハッシュと、送信されたページのハッシュを比較して異なる場合、 // 自分が更新している間に第三者が更新した(=競合が起きた)と判断する。 $collided = isset($vars['digest']) && $old_digest !== 0 && $vars['digest'] !== $old_digest; if ($collided && isset($vars['original'])) { return array('msg' => $_string['title_collided'], 'body' => $_string['msg_collided'] . Utility::showCollision($oldpostdata, $postdata, $vars['original']) . Utility::editForm($this->page, $postdata, false)); } // add client info to diff // $diffdata[] = '// IP:"'. REMOTE_ADDR . '" TIME:"' . UTIME . '" REFERER:"' . $referer . '" USER_AGENT:"' . $user_agent. "\n"; FileFactory::Diff($this->page)->set($diffdata); unset($oldpostdata, $diff, $diffdata); // Logging postdata (Plus!) if (self::POST_LOGGING === TRUE) { Utility::dump(self::POST_LOG_FILENAME); } // 入力が空の場合、削除とする if (empty($str)) { // Wikiページを削除 $ret = $this->wiki->set(''); Recent::set($this->page, true); } else { // Wikiを保存 $ret = $this->wiki->set($postdata, $keeptimestamp); // 最終更新を更新 Recent::set($this->page); } if ($this->page !== $whatsnew || $this->page !== $whatsdeleted || !$this->isHidden()) { // バックアップを更新 Factory::Backup($this->page)->set(); // 更新ログをつける LogFactory::factory('update', $this->page)->set(); if (!$keeptimestamp && !empty($str)) { // weblogUpdates.pingを送信 $ping = new Ping($this->page); $ping->send(); } } // 簡易競合チェック if ($collided) { return array('msg' => $_string['title_collided'], 'body' => $_string['msg_collided_auto']); } }
/** * CAPTCHAチェック * @param boolean $save セッションに保存するか * @param string $message エラーメッセージの内容 */ public static function check($save = true, $message = '', $multipart = false) { global $recaptcha_public_key, $recaptcha_private_key, $vars, $session, $_string, $_button; // Captchaのセッション名(ticketとリモートホストの加算値。ticketはプログラマーから見てもわからない) $session_name = self::CAPTCHA_SESSION_PREFIX . md5(Utility::getTicket() . REMOTE_ADDR); if ($save && $session->offsetExists($session_name) && $session->offsetGet($session_name) === true) { // CAPTCHA認証済みの場合 // return array('msg'=>'CAPTCHA','body'=>'Your host was already to challenged.'); return; } if (isset($recaptcha_public_key) && isset($recaptcha_private_key)) { // reCaptchaを使う場合 $captcha = new ReCaptcha($recaptcha_public_key, $recaptcha_private_key); // 入力があった場合 if (isset($vars['recaptcha_challenge_field']) && isset($vars['recaptcha_response_field'])) { if ($captcha->verify($vars['recaptcha_challenge_field'], $vars['recaptcha_response_field'])) { if ($save) { // captcha認証済セッションを保存 $session->offsetSet($session_name, true); // captcha認証済セッションの有効期間を設定 $session->setExpirationSeconds($session_name, self::CAPTCHA_SESSION_EXPIRE); } // return array('msg'=>'CAPTCHA','body'=>'OK!'); return; // ここで書き込み処理に戻る } else { // CAPTCHA認証失敗ログをつける Utility::dump('captcha'); $message = $_string['captcha_failure']; } // チャレンジ&レスポンスデーターを削除 unset($vars['recaptcha_challenge_field'], $vars['recaptcha_response_field']); } // 念のためcaptcha認証済みセッションを削除 $session->offsetUnset($session_name); // reCaptchaの設定をオーバーライド // 言語設定 $captcha->setOption('lang', substr(LANG, 0, 2)); // テーマ $captcha->setOption('theme', self::RECAPTCHA_THEME); $form = $captcha->getHTML(); } else { // reCaptchaを使わない場合 $captcha_dir = CACHE_DIR . self::CAPTCHA_IMAGE_DIR_NAME . DIRECTORY_SEPARATOR; self::mkdir_r($captcha_dir); if (isset($vars['challenge_field']) && isset($vars['response_field'])) { // Captchaチェック処理 if ($session->offsetGet(self::CAPTCHA_SESSION_PREFIX . $vars['response_field']) === strtolower($vars['challenge_field'])) { if ($save) { // captcha認証済セッションを保存 $session->offsetSet($session_name, true); // captcha認証済セッションの有効期間を設定 $session->setExpirationSeconds($session_name, self::CAPTCHA_SESSION_EXPIRE); } // 認証用セッションの削除 $session->offsetUnset(self::CAPTCHA_SESSION_PREFIX . $vars['response_field']); if (file_exists($captcha_dir . $vars['response_field'] . '.png')) { // キャッシュ画像を削除 unlink($captcha_dir . $vars['response_field'] . '.png'); } // return array('msg'=>'CAPTCHA','body'=>'OK!'); return; // ここで書き込み処理に戻る } else { // CAPTCHA認証失敗ログをつける Utility::dump('captcha'); $message = $_string['captcha_failure']; } // チャレンジ&レスポンスデーターを削除 unset($vars['response_field'], $vars['challenge_field']); } // 念のためcaptcha認証済みセッションを削除 $session->offsetUnset($session_name); // GDが使える場合、画像認証にする if (extension_loaded('gd')) { // フォルダが存在しない場合作成を試みる if (!file_exists($captcha_dir)) { mkdir($captcha_dir); chmod(0777, $captcha_dir); } // 古い画像を削除する $di = new DirectoryIterator($captcha_dir); foreach ($di as $f) { if (!$f->isFile()) { // ファイルでない continue; } if (time() - $f->getMTime() > self::CAPTCHA_TIMEOUT) { // タイムアウト時間よりも古いファイルは削除する unlink($f->getRealPath()); } } /* $handle = opendir($captcha_dir,null); if ($handle) { while( $entry = readdir($handle) ){ if( $entry !== '.' && $entry !== '..'){ $f = realpath($captcha_dir . $entry); if (time() - filectime($f) > self::CAPTCHA_TIMEOUT) unlink($f); } } closedir($handle); } */ // 画像CAPTCHAを生成 $captcha = new Image(array('wordLen' => self::CAPTCHA_WORD_LENGTH, 'timeout' => self::CAPTCHA_TIMEOUT, 'font' => LIB_DIR . self::CAPTCHA_IMAGE_FONT, 'ImgDir' => $di->getPath())); $captcha->generate(); // cache_refプラグインを用いて画像を表示 $form = '<img src="' . Router::get_cmd_uri('cache_ref', null, null, array('src' => self::CAPTCHA_IMAGE_DIR_NAME . '/' . $captcha->getId() . '.png')) . '" height="' . $captcha->getHeight() . '" width="' . $captcha->getWidth() . '" alt="' . Utility::htmlsc($captcha->getImgAlt()) . '" /><br />' . "\n"; // 画像を取得 } else { // GDがない場合アスキーアート $captcha = new Figlet(array('wordLen' => self::CAPTCHA_WORD_LENGTH, 'timeout' => self::CAPTCHA_TIMEOUT)); $captcha->generate(); // \が¥に見えるのでフォントを明示的に指定。 $form = '<pre style="font-family: Monaco, Menlo, Consolas, \'Courier New\' !important;">' . Utility::htmlsc($captcha->getFiglet()->render($captcha->getWord())) . '</pre>' . "\n" . '<br />' . "\n"; // AAを取得 } // 識別子のセッション名 $response_session = self::CAPTCHA_SESSION_PREFIX . $captcha->getId(); // 識別子のセッションを発行 $session->offsetSet($response_session, $captcha->getWord()); // captchaの有効期間 $session->setExpirationSeconds($response_session, self::CAPTCHA_TIMEOUT); $form .= '<input type="hidden" name="response_field" value="' . $captcha->getId() . '" />' . "\n"; $form .= '<div class="input-group">'; $form .= '<span class="input-group-addon"><span class="fa fa-key"></span></span>'; $form .= '<input type="text" class="form-control" name="challenge_field" maxlength="' . $captcha->getWordLen() . '" size="' . $captcha->getWordLen() . '" />'; $form .= '<span class="input-group-btn">'; $form .= '<button type="submit" class="btn btn-primary" value="submit">' . $_button['submit'] . '</button>'; $form .= '</span>'; $form .= '</div>'; // $form .= $captcha->getWord(); } // $ret[] = $session->offsetExists($session_name) ? 'true' : 'false'; // $ret[] = Zend\Debug\Debug::Dump($vars); // $ret[] = Zend\Debug\Debug::Dump($captcha->getSession()); if (!empty($message)) { $ret[] = '<p class="alert alert-warning"><span class="fa fa-warning"></span>' . $message . '</p>'; } // PostIdが有効な場合 if (isset($use_spam_check['multiple_post']) && $use_spam_check['multiple_post'] === 1) { $vars['postid'] = PostId::generate($vars['cmd']); } $ret[] = '<fieldset>'; $ret[] = '<legend>CAPTCHA</legend>'; $ret[] = '<p>' . $_string['captcha_msg'] . '</p>'; // フォームを出力 $ret[] = '<form method="post" action="' . Router::get_script_uri() . '" method="post" class="form-inline">'; //unset($vars['ajax']); // ストアされている値を出力 foreach ($vars as $key => $value) { if ($key === 'ajax') { continue; } if (strpos($key, 'attach_file', 0) === 0) { // ファイルフォームだった場合。(あまりいい実装ではない) $ret[] = '<input type="file" name="' . $key . '" value="' . (!empty($value) ? Utility::htmlsc($value) : '') . '" class="hidden" />'; continue; } $ret[] = '<input type="hidden" name="' . $key . '" value="' . (!empty($value) ? Utility::htmlsc($value) : '') . '" />'; } // CAPTCHAフォームを出力 $ret[] = $form; $ret[] = '</form>'; $ret[] = '</fieldset>'; // return array('msg'=>'CAPTCHA','body'=>join("\n",$ret)); new Render('CAPTCHA', join("\n", $ret)); exit; }