Server IP : 80.87.202.40 / Your IP : 216.73.216.169 Web Server : Apache System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64 User : bitrix ( 600) PHP Version : 8.2.27 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/main/services/ |
Upload File : |
<?php if (!empty($_GET['ts']) && $_GET['ts'] === 'bxviewer') { return; } if (!empty($_GET['_gen'])) { return; } $encryptedData = $_GET['_esd'] ?? null; if (empty($encryptedData)) { return; } function readConfig(): ?array { /** @see \Bitrix\Main\Config\Configuration::CONFIGURATION_FILE_PATH */ /** @see \Bitrix\Main\Config\Configuration::CONFIGURATION_FILE_EXTRA */ $settingsPath = $_SERVER['DOCUMENT_ROOT'] . '/bitrix/.settings.php'; $settingsExtraPath = $_SERVER['DOCUMENT_ROOT'] . '/bitrix/.settings_extra.php'; $settings = include($settingsPath); if (empty($settings) || (is_array($settings) === false)) { $settings = []; } if (file_exists($settingsExtraPath)) { $settingsExtra = include($settingsExtraPath); if (is_array($settingsExtra) && !empty($settingsExtra)) { foreach ($settingsExtra as $k => $v) { $settings[$k] = $v; } } } /** @see \Bitrix\Disk\QuickAccess\Configuration::CONFIG_SECTION */ /** @see \Bitrix\Disk\QuickAccess\Configuration::CONFIG_STORAGE */ if (empty($settings['main.token_service']['value']['storage'])) { return null; } if (!is_array($settings['main.token_service']['value']['storage'])) { return null; } if (empty($settings['main.token_service']['value']['key'])) { return null; } return $settings['main.token_service']['value']; } $config = readConfig(); if (!$config) { return null; } function isValidSign(string $key, string $signedUserToken): bool { $parts = explode('.', $signedUserToken, 2); if (count($parts) !== 2) { return false; } [$message, $signature] = $parts; if (empty($message) || empty($signature)) { return false; } $key = hash('sha512', $key); $expectedSignature = bin2hex(hash_hmac('sha256', $message, $key, true)); return hash_equals($expectedSignature, $signature); } function getMemcacheStorage(array $config): ?\Memcache { if (!extension_loaded('memcache')) { return null; } $connection = new \Memcache(); $result = $connection->pconnect($config['host'], $config['port'], 3); return $result ? $connection : null; } function getRedisStorage(array $config): ?\Redis { if (!extension_loaded('redis')) { return null; } $connection = new \Redis(); $params = [ $config['host'], $config['port'], $config['timeout'] ?? 0, null, 0, $config['readTimeout'] ?? 0 ]; $result = $connection->pconnect(...$params); if ($result) { if (isset($config['compression']) || defined('\Redis::COMPRESSION_LZ4')) { $connection->setOption(\Redis::OPT_COMPRESSION, $config['compression'] ?? \Redis::COMPRESSION_LZ4); $connection->setOption(\Redis::OPT_COMPRESSION_LEVEL, $config['compression_level'] ?? \Redis::COMPRESSION_ZSTD_MAX); } if (isset($config['serializer']) || defined('\Redis::SERIALIZER_IGBINARY')) { $connection->setOption(\Redis::OPT_SERIALIZER, $config['serializer'] ?? \Redis::SERIALIZER_IGBINARY); } } return $result ? $connection : null; } function getStorage(array $config): \Memcache|\Redis|null { if ($config['type'] === 'redis') { return getRedisStorage($config); } if ($config['type'] === 'memcache') { return getMemcacheStorage($config); } return null; } /** * @see \Bitrix\Disk\QuickAccess\Storage\RedisScopeStorage::hasScope * @see \Bitrix\Disk\QuickAccess\Storage\ScopeStorage::hasScope */ function hasScope( string $prefix, string $userToken, string $scope, \Redis|\Memcache $storage ): bool { if (empty($scope)) { return false; } $key = "{$prefix}userScopes:{$userToken}"; if ($storage instanceof \Redis) { $expirationTime = $storage->zScore($key, $scope); if (!$expirationTime) { return false; } if ($expirationTime <= time()) { return false; } return true; } else { $storedScopes = $storage->get($key); if (empty($storedScopes) || !is_string($storedScopes)) { return false; } $storedScopes = decodeJson($storedScopes); if ($storedScopes[$scope] < time()) { return false; } return true; } } function decodeJson(string $data): array { return json_decode($data, true, 64) ?: []; } function decryptData(string $data, string $key): ?array { $data = base64_decode($data, true); if ($data === false) { return null; } $cipherAlgorithm = 'aes-256-ctr'; $hashAlgorithm = 'sha256'; $ivLength = openssl_cipher_iv_length($cipherAlgorithm); $iv = substr($data, 0, $ivLength); $raw = substr($data, $ivLength); $keyHash = openssl_digest($iv . $key, $hashAlgorithm, true); $decrypted = openssl_decrypt($raw, $cipherAlgorithm, $keyHash, OPENSSL_RAW_DATA, $iv); if ($decrypted === false) { return null; } $hashPart = substr($decrypted, 0, strlen($keyHash)); $result = substr($decrypted, strlen($keyHash)); $checkHash = openssl_digest($result, $hashAlgorithm, true); if ($hashPart !== $checkHash) { return null; } return decodeJson($result); } $cookiePrefix = $config['cookiePrefix'] ?? 'BITRIX_SM'; /** @see \Bitrix\Disk\QuickAccess\ScopeTokenService::COOKIE_NAME */ $signedUserToken = $_COOKIE["{$cookiePrefix}_DTOKEN"] ?? null; if (empty($signedUserToken)) { return; } $key = $config['key']; if (isValidSign($key, $signedUserToken) === false) { return; } $decryptedData = decryptData($encryptedData, $key); if (empty($decryptedData)) { return; } $storage = getStorage($config['storage']); if (!$storage) { return; } $userToken = explode('.', $signedUserToken, 2)[0]; if (!hasScope($config['storage']['keyPrefix'], $userToken, $decryptedData['scope'], $storage)) { return; } /** @see \Bitrix\Disk\QuickAccess\Storage\ScopeStorage::getFileKey */ $fileInfoKey = "{$config['storage']['keyPrefix']}file:{$decryptedData['fileId']}"; $storedData = $storage->get($fileInfoKey); if (empty($storedData)) { return; } try { $storedData = json_decode($storedData, true, 3, JSON_THROW_ON_ERROR); } catch (\JsonException $e) { return; } $accelRedirectPath = $storedData['path']; $contentType = $storedData['contentType']; $expirationTime = $storedData['expirationTime']; $dir = $storedData['dir']; $bFileId = $storedData['id']; $fileName = $storedData['filename']; $attachmentName = $decryptedData['l'] ?? null; if (time() > $expirationTime) { return; } $requestedWidth = isset($_GET['width']) ? (int)$_GET['width'] : 0; $requestedHeight = isset($_GET['height']) ? (int)$_GET['height'] : 0; $originalWidth = (int)$storedData['width'] ?: 0; $originalHeight = (int)$storedData['height'] ?: 0; // Resize the image only if a smaller version than the original is needed. if ( $requestedWidth > 0 && $requestedHeight > 0 && ($requestedWidth < $originalWidth || $requestedHeight < $originalHeight) ) { $exact = $_GET['exact'] === 'Y' ? 2 : 1; if (empty($storedData['handlerId'])) { $resizeDir = "{$requestedWidth}_{$requestedHeight}_{$exact}"; $accelRedirectPath = "/upload/resize_cache/x/{$dir}/{$resizeDir}/{$fileName}"; } else { $encodedDir = rawurlencode($dir); $delimiterPosition = strpos($accelRedirectPath, $encodedDir); if ($delimiterPosition === false) { return; } $partBeforeDir = substr($accelRedirectPath, 0, $delimiterPosition); $dirAndRest = substr($accelRedirectPath, $delimiterPosition); $defaultResizeFilter = [ ['width' => $requestedWidth, 'height' => $requestedHeight], $exact, [], false, [0 => ['name' => 'sharpen', 'precision' => 15]], true ]; $resizeDir = md5(serialize($defaultResizeFilter)); $accelRedirectPath = $partBeforeDir . rawurlencode("resize_cache/{$bFileId}/{$resizeDir}/") . $dirAndRest; $accelRedirectPath = '/upload/resize_cache/c' . $accelRedirectPath; } } header('X-Accel-Buffering: no'); header('X-Accel-Redirect: ' . $accelRedirectPath); header('Content-Type: ' . $contentType); if ($attachmentName) { $urlEncodedName = rawurlencode($attachmentName); header("X-CD-Info: attachment; filename*=utf-8''{$urlEncodedName}"); } header('X-Gen-Src: ' . $_SERVER['REQUEST_URI'] . '&_gen=1'); die;