/** * Load all of the supplier's Ed25519 public keys * * @param string $supplier * @param boolean $force_flush * @return SupplierObject|SupplierObject[] * @throws NoSupplier */ public function getSupplier(string $supplier = '', bool $force_flush = false) { if (empty($supplier)) { // Fetch all suppliers if ($force_flush || empty($this->supplierCache)) { $supplierCache = []; $allSuppliers = \Airship\list_all_files(ROOT . '/config/supplier_keys', 'json'); foreach ($allSuppliers as $supplierKeyFile) { // We want everything except the .json $supplier = $this->escapeSupplierName(Binary::safeSubstr($this->getEndPiece($supplierKeyFile), 0, -5)); try { $data = \Airship\loadJSON($supplierKeyFile); } catch (FileNotFound $ex) { $data = []; } $supplierCache[$supplier] = new SupplierObject($supplier, $data); } $this->supplierCache = $supplierCache; } return $this->supplierCache; } // Otherwise, we're just fetching one supplier's keys if ($force_flush || empty($this->supplierCache[$supplier])) { try { $supplier = $this->escapeSupplierName($supplier); $supplierFile = ROOT . '/config/supplier_keys/' . $supplier . '.json'; if (!\file_exists($supplierFile)) { throw new NoSupplier(\__("Supplier file not found: %s", "default", $supplierFile)); } $data = \Airship\loadJSON($supplierFile); } catch (FileNotFound $ex) { throw new NoSupplier(\__("Supplier not found: %s", "default", $supplier), 0, $ex); } $this->supplierCache[$supplier] = new SupplierObject($supplier, $data); } if (isset($this->supplierCache[$supplier])) { return $this->supplierCache[$supplier]; } throw new NoSupplier(); }
<?php declare (strict_types=1); use ParagonIE\ConstantTime\Binary; require_once \dirname(__DIR__) . '/src/bootstrap.php'; /** * Grabs a random file and tells you to audit it. */ if ($argc > 1) { $extensions = \array_slice($argv, 1); } else { $extensions = ['php', 'twig']; } $fileList = []; foreach ($extensions as $ex) { foreach (\Airship\list_all_files(\dirname(__DIR__) . '/src/', $ex) as $file) { $fileList[] = $file; } } $choice = \random_int(0, \count($fileList) - 1); echo "Audit this file:\n\t"; $l = Binary::safeStrlen(\dirname(__DIR__)); echo Binary::safeSubstr($fileList[$choice], $l), "\n";
/** * Get an array of GadgetUpdater objects * * @return GadgetUpdater[] */ public function getGadgets() : array { $gadgets = []; // First, each cabin's gadgets: foreach (\glob(ROOT . '/Cabin/*') as $dir) { if (!\is_dir($dir)) { continue; } $cabinInfo = \Airship\loadJSON($dir . '/manifest.json'); if (\is_dir($dir . '/Gadgets')) { foreach (\Airship\list_all_files($dir . '/Gadgets/', 'phar') as $file) { $manifest = $this->getPharManifest($file); $name = \preg_replace('#^.+?/([^\\/]+)\\.phar$#', '$1', $file); $gadgets[$name] = new GadgetUpdater($this->hail, $manifest, $this->getSupplier($manifest['supplier']), $file); $gadgets[$name]->setCabin($cabinInfo['supplier'], $cabinInfo['name']); } } } // Then, the universal gadgets: foreach (\Airship\list_all_files(ROOT . '/Gadgets/', 'phar') as $file) { $manifest = $this->getPharManifest($file); $name = \preg_replace('#^.+?/([^\\/]+)\\.phar$#', '$1', $file); $orig = '' . $name; // Handle name collisions while (isset($gadgets[$name])) { $i = isset($i) ? ++$i : 2; $name = $orig . '-' . $i; } $gadgets[$name] = new GadgetUpdater($this->hail, $manifest, $this->getSupplier($manifest['supplier']), $file); } return $gadgets; }
/** * Clears all cached data. * * @return bool */ function clear_cache() { \clearstatcache(); if (\extension_loaded('apcu')) { \apcu_clear_cache(); } $dirs = ['comments', 'csp_hash', 'csp_static', 'html_purifier', 'markdown', 'static']; foreach ($dirs as $dir) { if (!\is_dir($dir)) { \mkdir($dir, 0775, true); continue; } foreach (\Airship\list_all_files(ROOT . '/tmp/cache/' . $dir) as $f) { if (\is_dir($f)) { continue; } if (\preg_match('#/([0-9a-z]+)$#', $f)) { \unlink($f); } } } // Nuke the Twig cache separately: foreach (\Airship\list_all_files(ROOT . '/tmp/cache/twig') as $f) { if (\is_dir($f)) { continue; } if (\preg_match('#/([0-9a-z]+).php$#', $f)) { \unlink($f); } } foreach (\glob(ROOT . '/tmp/cache/*.json') as $file) { \unlink($file); } \clearstatcache(); return true; }
$link = ROOT . '/public/static/' . $active['name']; if (!\is_link($link)) { // Remove copies, we only allow symlinks in static if (\is_dir($link)) { \rmdir($link); } elseif (\file_exists($link)) { \unlink($link); } // Create a symlink from public/static/* to Cabin/*/public /** @noinspection PhpUsageOfSilenceOperatorInspection */ @\symlink(CABIN_DIR . '/public', ROOT . '/public/static/' . $active['name']); } } // Let's load the default cargo modules if (\is_dir(CABIN_DIR . '/Lens/cargo')) { $cargoCacheFile = ROOT . '/tmp/cache/cargo-' . $active['name'] . '.cache.json'; if (\file_exists($cargoCacheFile)) { $data = Airship\loadJSON($cargoCacheFile); $state->cargo = $data; } else { $dir = \getcwd(); \chdir(CABIN_DIR . '/Lens'); foreach (\Airship\list_all_files('cargo', 'twig') as $cargo) { $idx = \str_replace(['__', '/'], ['', '__'], Binary::safeSubstr($cargo, 6, -5)); Gadgets::loadCargo($idx, $cargo); } \chdir($dir); // Store the cache file \Airship\saveJSON($cargoCacheFile, $state->cargo); } }
/** * We just need to clear the template caches and the cabin data. * * @return bool */ public function clearCache() : bool { \Airship\clear_cache(); $dirs = ['csp_hash', 'csp_static', 'html_purifier', 'markdown', 'rst', 'static', 'twig']; foreach ($dirs as $dir) { if (!\is_dir(ROOT . '/tmp/cache/' . $dir)) { continue; } foreach (\Airship\list_all_files(ROOT . '/tmp/cache/' . $dir) as $file) { if ($file === ROOT . '/tmp/cache/' . $dir . '/.gitignore') { continue; } \unlink($file); } } if (\file_exists(ROOT . '/tmp/cache/cabin_data.json')) { \unlink(ROOT . '/tmp/cache/cabin_data.json'); } \clearstatcache(); return true; }
/** * @route admin/settings */ public function manageSettings() { $state = State::instance(); $settings = ['universal' => $state->universal]; $post = $this->post(new SettingsFilter()); if (!empty($post)) { if ($this->saveSettings($post)) { \Airship\clear_cache(); \Airship\redirect($this->airship_cabin_prefix . '/admin/settings', ['msg' => 'saved']); } else { $this->log('Could not save new settings', LogLevel::ALERT); } } // Load individual files... $settings['cabins'] = $this->loadJSONConfigFile('cabins.json'); $settings['content_security_policy'] = $this->loadJSONConfigFile('content_security_policy.json'); $settings['keyring'] = $this->loadJSONConfigFile('keyring.json'); foreach (\Airship\list_all_files(ROOT . '/config/supplier_keys/', 'json') as $supplier) { $name = \Airship\path_to_filename($supplier, true); $settings['suppliers'][$name] = \Airship\loadJSON($supplier); } $this->lens('admin_settings', ['active_link' => 'bridge-link-admin-settings', 'config' => $settings, 'groups' => $this->acct->getGroupTree()]); }
use Airship\Engine\Security\Util; require_once \dirname(__DIR__) . '/src/bootstrap.php'; /** * Generates a list of all files -- use this for narrowing * the scope of a pre-release code audit. */ if ($argc > 1) { $extensions = \array_slice($argv, 1); } else { $extensions = ['php', 'twig']; } $fileList = []; $repository = 'https://github.com/paragonie/airship/blob/master/'; $cutoff = \strlen(\dirname(__DIR__) . '/src') + 1; $dirs = []; $allDirs = \Airship\list_all_files(\dirname(__DIR__) . '/src'); \sort($allDirs, \SORT_STRING & ~\SORT_FLAG_CASE); foreach ($allDirs as $file) { $print = \trim(Util::subString($file, $cutoff), '/'); $pieces = \explode('/', $print); $max = \count($pieces) - 1; $name = \array_pop($pieces); if (Util::subString($print, 0, 3) === 'tmp' || Util::subString($print, 0, 5) === 'files') { continue; } $currentDir = \implode('/', $pieces); if ($max > 0 && !isset($dirs[$currentDir])) { echo \str_repeat(' ', 3 * ($max - 1)) . '- [ ] '; echo $pieces[$max - 1]; $dirs[$currentDir] = true; echo "\n";
/** * Create the default pages (about, contact). */ protected function finalDefaultPages() { foreach (\Airship\list_all_files(ROOT . '/Installer/default_pages') as $file) { $filedata = \file_get_contents($file); if (\preg_match('#/([^./]+).md$#', $file, $m)) { $pageid = $this->db->insertGet('airship_custom_page', ['cabin' => 'Hull', 'url' => $m[1], 'active' => true, 'cache' => false], 'pageid'); $this->db->insert('airship_custom_page_version', ['page' => $pageid, 'uniqueid' => \Airship\uniqueId(), 'published' => true, 'formatting' => 'Markdown', 'bridge_user' => 1, 'body' => $filedata, 'metadata' => '[]', 'raw' => false]); } } }