Example #1
0
 /**
  * Fire the add command!
  *
  * @param array $args
  * @return bool
  */
 public function fire(array $args = []) : bool
 {
     try {
         $this->getSession();
         $dir = $this->session['dir'] . $this->findRelativeDir();
     } catch (\Error $e) {
         echo $e->getMessage(), "\n";
         return false;
     }
     if (\count($args) === 0) {
         echo 'No file passed.', "\n";
         return false;
     }
     if (!isset($this->session['add'])) {
         echo 'Creating session data', "\n";
         $this->session['add'] = [];
     }
     $added = 0;
     foreach ($args as $file) {
         $l = Binary::safeStrlen($file) - 1;
         if ($file[$l] === DIRECTORY_SEPARATOR) {
             $file = Binary::safeSubstr($file, 0, -1);
         }
         $added += $this->addFile($file, $dir);
     }
     echo $added, ' file', $added === 1 ? '' : 's', ' added.', "\n";
     return true;
 }
Example #2
0
/**
 * Request a value.
 * @param string $text
 * @return string
 */
function prompt(string $text = '')
{
    static $fp = null;
    if ($fp === null) {
        $fp = \fopen('php://stdin', 'r');
    }
    echo $text;
    return Binary::safeSubstr(\fgets($fp), 0, -1);
}
Example #3
0
 /**
  * Work around poorly-configured web servers by parsing out the GET parameters
  *
  * Be forewarned: this will overwrite $lastPiece
  *
  * @param string& $lastPiece (optional)
  * @return array
  */
 protected function httpGetParams(string &$lastPiece = null) : array
 {
     if ($lastPiece === null) {
         return $_GET ?? [];
     }
     $p = \strpos($lastPiece, '?');
     if ($p !== false && empty($_GET)) {
         $_GET = \Airship\array_from_http_query(Binary::safeSubstr($lastPiece, $p + 1));
         $lastPiece = Binary::safeSubstr($lastPiece, 0, $p);
     }
     return $_GET;
 }
Example #4
0
 /**
  * If a file path is absolute, but still in the root, truncate it.
  * If a file path is relative to the root, return it.
  * Otherwise, thorw an error!
  *
  * @param string $file
  * @return string
  * @throws \Error
  */
 protected function getRealPath(string $file) : string
 {
     if (!\file_exists($file)) {
         throw new \Error('File not found: ' . $file);
     }
     if (\strpos($file, $this->session['dir']) === 0) {
         $x = Binary::safeStrlen($this->session['dir']);
         return Binary::safeSubstr($file, $x + 1);
     } elseif ($file[0] !== DIRECTORY_SEPARATOR) {
         return $file;
     } else {
         throw new \Error('File path is outside the root directory: ' . $file);
     }
 }
Example #5
0
 /**
  * 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();
 }
Example #6
0
<?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";
Example #7
0
 /**
  * WordPress's internal password hashing algorithm. Only used for migrations.
  * The actual security of CMS Airship doesn't depend on this algorithm.
  *
  * @internal
  * @param HiddenString $password
  * @param string $setting
  * @return string
  */
 private function wordPressCryptPrivate(HiddenString $password, string $setting) : string
 {
     $output = '*0';
     if (Binary::safeSubstr($setting, 0, 2) === $output) {
         $output = '*1';
     }
     $id = Binary::safeSubstr($setting, 0, 3);
     if ($id !== '$P$' && $id !== '$H$') {
         return $output;
     }
     // This is a really weird way to encode iteration count.
     $count_log2 = \strpos($this->itoa64, $setting[3]);
     if ($count_log2 < 7 || $count_log2 > 30) {
         return $output;
     }
     $count = 1 << $count_log2;
     $salt = Binary::safeSubstr($setting, 4, 8);
     if (Binary::safeStrlen($salt) !== 8) {
         return $output;
     }
     // And now we do our (default 8192) rounds of MD5...
     $hash = \md5($salt . $password->getString(), true);
     do {
         $hash = \md5($hash . $password->getString(), true);
     } while (--$count);
     $output = Binary::safeSubstr($setting, 0, 12);
     $output .= $this->encode64($hash, 16);
     return $output;
 }
Example #8
0
 /**
  * Binary-safe substr() implementation
  *
  * @param string $str
  * @param int $start
  * @param int|null $length
  * @return string
  */
 public static function subString(string $str, int $start, $length = null) : string
 {
     return Binary::safeSubstr($str, $start, $length);
 }
Example #9
0
/**
 * Configure the application event logger here
 */
