diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f55f38..3f4400d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +# v2.3.0 +## 04/27/2021 + +1. [](#new) + * Added new Advanced Git Ignore field where it is possible to specify custom git ignore entries to play along with GitSync [#197](https://github.com/trilbymedia/grav-plugin-git-sync/issues/197) [#117](https://github.com/trilbymedia/grav-plugin-git-sync/issues/117) + * Support `ssh://` protocol and SSH Key authentication ([read more](https://github.com/trilbymedia/grav-plugin-git-sync#ssh--enterprise)) [#110](https://github.com/trilbymedia/grav-plugin-git-sync/issues/110) +1. [](#improved) + * Updated PHP Encryption dependency +1. [](#bugfix) + * Fixed issue with Flex Objects, preventing GitSync's settings to get refreshed `onAdminSave` when "Sync on Page Save" disabled + * Return raw URL for repositories setup with `ssh://` protocol, instead of injecting the password like `git://` and `http://` protocols do [#104](https://github.com/trilbymedia/grav-plugin-git-sync/issues/104) + # v2.2.0 ## 04/17/2021 diff --git a/README.md b/README.md index e5ce9c4..f712a3b 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,6 @@ Git Sync captures any change that you make on your site and instantly updates yo Thanks to this powerful bi-directional flow, Git Sync can now turn your site into a collaborative environment where the source of truth is always your git repository and unlimited collaborators and sites can share and contribute to the same content. -> :warning: With GitHub’s recent change of repository default branches being named ‘main’ instead of ‘master’ the following work-around is needed until GitHub also addresses automatic default branch re-routing: -> 1. Once you have created your new repo, create a new branch called ‘master’ -> 2. Set the default branch of the repo to this newly created ‘master’ branch ## Videos: Setup and Demo @@ -33,6 +30,7 @@ After having installed the plugin, make sure to go in the plugin settings in ord * Easy step-by-step Wizard setup will guide you through a detailed process for setting things up * Supported hosting services: [GitHub](https://github.com), [BitBucket](https://bitbucket.org), [GitLab](https://gitlab.com) as well as any self-hosted and git service with webhooks support. * Private repositories +* Basic SSH / Enterprise support (You will need SSH Key properly setup on your machine) * Synchronize any folder under `user` (pages, themes, config) * 2FA (Two-Factor Authentication) and Access Token support * Webhooks support allow for automatic synchronization from the Git Repository with secure Webhook URL auto-generated and support for Webhook Secret (when available) @@ -70,6 +68,18 @@ In order for the plugin to work, the server needs to run `git` 1.7.1 and above. The PHP `exec()` and `escapeshellarg()` functions are mandatory. Ensure the options to be enabled in your PHP. +# SSH / Enterprise + +Since version v2.3.0, GitSync supports SSH authentication. This means you can omit password altogether and rely on the Repository URL and SSH key on your machine, that you can point to from the Advanced settings in GitSync. + +Please note that In order to be able to sparse-checkout and push changes, it is expected you have an ssh-key configured for accessing the repository. This is usually found under `~/.ssh` and it needs to be configured for the same user that runs the web-server. + +Point it to the secret (not the public) and make also sure you have strict permissions to the file. (`-rw-------`). + +Example: private_key: `/home/www-data/.ssh/id_rsa` + +> **IMPORTANT**: SSH keys with passphrase are **NOT** supported. To remove a passphrase, run the `ssh-keygen -p` command and when asked for the new passphrase leave blank and return. + # Known Issues and Resolutions **Q:** `error: The requested URL returned error: 403 Forbidden while accessing...` [#39](https://github.com/trilbymedia/grav-plugin-git-sync/issues/39) **A:** This might be caused by your computer having stored in the registry a user/password that might conflict with the one you are intending to use. diff --git a/blueprints.yaml b/blueprints.yaml index fd4e622..c13c1e4 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -1,7 +1,7 @@ name: Git Sync type: plugin slug: git-sync -version: 2.2.0 +version: 2.3.0 description: Allows to synchronize portions of Grav with Git Repositories (GitHub, BitBucket, GitLab) icon: git author: @@ -243,6 +243,29 @@ form: help: If the default `git` command doesn't work on your machine or if you want to specify a custom path, do it in here placeholder: /usr/bin/git + git.ignore: + type: textarea + label: Git Ignore + help: Add custom git ignore rules to go along with GitSync. One per line + rows: 6 + placeholder: | + node_modules + /.idea + + git.private_key: + type: text + label: Private SSH Key + placeholder: ~/.ssh/id_rsa + markdown: true + description: > + In order to be able to sparse-checkout and push changes, it is expected you have an ssh-key configured for accessing the repository. This is usually found under `~/.ssh` and it needs to be configured for the same user that runs the web-server.
+
+ Point it to the secret (not the public) and make also sure you have strict permissions to the file. (`-rw-------`).
+
+ Example: `private_key: /home/www-data/.ssh/id_rsa`
+
+ **IMPORTANT**: SSH keys with passphrase are __NOT__ supported. To remove a passphrase, run the `ssh-keygen -p` command and when asked for the new passphrase leave blank and return. + logging: type: toggle default: 0 diff --git a/classes/GitSync.php b/classes/GitSync.php index 8c9da1c..4b52edd 100644 --- a/classes/GitSync.php +++ b/classes/GitSync.php @@ -145,10 +145,17 @@ public function setUser($name = null, $email = null) { $name = $this->getConfig('git', $name)['name']; $email = $this->getConfig('git', $email)['email']; + $privateKey = $this->getGitConfig('private_key', null); $this->execute("config user.name \"{$name}\""); $this->execute("config user.email \"{$email}\""); + if ($privateKey) { + $this->execute('config core.sshCommand "ssh -i ' . $privateKey . ' -F /dev/null"'); + } else { + $this->execute('config --unset core.sshCommand'); + } + return true; } @@ -214,6 +221,9 @@ public function enableSparseCheckout() } } + $ignoreEntries = explode("\n", $this->getGitConfig('ignore', '')); + $ignore = array_merge($ignore, $ignoreEntries); + $file = File::instance(rtrim($this->repositoryPath, '/') . '/.gitignore'); $file->save(implode("\r\n", $ignore)); $file->free(); @@ -471,7 +481,7 @@ public function execute($command, $quiet = false) exec($command, $output, $returnValue); } - if ($returnValue !== 0 && !$quiet) { + if ($returnValue !== 0 && (!empty($output) && $returnValue === 5) && !$quiet) { throw new \RuntimeException(implode("\r\n", $output)); } diff --git a/classes/Helper.php b/classes/Helper.php index 0a8ef34..5208924 100644 --- a/classes/Helper.php +++ b/classes/Helper.php @@ -5,6 +5,7 @@ use Defuse\Crypto\Crypto; use Grav\Common\Config\Config; use Grav\Common\Grav; +use Grav\Common\Utils; use SebastianBergmann\Git\RuntimeException; class Helper @@ -69,6 +70,10 @@ public static function prepareRepository($user, $password, $repository) $user = $user ? urlencode($user) . ':' : ''; $password = urlencode($password); + if (Utils::startsWith($repository, 'ssh://')) { + return $repository; + } + return str_replace('://', "://${user}${password}@", $repository); } diff --git a/composer.lock b/composer.lock index abf64f2..a6dbefb 100644 --- a/composer.lock +++ b/composer.lock @@ -8,26 +8,25 @@ "packages": [ { "name": "defuse/php-encryption", - "version": "v2.2.1", + "version": "v2.3.1", "source": { "type": "git", "url": "https://github.com/defuse/php-encryption.git", - "reference": "0f407c43b953d571421e0020ba92082ed5fb7620" + "reference": "77880488b9954b7884c25555c2a0ea9e7053f9d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/defuse/php-encryption/zipball/0f407c43b953d571421e0020ba92082ed5fb7620", - "reference": "0f407c43b953d571421e0020ba92082ed5fb7620", + "url": "https://api.github.com/repos/defuse/php-encryption/zipball/77880488b9954b7884c25555c2a0ea9e7053f9d2", + "reference": "77880488b9954b7884c25555c2a0ea9e7053f9d2", "shasum": "" }, "require": { "ext-openssl": "*", "paragonie/random_compat": ">= 2", - "php": ">=5.4.0" + "php": ">=5.6.0" }, "require-dev": { - "nikic/php-parser": "^2.0|^3.0|^4.0", - "phpunit/phpunit": "^4|^5" + "phpunit/phpunit": "^4|^5|^6|^7|^8|^9" }, "bin": [ "bin/generate-defuse-key" @@ -67,7 +66,11 @@ "security", "symmetric key cryptography" ], - "time": "2018-07-24T23:27:56+00:00" + "support": { + "issues": "https://github.com/defuse/php-encryption/issues", + "source": "https://github.com/defuse/php-encryption/tree/v2.3.1" + }, + "time": "2021-04-09T23:57:26+00:00" }, { "name": "sebastian/git", @@ -112,6 +115,10 @@ "keywords": [ "git" ], + "support": { + "issues": "https://github.com/sebastianbergmann/git/issues", + "source": "https://github.com/sebastianbergmann/git/tree/master" + }, "abandoned": true, "time": "2017-01-23T20:57:12+00:00" } @@ -128,5 +135,5 @@ "ext-openssl": "*" }, "platform-dev": [], - "plugin-api-version": "1.1.0" + "plugin-api-version": "2.0.0" } diff --git a/git-sync.php b/git-sync.php index 6809beb..2a1b0f5 100644 --- a/git-sync.php +++ b/git-sync.php @@ -6,6 +6,7 @@ use Grav\Common\Config\Config; use Grav\Common\Data\Data; use Grav\Common\Grav; +use Grav\Common\Page\Interfaces\PageInterface; use Grav\Common\Plugin; use Grav\Common\Scheduler\Scheduler; use Grav\Plugin\GitSync\AdminController; @@ -376,15 +377,15 @@ public function onAdminSave(Event $event) */ public function onAdminAfterSave(Event $event) { - if (!$this->grav['config']->get('plugins.git-sync.sync.on_save', true)) { - return; - } - $obj = $event['object']; $adminPath = trim($this->grav['admin']->base, '/'); $uriPath = $this->grav['uri']->path(); $isPluginRoute = $uriPath === "/$adminPath/plugins/" . $this->name; + if ($obj instanceof PageInterface && !$this->grav['config']->get('plugins.git-sync.sync.on_save', true)) { + return; + } + if ($obj instanceof Data) { $folders = $this->git->getConfig('folders', $event['object']->get('folders', [])); $data_type = preg_replace('#^/' . preg_quote($adminPath, '#') . '/#', '', $uriPath); diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php index fce8549..4d989a2 100644 --- a/vendor/composer/ClassLoader.php +++ b/vendor/composer/ClassLoader.php @@ -37,11 +37,13 @@ * * @author Fabien Potencier * @author Jordi Boggiano - * @see http://www.php-fig.org/psr/psr-0/ - * @see http://www.php-fig.org/psr/psr-4/ + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ */ class ClassLoader { + private $vendorDir; + // PSR-4 private $prefixLengthsPsr4 = array(); private $prefixDirsPsr4 = array(); @@ -57,10 +59,17 @@ class ClassLoader private $missingClasses = array(); private $apcuPrefix; + private static $registeredLoaders = array(); + + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + } + public function getPrefixes() { if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', $this->prefixesPsr0); + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); } return array(); @@ -300,6 +309,15 @@ public function getApcuPrefix() public function register($prepend = false) { spl_autoload_register(array($this, 'loadClass'), true, $prepend); + + if (null === $this->vendorDir) { + //no-op + } elseif ($prepend) { + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; + } else { + unset(self::$registeredLoaders[$this->vendorDir]); + self::$registeredLoaders[$this->vendorDir] = $this; + } } /** @@ -308,6 +326,10 @@ public function register($prepend = false) public function unregister() { spl_autoload_unregister(array($this, 'loadClass')); + + if (null !== $this->vendorDir) { + unset(self::$registeredLoaders[$this->vendorDir]); + } } /** @@ -367,6 +389,16 @@ public function findFile($class) return $file; } + /** + * Returns the currently registered loaders indexed by their corresponding vendor directories. + * + * @return self[] + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + private function findFileWithExtension($class, $ext) { // PSR-4 lookup diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php new file mode 100644 index 0000000..52bdabf --- /dev/null +++ b/vendor/composer/InstalledVersions.php @@ -0,0 +1,309 @@ + + array ( + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'aliases' => + array ( + ), + 'reference' => 'ea50fecd1924f436e13c2e53967160e97a14380a', + 'name' => '__root__', + ), + 'versions' => + array ( + '__root__' => + array ( + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'aliases' => + array ( + ), + 'reference' => 'ea50fecd1924f436e13c2e53967160e97a14380a', + ), + 'defuse/php-encryption' => + array ( + 'pretty_version' => 'v2.3.1', + 'version' => '2.3.1.0', + 'aliases' => + array ( + ), + 'reference' => '77880488b9954b7884c25555c2a0ea9e7053f9d2', + ), + 'paragonie/random_compat' => + array ( + 'replaced' => + array ( + 0 => '9.99.99', + ), + ), + 'sebastian/git' => + array ( + 'pretty_version' => '2.1.4', + 'version' => '2.1.4.0', + 'aliases' => + array ( + ), + 'reference' => '815bbbc963cf35e5413df195aa29df58243ecd24', + ), + ), +); +private static $canGetVendors; +private static $installedByVendor = array(); + + + + + + + +public static function getInstalledPackages() +{ +$packages = array(); +foreach (self::getInstalled() as $installed) { +$packages[] = array_keys($installed['versions']); +} + + +if (1 === \count($packages)) { +return $packages[0]; +} + +return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); +} + + + + + + + + + +public static function isInstalled($packageName) +{ +foreach (self::getInstalled() as $installed) { +if (isset($installed['versions'][$packageName])) { +return true; +} +} + +return false; +} + + + + + + + + + + + + + + +public static function satisfies(VersionParser $parser, $packageName, $constraint) +{ +$constraint = $parser->parseConstraints($constraint); +$provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + +return $provided->matches($constraint); +} + + + + + + + + + + +public static function getVersionRanges($packageName) +{ +foreach (self::getInstalled() as $installed) { +if (!isset($installed['versions'][$packageName])) { +continue; +} + +$ranges = array(); +if (isset($installed['versions'][$packageName]['pretty_version'])) { +$ranges[] = $installed['versions'][$packageName]['pretty_version']; +} +if (array_key_exists('aliases', $installed['versions'][$packageName])) { +$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); +} +if (array_key_exists('replaced', $installed['versions'][$packageName])) { +$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); +} +if (array_key_exists('provided', $installed['versions'][$packageName])) { +$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); +} + +return implode(' || ', $ranges); +} + +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + + + + + +public static function getVersion($packageName) +{ +foreach (self::getInstalled() as $installed) { +if (!isset($installed['versions'][$packageName])) { +continue; +} + +if (!isset($installed['versions'][$packageName]['version'])) { +return null; +} + +return $installed['versions'][$packageName]['version']; +} + +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + + + + + +public static function getPrettyVersion($packageName) +{ +foreach (self::getInstalled() as $installed) { +if (!isset($installed['versions'][$packageName])) { +continue; +} + +if (!isset($installed['versions'][$packageName]['pretty_version'])) { +return null; +} + +return $installed['versions'][$packageName]['pretty_version']; +} + +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + + + + + +public static function getReference($packageName) +{ +foreach (self::getInstalled() as $installed) { +if (!isset($installed['versions'][$packageName])) { +continue; +} + +if (!isset($installed['versions'][$packageName]['reference'])) { +return null; +} + +return $installed['versions'][$packageName]['reference']; +} + +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + + + + + +public static function getRootPackage() +{ +$installed = self::getInstalled(); + +return $installed[0]['root']; +} + + + + + + + +public static function getRawData() +{ +return self::$installed; +} + + + + + + + + + + + + + + + + + + + +public static function reload($data) +{ +self::$installed = $data; +self::$installedByVendor = array(); +} + + + + +private static function getInstalled() +{ +if (null === self::$canGetVendors) { +self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); +} + +$installed = array(); + +if (self::$canGetVendors) { + +foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { +if (isset(self::$installedByVendor[$vendorDir])) { +$installed[] = self::$installedByVendor[$vendorDir]; +} elseif (is_file($vendorDir.'/composer/installed.php')) { +$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php'; +} +} +} + +$installed[] = self::$installed; + +return $installed; +} +} diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index be7d590..4a14d1a 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -6,6 +6,7 @@ $baseDir = dirname($vendorDir); return array( + 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', 'Grav\\Plugin\\GitSyncPlugin' => $baseDir . '/git-sync.php', 'SebastianBergmann\\Git\\Exception' => $vendorDir . '/sebastian/git/src/Exception/Exception.php', 'SebastianBergmann\\Git\\Git' => $vendorDir . '/sebastian/git/src/Git.php', diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index c545f2c..eff7ab1 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -22,13 +22,15 @@ public static function getLoader() return self::$loader; } + require __DIR__ . '/platform_check.php'; + spl_autoload_register(array('ComposerAutoloaderInitc058e1b5c686df0909ec1cc39bb5d854', 'loadClassLoader'), true, true); - self::$loader = $loader = new \Composer\Autoload\ClassLoader(); + self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__))); spl_autoload_unregister(array('ComposerAutoloaderInitc058e1b5c686df0909ec1cc39bb5d854', 'loadClassLoader')); $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'; + require __DIR__ . '/autoload_static.php'; call_user_func(\Composer\Autoload\ComposerStaticInitc058e1b5c686df0909ec1cc39bb5d854::getInitializer($loader)); } else { diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 29c0bd8..823f2cc 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -34,6 +34,7 @@ class ComposerStaticInitc058e1b5c686df0909ec1cc39bb5d854 ); public static $classMap = array ( + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 'Grav\\Plugin\\GitSyncPlugin' => __DIR__ . '/../..' . '/git-sync.php', 'SebastianBergmann\\Git\\Exception' => __DIR__ . '/..' . '/sebastian/git/src/Exception/Exception.php', 'SebastianBergmann\\Git\\Git' => __DIR__ . '/..' . '/sebastian/git/src/Git.php', diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index f800b42..2a900cf 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -1,115 +1,124 @@ -[ - { - "name": "defuse/php-encryption", - "version": "v2.2.1", - "version_normalized": "2.2.1.0", - "source": { - "type": "git", - "url": "https://github.com/defuse/php-encryption.git", - "reference": "0f407c43b953d571421e0020ba92082ed5fb7620" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/defuse/php-encryption/zipball/0f407c43b953d571421e0020ba92082ed5fb7620", - "reference": "0f407c43b953d571421e0020ba92082ed5fb7620", - "shasum": "" - }, - "require": { - "ext-openssl": "*", - "paragonie/random_compat": ">= 2", - "php": ">=5.4.0" - }, - "require-dev": { - "nikic/php-parser": "^2.0|^3.0|^4.0", - "phpunit/phpunit": "^4|^5" - }, - "time": "2018-07-24T23:27:56+00:00", - "bin": [ - "bin/generate-defuse-key" - ], - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Defuse\\Crypto\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Hornby", - "email": "taylor@defuse.ca", - "homepage": "https://defuse.ca/" +{ + "packages": [ + { + "name": "defuse/php-encryption", + "version": "v2.3.1", + "version_normalized": "2.3.1.0", + "source": { + "type": "git", + "url": "https://github.com/defuse/php-encryption.git", + "reference": "77880488b9954b7884c25555c2a0ea9e7053f9d2" }, - { - "name": "Scott Arciszewski", - "email": "info@paragonie.com", - "homepage": "https://paragonie.com" - } - ], - "description": "Secure PHP Encryption Library", - "keywords": [ - "aes", - "authenticated encryption", - "cipher", - "crypto", - "cryptography", - "encrypt", - "encryption", - "openssl", - "security", - "symmetric key cryptography" - ] - }, - { - "name": "sebastian/git", - "version": "2.1.4", - "version_normalized": "2.1.4.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/git.git", - "reference": "815bbbc963cf35e5413df195aa29df58243ecd24" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/git/zipball/815bbbc963cf35e5413df195aa29df58243ecd24", - "reference": "815bbbc963cf35e5413df195aa29df58243ecd24", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "time": "2017-01-23T20:57:12+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/defuse/php-encryption/zipball/77880488b9954b7884c25555c2a0ea9e7053f9d2", + "reference": "77880488b9954b7884c25555c2a0ea9e7053f9d2", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "paragonie/random_compat": ">= 2", + "php": ">=5.6.0" + }, + "require-dev": { + "phpunit/phpunit": "^4|^5|^6|^7|^8|^9" + }, + "time": "2021-04-09T23:57:26+00:00", + "bin": [ + "bin/generate-defuse-key" + ], + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Defuse\\Crypto\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Hornby", + "email": "taylor@defuse.ca", + "homepage": "https://defuse.ca/" + }, + { + "name": "Scott Arciszewski", + "email": "info@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "Secure PHP Encryption Library", + "keywords": [ + "aes", + "authenticated encryption", + "cipher", + "crypto", + "cryptography", + "encrypt", + "encryption", + "openssl", + "security", + "symmetric key cryptography" + ], + "support": { + "issues": "https://github.com/defuse/php-encryption/issues", + "source": "https://github.com/defuse/php-encryption/tree/v2.3.1" + }, + "install-path": "../defuse/php-encryption" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Simple wrapper for Git", - "homepage": "http://www.github.com/sebastianbergmann/git", - "keywords": [ - "git" - ], - "abandoned": true - } -] + { + "name": "sebastian/git", + "version": "2.1.4", + "version_normalized": "2.1.4.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/git.git", + "reference": "815bbbc963cf35e5413df195aa29df58243ecd24" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/git/zipball/815bbbc963cf35e5413df195aa29df58243ecd24", + "reference": "815bbbc963cf35e5413df195aa29df58243ecd24", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "time": "2017-01-23T20:57:12+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Simple wrapper for Git", + "homepage": "http://www.github.com/sebastianbergmann/git", + "keywords": [ + "git" + ], + "abandoned": true, + "install-path": "../sebastian/git" + } + ], + "dev": true, + "dev-package-names": [] +} diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php new file mode 100644 index 0000000..3343dd3 --- /dev/null +++ b/vendor/composer/installed.php @@ -0,0 +1,49 @@ + + array ( + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'aliases' => + array ( + ), + 'reference' => 'ea50fecd1924f436e13c2e53967160e97a14380a', + 'name' => '__root__', + ), + 'versions' => + array ( + '__root__' => + array ( + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'aliases' => + array ( + ), + 'reference' => 'ea50fecd1924f436e13c2e53967160e97a14380a', + ), + 'defuse/php-encryption' => + array ( + 'pretty_version' => 'v2.3.1', + 'version' => '2.3.1.0', + 'aliases' => + array ( + ), + 'reference' => '77880488b9954b7884c25555c2a0ea9e7053f9d2', + ), + 'paragonie/random_compat' => + array ( + 'replaced' => + array ( + 0 => '9.99.99', + ), + ), + 'sebastian/git' => + array ( + 'pretty_version' => '2.1.4', + 'version' => '2.1.4.0', + 'aliases' => + array ( + ), + 'reference' => '815bbbc963cf35e5413df195aa29df58243ecd24', + ), + ), +); diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php new file mode 100644 index 0000000..cd1bd2c --- /dev/null +++ b/vendor/composer/platform_check.php @@ -0,0 +1,26 @@ += 70103)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 7.1.3". You are running ' . PHP_VERSION . '.'; +} + +if ($issues) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); + } elseif (!headers_sent()) { + echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; + } + } + trigger_error( + 'Composer detected issues in your platform: ' . implode(' ', $issues), + E_USER_ERROR + ); +} diff --git a/vendor/defuse/php-encryption/.gitignore b/vendor/defuse/php-encryption/.gitignore deleted file mode 100644 index 987c516..0000000 --- a/vendor/defuse/php-encryption/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -*~ -/test/unit/File/big-generated-file -/composer.lock -/vendor -defuse-crypto.phar -defuse-crypto.phar.sig -composer.phar -box.phar -phpunit.phar -phpunit.phar.asc -test/unit/File/tmp diff --git a/vendor/defuse/php-encryption/.php_cs b/vendor/defuse/php-encryption/.php_cs deleted file mode 100644 index e317732..0000000 --- a/vendor/defuse/php-encryption/.php_cs +++ /dev/null @@ -1,60 +0,0 @@ -level(Symfony\CS\FixerInterface::PSR2_LEVEL) - ->fixers([ - 'blankline_after_open_tag', - 'empty_return', - 'extra_empty_lines', - 'function_typehint_space', - 'join_function', - 'method_argument_default_value', - 'multiline_array_trailing_comma', - 'no_blank_lines_after_class_opening', - 'no_empty_lines_after_phpdocs', - 'phpdoc_indent', - 'phpdoc_no_access', - 'phpdoc_no_empty_return', - 'phpdoc_no_package', - 'phpdoc_params', - 'phpdoc_scalar', - 'phpdoc_separation', - 'phpdoc_trim', - 'phpdoc_type_to_var', - 'phpdoc_types', - 'phpdoc_var_without_name', - 'remove_leading_slash_use', - 'remove_lines_between_uses', - 'short_bool_cast', - 'single_quote', - 'spaces_after_semicolon', - 'spaces_before_semicolon', - 'spaces_cast', - 'standardize_not_equal', - 'ternary_spaces', - 'trim_array_spaces', - 'unneeded_control_parentheses', - 'unused_use', - 'whitespacy_lines', - 'align_double_arrow', - 'concat_with_spaces', - 'logical_not_operators_with_successor_space', - 'multiline_spaces_before_semicolon', - 'newline_after_open_tag', - 'ordered_use', - 'php_unit_construct', - 'phpdoc_order', - 'short_array_syntax', - ]); - -if (null === $input->getArgument('path')) { - $config - ->finder( - Symfony\CS\Finder\DefaultFinder::create() - ->in('src') - ->in('test') - ->exclude('vendor') - ); -} - -return $config; diff --git a/vendor/defuse/php-encryption/README.md b/vendor/defuse/php-encryption/README.md index da08538..b16700a 100644 --- a/vendor/defuse/php-encryption/README.md +++ b/vendor/defuse/php-encryption/README.md @@ -4,14 +4,23 @@ php-encryption [![Build Status](https://travis-ci.org/defuse/php-encryption.svg?branch=master)](https://travis-ci.org/defuse/php-encryption) [![codecov](https://codecov.io/gh/defuse/php-encryption/branch/master/graph/badge.svg)](https://codecov.io/gh/defuse/php-encryption) [![Latest Stable Version](https://poser.pugx.org/defuse/php-encryption/v/stable)](https://packagist.org/packages/defuse/php-encryption) -[![Latest Unstable Version](https://poser.pugx.org/defuse/php-encryption/v/unstable)](https://packagist.org/packages/defuse/php-encryption) [![License](https://poser.pugx.org/defuse/php-encryption/license)](https://packagist.org/packages/defuse/php-encryption) [![Downloads](https://img.shields.io/packagist/dt/defuse/php-encryption.svg)](https://packagist.org/packages/defuse/php-encryption) +```terminal +composer require defuse/php-encryption +``` + This is a library for encrypting data with a key or password in PHP. **It -requires PHP 5.6 or newer and OpenSSL 1.0.1 or newer.** The current version is -v2.2.1, which is expected to remain stable and supported by its authors with -security and bugfixes until at least January 1st, 2020. +requires PHP 5.6 or newer and OpenSSL 1.0.1 or newer.** We recommend using a +version of PHP that [still has security +support](https://www.php.net/supported-versions.php), which at the time of +writing means PHP 7.3 or later. Using this library with an unsupported +version of PHP could lead to security vulnerabilities. + +The current version of `php-encryption` is v2.3.1. This library is expected to +remain stable and supported by its authors with security and bugfixes until at +least January 1st, 2022. The library is a joint effort between [Taylor Hornby](https://defuse.ca/) and [Scott Arciszewski](https://paragonie.com/blog/author/scott-arcizewski) as well @@ -90,7 +99,7 @@ a formal audit, please [contact Taylor Hornby](https://defuse.ca/contact.htm). Public Keys ------------ -The GnuPG public key used to sign releases is available in +The GnuPG public key used to sign current and older releases is available in [dist/signingkey.asc](https://github.com/defuse/php-encryption/raw/master/dist/signingkey.asc). Its fingerprint is: ``` @@ -100,3 +109,13 @@ The GnuPG public key used to sign releases is available in You can verify it against Taylor Hornby's [contact page](https://defuse.ca/contact.htm) and [twitter](https://twitter.com/DefuseSec/status/723741424253059074). + +Due to the old key expiring, new releases will be signed with a new public key +available in [dist/signingkey-new.asc](https://github.com/defuse/php-encryption/raw/master/dist/signingkey-new.asc). Its fingerprint is: + +``` +6DD6 E677 0281 5846 FC85 25A3 DD2E 507F 7BDB 1669 +``` + +A signature of this new key by the old key is available in +[dist/signingkey-new.asc.sig](https://github.com/defuse/php-encryption/raw/master/dist/signingkey-new.asc.sig). diff --git a/vendor/defuse/php-encryption/composer.json b/vendor/defuse/php-encryption/composer.json index 44c1e42..025f38d 100644 --- a/vendor/defuse/php-encryption/composer.json +++ b/vendor/defuse/php-encryption/composer.json @@ -23,11 +23,10 @@ "require": { "paragonie/random_compat": ">= 2", "ext-openssl": "*", - "php": ">=5.4.0" + "php": ">=5.6.0" }, "require-dev": { - "phpunit/phpunit": "^4|^5", - "nikic/php-parser": "^2.0|^3.0|^4.0" + "phpunit/phpunit": "^4|^5|^6|^7|^8|^9" }, "bin": [ "bin/generate-defuse-key" diff --git a/vendor/defuse/php-encryption/dist/Makefile b/vendor/defuse/php-encryption/dist/Makefile index 4b65c9e..833e479 100644 --- a/vendor/defuse/php-encryption/dist/Makefile +++ b/vendor/defuse/php-encryption/dist/Makefile @@ -2,14 +2,15 @@ # must be installed and in your $PATH. Run it from inside the dist/ directory. box := $(shell which box) -composer := "composer" +composer := $(shell which composer) +gitcommit := $(shell git rev-parse HEAD) .PHONY: all all: build-phar .PHONY: sign-phar sign-phar: - gpg -u 7B4B2D98 --armor --output defuse-crypto.phar.sig --detach-sig defuse-crypto.phar + gpg -u DD2E507F7BDB1669 --armor --output defuse-crypto.phar.sig --detach-sig defuse-crypto.phar # ensure we run in clean tree. export git tree and run there. .PHONY: build-phar @@ -33,5 +34,6 @@ defuse-crypto.phar: dist/box.json composer.lock php -d phar.readonly=0 $(box) build -c box.json -v composer.lock: + $(composer) config autoloader-suffix $(gitcommit) $(composer) install --no-dev diff --git a/vendor/defuse/php-encryption/dist/signingkey-new.asc b/vendor/defuse/php-encryption/dist/signingkey-new.asc new file mode 100644 index 0000000..7e3a4a1 --- /dev/null +++ b/vendor/defuse/php-encryption/dist/signingkey-new.asc @@ -0,0 +1,53 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=Ysgx +-----END PGP PUBLIC KEY BLOCK----- diff --git a/vendor/defuse/php-encryption/dist/signingkey-new.asc.sig b/vendor/defuse/php-encryption/dist/signingkey-new.asc.sig new file mode 100644 index 0000000..56e1f3a Binary files /dev/null and b/vendor/defuse/php-encryption/dist/signingkey-new.asc.sig differ diff --git a/vendor/defuse/php-encryption/docs/InternalDeveloperDocs.md b/vendor/defuse/php-encryption/docs/InternalDeveloperDocs.md index 19b0086..b68f710 100644 --- a/vendor/defuse/php-encryption/docs/InternalDeveloperDocs.md +++ b/vendor/defuse/php-encryption/docs/InternalDeveloperDocs.md @@ -154,7 +154,7 @@ make sign-phar Tag the release: ``` -git -c user.signingkey=7B4B2D98 tag -s "" -m "" +git -c user.signingkey=DD2E507F7BDB1669 tag -s "" -m "" ``` `` should be in the format `v2.0.0` and `` should look diff --git a/vendor/defuse/php-encryption/docs/Tutorial.md b/vendor/defuse/php-encryption/docs/Tutorial.md index f130caf..a40cac3 100644 --- a/vendor/defuse/php-encryption/docs/Tutorial.md +++ b/vendor/defuse/php-encryption/docs/Tutorial.md @@ -229,10 +229,10 @@ application is using don't compute it either. Then, when the user logs in, Dave's code will load the protected key from the user's account record, unlock it to get a `Key` object, and save the `Key` -object somewhere safe (like temporary memory-backed session storage). Note that -wherever Dave's code saves the key, it must be destroyed once the user logs out, -or else the attacker might be able to find users' keys even if they were never -logged in during the attack. +object somewhere safe (like temporary memory-backed session storage or +a cookie). Note that wherever Dave's code saves the key, it must be destroyed +once the user logs out, or else the attacker might be able to find users' keys +even if they were never logged in during the attack. ```php unlockKey($password); $user_key_encoded = $user_key->saveToAsciiSafeString(); -// ... save $user_key_encoded in the session +// ... save $user_key_encoded in a cookie ``` ```php @@ -255,7 +255,7 @@ $user_key_encoded = $user_key->saveToAsciiSafeString(); ``` When a user adds their credit card number, Dave's code will get the key from the -session and use it to encrypt the credit card number: +memory-backed session or cookie and use it to encrypt the credit card number: ```php - - - - - - - - - - diff --git a/vendor/defuse/php-encryption/src/Core.php b/vendor/defuse/php-encryption/src/Core.php index 3506cda..1f8e829 100644 --- a/vendor/defuse/php-encryption/src/Core.php +++ b/vendor/defuse/php-encryption/src/Core.php @@ -228,7 +228,10 @@ public static function hashEquals($expected, $given) */ public static function ensureConstantExists($name) { - Core::ensureTrue(\defined($name)); + Core::ensureTrue( + \defined($name), + 'Constant '.$name.' does not exists' + ); } /** @@ -241,7 +244,10 @@ public static function ensureConstantExists($name) */ public static function ensureFunctionExists($name) { - Core::ensureTrue(\function_exists($name)); + Core::ensureTrue( + \function_exists($name), + 'function '.$name.' does not exists' + ); } /** @@ -434,6 +440,9 @@ public static function pbkdf2($algorithm, $password, $salt, $count, $key_length, $last = $xorsum = \hash_hmac($algorithm, $last, $password, true); // perform the other $count - 1 iterations for ($j = 1; $j < $count; $j++) { + /** + * @psalm-suppress InvalidOperand + */ $xorsum ^= ($last = \hash_hmac($algorithm, $last, $password, true)); } $output .= $xorsum; diff --git a/vendor/defuse/php-encryption/src/File.php b/vendor/defuse/php-encryption/src/File.php index 0d4ed74..3a64c4a 100644 --- a/vendor/defuse/php-encryption/src/File.php +++ b/vendor/defuse/php-encryption/src/File.php @@ -191,6 +191,10 @@ public static function decryptResourceWithPassword($inputHandle, $outputHandle, */ private static function encryptFileInternal($inputFilename, $outputFilename, KeyOrPassword $secret) { + if (file_exists($inputFilename) && file_exists($outputFilename) && realpath($inputFilename) === realpath($outputFilename)) { + throw new Ex\IOException('Input and output filenames must be different.'); + } + /* Open the input file. */ $if = @\fopen($inputFilename, 'rb'); if ($if === false) { @@ -256,6 +260,10 @@ private static function encryptFileInternal($inputFilename, $outputFilename, Key */ private static function decryptFileInternal($inputFilename, $outputFilename, KeyOrPassword $secret) { + if (file_exists($inputFilename) && file_exists($outputFilename) && realpath($inputFilename) === realpath($outputFilename)) { + throw new Ex\IOException('Input and output filenames must be different.'); + } + /* Open the input file. */ $if = @\fopen($inputFilename, 'rb'); if ($if === false) { @@ -320,6 +328,9 @@ private static function decryptFileInternal($inputFilename, $outputFilename, Key * * @throws Ex\EnvironmentIsBrokenException * @throws Ex\IOException + * @psalm-suppress PossiblyInvalidArgument + * Fixes erroneous errors caused by PHP 7.2 switching the return value + * of hash_init from a resource to a HashContext. */ private static function encryptResourceInternal($inputHandle, $outputHandle, KeyOrPassword $secret) { @@ -346,7 +357,7 @@ private static function encryptResourceInternal($inputHandle, $outputHandle, Key $iv = Core::secureRandom($ivsize); /* Initialize a streaming HMAC state. */ - /** @var resource $hmac */ + /** @var mixed $hmac */ $hmac = \hash_init(Core::HASH_FUNCTION_NAME, HASH_HMAC, $akey); Core::ensureTrue( \is_resource($hmac) || \is_object($hmac), @@ -369,6 +380,9 @@ private static function encryptResourceInternal($inputHandle, $outputHandle, Key $thisIv = $iv; /* How many blocks do we encrypt at a time? We increment by this value. */ + /** + * @psalm-suppress RedundantCast + */ $inc = (int) (Core::BUFFER_BYTE_SIZE / Core::BLOCK_BYTE_SIZE); /* Loop until we reach the end of the input file. */ @@ -436,6 +450,9 @@ private static function encryptResourceInternal($inputHandle, $outputHandle, Key * @throws Ex\EnvironmentIsBrokenException * @throws Ex\IOException * @throws Ex\WrongKeyOrModifiedCiphertextException + * @psalm-suppress PossiblyInvalidArgument + * Fixes erroneous errors caused by PHP 7.2 switching the return value + * of hash_init from a resource to a HashContext. */ public static function decryptResourceInternal($inputHandle, $outputHandle, KeyOrPassword $secret) { @@ -486,10 +503,13 @@ public static function decryptResourceInternal($inputHandle, $outputHandle, KeyO $thisIv = $iv; /* How many blocks do we encrypt at a time? We increment by this value. */ + /** + * @psalm-suppress RedundantCast + */ $inc = (int) (Core::BUFFER_BYTE_SIZE / Core::BLOCK_BYTE_SIZE); /* Get the HMAC. */ - if (\fseek($inputHandle, (-1 * Core::MAC_BYTE_SIZE), SEEK_END) === false) { + if (\fseek($inputHandle, (-1 * Core::MAC_BYTE_SIZE), SEEK_END) === -1) { throw new Ex\IOException( 'Cannot seek to beginning of MAC within input file' ); @@ -511,19 +531,19 @@ public static function decryptResourceInternal($inputHandle, $outputHandle, KeyO $stored_mac = self::readBytes($inputHandle, Core::MAC_BYTE_SIZE); /* Initialize a streaming HMAC state. */ - /** @var resource $hmac */ + /** @var mixed $hmac */ $hmac = \hash_init(Core::HASH_FUNCTION_NAME, HASH_HMAC, $akey); Core::ensureTrue(\is_resource($hmac) || \is_object($hmac), 'Cannot initialize a hash context'); /* Reset file pointer to the beginning of the file after the header */ - if (\fseek($inputHandle, Core::HEADER_VERSION_SIZE, SEEK_SET) === false) { + if (\fseek($inputHandle, Core::HEADER_VERSION_SIZE, SEEK_SET) === -1) { throw new Ex\IOException( 'Cannot read seek within input file' ); } /* Seek to the start of the actual ciphertext. */ - if (\fseek($inputHandle, Core::SALT_BYTE_SIZE + $ivsize, SEEK_CUR) === false) { + if (\fseek($inputHandle, Core::SALT_BYTE_SIZE + $ivsize, SEEK_CUR) === -1) { throw new Ex\IOException( 'Cannot seek input file to beginning of ciphertext' ); @@ -534,7 +554,7 @@ public static function decryptResourceInternal($inputHandle, $outputHandle, KeyO \hash_update($hmac, $header); \hash_update($hmac, $file_salt); \hash_update($hmac, $iv); - /** @var resource $hmac2 */ + /** @var mixed $hmac2 */ $hmac2 = \hash_copy($hmac); $break = false; @@ -565,7 +585,7 @@ public static function decryptResourceInternal($inputHandle, $outputHandle, KeyO \hash_update($hmac, $read); /* Remember this buffer-sized chunk's HMAC. */ - /** @var resource $chunk_mac */ + /** @var mixed $chunk_mac */ $chunk_mac = \hash_copy($hmac); Core::ensureTrue(\is_resource($chunk_mac) || \is_object($chunk_mac), 'Cannot duplicate a hash context'); $macs []= \hash_final($chunk_mac); @@ -585,7 +605,7 @@ public static function decryptResourceInternal($inputHandle, $outputHandle, KeyO /* PASS #2: Decrypt and write output. */ /* Rewind to the start of the actual ciphertext. */ - if (\fseek($inputHandle, Core::SALT_BYTE_SIZE + $ivsize + Core::HEADER_VERSION_SIZE, SEEK_SET) === false) { + if (\fseek($inputHandle, Core::SALT_BYTE_SIZE + $ivsize + Core::HEADER_VERSION_SIZE, SEEK_SET) === -1) { throw new Ex\IOException( 'Could not move the input file pointer during decryption' ); @@ -619,7 +639,7 @@ public static function decryptResourceInternal($inputHandle, $outputHandle, KeyO * remembered from pass #1 to ensure attackers didn't change the * ciphertext after MAC verification. */ \hash_update($hmac2, $read); - /** @var resource $calc_mac */ + /** @var mixed $calc_mac */ $calc_mac = \hash_copy($hmac2); Core::ensureTrue(\is_resource($calc_mac) || \is_object($calc_mac), 'Cannot duplicate a hash context'); $calc = \hash_final($calc_mac); @@ -670,8 +690,6 @@ public static function decryptResourceInternal($inputHandle, $outputHandle, KeyO * * @throws Ex\IOException * @throws Ex\EnvironmentIsBrokenException - * - * @return string */ public static function readBytes($stream, $num_bytes) { @@ -711,8 +729,6 @@ public static function readBytes($stream, $num_bytes) * @return int * * @throws Ex\IOException - * - * @return string */ public static function writeBytes($stream, $buf, $num_bytes = null) {