X-Git-Url: https://git.cyclocoop.org/%27.WWW_URL.%27admin/?a=blobdiff_plain;f=includes%2Fauth%2FLocalPasswordPrimaryAuthenticationProvider.php;h=86a6aae0aba4e31070ccfed37544ef5f7e9c9940;hb=64f08b23ee6f29cd38289f8d48bad7469d248107;hp=bbc6e8d3b52c9173233b4009e2d18a69f120ca2f;hpb=abb4d29b54c1bc4b4fb620f1124559ead13a074e;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/auth/LocalPasswordPrimaryAuthenticationProvider.php b/includes/auth/LocalPasswordPrimaryAuthenticationProvider.php index bbc6e8d3b5..86a6aae0ab 100644 --- a/includes/auth/LocalPasswordPrimaryAuthenticationProvider.php +++ b/includes/auth/LocalPasswordPrimaryAuthenticationProvider.php @@ -88,22 +88,26 @@ class LocalPasswordPrimaryAuthenticationProvider 'user_id', 'user_password', 'user_password_expires', ]; - $dbw = wfGetDB( DB_MASTER ); - $row = $dbw->selectRow( + $dbr = wfGetDB( DB_REPLICA ); + $row = $dbr->selectRow( 'user', $fields, [ 'user_name' => $username ], __METHOD__ ); if ( !$row ) { - return AuthenticationResponse::newAbstain(); + // Do not reveal whether its bad username or + // bad password to prevent username enumeration + // on private wikis. (T134100) + return $this->failResponse( $req ); } + $oldRow = clone $row; // Check for *really* old password hashes that don't even have a type // The old hash format was just an md5 hex hash, with no type information if ( preg_match( '/^[0-9a-f]{32}$/', $row->user_password ) ) { if ( $this->config->get( 'PasswordSalt' ) ) { - $row->user_password = ":A:{$row->user_id}:{$row->user_password}"; + $row->user_password = ":B:{$row->user_id}:{$row->user_password}"; } else { $row->user_password = ":A:{$row->user_password}"; } @@ -131,13 +135,19 @@ class LocalPasswordPrimaryAuthenticationProvider // @codeCoverageIgnoreStart if ( $this->getPasswordFactory()->needsUpdate( $pwhash ) ) { - $pwhash = $this->getPasswordFactory()->newFromPlaintext( $req->password ); - $dbw->update( - 'user', - [ 'user_password' => $pwhash->toString() ], - [ 'user_id' => $row->user_id ], - __METHOD__ - ); + $newHash = $this->getPasswordFactory()->newFromPlaintext( $req->password ); + \DeferredUpdates::addCallableUpdate( function () use ( $newHash, $oldRow ) { + $dbw = wfGetDB( DB_MASTER ); + $dbw->update( + 'user', + [ 'user_password' => $newHash->toString() ], + [ + 'user_id' => $oldRow->user_id, + 'user_password' => $oldRow->user_password + ], + __METHOD__ + ); + } ); } // @codeCoverageIgnoreEnd @@ -152,8 +162,8 @@ class LocalPasswordPrimaryAuthenticationProvider return false; } - $dbw = wfGetDB( DB_MASTER ); - $row = $dbw->selectRow( + $dbr = wfGetDB( DB_REPLICA ); + $row = $dbr->selectRow( 'user', [ 'user_password' ], [ 'user_name' => $username ], @@ -235,14 +245,14 @@ class LocalPasswordPrimaryAuthenticationProvider $pwhash = null; - if ( $this->loginOnly ) { - $pwhash = $this->getPasswordFactory()->newFromCiphertext( null ); - $expiry = null; - // @codeCoverageIgnoreStart - } elseif ( get_class( $req ) === PasswordAuthenticationRequest::class ) { - // @codeCoverageIgnoreEnd - $pwhash = $this->getPasswordFactory()->newFromPlaintext( $req->password ); - $expiry = $this->getNewPasswordExpiry( $username ); + if ( get_class( $req ) === PasswordAuthenticationRequest::class ) { + if ( $this->loginOnly ) { + $pwhash = $this->getPasswordFactory()->newFromCiphertext( null ); + $expiry = null; + } else { + $pwhash = $this->getPasswordFactory()->newFromPlaintext( $req->password ); + $expiry = $this->getNewPasswordExpiry( $username ); + } } if ( $pwhash ) { @@ -290,7 +300,7 @@ class LocalPasswordPrimaryAuthenticationProvider // Nothing we can do besides claim it, because the user isn't in // the DB yet if ( $req->username !== $user->getName() ) { - $req = clone( $req ); + $req = clone $req; $req->username = $user->getName(); } $ret = AuthenticationResponse::newPass( $req->username );