Page MenuHomePhabricator

D8272.id19680.diff
No OneTemporary

D8272.id19680.diff

diff --git a/resources/sql/autopatches/20140218.passwords.3.vcsextend.sql b/resources/sql/autopatches/20140218.passwords.3.vcsextend.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20140218.passwords.3.vcsextend.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_repository.repository_vcspassword
+ CHANGE passwordHash passwordHash VARCHAR(128) COLLATE utf8_bin NOT NULL;
diff --git a/resources/sql/autopatches/20140218.passwords.4.vcs.php b/resources/sql/autopatches/20140218.passwords.4.vcs.php
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20140218.passwords.4.vcs.php
@@ -0,0 +1,27 @@
+<?php
+
+$table = new PhabricatorRepositoryVCSPassword();
+$conn_w = $table->establishConnection('w');
+
+echo "Upgrading password hashing for VCS passwords.\n";
+
+$best_hasher = PhabricatorPasswordHasher::getBestHasher();
+foreach (new LiskMigrationIterator($table) as $password) {
+ $id = $password->getID();
+
+ echo "Migrating VCS password {$id}...\n";
+
+ $input_hash = $password->getPasswordHash();
+ $input_envelope = new PhutilOpaqueEnvelope($input_hash);
+
+ $storage_hash = $best_hasher->getPasswordHashForStorage($input_envelope);
+
+ queryfx(
+ $conn_w,
+ 'UPDATE %T SET passwordHash = %s WHERE id = %d',
+ $table->getTableName(),
+ $storage_hash->openEnvelope(),
+ $id);
+}
+
+echo "Done.\n";
diff --git a/src/applications/diffusion/controller/DiffusionServeController.php b/src/applications/diffusion/controller/DiffusionServeController.php
--- a/src/applications/diffusion/controller/DiffusionServeController.php
+++ b/src/applications/diffusion/controller/DiffusionServeController.php
@@ -426,6 +426,18 @@
return null;
}
+ // If the user's password is stored using a less-than-optimal hash, upgrade
+ // them to the strongest available hash.
+
+ $hash_envelope = new PhutilOpaqueEnvelope(
+ $password_entry->getPasswordHash());
+ if (PhabricatorPasswordHasher::canUpgradeHash($hash_envelope)) {
+ $password_entry->setPassword($password, $user);
+ $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
+ $password_entry->save();
+ unset($unguarded);
+ }
+
return $user;
}
diff --git a/src/applications/diffusion/panel/DiffusionSetPasswordPanel.php b/src/applications/diffusion/panel/DiffusionSetPasswordPanel.php
--- a/src/applications/diffusion/panel/DiffusionSetPasswordPanel.php
+++ b/src/applications/diffusion/panel/DiffusionSetPasswordPanel.php
@@ -165,6 +165,26 @@
}
}
+ $hash_envelope = new PhutilOpaqueEnvelope($vcspassword->getPasswordHash());
+
+ $form->appendChild(
+ id(new AphrontFormStaticControl())
+ ->setLabel(pht('Current Algorithm'))
+ ->setValue(
+ PhabricatorPasswordHasher::getCurrentAlgorithmName($hash_envelope)));
+
+ $form->appendChild(
+ id(new AphrontFormStaticControl())
+ ->setLabel(pht('Best Available Algorithm'))
+ ->setValue(PhabricatorPasswordHasher::getBestAlgorithmName()));
+
+ if (PhabricatorPasswordHasher::canUpgradeHash($hash_envelope)) {
+ $errors[] = pht(
+ 'The strength of your stored VCS password hash can be upgraded. '.
+ 'To upgrade, either: use the password to authenticate with a '.
+ 'repository; or change your password.');
+ }
+
$object_box = id(new PHUIObjectBoxView())
->setHeaderText($title)
->setForm($form)
diff --git a/src/applications/repository/storage/PhabricatorRepositoryVCSPassword.php b/src/applications/repository/storage/PhabricatorRepositoryVCSPassword.php
--- a/src/applications/repository/storage/PhabricatorRepositoryVCSPassword.php
+++ b/src/applications/repository/storage/PhabricatorRepositoryVCSPassword.php
@@ -9,26 +9,38 @@
public function setPassword(
PhutilOpaqueEnvelope $password,
PhabricatorUser $user) {
- return $this->setPasswordHash($this->hashPassword($password, $user));
+ $hash_envelope = $this->hashPassword($password, $user);
+ return $this->setPasswordHash($hash_envelope->openEnvelope());
}
public function comparePassword(
PhutilOpaqueEnvelope $password,
PhabricatorUser $user) {
- $hash = $this->hashPassword($password, $user);
- return ($hash == $this->getPasswordHash());
+ return PhabricatorPasswordHasher::comparePassword(
+ $this->getPasswordHashInput($password, $user),
+ new PhutilOpaqueEnvelope($this->getPasswordHash()));
}
- private function hashPassword(
+ private function getPasswordHashInput(
PhutilOpaqueEnvelope $password,
PhabricatorUser $user) {
-
if ($user->getPHID() != $this->getUserPHID()) {
throw new Exception("User does not match password user PHID!");
}
- return PhabricatorHash::digestPassword($password, $user->getPHID());
+ $raw_input = PhabricatorHash::digestPassword($password, $user->getPHID());
+ return new PhutilOpaqueEnvelope($raw_input);
+ }
+
+ private function hashPassword(
+ PhutilOpaqueEnvelope $password,
+ PhabricatorUser $user) {
+
+ $input_envelope = $this->getPasswordHashInput($password, $user);
+
+ $best_hasher = PhabricatorPasswordHasher::getBestHasher();
+ return $best_hasher->getPasswordHashForStorage($input_envelope);
}
}
diff --git a/src/applications/settings/panel/PhabricatorSettingsPanelPassword.php b/src/applications/settings/panel/PhabricatorSettingsPanelPassword.php
--- a/src/applications/settings/panel/PhabricatorSettingsPanelPassword.php
+++ b/src/applications/settings/panel/PhabricatorSettingsPanelPassword.php
@@ -114,7 +114,6 @@
$hash_envelope = new PhutilOpaqueEnvelope($user->getPasswordHash());
if (PhabricatorPasswordHasher::canUpgradeHash($hash_envelope)) {
- $best_hash = PhabricatorPasswordHasher::getBestHasher();
$errors[] = pht(
'The strength of your stored password hash can be upgraded. '.
'To upgrade, either: log out and log in using your password; or '.
@@ -157,34 +156,16 @@
id(new AphrontFormSubmitControl())
->setValue(pht('Change Password')));
- if (!strlen($user->getPasswordHash())) {
- $current_name = pht('None');
- } else {
- try {
- $current_hasher = PhabricatorPasswordHasher::getHasherForHash(
- new PhutilOpaqueEnvelope($user->getPasswordHash()));
- $current_name = $current_hasher->getHumanReadableName();
- } catch (Exception $ex) {
- $current_name = pht('Unknown');
- }
- }
-
$form->appendChild(
id(new AphrontFormStaticControl())
->setLabel(pht('Current Algorithm'))
- ->setValue($current_name));
-
- try {
- $best_hasher = PhabricatorPasswordHasher::getBestHasher();
- $best_name = $best_hasher->getHumanReadableName();
- } catch (Exception $ex) {
- $best_name = pht('Unknown');
- }
+ ->setValue(PhabricatorPasswordHasher::getCurrentAlgorithmName(
+ new PhutilOpaqueEnvelope($user->getPasswordHash()))));
$form->appendChild(
id(new AphrontFormStaticControl())
->setLabel(pht('Best Available Algorithm'))
- ->setValue($best_name));
+ ->setValue(PhabricatorPasswordHasher::getBestAlgorithmName()));
$form_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Change Password'))
diff --git a/src/infrastructure/util/password/PhabricatorPasswordHasher.php b/src/infrastructure/util/password/PhabricatorPasswordHasher.php
--- a/src/infrastructure/util/password/PhabricatorPasswordHasher.php
+++ b/src/infrastructure/util/password/PhabricatorPasswordHasher.php
@@ -385,4 +385,40 @@
return $hasher->verifyPassword($password, $parts['hash']);
}
+
+ /**
+ * Get the human-readable algorithm name for a given hash.
+ *
+ * @param PhutilOpaqueEnvelope Storage hash.
+ * @return string Human-readable algorithm name.
+ */
+ public static function getCurrentAlgorithmName(PhutilOpaqueEnvelope $hash) {
+ $raw_hash = $hash->openEnvelope();
+ if (!strlen($raw_hash)) {
+ return pht('None');
+ }
+
+ try {
+ $current_hasher = PhabricatorPasswordHasher::getHasherForHash($hash);
+ return $current_hasher->getHumanReadableName();
+ } catch (Exception $ex) {
+ return pht('Unknown');
+ }
+ }
+
+
+ /**
+ * Get the human-readable algorithm name for the best available hash.
+ *
+ * @return string Human-readable name for best hash.
+ */
+ public static function getBestAlgorithmName() {
+ try {
+ $best_hasher = PhabricatorPasswordHasher::getBestHasher();
+ return $best_hasher->getHumanReadableName();
+ } catch (Exception $ex) {
+ return pht('Unknown');
+ }
+ }
+
}

File Metadata

Mime Type
text/plain
Expires
Sat, Mar 15, 11:05 PM (1 w, 2 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7704357
Default Alt Text
D8272.id19680.diff (8 KB)

Event Timeline