Beispiel #1
0
 /**
  * @param resource $resource Stream resource.
  * @param bool $autoClose True to close the resource on destruct, false to leave it open.
  */
 public function __construct($resource, bool $autoClose = true)
 {
     parent::__construct($resource, $autoClose);
     stream_set_write_buffer($resource, 0);
     stream_set_chunk_size($resource, self::CHUNK_SIZE);
     $this->writeQueue = new \SplQueue();
     $this->onCancelled = function (Throwable $exception) {
         $this->free($exception);
     };
 }
Beispiel #2
0
 /**
  * @param resource $resource Stream resource.
  * @param bool $autoClose True to close the resource on destruct, false to leave it open.
  */
 public function __construct($resource, bool $autoClose = true)
 {
     parent::__construct($resource, $autoClose);
     stream_set_read_buffer($resource, 0);
     stream_set_chunk_size($resource, self::CHUNK_SIZE);
     $this->queue = new \SplQueue();
     $this->poll = $this->createPoll($resource, $this->queue);
     $this->onCancelled = function () {
         $this->poll->cancel();
         $this->queue->shift();
     };
 }
 /**
  * Returns the pointer to the random source.
  * @return resource The pointer to the random source.
  */
 private function getPointer()
 {
     if (!isset($this->pointer)) {
         $this->pointer = fopen($this->source, 'r');
         // File read buffering is not supported on HHVM
         if (!defined('HHVM_VERSION')) {
             stream_set_chunk_size($this->pointer, 32);
             stream_set_read_buffer($this->pointer, 32);
         }
     }
     return $this->pointer;
 }
Beispiel #4
0
 function __construct($host, $port, $timeout_ms = 2000)
 {
     $timeout_f = (double) $timeout_ms / 1000;
     $this->sock = @stream_socket_client("{$host}:{$port}", $errno, $errstr, $timeout_f);
     if (!$this->sock) {
         throw new SSDBException("{$errno}: {$errstr}");
     }
     $timeout_sec = intval($timeout_ms / 1000);
     $timeout_usec = ($timeout_ms - $timeout_sec * 1000) * 1000;
     @stream_set_timeout($this->sock, $timeout_sec, $timeout_usec);
     if (function_exists('stream_set_chunk_size')) {
         @stream_set_chunk_size($this->sock, 1024 * 1024);
     }
 }
 function __construct($stream, $eol = false)
 {
     $this->eol = $eol ?: null;
     $this->ceol = strlen($eol ?: PHP_EOL);
     if (!$eol) {
         ini_set('auto_detect_line_endings', true);
     }
     if (is_resource($stream)) {
         $this->stream = $stream;
     } else {
         $this->stream = fopen($stream, 'rb+');
     }
     stream_set_chunk_size($this->stream, $this->blocksize);
 }
Beispiel #6
0
 public function __construct($host, $port, $connection_timeout, $read_write_timeout = null, $context = null, $blocking = false)
 {
     $errstr = $errno = null;
     $this->sock = null;
     if ($context) {
         $remote = sprintf('tls://%s:%s', $host, $port);
         $this->sock = @stream_socket_client($remote, $errno, $errstr, $connection_timeout, STREAM_CLIENT_CONNECT, $context);
     } else {
         $remote = sprintf('tcp://%s:%s', $host, $port);
         $this->sock = @stream_socket_client($remote, $errno, $errstr, $connection_timeout, STREAM_CLIENT_CONNECT);
     }
     if (!$this->sock) {
         throw new RuntimeException("Error Connecting to server({$errno}): {$errstr} ");
     }
     if (null !== $read_write_timeout) {
         if (!stream_set_timeout($this->sock, $read_write_timeout)) {
             throw new \Exception("Timeout (stream_set_timeout) could not be set");
         }
     }
     /**
      * Manually set blocking & write buffer settings and make sure they are successfuly set
      * Use non-blocking as we dont want to stuck waiting for socket data while fread() w/o timeout
      */
     if (!stream_set_blocking($this->sock, $blocking)) {
         throw new \Exception("Blocking could not be set");
     }
     $rbuff = stream_set_read_buffer($this->sock, 0);
     if (!(0 === $rbuff)) {
         throw new \Exception("Read buffer could not be set");
     }
     /**
      * ! this is not reliably returns success (0)
      * ! but default buffer is pretty high (few Kb), so will not affect sending single small pushes
      *
      * Output using fwrite() is normally buffered at 8K.
      * This means that if there are two processes wanting to write to the same output stream (a file),
      * each is paused after 8K of data to allow the other to write.
      *
      * Ensures that all writes with fwrite() are completed
      * before other processes are allowed to write to that output stream
      */
     stream_set_write_buffer($this->sock, 0);
     /**
      * Set small chunk size (default=4096/8192)
      * Setting this to small values (100bytes) still does NOT help detecting feof()
      */
     stream_set_chunk_size($this->sock, 1024);
 }
Beispiel #7
0
 /**
  * @group feof
  * @group filesystemfunc
  */
 function testFeofReadWithoutStreamChunking()
 {
     $fullFile = "{$this->basePath}/test";
     $this->put('/test', 'abcd');
     $h = fopen($fullFile, "r");
     // See stream_chunk_ensure_quirk
     stream_set_chunk_size($h, 1);
     $this->assertFalse(feof($h));
     fread($h, 2);
     $this->assertFalse(feof($h));
     fread($h, 2);
     $this->assertFalse(feof($h));
     fread($h, 1);
     $this->assertTrue(feof($h));
     fseek($h, 2);
     $this->assertFalse(feof($h));
 }
