diff options
author | Pierre Schmitz <pierre@archlinux.de> | 2010-04-07 04:33:59 +0200 |
---|---|---|
committer | Pierre Schmitz <pierre@archlinux.de> | 2010-04-07 04:33:59 +0200 |
commit | 03e45da6f96fd9aa411e015554f559b3ee9a61da (patch) | |
tree | 4936acbffcd395763235288a09bfd5576d16d3ff /includes | |
parent | 6f5403ca6e8561c3dcd19284f86b4c3c8dd715ff (diff) |
update to MediaWiki 1.15.3
Diffstat (limited to 'includes')
-rw-r--r-- | includes/BagOStuff.php | 17 | ||||
-rw-r--r-- | includes/DefaultSettings.php | 4 | ||||
-rw-r--r-- | includes/User.php | 6 | ||||
-rw-r--r-- | includes/api/ApiLogin.php | 18 | ||||
-rw-r--r-- | includes/specials/SpecialUserlogin.php | 63 | ||||
-rw-r--r-- | includes/templates/Userlogin.php | 1 |
6 files changed, 96 insertions, 13 deletions
diff --git a/includes/BagOStuff.php b/includes/BagOStuff.php index 572dca6c..ffa8a0bb 100644 --- a/includes/BagOStuff.php +++ b/includes/BagOStuff.php @@ -437,10 +437,19 @@ class MediaWikiBagOStuff extends SqlBagOStuff { var $lb, $db; function _getDB(){ - if ( !isset( $this->lb ) ) { - $this->lb = wfGetLBFactory()->newMainLB(); - $this->db = $this->lb->getConnection( DB_MASTER ); - $this->db->clearFlag( DBO_TRX ); + global $wgDBtype; + if ( !isset( $this->db ) ) { + /* We must keep a separate connection to MySQL in order to avoid deadlocks + * However, SQLite has an opposite behaviour. + * @todo Investigate behaviour for other databases + */ + if ( $wgDBtype == 'sqlite' ) { + $this->db = wfGetDB( DB_MASTER ); + } else { + $this->lb = wfGetLBFactory()->newMainLB(); + $this->db = $this->lb->getConnection( DB_MASTER ); + $this->db->clearFlag( DBO_TRX ); + } } return $this->db; } diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index 4ac466c8..fab77806 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -33,7 +33,7 @@ if ( !defined( 'MW_PHP4' ) ) { } /** MediaWiki version number */ -$wgVersion = '1.15.2'; +$wgVersion = '1.15.3'; /** Name of the site. It must be changed in LocalSettings.php */ $wgSitename = 'MediaWiki'; @@ -2561,7 +2561,7 @@ $wgAutoloadClasses = array(); * $wgExtensionCredits[$type][] = array( * 'name' => 'Example extension', * 'version' => 1.9, - * 'svn-revision' => '$LastChangedRevision: 63438 $', + * 'svn-revision' => '$LastChangedRevision: 64681 $', * 'author' => 'Foo Barstein', * 'url' => 'http://wwww.example.com/Example%20Extension/', * 'description' => 'An example extension', diff --git a/includes/User.php b/includes/User.php index cc861ad4..2ccc695b 100644 --- a/includes/User.php +++ b/includes/User.php @@ -2771,7 +2771,7 @@ class User { return EDIT_TOKEN_SUFFIX; } else { if( !isset( $_SESSION['wsEditToken'] ) ) { - $token = $this->generateToken(); + $token = self::generateToken(); $_SESSION['wsEditToken'] = $token; } else { $token = $_SESSION['wsEditToken']; @@ -2789,7 +2789,7 @@ class User { * @param $salt \string Optional salt value * @return \string The new random token */ - function generateToken( $salt = '' ) { + public static function generateToken( $salt = '' ) { $token = dechex( mt_rand() ) . dechex( mt_rand() ); return md5( $token . $salt ); } @@ -2884,7 +2884,7 @@ class User { $now = time(); $expires = $now + 7 * 24 * 60 * 60; $expiration = wfTimestamp( TS_MW, $expires ); - $token = $this->generateToken( $this->mId . $this->mEmail . $expires ); + $token = self::generateToken( $this->mId . $this->mEmail . $expires ); $hash = md5( $token ); $this->load(); $this->mEmailToken = $hash; diff --git a/includes/api/ApiLogin.php b/includes/api/ApiLogin.php index bc477e1d..1d2c3436 100644 --- a/includes/api/ApiLogin.php +++ b/includes/api/ApiLogin.php @@ -60,6 +60,7 @@ class ApiLogin extends ApiBase { 'wpName' => $params['name'], 'wpPassword' => $params['password'], 'wpDomain' => $params['domain'], + 'wpLoginToken' => $params['token'], 'wpRemember' => '' )); @@ -88,6 +89,15 @@ class ApiLogin extends ApiBase { $result['cookieprefix'] = $wgCookiePrefix; $result['sessionid'] = session_id(); break; + + case LoginForm::NEED_TOKEN: + $result['result'] = 'NeedToken'; + $result['token'] = $loginForm->getLoginToken(); + break; + + case LoginForm::WRONG_TOKEN: + $result['result'] = 'WrongToken'; + break; case LoginForm :: NO_NAME : $result['result'] = 'NoName'; @@ -133,7 +143,8 @@ class ApiLogin extends ApiBase { return array ( 'name' => null, 'password' => null, - 'domain' => null + 'domain' => null, + 'token' => null, ); } @@ -141,7 +152,8 @@ class ApiLogin extends ApiBase { return array ( 'name' => 'User Name', 'password' => 'Password', - 'domain' => 'Domain (optional)' + 'domain' => 'Domain (optional)', + 'token' => 'Login token obtained in first request', ); } @@ -162,6 +174,6 @@ class ApiLogin extends ApiBase { } public function getVersion() { - return __CLASS__ . ': $Id: ApiLogin.php 48091 2009-03-06 13:49:44Z catrope $'; + return __CLASS__ . ': $Id: ApiLogin.php 64680 2010-04-07 00:13:46Z tstarling $'; } } diff --git a/includes/specials/SpecialUserlogin.php b/includes/specials/SpecialUserlogin.php index b065bdd6..0f5f69b7 100644 --- a/includes/specials/SpecialUserlogin.php +++ b/includes/specials/SpecialUserlogin.php @@ -34,10 +34,14 @@ class LoginForm { const ABORTED = 8; const CREATE_BLOCKED = 9; const THROTTLED = 10; + const USER_BLOCKED = 11; + const NEED_TOKEN = 12; + const WRONG_TOKEN = 13; var $mName, $mPassword, $mRetype, $mReturnTo, $mCookieCheck, $mPosted; var $mAction, $mCreateaccount, $mCreateaccountMail, $mMailmypassword; var $mLoginattempt, $mRemember, $mEmail, $mDomain, $mLanguage, $mSkipCookieCheck; + var $mToken; /** * Constructor @@ -65,6 +69,7 @@ class LoginForm { $this->mRemember = $request->getCheck( 'wpRemember' ); $this->mLanguage = $request->getText( 'uselang' ); $this->mSkipCookieCheck = $request->getCheck( 'wpSkipCookieCheck' ); + $this->mToken = $request->getVal( 'wpLoginToken' ); if ( $wgRedirectOnLogin ) { $this->mReturnTo = $wgRedirectOnLogin; @@ -382,7 +387,22 @@ class LoginForm { if ( '' == $this->mName ) { return self::NO_NAME; } + + // We require a login token to prevent login CSRF + // Handle part of this before incrementing the throttle so + // token-less login attempts don't count towards the throttle + // but wrong-token attempts do. + // If the user doesn't have a login token yet, set one. + if ( !self::getLoginToken() ) { + self::setLoginToken(); + return self::NEED_TOKEN; + } + // If the user didn't pass a login token, tell them we need one + if ( !$this->mToken ) { + return self::NEED_TOKEN; + } + global $wgPasswordAttemptThrottle; $throttleCount=0; @@ -401,6 +421,11 @@ class LoginForm { return self::THROTTLED; } } + + // Validate the login token + if ( $this->mToken !== self::getLoginToken() ) { + return self::WRONG_TOKEN; + } // Load $wgUser now, and check to see if we're logging in as the same // name. This is necessary because loading $wgUser (say by calling @@ -532,6 +557,7 @@ class LoginForm { $wgUser->invalidateCache(); } $wgUser->setCookies(); + self::clearLoginToken(); // Reset the throttle $key = wfMemcKey( 'password-throttle', wfGetIP(), md5( $this->mName ) ); @@ -550,7 +576,11 @@ class LoginForm { return $this->cookieRedirectCheck( 'login' ); } break; - + + case self::NEED_TOKEN: + case self::WRONG_TOKEN: + $this->mainLoginForm( wfMsg( 'sessionfailure' ) ); + break; case self::NO_NAME: case self::ILLEGAL: $this->mainLoginForm( wfMsg( 'noname' ) ); @@ -881,6 +911,11 @@ class LoginForm { $template->set( 'canremember', ( $wgCookieExpiration > 0 ) ); $template->set( 'remember', $wgUser->getOption( 'rememberpassword' ) or $this->mRemember ); + if ( !self::getLoginToken() ) { + self::setLoginToken(); + } + $template->set( 'token', self::getLoginToken() ); + # Prepare language selection links as needed if( $wgLoginLanguageSelector ) { $template->set( 'languages', $this->makeLanguageSelector() ); @@ -929,6 +964,32 @@ class LoginForm { global $wgDisableCookieCheck, $wgRequest; return $wgDisableCookieCheck ? true : $wgRequest->checkSessionCookie(); } + + /** + * Get the login token from the current session + */ + public static function getLoginToken() { + global $wgRequest; + return $wgRequest->getSessionData( 'wsLoginToken' ); + } + + /** + * Generate a new login token and attach it to the current session + */ + public static function setLoginToken() { + global $wgRequest; + // Use User::generateToken() instead of $user->editToken() + // because the latter reuses $_SESSION['wsEditToken'] + $wgRequest->setSessionData( 'wsLoginToken', User::generateToken() ); + } + + /** + * Remove any login token attached to the current session + */ + public static function clearLoginToken() { + global $wgRequest; + $wgRequest->setSessionData( 'wsLoginToken', null ); + } /** * @private diff --git a/includes/templates/Userlogin.php b/includes/templates/Userlogin.php index 1caa7ea2..432d3003 100644 --- a/includes/templates/Userlogin.php +++ b/includes/templates/Userlogin.php @@ -87,6 +87,7 @@ class UserloginTemplate extends QuickTemplate { </tr> </table> <?php if( @$this->haveData( 'uselang' ) ) { ?><input type="hidden" name="uselang" value="<?php $this->text( 'uselang' ); ?>" /><?php } ?> +<?php if( @$this->haveData( 'token' ) ) { ?><input type="hidden" name="wpLoginToken" value="<?php $this->text( 'token' ); ?>" /><?php } ?> </form> </div> <div id="loginend"><?php $this->msgWiki( 'loginend' ); ?></div> |