Changeset View
Changeset View
Standalone View
Standalone View
src/applications/people/storage/PhabricatorUser.php
Show First 20 Lines • Show All 106 Lines • ▼ Show 20 Lines | if (!$this->getPHID()) { | ||||
throw new Exception( | throw new Exception( | ||||
"You can not set a password for an unsaved user because their PHID ". | "You can not set a password for an unsaved user because their PHID ". | ||||
"is a salt component in the password hash."); | "is a salt component in the password hash."); | ||||
} | } | ||||
if (!strlen($envelope->openEnvelope())) { | if (!strlen($envelope->openEnvelope())) { | ||||
$this->setPasswordHash(''); | $this->setPasswordHash(''); | ||||
} else { | } else { | ||||
$this->setPasswordSalt(md5(mt_rand())); | $this->setPasswordSalt(md5(Filesystem::readRandomBytes(32))); | ||||
$hash = $this->hashPassword($envelope); | $hash = $this->hashPassword($envelope); | ||||
$this->setPasswordHash($hash); | $this->setPasswordHash($hash->openEnvelope()); | ||||
} | } | ||||
return $this; | return $this; | ||||
} | } | ||||
// To satisfy PhutilPerson. | // To satisfy PhutilPerson. | ||||
public function getSex() { | public function getSex() { | ||||
return $this->sex; | return $this->sex; | ||||
} | } | ||||
Show All 39 Lines | final class PhabricatorUser | ||||
public function comparePassword(PhutilOpaqueEnvelope $envelope) { | public function comparePassword(PhutilOpaqueEnvelope $envelope) { | ||||
if (!strlen($envelope->openEnvelope())) { | if (!strlen($envelope->openEnvelope())) { | ||||
return false; | return false; | ||||
} | } | ||||
if (!strlen($this->getPasswordHash())) { | if (!strlen($this->getPasswordHash())) { | ||||
return false; | return false; | ||||
} | } | ||||
$password_hash = $this->hashPassword($envelope); | |||||
return ($password_hash === $this->getPasswordHash()); | return PhabricatorPasswordHasher::comparePassword( | ||||
$this->getPasswordHashInput($envelope), | |||||
// TODO: For now, we need to add a prefix. | |||||
new PhutilOpaqueEnvelope('md5:'.$this->getPasswordHash())); | |||||
} | } | ||||
private function hashPassword(PhutilOpaqueEnvelope $envelope) { | private function getPasswordHashInput(PhutilOpaqueEnvelope $password) { | ||||
$hash = $this->getUsername(). | $input = | ||||
$envelope->openEnvelope(). | $this->getUsername(). | ||||
$password->openEnvelope(). | |||||
$this->getPHID(). | $this->getPHID(). | ||||
$this->getPasswordSalt(); | $this->getPasswordSalt(); | ||||
for ($ii = 0; $ii < 1000; $ii++) { | |||||
$hash = md5($hash); | return new PhutilOpaqueEnvelope($input); | ||||
} | } | ||||
return $hash; | |||||
private function hashPassword(PhutilOpaqueEnvelope $password) { | |||||
$hasher = PhabricatorPasswordHasher::getBestHasher(); | |||||
$input_envelope = $this->getPasswordHashInput($password); | |||||
$output_envelope = $hasher->getPasswordHashForStorage($input_envelope); | |||||
// TODO: For now, we need to strip the type prefix until we can upgrade | |||||
// the storage. | |||||
$raw_output = $output_envelope->openEnvelope(); | |||||
$raw_output = substr($raw_output, strlen('md5:')); | |||||
return new PhutilOpaqueEnvelope($raw_output); | |||||
} | } | ||||
const CSRF_CYCLE_FREQUENCY = 3600; | const CSRF_CYCLE_FREQUENCY = 3600; | ||||
const CSRF_SALT_LENGTH = 8; | const CSRF_SALT_LENGTH = 8; | ||||
const CSRF_TOKEN_LENGTH = 16; | const CSRF_TOKEN_LENGTH = 16; | ||||
const CSRF_BREACH_PREFIX = 'B@'; | const CSRF_BREACH_PREFIX = 'B@'; | ||||
const EMAIL_CYCLE_FREQUENCY = 86400; | const EMAIL_CYCLE_FREQUENCY = 86400; | ||||
▲ Show 20 Lines • Show All 565 Lines • Show Last 20 Lines |