X-Git-Url: https://git.cyclocoop.org/%242?a=blobdiff_plain;ds=sidebyside;f=includes%2FCryptRand.php;h=858eebf205b440a16e60fc33172e59728db5cd15;hb=3c899bfc66218e8a65b45ad158e3dcb6081ac4e9;hp=9f0f7de1eed6ccbf4625e20e7f37b0876fd7d424;hpb=1c283f2a413f00d752c9f49d74008c4cb00a7c86;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/CryptRand.php b/includes/CryptRand.php index 9f0f7de1ee..858eebf205 100644 --- a/includes/CryptRand.php +++ b/includes/CryptRand.php @@ -5,6 +5,21 @@ * This is based in part on Drupal code as well as what we used in our own code * prior to introduction of this class. * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * * @author Daniel Friesen * @file */ @@ -54,7 +69,7 @@ class MWCryptRand { // It'll also vary slightly across different machines $state = serialize( $_SERVER ); - // To try and vary the system information of the state a bit more + // To try vary the system information of the state a bit more // by including the system's hostname into the state $state .= wfHostname(); @@ -63,13 +78,22 @@ class MWCryptRand { // Include some information about the filesystem's current state in the random state $files = array(); + // We know this file is here so grab some info about ourself $files[] = __FILE__; + + // We must also have a parent folder, and with the usual file structure, a grandparent + $files[] = __DIR__; + $files[] = dirname( __DIR__ ); + // The config file is likely the most often edited file we know should be around - // so if the constant with it's location is defined include it's stat info into the state + // so include its stat info into the state. + // The constant with its location will almost always be defined, as WebStart.php defines + // MW_CONFIG_FILE to $IP/LocalSettings.php unless being configured with MW_CONFIG_CALLBACK (eg. the installer) if ( defined( 'MW_CONFIG_FILE' ) ) { $files[] = MW_CONFIG_FILE; } + foreach ( $files as $file ) { wfSuppressWarnings(); $stat = stat( $file ); @@ -120,7 +144,7 @@ class MWCryptRand { /** * Randomly hash data while mixing in clock drift data for randomness * - * @param $data The data to randomly hash. + * @param $data string The data to randomly hash. * @return String The hashed bytes * @author Tim Starling */ @@ -166,7 +190,7 @@ class MWCryptRand { /** * Return a rolling random state initially build using data from unstable sources - * @return A new weak random state + * @return string A new weak random state */ protected function randomState() { static $state = null; @@ -184,6 +208,7 @@ class MWCryptRand { /** * Decide on the best acceptable hash algorithm we have available for hash() + * @throws MWException * @return String A hash algorithm */ protected function hashAlgo() { @@ -227,6 +252,7 @@ class MWCryptRand { * Generate an acceptably unstable one-way-hash of some text * making use of the best hash algorithm that we have available. * + * @param $data string * @return String A raw hash of the data */ protected function hash( $data ) { @@ -237,6 +263,8 @@ class MWCryptRand { * Generate an acceptably unstable one-way-hmac of some text * making use of the best hash algorithm that we have available. * + * @param $data string + * @param $key string * @return String A raw hash of the data */ protected function hmac( $data, $key ) { @@ -256,17 +284,10 @@ class MWCryptRand { /** * @see self::generate() */ - public function realGenerate( $bytes, $forceStrong = false, $method = null ) { + public function realGenerate( $bytes, $forceStrong = false ) { wfProfileIn( __METHOD__ ); - if ( is_string( $forceStrong ) && is_null( $method ) ) { - // If $forceStrong is a string then it's really $method - $method = $forceStrong; - $forceStrong = false; - } - if ( !is_null( $method ) ) { - wfDebug( __METHOD__ . ": Generating cryptographic random bytes for $method\n" ); - } + wfDebug( __METHOD__ . ": Generating cryptographic random bytes for " . wfGetAllCallers( 5 ) . "\n" ); $bytes = floor( $bytes ); static $buffer = ''; @@ -278,19 +299,18 @@ class MWCryptRand { if ( strlen( $buffer ) < $bytes ) { // If available make use of mcrypt_create_iv URANDOM source to generate randomness // On unix-like systems this reads from /dev/urandom but does it without any buffering - // and bypasses openbasdir restrictions so it's preferable to reading directly + // and bypasses openbasedir restrictions, so it's preferable to reading directly // On Windows starting in PHP 5.3.0 Windows' native CryptGenRandom is used to generate // entropy so this is also preferable to just trying to read urandom because it may work // on Windows systems as well. if ( function_exists( 'mcrypt_create_iv' ) ) { wfProfileIn( __METHOD__ . '-mcrypt' ); $rem = $bytes - strlen( $buffer ); - wfDebug( __METHOD__ . ": Trying to generate $rem bytes of randomness using mcrypt_create_iv.\n" ); $iv = mcrypt_create_iv( $rem, MCRYPT_DEV_URANDOM ); if ( $iv === false ) { wfDebug( __METHOD__ . ": mcrypt_create_iv returned false.\n" ); } else { - $bytes .= $iv; + $buffer .= $iv; wfDebug( __METHOD__ . ": mcrypt_create_iv generated " . strlen( $iv ) . " bytes of randomness.\n" ); } wfProfileOut( __METHOD__ . '-mcrypt' ); @@ -298,15 +318,15 @@ class MWCryptRand { } if ( strlen( $buffer ) < $bytes ) { - // If available make use of openssl's random_pesudo_bytes method to attempt to generate randomness. + // If available make use of openssl's random_pseudo_bytes method to attempt to generate randomness. // However don't do this on Windows with PHP < 5.3.4 due to a bug: // http://stackoverflow.com/questions/1940168/openssl-random-pseudo-bytes-is-slow-php + // http://git.php.net/?p=php-src.git;a=commitdiff;h=cd62a70863c261b07f6dadedad9464f7e213cad5 if ( function_exists( 'openssl_random_pseudo_bytes' ) && ( !wfIsWindows() || version_compare( PHP_VERSION, '5.3.4', '>=' ) ) ) { wfProfileIn( __METHOD__ . '-openssl' ); $rem = $bytes - strlen( $buffer ); - wfDebug( __METHOD__ . ": Trying to generate $rem bytes of randomness using openssl_random_pseudo_bytes.\n" ); $openssl_bytes = openssl_random_pseudo_bytes( $rem, $openssl_strong ); if ( $openssl_bytes === false ) { wfDebug( __METHOD__ . ": openssl_random_pseudo_bytes returned false.\n" ); @@ -327,7 +347,6 @@ class MWCryptRand { if ( strlen( $buffer ) < $bytes && ( function_exists( 'stream_set_read_buffer' ) || $forceStrong ) ) { wfProfileIn( __METHOD__ . '-fopen-urandom' ); $rem = $bytes - strlen( $buffer ); - wfDebug( __METHOD__ . ": Trying to generate $rem bytes of randomness using /dev/urandom.\n" ); if ( !function_exists( 'stream_set_read_buffer' ) && $forceStrong ) { wfDebug( __METHOD__ . ": Was forced to read from /dev/urandom without control over the buffer size.\n" ); } @@ -351,7 +370,6 @@ class MWCryptRand { stream_set_read_buffer( $urandom, $rem ); $chunk_size = $rem; } - wfDebug( __METHOD__ . ": Reading from /dev/urandom with a buffer size of $chunk_size.\n" ); $random_bytes = fread( $urandom, max( $chunk_size, $rem ) ); $buffer .= $random_bytes; fclose( $urandom ); @@ -399,13 +417,13 @@ class MWCryptRand { /** * @see self::generateHex() */ - public function realGenerateHex( $chars, $forceStrong = false, $method = null ) { + public function realGenerateHex( $chars, $forceStrong = false ) { // hex strings are 2x the length of raw binary so we divide the length in half // odd numbers will result in a .5 that leads the generate() being 1 character // short, so we use ceil() to ensure that we always have enough bytes $bytes = ceil( $chars / 2 ); // Generate the data and then convert it to a hex string - $hex = bin2hex( $this->generate( $bytes, $forceStrong, $method ) ); + $hex = bin2hex( $this->generate( $bytes, $forceStrong ) ); // A bit of paranoia here, the caller asked for a specific length of string // here, and it's possible (eg when given an odd number) that we may actually // have at least 1 char more than they asked for. Just in case they made this @@ -420,6 +438,7 @@ class MWCryptRand { /** * Return a singleton instance of MWCryptRand + * @return MWCryptRand */ protected static function singleton() { if ( is_null( self::$singleton ) ) { @@ -449,11 +468,10 @@ class MWCryptRand { * @param $forceStrong bool Pass true if you want generate to prefer cryptographically * strong sources of entropy even if reading from them may steal * more entropy from the system than optimal. - * @param $method The calling method, for debug info. May be the second argument if you are not using forceStrong * @return String Raw binary random data */ - public static function generate( $bytes, $forceStrong = false, $method = null ) { - return self::singleton()->realGenerate( $bytes, $forceStrong, $method ); + public static function generate( $bytes, $forceStrong = false ) { + return self::singleton()->realGenerate( $bytes, $forceStrong ); } /** @@ -466,11 +484,10 @@ class MWCryptRand { * @param $forceStrong bool Pass true if you want generate to prefer cryptographically * strong sources of entropy even if reading from them may steal * more entropy from the system than optimal. - * @param $method The calling method, for debug info. May be the second argument if you are not using forceStrong * @return String Hexadecimal random data */ - public static function generateHex( $chars, $forceStrong = false, $method = null ) { - return self::singleton()->realGenerateHex( $chars, $forceStrong, $method ); + public static function generateHex( $chars, $forceStrong = false ) { + return self::singleton()->realGenerateHex( $chars, $forceStrong ); } }