From f78ffd98795c36a739228fc52711ad6f15d0eaae Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Sun, 16 Apr 2017 21:07:51 +0200 Subject: Bump composer Signed-off-by: Lukas Reschke --- vendor/autoload.php | 2 +- vendor/composer/ClassLoader.php | 46 ++++++++++++++++++++++++++++++++------- vendor/composer/LICENSE | 2 +- vendor/composer/autoload_real.php | 2 +- vendor/composer/installed.json | 8 +++---- 5 files changed, 45 insertions(+), 15 deletions(-) diff --git a/vendor/autoload.php b/vendor/autoload.php index e277114..c749f66 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -2,6 +2,6 @@ // autoload.php @generated by Composer -require_once __DIR__ . '/composer' . '/autoload_real.php'; +require_once __DIR__ . '/composer/autoload_real.php'; return ComposerAutoloaderInit994b8d870ddb923ebc3ff0ceaaaa96a6::getLoader(); diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php index ac67d30..2c72175 100644 --- a/vendor/composer/ClassLoader.php +++ b/vendor/composer/ClassLoader.php @@ -55,6 +55,7 @@ class ClassLoader private $classMap = array(); private $classMapAuthoritative = false; private $missingClasses = array(); + private $apcuPrefix; public function getPrefixes() { @@ -271,6 +272,26 @@ class ClassLoader return $this->classMapAuthoritative; } + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + /** * Registers this instance as an autoloader. * @@ -313,11 +334,6 @@ class ClassLoader */ public function findFile($class) { - // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731 - if ('\\' == $class[0]) { - $class = substr($class, 1); - } - // class map lookup if (isset($this->classMap[$class])) { return $this->classMap[$class]; @@ -325,6 +341,12 @@ class ClassLoader if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { return false; } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } $file = $this->findFileWithExtension($class, '.php'); @@ -333,6 +355,10 @@ class ClassLoader $file = $this->findFileWithExtension($class, '.hh'); } + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + if (false === $file) { // Remember that this class does not exist. $this->missingClasses[$class] = true; @@ -348,9 +374,13 @@ class ClassLoader $first = $class[0]; if (isset($this->prefixLengthsPsr4[$first])) { - foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) { - if (0 === strpos($class, $prefix)) { - foreach ($this->prefixDirsPsr4[$prefix] as $dir) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath.'\\'; + if (isset($this->prefixDirsPsr4[$search])) { + foreach ($this->prefixDirsPsr4[$search] as $dir) { + $length = $this->prefixLengthsPsr4[$first][$search]; if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { return $file; } diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE index 1a28124..f27399a 100644 --- a/vendor/composer/LICENSE +++ b/vendor/composer/LICENSE @@ -1,5 +1,5 @@ -Copyright (c) 2016 Nils Adermann, Jordi Boggiano +Copyright (c) Nils Adermann, Jordi Boggiano Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 38d2ec6..b42ef68 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -23,7 +23,7 @@ class ComposerAutoloaderInit994b8d870ddb923ebc3ff0ceaaaa96a6 self::$loader = $loader = new \Composer\Autoload\ClassLoader(); spl_autoload_unregister(array('ComposerAutoloaderInit994b8d870ddb923ebc3ff0ceaaaa96a6', 'loadClassLoader')); - $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION'); + $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); if ($useStaticLoader) { require_once __DIR__ . '/autoload_static.php'; diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index c084769..a0c7fd4 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -17,7 +17,7 @@ "require": { "php": ">=5.3.0" }, - "time": "2016-10-10 12:19:37", + "time": "2016-10-10T12:19:37+00:00", "type": "library", "extra": { "branch-alias": { @@ -74,7 +74,7 @@ "symfony/class-loader": "~2.8|~3.0", "symfony/http-kernel": "~2.8|~3.0" }, - "time": "2016-09-06 11:02:40", + "time": "2016-09-06T11:02:40+00:00", "type": "library", "extra": { "branch-alias": { @@ -128,7 +128,7 @@ "suggest": { "ext-mbstring": "For best performance" }, - "time": "2016-05-18 14:26:46", + "time": "2016-05-18T14:26:46+00:00", "type": "library", "extra": { "branch-alias": { @@ -198,7 +198,7 @@ "symfony/event-dispatcher": "", "symfony/process": "" }, - "time": "2016-10-06 01:44:51", + "time": "2016-10-06T01:44:51+00:00", "type": "library", "extra": { "branch-alias": { -- cgit v1.2.3 From 960c1aaaaf1c6ce3ab7579040a59e28baee4be99 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Sun, 16 Apr 2017 21:08:50 +0200 Subject: Verify integrity of downloaded update This verifies the integrity of the downloaded update using OpenSSL. The certificate is the one that we also use for the regular code signing. Signed-off-by: Lukas Reschke --- index.php | 189 ++++++++++++++++++++++++++++++++++++++------------ lib/UpdateCommand.php | 41 ++++++----- lib/Updater.php | 107 ++++++++++++++++++++++++---- updater.phar | Bin 591718 -> 595635 bytes 4 files changed, 260 insertions(+), 77 deletions(-) diff --git a/index.php b/index.php index 3f14aa5..4307f00 100644 --- a/index.php +++ b/index.php @@ -1,6 +1,6 @@ + * @copyright Copyright (c) 2016-2017 Lukas Reschke * @copyright Copyright (c) 2016 Morris Jobke * * @license GNU AGPL version 3 or any later version @@ -216,6 +216,15 @@ class Updater { return $this->currentVersion; } + /** + * Returns currently used release channel + * + * @return string + */ + private function getCurrentReleaseChannel() { + return !is_null($this->getConfigOption('updater.release.channel')) ? $this->getConfigOption('updater.release.channel') : 'stable'; + } + /** * @return string * @throws \Exception @@ -230,7 +239,7 @@ class Updater { if ($version !== '' && $version !== $this->currentVersion) { $this->updateAvailable = true; - $releaseChannel = !is_null($this->getConfigOption('updater.release.channel')) ? $this->getConfigOption('updater.release.channel') : 'stable'; + $releaseChannel = $this->getCurrentReleaseChannel(); $updateText = 'Update to ' . $versionString . ' available. (channel: "' . htmlentities($releaseChannel) . '")
Following file will be downloaded automatically: ' . $response['url'] . ''; } else { $updateText = 'No update available.'; @@ -239,7 +248,7 @@ class Updater { if ($this->updateAvailable && isset($response['autoupdater']) && !($response['autoupdater'] === 1 || $response['autoupdater'] === '1')) { $this->updateAvailable = false; - $updateText .= '
The updater is disabled for this update - please update manually.' . $response['autoupdater']; + $updateText .= '
The updater is disabled for this update - please update manually.'; } $this->silentLog('[info] end of checkForUpdate() ' . $updateText); @@ -498,7 +507,7 @@ class Updater { } $this->silentLog('[info] updaterServer: ' . $updaterServer); - $releaseChannel = !is_null($this->getConfigOption('updater.release.channel')) ? $this->getConfigOption('updater.release.channel') : 'stable'; + $releaseChannel = $this->getCurrentReleaseChannel(); $this->silentLog('[info] releaseChannel: ' . $releaseChannel); $this->silentLog('[info] internal version: ' . $this->getConfigOption('version')); @@ -597,13 +606,10 @@ class Updater { } /** - * Extracts the download - * - * @throws \Exception + * @return string + * @throws Exception */ - public function extractDownload() { - $this->silentLog('[info] extractDownload()'); - + private function getDownloadedFilePath() { $storageLocation = $this->getDataDirectoryLocation() . '/updater-'.$this->getConfigOption('instanceid') . '/downloads/'; $this->silentLog('[info] storage location: ' . $storageLocation); @@ -612,15 +618,88 @@ class Updater { if(count($files) !== 3) { throw new \Exception('Not exact 3 files existent in folder'); } + return $storageLocation . '/' . $files[2]; + } + + /** + * Verifies the integrity of the downloaded file + * + * @throws \Exception + */ + public function verifyIntegrity() { + $this->silentLog('[info] verifyIntegrity()'); + + if($this->getCurrentReleaseChannel() === 'daily') { + $this->silentLog('[info] current channel is "daily" which is not signed. Skipping verification.'); + return; + } + + $response = $this->getUpdateServerResponse(); + if(!isset($response['signature'])) { + throw new \Exception('No signature specified for defined update'); + } + + $certificate = <<getDownloadedFilePath()), + base64_decode($response['signature']), + $certificate, + OPENSSL_ALGO_SHA512 + ); + + if($validSignature === false) { + throw new \Exception('Signature of update is not valid'); + } + + $this->silentLog('[info] end of verifyIntegrity()'); + } + + /** + * Extracts the download + * + * @throws \Exception + */ + public function extractDownload() { + $this->silentLog('[info] extractDownload()'); + $downloadedFilePath = $this->getDownloadedFilePath(); $zip = new \ZipArchive; - $zipState = $zip->open($storageLocation . '/' . $files[2]); + $zipState = $zip->open($downloadedFilePath); if ($zipState === true) { - $zip->extractTo($storageLocation); + $zip->extractTo(dirname($downloadedFilePath)); $zip->close(); - $state = unlink($storageLocation . '/' . $files[2]); + $state = unlink($downloadedFilePath); if($state === false) { - throw new \Exception('Cant unlink '. $storageLocation . '/' . $files[2]); + throw new \Exception('Cant unlink '. $downloadedFilePath); } } else { throw new \Exception('Cant handle ZIP file. Error code is: '.$zipState); @@ -1104,7 +1183,7 @@ if(isset($_POST['step'])) { } $step = (int)$_POST['step']; - if($step > 11 || $step < 1) { + if($step > 12 || $step < 1) { throw new \Exception('Invalid step'); } @@ -1126,21 +1205,24 @@ if(isset($_POST['step'])) { $updater->downloadUpdate(); break; case 6: - $updater->extractDownload(); + $updater->verifyIntegrity(); break; case 7: - $updater->replaceEntryPoints(); + $updater->extractDownload(); break; case 8: - $updater->deleteOldFiles(); + $updater->replaceEntryPoints(); break; case 9: - $updater->moveNewVersionInPlace(); + $updater->deleteOldFiles(); break; case 10: - $updater->setMaintenanceMode(false); + $updater->moveNewVersionInPlace(); break; case 11: + $updater->setMaintenanceMode(false); + break; + case 12: $updater->finalize(); break; } @@ -1476,30 +1558,34 @@ if(strpos($updaterUrl, 'index.php') === false) {

Downloading

-
  • +
  • +

    Verifying integrity

    + +
  • +
  • Extracting

  • -
  • +
  • Replace entry points

  • -
  • +
  • Delete old files

  • -
  • +
  • Move new files in place

  • -
  • +
  • Keep maintenance mode active?

  • -
  • +
  • Done