Hello List,

this patch makes Enigmail preview the key(s) attached to an email before 
importing them into the keyring. This works by importing the key(s) into a 
temporary file and reading back the GPG output.

Regards
Kai

---
 package/files.jsm                      |  10 +++
 package/keyRing.jsm                    | 131 +++++++++++++++++++++++++++++++++
 ui/content/enigmailMessengerOverlay.js |  43 +++++++++--
 ui/locale/en-US/enigmail.properties    |   3 +
 4 files changed, 180 insertions(+), 7 deletions(-)

diff --git a/package/files.jsm b/package/files.jsm
index f6b5eb3..b6aeba9 100644
--- a/package/files.jsm
+++ b/package/files.jsm
@@ -264,6 +264,15 @@ const EnigmailFiles = {
     return EnigmailFiles.getTempDirObj().path;
   },
 
+  createTempDir: function(name) {
+    var localFile = Cc[NS_LOCAL_FILE_CONTRACTID].createInstance(Ci.nsIFile);
+
+    localFile.initWithPath(EnigmailFiles.getTempDir() + "/" + name);
+    localFile.create(Ci.nsIFile.DIRECTORY_TYPE, 509 /* = 0775 */ );
+
+    return localFile;
+  },
+
   /**
    *  Write data to a file
    *  @filePath |string| or |nsIFile| object - the file to be created
@@ -299,3 +308,4 @@ const EnigmailFiles = {
     return nsFileObj.path;
   }
 };
+
diff --git a/package/keyRing.jsm b/package/keyRing.jsm
index 3792587..f983cfe 100644
--- a/package/keyRing.jsm
+++ b/package/keyRing.jsm
@@ -487,6 +487,136 @@ const EnigmailKeyRing = {
     return exitCodeObj.value;
   },
 
+  previewKey: function(aaKeys, errorMsgObj) {
+    var ret = [];
+    const beginIndexObj = {};
+    const endIndexObj = {};
+    const blockType = EnigmailArmor.locateArmoredBlock(aaKeys, 0, "", 
beginIndexObj, endIndexObj, {});
+    if (!blockType) {
+      errorMsgObj.value = EnigmailLocale.getString("noPGPblock");
+      return ret;
+    }
+
+    if (blockType != "PUBLIC KEY BLOCK") {
+      errorMsgObj.value = EnigmailLocale.getString("notFirstBlock");
+      return ret;
+    }
+
+    const pgpBlock = aaKeys.substr(beginIndexObj.value,
+      endIndexObj.value - beginIndexObj.value + 1);
+    const tempDir = EnigmailFiles.createTempDir("enigmail_import");
+    const tempPath = EnigmailFiles.getFilePath(tempDir);
+    const args = EnigmailGpg.getStandardArgs(true).concat([
+      "--import",
+      "--trustdb", tempPath + "/trustdb",
+      "--no-default-keyring", "--keyring", tempPath + "/keyring"
+    ]);
+
+    const exitCodeObj = {};
+    const statusMsgObj = {};
+
+    EnigmailExecution.execCmd(EnigmailGpg.agentPath, args, pgpBlock, 
exitCodeObj, {}, statusMsgObj, errorMsgObj);
+
+    const statusMsg = statusMsgObj.value;
+
+    tempDir.remove(true);
+
+    if (exitCodeObj.value === 0) {
+      var state = "newOrResult";
+      var lines = statusMsg.split("\n");
+      var idx = 0;
+      var cur = {};
+
+      while (state != "end") {
+        if (idx >= lines.length) {
+          errorMsgObj.value = "failed to parse gpg output";
+          return [];
+        }
+
+        EnigmailLog.DEBUG("state: '" + state + "', line: '" + lines[idx] + 
"'\n");
+
+        switch (state) {
+          case "newOrResult":
+            {
+              const imported = lines[idx].match(/^IMPORTED (\w+) (.+)/);
+              if (imported && (imported.length > 2)) {
+                EnigmailLog.DEBUG("new imported: " + imported[1] + " (" + 
imported[2] + ")\n");
+                state = "summary";
+                cur.id = imported[1];
+                cur.name = imported[2];
+                cur.state = "new";
+                idx += 1;
+                break;
+              }
+
+              const import_res = lines[idx].match(/^IMPORT_RES ([0-9 ]+)/);
+              if (import_res && (import_res.length > 1)) {
+                EnigmailLog.DEBUG("import result: " + import_res[1] + "\n");
+                state = "end";
+              }
+              else {
+                state = "summary";
+              }
+
+              break;
+            }
+
+          case "summary":
+            {
+              const import_ok = lines[idx].match(/^IMPORT_OK (\d+) (\w+)/);
+              if (import_ok && (import_ok.length > 2)) {
+                EnigmailLog.DEBUG("import ok: " + import_ok[1] + " (" + 
import_ok[2] + ")\n");
+
+                state = "newOrResult";
+                cur.fingerprint = import_ok[2];
+
+                if (cur.state === undefined) {
+                  cur.state = "old";
+                }
+
+                ret.push(cur);
+                cur = {};
+                idx += 1;
+                break;
+              }
+
+              const import_err = lines[idx].match(/^IMPORT_PROBLEM (\d+) 
(\w+)/);
+              if (import_err && (import_err.length > 2)) {
+                EnigmailLog.DEBUG("import err: " + import_err[1] + " (" + 
import_err[2] + ")\n");
+                state = "newOrResult";
+                cur.fingerprint = import_err[2];
+
+                if (cur.state === undefined) {
+                  cur.state = "invalid";
+                }
+
+                ret.push(cur);
+                cur = {};
+                idx += 1;
+                break;
+              }
+
+              errorMsgObj.value = "failed to parse gpg output";
+              return [];
+            }
+
+          default:
+            {
+              EnigmailLog.DEBUG("skip line '" + lines[idx] + "'\n");
+              idx += 1;
+              break;
+            }
+        }
+      }
+      errorMsgObj.value = "";
+    }
+    else {
+      errorMsgObj.value = EnigmailLocale.getString("cantImport");
+    }
+
+    return ret;
+  },
+
   showKeyPhoto: function(keyId, photoNumber, exitCodeObj, errorMsgObj) {
     EnigmailLog.DEBUG("keyRing.js: EnigmailKeyRing.showKeyPhoto, keyId=" + 
keyId + " photoNumber=" + photoNumber + "\n");
 
@@ -1047,3 +1177,4 @@ function getKeyListEntryOfKey(keyId) {
   }
   return res;
 }
+
diff --git a/ui/content/enigmailMessengerOverlay.js 
b/ui/content/enigmailMessengerOverlay.js
index f6d24f4..4097ce3 100644
--- a/ui/content/enigmailMessengerOverlay.js
+++ b/ui/content/enigmailMessengerOverlay.js
@@ -2134,15 +2134,43 @@ Enigmail.msg = {
     }
 
     if (callbackArg.actionType == "importKey") {
-      try {
-        exitStatus = EnigmailKeyRing.importKey(parent, 0, callbackArg.data, 
"", errorMsgObj);
-      }
-      catch (ex) {}
-      if (exitStatus === 0) {
-        EnigmailDialog.longAlert(window, 
EnigmailLocale.getString("successKeyImport") + "\n\n" + errorMsgObj.value);
+      var preview = EnigmailKeyRing.previewKey(callbackArg.data, errorMsgObj);
+
+      if (errorMsgObj.value === "") {
+        if (preview.length > 0) {
+          if (preview.length == 1) {
+            exitStatus = EnigmailDialog.confirmDlg(window, 
EnigmailLocale.getString("doImportOne", [preview[0].name, preview[0].id]));
+          }
+          else {
+            exitStatus = EnigmailDialog.confirmDlg(window,
+              EnigmailLocale.getString("doImportMultiple", [
+                preview.map(function(a) {
+                  return "\t" + a.name + " (" + a.id + ")";
+                }).
+                join("\n")
+              ]));
+          }
+
+          if (exitStatus) {
+            try {
+              exitStatus = EnigmailKeyRing.importKey(parent, 0, 
callbackArg.data, "", errorMsgObj);
+            }
+            catch (ex) {}
+
+            if (exitStatus === 0) {
+              EnigmailDialog.longAlert(window, 
EnigmailLocale.getString("successKeyImport") + "\n\n" + errorMsgObj.value);
+            }
+            else {
+              EnigmailDialog.alert(window, 
EnigmailLocale.getString("failKeyImport") + "\n" + errorMsgObj.value);
+            }
+          }
+        }
+        else {
+          EnigmailDialog.alert(window, EnigmailLocale.getString("noKeyFound") 
+ "\n" + errorMsgObj.value);
+        }
       }
       else {
-        EnigmailDialog.alert(window, EnigmailLocale.getString("failKeyImport") 
+ "\n" + errorMsgObj.value);
+        EnigmailDialog.alert(window, EnigmailLocale.getString("previewFailed") 
+ "\n" + errorMsgObj.value);
       }
 
       return;
@@ -2297,3 +2325,4 @@ Enigmail.msg = {
 };
 
 window.addEventListener("load", 
Enigmail.msg.messengerStartup.bind(Enigmail.msg), false);
+
diff --git a/ui/locale/en-US/enigmail.properties 
b/ui/locale/en-US/enigmail.properties
index b30b04b..c69999b 100644
--- a/ui/locale/en-US/enigmail.properties
+++ b/ui/locale/en-US/enigmail.properties
@@ -314,6 +314,9 @@ unverifiedReply=Indented message part (reply) was probably 
modified
 decryptToImport=Click Decrypt button to import public key block in message
 sigMismatch=Error - Signature mismatch
 cantImport=Error in importing public key\n\n
+doImportOne=Import %S (%S)?
+doImportMultiple=Import the following keys?\n\n%S
+previewFailed=Can't read public key file.
 sc.wrongCardAvailable=The SmartCard %1$S found in your reader cannot be used 
to process the message.\nPlease insert your SmartCard %2$S and repeat the 
operation.
 sc.insertCard=The operation requires your SmartCard %S.\nPlease insert the 
required SmartCard and repeat the operation.
 sc.removeCard=The operation requires no SmartCard to be in the reader.\nPlease 
remove your SmartCard and repeat the operation.
-- 
2.3.6

_______________________________________________
enigmail-users mailing list
[email protected]
To unsubscribe or make changes to your subscription click here:
https://admin.hostpoint.ch/mailman/listinfo/enigmail-users_enigmail.net

Reply via email to