isCheckRequirementsNeeded = $pIsCheckRequirementsNeeded; $this->sessionData = new CSecurityTemporaryStorage(self::SESSION_DATA_KEY, $pIsFirstStart); $isOk = $this->initializeAvailableTests(); if($isOk) { $isOk = $this->initializeNeededTests($pTests); } if(!$isOk) { throw new Exception('Error while initializing'); } } /** * Start testing and return results * @param array $pParams * @return array|bool */ public function startTesting($pParams = array()) { $testName = $this->getCurrentTestName(); if(!$testName) return false; if(!is_callable($testName, "check")) return false; $test = new $testName; if(!($test instanceof CSecurityBaseTest)) return false; try { $testParams = $this->makeParamsForTest($testName, $pParams); if($this->isCheckRequirementsNeeded) $test->checkRequirements($testParams); $result = $test->check($testParams); } catch(CSecurityRequirementsException $exception) { $result = array( "name" => $test->getName(), "status" => true, "fatal_error_text" => $exception->getMessage() ); } if($result) { if(!isset($result["in_progress"]) || !$result["in_progress"]) { $this->finalizeLastTest(); if(isset($result["timeout"])) $result["timeout"] = 0; } } return $result; } /** * Run several tests * @param string|array $pType * @param bool $pIsFirstStart * @param bool $pIsCheckRequirementsNeeded * @return array|bool */ public static function runTestPackage($pType = "", $pIsFirstStart = false, $pIsCheckRequirementsNeeded = true) { try { $tests = CSecurityTestsPackage::getTestsPackage($pType); $dispatcher = new CSecuritySiteChecker($tests, $pIsFirstStart, $pIsCheckRequirementsNeeded); $result = $dispatcher->startTesting(); $result["percent"] = $dispatcher->getPercent(); if($dispatcher->isAllTestCompleted()) { $result["all_done"] = "Y"; self::clearCache(); } else { $result["all_done"] = "N"; } } catch(Exception $e) { $result = array("all_done" => "Y"); } return $result; } /** * Return current percent of complete testing * @return int */ public function getPercent() { $totalTestsCount = count($this->neededTests); $remainingTestsCount = count($this->sessionData->getArray("NEEDED_TESTS")); return intval((($totalTestsCount - $remainingTestsCount) / $totalTestsCount) * 100); } /** * Return saved testing results * @param array $pFilter * @param int $pMaxCount * @return bool|CDBResult */ protected static function getList($pFilter = array(), $pMaxCount = 1) { /** @global CDataBase $DB */ global $DB; $sqlQuery = "SELECT RESULTS, ".$DB->DateToCharFunction("TEST_DATE", "SHORT")." TEST_DATE FROM ".self::$tableName; if (is_array($pFilter) && !empty($pFilter)) { $sqlWhereQuery = array(); foreach($pFilter as $key => $value) { if (is_string($value) && $value != "" && in_array($key, self::$dbFields)) { $sqlWhereQuery[] = $key."='".$DB->ForSql($value)."'"; } } if(!empty($sqlWhereQuery)) { $sqlQuery .= " WHERE ".GetFilterSqlSearch($sqlWhereQuery); } } $sqlQuery .= " ORDER BY ID desc"; $sqlQuery = $DB->TopSql($sqlQuery, $pMaxCount); $arResult = $DB->Query($sqlQuery, false, "FILE: ".__FILE__."
LINE: ".__LINE__); return $arResult; } /** * Add new testing results ro DB * @param array $pResults * @return bool */ public static function addResults($pResults) { if (!isset($pResults) || !is_array($pResults)) return false; /** @global CDataBase $DB */ global $DB; $fields = array("RESULTS" => serialize($pResults)); $insertValues = $DB->PrepareInsert(self::$tableName, $fields); $testingDate = self::getFormatedDate(time()); $sqlQuery = "INSERT INTO ".self::$tableName."(".$insertValues[0].", TEST_DATE) ". "VALUES(".$insertValues[1].", ".$testingDate.")"; /** @var CDBResult $queryResult */ $queryResult = $DB->QueryBind($sqlQuery, $fields); if($queryResult && $queryResult->result) { return true; } else { return false; } } /** * Return last saved testing results * @return array */ public static function getLastTestingInfo() { /** @global CCacheManager $CACHE_MANAGER*/ global $CACHE_MANAGER; $cacheId = self::CACHE_BASE_ID."_last_results"; if($CACHE_MANAGER->read(self::CHECKING_REPEAT_TIME, $cacheId, self::CACHE_DIR)) { $lastResult = $CACHE_MANAGER->get($cacheId); } else { $lastResult = array(); $dbResults = self::getList(); if($dbResults) { $result = $dbResults->fetch(); if($result && isset($result["RESULTS"])) { if(checkSerializedData($result["RESULTS"])) { $lastResult["results"] = unserialize($result["RESULTS"], ['allowed_classes' => false]); } } if($result && isset($result["TEST_DATE"])) { $lastResult["test_date"] = $result["TEST_DATE"]; } } $CACHE_MANAGER->set($cacheId, $lastResult); } return (is_array($lastResult) ? $lastResult: array()) ; } /** * */ public static function clearTemporaryData() { CSecurityTemporaryStorage::ClearAll(); } /** * Return true if administrator must run testing * @return bool */ public static function isNewTestNeeded() { /** * @global CCacheManager $CACHE_MANAGER * @global CDataBase $DB */ global $DB, $CACHE_MANAGER; $cacheId = self::CACHE_BASE_ID."_last_check"; if($CACHE_MANAGER->read(self::CHECKING_REPEAT_TIME, $cacheId, self::CACHE_DIR)) { $result = $CACHE_MANAGER->get($cacheId); } else { $minimalDate = self::getFormatedDate(time() - self::CHECKING_REPEAT_TIME); $sqlQuery = " SELECT COUNT(ID) AS COUNT FROM ".self::$tableName." WHERE TEST_DATE >= ".$minimalDate." "; $res = $DB->query($sqlQuery, false, $err_mess = "FILE: ".__FILE__."
LINE: ".__LINE__); $result = true; if($count = $res->fetch()) { if($count["COUNT"] > 0) { $result = false; } } $CACHE_MANAGER->set($cacheId, $result); } return $result; } /** * @param $timestamp * @return string */ protected static function getFormatedDate($timestamp) { /** @global CDataBase $DB */ global $DB; return $DB->CharToDateFunction(ConvertTimeStamp($timestamp + CTimeZone::GetOffset(), "FULL")); } /** * */ protected static function clearCache() { /** @global CCacheManager $CACHE_MANAGER*/ global $CACHE_MANAGER; $CACHE_MANAGER->CleanDir(self::CACHE_DIR); } /** * */ public function isAnyCheckingExists() { } /** * */ protected function finalizeLastTest() { $this->sessionData->clearKey("STEP"); $nextTestName = $this->sessionData->getArrayPop("NEEDED_TESTS"); if(is_string($nextTestName) && $nextTestName != "") { $this->sessionData->setData("CUR_TEST", $nextTestName); } else { $this->sessionData->setData("ALL_DONE", true); } } /** * @return bool */ public function isAllTestCompleted() { return $this->sessionData->getBool("ALL_DONE"); } /** * @param array $pResults * @return int */ public static function calculateCriticalResults($pResults = array()) { if(empty($pResults)) { $testingInfo = CSecuritySiteChecker::getLastTestingInfo(); if(isset($testingInfo["results"])) { $results = $testingInfo["results"]; } else { $results = array(); } } else { $results = $pResults; } $criticalResultsCount = 0; foreach($results as $result) { if(isset($result["critical"]) && $result["critical"] === CSecurityCriticalLevel::HIGHT) $criticalResultsCount++; } return $criticalResultsCount; } /** * @return bool */ public static function OnAdminInformerInsertItems() { /** @global CUser $USER */ global $USER; if(!$USER->isAdmin()) return false; if(!self::isNewTestNeeded()) return false; try { $adminUrl = self::ADMIN_PAGE_URL."?lang=".LANGUAGE_ID; $htmlText = '
'.GetMessage("SEC_CHECKER_INFORMER_DESCRIPTION").'
'; $WAFAIParams = array( "TITLE" => GetMessage("SEC_CHECKER_INFORMER_TITLE"), "COLOR" => "blue", "ALERT" => true, "HTML" => $htmlText, "FOOTER" => ''.GetMessage("SEC_CHECKER_INFORMER_LINK").'' ); } catch (Exception $e) { $WAFAIParams = array( "TITLE" => GetMessage("SEC_CHECKER_INFORMER_TITLE")." - ".GetMessage("top_panel_ai_title_err"), "ALERT" => true, "HTML" => $e->getMessage() ); } CAdminInformer::AddItem($WAFAIParams); return true; } /** * @return string */ protected function getCurrentTestName() { if($this->sessionData->isEmpty("CUR_TEST")) { $this->finalizeLastTest(); } return $this->sessionData->getString("CUR_TEST"); } /** * @param string $pTestName * @param array $pParams * @return array */ protected function makeParamsForTest($pTestName, $pParams) { if(is_array($pParams) && !empty($pParams)) { return $pParams; } else { return array( "TEST_ID" => md5($pTestName), "STEP" => $this->getNextStep() ); } } /** * @return int */ protected function getNextStep() { if($this->sessionData->isExists("STEP")) { $this->sessionData->increment("STEP"); } else { $this->sessionData->setData("STEP", 0); } return $this->sessionData->getInt("STEP"); } /** * @return bool */ protected function initializeAvailableTests() { $this->allTests = CSecurityTestsPackage::getAllTests(); return true; } /** * @param string|array $pTests * @return bool */ protected function initializeNeededTests($pTests) { if(is_string($pTests) && $pTests != "") { $this->neededTests = array($pTests); } elseif(is_array($pTests) && !empty($pTests)) { $this->neededTests = $pTests; } else { $this->neededTests = $this->allTests; } if(!$this->sessionData->isExists("NEEDED_TESTS")) { $this->sessionData->setData("NEEDED_TESTS", $this->neededTests); } return true; } }