Beispiel #8
0
 public function init()
 {
     parent::init();
     $timeout_f = (double) $this->timeout_ms / 1000;
     $this->sock = @stream_socket_client("{$this->host}:{$this->port}", $errno, $errstr, $timeout_f);
     if (!$this->sock) {
         throw new Exception("{$errno}: {$errstr}");
     }
     $timeout_sec = intval($this->timeout_ms / 1000);
     $timeout_usec = ($this->timeout_ms - $timeout_sec * 1000) * 1000;
     @stream_set_timeout($this->sock, $timeout_sec, $timeout_usec);
     if (function_exists('stream_set_chunk_size')) {
         @stream_set_chunk_size($this->sock, 1024 * 1024);
     }
     if (true === $this->easy) {
         $this->easy();
     }
 }
Beispiel #9
0
 /**
  * A little bit messy but mainy to give useful errors.  It's probably going to be the most common thing people hit.
  *
  * AbstractRegister constructor.
  * @param BoardInterface $board
  * @throws InternalFailureException
  */
 public function __construct(BoardInterface $board)
 {
     //If there's a direct mapping file, try to use it.
     //Kept this generic in case we eventually get a /dev/spimem, /dev/pwmmem etc
     $dm_file = static::getDirectMemoryFile();
     if ($dm_file !== null && file_exists($dm_file)) {
         $this->mmap = @mmap_open($dm_file, self::MMAP_BLOCK_SIZE, static::getOffset());
         if ($this->mmap === false) {
             $reg_reflect = new \ReflectionClass($this);
             throw new InternalFailureException(sprintf('Couldn\'t map %s register.  You must either run as root, or be a member of the %s group.', $reg_reflect->getShortName(), posix_getgrgid(filegroup($dm_file))['name']));
         }
     } else {
         $this->mmap = @mmap_open('/dev/mem', self::MMAP_BLOCK_SIZE, $board->getPeripheralBaseAddress() + static::getOffset());
         if ($this->mmap === false) {
             $reg_reflect = new \ReflectionClass($this);
             throw new InternalFailureException(sprintf('Couldn\'t map %s register. Are you running as root?', $reg_reflect->getShortName()));
         }
     }
     //Only read 4 bytes at a time, not PHP's 8k default
     stream_set_chunk_size($this->mmap, 4);
     //Should there be a 'register backup' in here that gets replayed on destruct?
 }
Beispiel #10
0
 /**
  * @param resource $socket
  * @param bool $autoClose True to close the resource on destruct, false to leave it open.
  */
 public function __construct($socket, bool $autoClose = true)
 {
     parent::__construct($socket, $autoClose);
     stream_set_read_buffer($socket, 0);
     stream_set_write_buffer($socket, 0);
     stream_set_chunk_size($socket, self::MAX_PACKET_SIZE);
     $this->readQueue = new \SplQueue();
     $this->writeQueue = new \SplQueue();
     $this->poll = $this->createPoll($socket, $this->readQueue);
     $this->await = $this->createAwait($socket, $this->writeQueue);
     $this->onReceiveCancelled = function () {
         $this->poll->cancel();
         $this->readQueue->shift();
     };
     $this->onSendCancelled = function (\Exception $exception) {
         $this->free($exception);
     };
     try {
         list($this->address, $this->port) = Socket\getName($socket, false);
     } catch (FailureException $exception) {
         $this->close();
     }
 }
Beispiel #11
0
 /**
  * Get random bytes
  *
  * @param	int	$length	Output length
  * @return	string
  */
 public function get_random_bytes($length)
 {
     if (empty($length) or !ctype_digit((string) $length)) {
         return FALSE;
     }
     // Unfortunately, none of the following PRNGs is guaranteed to exist ...
     if (defined('MCRYPT_DEV_URANDOM') && ($output = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM)) !== FALSE) {
         return $output;
     }
     if (is_readable('/dev/urandom') && ($fp = fopen('/dev/urandom', 'rb')) !== FALSE) {
         // Try not to waste entropy ...
         is_php('5.4') && stream_set_chunk_size($fp, $length);
         $output = fread($fp, $length);
         fclose($fp);
         if ($output !== FALSE) {
             return $output;
         }
     }
     if (function_exists('openssl_random_pseudo_bytes')) {
         return openssl_random_pseudo_bytes($length);
     }
     return FALSE;
 }
