コード例 #1
0
ファイル: Cabins.php プロジェクト: paragonie/airship
 /**
  * Update Cabin configuration
  *
  * @route cabins/manage{_string}
  * @param string $cabinName
  */
 public function manage(string $cabinName = '')
 {
     if (!$this->isSuperUser()) {
         // Admins only!
         \Airship\redirect($this->airship_cabin_prefix);
     }
     if (!\in_array($cabinName, $this->getCabinNamespaces())) {
         // Invalid cabin name
         \Airship\redirect($this->airship_cabin_prefix . '/cabins');
     }
     $this->setTemplateExtraData($cabinName);
     if (!$this->ensureCabinLinkExists($cabinName)) {
         \Airship\json_response(['error' => 'Could not create symlink']);
     }
     $cabin = \Airship\loadJSON(ROOT . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'cabins.json');
     // Apply the cabin's input filter:
     $filterName = '\\Airship\\Cabin\\' . $cabinName . '\\ConfigFilter';
     if (\class_exists($filterName)) {
         $filter = new $filterName();
     } else {
         $filter = (new GeneralFilterContainer())->addFilter('content_security_policy', new ArrayFilter());
     }
     $post = $this->post($filter);
     if (!empty($post)) {
         if ($this->saveSettings($cabinName, $cabin, $post)) {
             \Airship\redirect($this->airship_cabin_prefix . '/cabins/manage/' . $cabinName);
         }
     }
     $settings = [];
     foreach ($cabin as $path => $data) {
         if ($data['name'] === $cabinName) {
             $settings['cabin'] = $data;
             $settings['cabin']['path'] = $path;
             break;
         }
     }
     if (empty($settings['cabin'])) {
         // Cabin not found
         \Airship\redirect($this->airship_cabin_prefix);
     }
     $settings['content_security_policy'] = $this->loadJSONConfigFile($cabinName, 'content_security_policy.json');
     $settings['cabin_extra'] = \Airship\loadJSON(ROOT . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'Cabin' . DIRECTORY_SEPARATOR . $cabinName . DIRECTORY_SEPARATOR . 'config.json');
     $gadgets = ROOT . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'Cabin' . DIRECTORY_SEPARATOR . $cabinName . DIRECTORY_SEPARATOR . 'gadgets.json';
     if (!\file_exists($gadgets)) {
         \file_put_contents($gadgets, '[]');
     }
     $settings['gadgets'] = \Airship\loadJSON($gadgets);
     $settings['motifs'] = $this->getCabinsMotifs($cabinName);
     $settings['twig_vars'] = \Airship\loadJSON(ROOT . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'Cabin' . DIRECTORY_SEPARATOR . $cabinName . DIRECTORY_SEPARATOR . 'twig_vars.json');
     $this->lens('cabin_manage', ['name' => $cabinName, 'config' => $settings]);
 }
コード例 #2
0
ファイル: Notary.php プロジェクト: paragonie/airship
 /**
  * @route notary/verify
  */
 public function verify()
 {
     // Input validation
     if (empty($_POST['challenge'])) {
         \Airship\json_response(['status' => 'error', 'message' => 'Expected a challenge=something HTTP POST parameter.']);
     }
     if (!\is_string($_POST['challenge'])) {
         \Airship\json_response(['status' => 'error', 'message' => 'Challenge must be a string.']);
     }
     if (Binary::safeStrlen($_POST['challenge']) < 20) {
         \Airship\json_response(['status' => 'error', 'message' => 'Challenge is too short. Continuum should be generating a long random nonce.']);
     }
     try {
         list($update, $signature) = $this->chanUp->verifyUpdate($this->sk, $_POST['challenge']);
         \Airship\json_response(['status' => 'OK', 'response' => $update, 'signature' => $signature]);
     } catch (\Exception $ex) {
         \Airship\json_response(['status' => 'error', 'message' => $ex->getMessage()]);
     }
 }
