Changeset 42130 for trunk/src/wp-includes/random_compat/random.php
- Timestamp:
- 11/08/2017 11:47:04 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/random_compat/random.php
r36886 r42130 4 4 * for using the new PHP 7 random_* API in PHP 5 projects 5 5 * 6 * @version 1.2.17 * @released 201 6-02-296 * @version 2.0.10 7 * @released 2017-03-13 8 8 * 9 9 * The MIT License (MIT) 10 10 * 11 * Copyright (c) 2015 Paragon Initiative Enterprises11 * Copyright (c) 2015 - 2017 Paragon Initiative Enterprises 12 12 * 13 13 * Permission is hereby granted, free of charge, to any person obtaining a copy … … 32 32 if (!defined('PHP_VERSION_ID')) { 33 33 // This constant was introduced in PHP 5.2.7 34 $RandomCompatversion = explode('.', PHP_VERSION);34 $RandomCompatversion = array_map('intval', explode('.', PHP_VERSION)); 35 35 define( 36 36 'PHP_VERSION_ID', … … 42 42 } 43 43 44 if (PHP_VERSION_ID < 70000) { 45 46 if (!defined('RANDOM_COMPAT_READ_BUFFER')) { 47 define('RANDOM_COMPAT_READ_BUFFER', 8); 48 } 49 50 $RandomCompatDIR = dirname(__FILE__); 51 52 require_once $RandomCompatDIR.'/byte_safe_strings.php'; 53 require_once $RandomCompatDIR.'/cast_to_int.php'; 54 require_once $RandomCompatDIR.'/error_polyfill.php'; 55 56 if (!function_exists('random_bytes')) { 44 /** 45 * PHP 7.0.0 and newer have these functions natively. 46 */ 47 if (PHP_VERSION_ID >= 70000) { 48 return; 49 } 50 51 if (!defined('RANDOM_COMPAT_READ_BUFFER')) { 52 define('RANDOM_COMPAT_READ_BUFFER', 8); 53 } 54 55 $RandomCompatDIR = dirname(__FILE__); 56 57 require_once $RandomCompatDIR . '/byte_safe_strings.php'; 58 require_once $RandomCompatDIR . '/cast_to_int.php'; 59 require_once $RandomCompatDIR . '/error_polyfill.php'; 60 61 if (!is_callable('random_bytes')) { 62 /** 63 * PHP 5.2.0 - 5.6.x way to implement random_bytes() 64 * 65 * We use conditional statements here to define the function in accordance 66 * to the operating environment. It's a micro-optimization. 67 * 68 * In order of preference: 69 * 1. Use libsodium if available. 70 * 2. fread() /dev/urandom if available (never on Windows) 71 * 3. mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM) 72 * 4. COM('CAPICOM.Utilities.1')->GetRandom() 73 * 74 * See RATIONALE.md for our reasoning behind this particular order 75 */ 76 if (extension_loaded('libsodium')) { 77 // See random_bytes_libsodium.php 78 if (PHP_VERSION_ID >= 50300 && is_callable('\\Sodium\\randombytes_buf')) { 79 require_once $RandomCompatDIR . '/random_bytes_libsodium.php'; 80 } elseif (method_exists('Sodium', 'randombytes_buf')) { 81 require_once $RandomCompatDIR . '/random_bytes_libsodium_legacy.php'; 82 } 83 } 84 85 /** 86 * Reading directly from /dev/urandom: 87 */ 88 if (DIRECTORY_SEPARATOR === '/') { 89 // DIRECTORY_SEPARATOR === '/' on Unix-like OSes -- this is a fast 90 // way to exclude Windows. 91 $RandomCompatUrandom = true; 92 $RandomCompat_basedir = ini_get('open_basedir'); 93 94 if (!empty($RandomCompat_basedir)) { 95 $RandomCompat_open_basedir = explode( 96 PATH_SEPARATOR, 97 strtolower($RandomCompat_basedir) 98 ); 99 $RandomCompatUrandom = (array() !== array_intersect( 100 array('/dev', '/dev/', '/dev/urandom'), 101 $RandomCompat_open_basedir 102 )); 103 $RandomCompat_open_basedir = null; 104 } 105 106 if ( 107 !is_callable('random_bytes') 108 && 109 $RandomCompatUrandom 110 && 111 @is_readable('/dev/urandom') 112 ) { 113 // Error suppression on is_readable() in case of an open_basedir 114 // or safe_mode failure. All we care about is whether or not we 115 // can read it at this point. If the PHP environment is going to 116 // panic over trying to see if the file can be read in the first 117 // place, that is not helpful to us here. 118 119 // See random_bytes_dev_urandom.php 120 require_once $RandomCompatDIR . '/random_bytes_dev_urandom.php'; 121 } 122 // Unset variables after use 123 $RandomCompat_basedir = null; 124 } else { 125 $RandomCompatUrandom = false; 126 } 127 128 /** 129 * mcrypt_create_iv() 130 * 131 * We only want to use mcypt_create_iv() if: 132 * 133 * - random_bytes() hasn't already been defined 134 * - the mcrypt extensions is loaded 135 * - One of these two conditions is true: 136 * - We're on Windows (DIRECTORY_SEPARATOR !== '/') 137 * - We're not on Windows and /dev/urandom is readabale 138 * (i.e. we're not in a chroot jail) 139 * - Special case: 140 * - If we're not on Windows, but the PHP version is between 141 * 5.6.10 and 5.6.12, we don't want to use mcrypt. It will 142 * hang indefinitely. This is bad. 143 * - If we're on Windows, we want to use PHP >= 5.3.7 or else 144 * we get insufficient entropy errors. 145 */ 146 if ( 147 !is_callable('random_bytes') 148 && 149 // Windows on PHP < 5.3.7 is broken, but non-Windows is not known to be. 150 (DIRECTORY_SEPARATOR === '/' || PHP_VERSION_ID >= 50307) 151 && 152 // Prevent this code from hanging indefinitely on non-Windows; 153 // see https://bugs.php.net/bug.php?id=69833 154 ( 155 DIRECTORY_SEPARATOR !== '/' || 156 (PHP_VERSION_ID <= 50609 || PHP_VERSION_ID >= 50613) 157 ) 158 && 159 extension_loaded('mcrypt') 160 ) { 161 // See random_bytes_mcrypt.php 162 require_once $RandomCompatDIR . '/random_bytes_mcrypt.php'; 163 } 164 $RandomCompatUrandom = null; 165 166 /** 167 * This is a Windows-specific fallback, for when the mcrypt extension 168 * isn't loaded. 169 */ 170 if ( 171 !is_callable('random_bytes') 172 && 173 extension_loaded('com_dotnet') 174 && 175 class_exists('COM') 176 ) { 177 $RandomCompat_disabled_classes = preg_split( 178 '#\s*,\s*#', 179 strtolower(ini_get('disable_classes')) 180 ); 181 182 if (!in_array('com', $RandomCompat_disabled_classes)) { 183 try { 184 $RandomCompatCOMtest = new COM('CAPICOM.Utilities.1'); 185 if (method_exists($RandomCompatCOMtest, 'GetRandom')) { 186 // See random_bytes_com_dotnet.php 187 require_once $RandomCompatDIR . '/random_bytes_com_dotnet.php'; 188 } 189 } catch (com_exception $e) { 190 // Don't try to use it. 191 } 192 } 193 $RandomCompat_disabled_classes = null; 194 $RandomCompatCOMtest = null; 195 } 196 197 /** 198 * throw new Exception 199 */ 200 if (!is_callable('random_bytes')) { 57 201 /** 58 * PHP 5.2.0 - 5.6.x way to implement random_bytes() 202 * We don't have any more options, so let's throw an exception right now 203 * and hope the developer won't let it fail silently. 59 204 * 60 * We use conditional statements here to define the function in accordance 61 * to the operating environment. It's a micro-optimization. 62 * 63 * In order of preference: 64 * 1. Use libsodium if available. 65 * 2. fread() /dev/urandom if available (never on Windows) 66 * 3. mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM) 67 * 4. COM('CAPICOM.Utilities.1')->GetRandom() 68 * 5. openssl_random_pseudo_bytes() (absolute last resort) 69 * 70 * See ERRATA.md for our reasoning behind this particular order 205 * @param mixed $length 206 * @return void 207 * @throws Exception 71 208 */ 72 if (extension_loaded('libsodium')) { 73 // See random_bytes_libsodium.php 74 if (PHP_VERSION_ID >= 50300 && function_exists('\\Sodium\\randombytes_buf')) { 75 require_once $RandomCompatDIR.'/random_bytes_libsodium.php'; 76 } elseif (method_exists('Sodium', 'randombytes_buf')) { 77 require_once $RandomCompatDIR.'/random_bytes_libsodium_legacy.php'; 78 } 79 } 80 81 /** 82 * Reading directly from /dev/urandom: 83 */ 84 if (DIRECTORY_SEPARATOR === '/') { 85 // DIRECTORY_SEPARATOR === '/' on Unix-like OSes -- this is a fast 86 // way to exclude Windows. 87 $RandomCompatUrandom = true; 88 $RandomCompat_basedir = ini_get('open_basedir'); 89 90 if (!empty($RandomCompat_basedir)) { 91 $RandomCompat_open_basedir = explode( 92 PATH_SEPARATOR, 93 strtolower($RandomCompat_basedir) 94 ); 95 $RandomCompatUrandom = in_array( 96 '/dev', 97 $RandomCompat_open_basedir 98 ); 99 $RandomCompat_open_basedir = null; 100 } 101 102 if ( 103 !function_exists('random_bytes') 104 && 105 $RandomCompatUrandom 106 && 107 @is_readable('/dev/urandom') 108 ) { 109 // Error suppression on is_readable() in case of an open_basedir 110 // or safe_mode failure. All we care about is whether or not we 111 // can read it at this point. If the PHP environment is going to 112 // panic over trying to see if the file can be read in the first 113 // place, that is not helpful to us here. 114 115 // See random_bytes_dev_urandom.php 116 require_once $RandomCompatDIR.'/random_bytes_dev_urandom.php'; 117 } 118 // Unset variables after use 119 $RandomCompat_basedir = null; 120 $RandomCompatUrandom = null; 121 } 122 123 /** 124 * mcrypt_create_iv() 125 */ 126 if ( 127 !function_exists('random_bytes') 128 && 129 PHP_VERSION_ID >= 50307 130 && 131 extension_loaded('mcrypt') 132 ) { 133 // Prevent this code from hanging indefinitely on non-Windows; 134 // see https://bugs.php.net/bug.php?id=69833 135 if ( 136 DIRECTORY_SEPARATOR !== '/' || 137 (PHP_VERSION_ID <= 50609 || PHP_VERSION_ID >= 50613) 138 ) { 139 // See random_bytes_mcrypt.php 140 require_once $RandomCompatDIR.'/random_bytes_mcrypt.php'; 141 } 142 } 143 144 if ( 145 !function_exists('random_bytes') 146 && 147 extension_loaded('com_dotnet') 148 && 149 class_exists('COM') 150 ) { 151 $RandomCompat_disabled_classes = preg_split( 152 '#\s*,\s*#', 153 strtolower(ini_get('disable_classes')) 209 function random_bytes($length) 210 { 211 unset($length); // Suppress "variable not used" warnings. 212 throw new Exception( 213 'There is no suitable CSPRNG installed on your system' 154 214 ); 155 156 if (!in_array('com', $RandomCompat_disabled_classes)) { 157 try { 158 $RandomCompatCOMtest = new COM('CAPICOM.Utilities.1'); 159 if (method_exists($RandomCompatCOMtest, 'GetRandom')) { 160 // See random_bytes_com_dotnet.php 161 require_once $RandomCompatDIR.'/random_bytes_com_dotnet.php'; 162 } 163 } catch (com_exception $e) { 164 // Don't try to use it. 165 } 166 } 167 $RandomCompat_disabled_classes = null; 168 $RandomCompatCOMtest = null; 169 } 170 171 /** 172 * openssl_random_pseudo_bytes() 173 */ 174 if ( 175 ( 176 // Unix-like with PHP >= 5.3.0 or 177 ( 178 DIRECTORY_SEPARATOR === '/' 179 && 180 PHP_VERSION_ID >= 50300 181 ) 182 || 183 // Windows with PHP >= 5.4.1 184 PHP_VERSION_ID >= 50401 185 ) 186 && 187 !function_exists('random_bytes') 188 && 189 extension_loaded('openssl') 190 ) { 191 // See random_bytes_openssl.php 192 require_once $RandomCompatDIR.'/random_bytes_openssl.php'; 193 } 194 195 /** 196 * throw new Exception 197 */ 198 if (!function_exists('random_bytes')) { 199 /** 200 * We don't have any more options, so let's throw an exception right now 201 * and hope the developer won't let it fail silently. 202 */ 203 function random_bytes($length) 204 { 205 throw new Exception( 206 'There is no suitable CSPRNG installed on your system' 207 ); 208 } 209 } 210 } 211 212 if (!function_exists('random_int')) { 213 require_once $RandomCompatDIR.'/random_int.php'; 214 } 215 216 $RandomCompatDIR = null; 217 } 215 } 216 } 217 } 218 219 if (!is_callable('random_int')) { 220 require_once $RandomCompatDIR . '/random_int.php'; 221 } 222 223 $RandomCompatDIR = null;
Note: See TracChangeset
for help on using the changeset viewer.