Beispiel #12
0
 /**
  * Generates specified number of random bytes.
  * Note that output may not be ASCII.
  * @see generateRandomString() if you need a string.
  *
  * @param int $length the number of bytes to generate
  * @return string the generated random bytes
  * @throws InvalidParamException if wrong length is specified
  * @throws Exception on failure.
  */
 public function generateRandomKey($length = 32)
 {
     if (!is_int($length)) {
         throw new InvalidParamException('First parameter ($length) must be an integer');
     }
     if ($length < 1) {
         throw new InvalidParamException('First parameter ($length) must be greater than 0');
     }
     // always use random_bytes() if it is available
     if (function_exists('random_bytes')) {
         return random_bytes($length);
     }
     // The recent LibreSSL RNGs are faster and likely better than /dev/urandom.
     // Parse OPENSSL_VERSION_TEXT because OPENSSL_VERSION_NUMBER is no use for LibreSSL.
     // https://bugs.php.net/bug.php?id=71143
     if ($this->_useLibreSSL === null) {
         $this->_useLibreSSL = defined('OPENSSL_VERSION_TEXT') && preg_match('{^LibreSSL (\\d\\d?)\\.(\\d\\d?)\\.(\\d\\d?)$}', OPENSSL_VERSION_TEXT, $matches) && 10000 * $matches[1] + 100 * $matches[2] + $matches[3] >= 20105;
     }
     // Since 5.4.0, openssl_random_pseudo_bytes() reads from CryptGenRandom on Windows instead
     // of using OpenSSL library. LibreSSL is OK everywhere but don't use OpenSSL on non-Windows.
     if ($this->_useLibreSSL || DIRECTORY_SEPARATOR !== '/' && substr_compare(PHP_OS, 'win', 0, 3, true) === 0 && function_exists('openssl_random_pseudo_bytes')) {
         $key = openssl_random_pseudo_bytes($length, $cryptoStrong);
         if ($cryptoStrong === false) {
             throw new Exception('openssl_random_pseudo_bytes() set $crypto_strong false. Your PHP setup is insecure.');
         }
         if ($key !== false && StringHelper::byteLength($key) === $length) {
             return $key;
         }
     }
     // mcrypt_create_iv() does not use libmcrypt. Since PHP 5.3.7 it directly reads
     // CryptGenRandom on Windows. Elsewhere it directly reads /dev/urandom.
     if (function_exists('mcrypt_create_iv')) {
         $key = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
         if (StringHelper::byteLength($key) === $length) {
             return $key;
         }
     }
     // If not on Windows, try to open a random device.
     if ($this->_randomFile === null && DIRECTORY_SEPARATOR === '/') {
         // urandom is a symlink to random on FreeBSD.
         $device = PHP_OS === 'FreeBSD' ? '/dev/random' : '/dev/urandom';
         // Check random device for special character device protection mode. Use lstat()
         // instead of stat() in case an attacker arranges a symlink to a fake device.
         $lstat = @lstat($device);
         if ($lstat !== false && ($lstat['mode'] & 0170000) === 020000) {
             $this->_randomFile = fopen($device, 'rb') ?: null;
             if (is_resource($this->_randomFile)) {
                 // Reduce PHP stream buffer from default 8192 bytes to optimize data
                 // transfer from the random device for smaller values of $length.
                 // This also helps to keep future randoms out of user memory space.
                 $bufferSize = 8;
                 if (function_exists('stream_set_read_buffer')) {
                     stream_set_read_buffer($this->_randomFile, $bufferSize);
                 }
                 // stream_set_read_buffer() isn't implemented on HHVM
                 if (function_exists('stream_set_chunk_size')) {
                     stream_set_chunk_size($this->_randomFile, $bufferSize);
                 }
             }
         }
     }
     if (is_resource($this->_randomFile)) {
         $buffer = '';
         $stillNeed = $length;
         while ($stillNeed > 0) {
             $someBytes = fread($this->_randomFile, $stillNeed);
             if ($someBytes === false) {
                 break;
             }
             $buffer .= $someBytes;
             $stillNeed -= StringHelper::byteLength($someBytes);
             if ($stillNeed === 0) {
                 // Leaving file pointer open in order to make next generation faster by reusing it.
                 return $buffer;
             }
         }
         fclose($this->_randomFile);
         $this->_randomFile = null;
     }
     throw new Exception('Unable to generate a random key');
 }
/**
 * Unless open_basedir is enabled, use /dev/urandom for
 * random numbers in accordance with best practices
 * 
 * Why we use /dev/urandom and not /dev/random
 * @ref http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers
 * 
 * @param int $bytes
 * 
 * @throws Exception
 * 
 * @return string
 */
