Bug 1594855 - initial integration of Enigmail backend code. r=patrick DONTBUILD
authorKai Engert <kaie@kuix.de>
Sun, 17 Nov 2019 13:10:03 +0100
changeset 36657 86209ae8455a055ce314f7638705fa789ccd1b17
parent 36656 881bcd3d0f1164172268e4a8ffa44bd7dc6eb114
child 36658 78130fcb03716b7a22e451e4d2197d20288bfde0
push id2534
push userclokep@gmail.com
push dateMon, 02 Dec 2019 19:52:51 +0000
treeherdercomm-beta@055c50840778 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspatrick
bugs1594855
Bug 1594855 - initial integration of Enigmail backend code. r=patrick DONTBUILD
mail/extensions/openpgp/content/bond.js
mail/extensions/openpgp/content/modules/app.jsm
mail/extensions/openpgp/content/modules/core.jsm
mail/extensions/openpgp/content/modules/cryptoAPI.jsm
mail/extensions/openpgp/content/modules/cryptoAPI/interface.js
mail/extensions/openpgp/content/modules/lazy.jsm
mail/extensions/openpgp/content/modules/locale.jsm
mail/extensions/openpgp/content/modules/mimeDecrypt.jsm
mail/extensions/openpgp/content/modules/prefs.jsm
mail/extensions/openpgp/content/modules/rnp.jsm
mail/extensions/openpgp/content/strings/bond.dtd
mail/extensions/openpgp/jar.mn
mail/extensions/openpgp/locale/jar.mn
mail/extensions/openpgp/locale/moz.build
mail/extensions/openpgp/moz.build
new file mode 100644
--- /dev/null
+++ b/mail/extensions/openpgp/content/bond.js
@@ -0,0 +1,76 @@
+/* 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/. */
+
+/* This file is a thin interface on top of the rest of the OpenPGP
+ * integration ot minimize the amount of code that must be
+ * included in files outside the extensions/openpgp directory. */
+
+"use strict";
+
+const EXPORTED_SYMBOLS = ["BondOpenPGP"];
+
+var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+const EnigmailLazy = ChromeUtils.import(
+  "chrome://openpgp/content/modules/lazy.jsm"
+).EnigmailLazy;
+
+const getEnigmailApp = EnigmailLazy.loader("enigmail/app.jsm", "EnigmailApp");
+const getEnigmailCore = EnigmailLazy.loader(
+  "enigmail/core.jsm",
+  "EnigmailCore"
+);
+const getEnigmailAmPrefsService = EnigmailLazy.loader(
+  "enigmail/amPrefsService.jsm",
+  "EnigmailAmPrefsService"
+);
+const getEnigmailPgpmimeHander = EnigmailLazy.loader(
+  "enigmail/pgpmimeHandler.jsm",
+  "EnigmailPgpmimeHander"
+);
+const getRNP = EnigmailLazy.loader("enigmail/rnp.jsm", "RNP");
+const getEnigmailWindows = EnigmailLazy.loader(
+  "enigmail/windows.jsm",
+  "EnigmailWindows"
+);
+
+/* global APP_SHUTDOWN: false */
+
+var BondOpenPGP = {
+  logException(exc) {
+    try {
+      Services.console.logStringMessage(exc.toString() + "\n" + exc.stack);
+    } catch (x) {}
+  },
+
+  initDone: false,
+
+  init() {
+    if (this.initDone) {
+      return;
+    }
+
+    this.initDone = true;
+    console.log("loading OpenPGP");
+    try {
+      getRNP().init({});
+      //TODO: check RNP.libLoaded
+
+      getEnigmailApp().initAddon();
+      getEnigmailAmPrefsService().startup(0);
+      getEnigmailCore().startup(0);
+      getEnigmailPgpmimeHander().startup(0);
+
+      Services.console.logStringMessage("OpenPGP bootstrap completed");
+    } catch (ex) {
+      this.logException(ex);
+    }
+  },
+
+  openKeyManager(window) {
+    getEnigmailWindows().openKeyManager(window);
+  },
+};
+
+BondOpenPGP.init();
--- a/mail/extensions/openpgp/content/modules/app.jsm
+++ b/mail/extensions/openpgp/content/modules/app.jsm
@@ -59,13 +59,13 @@ var EnigmailApp = {
   setVersion: function(version) {
     EnigmailApp._version = version;
   },
 
   setInstallLocation: function(location) {
     EnigmailApp._installLocation = location;
   },
 
-  initAddon: function(addon) {
-    EnigmailApp.setVersion(addon.version);
-    EnigmailApp.setInstallLocation(addon.installPath);
+  initAddon: function() {
+    EnigmailApp.setVersion(0);
+    EnigmailApp.setInstallLocation(0);
   }
 };
--- a/mail/extensions/openpgp/content/modules/core.jsm
+++ b/mail/extensions/openpgp/content/modules/core.jsm
@@ -31,17 +31,17 @@ const getEnigmailPrefs = EnigmailLazy.lo
 const getEnigmailVerify = EnigmailLazy.loader("enigmail/mimeVerify.jsm", "EnigmailVerify");
 const getEnigmailWindows = EnigmailLazy.loader("enigmail/windows.jsm", "EnigmailWindows");
 const getEnigmailDialog = EnigmailLazy.loader("enigmail/dialog.jsm", "EnigmailDialog");
 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 getEnigmailOverlays = EnigmailLazy.loader("enigmail/enigmailOverlays.jsm", "EnigmailOverlays");
 const getEnigmailSqlite = EnigmailLazy.loader("enigmail/sqliteDb.jsm", "EnigmailSqliteDb");
 const getEnigmailTimer = EnigmailLazy.loader("enigmail/timer.jsm", "EnigmailTimer");
 const Services = ChromeUtils.import("resource://gre/modules/Services.jsm").Services;
 
 var EXPORTED_SYMBOLS = ["EnigmailCore"];
 
 // Interfaces
 const nsIEnvironment = Ci.nsIEnvironment;
@@ -81,28 +81,32 @@ var EnigmailCore = {
     this.factories = [];
 
     function continueStartup(type) {
       logger.DEBUG(`core.jsm: startup.continueStartup(${type})\n`);
 
       try {
         let mimeEncrypt = getEnigmailMimeEncrypt();
         mimeEncrypt.startup(reason);
-        getEnigmailOverlays().startup();
+        //getEnigmailOverlays().startup();
         self.factories.push(new Factory(getEnigmailProtocolHandler()));
         self.factories.push(new Factory(mimeEncrypt.Handler));
       } 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();
     getEnigmailFiltersWrapper().onStartup();
     continueStartup(1);
+
+    let myName = getEnigmailLocale().getString("Enigmail");
+    console.log("core.jsm: loaded string from properties " + myName);
   },
 
   shutdown: function(reason) {
     getEnigmailLog().DEBUG("core.jsm: shutdown():\n");
 
     let cLineReg = getEnigmailCommandLine().categoryRegistry;
     let catMan = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
     catMan.deleteCategoryEntry(cLineReg.category, cLineReg.entry, false);
--- a/mail/extensions/openpgp/content/modules/cryptoAPI.jsm
+++ b/mail/extensions/openpgp/content/modules/cryptoAPI.jsm
@@ -7,20 +7,27 @@
 
 "use strict";
 
 var EXPORTED_SYMBOLS = ["EnigmailCryptoAPI"];
 
 var gCurrentApi = null;
 var Services = ChromeUtils.import("resource://gre/modules/Services.jsm").Services;
 
-
 function EnigmailCryptoAPI() {
   if (!gCurrentApi) {
-    const {
-      getGnuPGAPI
-    } = ChromeUtils.import("chrome://openpgp/content/modules/cryptoAPI/gnupg.js");
-
-    gCurrentApi = getGnuPGAPI();
+    const gOpenPGPEngine = Services.prefs.getIntPref("temp.openpgp.engine");
+    
+    if (gOpenPGPEngine == 1) {
+      const {
+        getRNPAPI
+      } = ChromeUtils.import("chrome://openpgp/content/modules/cryptoAPI/rnp-cryptoAPI.js");
+      gCurrentApi = getRNPAPI();
+    } else if (gOpenPGPEngine == 2) {
+      const {
+        getGnuPGAPI
+      } = ChromeUtils.import("chrome://openpgp/content/modules/cryptoAPI/gnupg.js");
+      gCurrentApi = getGnuPGAPI();
+    }
   }
 
   return gCurrentApi;
 }
--- a/mail/extensions/openpgp/content/modules/cryptoAPI/interface.js
+++ b/mail/extensions/openpgp/content/modules/cryptoAPI/interface.js
@@ -33,21 +33,23 @@ class CryptoAPI {
     console.log("CryptoAPI.sync() starting");
 
     if (!inspector) {
       inspector = Cc["@mozilla.org/jsinspector;1"].createInstance(Ci.nsIJSInspector);
     }
 
     let res = null;
     let p = promise.then(gotResult => {
-      console.log("CryptoAPI.sync() good result: " + gotResult);
+      console.log("CryptoAPI.sync() good result:");
+      console.log(gotResult);
       res = gotResult;
       inspector.exitNestedEventLoop();
     }).catch(gotResult => {
-      console.log("CryptoAPI.sync() failed result: " + gotResult);
+      console.log("CryptoAPI.sync() failed result:");
+      console.log(gotResult);
       res = gotResult;
       inspector.exitNestedEventLoop();
     });
 
     inspector.enterNestedEventLoop(0);
 
     console.log("CryptoAPI.sync() leaving");
     return res;
--- a/mail/extensions/openpgp/content/modules/lazy.jsm
+++ b/mail/extensions/openpgp/content/modules/lazy.jsm
@@ -10,15 +10,22 @@ const EXPORTED_SYMBOLS = ["EnigmailLazy"
 
 
 var EnigmailLazy = {
   loader: function(component, name) {
     let holder = null;
     return function() {
       if (holder === null) {
         component = component.replace(/^enigmail\//, "");
-        const into = ChromeUtils.import("chrome://openpgp/content/modules/" + component);
-        holder = into[name];
+        let url;
+        try {
+          url = "chrome://openpgp/content/modules/" + component;
+          const into = ChromeUtils.import(url);
+          holder = into[name];
+        } catch (ex) {
+          console.log(ex);
+          console.log("lazy loading couldn't get " + url);
+        }
       }
       return holder;
     };
   }
 };
--- a/mail/extensions/openpgp/content/modules/locale.jsm
+++ b/mail/extensions/openpgp/content/modules/locale.jsm
@@ -43,46 +43,43 @@ var EnigmailLocale = {
    * @param subPhrases: String or Array of Strings - [Optional] additional input to be embedded
    *                                                  in the resulting localized text
    *
    * @return String: the localized string
    */
   getString: function(aStr, subPhrases) {
     if (!gEnigStringBundle) {
       try {
-        /* HACK: The string bundle cache is cleared on addon shutdown, however it doesn't appear to do so reliably.
-          Errors can erratically happen on next load of the same file in certain instances. (at minimum, when strings are added/removed)
-          The apparently accepted solution to reliably load new versions is to always create bundles with a unique URL so as to bypass the cache.
-          This is accomplished by passing a random number in a parameter after a '?'. (this random ID is otherwise ignored)
-          The loaded string bundle is still cached on startup and should still be cleared out of the cache on addon shutdown.
-          This just bypasses the built-in cache for repeated loads of the same path so that a newly installed update loads cleanly. */
-        let bundlePath = "chrome://openpgp/locale/enigmail.properties?" + Math.random();
+        let bundlePath = "chrome://openpgp/content/strings/enigmail.properties";
         EnigmailLog.DEBUG("locale.jsm: loading stringBundle " + bundlePath + "\n");
         let strBundleService = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService);
         gEnigStringBundle = strBundleService.createBundle(bundlePath);
       } catch (ex) {
         EnigmailLog.ERROR("locale.jsm: Error in instantiating stringBundleService\n");
       }
     }
 
     if (gEnigStringBundle) {
       try {
+        let rv;
         if (subPhrases) {
           if (typeof (subPhrases) == "string") {
-            return gEnigStringBundle.formatStringFromName(aStr, [subPhrases], 1);
+            rv = gEnigStringBundle.formatStringFromName(aStr, [subPhrases], 1);
           }
           else {
-            return gEnigStringBundle.formatStringFromName(aStr, subPhrases, subPhrases.length);
+            rv = gEnigStringBundle.formatStringFromName(aStr, subPhrases, subPhrases.length);
           }
         }
         else {
-          return gEnigStringBundle.GetStringFromName(aStr);
+          rv = gEnigStringBundle.GetStringFromName(aStr);
         }
+        EnigmailLog.DEBUG("locale.jsm: successfully loaded " + aStr + "\n");
+        return rv;
       } catch (ex) {
-        EnigmailLog.ERROR("locale.jsm: Error in querying stringBundleService for string '" + aStr + "'\n");
+        EnigmailLog.ERROR("locale.jsm: Error in querying stringBundleService for string '" + aStr + "', " + ex + "\n");
       }
     }
     return aStr;
   },
 
   /**
    * Get the locale for the User Interface
    *
--- a/mail/extensions/openpgp/content/modules/mimeDecrypt.jsm
+++ b/mail/extensions/openpgp/content/modules/mimeDecrypt.jsm
@@ -32,17 +32,17 @@ const PGPMIME_JS_DECRYPTOR_CONTRACTID = 
 const PGPMIME_JS_DECRYPTOR_CID = Components.ID("{7514cbeb-2bfd-4b2c-829b-1a4691fa0ac8}");
 
 const ENCODING_DEFAULT = 0;
 const ENCODING_BASE64 = 1;
 const ENCODING_QP = 2;
 
 const LAST_MSG = EnigmailSingletons.lastDecryptedMessage;
 
-var gDebugLogLevel = 0;
+var gDebugLogLevel = 5;
 
 var gNumProc = 0;
 
 var EnigmailMimeDecrypt = {
   /**
    * create a new instance of a PGP/MIME decryption handler
    */
   newPgpMimeHandler: function() {
--- a/mail/extensions/openpgp/content/modules/prefs.jsm
+++ b/mail/extensions/openpgp/content/modules/prefs.jsm
@@ -57,20 +57,21 @@ var gPrefs = {};
  */
 function pref(key, val) {
   gPrefs[key] = val;
 }
 
 /**
  * Load default preferences for bootstrapped addon
  */
+/* no longer necessary
 function setDefaultPrefs() {
   EnigmailLog.DEBUG("prefs.jsm: setDefaultPrefs()\n");
 
-  Services.scriptloader.loadSubScript("chrome://openpgp/content/preferences/defaultPrefs.js", {}, "UTF-8");
+  Services.scriptloader.loadSubScript("chrome://openpgp/content/prefs/openpgp-prefs.js", {}, "UTF-8");
 
   let branch = p.defaultBranch;
   for (let key in gPrefs) {
     try {
       let val = gPrefs[key];
       switch (typeof val) {
         case "boolean":
           branch.setBoolPref(key, val);
@@ -83,23 +84,24 @@ function setDefaultPrefs() {
           break;
       }
     }
     catch(ex) {
       EnigmailLog.ERROR(`prefs.jsm: setDefaultPrefs(${key}: ERROR ${ex.toString()}\n`);
     }
   }
 }
+*/
 
 
 var EnigmailPrefs = {
   startup: function(reason) {
     try {
       initPrefService();
-      setDefaultPrefs();
+      //setDefaultPrefs();
     }
     catch (ex) {
       EnigmailLog.ERROR("prefs.jsm: Error while loading default prefs: " + ex.message + "\n");
     }
   },
 
   getPrefRoot: function() {
     if (!p.branch) {
--- a/mail/extensions/openpgp/content/modules/rnp.jsm
+++ b/mail/extensions/openpgp/content/modules/rnp.jsm
@@ -1,16 +1,19 @@
 /* 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 http://mozilla.org/MPL/2.0/. */
 
 const { ctypes } = ChromeUtils.import("resource://gre/modules/ctypes.jsm");
 const { RNPLibLoader } = ChromeUtils.import(
   "chrome://openpgp/content/modules/rnpLib.jsm"
 );
+const { EnigmailConstants } = ChromeUtils.import(
+  "chrome://openpgp/content/modules/constants.jsm"
+);
 
 // rnp module
 
 var RNPLib;
 
 var RNP = {
   hasRan: false,
   libLoaded: false,
@@ -70,16 +73,17 @@ var RNP = {
 
     let max_out = encrypted.length * 2;
 
     let output_to_memory = new RNPLib.rnp_output_t;
     RNPLib.rnp_output_to_memory(output_to_memory.address(), max_out);
 
     let result = {};
     result.decryptedData = "";
+    result.statusFlags = 0;
 
     result.exitCode = RNPLib.rnp_decrypt(
       RNPLib.ffi,
       input_from_memory,
       output_to_memory
     );
     console.log("decrypt exit code: " + result.exitCode);
 
@@ -99,16 +103,17 @@ var RNP = {
         //let buf_array = ctypes.cast(result_buf, ctypes.uint8_t.array(result_len.value).ptr).contents;
         //let char_array = ctypes.cast(buf_array, ctypes.char.array(result_len.value));
 
         let char_array = ctypes.cast(
           result_buf,
           ctypes.char.array(result_len.value).ptr
         ).contents;
 
+        result.statusFlags |= EnigmailConstants.DECRYPTION_OKAY;
         result.decryptedData = char_array.readString();
         console.log(result.decryptedData);
       }
     }
 
     RNPLib.rnp_input_destroy(input_from_memory);
     RNPLib.rnp_output_destroy(output_to_memory);
 
new file mode 100644
--- /dev/null
+++ b/mail/extensions/openpgp/content/strings/bond.dtd
@@ -0,0 +1,2 @@
+<!ENTITY manageKeysOpenPGPCmd.label "OpenPGP Key Management…">
+<!ENTITY manageKeysOpenPGPCmd.accesskey "o">
new file mode 100644
--- /dev/null
+++ b/mail/extensions/openpgp/jar.mn
@@ -0,0 +1,28 @@
+# 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 http://mozilla.org/MPL/2.0/.
+
+openpgp.jar:
+% content openpgp %content/openpgp/
+  content/openpgp/bond.js                      (content/bond.js)
+  content/openpgp/modules                      (content/modules/*.js*)
+  content/openpgp/modules/stdlib               (content/modules/stdlib/*.js*)
+  content/openpgp/modules/cryptoAPI            (content/modules/cryptoAPI/*.js*)
+  content/openpgp/strings/enigmail.properties  (content/strings/enigmail.properties)
+  content/openpgp/strings/enigmail.dtd         (content/strings/enigmail.dtd)
+  content/openpgp/strings/bond.dtd             (content/strings/bond.dtd)
+  content/openpgp/ui                           (content/ui/*)
+% skin openpgp classic/1.0 %skin/tb-mac/ os=Darwin
+% skin openpgp classic/1.0 %skin/tb-win/ os=WINNT
+% skin openpgp classic/1.0 %skin/tb-linux/
+  skin/tb-mac                                  (skin/tb-mac/*)
+  skin/tb-win                                  (skin/tb-win/*)
+  skin/tb-linux                                (skin/tb-linux/*)
+
+#  content/openpgp/strings/enigmail.dtd        (content/strings/enigmail.dtd)
+#  content/openpgp/strings/am-enigprefs.properties (content/strings/am-enigprefs.properties)
+
+#messenger.jar:
+#  content/messenger/am-enigprefs.xul (content/am-enigprefs.xul)
+
+
new file mode 100644
--- /dev/null
+++ b/mail/extensions/openpgp/locale/jar.mn
@@ -0,0 +1,10 @@
+#filter substitution
+
+#openpgp.jar:
+#% locale openpgp @AB_CD@ %
+#  locale/openpgp/enigmail.properties  (%enigmail.properties)
+#  locale/openpgp/enigmail.dtd         (%enigmail.dtd)
+
+
+#@AB_CD@.jar:
+#  locale/@AB_CD@/messenger/am-enigprefs.properties  (%am-enigprefs.properties)
new file mode 100644
--- /dev/null
+++ b/mail/extensions/openpgp/locale/moz.build
@@ -0,0 +1,5 @@
+# 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 http://mozilla.org/MPL/2.0/.
+
+#JAR_MANIFESTS += ['jar.mn']
new file mode 100644
--- /dev/null
+++ b/mail/extensions/openpgp/moz.build
@@ -0,0 +1,13 @@
+# 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 http://mozilla.org/MPL/2.0/.
+
+JAR_MANIFESTS += ['jar.mn']
+
+#DIRS += [
+#    'locale',
+#]
+
+JS_PREFERENCE_FILES += [
+    'prefs/openpgp-prefs.js',
+]