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