function random_bytes($bytes)
{
    static $fp = null;
    /**
     * This block should only be run once
     */
    if (empty($fp)) {
        /**
         * We use /dev/urandom if it is a char device.
         * We never fall back to /dev/random
         */
        $fp = fopen('/dev/urandom', 'rb');
        if (!empty($fp)) {
            $st = fstat($fp);
            if (($st['mode'] & 0170000) !== 020000) {
                fclose($fp);
                $fp = false;
            }
        }
        if (!empty($fp)) {
            /**
             * stream_set_read_buffer() does not exist in HHVM
             * 
             * If we don't set the stream's read buffer to 0, PHP will
             * internally buffer 8192 bytes, which can waste entropy
             * 
             * stream_set_read_buffer returns 0 on success
             */
            if (function_exists('stream_set_read_buffer')) {
                stream_set_read_buffer($fp, RANDOM_COMPAT_READ_BUFFER);
            }
            if (function_exists('stream_set_chunk_size')) {
                stream_set_chunk_size($fp, RANDOM_COMPAT_READ_BUFFER);
            }
        }
    }
    try {
        $bytes = RandomCompat_intval($bytes);
    } catch (TypeError $ex) {
        throw new TypeError('random_bytes(): $bytes must be an integer');
    }
    if ($bytes < 1) {
        throw new Error('Length must be greater than 0');
    }
    /**
     * This if() block only runs if we managed to open a file handle
     * 
     * It does not belong in an else {} block, because the above 
     * if (empty($fp)) line is logic that should only be run once per
     * page load.
     */
    if (!empty($fp)) {
        $remaining = $bytes;
        $buf = '';
        /**
         * We use fread() in a loop to protect against partial reads
         */
        do {
            $read = fread($fp, $remaining);
            if ($read === false) {
                /**
                 * We cannot safely read from the file. Exit the
                 * do-while loop and trigger the exception condition
                 */
                $buf = false;
                break;
            }
            /**
             * Decrease the number of bytes returned from remaining
             */
            $remaining -= RandomCompat_strlen($read);
            $buf .= $read;
        } while ($remaining > 0);
        /**
         * Is our result valid?
         */
        if ($buf !== false) {
            if (RandomCompat_strlen($buf) === $bytes) {
                /**
                 * Return our random entropy buffer here:
                 */
                return $buf;
            }
        }
    }
    /**
     * If we reach here, PHP has failed us.
     */
    throw new Exception('Error reading from source device');
}
Beispiel #14
0
 /**
  * Opens an internal GPG subprocess for the current operation
  *
  * Opens a GPG subprocess, then connects the subprocess to some pipes. Sets
  * the private class property {@link Crypt_GPG_Engine::$_process} to
  * the new subprocess.
  *
  * @return void
  *
  * @throws Crypt_GPG_OpenSubprocessException if the subprocess could not be
  *         opened.
  *
  * @see Crypt_GPG_Engine::setOperation()
  * @see Crypt_GPG_Engine::_closeSubprocess()
  * @see Crypt_GPG_Engine::$_process
  */
 private function _openSubprocess()
 {
     $version = $this->getVersion();
     // log versions, but not when looking for the version number
     if ($version !== '1.0.0') {
         $this->_debug('USING GPG ' . $version . ' with PHP ' . PHP_VERSION);
     }
     // Binary operations will not work on Windows with PHP < 5.2.6. This is
     // in case stream_select() ever works on Windows.
     $rb = version_compare(PHP_VERSION, '5.2.6') < 0 ? 'r' : 'rb';
     $wb = version_compare(PHP_VERSION, '5.2.6') < 0 ? 'w' : 'wb';
     $env = $_ENV;
     // Newer versions of GnuPG return localized results. Crypt_GPG only
     // works with English, so set the locale to 'C' for the subprocess.
     $env['LC_ALL'] = 'C';
     // If using GnuPG 2.x < 2.1.13 start the gpg-agent
     if (version_compare($version, '2.0.0', 'ge') && version_compare($version, '2.1.13', 'lt')) {
         if (!$this->_agent) {
             throw new Crypt_GPG_OpenSubprocessException('Unable to open gpg-agent subprocess (gpg-agent not found). ' . 'Please specify location of the gpg-agent binary ' . 'using the \'agent\' driver option.');
         }
         $agentArguments = array('--daemon', '--options /dev/null', '--csh', '--keep-display', '--no-grab', '--ignore-cache-for-signing', '--pinentry-touch-file /dev/null', '--disable-scdaemon', '--no-use-standard-socket', '--pinentry-program ' . escapeshellarg($this->_getPinEntry()));
         if ($this->_homedir) {
             $agentArguments[] = '--homedir ' . escapeshellarg($this->_homedir);
         }
         if ($version21 = version_compare($version, '2.1.0', 'ge')) {
             // This is needed to get socket file location in stderr output
             // Note: This does not help when the agent already is running
             $agentArguments[] = '--verbose';
         }
         $agentCommandLine = $this->_agent . ' ' . implode(' ', $agentArguments);
         $agentDescriptorSpec = array(self::FD_INPUT => array('pipe', $rb), self::FD_OUTPUT => array('pipe', $wb), self::FD_ERROR => array('pipe', $wb));
         $this->_debug('OPENING GPG-AGENT SUBPROCESS WITH THE FOLLOWING COMMAND:');
         $this->_debug($agentCommandLine);
         $this->_agentProcess = proc_open($agentCommandLine, $agentDescriptorSpec, $this->_agentPipes, null, $env, array('binary_pipes' => true));
         if (!is_resource($this->_agentProcess)) {
             throw new Crypt_GPG_OpenSubprocessException('Unable to open gpg-agent subprocess.', 0, $agentCommandLine);
         }
         // Get GPG_AGENT_INFO and set environment variable for gpg process.
         // This is a blocking read, but is only 1 line.
         $agentInfo = fread($this->_agentPipes[self::FD_OUTPUT], self::CHUNK_SIZE);
         // For GnuPG 2.1 we need to read both stderr and stdout
         if ($version21) {
             $agentInfo .= "\n" . fread($this->_agentPipes[self::FD_ERROR], self::CHUNK_SIZE);
         }
         if ($agentInfo) {
             foreach (explode("\n", $agentInfo) as $line) {
                 if ($version21) {
                     if (preg_match('/listening on socket \'([^\']+)/', $line, $m)) {
                         $this->_agentInfo = $m[1];
                     } else {
                         if (preg_match('/gpg-agent\\[([0-9]+)\\].* started/', $line, $m)) {
                             $this->_agentInfo .= ':' . $m[1] . ':1';
                         }
                     }
                 } else {
                     if (preg_match('/GPG_AGENT_INFO=([^;]+)/', $line, $m)) {
                         $this->_agentInfo = $m[1];
                         break;
                     }
                 }
             }
         }
         $this->_debug('GPG-AGENT-INFO: ' . $this->_agentInfo);
         $env['GPG_AGENT_INFO'] = $this->_agentInfo;
         // gpg-agent daemon is started, we can close the launching process
         $this->_closeAgentLaunchProcess();
         // Terminate processes if something went wrong
         register_shutdown_function(array($this, '__destruct'));
     }
     // "Register" GPGConf existence for _closeIdleAgents()
     if (version_compare($version, '2.1.0', 'ge')) {
         if ($this->_gpgconf === null) {
             $this->_gpgconf = $this->_getGPGConf();
         }
     } else {
         $this->_gpgconf = false;
     }
     $commandLine = $this->_binary;
     $defaultArguments = array('--status-fd ' . escapeshellarg(self::FD_STATUS), '--command-fd ' . escapeshellarg(self::FD_COMMAND), '--no-secmem-warning', '--no-tty', '--no-default-keyring', '--no-options');
     if (version_compare($version, '1.0.7', 'ge')) {
         if (version_compare($version, '2.0.0', 'lt')) {
             $defaultArguments[] = '--no-use-agent';
         }
         $defaultArguments[] = '--no-permission-warning';
     }
     if (version_compare($version, '1.4.2', 'ge')) {
         $defaultArguments[] = '--exit-on-status-write-error';
     }
     if (version_compare($version, '1.3.2', 'ge')) {
         $defaultArguments[] = '--trust-model always';
     } else {
         $defaultArguments[] = '--always-trust';
     }
     // Since 2.1.13 we can use "loopback mode" instead of gpg-agent
     if (version_compare($version, '2.1.13', 'ge')) {
         $defaultArguments[] = '--pinentry-mode loopback';
     }
     $arguments = array_merge($defaultArguments, $this->_arguments);
     if ($this->_homedir) {
         $arguments[] = '--homedir ' . escapeshellarg($this->_homedir);
         // the random seed file makes subsequent actions faster so only
         // disable it if we have to.
         if (!is_writeable($this->_homedir)) {
             $arguments[] = '--no-random-seed-file';
         }
     }
     if ($this->_publicKeyring) {
         $arguments[] = '--keyring ' . escapeshellarg($this->_publicKeyring);
     }
     if ($this->_privateKeyring) {
         $arguments[] = '--secret-keyring ' . escapeshellarg($this->_privateKeyring);
     }
     if ($this->_trustDb) {
         $arguments[] = '--trustdb-name ' . escapeshellarg($this->_trustDb);
     }
     $commandLine .= ' ' . implode(' ', $arguments) . ' ' . $this->_operation;
     $descriptorSpec = array(self::FD_INPUT => array('pipe', $rb), self::FD_OUTPUT => array('pipe', $wb), self::FD_ERROR => array('pipe', $wb), self::FD_STATUS => array('pipe', $wb), self::FD_COMMAND => array('pipe', $rb), self::FD_MESSAGE => array('pipe', $rb));
     $this->_debug('OPENING GPG SUBPROCESS WITH THE FOLLOWING COMMAND:');
     $this->_debug($commandLine);
     $this->_process = proc_open($commandLine, $descriptorSpec, $this->_pipes, null, $env, array('binary_pipes' => true));
     if (!is_resource($this->_process)) {
         throw new Crypt_GPG_OpenSubprocessException('Unable to open GPG subprocess.', 0, $commandLine);
     }
     // Set streams as non-blocking. See Bug #18618.
     foreach ($this->_pipes as $pipe) {
         stream_set_blocking($pipe, 0);
         stream_set_write_buffer($pipe, self::CHUNK_SIZE);
         stream_set_chunk_size($pipe, self::CHUNK_SIZE);
         stream_set_read_buffer($pipe, self::CHUNK_SIZE);
     }
     $this->_openPipes = $this->_pipes;
 }
