diff --git a/composer-setup.php b/composer-setup.php deleted file mode 100755 index e3a76a3..0000000 --- a/composer-setup.php +++ /dev/null @@ -1,5077 +0,0 @@ - - * Jordi Boggiano - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -setupEnvironment(); -process(is_array($argv) ? $argv : array()); - -/** - * Initializes various values - * - * @throws RuntimeException If uopz extension prevents exit calls - */ -function setupEnvironment() -{ - ini_set('display_errors', 1); - - if (extension_loaded('uopz') && !(ini_get('uopz.disable') || ini_get('uopz.exit'))) { - // uopz works at opcode level and disables exit calls - if (function_exists('uopz_allow_exit')) { - @uopz_allow_exit(true); - } else { - throw new RuntimeException('The uopz extension ignores exit calls and breaks this installer.'); - } - } - - $installer = 'ComposerInstaller'; - - if (defined('PHP_WINDOWS_VERSION_MAJOR')) { - if ($version = getenv('COMPOSERSETUP')) { - $installer = sprintf('Composer-Setup.exe/%s', $version); - } - } - - define('COMPOSER_INSTALLER', $installer); -} - -/** - * Processes the installer - */ -function process($argv) -{ - // Determine ANSI output from --ansi and --no-ansi flags - setUseAnsi($argv); - - if (in_array('--help', $argv)) { - displayHelp(); - exit(0); - } - - $check = in_array('--check', $argv); - $help = in_array('--help', $argv); - $force = in_array('--force', $argv); - $quiet = in_array('--quiet', $argv); - $channel = 'stable'; - if (in_array('--snapshot', $argv)) { - $channel = 'snapshot'; - } elseif (in_array('--preview', $argv)) { - $channel = 'preview'; - } elseif (in_array('--1', $argv)) { - $channel = '1'; - } elseif (in_array('--2', $argv)) { - $channel = '2'; - } - $disableTls = in_array('--disable-tls', $argv); - $installDir = getOptValue('--install-dir', $argv, false); - $version = getOptValue('--version', $argv, false); - $filename = getOptValue('--filename', $argv, 'composer.phar'); - $cafile = getOptValue('--cafile', $argv, false); - - if (!checkParams($installDir, $version, $cafile)) { - exit(1); - } - - $ok = checkPlatform($warnings, $quiet, $disableTls, true); - - if ($check) { - // Only show warnings if we haven't output any errors - if ($ok) { - showWarnings($warnings); - showSecurityWarning($disableTls); - } - exit($ok ? 0 : 1); - } - - if ($ok || $force) { - $installer = new Installer($quiet, $disableTls, $cafile); - if ($installer->run($version, $installDir, $filename, $channel)) { - showWarnings($warnings); - showSecurityWarning($disableTls); - exit(0); - } - } - - exit(1); -} - -/** - * Displays the help - */ -function displayHelp() -{ - echo << $value) { - $next = $key + 1; - if (0 === strpos($value, $opt)) { - if ($optLength === strlen($value) && isset($argv[$next])) { - return trim($argv[$next]); - } else { - return trim(substr($value, $optLength + 1)); - } - } - } - - return $default; -} - -/** - * Checks that user-supplied params are valid - * - * @param mixed $installDir The required istallation directory - * @param mixed $version The required composer version to install - * @param mixed $cafile Certificate Authority file - * - * @return bool True if the supplied params are okay - */ -function checkParams($installDir, $version, $cafile) -{ - $result = true; - - if (false !== $installDir && !is_dir($installDir)) { - out("The defined install dir ({$installDir}) does not exist.", 'info'); - $result = false; - } - - if (false !== $version && 1 !== preg_match('/^\d+\.\d+\.\d+(\-(alpha|beta|RC)\d*)*$/', $version)) { - out("The defined install version ({$version}) does not match release pattern.", 'info'); - $result = false; - } - - if (false !== $cafile && (!file_exists($cafile) || !is_readable($cafile))) { - out("The defined Certificate Authority (CA) cert file ({$cafile}) does not exist or is not readable.", 'info'); - $result = false; - } - return $result; -} - -/** - * Checks the platform for possible issues running Composer - * - * Errors are written to the output, warnings are saved for later display. - * - * @param array $warnings Populated by method, to be shown later - * @param bool $quiet Quiet mode - * @param bool $disableTls Bypass tls - * @param bool $install If we are installing, rather than diagnosing - * - * @return bool True if there are no errors - */ -function checkPlatform(&$warnings, $quiet, $disableTls, $install) -{ - getPlatformIssues($errors, $warnings, $install); - - // Make openssl warning an error if tls has not been specifically disabled - if (isset($warnings['openssl']) && !$disableTls) { - $errors['openssl'] = $warnings['openssl']; - unset($warnings['openssl']); - } - - if (!empty($errors)) { - // Composer-Setup.exe uses "Some settings" to flag platform errors - out('Some settings on your machine make Composer unable to work properly.', 'error'); - out('Make sure that you fix the issues listed below and run this script again:', 'error'); - outputIssues($errors); - return false; - } - - if (empty($warnings) && !$quiet) { - out('All settings correct for using Composer', 'success'); - } - return true; -} - -/** - * Checks platform configuration for common incompatibility issues - * - * @param array $errors Populated by method - * @param array $warnings Populated by method - * @param bool $install If we are installing, rather than diagnosing - * - * @return bool If any errors or warnings have been found - */ -function getPlatformIssues(&$errors, &$warnings, $install) -{ - $errors = array(); - $warnings = array(); - - if ($iniPath = php_ini_loaded_file()) { - $iniMessage = PHP_EOL.'The php.ini used by your command-line PHP is: ' . $iniPath; - } else { - $iniMessage = PHP_EOL.'A php.ini file does not exist. You will have to create one.'; - } - $iniMessage .= PHP_EOL.'If you can not modify the ini file, you can also run `php -d option=value` to modify ini values on the fly. You can use -d multiple times.'; - - if (ini_get('detect_unicode')) { - $errors['unicode'] = array( - 'The detect_unicode setting must be disabled.', - 'Add the following to the end of your `php.ini`:', - ' detect_unicode = Off', - $iniMessage - ); - } - - if (extension_loaded('suhosin')) { - $suhosin = ini_get('suhosin.executor.include.whitelist'); - $suhosinBlacklist = ini_get('suhosin.executor.include.blacklist'); - if (false === stripos($suhosin, 'phar') && (!$suhosinBlacklist || false !== stripos($suhosinBlacklist, 'phar'))) { - $errors['suhosin'] = array( - 'The suhosin.executor.include.whitelist setting is incorrect.', - 'Add the following to the end of your `php.ini` or suhosin.ini (Example path [for Debian]: /etc/php5/cli/conf.d/suhosin.ini):', - ' suhosin.executor.include.whitelist = phar '.$suhosin, - $iniMessage - ); - } - } - - if (!function_exists('json_decode')) { - $errors['json'] = array( - 'The json extension is missing.', - 'Install it or recompile php without --disable-json' - ); - } - - if (!extension_loaded('Phar')) { - $errors['phar'] = array( - 'The phar extension is missing.', - 'Install it or recompile php without --disable-phar' - ); - } - - if (!extension_loaded('filter')) { - $errors['filter'] = array( - 'The filter extension is missing.', - 'Install it or recompile php without --disable-filter' - ); - } - - if (!extension_loaded('hash')) { - $errors['hash'] = array( - 'The hash extension is missing.', - 'Install it or recompile php without --disable-hash' - ); - } - - if (!extension_loaded('iconv') && !extension_loaded('mbstring')) { - $errors['iconv_mbstring'] = array( - 'The iconv OR mbstring extension is required and both are missing.', - 'Install either of them or recompile php without --disable-iconv' - ); - } - - if (!ini_get('allow_url_fopen')) { - $errors['allow_url_fopen'] = array( - 'The allow_url_fopen setting is incorrect.', - 'Add the following to the end of your `php.ini`:', - ' allow_url_fopen = On', - $iniMessage - ); - } - - if (extension_loaded('ionCube Loader') && ioncube_loader_iversion() < 40009) { - $ioncube = ioncube_loader_version(); - $errors['ioncube'] = array( - 'Your ionCube Loader extension ('.$ioncube.') is incompatible with Phar files.', - 'Upgrade to ionCube 4.0.9 or higher or remove this line (path may be different) from your `php.ini` to disable it:', - ' zend_extension = /usr/lib/php5/20090626+lfs/ioncube_loader_lin_5.3.so', - $iniMessage - ); - } - - if (version_compare(PHP_VERSION, '5.3.2', '<')) { - $errors['php'] = array( - 'Your PHP ('.PHP_VERSION.') is too old, you must upgrade to PHP 5.3.2 or higher.' - ); - } - - if (version_compare(PHP_VERSION, '5.3.4', '<')) { - $warnings['php'] = array( - 'Your PHP ('.PHP_VERSION.') is quite old, upgrading to PHP 5.3.4 or higher is recommended.', - 'Composer works with 5.3.2+ for most people, but there might be edge case issues.' - ); - } - - if (!extension_loaded('openssl')) { - $warnings['openssl'] = array( - 'The openssl extension is missing, which means that secure HTTPS transfers are impossible.', - 'If possible you should enable it or recompile php with --with-openssl' - ); - } - - if (extension_loaded('openssl') && OPENSSL_VERSION_NUMBER < 0x1000100f) { - // Attempt to parse version number out, fallback to whole string value. - $opensslVersion = trim(strstr(OPENSSL_VERSION_TEXT, ' ')); - $opensslVersion = substr($opensslVersion, 0, strpos($opensslVersion, ' ')); - $opensslVersion = $opensslVersion ? $opensslVersion : OPENSSL_VERSION_TEXT; - - $warnings['openssl_version'] = array( - 'The OpenSSL library ('.$opensslVersion.') used by PHP does not support TLSv1.2 or TLSv1.1.', - 'If possible you should upgrade OpenSSL to version 1.0.1 or above.' - ); - } - - if (!defined('HHVM_VERSION') && !extension_loaded('apcu') && ini_get('apc.enable_cli')) { - $warnings['apc_cli'] = array( - 'The apc.enable_cli setting is incorrect.', - 'Add the following to the end of your `php.ini`:', - ' apc.enable_cli = Off', - $iniMessage - ); - } - - if (!$install && extension_loaded('xdebug')) { - $warnings['xdebug_loaded'] = array( - 'The xdebug extension is loaded, this can slow down Composer a little.', - 'Disabling it when using Composer is recommended.' - ); - - if (ini_get('xdebug.profiler_enabled')) { - $warnings['xdebug_profile'] = array( - 'The xdebug.profiler_enabled setting is enabled, this can slow down Composer a lot.', - 'Add the following to the end of your `php.ini` to disable it:', - ' xdebug.profiler_enabled = 0', - $iniMessage - ); - } - } - - if (!extension_loaded('zlib')) { - $warnings['zlib'] = array( - 'The zlib extension is not loaded, this can slow down Composer a lot.', - 'If possible, install it or recompile php with --with-zlib', - $iniMessage - ); - } - - if (defined('PHP_WINDOWS_VERSION_BUILD') - && (version_compare(PHP_VERSION, '7.2.23', '<') - || (version_compare(PHP_VERSION, '7.3.0', '>=') - && version_compare(PHP_VERSION, '7.3.10', '<')))) { - $warnings['onedrive'] = array( - 'The Windows OneDrive folder is not supported on PHP versions below 7.2.23 and 7.3.10.', - 'Upgrade your PHP ('.PHP_VERSION.') to use this location with Composer.' - ); - } - - if (extension_loaded('uopz') && !(ini_get('uopz.disable') || ini_get('uopz.exit'))) { - $warnings['uopz'] = array( - 'The uopz extension ignores exit calls and may not work with all Composer commands.', - 'Disabling it when using Composer is recommended.' - ); - } - - ob_start(); - phpinfo(INFO_GENERAL); - $phpinfo = ob_get_clean(); - if (preg_match('{Configure Command(?: *| *=> *)(.*?)(?:|$)}m', $phpinfo, $match)) { - $configure = $match[1]; - - if (false !== strpos($configure, '--enable-sigchild')) { - $warnings['sigchild'] = array( - 'PHP was compiled with --enable-sigchild which can cause issues on some platforms.', - 'Recompile it without this flag if possible, see also:', - ' https://bugs.php.net/bug.php?id=22999' - ); - } - - if (false !== strpos($configure, '--with-curlwrappers')) { - $warnings['curlwrappers'] = array( - 'PHP was compiled with --with-curlwrappers which will cause issues with HTTP authentication and GitHub.', - 'Recompile it without this flag if possible' - ); - } - } - - // Stringify the message arrays - foreach ($errors as $key => $value) { - $errors[$key] = PHP_EOL.implode(PHP_EOL, $value); - } - - foreach ($warnings as $key => $value) { - $warnings[$key] = PHP_EOL.implode(PHP_EOL, $value); - } - - return !empty($errors) || !empty($warnings); -} - - -/** - * Outputs an array of issues - * - * @param array $issues - */ -function outputIssues($issues) -{ - foreach ($issues as $issue) { - out($issue, 'info'); - } - out(''); -} - -/** - * Outputs any warnings found - * - * @param array $warnings - */ -function showWarnings($warnings) -{ - if (!empty($warnings)) { - out('Some settings on your machine may cause stability issues with Composer.', 'error'); - out('If you encounter issues, try to change the following:', 'error'); - outputIssues($warnings); - } -} - -/** - * Outputs an end of process warning if tls has been bypassed - * - * @param bool $disableTls Bypass tls - */ -function showSecurityWarning($disableTls) -{ - if ($disableTls) { - out('You have instructed the Installer not to enforce SSL/TLS security on remote HTTPS requests.', 'info'); - out('This will leave all downloads during installation vulnerable to Man-In-The-Middle (MITM) attacks', 'info'); - } -} - -/** - * colorize output - */ -function out($text, $color = null, $newLine = true) -{ - $styles = array( - 'success' => "\033[0;32m%s\033[0m", - 'error' => "\033[31;31m%s\033[0m", - 'info' => "\033[33;33m%s\033[0m" - ); - - $format = '%s'; - - if (isset($styles[$color]) && USE_ANSI) { - $format = $styles[$color]; - } - - if ($newLine) { - $format .= PHP_EOL; - } - - printf($format, $text); -} - -/** - * Returns the system-dependent Composer home location, which may not exist - * - * @return string - */ -function getHomeDir() -{ - $home = getenv('COMPOSER_HOME'); - - if (!$home) { - $userDir = getUserDir(); - - if (defined('PHP_WINDOWS_VERSION_MAJOR')) { - $home = $userDir.'/Composer'; - } else { - $home = $userDir.'/.composer'; - - if (!is_dir($home) && useXdg()) { - // XDG Base Directory Specifications - if (!($xdgConfig = getenv('XDG_CONFIG_HOME'))) { - $xdgConfig = $userDir.'/.config'; - } - $home = $xdgConfig.'/composer'; - } - } - } - return $home; -} - -/** - * Returns the location of the user directory from the environment - * @throws RuntimeException If the environment value does not exists - * - * @return string - */ -function getUserDir() -{ - $userEnv = defined('PHP_WINDOWS_VERSION_MAJOR') ? 'APPDATA' : 'HOME'; - $userDir = getenv($userEnv); - - if (!$userDir) { - throw new RuntimeException('The '.$userEnv.' or COMPOSER_HOME environment variable must be set for composer to run correctly'); - } - - return rtrim(strtr($userDir, '\\', '/'), '/'); -} - -/** - * @return bool - */ -function useXdg() -{ - foreach (array_keys($_SERVER) as $key) { - if (strpos($key, 'XDG_') === 0) { - return true; - } - } - return false; -} - -function validateCaFile($contents) -{ - // assume the CA is valid if php is vulnerable to - // https://www.sektioneins.de/advisories/advisory-012013-php-openssl_x509_parse-memory-corruption-vulnerability.html - if ( - PHP_VERSION_ID <= 50327 - || (PHP_VERSION_ID >= 50400 && PHP_VERSION_ID < 50422) - || (PHP_VERSION_ID >= 50500 && PHP_VERSION_ID < 50506) - ) { - return !empty($contents); - } - - return (bool) openssl_x509_parse($contents); -} - -class Installer -{ - private $quiet; - private $disableTls; - private $cafile; - private $displayPath; - private $target; - private $tmpFile; - private $baseUrl; - private $algo; - private $errHandler; - private $httpClient; - private $pubKeys = array(); - private $installs = array(); - - /** - * Constructor - must not do anything that throws an exception - * - * @param bool $quiet Quiet mode - * @param bool $disableTls Bypass tls - * @param mixed $cafile Path to CA bundle, or false - */ - public function __construct($quiet, $disableTls, $caFile) - { - if (($this->quiet = $quiet)) { - ob_start(); - } - $this->disableTls = $disableTls; - $this->cafile = $caFile; - $this->errHandler = new ErrorHandler(); - } - - /** - * Runs the installer - * - * @param mixed $version Specific version to install, or false - * @param mixed $installDir Specific installation directory, or false - * @param string $filename Specific filename to save to, or composer.phar - * @param string $channel Specific version channel to use - * @throws Exception If anything other than a RuntimeException is caught - * - * @return bool If the installation succeeded - */ - public function run($version, $installDir, $filename, $channel) - { - try { - $this->initTargets($installDir, $filename); - $this->initTls(); - $this->httpClient = new HttpClient($this->disableTls, $this->cafile); - $result = $this->install($version, $channel); - - // in case --1 or --2 is passed, we leave the default channel for next self-update to stable - if (is_numeric($channel)) { - $channel = 'stable'; - } - - if ($result && $channel !== 'stable' && !$version && defined('PHP_BINARY')) { - $null = (defined('PHP_WINDOWS_VERSION_MAJOR') ? 'NUL' : '/dev/null'); - @exec(escapeshellarg(PHP_BINARY) .' '.escapeshellarg($this->target).' self-update --'.$channel.' --set-channel-only -q > '.$null.' 2> '.$null, $output); - } - } catch (Exception $e) { - $result = false; - } - - // Always clean up - $this->cleanUp($result); - - if (isset($e)) { - // Rethrow anything that is not a RuntimeException - if (!$e instanceof RuntimeException) { - throw $e; - } - out($e->getMessage(), 'error'); - } - return $result; - } - - /** - * Initialization methods to set the required filenames and composer url - * - * @param mixed $installDir Specific installation directory, or false - * @param string $filename Specific filename to save to, or composer.phar - * @throws RuntimeException If the installation directory is not writable - */ - protected function initTargets($installDir, $filename) - { - $this->displayPath = ($installDir ? rtrim($installDir, '/').'/' : '').$filename; - $installDir = $installDir ? realpath($installDir) : getcwd(); - - if (!is_writeable($installDir)) { - throw new RuntimeException('The installation directory "'.$installDir.'" is not writable'); - } - - $this->target = $installDir.DIRECTORY_SEPARATOR.$filename; - $this->tmpFile = $installDir.DIRECTORY_SEPARATOR.basename($this->target, '.phar').'-temp.phar'; - - $uriScheme = $this->disableTls ? 'http' : 'https'; - $this->baseUrl = $uriScheme.'://getcomposer.org'; - } - - /** - * A wrapper around methods to check tls and write public keys - * @throws RuntimeException If SHA384 is not supported - */ - protected function initTls() - { - if ($this->disableTls) { - return; - } - - if (!in_array('sha384', array_map('strtolower', openssl_get_md_methods()))) { - throw new RuntimeException('SHA384 is not supported by your openssl extension'); - } - - $this->algo = defined('OPENSSL_ALGO_SHA384') ? OPENSSL_ALGO_SHA384 : 'SHA384'; - $home = $this->getComposerHome(); - - $this->pubKeys = array( - 'dev' => $this->installKey(self::getPKDev(), $home, 'keys.dev.pub'), - 'tags' => $this->installKey(self::getPKTags(), $home, 'keys.tags.pub') - ); - - if (empty($this->cafile) && !HttpClient::getSystemCaRootBundlePath()) { - $this->cafile = $this->installKey(HttpClient::getPackagedCaFile(), $home, 'cacert.pem'); - } - } - - /** - * Returns the Composer home directory, creating it if required - * @throws RuntimeException If the directory cannot be created - * - * @return string - */ - protected function getComposerHome() - { - $home = getHomeDir(); - - if (!is_dir($home)) { - $this->errHandler->start(); - - if (!mkdir($home, 0777, true)) { - throw new RuntimeException(sprintf( - 'Unable to create Composer home directory "%s": %s', - $home, - $this->errHandler->message - )); - } - $this->installs[] = $home; - $this->errHandler->stop(); - } - return $home; - } - - /** - * Writes public key data to disc - * - * @param string $data The public key(s) in pem format - * @param string $path The directory to write to - * @param string $filename The name of the file - * @throws RuntimeException If the file cannot be written - * - * @return string The path to the saved data - */ - protected function installKey($data, $path, $filename) - { - $this->errHandler->start(); - - $target = $path.DIRECTORY_SEPARATOR.$filename; - $installed = file_exists($target); - $write = file_put_contents($target, $data, LOCK_EX); - @chmod($target, 0644); - - $this->errHandler->stop(); - - if (!$write) { - throw new RuntimeException(sprintf('Unable to write %s to: %s', $filename, $path)); - } - - if (!$installed) { - $this->installs[] = $target; - } - - return $target; - } - - /** - * The main install function - * - * @param mixed $version Specific version to install, or false - * @param string $channel Version channel to use - * - * @return bool If the installation succeeded - */ - protected function install($version, $channel) - { - $retries = 3; - $result = false; - $infoMsg = 'Downloading...'; - $infoType = 'info'; - - while ($retries--) { - if (!$this->quiet) { - out($infoMsg, $infoType); - $infoMsg = 'Retrying...'; - $infoType = 'error'; - } - - if (!$this->getVersion($channel, $version, $url, $error)) { - out($error, 'error'); - continue; - } - - if (!$this->downloadToTmp($url, $signature, $error)) { - out($error, 'error'); - continue; - } - - if (!$this->verifyAndSave($version, $signature, $error)) { - out($error, 'error'); - continue; - } - - $result = true; - break; - } - - if (!$this->quiet) { - if ($result) { - out(PHP_EOL."Composer (version {$version}) successfully installed to: {$this->target}", 'success'); - out("Use it: php {$this->displayPath}", 'info'); - out(''); - } else { - out('The download failed repeatedly, aborting.', 'error'); - } - } - return $result; - } - - /** - * Sets the version url, downloading version data if required - * - * @param string $channel Version channel to use - * @param false|string $version Version to install, or set by method - * @param null|string $url The versioned url, set by method - * @param null|string $error Set by method on failure - * - * @return bool If the operation succeeded - */ - protected function getVersion($channel, &$version, &$url, &$error) - { - $error = ''; - - if ($version) { - if (empty($url)) { - $url = $this->baseUrl."/download/{$version}/composer.phar"; - } - return true; - } - - $this->errHandler->start(); - - if ($this->downloadVersionData($data, $error)) { - $this->parseVersionData($data, $channel, $version, $url); - } - - $this->errHandler->stop(); - return empty($error); - } - - /** - * Downloads and json-decodes version data - * - * @param null|array $data Downloaded version data, set by method - * @param null|string $error Set by method on failure - * - * @return bool If the operation succeeded - */ - protected function downloadVersionData(&$data, &$error) - { - $url = $this->baseUrl.'/versions'; - $errFmt = 'The "%s" file could not be %s: %s'; - - if (!$json = $this->httpClient->get($url)) { - $error = sprintf($errFmt, $url, 'downloaded', $this->errHandler->message); - return false; - } - - if (!$data = json_decode($json, true)) { - $error = sprintf($errFmt, $url, 'json-decoded', $this->getJsonError()); - return false; - } - return true; - } - - /** - * A wrapper around the methods needed to download and save the phar - * - * @param string $url The versioned download url - * @param null|string $signature Set by method on successful download - * @param null|string $error Set by method on failure - * - * @return bool If the operation succeeded - */ - protected function downloadToTmp($url, &$signature, &$error) - { - $error = ''; - $errFmt = 'The "%s" file could not be downloaded: %s'; - $sigUrl = $url.'.sig'; - $this->errHandler->start(); - - if (!$fh = fopen($this->tmpFile, 'w')) { - $error = sprintf('Could not create file "%s": %s', $this->tmpFile, $this->errHandler->message); - - } elseif (!$this->getSignature($sigUrl, $signature)) { - $error = sprintf($errFmt, $sigUrl, $this->errHandler->message); - - } elseif (!fwrite($fh, $this->httpClient->get($url))) { - $error = sprintf($errFmt, $url, $this->errHandler->message); - } - - if (is_resource($fh)) { - fclose($fh); - } - $this->errHandler->stop(); - return empty($error); - } - - /** - * Verifies the downloaded file and saves it to the target location - * - * @param string $version The composer version downloaded - * @param string $signature The digital signature to check - * @param null|string $error Set by method on failure - * - * @return bool If the operation succeeded - */ - protected function verifyAndSave($version, $signature, &$error) - { - $error = ''; - - if (!$this->validatePhar($this->tmpFile, $pharError)) { - $error = 'The download is corrupt: '.$pharError; - - } elseif (!$this->verifySignature($version, $signature, $this->tmpFile)) { - $error = 'Signature mismatch, could not verify the phar file integrity'; - - } else { - $this->errHandler->start(); - - if (!rename($this->tmpFile, $this->target)) { - $error = sprintf('Could not write to file "%s": %s', $this->target, $this->errHandler->message); - } - chmod($this->target, 0755); - $this->errHandler->stop(); - } - - return empty($error); - } - - /** - * Parses an array of version data to match the required channel - * - * @param array $data Downloaded version data - * @param mixed $channel Version channel to use - * @param false|string $version Set by method - * @param mixed $url The versioned url, set by method - */ - protected function parseVersionData(array $data, $channel, &$version, &$url) - { - foreach ($data[$channel] as $candidate) { - if ($candidate['min-php'] <= PHP_VERSION_ID) { - $version = $candidate['version']; - $url = $this->baseUrl.$candidate['path']; - break; - } - } - - if (!$version) { - $error = sprintf( - 'None of the %d %s version(s) of Composer matches your PHP version (%s / ID: %d)', - count($data[$channel]), - $channel, - PHP_VERSION, - PHP_VERSION_ID - ); - throw new RuntimeException($error); - } - } - - /** - * Downloads the digital signature of required phar file - * - * @param string $url The signature url - * @param null|string $signature Set by method on success - * - * @return bool If the download succeeded - */ - protected function getSignature($url, &$signature) - { - if (!$result = $this->disableTls) { - $signature = $this->httpClient->get($url); - - if ($signature) { - $signature = json_decode($signature, true); - $signature = base64_decode($signature['sha384']); - $result = true; - } - } - - return $result; - } - - /** - * Verifies the signature of the downloaded phar - * - * @param string $version The composer versione - * @param string $signature The downloaded digital signature - * @param string $file The temp phar file - * - * @return bool If the operation succeeded - */ - protected function verifySignature($version, $signature, $file) - { - if (!$result = $this->disableTls) { - $path = preg_match('{^[0-9a-f]{40}$}', $version) ? $this->pubKeys['dev'] : $this->pubKeys['tags']; - $pubkeyid = openssl_pkey_get_public('file://'.$path); - - $result = 1 === openssl_verify( - file_get_contents($file), - $signature, - $pubkeyid, - $this->algo - ); - - // PHP 8 automatically frees the key instance and deprecates the function - if (PHP_VERSION_ID < 80000) { - openssl_free_key($pubkeyid); - } - } - - return $result; - } - - /** - * Validates the downloaded phar file - * - * @param string $pharFile The temp phar file - * @param null|string $error Set by method on failure - * - * @return bool If the operation succeeded - */ - protected function validatePhar($pharFile, &$error) - { - if (ini_get('phar.readonly')) { - return true; - } - - try { - // Test the phar validity - $phar = new Phar($pharFile); - // Free the variable to unlock the file - unset($phar); - $result = true; - - } catch (Exception $e) { - if (!$e instanceof UnexpectedValueException && !$e instanceof PharException) { - throw $e; - } - $error = $e->getMessage(); - $result = false; - } - return $result; - } - - /** - * Returns a string representation of the last json error - * - * @return string The error string or code - */ - protected function getJsonError() - { - if (function_exists('json_last_error_msg')) { - return json_last_error_msg(); - } else { - return 'json_last_error = '.json_last_error(); - } - } - - /** - * Cleans up resources at the end of the installation - * - * @param bool $result If the installation succeeded - */ - protected function cleanUp($result) - { - if (!$result) { - // Output buffered errors - if ($this->quiet) { - $this->outputErrors(); - } - // Clean up stuff we created - $this->uninstall(); - } - } - - /** - * Outputs unique errors when in quiet mode - * - */ - protected function outputErrors() - { - $errors = explode(PHP_EOL, ob_get_clean()); - $shown = array(); - - foreach ($errors as $error) { - if ($error && !in_array($error, $shown)) { - out($error, 'error'); - $shown[] = $error; - } - } - } - - /** - * Uninstalls newly-created files and directories on failure - * - */ - protected function uninstall() - { - foreach (array_reverse($this->installs) as $target) { - if (is_file($target)) { - @unlink($target); - } elseif (is_dir($target)) { - @rmdir($target); - } - } - - if (file_exists($this->tmpFile)) { - @unlink($this->tmpFile); - } - } - - public static function getPKDev() - { - return <<message) { - $this->message .= PHP_EOL; - } - $this->message .= preg_replace('{^file_get_contents\(.*?\): }', '', $msg); - } - - /** - * Starts error-handling if not already active - * - * Any message is cleared - */ - public function start() - { - if (!$this->active) { - set_error_handler(array($this, 'handleError')); - $this->active = true; - } - $this->message = ''; - } - - /** - * Stops error-handling if active - * - * Any message is preserved until the next call to start() - */ - public function stop() - { - if ($this->active) { - restore_error_handler(); - $this->active = false; - } - } -} - -class NoProxyPattern -{ - private $composerInNoProxy = false; - private $rulePorts = array(); - - public function __construct($pattern) - { - $rules = preg_split('{[\s,]+}', $pattern, null, PREG_SPLIT_NO_EMPTY); - - if ($matches = preg_grep('{getcomposer\.org(?::\d+)?}i', $rules)) { - $this->composerInNoProxy = true; - - foreach ($matches as $match) { - if (strpos($match, ':') !== false) { - list(, $port) = explode(':', $match); - $this->rulePorts[] = (int) $port; - } - } - } - } - - /** - * Returns true if NO_PROXY contains getcomposer.org - * - * @param string $url http(s)://getcomposer.org - * - * @return bool - */ - public function test($url) - { - if (!$this->composerInNoProxy) { - return false; - } - - if (empty($this->rulePorts)) { - return true; - } - - if (strpos($url, 'http://') === 0) { - $port = 80; - } else { - $port = 443; - } - - return in_array($port, $this->rulePorts); - } -} - -class HttpClient { - - private $options = array('http' => array()); - private $disableTls = false; - - public function __construct($disableTls = false, $cafile = false) - { - $this->disableTls = $disableTls; - if ($this->disableTls === false) { - if (!empty($cafile) && !is_dir($cafile)) { - if (!is_readable($cafile) || !validateCaFile(file_get_contents($cafile))) { - throw new RuntimeException('The configured cafile (' .$cafile. ') was not valid or could not be read.'); - } - } - $options = $this->getTlsStreamContextDefaults($cafile); - $this->options = array_replace_recursive($this->options, $options); - } - } - - public function get($url) - { - $context = $this->getStreamContext($url); - $result = file_get_contents($url, false, $context); - - if ($result && extension_loaded('zlib')) { - $decode = false; - foreach ($http_response_header as $header) { - if (preg_match('{^content-encoding: *gzip *$}i', $header)) { - $decode = true; - continue; - } elseif (preg_match('{^HTTP/}i', $header)) { - $decode = false; - } - } - - if ($decode) { - if (version_compare(PHP_VERSION, '5.4.0', '>=')) { - $result = zlib_decode($result); - } else { - // work around issue with gzuncompress & co that do not work with all gzip checksums - $result = file_get_contents('compress.zlib://data:application/octet-stream;base64,'.base64_encode($result)); - } - - if (!$result) { - throw new RuntimeException('Failed to decode zlib stream'); - } - } - } - - return $result; - } - - protected function getStreamContext($url) - { - if ($this->disableTls === false) { - if (PHP_VERSION_ID < 50600) { - $this->options['ssl']['SNI_server_name'] = parse_url($url, PHP_URL_HOST); - } - } - // Keeping the above mostly isolated from the code copied from Composer. - return $this->getMergedStreamContext($url); - } - - protected function getTlsStreamContextDefaults($cafile) - { - $ciphers = implode(':', array( - 'ECDHE-RSA-AES128-GCM-SHA256', - 'ECDHE-ECDSA-AES128-GCM-SHA256', - 'ECDHE-RSA-AES256-GCM-SHA384', - 'ECDHE-ECDSA-AES256-GCM-SHA384', - 'DHE-RSA-AES128-GCM-SHA256', - 'DHE-DSS-AES128-GCM-SHA256', - 'kEDH+AESGCM', - 'ECDHE-RSA-AES128-SHA256', - 'ECDHE-ECDSA-AES128-SHA256', - 'ECDHE-RSA-AES128-SHA', - 'ECDHE-ECDSA-AES128-SHA', - 'ECDHE-RSA-AES256-SHA384', - 'ECDHE-ECDSA-AES256-SHA384', - 'ECDHE-RSA-AES256-SHA', - 'ECDHE-ECDSA-AES256-SHA', - 'DHE-RSA-AES128-SHA256', - 'DHE-RSA-AES128-SHA', - 'DHE-DSS-AES128-SHA256', - 'DHE-RSA-AES256-SHA256', - 'DHE-DSS-AES256-SHA', - 'DHE-RSA-AES256-SHA', - 'AES128-GCM-SHA256', - 'AES256-GCM-SHA384', - 'AES128-SHA256', - 'AES256-SHA256', - 'AES128-SHA', - 'AES256-SHA', - 'AES', - 'CAMELLIA', - 'DES-CBC3-SHA', - '!aNULL', - '!eNULL', - '!EXPORT', - '!DES', - '!RC4', - '!MD5', - '!PSK', - '!aECDH', - '!EDH-DSS-DES-CBC3-SHA', - '!EDH-RSA-DES-CBC3-SHA', - '!KRB5-DES-CBC3-SHA', - )); - - /** - * CN_match and SNI_server_name are only known once a URL is passed. - * They will be set in the getOptionsForUrl() method which receives a URL. - * - * cafile or capath can be overridden by passing in those options to constructor. - */ - $options = array( - 'ssl' => array( - 'ciphers' => $ciphers, - 'verify_peer' => true, - 'verify_depth' => 7, - 'SNI_enabled' => true, - ) - ); - - /** - * Attempt to find a local cafile or throw an exception. - * The user may go download one if this occurs. - */ - if (!$cafile) { - $cafile = self::getSystemCaRootBundlePath(); - } - if (is_dir($cafile)) { - $options['ssl']['capath'] = $cafile; - } elseif ($cafile) { - $options['ssl']['cafile'] = $cafile; - } else { - throw new RuntimeException('A valid cafile could not be located automatically.'); - } - - /** - * Disable TLS compression to prevent CRIME attacks where supported. - */ - if (version_compare(PHP_VERSION, '5.4.13') >= 0) { - $options['ssl']['disable_compression'] = true; - } - - return $options; - } - - /** - * function copied from Composer\Util\StreamContextFactory::initOptions - * - * Any changes should be applied there as well, or backported here. - * - * @param string $url URL the context is to be used for - * @return resource Default context - * @throws \RuntimeException if https proxy required and OpenSSL uninstalled - */ - protected function getMergedStreamContext($url) - { - $options = $this->options; - - // Handle HTTP_PROXY/http_proxy on CLI only for security reasons - if ((PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') && (!empty($_SERVER['HTTP_PROXY']) || !empty($_SERVER['http_proxy']))) { - $proxy = parse_url(!empty($_SERVER['http_proxy']) ? $_SERVER['http_proxy'] : $_SERVER['HTTP_PROXY']); - } - - // Prefer CGI_HTTP_PROXY if available - if (!empty($_SERVER['CGI_HTTP_PROXY'])) { - $proxy = parse_url($_SERVER['CGI_HTTP_PROXY']); - } - - // Override with HTTPS proxy if present and URL is https - if (preg_match('{^https://}i', $url) && (!empty($_SERVER['HTTPS_PROXY']) || !empty($_SERVER['https_proxy']))) { - $proxy = parse_url(!empty($_SERVER['https_proxy']) ? $_SERVER['https_proxy'] : $_SERVER['HTTPS_PROXY']); - } - - // Remove proxy if URL matches no_proxy directive - if (!empty($_SERVER['NO_PROXY']) || !empty($_SERVER['no_proxy']) && parse_url($url, PHP_URL_HOST)) { - $pattern = new NoProxyPattern(!empty($_SERVER['no_proxy']) ? $_SERVER['no_proxy'] : $_SERVER['NO_PROXY']); - if ($pattern->test($url)) { - unset($proxy); - } - } - - if (!empty($proxy)) { - $proxyURL = isset($proxy['scheme']) ? $proxy['scheme'] . '://' : ''; - $proxyURL .= isset($proxy['host']) ? $proxy['host'] : ''; - - if (isset($proxy['port'])) { - $proxyURL .= ":" . $proxy['port']; - } elseif (strpos($proxyURL, 'http://') === 0) { - $proxyURL .= ":80"; - } elseif (strpos($proxyURL, 'https://') === 0) { - $proxyURL .= ":443"; - } - - // http(s):// is not supported in proxy - $proxyURL = str_replace(array('http://', 'https://'), array('tcp://', 'ssl://'), $proxyURL); - - if (0 === strpos($proxyURL, 'ssl:') && !extension_loaded('openssl')) { - throw new RuntimeException('You must enable the openssl extension to use a proxy over https'); - } - - $options['http'] = array( - 'proxy' => $proxyURL, - ); - - // set request_fulluri, depending on default requirements and the environment - switch (parse_url($url, PHP_URL_SCHEME)) { - case 'http': // default is true for HTTP, check if explicitly disabled - $reqFullUriEnv = getenv('HTTP_PROXY_REQUEST_FULLURI'); - if ($reqFullUriEnv === false || $reqFullUriEnv === '' || (strtolower($reqFullUriEnv) !== 'false' && (bool) $reqFullUriEnv)) { - $options['http']['request_fulluri'] = true; - } - break; - case 'https': // default is false for HTTPS, check if explicitly enabled - $reqFullUriEnv = getenv('HTTPS_PROXY_REQUEST_FULLURI'); - if (strtolower($reqFullUriEnv) !== 'false' && (bool) $reqFullUriEnv) { - $options['http']['request_fulluri'] = true; - } - break; - } - - // handle proxy auth if present - if (isset($proxy['user'])) { - $auth = rawurldecode($proxy['user']); - if (isset($proxy['pass'])) { - $auth .= ':' . rawurldecode($proxy['pass']); - } - $auth = base64_encode($auth); - - $options['http']['header'] = "Proxy-Authorization: Basic {$auth}\r\n"; - } - } - - if (isset($options['http']['header'])) { - $options['http']['header'] .= "Connection: close\r\n"; - } else { - $options['http']['header'] = "Connection: close\r\n"; - } - if (extension_loaded('zlib')) { - $options['http']['header'] .= "Accept-Encoding: gzip\r\n"; - } - $options['http']['header'] .= "User-Agent: ".COMPOSER_INSTALLER."\r\n"; - $options['http']['protocol_version'] = 1.1; - $options['http']['timeout'] = 600; - - return stream_context_create($options); - } - - /** - * This method was adapted from Sslurp. - * https://github.com/EvanDotPro/Sslurp - * - * (c) Evan Coury - * - * For the full copyright and license information, please see below: - * - * Copyright (c) 2013, Evan Coury - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - public static function getSystemCaRootBundlePath() - { - static $caPath = null; - - if ($caPath !== null) { - return $caPath; - } - - // If SSL_CERT_FILE env variable points to a valid certificate/bundle, use that. - // This mimics how OpenSSL uses the SSL_CERT_FILE env variable. - $envCertFile = getenv('SSL_CERT_FILE'); - if ($envCertFile && is_readable($envCertFile) && validateCaFile(file_get_contents($envCertFile))) { - return $caPath = $envCertFile; - } - - // If SSL_CERT_DIR env variable points to a valid certificate/bundle, use that. - // This mimics how OpenSSL uses the SSL_CERT_FILE env variable. - $envCertDir = getenv('SSL_CERT_DIR'); - if ($envCertDir && is_dir($envCertDir) && is_readable($envCertDir)) { - return $caPath = $envCertDir; - } - - $configured = ini_get('openssl.cafile'); - if ($configured && strlen($configured) > 0 && is_readable($configured) && validateCaFile(file_get_contents($configured))) { - return $caPath = $configured; - } - - $configured = ini_get('openssl.capath'); - if ($configured && is_dir($configured) && is_readable($configured)) { - return $caPath = $configured; - } - - $caBundlePaths = array( - '/etc/pki/tls/certs/ca-bundle.crt', // Fedora, RHEL, CentOS (ca-certificates package) - '/etc/ssl/certs/ca-certificates.crt', // Debian, Ubuntu, Gentoo, Arch Linux (ca-certificates package) - '/etc/ssl/ca-bundle.pem', // SUSE, openSUSE (ca-certificates package) - '/usr/local/share/certs/ca-root-nss.crt', // FreeBSD (ca_root_nss_package) - '/usr/ssl/certs/ca-bundle.crt', // Cygwin - '/opt/local/share/curl/curl-ca-bundle.crt', // OS X macports, curl-ca-bundle package - '/usr/local/share/curl/curl-ca-bundle.crt', // Default cURL CA bunde path (without --with-ca-bundle option) - '/usr/share/ssl/certs/ca-bundle.crt', // Really old RedHat? - '/etc/ssl/cert.pem', // OpenBSD - '/usr/local/etc/ssl/cert.pem', // FreeBSD 10.x - '/usr/local/etc/openssl/cert.pem', // OS X homebrew, openssl package - '/usr/local/etc/openssl@1.1/cert.pem', // OS X homebrew, openssl@1.1 package - ); - - foreach ($caBundlePaths as $caBundle) { - if (@is_readable($caBundle) && validateCaFile(file_get_contents($caBundle))) { - return $caPath = $caBundle; - } - } - - foreach ($caBundlePaths as $caBundle) { - $caBundle = dirname($caBundle); - if (is_dir($caBundle) && glob($caBundle.'/*')) { - return $caPath = $caBundle; - } - } - - return $caPath = false; - } - - public static function getPackagedCaFile() - { - return <<=7.2.5", + "psr/log": "^1|^2|^3", + "symfony/http-client-contracts": "^2.2", + "symfony/polyfill-php73": "^1.11", + "symfony/polyfill-php80": "^1.16", + "symfony/service-contracts": "^1.0|^2" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "2.2" + }, + "require-dev": { + "amphp/amp": "^2.5", + "amphp/http-client": "^4.2.1", + "amphp/http-tunnel": "^1.0", + "amphp/socket": "^1.1", + "guzzlehttp/promises": "^1.4", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "psr/http-client": "^1.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/http-kernel": "^4.4.13|^5.1.5", + "symfony/process": "^4.4|^5.0", + "symfony/stopwatch": "^4.4|^5.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-client/tree/v5.2.12" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-07-23T15:55:19+00:00" + }, { "name": "symfony/http-client-contracts", "version": "v2.4.0", @@ -7614,5 +7697,5 @@ "ext-json": "*" }, "platform-dev": [], - "plugin-api-version": "2.0.0" + "plugin-api-version": "2.3.0" } diff --git a/config/packages/prod/monolog.yaml b/config/packages/prod/monolog.yaml index ed99010..2b02fa0 100755 --- a/config/packages/prod/monolog.yaml +++ b/config/packages/prod/monolog.yaml @@ -1,9 +1,9 @@ -monolog: - handlers: - main: - type: rotating_file - path: '%kernel.logs_dir%/%kernel.environment%.log' - level: debug +#monolog: +# handlers: +# main: +# type: rotating_file +# path: '%kernel.logs_dir%/%kernel.environment%.log' +# level: debug # max number of log files to keep # defaults to zero, which means infinite files - max_files: 10 +# max_files: 10