Ticket #28633: 28633.10.patch
File 28633.10.patch, 33.9 KB (added by , 9 years ago) |
---|
-
wp-includes/pluggable.php
From 975345d36844cdbf836a8c6e466b54484fb51090 Mon Sep 17 00:00:00 2001 From: Scott <scott@paragonie.com> Date: Wed, 9 Sep 2015 17:52:23 -0400 Subject: [PATCH] Fix #28633 - use random_compat for PHP 7 CSPRNG functions in PHP 5 --- wp-includes/pluggable.php | 10 ++ wp-includes/random_compat/byte_safe_strings.php | 154 +++++++++++++++++++ wp-includes/random_compat/error_polyfill.php | 56 +++++++ wp-includes/random_compat/random.php | 80 ++++++++++ .../random_compat/random_bytes_com_dotnet.php | 76 +++++++++ .../random_compat/random_bytes_dev_urandom.php | 137 +++++++++++++++++ wp-includes/random_compat/random_bytes_mcrypt.php | 71 +++++++++ wp-includes/random_compat/random_bytes_openssl.php | 76 +++++++++ wp-includes/random_compat/random_int.php | 170 +++++++++++++++++++++ wp-settings.php | 3 + 10 files changed, 833 insertions(+) create mode 100644 wp-includes/random_compat/byte_safe_strings.php create mode 100644 wp-includes/random_compat/error_polyfill.php create mode 100644 wp-includes/random_compat/random.php create mode 100644 wp-includes/random_compat/random_bytes_com_dotnet.php create mode 100644 wp-includes/random_compat/random_bytes_dev_urandom.php create mode 100644 wp-includes/random_compat/random_bytes_mcrypt.php create mode 100644 wp-includes/random_compat/random_bytes_openssl.php create mode 100644 wp-includes/random_compat/random_int.php diff --git a/wp-includes/pluggable.php b/wp-includes/pluggable.php index 5889b5c..f89a81c 100644
a b if ( !function_exists('wp_rand') ) : 2119 2119 function wp_rand( $min = 0, $max = 0 ) { 2120 2120 global $rnd_value; 2121 2121 2122 // Use an external source? 2123 static $external_rand_source_available = true; 2124 if ( $external_rand_source_available ) { 2125 try { 2126 $val = random_int( $min, $max ); 2127 } catch (Exception $e) { 2128 $external_rand_source_available = false; 2129 } 2130 } 2131 2122 2132 // Reset $rnd_value after 14 uses 2123 2133 // 32(md5) + 40(sha1) + 40(sha1) / 8 = 14 random numbers from $rnd_value 2124 2134 if ( strlen($rnd_value) < 8 ) { -
new file wp-includes/random_compat/byte_safe_strings.php
diff --git a/wp-includes/random_compat/byte_safe_strings.php b/wp-includes/random_compat/byte_safe_strings.php new file mode 100644 index 0000000..ad45830
- + 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 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 (!function_exists('RandomCompat_strlen')) { 30 if (ini_get('mbstring.func_overload') & MB_OVERLOAD_STRING) { 31 /** 32 * strlen() implementation that isn't brittle to mbstring.func_overload 33 * 34 * This version uses mb_strlen() in '8bit' mode to treat strings as raw 35 * binary rather than UTF-8, ISO-8859-1, etc 36 * 37 * @param string $binary_string 38 * 39 * @throws TypeError 40 * 41 * @return int 42 */ 43 function RandomCompat_strlen($binary_string) 44 { 45 if (!is_string($binary_string)) { 46 throw new TypeError( 47 'RandomCompat_strlen() expects a string' 48 ); 49 } 50 return mb_strlen($binary_string, '8bit'); 51 } 52 } else { 53 /** 54 * strlen() implementation that isn't brittle to mbstring.func_overload 55 * 56 * This version just used the default strlen() 57 * 58 * @param string $binary_string 59 * 60 * @throws TypeError 61 * 62 * @return int 63 */ 64 function RandomCompat_strlen($binary_string) 65 { 66 if (!is_string($binary_string)) { 67 throw new TypeError( 68 'RandomCompat_strlen() expects a string' 69 ); 70 } 71 return strlen($binary_string); 72 } 73 } 74 } 75 76 if (!function_exists('RandomCompat_substr')) { 77 if (ini_get('mbstring.func_overload') & MB_OVERLOAD_STRING) { 78 /** 79 * substr() implementation that isn't brittle to mbstring.func_overload 80 * 81 * This version uses mb_substr() in '8bit' mode to treat strings as raw 82 * binary rather than UTF-8, ISO-8859-1, etc 83 * 84 * @param string $binary_string 85 * @param int $start 86 * @param int $length (optional) 87 * 88 * @throws TypeError 89 * 90 * @return string 91 */ 92 function RandomCompat_substr($binary_string, $start, $length = null) 93 { 94 if (!is_string($binary_string)) { 95 throw new TypeError( 96 'RandomCompat_substr(): First argument should be a string' 97 ); 98 } 99 if (!is_int($start)) { 100 throw new TypeError( 101 'RandomCompat_substr(): Second argument should be an integer' 102 ); 103 } 104 if ($length === null) { 105 /** 106 * mb_substr($str, 0, NULL, '8bit') returns an empty string on 107 * PHP 5.3, so we have to find the length ourselves. 108 */ 109 $length = RandomCompat_strlen($length) - $start; 110 } elseif (!is_int($length)) { 111 throw new TypeError( 112 'RandomCompat_substr(): Third argument should be an integer, or omitted' 113 ); 114 } 115 return mb_substr($binary_string, $start, $length, '8bit'); 116 } 117 } else { 118 /** 119 * substr() implementation that isn't brittle to mbstring.func_overload 120 * 121 * This version just uses the default substr() 122 * 123 * @param string $binary_string 124 * @param int $start 125 * @param int $length (optional) 126 * 127 * @throws TypeError 128 * 129 * @return string 130 */ 131 function RandomCompat_substr($binary_string, $start, $length = null) 132 { 133 if (!is_string($binary_string)) { 134 throw new TypeError( 135 'RandomCompat_substr(): First argument should be a string' 136 ); 137 } 138 if (!is_int($start)) { 139 throw new TypeError( 140 'RandomCompat_substr(): Second argument should be an integer' 141 ); 142 } 143 if ($length !== null) { 144 if (!is_int($length)) { 145 throw new TypeError( 146 'RandomCompat_substr(): Third argument should be an integer, or omitted' 147 ); 148 } 149 return substr($binary_string, $start, $length); 150 } 151 return substr($binary_string, $start); 152 } 153 } 154 } -
new file wp-includes/random_compat/error_polyfill.php
diff --git a/wp-includes/random_compat/error_polyfill.php b/wp-includes/random_compat/error_polyfill.php new file mode 100644 index 0000000..7253ff7
- + 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 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 (!interface_exists('Throwable', false)) { 30 interface Throwable 31 { 32 public function getMessage(); 33 public function getCode(); 34 public function getFile(); 35 public function getLine(); 36 public function getTrace(); 37 public function getTraceAsString(); 38 public function getPrevious(); 39 public function __toString(); 40 } 41 } 42 43 if (!class_exists('Error', false)) { 44 // We can't really avoid making this extend Exception in PHP 5. 45 class Error extends Exception implements Throwable 46 { 47 48 } 49 } 50 51 if (!class_exists('TypeError', false)) { 52 class TypeError extends Error 53 { 54 55 } 56 } 57 No newline at end of file -
new file wp-includes/random_compat/random.php
diff --git a/wp-includes/random_compat/random.php b/wp-includes/random_compat/random.php new file mode 100644 index 0000000..ca72197
- + 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 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('PHP_VERSION_ID')) { 30 // This constant was introduced in PHP 5.2.7 31 $version = explode('.', PHP_VERSION); 32 define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2])); 33 } 34 if (PHP_VERSION_ID < 70000) { 35 if (!defined('RANDOM_COMPAT_READ_BUFFER')) { 36 define('RANDOM_COMPAT_READ_BUFFER', 8); 37 } 38 require_once "byte_safe_strings.php"; 39 require_once "error_polyfill.php"; 40 if (!function_exists('random_bytes')) { 41 /** 42 * PHP 5.2.0 - 5.6.x way to implement random_bytes() 43 * 44 * We use conditional statements here to define the function in accordance 45 * to the operating environment. It's a micro-optimization. 46 * 47 * In order of preference: 48 * 1. fread() /dev/urandom if available 49 * 2. mcrypt_create_iv($bytes, MCRYPT_CREATE_IV) 50 * 3. COM('CAPICOM.Utilities.1')->GetRandom() 51 * 4. openssl_random_pseudo_bytes() 52 * 53 * See ERRATA.md for our reasoning behind this particular order 54 */ 55 if (!ini_get('open_basedir') && is_readable('/dev/urandom')) { 56 // See random_bytes_dev_urandom.php 57 require_once "random_bytes_dev_urandom.php"; 58 } elseif (PHP_VERSION_ID >= 50307 && function_exists('mcrypt_create_iv')) { 59 // See random_bytes_mcrypt.php 60 require_once "random_bytes_mcrypt.php"; 61 } elseif (extension_loaded('com_dotnet')) { 62 // See random_bytes_com_dotnet.php 63 require_once "random_bytes_com_dotnet.php"; 64 } elseif (function_exists('openssl_random_pseudo_bytes')) { 65 // See random_bytes_openssl.php 66 require_once "random_bytes_openssl.php"; 67 } else { 68 /** 69 * We don't have any more options, so let's throw an exception right now 70 * and hope the developer won't let it fail silently. 71 */ 72 throw new Exception( 73 'There is no suitable CSPRNG installed on your system' 74 ); 75 } 76 } 77 if (!function_exists('random_int')) { 78 require_once "random_int.php"; 79 } 80 } -
new file wp-includes/random_compat/random_bytes_com_dotnet.php
diff --git a/wp-includes/random_compat/random_bytes_com_dotnet.php b/wp-includes/random_compat/random_bytes_com_dotnet.php new file mode 100644 index 0000000..241eee0
- + 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 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 if (!function_exists('random_bytes') && extension_loaded('com_dotnet')) { 29 /** 30 * Windows with PHP < 5.3.0 will not have the function 31 * openssl_random_pseudo_bytes() available, so let's use 32 * CAPICOM to work around this deficiency. 33 * 34 * @param int $bytes 35 * 36 * @throws Exception 37 * 38 * @return string 39 */ 40 function random_bytes($bytes) 41 { 42 if (!is_int($bytes)) { 43 throw new TypeError( 44 'Length must be an integer' 45 ); 46 } 47 if ($bytes < 1) { 48 throw new Error( 49 'Length must be greater than 0' 50 ); 51 } 52 $buf = ''; 53 $util = new COM('CAPICOM.Utilities.1'); 54 $execCount = 0; 55 /** 56 * Let's not let it loop forever. If we run N times and fail to 57 * get N bytes of random data, then CAPICOM has failed us. 58 */ 59 do { 60 $buf .= base64_decode($util->GetRandom($bytes, 0)); 61 if (RandomCompat_strlen($buf) >= $bytes) { 62 /** 63 * Return our random entropy buffer here: 64 */ 65 return RandomCompat_substr($buf, 0, $bytes); 66 } 67 ++$execCount; 68 } while ($execCount < $bytes); 69 /** 70 * If we reach here, PHP has failed us. 71 */ 72 throw new Exception( 73 'PHP failed to generate random data.' 74 ); 75 } 76 } -
new file wp-includes/random_compat/random_bytes_dev_urandom.php
diff --git a/wp-includes/random_compat/random_bytes_dev_urandom.php b/wp-includes/random_compat/random_bytes_dev_urandom.php new file mode 100644 index 0000000..e55b66d
- + 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 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 (!function_exists('random_bytes') && !ini_get('open_basedir') && is_readable('/dev/urandom')) { 30 if (!defined('RANDOM_COMPAT_READ_BUFFER')) { 31 define('RANDOM_COMPAT_READ_BUFFER', 8); 32 } 33 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 * stream_set_read_buffer() does not exist in HHVM 68 * 69 * If we don't set the stream's read buffer to 0, PHP will 70 * internally buffer 8192 bytes, which can waste entropy 71 * 72 * stream_set_read_buffer returns 0 on success 73 */ 74 if (!empty($fp) && function_exists('stream_set_read_buffer')) { 75 stream_set_read_buffer($fp, RANDOM_COMPAT_READ_BUFFER); 76 } 77 } 78 if (!is_int($bytes)) { 79 throw new TypeError( 80 'Length must be an integer' 81 ); 82 } 83 if ($bytes < 1) { 84 throw new Error( 85 'Length must be greater than 0' 86 ); 87 } 88 /** 89 * This if() block only runs if we managed to open a file handle 90 * 91 * It does not belong in an else {} block, because the above 92 * if (empty($fp)) line is logic that should only be run once per 93 * page load. 94 */ 95 if (!empty($fp)) { 96 $remaining = $bytes; 97 $buf = ''; 98 /** 99 * We use fread() in a loop to protect against partial reads 100 */ 101 do { 102 $read = fread($fp, $remaining); 103 if ($read === false) { 104 /** 105 * We cannot safely read from the file. Exit the 106 * do-while loop and trigger the exception condition 107 */ 108 $buf = false; 109 break; 110 } 111 /** 112 * Decrease the number of bytes returned from remaining 113 */ 114 $remaining -= RandomCompat_strlen($read); 115 $buf .= $read; 116 } while ($remaining > 0); 117 118 /** 119 * Is our result valid? 120 */ 121 if ($buf !== false) { 122 if (RandomCompat_strlen($buf) === $bytes) { 123 /** 124 * Return our random entropy buffer here: 125 */ 126 return $buf; 127 } 128 } 129 } 130 /** 131 * If we reach here, PHP has failed us. 132 */ 133 throw new Exception( 134 'PHP failed to generate random data.' 135 ); 136 } 137 } -
new file wp-includes/random_compat/random_bytes_mcrypt.php
diff --git a/wp-includes/random_compat/random_bytes_mcrypt.php b/wp-includes/random_compat/random_bytes_mcrypt.php new file mode 100644 index 0000000..c58ab99
- + 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 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 (!function_exists('random_bytes') && function_exists('mcrypt_create_iv') && version_compare(PHP_VERSION, '5.3.7') >= 0) { 30 /** 31 * Powered by ext/mcrypt (and thankfully NOT libmcrypt) 32 * 33 * @ref https://bugs.php.net/bug.php?id=55169 34 * @ref https://github.com/php/php-src/blob/c568ffe5171d942161fc8dda066bce844bdef676/ext/mcrypt/mcrypt.c#L1321-L1386 35 * 36 * @param int $bytes 37 * 38 * @throws Exception 39 * 40 * @return string 41 */ 42 function random_bytes($bytes) 43 { 44 if (!is_int($bytes)) { 45 throw new TypeError( 46 'Length must be an integer' 47 ); 48 } 49 if ($bytes < 1) { 50 throw new Error( 51 'Length must be greater than 0' 52 ); 53 } 54 55 $buf = mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM); 56 if ($buf !== false) { 57 if (RandomCompat_strlen($buf) === $bytes) { 58 /** 59 * Return our random entropy buffer here: 60 */ 61 return $buf; 62 } 63 } 64 /** 65 * If we reach here, PHP has failed us. 66 */ 67 throw new Exception( 68 'PHP failed to generate random data.' 69 ); 70 } 71 } -
new file wp-includes/random_compat/random_bytes_openssl.php
diff --git a/wp-includes/random_compat/random_bytes_openssl.php b/wp-includes/random_compat/random_bytes_openssl.php new file mode 100644 index 0000000..5141ef6
- + 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 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 (!function_exists('random_bytes') && function_exists('openssl_random_pseudo_bytes')) { 30 /** 31 * Since openssl_random_pseudo_bytes() uses openssl's 32 * RAND_pseudo_bytes() API, which has been marked as deprecated by the 33 * OpenSSL team, this is our last resort before failure. 34 * 35 * @ref https://www.openssl.org/docs/crypto/RAND_bytes.html 36 * 37 * @param int $bytes 38 * 39 * @throws Exception 40 * 41 * @return string 42 */ 43 function random_bytes($bytes) 44 { 45 if (!is_int($bytes)) { 46 throw new TypeError( 47 'Length must be an integer' 48 ); 49 } 50 if ($bytes < 1) { 51 throw new Error( 52 'Length must be greater than 0' 53 ); 54 } 55 $secure = true; 56 /** 57 * $secure is passed by reference. If it's set to false, fail. Note 58 * that this will only return false if this function fails to return 59 * any data. 60 * 61 * @ref https://github.com/paragonie/random_compat/issues/6#issuecomment-119564973 62 */ 63 $buf = openssl_random_pseudo_bytes($bytes, $secure); 64 if ($buf !== false && $secure) { 65 if (RandomCompat_strlen($buf) === $bytes) { 66 return $buf; 67 } 68 } 69 /** 70 * If we reach here, PHP has failed us. 71 */ 72 throw new Exception( 73 'PHP failed to generate random data.' 74 ); 75 } 76 } -
new file wp-includes/random_compat/random_int.php
diff --git a/wp-includes/random_compat/random_int.php b/wp-includes/random_compat/random_int.php new file mode 100644 index 0000000..807ff7a
- + 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 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 (!function_exists('random_int')) { 30 /** 31 * Fetch a random integer between $min and $max inclusive 32 * 33 * @param int $min 34 * @param int $max 35 * 36 * @throws Exception 37 * 38 * @return int 39 */ 40 function random_int($min, $max) 41 { 42 /** 43 * Type and input logic checks 44 */ 45 if (!is_int($min)) { 46 throw new TypeError( 47 'random_int(): $min must be an integer' 48 ); 49 } 50 if (!is_int($max)) { 51 throw new TypeError( 52 'random_int(): $max must be an integer' 53 ); 54 } 55 if ($min > $max) { 56 throw new Error( 57 'Minimum value must be less than or equal to the maximum value' 58 ); 59 } 60 if ($max === $min) { 61 return $min; 62 } 63 64 /** 65 * Initialize variables to 0 66 * 67 * We want to store: 68 * $bytes => the number of random bytes we need 69 * $mask => an integer bitmask (for use with the &) operator 70 * so we can minimize the number of discards 71 */ 72 $attempts = $bits = $bytes = $mask = $valueShift = 0; 73 74 /** 75 * At this point, $range is a positive number greater than 0. It might 76 * overflow, however, if $max - $min > PHP_INT_MAX. PHP will cast it to 77 * a float and we will lose some precision. 78 */ 79 $range = $max - $min; 80 81 /** 82 * Test for integer overflow: 83 */ 84 if (!is_int($range)) { 85 /** 86 * Still safely calculate wider ranges. 87 * Provided by @CodesInChaos, @oittaa 88 * 89 * @ref https://gist.github.com/CodesInChaos/03f9ea0b58e8b2b8d435 90 * 91 * We use ~0 as a mask in this case because it generates all 1s 92 * 93 * @ref https://eval.in/400356 (32-bit) 94 * @ref http://3v4l.org/XX9r5 (64-bit) 95 */ 96 $bytes = PHP_INT_SIZE; 97 $mask = ~0; 98 } else { 99 /** 100 * $bits is effectively ceil(log($range, 2)) without dealing with 101 * type juggling 102 */ 103 while ($range > 0) { 104 if ($bits % 8 === 0) { 105 ++$bytes; 106 } 107 ++$bits; 108 $range >>= 1; 109 $mask = $mask << 1 | 1; 110 } 111 $valueShift = $min; 112 } 113 114 /** 115 * Now that we have our parameters set up, let's begin generating 116 * random integers until one falls between $min and $max 117 */ 118 do { 119 /** 120 * The rejection probability is at most 0.5, so this corresponds 121 * to a failure probability of 2^-128 for a working RNG 122 */ 123 if ($attempts > 128) { 124 throw new Exception( 125 'random_int: RNG is broken - too many rejections' 126 ); 127 } 128 129 /** 130 * Let's grab the necessary number of random bytes 131 */ 132 $randomByteString = random_bytes($bytes); 133 if ($randomByteString === false) { 134 throw new Exception( 135 'Random number generator failure' 136 ); 137 } 138 139 /** 140 * Let's turn $randomByteString into an integer 141 * 142 * This uses bitwise operators (<< and |) to build an integer 143 * out of the values extracted from ord() 144 * 145 * Example: [9F] | [6D] | [32] | [0C] => 146 * 159 + 27904 + 3276800 + 201326592 => 147 * 204631455 148 */ 149 $val = 0; 150 for ($i = 0; $i < $bytes; ++$i) { 151 $val |= ord($randomByteString[$i]) << ($i * 8); 152 } 153 154 /** 155 * Apply mask 156 */ 157 $val &= $mask; 158 $val += $valueShift; 159 160 ++$attempts; 161 /** 162 * If $val overflows to a floating point number, 163 * ... or is larger than $max, 164 * ... or smaller than $int, 165 * then try again. 166 */ 167 } while (!is_int($val) || $val > $max || $val < $min); 168 return (int) $val; 169 } 170 } -
wp-settings.php
diff --git a/wp-settings.php b/wp-settings.php index 993a120..9ba189c 100644
a b require( ABSPATH . WPINC . '/nav-menu.php' ); 153 153 require( ABSPATH . WPINC . '/nav-menu-template.php' ); 154 154 require( ABSPATH . WPINC . '/admin-bar.php' ); 155 155 156 // random_compat 157 require( ABSPATH . WPINC . '/random_compat/random.php' ); 158 156 159 // Load multisite-specific files. 157 160 if ( is_multisite() ) { 158 161 require( ABSPATH . WPINC . '/ms-functions.php' );