Beispiel #15
0
 /**
  * Get random bytes
  *
  * @ref https://github.com/paragonie/random_compat/
  *
  * @param  int $length Output length
  *
  * @return  string|false false on error
  */
 public static function get_random_bytes($length)
 {
     if (!$length || !ctype_digit((string) $length)) {
         return false;
     } else {
         $length = (int) $length;
     }
     if (function_exists('random_bytes') && self::is_php('7.0')) {
         /**
          * PHP 7 -> http://php.net/manual/de/function.random-bytes.php
          */
         try {
             $return = random_bytes($length);
         } catch (\Exception $e) {
             $return = false;
         }
         return $return;
     } else {
         /**
          * PHP 5.2.0 - 5.6.x way to implement random_bytes()
          *
          * // WARNING: Unfortunately, none of the following PRNGs is guaranteed to exist ...
          *
          * In order of preference:
          *   1. PHP-Module:   "mcrypt" via mcrypt_create_iv()
          *   2. Linux / BSD:  "/dev/urandom" via fread()
          *   3. Windows:      \COM('CAPICOM.Utilities.1')->GetRandom()
          *   4. PHP+OpenSSL:  openssl_random_pseudo_bytes()
          */
         /**
          * 1. PHP-Module
          */
         if (extension_loaded('mcrypt') && defined(MCRYPT_DEV_URANDOM) === true) {
             $output = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
             if ($output !== false && UTF8::strlen($output, '8bit') === $length) {
                 return $output;
             }
         }
         /**
          * 2. Linux / BSD
          */
         if (!ini_get('open_basedir') && is_readable('/dev/urandom')) {
             $fp = fopen('/dev/urandom', 'rb');
             if (!empty($fp)) {
                 $st = fstat($fp);
                 // In C, this would be: (stat_mode & S_IFMT) !== S_IFCHR
                 if (($st['mode'] & 0170000) !== 020000) {
                     fclose($fp);
                     $fp = false;
                 }
                 unset($st);
             }
         }
         if (isset($fp) && $fp !== false) {
             /**
              * stream_set_read_buffer() / stream_set_chunk_size does not exist in HHVM
              *
              * If we don't set the stream's read buffer to 0, PHP will
              * internally buffer 8192 bytes, which can waste entropy
              *
              * stream_set_read_buffer returns 0 on success
              */
             if (function_exists('stream_set_chunk_size')) {
                 stream_set_chunk_size($fp, $length);
             }
             if (function_exists('stream_set_read_buffer')) {
                 stream_set_read_buffer($fp, $length);
             }
             $remaining = $length;
             $buf = '';
             do {
                 $read = fread($fp, $remaining);
                 // We cannot safely read from the file, so exit the do-while loop.
                 if ($read === false) {
                     $buf = false;
                     break;
                 }
                 // Decrease the number of bytes returned from remaining.
                 $remaining -= UTF8::strlen($read, '8bit');
                 $buf .= $read;
             } while ($remaining > 0);
             fclose($fp);
             if ($buf !== false) {
                 if (UTF8::strlen($buf, '8bit') === $length) {
                     return $buf;
                 }
             }
         }
         /*
          * 3. Windows
          *
          * PHP can be used to access COM objects on Windows platforms
          *
          * ---
          *
          * PROBLEM: you see this error-message:
          *    com_exception thrown with message
          *      "Failed to create COM object `CAPICOM.Utilities.1': Ungültige Syntax
          *
          * SOLUTION: register the dll:
          *    regsvr32 c:\windows\capicom.dll
          *
          * ---
          *
          * @ref http://php.net/manual/en/ref.com.php
          */
         if (extension_loaded('com_dotnet') && class_exists('COM') === true) {
             // init
             $buf = '';
             /** @noinspection PhpUndefinedClassInspection */
             $util = new \COM('CAPICOM.Utilities.1');
             /**
              * Let's not let it loop forever. If we run N times and fail to
              * get N bytes of random data, then CAPICOM has failed us.
              */
             $execCount = 0;
             do {
                 /** @noinspection PhpUndefinedMethodInspection */
                 $buf .= base64_decode($util->GetRandom($length, 0));
                 if (UTF8::strlen($buf, '8bit') >= $length) {
                     return UTF8::substr($buf, 0, $length);
                 }
                 ++$execCount;
             } while ($execCount < $length);
         }
         /**
          * 4. PHP + OpenSSL
          *
          * fallback to "openssl_random_pseudo_bytes()"
          */
         if (function_exists('openssl_random_pseudo_bytes')) {
             $output = openssl_random_pseudo_bytes($length, $strong);
             if ($output !== false && $strong === true) {
                 if (UTF8::strlen($output, '8bit') === $length) {
                     return $output;
                 }
             }
         }
         return false;
     }
 }
