[Pkg-mediawiki-commits] r311 - in mediawiki/sid-sec/debian: . patches po
Thorsten Glaser
tg at alioth.debian.org
Wed May 16 13:03:46 UTC 2012
Author: tg
Date: 2012-05-16 13:03:46 +0000 (Wed, 16 May 2012)
New Revision: 311
Added:
mediawiki/sid-sec/debian/patches/CVE-2012-1581.patch
Modified:
mediawiki/sid-sec/debian/changelog
mediawiki/sid-sec/debian/patches/add_rss_guid.patch
mediawiki/sid-sec/debian/patches/debian_specific_config.patch
mediawiki/sid-sec/debian/patches/detect_invalid_titles.patch
mediawiki/sid-sec/debian/patches/mimetypes.patch
mediawiki/sid-sec/debian/patches/series
mediawiki/sid-sec/debian/patches/texvc_location.patch
mediawiki/sid-sec/debian/po/da.po
mediawiki/sid-sec/debian/watch
Log:
add fix for the last remaining CVE in #666269 and some lintian cleanup
Modified: mediawiki/sid-sec/debian/changelog
===================================================================
--- mediawiki/sid-sec/debian/changelog 2012-03-30 08:43:27 UTC (rev 310)
+++ mediawiki/sid-sec/debian/changelog 2012-05-16 13:03:46 UTC (rev 311)
@@ -1,13 +1,15 @@
-mediawiki (1:1.15.5-9) UNRELEASED; urgency=high
+mediawiki (1:1.15.5-9) unstable; urgency=high
+ * Team upload.
* Address MW security release 1.18.1-1 (Closes: #666269)
- CVE-2012-1578 MW#34212: doesn’t affect 1.15
- CVE-2012-1579 MW#34907: doesn’t affect 1.15
- CVE-2012-1580 MW#35317: doesn’t affect 1.15
- - CVE-2012-1581 MW#35078: (can’t access bugreport)
+ - CVE-2012-1581 MW#35078: fix backported
- CVE-2012-1582 MW#35315: fix backported
+ * Apply some lintian cleanup
- -- Thorsten Glaser <tg at mirbsd.de> Fri, 30 Mar 2012 10:41:58 +0200
+ -- Thorsten Glaser <tg at mirbsd.de> Wed, 16 May 2012 15:01:06 +0200
mediawiki (1:1.15.5-8) unstable; urgency=low
Added: mediawiki/sid-sec/debian/patches/CVE-2012-1581.patch
===================================================================
--- mediawiki/sid-sec/debian/patches/CVE-2012-1581.patch (rev 0)
+++ mediawiki/sid-sec/debian/patches/CVE-2012-1581.patch 2012-05-16 13:03:46 UTC (rev 311)
@@ -0,0 +1,745 @@
+Description: Add a better PRNG class; use it in some places
+ Original commitdiffs (squashed into one patch):
+ - 298741089078574ed352552cdf6ae4c91e4c7aad
+ - 0a1d98cb1e292d0fbb0adf134617c1aafdce2e0f
+ - 96c81c1b5be52b903aa1cd9c95e51c864c2db920
+ - 4645fef5428387a8ea27572342c6385f5be210cf
+ - 51d2acffb2cab8309ad75232ece80b3939f1ccba
+ Tim Starling said I would need all of those.
+Origin: Mediawiki git
+Bug: https://bugzilla.wikimedia.org/show_bug.cgi?id=35078
+
+Index: mediawiki-1.15.5/includes/AutoLoader.php
+===================================================================
+--- mediawiki-1.15.5.orig/includes/AutoLoader.php 2009-05-01 08:24:09.000000000 +0200
++++ mediawiki-1.15.5/includes/AutoLoader.php 2012-05-16 14:59:43.000000000 +0200
+@@ -125,6 +125,7 @@
+ 'memcached' => 'includes/memcached-client.php',
+ 'MessageCache' => 'includes/MessageCache.php',
+ 'MimeMagic' => 'includes/MimeMagic.php',
++ 'MWCryptRand' => 'includes/CryptRand.php',
+ 'MWException' => 'includes/Exception.php',
+ 'MWNamespace' => 'includes/Namespace.php',
+ 'MySQLSearchResultSet' => 'includes/SearchMySQL.php',
+Index: mediawiki-1.15.5/includes/CryptRand.php
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ mediawiki-1.15.5/includes/CryptRand.php 2012-05-16 14:59:43.000000000 +0200
+@@ -0,0 +1,468 @@
++<?php
++/**
++ * A cryptographic random generator class used for generating secret keys
++ *
++ * This is based in part on Drupal code as well as what we used in our own code
++ * prior to introduction of this class.
++ *
++ * @author Daniel Friesen
++ * @file
++ */
++
++class MWCryptRand {
++
++ /**
++ * Minimum number of iterations we want to make in our drift calculations.
++ */
++ const MIN_ITERATIONS = 1000;
++
++ /**
++ * Number of milliseconds we want to spend generating each separate byte
++ * of the final generated bytes.
++ * This is used in combination with the hash length to determine the duration
++ * we should spend doing drift calculations.
++ */
++ const MSEC_PER_BYTE = 0.5;
++
++ /**
++ * Singleton instance for public use
++ */
++ protected static $singleton = null;
++
++ /**
++ * The hash algorithm being used
++ */
++ protected $algo = null;
++
++ /**
++ * The number of bytes outputted by the hash algorithm
++ */
++ protected $hashLength = null;
++
++ /**
++ * A boolean indicating whether the previous random generation was done using
++ * cryptographically strong random number generator or not.
++ */
++ protected $strong = null;
++
++ /**
++ * Initialize an initial random state based off of whatever we can find
++ */
++ protected function initialRandomState() {
++ // $_SERVER contains a variety of unstable user and system specific information
++ // It'll vary a little with each page, and vary even more with separate users
++ // It'll also vary slightly across different machines
++ $state = serialize( $_SERVER );
++
++ // To try and vary the system information of the state a bit more
++ // by including the system's hostname into the state
++ $state .= wfHostname();
++
++ // Try to gather a little entropy from the different php rand sources
++ $state .= rand() . uniqid( mt_rand(), true );
++
++ // 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__;
++ // 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
++ if ( defined( 'MW_CONFIG_FILE' ) ) {
++ $files[] = MW_CONFIG_FILE;
++ }
++ foreach ( $files as $file ) {
++ wfSuppressWarnings();
++ $stat = stat( $file );
++ wfRestoreWarnings();
++ if ( $stat ) {
++ // stat() duplicates data into numeric and string keys so kill off all the numeric ones
++ foreach ( $stat as $k => $v ) {
++ if ( is_numeric( $k ) ) {
++ unset( $k );
++ }
++ }
++ // The absolute filename itself will differ from install to install so don't leave it out
++ $state .= realpath( $file );
++ $state .= implode( '', $stat );
++ } else {
++ // The fact that the file isn't there is worth at least a
++ // minuscule amount of entropy.
++ $state .= '0';
++ }
++ }
++
++ // Try and make this a little more unstable by including the varying process
++ // id of the php process we are running inside of if we are able to access it
++ if ( function_exists( 'getmypid' ) ) {
++ $state .= getmypid();
++ }
++
++ // If available try to increase the instability of the data by throwing in
++ // the precise amount of memory that we happen to be using at the moment.
++ if ( function_exists( 'memory_get_usage' ) ) {
++ $state .= memory_get_usage( true );
++ }
++
++ // It's mostly worthless but throw the wiki's id into the data for a little more variance
++ $state .= wfWikiID();
++
++ // If we have a secret key or proxy key set then throw it into the state as well
++ global $wgSecretKey, $wgProxyKey;
++ if ( $wgSecretKey ) {
++ $state .= $wgSecretKey;
++ } elseif ( $wgProxyKey ) {
++ $state .= $wgProxyKey;
++ }
++
++ return $state;
++ }
++
++ /**
++ * Randomly hash data while mixing in clock drift data for randomness
++ *
++ * @param $data string The data to randomly hash.
++ * @return String The hashed bytes
++ * @author Tim Starling
++ */
++ protected function driftHash( $data ) {
++ // Minimum number of iterations (to avoid slow operations causing the loop to gather little entropy)
++ $minIterations = self::MIN_ITERATIONS;
++ // Duration of time to spend doing calculations (in seconds)
++ $duration = ( self::MSEC_PER_BYTE / 1000 ) * $this->hashLength();
++ // Create a buffer to use to trigger memory operations
++ $bufLength = 10000000;
++ $buffer = str_repeat( ' ', $bufLength );
++ $bufPos = 0;
++
++ // Iterate for $duration seconds or at least $minIerations number of iterations
++ $iterations = 0;
++ $startTime = microtime( true );
++ $currentTime = $startTime;
++ while ( $iterations < $minIterations || $currentTime - $startTime < $duration ) {
++ // Trigger some memory writing to trigger some bus activity
++ // This may create variance in the time between iterations
++ $bufPos = ( $bufPos + 13 ) % $bufLength;
++ $buffer[$bufPos] = ' ';
++ // Add the drift between this iteration and the last in as entropy
++ $nextTime = microtime( true );
++ $delta = (int)( ( $nextTime - $currentTime ) * 1000000 );
++ $data .= $delta;
++ // Every 100 iterations hash the data and entropy
++ if ( $iterations % 100 === 0 ) {
++ $data = sha1( $data );
++ }
++ $currentTime = $nextTime;
++ $iterations++;
++ }
++ $timeTaken = $currentTime - $startTime;
++ $data = $this->hash( $data );
++
++ wfDebug( __METHOD__ . ": Clock drift calculation " .
++ "(time-taken=" . ( $timeTaken * 1000 ) . "ms, " .
++ "iterations=$iterations, " .
++ "time-per-iteration=" . ( $timeTaken / $iterations * 1e6 ) . "us)\n" );
++ return $data;
++ }
++
++ /**
++ * Return a rolling random state initially build using data from unstable sources
++ * @return string A new weak random state
++ */
++ protected function randomState() {
++ static $state = null;
++ if ( is_null( $state ) ) {
++ // Initialize the state with whatever unstable data we can find
++ // It's important that this data is hashed right afterwards to prevent
++ // it from being leaked into the output stream
++ $state = $this->hash( $this->initialRandomState() );
++ }
++ // Generate a new random state based on the initial random state or previous
++ // random state by combining it with clock drift
++ $state = $this->driftHash( $state );
++ return $state;
++ }
++
++ /**
++ * Decide on the best acceptable hash algorithm we have available for hash()
++ * @throws MWException
++ * @return String A hash algorithm
++ */
++ protected function hashAlgo() {
++ if ( !is_null( $this->algo ) ) {
++ return $this->algo;
++ }
++
++ $algos = hash_algos();
++ $preference = array( 'whirlpool', 'sha256', 'sha1', 'md5' );
++
++ foreach ( $preference as $algorithm ) {
++ if ( in_array( $algorithm, $algos ) ) {
++ $this->algo = $algorithm;
++ wfDebug( __METHOD__ . ": Using the {$this->algo} hash algorithm.\n" );
++ return $this->algo;
++ }
++ }
++
++ // We only reach here if no acceptable hash is found in the list, this should
++ // be a technical impossibility since most of php's hash list is fixed and
++ // some of the ones we list are available as their own native functions
++ // But since we already require at least 5.2 and hash() was default in
++ // 5.1.2 we don't bother falling back to methods like sha1 and md5.
++ throw new MWException( "Could not find an acceptable hashing function in hash_algos()" );
++ }
++
++ /**
++ * Return the byte-length output of the hash algorithm we are
++ * using in self::hash and self::hmac.
++ *
++ * @return int Number of bytes the hash outputs
++ */
++ protected function hashLength() {
++ if ( is_null( $this->hashLength ) ) {
++ $this->hashLength = strlen( $this->hash( '' ) );
++ }
++ return $this->hashLength;
++ }
++
++ /**
++ * 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 ) {
++ return hash( $this->hashAlgo(), $data, true );
++ }
++
++ /**
++ * 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 ) {
++ return hash_hmac( $this->hashAlgo(), $data, $key, true );
++ }
++
++ /**
++ * @see self::wasStrong()
++ */
++ public function realWasStrong() {
++ if ( is_null( $this->strong ) ) {
++ throw new MWException( __METHOD__ . ' called before generation of random data' );
++ }
++ return $this->strong;
++ }
++
++ /**
++ * @see self::generate()
++ */
++ public function realGenerate( $bytes, $forceStrong = false ) {
++ wfProfileIn( __METHOD__ );
++
++ wfDebug( __METHOD__ . ": Generating cryptographic random bytes for " . wfGetAllCallers( 5 ) . "\n" );
++
++ $bytes = floor( $bytes );
++ static $buffer = '';
++ if ( is_null( $this->strong ) ) {
++ // Set strength to false initially until we know what source data is coming from
++ $this->strong = true;
++ }
++
++ 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
++ // 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 );
++ $iv = mcrypt_create_iv( $rem, MCRYPT_DEV_URANDOM );
++ if ( $iv === false ) {
++ wfDebug( __METHOD__ . ": mcrypt_create_iv returned false.\n" );
++ } else {
++ $buffer .= $iv;
++ wfDebug( __METHOD__ . ": mcrypt_create_iv generated " . strlen( $iv ) . " bytes of randomness.\n" );
++ }
++ wfProfileOut( __METHOD__ . '-mcrypt' );
++ }
++ }
++
++ if ( strlen( $buffer ) < $bytes ) {
++ // If available make use of openssl's random_pesudo_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
++ if ( function_exists( 'openssl_random_pseudo_bytes' )
++ && ( !wfIsWindows() || version_compare( PHP_VERSION, '5.3.4', '>=' ) )
++ ) {
++ wfProfileIn( __METHOD__ . '-openssl' );
++ $rem = $bytes - strlen( $buffer );
++ $openssl_bytes = openssl_random_pseudo_bytes( $rem, $openssl_strong );
++ if ( $openssl_bytes === false ) {
++ wfDebug( __METHOD__ . ": openssl_random_pseudo_bytes returned false.\n" );
++ } else {
++ $buffer .= $openssl_bytes;
++ wfDebug( __METHOD__ . ": openssl_random_pseudo_bytes generated " . strlen( $openssl_bytes ) . " bytes of " . ( $openssl_strong ? "strong" : "weak" ) . " randomness.\n" );
++ }
++ if ( strlen( $buffer ) >= $bytes ) {
++ // openssl tells us if the random source was strong, if some of our data was generated
++ // using it use it's say on whether the randomness is strong
++ $this->strong = !!$openssl_strong;
++ }
++ wfProfileOut( __METHOD__ . '-openssl' );
++ }
++ }
++
++ // Only read from urandom if we can control the buffer size or were passed forceStrong
++ if ( strlen( $buffer ) < $bytes && ( function_exists( 'stream_set_read_buffer' ) || $forceStrong ) ) {
++ wfProfileIn( __METHOD__ . '-fopen-urandom' );
++ $rem = $bytes - strlen( $buffer );
++ if ( !function_exists( 'stream_set_read_buffer' ) && $forceStrong ) {
++ wfDebug( __METHOD__ . ": Was forced to read from /dev/urandom without control over the buffer size.\n" );
++ }
++ // /dev/urandom is generally considered the best possible commonly
++ // available random source, and is available on most *nix systems.
++ wfSuppressWarnings();
++ $urandom = fopen( "/dev/urandom", "rb" );
++ wfRestoreWarnings();
++
++ // Attempt to read all our random data from urandom
++ // php's fread always does buffered reads based on the stream's chunk_size
++ // so in reality it will usually read more than the amount of data we're
++ // asked for and not storing that risks depleting the system's random pool.
++ // If stream_set_read_buffer is available set the chunk_size to the amount
++ // of data we need. Otherwise read 8k, php's default chunk_size.
++ if ( $urandom ) {
++ // php's default chunk_size is 8k
++ $chunk_size = 1024 * 8;
++ if ( function_exists( 'stream_set_read_buffer' ) ) {
++ // If possible set the chunk_size to the amount of data we need
++ stream_set_read_buffer( $urandom, $rem );
++ $chunk_size = $rem;
++ }
++ $random_bytes = fread( $urandom, max( $chunk_size, $rem ) );
++ $buffer .= $random_bytes;
++ fclose( $urandom );
++ wfDebug( __METHOD__ . ": /dev/urandom generated " . strlen( $random_bytes ) . " bytes of randomness.\n" );
++ if ( strlen( $buffer ) >= $bytes ) {
++ // urandom is always strong, set to true if all our data was generated using it
++ $this->strong = true;
++ }
++ } else {
++ wfDebug( __METHOD__ . ": /dev/urandom could not be opened.\n" );
++ }
++ wfProfileOut( __METHOD__ . '-fopen-urandom' );
++ }
++
++ // If we cannot use or generate enough data from a secure source
++ // use this loop to generate a good set of pseudo random data.
++ // This works by initializing a random state using a pile of unstable data
++ // and continually shoving it through a hash along with a variable salt.
++ // We hash the random state with more salt to avoid the state from leaking
++ // out and being used to predict the /randomness/ that follows.
++ if ( strlen( $buffer ) < $bytes ) {
++ wfDebug( __METHOD__ . ": Falling back to using a pseudo random state to generate randomness.\n" );
++ }
++ while ( strlen( $buffer ) < $bytes ) {
++ wfProfileIn( __METHOD__ . '-fallback' );
++ $buffer .= $this->hmac( $this->randomState(), mt_rand() );
++ // This code is never really cryptographically strong, if we use it
++ // at all, then set strong to false.
++ $this->strong = false;
++ wfProfileOut( __METHOD__ . '-fallback' );
++ }
++
++ // Once the buffer has been filled up with enough random data to fulfill
++ // the request shift off enough data to handle the request and leave the
++ // unused portion left inside the buffer for the next request for random data
++ $generated = substr( $buffer, 0, $bytes );
++ $buffer = substr( $buffer, $bytes );
++
++ wfDebug( __METHOD__ . ": " . strlen( $buffer ) . " bytes of randomness leftover in the buffer.\n" );
++
++ wfProfileOut( __METHOD__ );
++ return $generated;
++ }
++
++ /**
++ * @see self::generateHex()
++ */
++ 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 ) );
++ // 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
++ // call intending to insert it into a database that does truncation we don't
++ // want to give them too much and end up with their database and their live
++ // code having two different values because part of what we gave them is truncated
++ // hence, we strip out any run of characters longer than what we were asked for.
++ return substr( $hex, 0, $chars );
++ }
++
++ /** Publicly exposed static methods **/
++
++ /**
++ * Return a singleton instance of MWCryptRand
++ * @return MWCryptRand
++ */
++ protected static function singleton() {
++ if ( is_null( self::$singleton ) ) {
++ self::$singleton = new self;
++ }
++ return self::$singleton;
++ }
++
++ /**
++ * Return a boolean indicating whether or not the source used for cryptographic
++ * random bytes generation in the previously run generate* call
++ * was cryptographically strong.
++ *
++ * @return bool Returns true if the source was strong, false if not.
++ */
++ public static function wasStrong() {
++ return self::singleton()->realWasStrong();
++ }
++
++ /**
++ * Generate a run of (ideally) cryptographically random data and return
++ * it in raw binary form.
++ * You can use MWCryptRand::wasStrong() if you wish to know if the source used
++ * was cryptographically strong.
++ *
++ * @param $bytes int the number of bytes of random data to generate
++ * @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.
++ * @return String Raw binary random data
++ */
++ public static function generate( $bytes, $forceStrong = false ) {
++ return self::singleton()->realGenerate( $bytes, $forceStrong );
++ }
++
++ /**
++ * Generate a run of (ideally) cryptographically random data and return
++ * it in hexadecimal string format.
++ * You can use MWCryptRand::wasStrong() if you wish to know if the source used
++ * was cryptographically strong.
++ *
++ * @param $chars int the number of hex chars of random data to generate
++ * @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.
++ * @return String Hexadecimal random data
++ */
++ public static function generateHex( $chars, $forceStrong = false ) {
++ return self::singleton()->realGenerateHex( $chars, $forceStrong );
++ }
++
++}
+Index: mediawiki-1.15.5/includes/GlobalFunctions.php
+===================================================================
+--- mediawiki-1.15.5.orig/includes/GlobalFunctions.php 2012-05-16 14:59:43.000000000 +0200
++++ mediawiki-1.15.5/includes/GlobalFunctions.php 2012-05-16 14:59:43.000000000 +0200
+@@ -2650,6 +2650,33 @@
+ }
+
+ /**
++ * Override session_id before session startup if php's built-in
++ * session generation code is not secure.
++ */
++function wfFixSessionID() {
++ // If the cookie or session id is already set we already have a session and should abort
++ if ( isset( $_COOKIE[ session_name() ] ) || session_id() ) {
++ return;
++ }
++
++ // PHP's built-in session entropy is enabled if:
++ // - entropy_file is set or you're on Windows with php 5.3.3+
++ // - AND entropy_length is > 0
++ // We treat it as disabled if it doesn't have an entropy length of at least 32
++ $entropyEnabled = (
++ ( wfIsWindows() && version_compare( PHP_VERSION, '5.3.3', '>=' ) )
++ || ini_get( 'session.entropy_file' )
++ )
++ && intval( ini_get( 'session.entropy_length' ) ) >= 32;
++
++ // If built-in entropy is not enabled or not sufficient override php's built in session id generation code
++ if ( !$entropyEnabled ) {
++ wfDebug( __METHOD__ . ": PHP's built in entropy is disabled or not sufficient, overriding session id generation using our cryptrand source.\n" );
++ session_id( MWCryptRand::generateHex( 32 ) );
++ }
++}
++
++/**
+ * Initialise php session
+ */
+ function wfSetupSession() {
+Index: mediawiki-1.15.5/includes/User.php
+===================================================================
+--- mediawiki-1.15.5.orig/includes/User.php 2012-05-16 14:59:43.000000000 +0200
++++ mediawiki-1.15.5/includes/User.php 2012-05-16 14:59:43.000000000 +0200
+@@ -733,23 +733,20 @@
+ }
+
+ /**
+- * Return a random password. Sourced from mt_rand, so it's not particularly secure.
+- * @todo hash random numbers to improve security, like generateToken()
++ * Return a random password.
+ *
+ * @return \string New random password
+ */
+ static function randomPassword() {
+ global $wgMinimalPasswordLength;
+- $pwchars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz';
+- $l = strlen( $pwchars ) - 1;
+-
+- $pwlength = max( 7, $wgMinimalPasswordLength );
+- $digit = mt_rand(0, $pwlength - 1);
+- $np = '';
+- for ( $i = 0; $i < $pwlength; $i++ ) {
+- $np .= $i == $digit ? chr( mt_rand(48, 57) ) : $pwchars{ mt_rand(0, $l)};
+- }
+- return $np;
++ // Decide the final password length based on our min password length, stopping at a minimum of 10 chars
++ $length = max( 10, $wgMinimalPasswordLength );
++ // Multiply by 1.25 to get the number of hex characters we need
++ $length = $length * 1.25;
++ // Generate random hex chars
++ $hex = MWCryptRand::generateHex( $length );
++ // Convert from base 16 to base 32 to get a proper password like string
++ return wfBaseConvert( $hex, 16, 32 );
+ }
+
+ /**
+@@ -778,7 +775,7 @@
+ $this->mTouched = '0'; # Allow any pages to be cached
+ }
+
+- $this->setToken(); # Random
++ $this->mToken = null; // Don't run cryptographic functions till we need a token
+ $this->mEmailAuthenticated = null;
+ $this->mEmailToken = '';
+ $this->mEmailTokenExpires = null;
+@@ -847,14 +844,15 @@
+ $this->mId = $sId;
+ if ( !$this->loadFromId() ) {
+ # Not a valid ID, loadFromId has switched the object to anon for us
++ $this->loadDefaults();
+ return false;
+ }
+
+- if ( isset( $_SESSION['wsToken'] ) ) {
+- $passwordCorrect = $_SESSION['wsToken'] == $this->mToken;
++ if ( isset( $_SESSION['wsToken'] ) && $_SESSION['wsToken'] ) {
++ $passwordCorrect = $this->getToken( false ) === $_SESSION['wsToken'];
+ $from = 'session';
+ } else if ( isset( $_COOKIE["{$wgCookiePrefix}Token"] ) ) {
+- $passwordCorrect = $this->mToken == $_COOKIE["{$wgCookiePrefix}Token"];
++ $passwordCorrect = $this->getToken( false ) === $_COOKIE["{$wgCookiePrefix}Token"];
+ $from = 'cookie';
+ } else {
+ # No session or persistent login cookie
+@@ -930,6 +928,9 @@
+ $this->decodeOptions( $row->user_options );
+ $this->mTouched = wfTimestamp(TS_MW,$row->user_touched);
+ $this->mToken = $row->user_token;
++ if ( $this->mToken == '' ) {
++ $this->mToken = null;
++ }
+ $this->mEmailAuthenticated = wfTimestampOrNull( TS_MW, $row->user_email_authenticated );
+ $this->mEmailToken = $row->user_email_token;
+ $this->mEmailTokenExpires = wfTimestampOrNull( TS_MW, $row->user_email_token_expires );
+@@ -1739,10 +1740,14 @@
+
+ /**
+ * Get the user's current token.
++ * @param $forceCreation Force the generation of a new token if the user doesn't have one (default=true for backwards compatibility)
+ * @return \string Token
+ */
+- function getToken() {
++ function getToken( $forceCreation = true ) {
+ $this->load();
++ if ( !$this->mToken && $forceCreation ) {
++ $this->setToken();
++ }
+ return $this->mToken;
+ }
+
+@@ -1757,14 +1762,7 @@
+ global $wgSecretKey, $wgProxyKey;
+ $this->load();
+ if ( !$token ) {
+- if ( $wgSecretKey ) {
+- $key = $wgSecretKey;
+- } elseif ( $wgProxyKey ) {
+- $key = $wgProxyKey;
+- } else {
+- $key = microtime();
+- }
+- $this->mToken = md5( $key . mt_rand( 0, 0x7fffffff ) . wfWikiID() . $this->mId );
++ $this->mToken = MWCryptRand::generateHex( USER_TOKEN_LENGTH );
+ } else {
+ $this->mToken = $token;
+ }
+@@ -2347,6 +2345,14 @@
+ function setCookies() {
+ $this->load();
+ if ( 0 == $this->mId ) return;
++ if ( !$this->mToken ) {
++ // When token is empty or NULL generate a new one and then save it to the database
++ // This allows a wiki to re-secure itself after a leak of it's user table or $wgSecretKey
++ // Simply by setting every cell in the user_token column to NULL and letting them be
++ // regenerated as users log back into the wiki.
++ $this->setToken();
++ $this->saveSettings();
++ }
+ $session = array(
+ 'wsUserID' => $this->mId,
+ 'wsToken' => $this->mToken,
+@@ -2426,7 +2432,7 @@
+ 'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ),
+ 'user_options' => $this->encodeOptions(),
+ 'user_touched' => $dbw->timestamp($this->mTouched),
+- 'user_token' => $this->mToken,
++ 'user_token' => strval( $this->mToken ),
+ 'user_email_token' => $this->mEmailToken,
+ 'user_email_token_expires' => $dbw->timestampOrNull( $this->mEmailTokenExpires ),
+ ), array( /* WHERE */
+@@ -2488,7 +2494,7 @@
+ 'user_email_authenticated' => $dbw->timestampOrNull( $user->mEmailAuthenticated ),
+ 'user_real_name' => $user->mRealName,
+ 'user_options' => $user->encodeOptions(),
+- 'user_token' => $user->mToken,
++ 'user_token' => strval( $user->mToken ),
+ 'user_registration' => $dbw->timestamp( $user->mRegistration ),
+ 'user_editcount' => 0,
+ );
+@@ -2522,7 +2528,7 @@
+ 'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ),
+ 'user_real_name' => $this->mRealName,
+ 'user_options' => $this->encodeOptions(),
+- 'user_token' => $this->mToken,
++ 'user_token' => strval( $this->mToken ),
+ 'user_registration' => $dbw->timestamp( $this->mRegistration ),
+ 'user_editcount' => 0,
+ ), __METHOD__
+@@ -2772,7 +2778,7 @@
+ return EDIT_TOKEN_SUFFIX;
+ } else {
+ if( !isset( $_SESSION['wsEditToken'] ) ) {
+- $token = self::generateToken();
++ $token = MWCryptRand::generateHex( 32 );
+ $_SESSION['wsEditToken'] = $token;
+ } else {
+ $token = $_SESSION['wsEditToken'];
+@@ -2791,8 +2797,7 @@
+ * @return \string The new random token
+ */
+ public static function generateToken( $salt = '' ) {
+- $token = dechex( mt_rand() ) . dechex( mt_rand() );
+- return md5( $token . $salt );
++ return MWCryptRand::generateHex( 32 );
+ }
+
+ /**
+@@ -2885,7 +2890,7 @@
+ $now = time();
+ $expires = $now + 7 * 24 * 60 * 60;
+ $expiration = wfTimestamp( TS_MW, $expires );
+- $token = self::generateToken( $this->mId . $this->mEmail . $expires );
++ $token = MWCryptRand::generateHex( 32 );
+ $hash = md5( $token );
+ $this->load();
+ $this->mEmailToken = $hash;
+@@ -3327,7 +3332,7 @@
+
+ if( $wgPasswordSalt ) {
+ if ( $salt === false ) {
+- $salt = substr( wfGenerateToken(), 0, 8 );
++ $salt = MWCryptRand::generateHex( 8 );
+ }
+ return ':B:' . $salt . ':' . md5( $salt . '-' . md5( $password ) );
+ } else {
+Index: mediawiki-1.15.5/includes/specials/SpecialUserlogin.php
+===================================================================
+--- mediawiki-1.15.5.orig/includes/specials/SpecialUserlogin.php 2010-05-28 09:02:34.000000000 +0200
++++ mediawiki-1.15.5/includes/specials/SpecialUserlogin.php 2012-05-16 14:59:44.000000000 +0200
+@@ -1025,9 +1025,9 @@
+ */
+ public static function setLoginToken() {
+ global $wgRequest;
+- // Use User::generateToken() instead of $user->editToken()
++ // Generate a token directly instead of using $user->editToken()
+ // because the latter reuses $_SESSION['wsEditToken']
+- $wgRequest->setSessionData( 'wsLoginToken', User::generateToken() );
++ $wgRequest->setSessionData( 'wsLoginToken', MWCryptRand::generateHex( 32 ) );
+ }
+
+ /**
+@@ -1051,7 +1051,7 @@
+ */
+ public static function setCreateaccountToken() {
+ global $wgRequest;
+- $wgRequest->setSessionData( 'wsCreateaccountToken', User::generateToken() );
++ $wgRequest->setSessionData( 'wsCreateaccountToken', MWCryptRand::generateHex( 32 ) );
+ }
+
+ /**
Modified: mediawiki/sid-sec/debian/patches/add_rss_guid.patch
===================================================================
--- mediawiki/sid-sec/debian/patches/add_rss_guid.patch 2012-03-30 08:43:27 UTC (rev 310)
+++ mediawiki/sid-sec/debian/patches/add_rss_guid.patch 2012-05-16 13:03:46 UTC (rev 311)
@@ -1,3 +1,5 @@
+# DP: add unique IDs to RSS output
+
Index: mediawiki-1.15.2/includes/Feed.php
===================================================================
--- mediawiki-1.15.2.orig/includes/Feed.php 2008-11-18 18:11:14.000000000 -0600
Modified: mediawiki/sid-sec/debian/patches/debian_specific_config.patch
===================================================================
--- mediawiki/sid-sec/debian/patches/debian_specific_config.patch 2012-03-30 08:43:27 UTC (rev 310)
+++ mediawiki/sid-sec/debian/patches/debian_specific_config.patch 2012-05-16 13:03:46 UTC (rev 311)
@@ -1,3 +1,6 @@
+# DP: use debian-specific system-wide installation path
+# DP: and include mediawiki-extensions provided configuration
+
--- mediawiki-1.15.4.orig/config/index.php
+++ mediawiki-1.15.4/config/index.php
@@ -28,7 +28,6 @@
Modified: mediawiki/sid-sec/debian/patches/detect_invalid_titles.patch
===================================================================
--- mediawiki/sid-sec/debian/patches/detect_invalid_titles.patch 2012-03-30 08:43:27 UTC (rev 310)
+++ mediawiki/sid-sec/debian/patches/detect_invalid_titles.patch 2012-05-16 13:03:46 UTC (rev 311)
@@ -1,3 +1,5 @@
+# DP: detect invalid titles and mark them as such
+
Index: mediawiki-1.15.2/includes/specials/SpecialMostlinked.php
===================================================================
--- mediawiki-1.15.2.orig/includes/specials/SpecialMostlinked.php 2008-07-17 20:31:18.000000000 -0500
Modified: mediawiki/sid-sec/debian/patches/mimetypes.patch
===================================================================
--- mediawiki/sid-sec/debian/patches/mimetypes.patch 2012-03-30 08:43:27 UTC (rev 310)
+++ mediawiki/sid-sec/debian/patches/mimetypes.patch 2012-05-16 13:03:46 UTC (rev 311)
@@ -1,3 +1,5 @@
+# DP: use system-wide MIME types information
+
Index: mediawiki-1.15.2/includes/DefaultSettings.php
===================================================================
--- mediawiki-1.15.2.orig/includes/DefaultSettings.php 2010-03-15 12:01:58.000000000 -0500
Modified: mediawiki/sid-sec/debian/patches/series
===================================================================
--- mediawiki/sid-sec/debian/patches/series 2012-03-30 08:43:27 UTC (rev 310)
+++ mediawiki/sid-sec/debian/patches/series 2012-05-16 13:03:46 UTC (rev 311)
@@ -20,3 +20,4 @@
fix-blacklist.patch
php54.patch
CVE-2012-1582.patch
+CVE-2012-1581.patch
Modified: mediawiki/sid-sec/debian/patches/texvc_location.patch
===================================================================
--- mediawiki/sid-sec/debian/patches/texvc_location.patch 2012-03-30 08:43:27 UTC (rev 310)
+++ mediawiki/sid-sec/debian/patches/texvc_location.patch 2012-05-16 13:03:46 UTC (rev 311)
@@ -1,3 +1,5 @@
+# DP: texvc is installed system-wide
+
Index: mediawiki-1.15.2/includes/DefaultSettings.php
===================================================================
--- mediawiki-1.15.2.orig/includes/DefaultSettings.php 2010-03-08 16:52:50.000000000 -0600
Modified: mediawiki/sid-sec/debian/po/da.po
===================================================================
--- mediawiki/sid-sec/debian/po/da.po 2012-03-30 08:43:27 UTC (rev 310)
+++ mediawiki/sid-sec/debian/po/da.po 2012-05-16 13:03:46 UTC (rev 311)
@@ -11,6 +11,7 @@
"PO-Revision-Date: 2011-05-24 18:30+01:00\n"
"Last-Translator: Joe Hansen <joedalton2 at yahoo.dk>\n"
"Language-Team: Danish <debian-l10n-danish at lists.debian.org>\n"
+"Language: da\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
Modified: mediawiki/sid-sec/debian/watch
===================================================================
--- mediawiki/sid-sec/debian/watch 2012-03-30 08:43:27 UTC (rev 310)
+++ mediawiki/sid-sec/debian/watch 2012-05-16 13:03:46 UTC (rev 311)
@@ -1,11 +1,2 @@
-# Example watch control file for uscan
-# Rename this file to "watch" and then you can run the "uscan" command
-# to check for upstream updates and more.
-# See uscan(1) for format
-
-# Compulsory line, this is a version 3 file
version=3
-
-# Uncomment to examine a Webserver directory
http://www.mediawiki.org/wiki/Download http://download.wikimedia.org/mediawiki/.*/mediawiki-(.*).tar.gz
-
More information about the Pkg-mediawiki-commits
mailing list