コード例 #3
0
ファイル: Skyport.php プロジェクト: paragonie/airship
 /**
  * Trigger the package install process
  */
 public function updatePackage()
 {
     $expected = ['package', 'supplier', 'type', 'version'];
     if (!\Airship\all_keys_exist($expected, $_POST)) {
         \Airship\json_response(['status' => 'ERROR', 'message' => \__('Incomplete request.')]);
     }
     try {
         $filter = new SkyportFilter();
         $_POST = $filter($_POST);
     } catch (\TypeError $ex) {
         $this->log("Input violation", LogLevel::ALERT, \Airship\throwableToArray($ex));
         \Airship\json_response(['status' => 'ERROR', 'message' => \__('Invalid input.')]);
     }
     /**
      * @security We need to guarantee RCE isn't possible:
      */
     $args = \implode(' ', [\escapeshellarg(Util::charWhitelist($_POST['type'], Util::PRINTABLE_ASCII)), \escapeshellarg(Util::charWhitelist($_POST['supplier'], Util::PRINTABLE_ASCII) . '/' . Util::charWhitelist($_POST['package'], Util::PRINTABLE_ASCII)), \escapeshellarg(Util::charWhitelist($_POST['version'], Util::PRINTABLE_ASCII))]);
     $output = \shell_exec('php -dphar.readonly=0 ' . ROOT . '/CommandLine/update_one.sh ' . $args);
     \Airship\json_response(['status' => 'OK', 'message' => $output]);
 }
コード例 #4
0
ファイル: Account.php プロジェクト: paragonie/airship
 /**
  * Make sure the secret exists, then get the GoogleAuth object
  *
  * @param int $userID
  * @return GoogleAuth
  * @throws \Airship\Alerts\Security\UserNotLoggedIn
  */
 protected function twoFactorPreamble(int $userID = 0) : GoogleAuth
 {
     if (!$userID) {
         $userID = $this->getActiveUserId();
     }
     $secret = $this->acct->getTwoFactorSecret($userID);
     if (empty($secret)) {
         if (!$this->acct->resetTwoFactorSecret($userID)) {
             \Airship\json_response(['test2']);
             \Airship\redirect($this->airship_cabin_prefix);
         }
         $secret = $this->acct->getTwoFactorSecret($userID);
     }
     return new GoogleAuth($secret, new TOTP(0, (int) ($this->config('two-factor.period') ?? 30), (int) ($this->config('two-factor.length') ?? 6)));
 }
コード例 #5
0
ファイル: Ajax.php プロジェクト: paragonie/airship
 /**
  * @route ajax/authors_save_photo
  */
 public function saveAuthorsPhoto()
 {
     $auth_bp = $this->blueprint('Author');
     if (IDE_HACKS) {
         $db = \Airship\get_database();
         $auth_bp = new Author($db);
     }
     $authorId = (int) $_POST['author'];
     if (!$this->isSuperUser()) {
         $authors = $auth_bp->getAuthorIdsForUser($this->getActiveUserId());
         if (!\in_array($authorId, $authors)) {
             \Airship\json_response(['status' => 'ERROR', 'message' => \__('You do not have permission to access this author\'s posts.')]);
         }
     }
     if (!\Airship\all_keys_exist(['cabin', 'context', 'author', 'filename'], $_POST)) {
         \Airship\json_response(['keys' => array_keys($_POST), 'status' => 'ERROR', 'message' => 'Insufficient parameters']);
     }
     $result = $auth_bp->savePhotoChoice($authorId, $_POST['context'], $_POST['cabin'], $_POST['filename']);
     if (!$result) {
         \Airship\json_response(['status' => 'ERROR', 'message' => 'Could not save photo choice.', 'photo' => null]);
     }
     \Airship\json_response(['status' => 'OK', 'message' => 'Saved!']);
 }
コード例 #6
0
ファイル: Ajax.php プロジェクト: paragonie/airship
 /**
  * @param CacheInterface $cache
  * @param string $uniqueID
  */
 protected function fetchComments(CacheInterface $cache, string $uniqueID)
 {
     $blog = $this->blog->getBlogPostByUniqueId($uniqueID);
     $comments = $this->blog->getCommentTree((int) $blog['postid']);
     $contents = $this->lensRender('blog/comments', ['blogpost' => $blog, 'comments' => $comments, 'config' => $this->config()]);
     $cache->set($uniqueID, ['status' => 'OK', 'cached' => $contents]);
     \Airship\json_response(['status' => 'OK', 'cached' => $contents]);
 }