Here is a patch I developed to store a hash of the master password on disk, and then display if the current password matches. (One of the things on the feature request list...)
Only visable in advanced options, but if the hash is stored when prompting for the password on the cool key, it won't accept a bad password. The advanced options accepts "bad" passwords, just displays a message about not matching the hash on disk and allows you to overwrite the value.
Looks like the forum is murdering the patch... send me an email and I can send the patch somewhere else.
Index: passwordmaker/chrome/content/passwdmaker/advanced-options.xul
===================================================================
--- passwordmaker.orig/chrome/content/passwdmaker/advanced-options.xul 2007-06-13 16:55:07.000000000 -0500
+++ passwordmaker/chrome/content/passwdmaker/advanced-options.xul 2007-06-13 18:06:20.000000000 -0500
@@ -131,6 +131,11 @@
accesskey="N"
tooltip="Download settings now"
oncommand="onUpdownload('download', true);"/>
+
+<command id="setHashedMasterPassword"
+ label="Set Hashed Master Password"
+ tooltip="Store Hashed Master Password to disk"
+ oncommand="onSetHashedMasterPassword();"/>
<keyset>
<key id="esc-key" keycode="VK_ESCAPE" command="closeCmd"/>
@@ -280,7 +285,13 @@
<row observes="isFolderCmd" align="center">
<hbox align="center"><button command="clipboardCopyCmd"/></hbox>
<hbox align="center"><button command="closeCmd"/></hbox>
- </row>
+ </row>
+ <row observes="isFolderCmd" align="center"> <hbox align="center">
+ <label id="passwordMatches" tooltip="" />
+ </hbox></row>
+ <row observes="isFolderCmd" align="center"> <hbox align="center">
+ <button command="setHashedMasterPassword"/>
+ </hbox></row>
</rows>
</grid>
</hbox>
Index: passwordmaker/chrome/content/passwdmaker/mpw.js
===================================================================
--- passwordmaker.orig/chrome/content/passwdmaker/mpw.js 2007-06-13 16:32:11.000000000 -0500
+++ passwordmaker/chrome/content/passwdmaker/mpw.js 2007-06-13 18:19:02.000000000 -0500
@@ -83,6 +83,19 @@
}
},
+ calculateMasterPasswordHash : function (clearTextMasterPassword, salt) {
+ var hash = PasswordMaker_SHA256.rstr_sha256(clearTextMasterPassword, salt);
+ return PasswordMaker_HashUtils.rstr2any(hash, passwordMaker.DEFAULT_CHARSET);
+ },
+
+ storeMasterPasswordHashedVal : function(clearTextMasterPassword) {
+ var salt = this._makeKey32();
+ PwdMkr_RDFUtils.updateTarget(passwordMaker.globalSettingsSubjectRes, passwordMaker.masterPasswordSaltRes, salt);
+
+ var hashed = this.calculateMasterPasswordHash(clearTextMasterPassword, salt);
+ PwdMkr_RDFUtils.updateTarget(passwordMaker.globalSettingsSubjectRes, passwordMaker.masterPasswordHashedRes, hashed);
+ },
+
encrypt : function(clearText) {
if (clearText == null || clearText == "")
return null;
@@ -101,9 +114,13 @@
var params = {inn:{passwordStorageLBValue:
PwdMkr_RDFUtils.getTarget(passwordMaker.globalSettingsSubjectRes, passwordMaker.masterPasswordStoragePredicateRes),
passwordMaker:passwordMaker,
- settings:passwordMaker.readAccountSettings(subjectRes)},
+ settings:passwordMaker.readAccountSettings(subjectRes),
+ salt:PwdMkr_RDFUtils.getTarget(passwordMaker.globalSettingsSubjectRes, passwordMaker.masterPasswordSaltRes),
+ hashed:PwdMkr_RDFUtils.getTarget(passwordMaker.globalSettingsSubjectRes, passwordMaker.masterPasswordHashedRes),
+ hashFunction:this.calculateMasterPasswordHash,
+ },
out:null};
-
+
// Return null or a decrypted password
window.openDialog("chrome://passwdmaker/chrome/passwordprompt.xul",
"", "chrome, dialog, modal, resizable=yes", params).focus();
@@ -114,4 +131,4 @@
}
return null;
}
-};
\ No newline at end of file
+};
Index: passwordmaker/chrome/content/passwdmaker/passwdmaker.js
===================================================================
--- passwordmaker.orig/chrome/content/passwdmaker/passwdmaker.js 2007-06-13 16:30:05.000000000 -0500
+++ passwordmaker/chrome/content/passwdmaker/passwdmaker.js 2007-06-13 16:49:17.000000000 -0500
@@ -46,6 +46,8 @@
masterPasswordPredicateRes : null, //http://passwordmaker.mozdev.org/rdf#masterPassword
masterPasswordKeyPredicateRes : null,
masterPasswordStoragePredicateRes : null,
+ masterPasswordSaltRes : null,
+ masterPasswordHashedRes : null,
maskMasterPasswordPredicateRes : null,
autoClearClipboardPredicateRes : null,
autoClearClipboardSecondsPredicateRes : null,
@@ -129,6 +131,8 @@
this.masterPasswordPredicateRes = PwdMkr_RDFUtils.makePredicate("masterPassword");
this.masterPasswordKeyPredicateRes = PwdMkr_RDFUtils.makePredicate("masterPasswordKey");
this.masterPasswordStoragePredicateRes = PwdMkr_RDFUtils.makePredicate("masterPasswordStorage");
+ this.masterPasswordSaltRes = PwdMkr_RDFUtils.makePredicate("masterPasswordSalt");
+ this.masterPasswordHashedRes = PwdMkr_RDFUtils.makePredicate("masterPasswordHashed");
this.maskMasterPasswordPredicateRes = PwdMkr_RDFUtils.makePredicate("maskMasterPassword");
this.autoClearClipboardPredicateRes = PwdMkr_RDFUtils.makePredicate("autoClearClipboard");
this.autoClearClipboardSecondsPredicateRes = PwdMkr_RDFUtils.makePredicate("autoClearClipboardSeconds");
@@ -1372,4 +1376,4 @@
isUsingPFF : function() {
return PasswordMakerPrefsWrapper.getChar("settings") == this.PFF;
}
-};
\ No newline at end of file
+};
Index: passwordmaker/chrome/content/passwdmaker/passwdmakerOverlay.js
===================================================================
--- passwordmaker.orig/chrome/content/passwdmaker/passwdmakerOverlay.js 2007-06-13 17:50:37.000000000 -0500
+++ passwordmaker/chrome/content/passwdmaker/passwdmakerOverlay.js 2007-06-13 18:05:03.000000000 -0500
@@ -20,7 +20,7 @@
**/
// References to the UI elements
-var passwordMaster, passwordMaster2, passwordGenerated, passwordStorageLB, passwordMaker,
+var passwordMaster, passwordMaster2, passwordGenerated, passwordStorageLB, passwordMaker, passwordMatches,
createTreeFolderBtn, newAccountCmd, usingURL, confirmMPWCB;
var NONE_CLICK_ACCOUNT_SETTINGS="[none - click account settings to set]";
@@ -39,6 +39,7 @@
passwordMaster = document.getElementById("passwordMaster");
passwordMaster2 = document.getElementById("passwordMaster2");
passwordGenerated = document.getElementById("passwordGenerated");
+ passwordMatches = document.getElementById("passwordMatches");
passwordStorageLB = document.getElementById("passwordStorageLB");
createTreeFolderBtn = document.getElementById("createTreeFolderBtn");
newAccountCmd = document.getElementById("newAccountCmd");
@@ -163,6 +164,7 @@
}
function generatepassword() {
+ passwordMatches.value = "";
if (passwordMaster.value == "") {
passwordGenerated.value = passwordMaker.ENTER_MPW;
return;
@@ -184,6 +186,28 @@
cells[13].getAttribute("label"), // charset
cells[14].getAttribute("label"), // prefix
cells[15].getAttribute("label")); // suffix
+
+ if (passwordMatches) {
+ var salt = PwdMkr_RDFUtils.getTarget(passwordMaker.globalSettingsSubjectRes, passwordMaker.masterPasswordSaltRes);
+ var hash = PwdMkr_RDFUtils.getTarget(passwordMaker.globalSettingsSubjectRes, passwordMaker.masterPasswordHashedRes);
+ var newHash = PwdMkr_MPW.calculateMasterPasswordHash(passwordMaster.value, salt);
+
+ if (hash) {
+ if (hash == newHash) {
+ passwordMatches.value = "Master Password matches stored hash value";
+ } else {
+ passwordMatches.value = "Master Password does not match stored hash.";
+ }
+ } else {
+ passwordMatches.value = "Master Password hash is not stored on disk."
+ }
+ }
+}
+
+function onSetHashedMasterPassword() {
+ if (passwordMaster.value == passwordMaster2.value) {
+ PwdMkr_MPW.storeMasterPasswordHashedVal(passwordMaster.value);
+ }
}
function importSettings() {
@@ -336,4 +360,4 @@
passwordStorageLB.value = previousPasswordStorageLBValue = passwordMaker._getLiteral(passwordMaker.globalSettingsSubjectRes, passwordMaker.masterPasswordStoragePredicateRes);
_update(quiet);
generatepassword();
-}
\ No newline at end of file
+}
Index: passwordmaker/chrome/content/passwdmaker/passwordprompt.js
===================================================================
--- passwordmaker.orig/chrome/content/passwdmaker/passwordprompt.js 2007-06-13 16:42:30.000000000 -0500
+++ passwordmaker/chrome/content/passwdmaker/passwordprompt.js 2007-06-13 18:18:59.000000000 -0500
@@ -18,7 +18,7 @@
along with this library; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
**/
-var passwordMaster, passwordMaster2, passwordStorageLB, confirmationRow,
+var passwordMaster, passwordMaster2, passwordStorageLB, confirmationRow, passwordSalt, passwordHashedVal, hashFunction,
passwordMaker; // do not make local to onOK()--used in onPasswordStorageLBChanged();
function onOK() {
@@ -28,6 +28,16 @@
passwordMaster.focus();
return false;
}
+ else if (passwordHashedVal) {
+ // check if the entered password matches the hashed value
+ var newHash = hashFunction(passwordMaster.value, passwordSalt);
+ if (newHash != passwordHashedVal) {
+ passwordMaker.prompts.alert(this, "PasswordMaker", "The master password is not correct.");
+ passwordMaster.value = "";
+ passwordMaster.focus();
+ return false;
+ }
+ }
else if (passwordMaster.value == "") {
// mpw can't be empty
passwordMaker.prompts.alert(this, "PasswordMaker", "The master password cannot be empty.");
@@ -61,6 +71,14 @@
confirmationRow.hidden =
passwordMaker._getLiteral(passwordMaker.globalSettingsSubjectRes, passwordMaker.confirmMPWPredicateRes) != "true";
+ passwordSalt = window.arguments[0].inn.salt;
+ passwordHashedVal = window.arguments[0].inn.hashed;
+ hashFunction = window.arguments[0].inn.hashFunction;
+
+ if (passwordHashedVal) {
+ confirmationRow.hidden = true;
+ }
+
var settings = window.arguments[0].inn.settings;
if (settings) {
var accountsTree = document.getElementById("accountsTree");