Beispiel #16
0
 public function fopen($path, $mode)
 {
     $fh = fopen($this->constructUrl($path), $mode);
     if ($fh) {
         // override the default 8k php stream chunk
         // size for non-file streams.
         stream_set_chunk_size($fh, 1024 * 1024 * 10);
     }
     return $fh;
 }
Beispiel #17
0
 /**
  * Change stream options.
  *
  * @codeCoverageIgnore
  *
  * @param  int $option One of STREAM_OPTION_BLOCKING, STREAM_OPTION_READ_TIMEOUT, STREAM_OPTION_WRITE_BUFFER.
  * @param  int $arg1   Depending on option.
  * @param  int $arg2   Depending on option.
  *
  * @return boolean Returns TRUE on success or FALSE on failure. If option is not implemented,
  *                 FALSE should be returned.
  */
 public function stream_set_option($option, $arg1, $arg2)
 {
     switch ($option) {
         case STREAM_OPTION_BLOCKING:
             return stream_set_blocking($this->resource, $arg1);
         case STREAM_OPTION_READ_TIMEOUT:
             return stream_set_timeout($this->resource, $arg1, $arg2);
         case STREAM_OPTION_WRITE_BUFFER:
             return stream_set_write_buffer($this->resource, $arg1);
         case STREAM_OPTION_READ_BUFFER:
             return stream_set_read_buffer($this->resource, $arg1);
         case STREAM_OPTION_CHUNK_SIZE:
             return stream_set_chunk_size($this->resource, $arg1);
     }
 }
