/** * Cabin install process. * * 1. Extract files to proper directory. * 2. Run the update triggers (install hooks and incremental upgrades) * 3. Create/update relevant configuration files. * 4. Create symbolic links. * 5. Clear the cache files. * * @param InstallFile $fileInfo * @return bool */ public function install(InstallFile $fileInfo) : bool { $ns = $this->makeNamespace($this->supplier->getName(), $this->package); $alias = 'cabin.' . $this->supplier->getName() . '.' . $this->package . '.phar'; $updater = new \Phar($fileInfo->getPath(), \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::KEY_AS_FILENAME); $updater->setAlias($alias); $metadata = $updater->getMetadata(); // Overwrite files $updater->extractTo(ROOT . '/Cabin/' . $ns); // Run the update trigger. $updateTrigger = ROOT . '/Cabin/' . $ns . '/update_trigger.php'; if (\file_exists($updateTrigger)) { /** * @security Make sure arbitrary RCE isn't possible here. */ \shell_exec('php -dphar.readonly=0 ' . \escapeshellarg($updateTrigger) . ' >/dev/null 2>&1 &'); } // Free up the updater alias $garbageAlias = Base64UrlSafe::encode(\random_bytes(33)) . '.phar'; $updater->setAlias($garbageAlias); unset($updater); self::$continuumLogger->store(LogLevel::INFO, 'Cabin install successful', $this->getLogContext($fileInfo)); return $this->configure($ns, $metadata); }
<?php $fname = dirname(__FILE__) . '/tempmanifest2.phar.php'; $pname = 'phar://' . $fname; $phar = new Phar($fname); $phar->setDefaultStub(); $phar->setAlias('fred'); $phar['file1.txt'] = 'hi'; $phar['file2.txt'] = 'hi2'; $phar['subdir/ectory/file.txt'] = 'hi3'; $phar->mount($pname . '/mount2', __FILE__); $phar->addEmptyDir('one/level'); $phar->extractTo(dirname(__FILE__) . '/extract2', 'mount2'); $phar->extractTo(dirname(__FILE__) . '/extract2'); $out = array(); foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator(dirname(__FILE__) . '/extract2', 0x3000), RecursiveIteratorIterator::CHILD_FIRST) as $path => $file) { $extracted[] = $path; } sort($extracted); foreach ($extracted as $out) { echo "{$out}\n"; } ?> ===DONE=== <?php @unlink(dirname(__FILE__) . '/tempmanifest2.phar.php'); $dir = dirname(__FILE__) . '/extract2/'; @unlink($dir . 'file1.txt'); @unlink($dir . 'file2.txt'); @unlink($dir . 'subdir/ectory/file.txt'); @rmdir($dir . 'subdir/ectory');
<?php $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.tar'; $fname2 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.2.phar.tar'; $p = new Phar($fname); $p->setAlias('foo'); $p['unused'] = 'hi'; try { $a = new Phar($fname2, 0, 'foo'); } catch (Exception $e) { echo $e->getMessage(), "\n"; } copy($fname, $fname2); echo "2\n"; try { $a = new Phar($fname2); } catch (Exception $e) { echo $e->getMessage(), "\n"; } try { $b = new Phar($fname, 0, 'another'); } catch (Exception $e) { echo $e->getMessage(), "\n"; } ?> ===DONE=== <?php error_reporting(0); unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.tar'); unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.2.phar.tar');
$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php'; $fname2 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.2.phar.php'; if (file_exists($fname)) { unlink($fname); } if (file_exists($fname2)) { unlink($fname2); } $phar = new Phar($fname); // no entries, never flushed $phar->setAlias('first'); $phar->setMetadata('hi'); unset($phar); $phar = new Phar($fname2); $phar['b'] = 'whatever'; // flushed try { $phar->setAlias('first'); } catch (Exception $e) { echo $e->getMessage() . "\n"; } $phar = new Phar($fname); var_dump($phar->getMetadata()); var_dump($phar->getAlias()); var_dump(file_exists($fname)); ?> ===DONE=== <?php error_reporting(0); unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php'); unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.2.phar.php');
<?php $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php'; $pname = 'phar://' . $fname; $file = '<?php echo "first stub\\n"; __HALT_COMPILER(); ?>'; $files = array(); $files['a'] = 'a'; $files['b'] = 'b'; $files['c'] = 'c'; include 'files/phar_test.inc'; $phar = new Phar($fname); echo $phar->getAlias() . "\n"; $phar->setAlias('test'); echo $phar->getAlias() . "\n"; ?> ===DONE=== <?php error_reporting(0); unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php'); unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phartmp.php'); __halt_compiler(); ?>
<?php $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.tar.php'; $pname = 'phar://' . $fname; $fname2 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.2.phar.tar.php'; $pname2 = 'phar://' . $fname2; $phar = new Phar($fname); $phar->setMetadata('hi there'); $phar['a'] = 'hi'; $phar['a']->setMetadata('a meta'); $phar['b'] = 'hi2'; $phar['c'] = 'hi3'; $phar['b']->chmod(0444); $phar->setStub("<?php ok __HALT_COMPILER();"); $phar->setAlias("hime"); unset($phar); copy($fname, $fname2); Phar::unlinkArchive($fname); var_dump(file_exists($fname), file_exists($pname . '/a')); $phar = new Phar($fname2); var_dump($phar['a']->getContent(), $phar['b']->getContent(), $phar['c']->getContent()); var_dump((string) decoct(fileperms($pname2 . '/b'))); var_dump($phar->getStub()); var_dump($phar->getAlias()); var_dump($phar->getMetadata()); var_dump($phar['a']->getMetadata()); ?> ===DONE=== <?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.2.phar.tar.php');
$phar = new Phar($fname); var_dump($phar->getAlias()); unset($phar); copy(dirname(__FILE__) . '/files/metadata.phar.zip', $fname); // existing phar.zip, no alias set $phar = new Phar($fname); var_dump($phar->getAlias()); // check that default alias can be overwritten $phar->setAlias('jiminycricket'); var_dump($phar->getAlias()); unset($phar); // existing phar.zip, alias set $phar = new Phar($fname); var_dump($phar->getAlias()); // check that alias can't be set manually try { $phar['.phar/alias.txt'] = 'pinocchio'; } catch (Exception $e) { echo $e->getMessage() . "\n"; } var_dump($phar->getAlias()); // check that user-defined alias can be overwritten $phar->setAlias('pinocchio'); var_dump($phar->getAlias()); ?> ===DONE=== <?php error_reporting(0); unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.zip'); __halt_compiler(); ?>
/** * Gadget install process. * * 1. Move .phar to the appropriate location. * 2. If this gadget is for a particular cabin, add it to that cabin's * gadgets.json file. * 3. Run the update triggers (install hooks and incremental upgrades). * 4. Clear the cache files. * * @param InstallFile $fileInfo * @return bool */ public function install(InstallFile $fileInfo) : bool { $supplier = $this->supplier->getName(); $fileName = $supplier . '.' . $this->package . '.phar'; $metadata = $this->getMetadata($fileInfo); // Move .phar file to its destination. if (!empty($metadata['cabin'])) { $gadgetConfigFile = ROOT . '/Cabin/' . $metadata['cabin'] . '/config/gadgets.json'; // Cabin-specific gadget $cabin = ROOT . '/Cabin/' . $metadata['cabin'] . '/Gadgets'; if (!\is_dir($cabin)) { $this->log('Could not install; cabin "' . $metadata['cabin'] . '" is not installed.', LogLevel::ERROR); return false; } $filePath = $cabin . '/' . $supplier . '/' . $fileName; if (!\is_dir($cabin . '/' . $supplier)) { \mkdir($cabin . '/' . $supplier, 0775); } } else { $gadgetConfigFile = ROOT . '/config/gadgets.json'; // Universal gadget. (Probably affects the Engine.) $filePath = ROOT . '/Gadgets/' . $supplier . '/' . $fileName; if (!\is_dir(ROOT . '/Gadgets/' . $supplier)) { \mkdir(ROOT . '/Gadgets/' . $supplier, 0775); } } $gadgetConfig = \Airship\loadJSON($gadgetConfigFile); $gadgetConfig[] = [['supplier' => $supplier, 'name' => $this->package, 'version' => $metadata['version'] ?? null, 'path' => $filePath, 'enabled' => true]]; \Airship\saveJSON($gadgetConfigFile, $gadgetConfig); \rename($fileInfo->getPath(), $filePath); // If cabin-specific, add to the cabin's gadget.json if ($metadata['cabin']) { $this->addToCabin($metadata['cabin']); } // Run the update hooks: $alias = 'gadget.' . $fileName; $phar = new \Phar($filePath, \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::KEY_AS_FILENAME); $phar->setAlias($alias); // Run the update trigger. if (\file_exists('phar://' . $alias . '/update_trigger.php')) { Sandbox::safeRequire('phar://' . $alias . '/update_trigger.php'); } self::$continuumLogger->store(LogLevel::INFO, 'Install successful', $this->getLogContext($fileInfo)); // Finally, clear the cache files: return $this->clearCache(); }
/** * Build and configure Phar object. * * @return Phar */ private function buildPhar() { $phar = new Phar($this->destinationFile); if (!empty($this->stubPath)) { $phar->setStub(file_get_contents($this->stubPath)); } else { if (!empty($this->cliStubFile)) { $cliStubFile = $this->cliStubFile->getPathWithoutBase($this->baseDirectory); } else { $cliStubFile = null; } if (!empty($this->webStubFile)) { $webStubFile = $this->webStubFile->getPathWithoutBase($this->baseDirectory); } else { $webStubFile = null; } $phar->setDefaultStub($cliStubFile, $webStubFile); } if ($this->metadata === null) { $this->createMetaData(); } if ($metadata = $this->metadata->toArray()) { $phar->setMetadata($metadata); } if (!empty($this->alias)) { $phar->setAlias($this->alias); } return $phar; }
<?php if ($argc != 3) { die('Usage: ' . $argv[0] . ' <directory> <phar archive>' . PHP_EOL . PHP_EOL); } $phar = new Phar($argv[2]); $phar->buildFromDirectory($argv[1]); $phar->setAlias('this.phar'); $phar->setStub('<?php require \'phar://this.phar/Autoload.php\'; __HALT_COMPILER(); ?>'); print 'Created Phar archive ' . $argv[2] . ' from ' . $argv[1] . PHP_EOL;
<?php $stub = '<?php Phar::mapPhar(); spl_autoload_register(function ($class) { $classFile = "phar://pagi.phar/" . str_replace("\\\\", "/", $class) . ".php"; if (file_exists($classFile)) { require_once $classFile; return true; } }); include "phar://pagi.phar/PAGI/Autoloader/Autoloader.php"; \\PAGI\\Autoloader\\Autoloader::register(); __HALT_COMPILER(); ?>'; $phar = new Phar($argv[1]); $phar->setAlias('pagi.phar'); $phar->buildFromDirectory($argv[2]); $phar->setStub($stub);
<?php $p = new Phar(__FILE__); var_dump($p->getAlias()); $p2 = new Phar(__FILE__); $p->setAlias("hi"); echo $p2->getAlias(), "\n"; echo "ok\n"; __halt_compiler(); ?> 6test.txtt��Hzzo�hi �����Ji5���4 QCڱ�GBMB
/** * Build and configure Phar object. * * @return Phar */ private function buildPhar() { $phar = new Phar($this->destinationFile); if ($this->signatureAlgorithm == Phar::OPENSSL) { // Load up the contents of the key $keyContents = file_get_contents($this->key); // Attempt to load the given key as a PKCS#12 Cert Store first. if (openssl_pkcs12_read($keyContents, $certs, $this->keyPassword)) { $private = openssl_pkey_get_private($certs['pkey']); } else { // Fall back to a regular PEM-encoded private key. // Setup an OpenSSL resource using the private key // and tell the Phar to sign it using that key. $private = openssl_pkey_get_private($keyContents, $this->keyPassword); } $phar->setSignatureAlgorithm(Phar::OPENSSL, $private); // Get the details so we can get the public key and write that out // alongside the phar. $details = openssl_pkey_get_details($private); file_put_contents($this->destinationFile . '.pubkey', $details['key']); } else { $phar->setSignatureAlgorithm($this->signatureAlgorithm); } if (!empty($this->stubPath)) { $phar->setStub(file_get_contents($this->stubPath)); } else { if (!empty($this->cliStubFile)) { $cliStubFile = $this->cliStubFile->getPathWithoutBase($this->baseDirectory); } else { $cliStubFile = null; } if (!empty($this->webStubFile)) { $webStubFile = $this->webStubFile->getPathWithoutBase($this->baseDirectory); } else { $webStubFile = null; } $phar->setDefaultStub($cliStubFile, $webStubFile); } if ($this->metadata === null) { $this->createMetaData(); } if ($metadata = $this->metadata->toArray()) { $phar->setMetadata($metadata); } if (!empty($this->alias)) { $phar->setAlias($this->alias); } return $phar; }
<?php $stub = '<?php Phar::mapPhar(); spl_autoload_register(function ($class) { $classFile = "phar://pami.phar/" . str_replace("\\\\", "/", $class) . ".php"; if (file_exists($classFile)) { require_once $classFile; return true; } }); include "phar://pami.phar/PAMI/Autoloader/Autoloader.php"; \\PAMI\\Autoloader\\Autoloader::register(); __HALT_COMPILER(); ?>'; $phar = new Phar($argv[1]); $phar->setAlias('pami.phar'); $phar->buildFromDirectory($argv[2]); $phar->setStub($stub);
<?php $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.zip'; $fname2 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.2.phar.zip'; $alias = 'phar://hio'; $phar = new Phar($fname); $phar['a.php'] = '<?php echo "This is a\\n"; include "' . $alias . '/b.php"; ?>'; $phar->setAlias('hio'); $phar->addEmptyDir('test'); $phar->stopBuffering(); try { var_dump($phar['a.php']->isExecutable()); $phar['a.php']->chmod(0777); copy($fname, $fname2); $phar->setAlias('unused'); $phar2 = new Phar($fname2); var_dump($phar2['a.php']->isExecutable()); $phar['a.php']->chmod(0666); var_dump($phar['a.php']->isExecutable()); echo "test dir\n"; var_dump($phar['test']->isDir()); var_dump($phar['test']->isReadable()); $phar['test']->chmod(00); var_dump($phar['test']->isReadable()); $phar['test']->chmod(0666); var_dump($phar['test']->isReadable()); } catch (Exception $e) { echo $e->getMessage() . "\n"; } ?> ===DONE===
<?php $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php'; $pname = 'phar://' . $fname; $phar = new Phar($fname); $phar->setDefaultStub(); $phar->setAlias('susan'); $phar['a.txt'] = "first file\n"; $phar['b.txt'] = "second file\n"; try { $phar->offsetGet('.phar/stub.php'); } catch (Exception $e) { echo $e->getMessage() . "\n"; } try { $phar->offsetGet('.phar/alias.txt'); } catch (Exception $e) { echo $e->getMessage() . "\n"; } try { $phar->offsetSet('.phar/stub.php', '<?php __HALT_COMPILER(); ?>'); } catch (Exception $e) { echo $e->getMessage() . "\n"; } var_dump(strlen($phar->getStub())); try { $phar->offsetUnset('.phar/stub.php'); } catch (Exception $e) { echo $e->getMessage() . "\n"; } var_dump(strlen($phar->getStub()));
<?php $stub = '<?php require_once "phar://ciphp.phar/App/App.php"; __HALT_COMPILER(); ?>'; $phar = new Phar($argv[1]); $phar->setAlias('ciphp.phar'); $phar->buildFromDirectory($argv[2]); $phar->setStub($stub);
$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.zip'; $fname2 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '2.phar.zip'; $fname3 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '3.phar.zip'; $phar = new Phar($fname); $phar->setStub('<?php echo "first stub\\n"; __HALT_COMPILER(); ?>'); $phar->setAlias('hio'); $files = array(); $files['a'] = 'a'; $files['b'] = 'b'; $files['c'] = 'c'; foreach ($files as $n => $file) { $phar[$n] = $file; } $phar->stopBuffering(); echo $phar->getAlias() . "\n"; $phar->setAlias('test'); echo $phar->getAlias() . "\n"; // test compression $phar->compressFiles(Phar::GZ); copy($fname, $fname2); $phar->setAlias('unused'); $p2 = new Phar($fname2); echo $p2->getAlias(), "\n"; $p2->compressFiles(Phar::BZ2); copy($fname2, $fname3); $p2->setAlias('unused2'); $p3 = new Phar($fname3); echo $p3->getAlias(), "\n"; ?> ===DONE===
/** * Let's install the automatic update. * * If we get to this point: * * 1. We know the signature is signed by * Paragon Initiative Enterprises, LLC. * 2. The hash was checked into Keyggdrasil, which * was independently vouched for by our peers. * * @param UpdateInfo $info * @param UpdateFile $file * @throws CouldNotUpdate */ protected function install(UpdateInfo $info, UpdateFile $file) { if (!$file->hashMatches($info->getChecksum())) { throw new CouldNotUpdate(\__('Checksum mismatched')); } // Let's open the update package: $path = $file->getPath(); $updater = new \Phar($path, \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::KEY_AS_FILENAME); $updater->setAlias($this->pharAlias); $metadata = $updater->getMetadata(); // We need to do this while we're replacing files. $this->bringSiteDown(); if (isset($metadata['files'])) { foreach ($metadata['files'] as $fileName) { $this->replaceFile($fileName); } } if (isset($metadata['autoRun'])) { foreach ($metadata['autoRun'] as $autoRun) { $this->autoRunScript($autoRun); } } // If we included composer.lock, we need to install the dependencies. if (\in_array('composer.lock', $metadata['files'])) { $composers = ['/usr/bin/composer', '/usr/bin/composer.phar', \dirname(ROOT) . '/composer', \dirname(ROOT) . '/composer.phar']; $composerUpdated = false; foreach ($composers as $composer) { if (\file_exists($composer)) { $dir = \getcwd(); \chdir(\dirname(ROOT)); \shell_exec("{$composer} install"); \chdir($dir); $composerUpdated = true; break; } } if (!$composerUpdated) { self::$continuumLogger->store(LogLevel::INFO, 'Could not update dependencies. Please run Composer manually.', $this->getLogContext($info, $file)); } } // Free up the updater alias $garbageAlias = Base64UrlSafe::encode(\random_bytes(63)) . '.phar'; $updater->setAlias($garbageAlias); unset($updater); // Now bring it back up. $this->bringSiteBackUp(); self::$continuumLogger->store(LogLevel::INFO, 'CMS Airship core update installed', $this->getLogContext($info, $file)); }
/** * Build and configure Phar object. * * @return Phar */ private function buildPhar() { $phar = new Phar($this->destinationFile, 0, $this->alias); $phar->setSignatureAlgorithm($this->signatureAlgorithm); /* * File compression, if needed. */ if (Phar::NONE != $this->compression) { $phar->compressFiles($this->compression); } if (isset($this->customStubPath)) { $phar->setStub(file_get_contents($this->customStubPath)); } else { $phar->setDefaultStub($this->cliStubFile, $this->webStubFile); } if ($metadata = $this->metadata->toArray()) { $phar->setMetadata($metadata); } if (!empty($this->alias)) { $phar->setAlias($this->alias); } return $phar; }
<?php $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar'; $p = new Phar($fname); try { $p->setAlias('hi/'); } catch (Exception $e) { echo $e->getMessage() . "\n"; } try { $p->setAlias('hi\\l'); } catch (Exception $e) { echo $e->getMessage() . "\n"; } try { $p->setAlias('hil;'); } catch (Exception $e) { echo $e->getMessage() . "\n"; } try { $p->setAlias(':hil'); } catch (Exception $e) { echo $e->getMessage() . "\n"; } ?> ===DONE=== <?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar');
print_exception($e); } $b->delete(array()); try { $a->delete('oops'); } catch (Exception $e) { echo $e->getMessage() . "\n"; } try { $b->delete('oops'); } catch (Exception $e) { echo $e->getMessage() . "\n"; } echo $a->getPath() . "\n"; try { $a->setAlias('oops'); } catch (Exception $e) { echo $e->getMessage() . "\n"; } try { $b->setAlias('oops'); } catch (Exception $e) { echo $e->getMessage() . "\n"; } ini_set('phar.readonly', 0); $a->setAlias(array()); ini_set('phar.readonly', 1); try { $b->stopBuffering(); } catch (Exception $e) { echo $e->getMessage() . "\n";
/** * Build and configure Phar object. * * @return Phar */ private function buildPhar() { $phar = new Phar($this->destinationFile); $phar->setSignatureAlgorithm($this->signatureAlgorithm); if (isset($this->stubPath)) { $phar->setStub(file_get_contents($this->stubPath)); } else { $phar->setDefaultStub($this->cliStubFile->getPathWithoutBase($this->baseDirectory), $this->webStubFile->getPathWithoutBase($this->baseDirectory)); } if ($metadata = $this->metadata->toArray()) { $phar->setMetadata($metadata); } if (!empty($this->alias)) { $phar->setAlias($this->alias); } return $phar; }
/** * We just need to replace the Phar * * If we get to this point: * * 1. We know the signature is signed by the supplier. * 2. The hash was checked into Keyggdrasil, which * was independently vouched for by our peers. * * @param UpdateInfo $info * @param UpdateFile $file * @throws CouldNotUpdate */ protected function install(UpdateInfo $info, UpdateFile $file) { if (!$file->hashMatches($info->getChecksum())) { throw new CouldNotUpdate(\__('Checksum mismatched')); } // Create a backup of the old Gadget: \rename($this->filePath, $this->filePath . '.backup'); \rename($file->getPath(), $this->filePath); $this->log('Begin install process', LogLevel::DEBUG, ['path' => $file->getPath(), 'hash' => $file->getHash(), 'version' => $file->getVersion(), 'size' => $file->getSize()]); // Get metadata from the old version of this Gadget: $oldAlias = Base64UrlSafe::encode(\random_bytes(48)) . '.phar'; $oldGadget = new \Phar($this->filePath, \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::KEY_AS_FILENAME); $oldGadget->setAlias($oldAlias); $oldMetadata = $oldGadget->getMetadata(); unset($oldGadget); unset($oldAlias); // Let's open the update package: $newGadget = new \Phar($this->filePath, \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::KEY_AS_FILENAME, $this->pharAlias); $newGadget->setAlias($this->pharAlias); $metaData = $newGadget->getMetadata(); // We need to do this while we're replacing files. $this->bringSiteDown(); Sandbox::safeRequire('phar://' . $this->pharAlias . '/update_trigger.php', $oldMetadata); // Free up the updater alias $garbageAlias = Base64UrlSafe::encode(\random_bytes(48)) . '.phar'; $newGadget->setAlias($garbageAlias); unset($newGadget); // Now bring it back up. $this->bringSiteBackUp(); // Make sure we update the version info. in the DB cache: $this->updateDBRecord('Gadget', $info); if ($metaData) { $this->updateJSON($info, $metaData); } self::$continuumLogger->store(LogLevel::INFO, 'Gadget update installed', $this->getLogContext($info, $file)); }
/** * Get metadata from the Phar * * @param string $file * @return array */ public function getPharManifest(string $file) : array { $phar = new \Phar($file); $phar->setAlias(Base64UrlSafe::encode(\random_bytes(33))); $meta = $phar->getMetadata(); if (empty($meta)) { return []; } return $meta; }
/** * Build and configure Phar object. * * @return Phar */ private function buildPhar() { $phar = new Phar($this->destinationFile); if ($this->signatureAlgorithm == Phar::OPENSSL) { // Load up the contents of the key $keyContents = file_get_contents($this->key); // Setup an OpenSSL resource using the private key and tell the Phar // to sign it using that key. $private = openssl_pkey_get_private($keyContents, $this->keyPassword); $phar->setSignatureAlgorithm(Phar::OPENSSL, $private); // Get the details so we can get the public key and write that out // alongside the phar. $details = openssl_pkey_get_details($private); file_put_contents($this->destinationFile . '.pubkey', $details['key']); } else { $phar->setSignatureAlgorithm($this->signatureAlgorithm); } if (isset($this->stubPath)) { $phar->setStub(file_get_contents($this->stubPath)); } else { if (!empty($this->cliStubFile)) { $cliStubFile = $this->cliStubFile->getPathWithoutBase($this->baseDirectory); } else { $cliStubFile = null; } if (!empty($this->webStubFile)) { $webStubFile = $this->webStubFile->getPathWithoutBase($this->baseDirectory); } else { $webStubFile = null; } $phar->setDefaultStub($cliStubFile, $webStubFile); } if ($metadata = $this->metadata->toArray()) { $phar->setMetadata($metadata); } if (!empty($this->alias)) { $phar->setAlias($this->alias); } return $phar; }
<?php $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar'; $tname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.zip'; $alias = 'phar://hio'; $phar = new Phar($fname); $phar['a.php'] = '<?php echo "This is a\\n"; include "' . $alias . '/b.php"; ?>'; $phar->setAlias('hio'); $phar->addEmptyDir('test'); $phar->stopBuffering(); copy($fname, $tname); $phar->setAlias('hio2'); try { $p = new Phar($tname); } catch (Exception $e) { echo $e->getMessage() . "\n"; } ?> ===DONE===
/** * Install an updated version of a cabin * * If we get to this point: * * 1. We know the signature is signed by the supplier. * 2. The hash was checked into Keyggdrasil, which * was independently vouched for by our peers. * * @param UpdateInfo $info * @param UpdateFile $file * @throws CouldNotUpdate */ protected function install(UpdateInfo $info, UpdateFile $file) { if (!$file->hashMatches($info->getChecksum())) { throw new CouldNotUpdate(\__('Checksum mismatched')); } $path = $file->getPath(); $this->log('Begin Cabin updater', LogLevel::DEBUG, ['path' => $path, 'supplier' => $info->getSupplierName(), 'name' => $info->getPackageName()]); $updater = new \Phar($path, \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::KEY_AS_FILENAME); $updater->setAlias($this->pharAlias); $ns = $this->makeNamespace($info->getSupplierName(), $info->getPackageName()); // We need to do this while we're replacing files. $this->bringCabinDown($ns); $oldMetadata = \Airship\loadJSON(ROOT . '/Cabin/' . $ns . '/manifest.json'); // Overwrite files $updater->extractTo(ROOT . '/Cabin/' . $ns, null, true); // Run the update trigger. Sandbox::safeInclude('phar://' . $this->pharAlias . '/update_trigger.php', $oldMetadata); // Free up the updater alias $garbageAlias = Base64UrlSafe::encode(\random_bytes(33)) . '.phar'; $updater->setAlias($garbageAlias); unset($updater); // Now bring it back up. $this->bringCabinBackUp($ns); // Make sure we update the version info. in the DB cache: $this->updateDBRecord('Cabin', $info); $this->log('Conclude Cabin updater', LogLevel::DEBUG, ['path' => $path, 'supplier' => $info->getSupplierName(), 'name' => $info->getPackageName()]); self::$continuumLogger->store(LogLevel::INFO, 'Cabin update installed', $this->getLogContext($info, $file)); }
<?php $fname = dirname(__FILE__) . '/phar_gzip.phar'; $pname = 'phar://' . $fname; $fname2 = dirname(__FILE__) . '/phar_gzip.2.phar'; $pname2 = 'phar://' . $fname2; $file = '<?php Phar::mapPhar(); var_dump("it worked"); include "phar://" . __FILE__ . "/tar_004.php"; __HALT_COMPILER();'; $files = array(); $files['tar_004.php'] = '<?php var_dump(__FILE__);'; $files['internal/file/here'] = "hi there!\n"; $files['internal/dir/'] = ''; $files['dir/'] = ''; $gzip = true; include 'files/phar_test.inc'; include $fname; $a = new Phar($fname); $a['test'] = 'hi'; copy($fname, $fname2); $a->setAlias('another'); $b = new Phar($fname2); var_dump($b->isFileFormat(Phar::PHAR)); var_dump($b->isCompressed() == Phar::GZ); ?> ===DONE===
<?php $stub = '<?php Phar::mapPhar(); spl_autoload_register(function ($class) { $classFile = "phar://ding.phar/" . str_replace("\\\\", "/", $class) . ".php"; if (file_exists($classFile)) { require_once $classFile; return true; } }); include "phar://ding.phar/Ding/Autoloader/Autoloader.php"; \\Ding\\Autoloader\\Autoloader::register(); __HALT_COMPILER(); ?>'; $phar = new Phar($argv[1]); $phar->setAlias('ding.phar'); $phar->buildFromDirectory($argv[2]); $phar->setStub($stub);