$log_setup_closure = function () {
    $state = State::instance();
    $loggerClass = Gears::getName('Ledger');
    $args = [];
    /**
     * Here we build our logger storage class
     */
    switch ($state->universal['ledger']['driver']) {
        case 'file':
            $path = $state->universal['ledger']['path'];
            if (Binary::safeStrlen($path) >= 2) {
                if ($path[0] === '~' && $path[1] === '/') {
                    $path = ROOT . '/' . Binary::safeSubstr($path, 2);
                }
            }
            $storage = new FileStore($path, $state->universal['ledger']['file-format'] ?? FileStore::FILE_FORMAT, $state->universal['ledger']['time-format'] ?? FileStore::TIME_FORMAT);
            break;
        case 'database':
            $path = $state->universal['ledger']['connection'];
            try {
                $storage = new DBStore($path, $state->universal['ledger']['table'] ?? DBStore::DEFAULT_TABLE);
            } catch (\Throwable $ex) {
                \http_response_code(500);
                echo \file_get_contents(__DIR__ . '/error_pages/uncaught-exception.html');
                if ($state->universal['debug']) {
                    echo '<pre>', $ex->getTraceAsString(), '</pre>';
                }
                exit(1);
Example #10
0
<?php

declare (strict_types=1);
use ParagonIE\ConstantTime\Binary;
/**
 * Paragon Initiative Enterprises
 * PSR-4 compatible autoloader
 */
\spl_autoload_register(function ($class) {
    // Project-specific namespace prefix
    $prefix = 'Airship\\Hangar';
    // Base directory for the namespace prefix
    $base_dir = __DIR__ . DIRECTORY_SEPARATOR;
    // Does the class use the namespace prefix?
    $len = \strlen($prefix);
    if (\strncmp($prefix, $class, $len) !== 0) {
        // no, move to the next registered autoloader
        return;
    }
    // Get the relative class name
    $relative_class = Binary::safeSubstr($class, $len);
    // Replace the namespace prefix with the base directory, replace namespace
    // separators with directory separators in the relative class name, append
    // with .php
    $file = $base_dir . \str_replace(['\\', '_'], DIRECTORY_SEPARATOR, $relative_class) . '.php';
    // If the file exists, require it
    if (\file_exists($file)) {
        require $file;
    }
});
Example #11
0
 /**
  * Actually serve the HTTP request
  */
 public function route()
 {
     $this->loadInjectedRoutes();
     $args = [];
     foreach ($this->cabin['data']['routes'] as $path => $landing) {
         $path = self::makePath($path);
         if (self::testLanding($path, $_SERVER['REQUEST_URI'], $args)) {
             self::$mypath = $path;
             self::$path = Binary::safeSubstr($_SERVER['REQUEST_URI'], Binary::safeStrlen(self::$patternPrefix) + 1);
             try {
                 // Attempt to serve the page:
                 return $this->serve($landing, \array_slice($args, 1));
             } catch (EmulatePageNotFound $ex) {
                 // If this exception is throw, we will attempt to serve
                 // the fallback route (which might end up with a 404 page)
                 return $this->serveFallback();
             }
         }
     }
     return $this->serveFallback();
 }
Example #12
0
    $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);
    }
}
Example #13
0
 /**
  * @covers \Airship\tempnam()
  */
 public function testTempNam()
 {
     $name = \Airship\tempnam();
     $name2 = \Airship\tempnam('foo-');
     $name3 = \Airship\tempnam('foo-', 'txt');
     $this->assertFileNotExists($name);
     $this->assertFileNotExists($name2);
     $this->assertFileNotExists($name3);
     $this->assertSame('foo-', Binary::safeSubstr(\Airship\path_to_filename($name3), 0, 4));
     $this->assertSame('.txt', Binary::safeSubstr($name3, -4));
 }
Example #14
0
}
/**
 * Let the user know precisely what's wrong, if anything is wrong.
 */
if (!Halite::isLibsodiumSetupCorrectly()) {
    // Easiest way to grab this info:
    \ob_start();
    \phpinfo();
    $data = \ob_get_clean();
    $version = '';
    foreach (\explode("\n", $data) as $line) {
        if (empty($line)) {
            continue;
        }
        if (\strpos($line, 'libsodium compiled version') !== false) {
            $version = \trim(Binary::safeSubstr(\trim($line), -6));
            break;
        }
    }
    die("Your libsodium is not setup correctly. Please make sure you have at least:\n\n" . "\tlibsodium     v1.0.10 (Installed: " . \Sodium\version_string() . ")\n" . "\tlibsodium-php v1.0.6  (Installed: " . $version . ")\n");
}
/**
 * 3. Process the CLI parameters
 */
$showAll = true;
if ($argc < 2) {
    // Default behavior: Display the help menu
    $argv[1] = 'help';
    $showAll = false;
    $argc = 2;
}