CanDoOperation('security_file_verifier_sign'); $canCollect = $USER->CanDoOperation('security_file_verifier_collect'); $canVerify = $USER->CanDoOperation('security_file_verifier_verify'); if(!$canSign && !$canCollect && !$canVerify) $APPLICATION->AuthForm(GetMessage("ACCESS_DENIED")); IncludeModuleLangFile(__FILE__); /*************************************************************************************************/ /*************************************************************************************************/ define("BX_FILE_CHECKER_REGION_KERNEL", 1); define("BX_FILE_CHECKER_REGION_ROOT", 2); define("BX_FILE_CHECKER_REGION_PERSONAL_ROOT", 4); define("BX_FILE_CHECKER_REGION_PUBLIC", 8); if (!defined("START_EXEC_TIME")) define("START_EXEC_TIME", getmicrotime()); class CFileChecker { var $arCollectedExtensions; var $startPath; var $serverFileErrorLogName = "serverfilerr"; var $serverErrorLog; var $serverErrorLogHandle; /** @var CFileCheckerLog */ var $fileLog; /** @var CFileCheckerErrorLog */ var $fileErrorLog; protected static $integrityKey = ''; public static function getIntegrityKey() { if(!self::$integrityKey) { $fileString = file_get_contents(__FILE__); $fileString = preg_replace("#<"."\\?[\\s]*define\\(\"BX_INTEGRITY_VALUE\",[\\s]*'[^']*?'\\);?[\\s]*\\?".">#i", "", $fileString); self::$integrityKey = hash('sha256', $fileString); } return self::$integrityKey; } public static function GetList() { $arFiles = array(); $vf = new CFileCheckerLog(); if ($handle = @opendir($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules")) { while (($file = readdir($handle)) !== false) { if ($file == "." || $file == "..") continue; if (!is_file($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/".$file)) continue; if (mb_substr($file, 0, mb_strlen("serverfilelog-")) != "serverfilelog-") continue; if (mb_substr($file, -4) != ".dat") continue; if (mb_substr($file, -8) === "_tmp.dat") continue; $ts = mb_substr($file, mb_strlen("serverfilelog-")); $ts = mb_substr($ts, 0, -4); if (intval($ts) <= 0) continue; $vf->__GetDescriptionList($ts); if ($vf->GetDescriptionTs() > 0) { $arFiles[] = array( "TIMESTAMP_X" => $vf->GetDescriptionTs(), "REGION" => $vf->GetDescriptionRegion(), "EXTENTIONS" => $vf->GetDescriptionCollectedExtensions(), "LOG" => "", "FILE" => $file, ); } } closedir($handle); } return $arFiles; } function SetCollectedExtensions($arCollectedExtensions) { $this->arCollectedExtensions = array(); foreach ($arCollectedExtensions as $ext) { $ext = trim($ext); if ($ext <> '') $this->arCollectedExtensions[] = mb_strtolower($ext); } } function SetStartPoint($startPath, $region) { $this->startPath = ""; if ($startPath <> '') { if (intval(mb_substr($startPath, 0, 1)) == $region) { $startPath = str_replace("\\", "/", mb_substr($startPath, 1)); $startPath = trim(trim($startPath, "/\\")); if ($startPath <> '') $this->startPath = "/".$startPath; } } } function GetFileInfo($filename) { $filename = str_replace("\\", "/", $filename); $fileSize = filesize($_SERVER["DOCUMENT_ROOT"].$filename); $fileCRC = CFileCheckerUtil::GetFileCRC($filename); return array("filename" => $filename, "fileSize" => $fileSize, "fileCRC" => $fileCRC); } function __WalkThrougtTree($path, $arSkipPaths, $level, &$arTs, $fileFunction) { $path = str_replace("\\", "/", $path); $path = trim(trim($path, "/\\")); if ($path <> '') $path = "/".$path; $startPathPart = ""; $le = false; if ($this->startPath <> '') { if ($path == '' || mb_strlen($this->startPath) >= mb_strlen($path) && mb_substr($this->startPath, 0, mb_strlen($path)) == $path) { if ($path <> '') $startPath = mb_substr($this->startPath, mb_strlen($path) + 1); else $startPath = $this->startPath; $pos = mb_strpos($startPath, "/"); $le = (($pos === false) ? false : true); if ($pos === false) $startPathPart = $startPath; else $startPathPart = mb_substr($startPath, 0, $pos); } } $arFiles = array(); if ($handle = @opendir($_SERVER["DOCUMENT_ROOT"].$path)) { while (($file = readdir($handle)) !== false) { if ($file == "." || $file == "..") continue; if ($startPathPart <> '' && ($le && $startPathPart > $file || !$le && $startPathPart >= $file)) continue; if (count($arSkipPaths) > 0) { $bSkip = False; for ($i = 0, $count = count($arSkipPaths); $i < $count; $i++) { if (mb_strpos($path."/".$file, $arSkipPaths[$i]) === 0) { $bSkip = True; break; } } if ($bSkip) continue; } $arFiles[] = $file; } closedir($handle); } sort($arFiles, SORT_STRING); for ($i = 0, $count = count($arFiles); $i < $count; $i++) { if (is_dir($_SERVER["DOCUMENT_ROOT"].$path."/".$arFiles[$i])) { $res = $this->__WalkThrougtTree($path."/".$arFiles[$i], $arSkipPaths, $level + 1, $arTs, $fileFunction); if (!$res) return false; } else { if (count($this->arCollectedExtensions) > 0) { $fileExt = mb_strtolower(GetFileExtension($arFiles[$i])); if (!in_array($fileExt, $this->arCollectedExtensions)) continue; } call_user_func(array(&$this, $fileFunction), $path."/".$arFiles[$i]); $arTs["StatNum"]++; } if ($arTs["MaxExecutionTime"] > 0 && (getmicrotime() - START_EXEC_TIME > $arTs["MaxExecutionTime"])) { $arTs["StartPoint"] = $path."/".$arFiles[$i]; return false; } } $arTs["StartPoint"] = ""; return true; } function __CollectFile($file) { $this->fileLog->Write($this->GetFileInfo($file)); } function __VerifyFile($file) { $arFileInfo = $this->GetFileInfo($file); $s = $this->fileLog->Search($arFileInfo["filename"]); if ($s) { if ($s["fileSize"] != $arFileInfo["fileSize"]) $this->fileErrorLog->Write("FS*".$arFileInfo["filename"]."*".$arFileInfo["fileSize"]."*".$s["fileSize"]); elseif ($s["fileCRC"] != $arFileInfo["fileCRC"]) $this->fileErrorLog->Write("FC*".$arFileInfo["filename"]."*".$arFileInfo["fileCRC"]."*".$s["fileCRC"]); } else { $this->fileErrorLog->Write("FN*".$arFileInfo["filename"]); } } function __VerifyLogFileRest() { while ($s = $this->fileLog->ReadLine()) $this->fileErrorLog->Write("FM*".$s); } function CollectCrc($region, $arCollectedExtensions, $pwdString, &$arTs, &$arErrors) { if (BX_PERSONAL_ROOT == BX_ROOT) $region = (($region | BX_FILE_CHECKER_REGION_PERSONAL_ROOT) ^ BX_FILE_CHECKER_REGION_PERSONAL_ROOT); $this->SetCollectedExtensions($arCollectedExtensions); $this->fileLog = new CFileCheckerLog(); if ($arTs["ts"] && intval($arTs["ts"]) > 0) { $region = (($region | $arTs["Completed"]) ^ $arTs["Completed"]); if (!$this->fileLog->CreateStep($arTs["ts"])) { $arErrors[] = "Can not open log file for appending. "; return true; } } else { $arTs["StartPoint"] = ""; if (!$this->fileLog->Create($region, $this->arCollectedExtensions)) { $arErrors[] = "Can not create log file. "; return true; } $arTs["ts"] = $this->fileLog->GetTs(); } $arTs["StatNum"] = 0; $res = true; if ($res && (($region & BX_FILE_CHECKER_REGION_KERNEL) != 0)) { $this->SetStartPoint($arTs["StartPoint"], BX_FILE_CHECKER_REGION_KERNEL); $res = $this->__WalkThrougtTree( BX_ROOT."/modules", array( $this->fileLog->GetLogCommonPathPart(), "/".$this->serverFileErrorLogName, ), 0, $arTs, "__CollectFile" ); if ($res) { $arTs["Completed"] = $arTs["Completed"] | BX_FILE_CHECKER_REGION_KERNEL; $arTs["StartPoint"] = ""; } else { $arTs["StartPoint"] = BX_FILE_CHECKER_REGION_KERNEL.$arTs["StartPoint"]; } } if ($res && (($region & BX_FILE_CHECKER_REGION_ROOT) != 0)) { $this->SetStartPoint($arTs["StartPoint"], BX_FILE_CHECKER_REGION_ROOT); $res = $this->__WalkThrougtTree( BX_ROOT, array( BX_ROOT."/modules", BX_PERSONAL_ROOT."/cache", BX_PERSONAL_ROOT."/cache_image", BX_PERSONAL_ROOT."/managed_cache", BX_PERSONAL_ROOT."/stack_cache", ), 0, $arTs, "__CollectFile" ); if ($res) { $arTs["Completed"] = $arTs["Completed"] | BX_FILE_CHECKER_REGION_ROOT; $arTs["StartPoint"] = ""; } else { $arTs["StartPoint"] = BX_FILE_CHECKER_REGION_ROOT.$arTs["StartPoint"]; } } if ($res && (($region & BX_FILE_CHECKER_REGION_PERSONAL_ROOT) != 0)) { $this->SetStartPoint($arTs["StartPoint"], BX_FILE_CHECKER_REGION_PERSONAL_ROOT); $res = $this->__WalkThrougtTree( BX_PERSONAL_ROOT, array( BX_ROOT."/modules", BX_PERSONAL_ROOT."/cache", BX_PERSONAL_ROOT."/cache_image", BX_PERSONAL_ROOT."/managed_cache", BX_PERSONAL_ROOT."/stack_cache", ), 0, $arTs, "__CollectFile" ); if ($res) { $arTs["Completed"] = $arTs["Completed"] | BX_FILE_CHECKER_REGION_PERSONAL_ROOT; $arTs["StartPoint"] = ""; } else { $arTs["StartPoint"] = BX_FILE_CHECKER_REGION_PERSONAL_ROOT.$arTs["StartPoint"]; } } if ($res && (($region & BX_FILE_CHECKER_REGION_PUBLIC) != 0)) { $this->SetStartPoint($arTs["StartPoint"], BX_FILE_CHECKER_REGION_PUBLIC); $res = $this->__WalkThrougtTree( "", array( BX_ROOT, "/upload", ), 0, $arTs, "__CollectFile" ); if ($res) { $arTs["Completed"] = $arTs["Completed"] | BX_FILE_CHECKER_REGION_PUBLIC; $arTs["StartPoint"] = ""; } else { $arTs["StartPoint"] = BX_FILE_CHECKER_REGION_PUBLIC.$arTs["StartPoint"]; } } $flag = ((($region | $arTs["Completed"]) ^ $arTs["Completed"]) == 0); if ($flag) $this->fileLog->CloseCreate($pwdString); else $this->fileLog->CloseCreateStep(); return $flag; } function VerifyCrc($ts, $pwdString, &$arTs, &$arErrors) { $this->fileLog = new CFileCheckerLog(); $this->fileErrorLog = new CFileCheckerErrorLog(); if ($arTs["ts"] && intval($arTs["ts"]) > 0) { if (!$this->fileLog->OpenStep($ts)) { $arErrors[] = GetMessage("MFC1_CANT_LOAD_DATAFILE").". "; return true; } $region = $this->fileLog->GetDescriptionRegion(); $region = (($region | $arTs["Completed"]) ^ $arTs["Completed"]); if (!$this->fileErrorLog->CreateStep()) { $arErrors[] = GetMessage("MFC1_CANT_OPEN_ERRORFILE").". "; return true; } } else { $arTs["StartPoint"] = ""; if (!$this->fileLog->Open($ts, $pwdString)) { $arErrors[] = GetMessage("MFC1_CANT_LOAD_DATAFILE"); return true; } $region = $this->fileLog->GetDescriptionRegion(); if (!$this->fileErrorLog->Create()) { $arErrors[] = GetMessage("MFC1_CANT_CREATE_ERRORFILE").". "; return true; } $arTs["ts"] = time(); } $arTs["StatNum"] = 0; $this->SetCollectedExtensions($this->fileLog->GetDescriptionCollectedExtensions()); $res = true; if ($res && (($region & BX_FILE_CHECKER_REGION_KERNEL) != 0)) { $this->SetStartPoint($arTs["StartPoint"], BX_FILE_CHECKER_REGION_KERNEL); $res = $this->__WalkThrougtTree( BX_ROOT."/modules", array( $this->fileLog->GetLogCommonPathPart(), "/".$this->serverFileErrorLogName, ), 0, $arTs, "__VerifyFile" ); if ($res) { $arTs["Completed"] = $arTs["Completed"] | BX_FILE_CHECKER_REGION_KERNEL; $arTs["StartPoint"] = ""; } else { $arTs["StartPoint"] = BX_FILE_CHECKER_REGION_KERNEL.$arTs["StartPoint"]; } } if ($res && (($region & BX_FILE_CHECKER_REGION_ROOT) != 0)) { $this->SetStartPoint($arTs["StartPoint"], BX_FILE_CHECKER_REGION_ROOT); $res = $this->__WalkThrougtTree( BX_ROOT, array( BX_ROOT."/modules", BX_PERSONAL_ROOT."/cache", BX_PERSONAL_ROOT."/cache_image", BX_PERSONAL_ROOT."/managed_cache", BX_PERSONAL_ROOT."/stack_cache", ), 0, $arTs, "__VerifyFile" ); if ($res) { $arTs["Completed"] = $arTs["Completed"] | BX_FILE_CHECKER_REGION_ROOT; $arTs["StartPoint"] = ""; } else { $arTs["StartPoint"] = BX_FILE_CHECKER_REGION_ROOT.$arTs["StartPoint"]; } } if ($res && (($region & BX_FILE_CHECKER_REGION_PERSONAL_ROOT) != 0)) { $this->SetStartPoint($arTs["StartPoint"], BX_FILE_CHECKER_REGION_PERSONAL_ROOT); $res = $this->__WalkThrougtTree( BX_PERSONAL_ROOT, array( BX_ROOT."/modules", BX_PERSONAL_ROOT."/cache", BX_PERSONAL_ROOT."/cache_image", BX_PERSONAL_ROOT."/managed_cache", BX_PERSONAL_ROOT."/stack_cache", ), 0, $arTs, "__VerifyFile" ); if ($res) { $arTs["Completed"] = $arTs["Completed"] | BX_FILE_CHECKER_REGION_PERSONAL_ROOT; $arTs["StartPoint"] = ""; } else { $arTs["StartPoint"] = BX_FILE_CHECKER_REGION_PERSONAL_ROOT.$arTs["StartPoint"]; } } if ($res && (($region & BX_FILE_CHECKER_REGION_PUBLIC) != 0)) { $this->SetStartPoint($arTs["StartPoint"], BX_FILE_CHECKER_REGION_PUBLIC); $res = $this->__WalkThrougtTree( "", array( BX_ROOT, "/upload", ), 0, $arTs, "__VerifyFile" ); if ($res) { $arTs["Completed"] = $arTs["Completed"] | BX_FILE_CHECKER_REGION_PUBLIC; $arTs["StartPoint"] = ""; } else { $arTs["StartPoint"] = BX_FILE_CHECKER_REGION_PUBLIC.$arTs["StartPoint"]; } } if ($res) { $this->__VerifyLogFileRest(); } if ($res) $this->fileLog->CloseOpen(); else $this->fileLog->CloseOpenStep(); $this->fileErrorLog->CloseCreate(); return $res; } } class CFileCheckerLog { var $serverFileLogName = "serverfilelog"; var $serverFileLogExt = "dat"; var $serverFileLogPath = "/bitrix/modules"; var $serverLog; var $serverLogTmp; var $serverLogHandle; var $serverLogTmpHandle; var $ts; var $logText; var $descrRegion; var $descrCollectedExtensions; var $descrTs; function __WriteDescription($region, $arCollectedExtensions) { $this->descrRegion = $region; $this->descrCollectedExtensions = $arCollectedExtensions; $this->descrTs = $this->ts; fwrite($this->serverLogTmpHandle, $this->ts."|".$region."|".implode(",", $arCollectedExtensions)."\n"); } function __ReadDescription() { fseek($this->serverLogTmpHandle, 0); $line = fgets($this->serverLogTmpHandle, 4096); $line = trim($line); $arLine = explode("|", $line); $this->descrTs = $arLine[0]; $this->descrRegion = $arLine[1]; $exts = $arLine[2]; $this->descrCollectedExtensions = explode(",", $exts); fseek($this->serverLogTmpHandle, -1); } function Create($region, $arCollectedExtensions) { $this->ts = time(); $this->__SetLogFileNames(); if ($this->serverLogTmpHandle = fopen($_SERVER["DOCUMENT_ROOT"].$this->serverLogTmp, "a+")) { $this->__WriteDescription($region, $arCollectedExtensions); return true; } return false; } function CreateStep($ts) { $this->ts = $ts; $this->__SetLogFileNames(); if ($this->serverLogTmpHandle = fopen($_SERVER["DOCUMENT_ROOT"].$this->serverLogTmp, "a+")) { $this->__ReadDescription(); return true; } return false; } function Write($arFileInfo) { fwrite($this->serverLogTmpHandle, $arFileInfo["filename"]."*".$arFileInfo["fileSize"]."*".$arFileInfo["fileCRC"]."\n"); } function CloseCreateStep() { fclose($this->serverLogTmpHandle); } function __Crypt($pwdString) { $fileString = file_get_contents($_SERVER["DOCUMENT_ROOT"].str_replace("\\", "/", $this->serverLogTmp)); $fileString = mb_substr($fileString, mb_strpos($fileString, "\n") + 1); $fileStringNew = CFileCheckerUtil::Encrypt($fileString, $pwdString); $this->serverLogHandle = fopen($_SERVER["DOCUMENT_ROOT"].$this->serverLog, "wb"); fwrite($this->serverLogHandle, $this->descrTs."|".$this->descrRegion."|".implode(",", $this->descrCollectedExtensions)."\n"); fwrite($this->serverLogHandle, $fileStringNew); fclose($this->serverLogHandle); } function CloseCreate($pwdString) { $this->CloseCreateStep(); sleep(3); $this->__Crypt($pwdString); @unlink($_SERVER["DOCUMENT_ROOT"].$this->serverLogTmp); } function __GetDescriptionList($ts) { $this->ts = $ts; $this->__SetLogFileNames(); $h = fopen($_SERVER["DOCUMENT_ROOT"].$this->serverLog, "r"); $line = fgets($h, 4096); $line = trim($line); $arLine = explode("|", $line); $this->descrTs = $arLine[0]; $this->descrRegion = $arLine[1]; $exts = $arLine[2]; $this->descrCollectedExtensions = explode(",", $exts); fclose($h); } function Open($ts, $pwdString) { $this->ts = $ts; $this->__SetLogFileNames(); $fileString = file_get_contents($_SERVER["DOCUMENT_ROOT"].str_replace("\\", "/", $this->serverLog)); $pos = mb_strpos($fileString, "\n"); $descr = mb_substr($fileString, 0, $pos); $fileStringNew = CFileCheckerUtil::Decrypt($fileString, $pwdString, $pos + 1); if (mb_substr($fileStringNew, 0, 1) != "/") return false; $this->serverLogTmpHandle = fopen($_SERVER["DOCUMENT_ROOT"].$this->serverLogTmp, "w"); fwrite($this->serverLogTmpHandle, $descr."\n"); fwrite($this->serverLogTmpHandle, $fileStringNew); fclose($this->serverLogTmpHandle); $this->OpenStep($ts); return true; } function OpenStep($ts) { $this->ts = $ts; $this->__SetLogFileNames(); $this->logText = file_get_contents($_SERVER["DOCUMENT_ROOT"].str_replace("\\", "/", $this->serverLogTmp)); $this->__ReadDescriptionFromString(); return true; } function __ReadDescriptionFromString() { $pos = mb_strpos($this->logText, "\n"); $line = mb_substr($this->logText, 0, $pos); $this->logText = mb_substr($this->logText, $pos + 1); $line = trim($line); $arLine = explode("|", $line); $this->descrTs = $arLine[0]; $this->descrRegion = $arLine[1]; $exts = $arLine[2]; $this->descrCollectedExtensions = explode(",", $exts); } function Search($filename) { $pos = -1; do { $pos = mb_strpos($this->logText, $filename, $pos + 1); if ($pos === false) { return false; } } while (($pos > 0) && (mb_substr($this->logText, $pos - 1, 1) !== "\n")); //check if it's begin of file or line $pos1 = mb_strpos($this->logText, "\n", $pos); $line = mb_substr($this->logText, $pos, $pos1 - $pos); $this->logText = mb_substr($this->logText, 0, $pos).mb_substr($this->logText, $pos1 + 1); $arLine = explode("*", $line); return array( "filename" => $arLine[0], "fileSize" => $arLine[1], "fileCRC" => $arLine[2] ); } function ReadLine() { $pos = mb_strpos($this->logText, "\n"); $line = mb_substr($this->logText, 0, $pos); $this->logText = mb_substr($this->logText, $pos + 1); return $line; } function CloseOpen() { @unlink($_SERVER["DOCUMENT_ROOT"].$this->serverLogTmp); } function CloseOpenStep() { $this->serverLogTmpHandle = fopen($_SERVER["DOCUMENT_ROOT"].$this->serverLogTmp, "w"); fwrite($this->serverLogTmpHandle, $this->descrTs."|".$this->descrRegion."|".implode(",", $this->descrCollectedExtensions)."\n"); fwrite($this->serverLogTmpHandle, $this->logText); fclose($this->serverLogTmpHandle); } function __SetLogFileNames() { $this->ts = intval($this->ts); $this->serverLog = $this->serverFileLogPath."/".$this->serverFileLogName."-".$this->ts.".".$this->serverFileLogExt; $this->serverLogTmp = $this->serverFileLogPath."/".$this->serverFileLogName."-".$this->ts."_tmp.".$this->serverFileLogExt; } function GetTs() { return $this->ts; } function GetDescriptionTs() { return $this->descrTs; } function GetDescriptionRegion() { return $this->descrRegion; } function GetDescriptionCollectedExtensions() { return $this->descrCollectedExtensions; } function GetLogCommonPathPart() { return $this->serverFileLogPath."/".$this->serverFileLogName."-"; } public static function GetDownloadName($ts) { $ts = intval($ts); if($ts <= 0) return ""; elseif(function_exists("gzcompress")) return "serverfilelog-".$ts.".dat.gz"; else return "serverfilelog-".$ts.".dat"; } public static function StartDownload($ts) { $ts = intval($ts); if ($ts <= 0) return false; $serverFileLog = "/bitrix/modules/serverfilelog-".$ts.".dat"; $streamFileName = $serverFileLog; if (function_exists("gzcompress")) { $streamFileName = $serverFileLog."2"; $zp_file = gzopen($_SERVER["DOCUMENT_ROOT"].$serverFileLog."2", "wb9f"); $hFile = fopen($_SERVER["DOCUMENT_ROOT"].$serverFileLog, "rb"); while (!feof($hFile)) { $buffer = fgets($hFile, 4096); if ($buffer <> '') gzwrite($zp_file, $buffer); } gzclose($zp_file); fclose($hFile); } return $streamFileName; } public static function StopDownload($ts) { $ts = intval($ts); if ($ts <= 0) return; $streamFileName = "/bitrix/modules/serverfilelog-".$ts.".dat2"; if (function_exists("gzcompress")) @unlink($_SERVER["DOCUMENT_ROOT"].$streamFileName); } } class CFileCheckerErrorLog { var $serverFileLogName = "serverfileerrorlog"; var $serverFileLogExt = "dat"; var $serverFileLogPath = "/bitrix/modules"; var $serverLog; var $serverLogHandle; var $logText; function Create() { $this->__SetLogFileNames(); if ($this->serverLogHandle = fopen($_SERVER["DOCUMENT_ROOT"].$this->serverLog, "w")) return true; return false; } function CreateStep() { $this->__SetLogFileNames(); if ($this->serverLogHandle = fopen($_SERVER["DOCUMENT_ROOT"].$this->serverLog, "a")) return true; return false; } function Write($message) { fwrite($this->serverLogHandle, $message."\n"); } function CloseCreate() { fclose($this->serverLogHandle); } function Open() { $this->__SetLogFileNames(); $this->logText = file_get_contents($_SERVER["DOCUMENT_ROOT"].str_replace("\\", "/", $this->serverLog)); return true; } function ReadLine() { $pos = mb_strpos($this->logText, "\n"); $line = mb_substr($this->logText, 0, $pos); $this->logText = mb_substr($this->logText, $pos + 1); return $line; } function CloseOpen() { } function __SetLogFileNames() { $this->serverLog = $this->serverFileLogPath."/".$this->serverFileLogName.".".$this->serverFileLogExt; } function GetLogCommonPathPart() { return $this->serverFileLogPath."/".$this->serverFileLogName.".".$this->serverFileLogExt; } } class CFileCheckerSubscriber { public static function IsSubscribed($fileName) { $fileName = trim($fileName); if ($fileName == '') return false; $fileString = file_get_contents($_SERVER["DOCUMENT_ROOT"].str_replace("\\", "/", $fileName)); if ($fileString == '') return false; return preg_match("#<"."\?[\s]*define\(\"BX_INTEGRITY_VALUE\",[\s]*'([^']*?)'\);?[\s]*\?".">#i", $fileString); } public static function Subscribe($fileName, $pwdString, $keyString, &$arErrors) { $fileName = trim($fileName); if ($fileName == '') { $arErrors[] = GetMessage("MFC1_FILE_NOT_SET").". "; return false; } $pwdString = trim($pwdString); if ($pwdString == '') { $arErrors[] = GetMessage("MFC1_PWD_NOT_SET").". "; return false; } $keyString = trim($keyString); if ($keyString == '') { $arErrors[] = GetMessage("MFC1_KEY_NOT_SET").". "; return false; } if ($keyString == $pwdString) { $arErrors[] = GetMessage("MFC1_PWD_KEY_EQ").". "; return false; } $fileString = file_get_contents($_SERVER["DOCUMENT_ROOT"].str_replace("\\", "/", $fileName)); if ($fileString == '') { $arErrors[] = GetMessage("MFC1_EMPTY_FILE").". "; return false; } if(mb_substr($fileString, 0, 4) === "Zend") { $arErrors[] = GetMessage("MFC1_ZEND_FILE").". "; return false; } $fileString = preg_replace("#<"."\\?[\\s]*define\\(\"BX_INTEGRITY_VALUE\",[\\s]*'[^']*?'\\);?[\\s]*\\?".">#i", "", $fileString); $currentCRC = sprintf("%u", crc32($fileString)); $keyString = CFileCheckerUtil::Encrypt($keyString, CFileChecker::getIntegrityKey()); $data = CFileCheckerSubscriber::__SetIntegrityParams( array("CRC" => $currentCRC, "KEY" => $keyString), $pwdString ); $fileString = "<"."?define(\"BX_INTEGRITY_VALUE\",'".$data."');?".">".$fileString; return CFileCheckerUtil::SetFileContents($fileName, $fileString); } public static function __SetIntegrityParams($arData, $password) { if (!is_array($arData) || !isset($arData["CRC"]) || !isset($arData["KEY"])) return False; $data = $arData["CRC"]."*".$arData["KEY"]; $dataNew = CFileCheckerUtil::Encrypt($data, $password); return $dataNew; } public static function Verify($fileName, $pwdString, &$keyString, &$arErrors) { $fileName = trim($fileName); if ($fileName == '') { $arErrors[] = GetMessage("MFC1_FILE_NOT_SET").". "; return false; } $pwdString = trim($pwdString); if ($pwdString == '') { $arErrors[] = GetMessage("MFC1_PWD_NOT_SET").". "; return false; } $fileString = file_get_contents($_SERVER["DOCUMENT_ROOT"].str_replace("\\", "/", $fileName)); if ($fileString == '') { $arErrors[] = GetMessage("MFC1_EMPTY_FILE").". "; return false; } if (preg_match("#<"."\\?[\\s]*define\\(\"BX_INTEGRITY_VALUE\",[\\s]*'([^']*?)'\\);?[\\s]*\\?".">#i", $fileString, $arMatches)) { $data = $arMatches[1]; if ($data <> '') { $fileString = preg_replace("#<"."\\?[\\s]*define\\(\"BX_INTEGRITY_VALUE\",[\\s]*'[^']*?'\\);?[\\s]*\\?".">#i", "", $fileString); $currentCRC = sprintf("%u", crc32($fileString)); if ($arIntegrityParams = CFileCheckerSubscriber::__GetIntegrityParams($data, $pwdString)) { if ($arIntegrityParams["CRC"] != $currentCRC) { $arErrors[] .= GetMessage("MFC1_CRC_NOT_CORRECT").". "; return false; } else { $keyString = $arIntegrityParams["KEY"]; $keyString = CFileCheckerUtil::Decrypt($keyString, CFileChecker::getIntegrityKey()); return true; } } else { $arErrors[] .= GetMessage("MFC1_NO_CRC").". "; return false; } } else { $arErrors[] .= GetMessage("MFC1_NO_CRC").". "; return false; } } else { $arErrors[] .= GetMessage("MFC1_NO_CRC_NOT_SET").". "; return false; } } public static function __GetIntegrityParams($data, $password) { if ($data == '') return False; $dataNew = CFileCheckerUtil::Decrypt($data, $password); $arDataNew = explode("*", $dataNew); if (count($arDataNew) != 2) return False; return array("CRC" => $arDataNew[0], "KEY" => $arDataNew[1]); } } class CFileCheckerUtil { public static function SetFileContents($filename, $content) { $filename = str_replace("\\", "/", $filename); if ($hFile = fopen($_SERVER["DOCUMENT_ROOT"].$filename, "wb")) { fwrite($hFile, $content); fclose($hFile); return true; } return false; } public static function GetFileCRC($filename) { $fileString = file_get_contents($_SERVER["DOCUMENT_ROOT"].str_replace("\\", "/", $filename)); $crc = crc32($fileString); return sprintf("%u", $crc); } public static function GetFileLength($filename) { return filesize($_SERVER["DOCUMENT_ROOT"].$filename); } public static function Encrypt($data, $pwdString) { return static::__CryptData($data, $pwdString, "E"); } public static function Decrypt($data, $pwdString, $startPosition = 0) { return static::__CryptData($data, $pwdString, "D", $startPosition); } protected static function __CryptData($data, $pwdString, $type, $startPosition = 0) { $type = mb_strtoupper($type); if ($type != "D") $type = "E"; if ($type == 'D') $data = urldecode($data); $key[] = ""; $box[] = ""; $pwdLength = mb_strlen($pwdString); for ($i = 0; $i <= 255; $i++) { $key[$i] = ord(mb_substr($pwdString, ($i % $pwdLength), 1)); $box[$i] = $i; } $x = 0; for ($i = 0; $i <= 255; $i++) { $x = ($x + $box[$i] + $key[$i]) % 256; $temp_swap = $box[$i]; $box[$i] = $box[$x]; $box[$x] = $temp_swap; } $cipher = ""; $a = 0; $j = 0; $data_len = defined("BX_UTF")? mb_strlen($data, 'latin1') : mb_strlen($data); for ($i = $startPosition; $i < $data_len; $i++) { $a = ($a + 1) % 256; $j = ($j + $box[$a]) % 256; $temp = $box[$a]; $box[$a] = $box[$j]; $box[$j] = $temp; $k = $box[(($box[$a] + $box[$j]) % 256)]; $cipherby = ord( defined("BX_UTF")? mb_substr($data, $i, 1, 'latin1') : mb_substr($data, $i, 1) ) ^ $k; $cipher .= chr($cipherby); } if ($type == 'D') return $cipher; else return urlencode($cipher); } } /*************************************************************************************************/ /*************************************************************************************************/ if (isset($_REQUEST["fcajax"]) && in_array($_REQUEST["fcajax"], array("cl", "vf", "df"))) { if (!check_bitrix_sessid()) { echo "ERR|Your session has been expired."; die(); } if ($_REQUEST["fcajax"] == "cl") { if(!$canCollect) $APPLICATION->AuthForm(GetMessage("ACCESS_DENIED")); if (intval($_REQUEST["tm"]) < 5) $_REQUEST["tm"] = 5; $collector = new CFileChecker(); $arTs = array( "ts" => intval($_REQUEST["ts"]), "Completed" => intval($_REQUEST["completed"]), "StartPoint" => $_REQUEST["startpoint"], "MaxExecutionTime" => intval($_REQUEST["tm"]), ); $arErrors = array(); $res = $collector->CollectCrc(intval($_REQUEST["region"]), explode(",", $_REQUEST["exts"]), $_REQUEST["pwd"], $arTs, $arErrors); if (count($arErrors) > 0) { echo "ERR|".implode("|", $arErrors); } else { if ($res) echo "FIN|".$arTs["ts"]."|".$arTs["StatNum"]; else echo "STP|".$arTs["Completed"]."|".$arTs["ts"]."|".$arTs["StartPoint"]."|".$arTs["StatNum"]; } } elseif ($_REQUEST["fcajax"] == "vf") { if(!$canVerify) $APPLICATION->AuthForm(GetMessage("ACCESS_DENIED")); if (intval($_REQUEST["tm"]) < 5) $_REQUEST["tm"] = 5; $collector = new CFileChecker(); $arTs = array( "ts" => intval($_REQUEST["ts"]), "Completed" => intval($_REQUEST["completed"]), "StartPoint" => $_REQUEST["startpoint"], "MaxExecutionTime" => intval($_REQUEST["tm"]), ); $arErrors = array(); $res = $collector->VerifyCrc(intval($_REQUEST["df"]), $_REQUEST["pwd"], $arTs, $arErrors); if (count($arErrors) > 0) { echo "ERR|".implode("|", $arErrors); } else { if ($res) { $io = CBXVirtualIo::GetInstance(); echo "FIN|"; $fl = new CFileCheckerErrorLog(); $fl->Open(); $i = 0; while ($s = $fl->ReadLine()) { if ($i > 300) { echo GetMessage("MFC1_EXISTS_OTHER_DIF"); break; } $arS = explode("*", $s); echo $io->GetLogicalName($arS[1])." - "; if ($arS[0] == "FS") echo GetMessage("MFC1_SIZE_DIF"); elseif ($arS[0] == "FC") echo GetMessage("MFC1_CRC_DIF"); elseif ($arS[0] == "FN") echo GetMessage("MFC1_NEW_DIF"); elseif ($arS[0] == "FM") echo GetMessage("MFC1_DEL_DIF"); echo "
"; $i++; } if ($i == 0) echo GetMessage("MFC1_NO_DIF"); $fl->CloseOpen(); COption::SetOptionInt("security", "last_files_check", time()); } else { echo "STP|".$arTs["Completed"]."|".$arTs["ts"]."|".$arTs["StartPoint"]."|".$arTs["StatNum"]; } } } elseif ($_REQUEST["fcajax"] == "df") { if(!$canCollect && !$canVerify) $APPLICATION->AuthForm(GetMessage("ACCESS_DENIED")); $_REQUEST["df"] = intval($_REQUEST["df"]); unlink($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/serverfilelog-".$_REQUEST["df"].".dat"); echo $_REQUEST["df"]; } die(); } if (isset($_REQUEST["fcdld"]) && $_REQUEST["fcdld"] == "Y" && check_bitrix_sessid() && $canCollect) { if (isset($_REQUEST["ts"]) && intval($_REQUEST["ts"]) > 0) { $streamFileName = CFileCheckerLog::StartDownload($_REQUEST["ts"]); $filesize = filesize($_SERVER["DOCUMENT_ROOT"].$streamFileName); header($_SERVER["SERVER_PROTOCOL"]." 200 OK"); header("Content-Type: application/force-download; name=\"".CFileCheckerLog::GetDownloadName($_REQUEST["ts"])."\""); header("Content-Transfer-Encoding: binary"); header("Content-Length: ".$filesize); header("Content-Disposition: attachment; filename=\"".CFileCheckerLog::GetDownloadName($_REQUEST["ts"])."\""); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Expires: 0"); header("Pragma: public"); $p = file_get_contents($_SERVER["DOCUMENT_ROOT"].str_replace("\\", "/", $streamFileName)); echo $p; flush(); CFileCheckerLog::StopDownload($_REQUEST["ts"]); } die(); } $tabStep = (isset($_REQUEST["tabStep"]) && intval($_REQUEST["tabStep"]) > 1 ? intval($_REQUEST["tabStep"]) : 1); if (isset($_REQUEST["backButton"])) $tabStep = $tabStep - 2; else if (isset($_REQUEST["backToStart"])) $tabStep = 1; $scriptName = "/bitrix/modules/security/admin/security_file_verifier.php"; $isSubscribed = CFileCheckerSubscriber::IsSubscribed($scriptName); $okMessage = ""; $errorMessage = ""; if ($_SERVER["REQUEST_METHOD"] == "POST" && $tabStep == 2 && check_bitrix_sessid()) { if ($isSubscribed) { $errorMessageTmp = ""; $okMessageTmp = ""; if ($_REQUEST["crc_password"] == '') $errorMessageTmp .= GetMessage("MFC1_ERR_NO_PWD").". "; if ($errorMessageTmp == '') { $keyString = ""; $arErrors = array(); if (!CFileCheckerSubscriber::Verify($scriptName, $_REQUEST["crc_password"], $keyString, $arErrors)) $errorMessageTmp .= GetMessage("MFC1_ERR_VERIFY")."
".implode("
", $arErrors); else $okMessageTmp = str_replace("#KEY#", $keyString, GetMessage("MFC1_OK_VERIFY")); } if ($errorMessageTmp <> '') { $errorMessage = $errorMessageTmp; $tabStep = 1; } if ($okMessageTmp <> '') $okMessage = $okMessageTmp; } elseif ($canSign) { $errorMessageTmp = ""; $okMessageTmp = ""; if ($_REQUEST["crc_password"] == '') $errorMessageTmp .= GetMessage("MFC1_ERR_C_PWD").". "; if ($errorMessageTmp == '' && $_REQUEST["crc_password"] != $_REQUEST["crc_password_check"]) $errorMessageTmp .= GetMessage("MFC1_ERR_C_PWD_CHECK").". "; if ($errorMessageTmp == '' && $_REQUEST["crc_key"] == '') $errorMessageTmp .= GetMessage("MFC1_ERR_C_KEY").". "; if ($errorMessageTmp == '' && $_REQUEST["crc_key"] == $_REQUEST["crc_password"]) $errorMessageTmp .= GetMessage("MFC1_ERR_C_PWD_KEY").". "; if ($errorMessageTmp == '') { $keyString = ""; $arErrors = array(); if (!CFileCheckerSubscriber::Subscribe($scriptName, $_REQUEST["crc_password"], $_REQUEST["crc_key"], $arErrors)) $errorMessageTmp .= GetMessage("MFC1_ERR_C_ERR")."
".implode("
", $arErrors); else $okMessageTmp = GetMessage("MFC1_ERR_C_SUCCESS")."."; } if ($errorMessageTmp <> '') { $errorMessage = $errorMessageTmp; $tabStep = 1; } if ($okMessageTmp <> '') $okMessage = $okMessageTmp; } else { $errorMessage = GetMessage("MFC1_ERR_C_ERR_RIGHT"); $tabStep = 1; } } if ($_SERVER["REQUEST_METHOD"] == "POST" && $tabStep == 3 && check_bitrix_sessid()) { $bOK = $_REQUEST["action"] === "verify" && $canVerify; if(!$bOK) $bOK = $_REQUEST["action"] === "collect" && $canCollect; if(!$bOK) { $tabStep = 2; $errorMessage .= GetMessage("MFC1_ERR_NO_ACT").". "; } } if ($_SERVER["REQUEST_METHOD"] == "POST" && $tabStep == 4 && check_bitrix_sessid()) { if ($_REQUEST["action"] == "collect" && $canCollect) { $errorMessageTmp = ""; $okMessageTmp = ""; COption::SetOptionString("security", "checker_exts", trim($_REQUEST["checker_exts"])); COption::SetOptionInt("security", "checker_time", trim($_REQUEST["checker_time"])); $region = 0; if ($_REQUEST["checker_region_kernel"] == "Y") $region |= BX_FILE_CHECKER_REGION_KERNEL; COption::SetOptionString("security", "checker_region_kernel", $_REQUEST["checker_region_kernel"] == "Y"? "Y": "N"); if ($_REQUEST["checker_region_root"] == "Y") $region |= BX_FILE_CHECKER_REGION_ROOT; COption::SetOptionString("security", "checker_region_root", $_REQUEST["checker_region_root"] == "Y"? "Y": "N"); if ($_REQUEST["checker_region_personal_root"] == "Y") $region |= BX_FILE_CHECKER_REGION_PERSONAL_ROOT; COption::SetOptionString("security", "checker_region_personal_root", $_REQUEST["checker_region_personal_root"] == "Y"? "Y": "N"); if ($_REQUEST["checker_region_public"] == "Y") $region |= BX_FILE_CHECKER_REGION_PUBLIC; COption::SetOptionString("security", "checker_region_public", $_REQUEST["checker_region_public"] == "Y"? "Y": "N"); if ($region <= 0) $errorMessageTmp .= GetMessage("MFC1_ERR_C_NO_REG").". "; if ($errorMessageTmp == '' && $_REQUEST['checker_pwd'] == '') $errorMessageTmp .= GetMessage("MFC1_ERR_C_NO_PWD1").". "; if ($errorMessageTmp <> '') { $errorMessage = $errorMessageTmp; $tabStep = 3; } } elseif ($_REQUEST["action"] == "verify" && $canVerify) { $errorMessageTmp = ""; $okMessageTmp = ""; if (isset($_FILES["crc_file"]) && is_uploaded_file($_FILES["crc_file"]["tmp_name"])) { $cf_select_dfile = ""; if(function_exists("gzcompress")) { $hFile = fopen($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/serverfilelog-1.dat", "wb"); $zp_file = gzopen($_FILES["crc_file"]["tmp_name"], "rb9f"); while (!gzeof($zp_file)) { $buffer = gzread($zp_file, 4096); if ($buffer <> '') fwrite($hFile, $buffer); } gzclose($zp_file); fclose($hFile); } else { copy($_FILES["crc_file"]["tmp_name"], $_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/serverfilelog-1.dat"); } $vf = new CFileCheckerLog(); $vf->__GetDescriptionList(1); $ts = intval($vf->GetDescriptionTs()); if ($ts > 0) { @unlink($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/serverfilelog-".$ts.".dat"); copy($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/serverfilelog-1.dat", $_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/serverfilelog-".$ts.".dat"); unlink($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/serverfilelog-1.dat"); $cf_select_dfile = $ts; } } else { $cf_select_dfile = $_REQUEST["cf_select_dfile"]; } $cf_select_dfile = intval($cf_select_dfile); if ($cf_select_dfile <= 0) $errorMessageTmp .= GetMessage("MFC1_ERR_V_FILE").". "; if ($errorMessageTmp <> '') { $errorMessage = $errorMessageTmp; $tabStep = 3; } } } if ($_SERVER["REQUEST_METHOD"] == "POST" && $tabStep == 5 && check_bitrix_sessid()) { if ($_REQUEST["action"] == "verify" && $canVerify) { $errorMessageTmp = ""; $okMessageTmp = ""; if ($_REQUEST['checker_pwd'] == '') $errorMessageTmp .= GetMessage("MFC1_ERR_V_PWD1").". "; if ($errorMessageTmp <> '') { $errorMessage = $errorMessageTmp; $tabStep = 4; } } } $APPLICATION->SetTitle(GetMessage("MFC1_TITLE")); require_once ($_SERVER["DOCUMENT_ROOT"].BX_ROOT."/modules/main/include/prolog_admin_after.php"); $arTabs = Array( Array("DIV" => "tabSign", "TAB" => GetMessage("MFC1_TAB_SIGN"), "TITLE" => GetMessage("MFC1_TAB_SIGN_DESCR")), Array("DIV" => "tabSelect", "TAB" => GetMessage("MFC1_TAB_SELECT"), "TITLE" => GetMessage("MFC1_TAB_SELECT_DESCR")), ); if ($tabStep > 2) { if ($_REQUEST["action"] == "collect" && $canCollect) { $arTabs[] = Array("DIV" => "tabCollect", "TAB" => GetMessage("MFC1_TAB_COLLECT"), "TITLE" => GetMessage("MFC1_TAB_COLLECT_DESCR")); $arTabs[] = Array("DIV" => "tabCollectResult", "TAB" => GetMessage("MFC1_TAB_COLLECT_REP"), "TITLE" => GetMessage("MFC1_TAB_COLLECT_REP_DESCR")); } if ($_REQUEST["action"] == "verify" && $canVerify) { $arTabs[] = Array("DIV" => "tabFile", "TAB" => GetMessage("MFC1_TAB_FILE"), "TITLE" => GetMessage("MFC1_TAB_FILE_DESCR")); $arTabs[] = Array("DIV" => "tabVerify", "TAB" => GetMessage("MFC1_TAB_VERIFY"), "TITLE" => GetMessage("MFC1_TAB_VERIFY_DESCR")); $arTabs[] = Array("DIV" => "tabVerifyResult", "TAB" => GetMessage("MFC1_TAB_VERIFY_REP"), "TITLE" => GetMessage("MFC1_TAB_VERIFY_REP_DESCR")); } } $tabControl = new CAdminTabControl("tabControl", $arTabs, false, true); ?>