Bug 1599233 - Import masterpass.jsm code from Valodim (Vincent Breitmoser). r=patrick DONTBUILD
authorKai Engert <kaie@kuix.de>
Wed, 27 Nov 2019 11:17:32 +0100
changeset 28273 01810b29d5ec858b90d01ce47999cccae993ae3e
parent 28272 4213d50b5bfcc46f65d4ac64903ff21ee0105e05
child 28274 5629275db993996f84626ca8ddbb5296fb42f8f5
push id16733
push userkaie@kuix.de
push dateWed, 27 Nov 2019 10:20:07 +0000
treeherdercomm-central@10abecc1ae80 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspatrick
bugs1599233
Bug 1599233 - Import masterpass.jsm code from Valodim (Vincent Breitmoser). r=patrick DONTBUILD
mail/extensions/openpgp/content/modules/core.jsm
mail/extensions/openpgp/content/modules/masterpass.jsm
--- a/mail/extensions/openpgp/content/modules/core.jsm
+++ b/mail/extensions/openpgp/content/modules/core.jsm
@@ -34,16 +34,17 @@ const getEnigmailDialog = EnigmailLazy.l
 const getEnigmailConfigure = EnigmailLazy.loader("enigmail/configure.jsm", "EnigmailConfigure");
 const getEnigmailApp = EnigmailLazy.loader("enigmail/app.jsm", "EnigmailApp");
 const getEnigmailKeyRefreshService = EnigmailLazy.loader("enigmail/keyRefreshService.jsm", "EnigmailKeyRefreshService");
 const getEnigmailKeyServer = EnigmailLazy.loader("enigmail/keyserver.jsm", "EnigmailKeyServer");
 const getEnigmailWksMimeHandler = EnigmailLazy.loader("enigmail/wksMimeHandler.jsm", "EnigmailWksMimeHandler");
 //const getEnigmailOverlays = EnigmailLazy.loader("enigmail/enigmailOverlays.jsm", "EnigmailOverlays");
 const getEnigmailSqlite = EnigmailLazy.loader("enigmail/sqliteDb.jsm", "EnigmailSqliteDb");
 const getEnigmailTimer = EnigmailLazy.loader("enigmail/timer.jsm", "EnigmailTimer");
+const getOpenPGPMasterpass = EnigmailLazy.loader("enigmail/masterpass.jsm", "OpenPGPMasterpass");
 const Services = ChromeUtils.import("resource://gre/modules/Services.jsm").Services;
 
 var EXPORTED_SYMBOLS = ["EnigmailCore"];
 
 // Interfaces
 const nsIEnvironment = Ci.nsIEnvironment;
 
 var gPreferredGpgPath = null;
@@ -84,16 +85,17 @@ var EnigmailCore = {
       logger.DEBUG(`core.jsm: startup.continueStartup(${type})\n`);
 
       try {
         let mimeEncrypt = getEnigmailMimeEncrypt();
         mimeEncrypt.startup(reason);
         //getEnigmailOverlays().startup();
         self.factories.push(new Factory(getEnigmailProtocolHandler()));
         self.factories.push(new Factory(mimeEncrypt.Handler));
+        getOpenPGPMasterpass().ensureMasterPassword();
       } catch (ex) {
         Services.console.logStringMessage("core.jsm: startup.continueStartup: error " + ex.message + "\n" + ex.stack + "\n");
         logger.DEBUG("core.jsm: startup.continueStartup: error " + ex.message + "\n" + ex.stack + "\n");
       }
     }
 
     getEnigmailVerify().registerContentTypeHandler();
     getEnigmailWksMimeHandler().registerContentTypeHandler();
new file mode 100644
--- /dev/null
+++ b/mail/extensions/openpgp/content/modules/masterpass.jsm
@@ -0,0 +1,80 @@
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ */
+ 
+/*global Components: false */
+
+"use strict";
+
+var EXPORTED_SYMBOLS = ["OpenPGPMasterpass"];
+
+const EnigmailLog = ChromeUtils.import("chrome://openpgp/content/modules/log.jsm").EnigmailLog;
+
+const PASS_URI = 'chrome://openpgp-secret-key-password';
+const PASS_REALM = 'DO NOT DELETE';
+const PASS_USER = 'openpgp';
+
+var OpenPGPMasterpass = {
+  getLoginManager: function() {
+    if (!this.loginManager) {
+      try {
+        this.loginManager = Components.classes["@mozilla.org/login-manager;1"].getService(Components.interfaces.nsILoginManager);
+      } catch (ex) {
+        EnigmailLog.writeException("masterpass.jsm", ex);
+      }
+    }
+    return this.loginManager;
+  },
+
+  ensureMasterPassword: function() {
+    let password = this.retrieveOpenPGPPassword();
+    if (password) {
+      return;
+    }
+
+    try {
+      let pass = this.generatePassword();
+
+      EnigmailLog.DEBUG("masterpass.jsm: ensureMasterPassword()\n");
+      let nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1", Ci.nsILoginInfo, "init");
+      // parameters: aHostname, aFormSubmitURL, aHttpRealm, aUsername, aPassword, aUsernameField, aPasswordField
+      let loginInfo = new nsLoginInfo(PASS_URI, null, PASS_REALM, PASS_USER, pass, '', '');
+
+      this.getLoginManager().addLogin(loginInfo);
+    } catch (ex) {
+      EnigmailLog.writeException("masterpass.jsm", ex);
+      throw ex;
+    }
+    EnigmailLog.DEBUG("masterpass.jsm: ensureMasterPassword(): ok\n");
+  },
+
+  generatePassword: function() {
+    const random_bytes = new Uint8Array(32);
+    crypto.getRandomValues(random_bytes);
+    let result = "";
+    for (let i = 0; i < 32; i++) {
+      result += (random_bytes[i] % 16).toString(16);
+    }
+    return result;
+  },
+
+  retrieveOpenPGPPassword: function() {
+    EnigmailLog.DEBUG("masterpass.jsm: retrieveMasterPassword()\n");
+    try {
+      var logins = this.getLoginManager().findLogins(PASS_URI, null, PASS_REALM);
+
+      for (let i = 0; i < logins.length; i++) {
+        if (logins[i].username == PASS_USER) {
+          EnigmailLog.DEBUG("masterpass.jsm: retrieveOpenPGPPassword(): ok\n");
+          return logins[i].password;
+        }
+      }
+    } catch (ex) {
+      EnigmailLog.writeException("masterpass.jsm", ex);
+    }
+    EnigmailLog.DEBUG("masterpass.jsm: retrieveMasterPassword(): not found!\n");
+    return null;
+  }
+};