Beispiel #18
0
 /**
  * password_hash()
  *
  * @link	http://php.net/password_hash
  * @param	string	$password
  * @param	int	$algo
  * @param	array	$options
  * @return	mixed
  */
 function password_hash($password, $algo, array $options = array())
 {
     static $func_override;
     isset($func_override) or $func_override = extension_loaded('mbstring') && ini_get('mbstring.func_override');
     if ($algo !== 1) {
         trigger_error('password_hash(): Unknown hashing algorithm: ' . (int) $algo, E_USER_WARNING);
         return NULL;
     }
     if (isset($options['cost']) && ($options['cost'] < 4 or $options['cost'] > 31)) {
         trigger_error('password_hash(): Invalid bcrypt cost parameter specified: ' . (int) $options['cost'], E_USER_WARNING);
         return NULL;
     }
     if (isset($options['salt']) && ($saltlen = $func_override ? mb_strlen($options['salt'], '8bit') : strlen($options['salt'])) < 22) {
         trigger_error('password_hash(): Provided salt is too short: ' . $saltlen . ' expecting 22', E_USER_WARNING);
         return NULL;
     } elseif (!isset($options['salt'])) {
         if (defined('MCRYPT_DEV_URANDOM')) {
             $options['salt'] = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);
         } elseif (function_exists('openssl_random_pseudo_bytes')) {
             $options['salt'] = openssl_random_pseudo_bytes(16);
         } elseif (DIRECTORY_SEPARATOR === '/' && (is_readable($dev = '/dev/arandom') or is_readable($dev = '/dev/urandom'))) {
             if (($fp = fopen($dev, 'rb')) === FALSE) {
                 log_message('error', 'compat/password: Unable to open ' . $dev . ' for reading.');
                 return FALSE;
             }
             // Try not to waste entropy ...
             is_php('5.4') && stream_set_chunk_size($fp, 16);
             $options['salt'] = '';
             for ($read = 0; $read < 16; $read = $func_override ? mb_strlen($options['salt'], '8bit') : strlen($options['salt'])) {
                 if (($read = fread($fp, 16 - $read)) === FALSE) {
                     log_message('error', 'compat/password: Error while reading from ' . $dev . '.');
                     return FALSE;
                 }
                 $options['salt'] .= $read;
             }
             fclose($fp);
         } else {
             log_message('error', 'compat/password: No CSPRNG available.');
             return FALSE;
         }
         $options['salt'] = str_replace('+', '.', rtrim(base64_encode($options['salt']), '='));
     } elseif (!preg_match('#^[a-zA-Z0-9./]+$#D', $options['salt'])) {
         $options['salt'] = str_replace('+', '.', rtrim(base64_encode($options['salt']), '='));
     }
     isset($options['cost']) or $options['cost'] = 10;
     return strlen($password = crypt($password, sprintf('$2y$%02d$%s', $options['cost'], $options['salt']))) === 60 ? $password : FALSE;
 }
Beispiel #19
0
 /**
  * getRandomBytes()
  *
  * Reads the specified amount of data from the system's PRNG.
  *
  * @param	int	$length	Desired output length
  * @return	string	A pseudo-random stream of bytes
  */
 public static function getRandomBytes($length, $rawOutput = false)
 {
     if (!is_int($length) or $length < 1) {
         throw new \InvalidArgumentException('Length must be an integer larger than 0.');
     }
     // @codeCoverageIgnoreStart
     if (\function_exists('openssl_random_pseudo_bytes')) {
         $cryptoStrong = null;
         if (($output = \openssl_random_pseudo_bytes($length, $cryptoStrong)) !== false && $cryptoStrong) {
             return $rawOutput ? $output : \bin2hex($output);
         }
     }
     if (\defined('MCRYPT_DEV_URANDOM')) {
         if (($output = \mcrypt_create_iv($length, MCRYPT_DEV_URANDOM)) !== false) {
             return $rawOutput ? $output : \bin2hex($output);
         }
     }
     if (\is_readable('/dev/urandom') && ($fp = \fopen('/dev/urandom', 'rb')) !== false) {
         \stream_set_chunk_size($fp, $length);
         $output = \fread($fp, $length);
         \fclose($fp);
         if ($output !== false) {
             return $rawOutput ? $output : \bin2hex($output);
         }
     }
     throw new \RuntimeException('No reliable PRNG source is available on the system.');
     // @codeCoverageIgnoreEnd
 }
