Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15385661
D8272.id19680.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
8 KB
Referenced Files
None
Subscribers
None
D8272.id19680.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D8272: Modernize VCS password storage to use shared hash infrastructure
Attached
Detach File
Event Timeline
Log In to Comment