[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

title

Body

[close]

/wp-includes/random_compat/ -> random_bytes_dev_urandom.php (source)

   1  <?php
   2  /**
   3   * Random_* Compatibility Library 
   4   * for using the new PHP 7 random_* API in PHP 5 projects
   5   * 
   6   * The MIT License (MIT)
   7   *
   8   * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises
   9   * 
  10   * Permission is hereby granted, free of charge, to any person obtaining a copy
  11   * of this software and associated documentation files (the "Software"), to deal
  12   * in the Software without restriction, including without limitation the rights
  13   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  14   * copies of the Software, and to permit persons to whom the Software is
  15   * furnished to do so, subject to the following conditions:
  16   * 
  17   * The above copyright notice and this permission notice shall be included in
  18   * all copies or substantial portions of the Software.
  19   * 
  20   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  23   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  26   * SOFTWARE.
  27   */
  28  
  29  if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
  30      define('RANDOM_COMPAT_READ_BUFFER', 8);
  31  }
  32  
  33  if (!is_callable('random_bytes')) {
  34      /**
  35       * Unless open_basedir is enabled, use /dev/urandom for
  36       * random numbers in accordance with best practices
  37       *
  38       * Why we use /dev/urandom and not /dev/random
  39       * @ref http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers
  40       *
  41       * @param int $bytes
  42       *
  43       * @throws Exception
  44       *
  45       * @return string
  46       */
  47      function random_bytes($bytes)
  48      {
  49          static $fp = null;
  50          /**
  51           * This block should only be run once
  52           */
  53          if (empty($fp)) {
  54              /**
  55               * We use /dev/urandom if it is a char device.
  56               * We never fall back to /dev/random
  57               */
  58              $fp = fopen('/dev/urandom', 'rb');
  59              if (!empty($fp)) {
  60                  $st = fstat($fp);
  61                  if (($st['mode'] & 0170000) !== 020000) {
  62                      fclose($fp);
  63                      $fp = false;
  64                  }
  65              }
  66  
  67              if (!empty($fp)) {
  68                  /**
  69                   * stream_set_read_buffer() does not exist in HHVM
  70                   *
  71                   * If we don't set the stream's read buffer to 0, PHP will
  72                   * internally buffer 8192 bytes, which can waste entropy
  73                   *
  74                   * stream_set_read_buffer returns 0 on success
  75                   */
  76                  if (is_callable('stream_set_read_buffer')) {
  77                      stream_set_read_buffer($fp, RANDOM_COMPAT_READ_BUFFER);
  78                  }
  79                  if (is_callable('stream_set_chunk_size')) {
  80                      stream_set_chunk_size($fp, RANDOM_COMPAT_READ_BUFFER);
  81                  }
  82              }
  83          }
  84  
  85          try {
  86              $bytes = RandomCompat_intval($bytes);
  87          } catch (TypeError $ex) {
  88              throw new TypeError(
  89                  'random_bytes(): $bytes must be an integer'
  90              );
  91          }
  92  
  93          if ($bytes < 1) {
  94              throw new Error(
  95                  'Length must be greater than 0'
  96              );
  97          }
  98  
  99          /**
 100           * This if() block only runs if we managed to open a file handle
 101           *
 102           * It does not belong in an else {} block, because the above
 103           * if (empty($fp)) line is logic that should only be run once per
 104           * page load.
 105           */
 106          if (!empty($fp)) {
 107              /**
 108               * @var int
 109               */
 110              $remaining = $bytes;
 111  
 112              /**
 113               * @var string|bool
 114               */
 115              $buf = '';
 116  
 117              /**
 118               * We use fread() in a loop to protect against partial reads
 119               */
 120              do {
 121                  /**
 122                   * @var string|bool
 123                   */
 124                  $read = fread($fp, $remaining);
 125                  if (!is_string($read)) {
 126                      if ($read === false) {
 127                          /**
 128                           * We cannot safely read from the file. Exit the
 129                           * do-while loop and trigger the exception condition
 130                           *
 131                           * @var string|bool
 132                           */
 133                          $buf = false;
 134                          break;
 135                      }
 136                  }
 137                  /**
 138                   * Decrease the number of bytes returned from remaining
 139                   */
 140                  $remaining -= RandomCompat_strlen($read);
 141                  /**
 142                   * @var string|bool
 143                   */
 144                  $buf = $buf . $read;
 145              } while ($remaining > 0);
 146  
 147              /**
 148               * Is our result valid?
 149               */
 150              if (is_string($buf)) {
 151                  if (RandomCompat_strlen($buf) === $bytes) {
 152                      /**
 153                       * Return our random entropy buffer here:
 154                       */
 155                      return $buf;
 156                  }
 157              }
 158          }
 159  
 160          /**
 161           * If we reach here, PHP has failed us.
 162           */
 163          throw new Exception(
 164              'Error reading from source device'
 165          );
 166      }
 167  }


Generated: Sat Nov 23 20:47:33 2019 Cross-referenced by PHPXref 0.7