Beispiel #20
0
}
if ($cli->getParam('in')) {
    $in = $cli->getParam('in');
} else {
    die("You must specify an input file\n");
}
if ($cli->getParam('out')) {
    $out = $cli->getParam('out');
} else {
    die("You must specify an output file\n");
}
$timeStart = microtime(true);
if (file_exists($in)) {
    $flvIn = fopen($in, "rb");
    if (function_exists("stream_set_chunk_size")) {
        stream_set_chunk_size($flvIn, 8 * 1024 * 1024);
    }
    $flvTag = fread($flvIn, $flvHeaderLen);
    if (strncmp($flvTag, "FLV", 3) != 0) {
        die("Input file is not a valid FLV file\n");
    }
    $fileLen = filesize($in);
    $filePos = $flvHeaderLen;
    $fileSize = $fileLen / (1024 * 1024);
    $pFilePos = 0;
} else {
    die("Input file doesn't exist\n");
}
$flvOut = fopen($out, "w+b");
if (!$flvOut) {
    die("Failed to create output file\n");
Beispiel #21
0
 /**
  * Alias for stream_set_chunk_size
  * @param integer $chunkSize
  * @return integer
  */
 public function setChunkSize($chunkSize)
 {
     if ($this->isOpen()) {
         stream_set_chunk_size($this->pointer, $chunkSize);
     }
     return $chunkSize;
 }
Beispiel #22
0
 /**
  * Sets the size of a stream's buffer.
  * 
  * @param int $size      The desired size of the buffer, in bytes.
  * @param int $direction The buffer of which direction to set. Valid
  *     values are the DIRECTION_* constants.
  * 
  * @return bool TRUE on success, FALSE on failure.
  */
 public function setBuffer($size, $direction = self::DIRECTION_ALL)
 {
     $result = parent::setBuffer($size, $direction);
     if (self::DIRECTION_SEND === $direction && function_exists('stream_set_chunk_size') && !$result) {
         return false !== @stream_set_chunk_size($this->stream, $size);
     }
     return $result;
 }
Beispiel #23
0
<?php

$fd = fopen(__DIR__ . '/stream_set_chunk_size.php.sample', 'rb');
var_dump(stream_set_chunk_size($fd, 8192));
var_dump(stream_set_chunk_size($fd, 256));
var_dump(stream_set_chunk_size($fd, 0));
fclose($fd);
Beispiel #24
0
 /**
  * Get random bytes
  *
  * @param	int	$length	Output length
  * @return	string
  */
 public function get_random_bytes($length)
 {
     if (empty($length) or !ctype_digit((string) $length)) {
         return FALSE;
     }
     if (function_exists('random_bytes')) {
         try {
             // The cast is required to avoid TypeError
             return random_bytes((int) $length);
         } catch (Exception $e) {
             // If random_bytes() can't do the job, we can't either ...
             // There's no point in using fallbacks.
             log_message('error', $e->getMessage());
             return FALSE;
         }
     }
     // Unfortunately, none of the following PRNGs is guaranteed to exist ...
     if (defined('MCRYPT_DEV_URANDOM') && ($output = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM)) !== FALSE) {
         return $output;
     }
     if (is_readable('/dev/urandom') && ($fp = fopen('/dev/urandom', 'rb')) !== FALSE) {
         // Try not to waste entropy ...
         stream_set_chunk_size($fp, $length);
         $output = fread($fp, $length);
         fclose($fp);
         if ($output !== FALSE) {
             return $output;
         }
     }
     if (function_exists('openssl_random_pseudo_bytes')) {
         return openssl_random_pseudo_bytes($length);
     }
     return FALSE;
 }
Beispiel #25
0
/**
 * StreamWrapper::stream_fread is usually called with a minimum buffer size of 8192
 * regardless of what value is passed to fread(). It will then keep reading until
 * the value passed to fread() is satisfied or EOF is reached.
 *
 * This can be overridden by calling stream_set_chunk_size($size), which has a
 * bizarre and undocumented quirk:
 *
 * // Pass $len from fread($h, $len) to StreamWrapper::stream_read($len)
 * stream_set_chunk_size($h, 1);
 *
 * // Pass stream chunk size to StreamWrapper::stream_read($len)
 * stream_set_chunk_size($h, 2);
 *
 * This function just tests that my assumptions about this behaviour remain correct.
 */
function stream_chunk_ensure_quirk()
{
    stream_wrapper_register('streamchunkquirk', 'Defile\\Test\\BufferTestingStream');
    $h = fopen('streamchunkquirk://yep', 'r');
    fread($h, 1);
    fclose($h);
    if (\Defile\Test\BufferTestingStream::$bufferSize != 8192) {
        throw new \UnexpectedValueException();
    }
    $h = fopen('streamchunkquirk://yep', 'r');
    stream_set_chunk_size($h, 1);
    fread($h, 999);
    fclose($h);
    if (\Defile\Test\BufferTestingStream::$bufferSize != 999) {
        throw new \UnexpectedValueException();
    }
    $h = fopen('streamchunkquirk://yep', 'r');
    stream_set_chunk_size($h, 2);
    fread($h, 999);
    fclose($h);
    if (\Defile\Test\BufferTestingStream::$bufferSize != 2) {
        throw new \UnexpectedValueException(\Defile\Test\BufferTestingStream::$bufferSize);
    }
    stream_wrapper_unregister('streamchunkquirk');
}
Beispiel #26
0
    {
        echo "option: ", $option, ", ", $arg1, ", ", $arg2, "\n";
        return false;
    }
}
var_dump(stream_wrapper_register('test', 'test_wrapper'));
$f = fopen("test://foo", "r");
/* when the chunk size is 1, the read buffer is skipped, but the
 * the writes are made in chunks of size 1 (business as usual)
 * This should probably be revisited */
echo "should return previous chunk size (8192)\n";
var_dump(stream_set_chunk_size($f, 1));
echo "should be read without buffer (\$count == 10000)\n";
var_dump(strlen(fread($f, 10000)));
echo "should elicit 3 writes of size 1 and return 3\n";
var_dump(fwrite($f, str_repeat('b', 3)));
echo "should return previous chunk size (1)\n";
var_dump(stream_set_chunk_size($f, 100));
echo "should elicit one read of size 100 (chunk size)\n";
var_dump(strlen(fread($f, 250)));
echo "should elicit one read of size 100 (chunk size)\n";
var_dump(strlen(fread($f, 50)));
echo "should elicit no read because there is sufficient cached data\n";
var_dump(strlen(fread($f, 50)));
echo "should elicit 2 writes of size 100 and one of size 50\n";
var_dump(strlen(fwrite($f, str_repeat('b', 250))));
echo "\nerror conditions\n";
var_dump(stream_set_chunk_size($f, 0));
var_dump(stream_set_chunk_size($f, -1));
var_dump(stream_set_chunk_size($f, array()));
Beispiel #27
0
 /**
  * Set the stream chunk size
  *
  * @param resource $fp
  * @param int      $chunkSize
  *
  * @return int
  */
 public function setChunkSize($fp, int $chunkSize) : int
 {
     return stream_set_chunk_size($fp, $chunkSize);
 }