diff --git a/package/keyserver.jsm b/package/keyserver.jsm
index 54cab84f..a9cc1efe 100644
--- a/package/keyserver.jsm
+++ b/package/keyserver.jsm
@@ -1,331 +1,428 @@
/*global Components:false */
/*
* 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/.
*/
"use strict";
const EXPORTED_SYMBOLS = ["EnigmailKeyServer"];
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://enigmail/subprocess.jsm"); /*global subprocess: false */
Cu.import("resource://enigmail/prefs.jsm"); /*global EnigmailPrefs: false */
Cu.import("resource://enigmail/files.jsm"); /*global EnigmailFiles: false */
Cu.import("resource://enigmail/os.jsm"); /*global EnigmailOS: false */
Cu.import("resource://enigmail/gpgAgent.jsm"); /*global EnigmailGpgAgent: false */
Cu.import("resource://enigmail/gpg.jsm"); /*global EnigmailGpg: false */
Cu.import("resource://enigmail/httpProxy.jsm"); /*global EnigmailHttpProxy: false */
Cu.import("resource://enigmail/core.jsm"); /*global EnigmailCore: false */
Cu.import("resource://enigmail/log.jsm"); /*global EnigmailLog: false */
Cu.import("resource://enigmail/tor.jsm"); /*global EnigmailTor: false */
Cu.import("resource://enigmail/locale.jsm"); /*global EnigmailLocale: false */
Cu.import("resource://enigmail/keyRing.jsm"); /*global EnigmailKeyRing: false */
Cu.import("resource://enigmail/subprocess.jsm"); /*global subprocess: false */
-Cu.import("resource://enigmail/core.jsm"); /*global EnigmailCore: false */
-Cu.import("resource://enigmail/prefs.jsm"); /*global EnigmailPrefs: false */
Cu.import("resource://enigmail/tor.jsm"); /*global EnigmailTor: false */
Cu.import("resource://enigmail/keyserverUris.jsm"); /*global EnigmailKeyserverURIs: false */
+Cu.import("resource://enigmail/funcs.jsm"); /*global EnigmailFuncs: false */
+Cu.import("resource://enigmail/stdlib.jsm"); /*global EnigmailStdlib: false */
+Cu.import("resource://enigmail/dialog.jsm"); /*global EnigmailDialog: false */
const nsIEnigmail = Ci.nsIEnigmail;
+const IOSERVICE_CONTRACTID = "@mozilla.org/network/io-service;1";
+
function matchesKeyserverAction(action, flag) {
return (action & flag) === flag;
}
function getRequestAction(actionFlags, keys) {
if (matchesKeyserverAction(actionFlags, nsIEnigmail.DOWNLOAD_KEY)) {
return ["--recv-keys"].concat(keys);
}
if (matchesKeyserverAction(actionFlags, nsIEnigmail.SEARCH_KEY)) {
return ["--search-keys"].concat(keys);
}
if (matchesKeyserverAction(actionFlags, nsIEnigmail.UPLOAD_KEY)) {
return ["--send-keys"].concat(keys);
}
if (matchesKeyserverAction(actionFlags, nsIEnigmail.REFRESH_KEY)) {
return ["--refresh-keys"];
}
return null;
}
function getInputData(actionFlags) {
if (matchesKeyserverAction(actionFlags, Ci.nsIEnigmail.SEARCH_KEY)) {
return "quit\n";
}
return null;
}
function buildProxyInfo(uri, proxyHost) {
if (proxyHost !== null) {
return ["--keyserver-options", "http-proxy=" + proxyHost];
}
return [];
}
function buildStandardArgs(action) {
if (matchesKeyserverAction(action, Ci.nsIEnigmail.SEARCH_KEY)) {
return EnigmailGpg.getStandardArgs(false).concat(["--command-fd", "0", "--fixed-list", "--with-colons"]);
}
return EnigmailGpg.getStandardArgs(true);
}
function flatten(arrOfArr) {
return arrOfArr.reduce(function(a, b) {
return a.concat(b);
}, []);
}
function isDownload(action) {
return matchesKeyserverAction(action, Ci.nsIEnigmail.REFRESH_KEY) || matchesKeyserverAction(action, Ci.nsIEnigmail.DOWNLOAD_KEY);
}
function gpgRequest(keyId, uri, action, usingTor) {
const proxyHost = getProxyModule().getHttpProxy(uri.keyserverName);
const args = flatten([
buildStandardArgs(action), ["--keyserver", uri],
buildProxyInfo(uri, proxyHost),
getRequestAction(action, keyId)
]);
return {
command: EnigmailGpgAgent.agentPath,
args: args,
usingTor: usingTor,
inputData: getInputData(action),
envVars: [],
isDownload: isDownload(action)
};
}
function requestOverTorWithSocks(keyId, uri, torProperties, action) {
const args = flatten([
buildStandardArgs(action), ["--keyserver", uri],
buildProxyInfo(uri, torProperties.args),
getRequestAction(action, keyId)
]);
return {
command: EnigmailGpgAgent.agentPath,
args: args,
usingTor: true,
envVars: [],
isDownload: isDownload(action)
};
}
function requestOverTorWithHelper(keyId, uri, torProperties, action) {
const args = flatten([
torProperties.args,
buildStandardArgs(action), ["--keyserver", uri],
getRequestAction(action, keyId)
]);
return {
command: torProperties.command,
args: args,
usingTor: true,
envVars: torProperties.envVars,
isDownload: isDownload(action)
};
}
function buildRequests(keyId, action, tor) {
const torProperties = tor.torProperties();
const uris = EnigmailKeyserverURIs.buildKeyserverUris();
const requests = [];
if (tor.isRequired(action) && !torProperties.isAvailable) {
EnigmailLog.CONSOLE("Unable to perform action with key " + keyId + " because Tor is required but not available.\n");
return [];
}
if (tor.isPreferred(action)) {
uris.forEach(function(uri) {
if (torProperties.helper !== null) {
requests.push(requestOverTorWithHelper(keyId, uri, torProperties.helper, action));
}
if (torProperties.socks !== null) {
requests.push(requestOverTorWithSocks(keyId, uri, torProperties.socks, action));
}
});
}
if (!tor.isRequired(action) || torProperties.useTorMode) {
uris.forEach(function(uri) {
requests.push(gpgRequest(keyId, uri, action, torProperties.useTorMode));
});
}
return requests;
}
function stringContains(stringToCheck, substring) {
return stringToCheck.indexOf(substring) > -1;
}
function convertRequestArgsToStrings(args) {
return args.map(function(a) {
return a.toString();
});
}
function execute(request, listener, subproc) {
EnigmailLog.CONSOLE("enigmail> " + EnigmailFiles.formatCmdLine(request.command, request.args) + "\n\n");
const envVars = request.envVars.concat(EnigmailCore.getEnvList());
let exitCode = null;
let proc = null;
try {
proc = subproc.call({
command: request.command,
arguments: convertRequestArgsToStrings(request.args),
environment: envVars,
charset: null,
stdin: request.inputData,
done: function(result) {
try {
if (result.exitCode === 0 && request.isDownload) {
EnigmailKeyRing.clearCache();
}
if (exitCode === null) {
exitCode = result.exitCode;
}
listener.done(exitCode);
}
catch (ex) {
EnigmailLog.ERROR("keyserver.jsm: execute: subprocess.call failed at finish with '" + ex.toString() + "'\n");
}
},
stdout: function(data) {
listener.stdout(data);
},
stderr: function(data) {
if (data.search(/^\[GNUPG:\] ERROR/m) >= 0) {
exitCode = 4;
}
listener.stderr(data);
},
mergeStderr: false
});
}
catch (ex) {
EnigmailLog.ERROR("keyserver.jsm: execute: subprocess.call failed with '" + ex.toString() + "'\n");
throw ex;
}
if (proc === null) {
EnigmailLog.ERROR("keyserver.jsm: execute: subprocess failed due to unknown reasons\n");
}
return proc;
}
function executeRefresh(request, subproc) {
let stdout = "";
let stderr = "";
let successful = false;
const listener = {
done: function(exitCode) {
successful = stringContains(stderr, "IMPORT_OK");
},
stderr: function(data) {
stderr += data;
},
stdout: function(data) {
stdout += data;
}
};
execute(request, listener, subproc).wait();
return successful;
}
function invalidArgumentsExist(actionFlags, keyserver, searchTerms, errorMsgObj) {
if (!keyserver) {
errorMsgObj.value = EnigmailLocale.getString("failNoServer");
return true;
}
if (!searchTerms && !matchesKeyserverAction(actionFlags, Ci.nsIEnigmail.REFRESH_KEY)) {
errorMsgObj.value = EnigmailLocale.getString("failNoID");
return true;
}
return false;
}
function build(actionFlags, keyserver, searchTerms, errorMsgObj) {
if (invalidArgumentsExist(actionFlags, keyserver, searchTerms, errorMsgObj)) {
return null;
}
const searchTermsList = searchTerms.split(" ");
return gpgRequest(searchTermsList, keyserver.trim(), actionFlags);
}
/**
* search, download or upload key on, from or to a keyserver
*
* @actionFlags: Integer - flags (bitmap) to determine the required action
* (see nsIEnigmail - Keyserver action flags for details)
* @keyserver: String - keyserver URL (optionally incl. protocol)
* @searchTerms: String - space-separated list of search terms or key IDs
* @listener: Object - execStart Listener Object. See execStart for details.
* @errorMsgObj: Object - object to hold error message in .value
*
* @return: Subprocess object, or null in case process could not be started
*/
function access(actionFlags, keyserver, searchTerms, listener, errorMsgObj) {
const request = build(actionFlags, keyserver, searchTerms, errorMsgObj, EnigmailHttpProxy);
if (request === null) return null;
return execute(request, listener, subprocess);
}
/**
* Refresh will refresh a key over Tor if Tor is available and over hkps if hkps is configured
* and available.
*
* @param String keyId - ID of the key to be refreshed
*/
function refresh(keyId) {
EnigmailLog.WRITE("[KEYSERVER]: Trying to refresh key: " + keyId + " at time: " + new Date().toUTCString() + "\n");
const refreshAction = Ci.nsIEnigmail.DOWNLOAD_KEY;
const requests = buildRequests(keyId, refreshAction, EnigmailTor, EnigmailHttpProxy);
for (let i = 0; i < requests.length; i++) {
const successStatus = executeRefresh(requests[i], subprocess);
if (successStatus || i === requests.length - 1) {
logRefreshAction(successStatus, requests[i].usingTor, keyId);
return;
}
}
}
function logRefreshAction(successStatus, usingTor, keyId) {
if (successStatus) {
EnigmailLog.CONSOLE("Refreshed key " + keyId + " over Tor: " + usingTor + ". Refreshed successfully: " + successStatus + "\n\n");
}
else {
EnigmailLog.CONSOLE("Failed to refresh key " + keyId + "\n\n");
}
}
let currentProxyModule = null;
function getProxyModule() {
if (currentProxyModule === null) {
currentProxyModule = EnigmailHttpProxy;
}
return currentProxyModule;
}
+
+/**
+ * Upload/refresh keys to/from keyservers.
+ *
+ * @win - |object| holding the parent window for the dialog
+ * @keys - |array| with key objects for the keys to upload/refresh
+ * @access - |nsIEnigmail| UPLOAD_WKS, UPLOAD_KEY or REFRESH_KEY
+ * @callbackFunc - |function| called when the key server operation finishes
+ * @resultObj - |object| with member importedKeys (|number| containing the number of imporeted keys)
+ *
+ * no return value
+ */
+function keyServerUpDownload(win, keys, access, callbackFunc, resultObj) {
+ let keyList = keys.map(function(x) {
+ return "0x" + x.keyId.toString();
+ }).join(", ");
+
+ EnigmailLog.DEBUG("keyserver.jsm: keyServerUpDownload: keyId=" + keyList + "\n");
+
+ const ioService = Cc[IOSERVICE_CONTRACTID].getService(Ci.nsIIOService);
+ if (ioService && ioService.offline) {
+ EnigmailDialog.alert(win, EnigmailLocale.getString("needOnline"));
+ return;
+ }
+
+ let keyDlObj = {
+ accessType: access,
+ keyServer: resultObj.value,
+ keyList: keyList,
+ fprList: [],
+ senderIdentities: [],
+ cbFunc: callbackFunc
+ };
+
+ if (access === nsIEnigmail.UPLOAD_WKD) {
+ for (let key of keys) {
+ // UPLOAD_WKD needs a nsIMsgIdentity
+ try {
+ for (let uid of key.userIds) {
+ let email = EnigmailFuncs.stripEmail(uid.userId);
+ let maybeIdent = EnigmailStdlib.getIdentityForEmail(email);
+
+ if (maybeIdent && maybeIdent.identity) {
+ keyDlObj.senderIdentities.push(maybeIdent.identity);
+ keyDlObj.fprList.push(key.fpr);
+ }
+ }
+
+ if (keyDlObj.senderIdentities.length === 0) {
+ let uids = key.userIds.map(function(x) {
+ return " - " + x.userId;
+ }).join("\n");
+ EnigmailDialog.alert(win, EnigmailLocale.getString("noWksIdentity", [uids]));
+ return;
+ }
+ }
+ catch (ex) {
+ EnigmailLog.DEBUG(ex + "\n");
+ }
+ }
+ }
+ else {
+ let autoKeyServer = EnigmailPrefs.getPref("autoKeyServerSelection") ? EnigmailPrefs.getPref("keyserver").split(/[ ,;]/g)[0] : null;
+ if (autoKeyServer) {
+ keyDlObj.keyServer = autoKeyServer;
+ }
+ else {
+ let inputObj = {};
+ let resultObj = {};
+ if (access != nsIEnigmail.REFRESH_KEY) {
+ inputObj.upload = true;
+ inputObj.keyId = keyList;
+ }
+ else {
+ inputObj.upload = false;
+ inputObj.keyId = "";
+ }
+
+ win.openDialog("chrome://enigmail/content/enigmailKeyserverDlg.xul",
+ "", "dialog,modal,centerscreen", inputObj, resultObj);
+ keyDlObj.keyServer = resultObj.value;
+ }
+
+ if (!keyDlObj.keyServer) {
+ return;
+ }
+ }
+
+ win.openDialog("chrome://enigmail/content/enigRetrieveProgress.xul",
+ "", "dialog,modal,centerscreen", keyDlObj, resultObj);
+
+}
+
const EnigmailKeyServer = {
access: access,
- refresh: refresh
+ refresh: refresh,
+ keyServerUpDownload: keyServerUpDownload
};
diff --git a/package/webKey.jsm b/package/webKey.jsm
index a3f6a26a..e0b29434 100644
--- a/package/webKey.jsm
+++ b/package/webKey.jsm
@@ -1,289 +1,289 @@
/*global Components: false */
/*
* 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/.
*/
/* eslint no-invalid-this: 0 */
/**
* This module serves to integrate WKS (Webkey service) into Enigmail
*/
"use strict";
var EXPORTED_SYMBOLS = ["EnigmailWks"];
const Cu = Components.utils;
const Cc = Components.classes;
const Ci = Components.interfaces;
Cu.import("resource://enigmail/files.jsm"); /* global EnigmailFiles: false */
Cu.import("resource://enigmail/log.jsm"); /*global EnigmailLog: false */
Cu.import("resource://enigmail/core.jsm"); /*global EnigmailCore: false */
Cu.import("resource://enigmail/execution.jsm"); /*global EnigmailExecution: false */
Cu.import("resource://enigmail/gpgAgent.jsm"); /*global EnigmailGpgAgent: false */
Cu.import("resource://enigmail/stdlib.jsm"); /*global EnigmailStdlib: false */
const GPG_WKS_CLIENT = "gpg-wks-client";
var EnigmailWks = {
wksClientPath: null,
/**
* Get WKS Client path (gpg-wks-client)
*
* @param window : Object - parent window for dialog display
* @param cb : Function(retValue) - callback function.
* retValue: nsIFile Object to gpg-wks-client executable or NULL
* @return : Object - NULL or a process handle
*/
getWksClientPathAsync: function(window, cb) {
EnigmailLog.DEBUG("webKey.jsm: getWksClientPathAsync\n");
if (EnigmailWks.wksClientPath === null) {
let listener = EnigmailExecution.newSimpleListener(null, function(ret) {
if (ret === 0) {
try {
let stdout = listener.stdoutData;
let libexecdir = /^libexecdir:(.+?)$/m.exec(stdout)[1];
if (libexecdir) {
libexecdir = libexecdir.replace(/%3a/gi, ":");
}
else {
libexecdir = "";
}
let wks_client = checkIfExists(libexecdir, GPG_WKS_CLIENT);
if (!wks_client) {
let bindir = /^bindir:(.+?)$/m.exec(stdout)[1];
if (bindir) {
bindir = bindir.replace(/%3a/gi, ":");
}
else {
bindir = "";
}
wks_client = checkIfExists(bindir, GPG_WKS_CLIENT);
if (!wks_client) {
cb(null);
return;
}
}
EnigmailWks.wksClientPath = wks_client;
cb(wks_client);
}
catch (e) {
EnigmailLog.DEBUG("webKey.jsm: getWksClientPathAsync: " + e.toString() + "\n");
cb(null);
}
}
else {
cb(null);
}
});
return EnigmailExecution.execStart(EnigmailGpgAgent.gpgconfPath, ["--list-dirs"], false, window, listener, {
value: null
});
}
else {
cb(EnigmailWks.wksClientPath);
return null;
}
},
/**
* Determine if WKS is supported by email provider
*
* @param email : String - user's email address
* @param window: Object - parent window of dialog display
* @param cb : Function(retValue) - callback function.
* retValue: Boolean: true if WKS is supported / false otherwise
* @return : Object - process handle
*/
isWksSupportedAsync: function(email, window, cb) {
EnigmailLog.DEBUG("webKey.jsm: isWksSupportedAsync: email = " + email + "\n");
return EnigmailWks.getWksClientPathAsync(window, function(wks_client) {
if (wks_client === null) {
cb(false);
}
let listener = EnigmailExecution.newSimpleListener(null, function(ret) {
cb(ret === 0);
});
let proc = EnigmailExecution.execStart(wks_client, ["--supported", email], false, window, listener, {
value: null
});
if (proc === null) {
cb(false);
}
});
},
/**
* Submit a key to the email provider (= send publication request)
*
* @param ident : nsIMsgIdentity - user's ID
* @param key : Enigmail KeyObject of user's key
* @param window: Object - parent window of dialog display
* @param cb : Function(retValue) - callback function.
* retValue: Boolean: true if submit was successful / false otherwise
* @return : Object - process handle
*/
submitKey: function(ident, key, window, cb) {
EnigmailLog.DEBUG("webKey.jsm: submitKey: email = " + ident.email + "\n");
return EnigmailWks.getWksClientPathAsync(window, function(wks_client) {
if (wks_client === null) {
cb(false);
return null;
}
let listener = EnigmailExecution.newSimpleListener(null, function(ret) {
if (ret !== 0) {
cb(false);
return;
}
EnigmailLog.DEBUG("webKey.jsm: submitKey: send " + listener.stdoutData + "\n");
let si = Components.classes["@mozdev.org/enigmail/composefields;1"].createInstance(Components.interfaces.nsIEnigMsgCompFields);
let subject = listener.stdoutData.match(/^Subject:[ \t]*(.+)$/im);
let to = listener.stdoutData.match(/^To:[ \t]*(.+)$/im);
if (subject !== null && to !== null) {
si.sendFlags |= (Ci.nsIEnigmail.SEND_VERBATIM);
EnigmailStdlib.sendMessage({
urls: [],
identity: ident,
to: to[1],
subject: subject[1],
securityInfo: si
}, {
compType: Ci.nsIMsgCompType.New,
deliveryType: Ci.nsIMsgCompDeliverMode.Now
}, {
match: function(x) {
- x.plainText(listener.stdoutData);
+ x.plainText(listener.stdoutData.replace(/\r\n/g, "\n"));
}
}, {}, {});
if (cb !== null) {
cb(true);
}
else {
cb(false);
}
}
else {
cb(false);
}
});
return EnigmailExecution.execStart(wks_client, ["--create", key.fpr, ident.email], false, window, listener, {
value: null
});
});
},
/**
* Submit a key to the email provider (= send publication request)
*
* @param ident : nsIMsgIdentity - user's ID
* @param body : String - complete message source of the confirmation-request email obtained
* from the email provider
* @param window: Object - parent window of dialog display
* @param cb : Function(retValue) - callback function.
* retValue: Boolean: true if submit was successful / false otherwise
* @return : Object - process handle
*/
confirmKey: function(ident, body, window, cb) {
var sanitized = body.replace(/\r?\n/g, "\r\n");
EnigmailLog.DEBUG("webKey.jsm: confirmKey: ident=" + ident.email + "\n");
return EnigmailWks.getWksClientPathAsync(window, function(wks_client) {
if (wks_client === null) {
if (cb) {
cb(false);
}
return;
}
let listener = EnigmailExecution.newSimpleListener(function(pipe) {
try {
pipe.write(sanitized);
pipe.close();
}
catch (e) {
if (cb) {
cb(false);
}
EnigmailLog.DEBUG(e + "\n");
}
}, function(ret) {
try {
let si = Components.classes["@mozdev.org/enigmail/composefields;1"].createInstance(Components.interfaces.nsIEnigMsgCompFields);
let subject = listener.stdoutData.match(/^Subject:[ \t]*(.+)$/im);
let to = listener.stdoutData.match(/^To:[ \t]*(.+)$/im);
if (subject !== null && to !== null) {
si.sendFlags |= (Ci.nsIEnigmail.SEND_VERBATIM);
EnigmailStdlib.sendMessage({
urls: [],
identity: ident,
to: to[1],
subject: subject[1],
securityInfo: si
}, {
compType: Ci.nsIMsgCompType.New,
deliveryType: Ci.nsIMsgCompDeliverMode.Now
}, {
match: function(x) {
- x.plainText(listener.stdoutData);
+ x.plainText(listener.stdoutData.replace(/\r\n/g, "\n"));
}
}, {}, {});
if (cb) {
cb(true);
}
}
}
catch (e) {
if (cb) {
cb(false);
}
EnigmailLog.DEBUG(e + "\n");
}
});
EnigmailExecution.execStart(wks_client, ["--receive"], false, window, listener, {
value: null
});
});
}
};
/**
* Check if a file exists and is executable
*
* @param path: String - directory name
* @param execFileName: String - executable name
*
* @return Object - nsIFile if file exists; NULL otherwise
*/
function checkIfExists(path, execFileName) {
EnigmailLog.DEBUG("webKey.jsm checkIfExists() path=" + path + " execFileName=" + execFileName + "\n");
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
execFileName = EnigmailFiles.potentialWindowsExecutable(execFileName);
EnigmailFiles.initPath(file, path);
file.append(execFileName);
if (file.exists() && file.isExecutable()) {
return file;
}
else {
return null;
}
}
diff --git a/ui/content/enigRetrieveProgress.js b/ui/content/enigRetrieveProgress.js
index 1ef77a02..a39b4ea2 100644
--- a/ui/content/enigRetrieveProgress.js
+++ b/ui/content/enigRetrieveProgress.js
@@ -1,314 +1,315 @@
/*global Components: false*/
/*
* 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/.
*/
/* eslint no-invalid-this: 0, no-loop-func: 0 */
"use strict";
const Cu = Components.utils;
const Ci = Components.interfaces;
const Cc = Components.classes;
const nsIEnigmail = Ci.nsIEnigmail;
Cu.import("resource://enigmail/core.jsm"); /*global EnigmailCore: false */
Cu.import("resource://enigmail/log.jsm"); /*global EnigmailLog: false */
Cu.import("resource://enigmail/locale.jsm"); /*global EnigmailLocale: false */
Cu.import("resource://enigmail/keyserver.jsm"); /*global EnigmailKeyServer: false */
Cu.import("resource://enigmail/errorHandling.jsm"); /*global EnigmailErrorHandling: false */
Cu.import("resource://enigmail/webKey.jsm"); /*global EnigmailWks: false */
Cu.import("resource://enigmail/data.jsm"); /*global EnigmailData: false */
Cu.import("resource://enigmail/dialog.jsm"); /*global EnigmailDialog: false */
// dialog is just an array we'll use to store various properties from the dialog document...
var dialog;
// the msgProgress is a nsIMsgProgress object
var msgProgress = null;
// random global variables...
var targetFile;
var itsASaveOperation = false;
var gProcess = null;
var gEnigCallbackFunc = null;
var gErrorData = '';
// all progress notifications are done through the nsIWebProgressListener implementation...
var progressListener = {
onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) {
if (aStateFlags & Ci.nsIWebProgressListener.STATE_START) {
// dialog.progress.setAttribute( "value", 0 );
// Put progress meter in undetermined mode.
dialog.progress.setAttribute("mode", "undetermined");
}
if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
// we are done transmitting
// Indicate completion in status area.
// Put progress meter at 100%.
dialog.progress.setAttribute("value", 100);
dialog.progress.setAttribute("mode", "normal");
if (msgProgress.processCanceledByUser)
enigSendKeyCancel();
window.close();
}
},
onProgressChange: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress) {},
onLocationChange: function(aWebProgress, aRequest, aLocation) {
// we can ignore this notification
},
onStatusChange: function(aWebProgress, aRequest, aStatus, aMessage) {
// we can ignore this notification
},
onSecurityChange: function(aWebProgress, aRequest, state) {
// we can ignore this notification
},
QueryInterface: function(iid) {
if (iid.equals(Ci.nsIWebProgressListener) ||
iid.equals(Ci.nsISupportsWeakReference) ||
iid.equals(Ci.nsISupports))
return this;
throw Components.results.NS_NOINTERFACE;
}
};
function onLoad() {
// Set global variables.
EnigmailLog.DEBUG("enigRetrieveProgress: onLoad\n");
var inArg = window.arguments[0];
window.arguments[1].result = false;
dialog = {};
dialog.strings = [];
dialog.progress = document.getElementById("dialog.progress");
var enigmailSvc = EnigmailCore.getService(window);
if (!enigmailSvc)
return;
gEnigCallbackFunc = inArg.cbFunc;
msgProgress = Cc["@mozilla.org/messenger/progress;1"].createInstance(Ci.nsIMsgProgress);
if (inArg.accessType == nsIEnigmail.UPLOAD_WKD) {
onLoadWkd(inArg);
}
else {
onLoadGpg(inArg);
}
}
function onLoadWkd(inArg) {
try {
var statTxt = document.getElementById("dialog.status2");
statTxt.value = EnigmailLocale.getString("keyserverTitle.uploading");
document.getElementById("progressWindow").setAttribute("title", EnigmailLocale.getString("keyserverTitle.uploading"));
var progressDlg = document.getElementById("dialog.progress");
progressDlg.setAttribute("mode", "undetermined");
let uploads = [];
// For each key fpr/sender identity pair, check whenever WKS is supported
// Result is an array of booleans
for (let i = 0; i < inArg.senderIdentities.length; i++) {
let keyFpr = inArg.fprList[i];
let senderIdent = inArg.senderIdentities[i];
let was_uploaded = new Promise(function(resolve, reject) {
EnigmailLog.DEBUG("enigRetrieveProgress: onLoadWkd: ident=" + senderIdent.email + ", key=" + keyFpr + "\n");
EnigmailWks.isWksSupportedAsync(senderIdent.email, window, function(is_supported) {
if (msgProgress && msgProgress.processCanceledByUser) {
reject("canceled");
}
+ EnigmailLog.DEBUG("enigRetrieveProgress: onLoadWkd: ident=" + senderIdent.email + ", supported=" + is_supported + "\n");
resolve(is_supported);
});
}).then(function(is_supported) {
+ let senderIdent = inArg.senderIdentities[i];
if (is_supported) {
let keyFpr = inArg.fprList[i];
- let senderIdent = inArg.senderIdentities[i];
return new Promise(function(resolve, reject) {
EnigmailWks.submitKey(senderIdent, {
'fpr': keyFpr
}, window, function(success) {
if (success) {
resolve(senderIdent);
}
else {
reject();
}
});
});
}
else {
- return new Promise.resolve(null);
+ return Promise.resolve(null);
}
});
uploads.push(was_uploaded);
}
Promise.all(uploads).catch(function(reason) {
let errorMsg = EnigmailLocale.getString("keyserverProgress.wksUploadFailed");
window.close();
gEnigCallbackFunc(-1, errorMsg, true);
}).then(function(senders) {
let uploaded_uids = [];
senders.forEach(function(val) {
if (val !== null) {
uploaded_uids.push(val.email);
}
});
progressDlg.setAttribute("value", 100);
progressDlg.setAttribute("mode", "normal");
EnigmailDialog.info(window, EnigmailLocale.getString("keyserverProgress.wksUploadCompleted"));
window.close();
});
}
catch (ex) {
EnigmailLog.DEBUG(ex);
}
}
function onLoadGpg(inArg) {
EnigmailLog.DEBUG("enigRetrieveProgress: onLoadGpg\n");
var subject;
var statTxt = document.getElementById("dialog.status2");
- if (inArg.accessType == nsIEnigmail.UPLOAD_KEY) {
+ if (inArg.accessType == nsIEnigmail.UPLOAD_KEY || inArg.accessType == nsIEnigmail.UPLOAD_WKD) {
statTxt.value = EnigmailLocale.getString("keyserverProgress.uploading");
subject = EnigmailLocale.getString("keyserverTitle.uploading");
}
else {
statTxt.value = EnigmailLocale.getString("keyserverProgress.refreshing");
subject = EnigmailLocale.getString("keyserverTitle.refreshing");
}
var procListener = {
done: function(exitCode) {
EnigmailLog.DEBUG("enigRetrieveProgress: subprocess terminated with " + exitCode + "\n");
processEnd(msgProgress, exitCode);
},
stdout: function(data) {
EnigmailLog.DEBUG("enigRetrieveProgress: got data on stdout: '" + data + "'\n");
},
stderr: function(data) {
EnigmailLog.DEBUG("enigRetrieveProgress: got data on stderr: '" + data + "'\n");
gErrorData += data;
}
};
msgProgress.registerListener(progressListener);
msgProgress.onStateChange(null, null, Ci.nsIWebProgressListener.STATE_START, 0);
var errorMsgObj = {};
gProcess = EnigmailKeyServer.access(inArg.accessType, inArg.keyServer, inArg.keyList, procListener, errorMsgObj);
if (!gProcess) {
EnigmailDialog.alert(window, EnigmailLocale.getString("sendKeysFailed") + "\n" + EnigmailData.convertGpgToUnicode(errorMsgObj.value));
}
document.getElementById("progressWindow").setAttribute("title", subject);
}
function onUnload() {
if (msgProgress) {
try {
msgProgress.unregisterListener(progressListener);
msgProgress = null;
}
catch (exception) {}
}
}
// If the user presses cancel, tell the app launcher and close the dialog...
function onCancel() {
try {
msgProgress.processCanceledByUser = true;
}
catch (ex) {
return true;
}
// don't Close up dialog by returning false, the backend will close the dialog when everything will be aborted.
return false;
}
function processEnd(progressBar, exitCode) {
EnigmailLog.DEBUG("enigmailRetrieveProgress.js: processEnd\n");
var errorMsg;
if (gProcess) {
gProcess = null;
EnigmailLog.DEBUG("enigmailRetrieveProgress.js: processEnd: exitCode = " + exitCode + "\n");
var statusText = gEnigCallbackFunc(exitCode, "", false);
errorMsg = "";
try {
if (gErrorData.length > 0) {
var statusFlagsObj = {};
var statusMsgObj = {};
errorMsg = EnigmailErrorHandling.parseErrorOutput(gErrorData, statusFlagsObj, statusMsgObj);
}
}
catch (ex) {}
EnigmailLog.DEBUG("enigmailRetrieveProgress.js: processEnd: errorMsg=" + errorMsg);
if (errorMsg.search(/ec=\d+/i) >= 0) {
exitCode = -1;
}
let j = errorMsg.search(/^\[GNUPG:\] IMPORT_RES/m);
if (j >= 0) {
let m = errorMsg.substr(j, 35).match(/^(\[GNUPG:\] IMPORT_RES +)([0-9]+)/);
if (m && m.length > 2) {
if (m[2] == "0") {
// no keys imported
exitCode = -2;
}
else {
exitCode = 0;
}
}
}
statusText = gEnigCallbackFunc(exitCode, "", false);
if (exitCode === 0) {
window.arguments[1].result = true;
}
}
if (progressBar) {
try {
progressBar.onStateChange(null, null, Ci.nsIWebProgressListener.STATE_STOP, 0);
}
catch (ex) {}
}
gEnigCallbackFunc(exitCode, errorMsg, true);
}
function enigSendKeyCancel() {
if (gProcess) {
var p = gProcess;
gEnigCallbackFunc = null;
gProcess = null;
p.kill(false);
}
}
diff --git a/ui/content/enigmailKeyManager.js b/ui/content/enigmailKeyManager.js
index 8c498a5c..1604311f 100644
--- a/ui/content/enigmailKeyManager.js
+++ b/ui/content/enigmailKeyManager.js
@@ -1,1999 +1,1938 @@
/*global Components: false, EnigInitCommon: false, EnigmailDialog: false */
/*
* 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/.
*/
"use strict";
// Uses: chrome://enigmail/content/enigmailCommon.js:
/* global EnigGetPref: false, EnigGetString: false, EnigFormatFpr: false, EnigGetTrustLabel: false, nsIEnigmail: false */
/* global GetEnigmailSvc: false, EnigConfirm: false, EnigAlert: false, EnigShowPhoto: false, EnigFilePicker: false */
/* global enigGetService: false, EnigGetTempDir: false, EnigReadFileContents: false, EnigGetLocalFileApi: false, EnigAlertPref: false */
/* global EnigEditKeyTrust: false, EnigEditKeyExpiry: false, EnigSignKey: false, EnigRevokeKey: false, EnigCreateRevokeCert: false */
/* global EnigLongAlert: false, EnigChangeKeyPwd: false, EnigDownloadKeys: false, EnigSetPref: false, EnigGetTrustCode: false */
/* global ENIG_KEY_DISABLED: false, ENIG_KEY_NOT_VALID: false, IOSERVICE_CONTRACTID: false, ENIG_LOCAL_FILE_CONTRACTID: false */
// imported packages
/* global EnigmailLog: false, EnigmailEvents: false, EnigmailKeyRing: false, EnigmailWindows: false, EnigmailKeyEditor: false */
/* global EnigmailKey: false, EnigmailLocale: false, EnigmailPrefs: false, EnigmailConstants: false */
// Initialize enigmailCommon
EnigInitCommon("enigmailKeyManager");
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://enigmail/streams.jsm"); /*global EnigmailStreams: false */
Cu.import("resource://enigmail/clipboard.jsm"); /*global EnigmailClipboard: false */
Cu.import("resource://enigmail/funcs.jsm"); /*global EnigmailFuncs: false */
Cu.import("resource://enigmail/stdlib.jsm"); /*global EnigmailStdlib: false */
Cu.import("resource://enigmail/pEpAdapter.jsm"); /*global EnigmailPEPAdapter: false */
+Cu.import("resource://enigmail/windows.jsm"); /*global EnigmailWindows: false */
+Cu.import("resource://enigmail/keyserver.jsm"); /*global EnigmailKeyServer: false */
const INPUT = 0;
const RESULT = 1;
const IOSERVICE_CONTRACTID = "@mozilla.org/network/io-service;1";
var gUserList;
var gKeyList;
var gEnigLastSelectedKeys = null;
var gKeySortList = null;
var gSearchInput = null;
var gShowAllKeysElement = null;
var gTreeChildren = null;
var gShowInvalidKeys = null;
var gShowUntrustedKeys = null;
var gShowOthersKeys = null;
var gPepKeyBlacklist = [];
function enigmailKeyManagerLoad() {
EnigmailLog.DEBUG("enigmailKeyManager.js: enigmailKeyManagerLoad\n");
gUserList = document.getElementById("pgpKeyList");
gSearchInput = document.getElementById("filterKey");
gShowAllKeysElement = document.getElementById("showAllKeys");
gTreeChildren = document.getElementById("pgpKeyListChildren");
gShowInvalidKeys = document.getElementById("showInvalidKeys");
gShowUntrustedKeys = document.getElementById("showUntrustedKeys");
gShowOthersKeys = document.getElementById("showOthersKeys");
window.addEventListener("reload-keycache", reloadKeys);
if (EnigGetPref("keyManShowAllKeys")) {
gShowAllKeysElement.setAttribute("checked", "true");
}
if (EnigmailPEPAdapter.usingPep()) {
pEpLoadBlacklist();
}
else {
let c = document.getElementById("pepBlacklistCol");
c.parentNode.removeChild(c);
}
gUserList.addEventListener('click', onListClick, true);
document.getElementById("bcEnableKey").setAttribute("label", EnigGetString("keyMan.disableKey"));
document.getElementById("pleaseWait").showPopup(gSearchInput, -1, -1, "tooltip", "after_end", "");
document.getElementById("statusText").value = EnigGetString("keyMan.loadingKeys");
document.getElementById("progressBar").removeAttribute("collapsed");
EnigmailEvents.dispatchEvent(loadkeyList, 100, null);
gUserList.view = gKeyListView;
gSearchInput.focus();
}
function displayFullList() {
return (gShowAllKeysElement.getAttribute("checked") == "true");
}
function loadkeyList() {
EnigmailLog.DEBUG("enigmailKeyManager.js: loadkeyList\n");
sortTree();
gKeyListView.applyFilter(0);
document.getElementById("pleaseWait").hidePopup();
document.getElementById("statusText").value = " ";
document.getElementById("progressBar").setAttribute("collapsed", "true");
}
function clearKeyCache() {
EnigmailKeyRing.clearCache();
refreshKeys();
}
function refreshKeys() {
EnigmailLog.DEBUG("enigmailKeyManager.js: refreshKeys\n");
var keyList = getSelectedKeys();
gEnigLastSelectedKeys = [];
for (var i = 0; i < keyList.length; i++) {
gEnigLastSelectedKeys[keyList[i]] = 1;
}
buildKeyList(true);
}
function reloadKeys() {
buildKeyList(false);
}
function buildKeyList(refresh) {
EnigmailLog.DEBUG("enigmailKeyManager.js: buildKeyList\n");
var keyListObj = {};
// if (refresh) {
// EnigmailKeyRing.clearCache();
// }
keyListObj = EnigmailKeyRing.getAllKeys(window, getSortColumn(), getSortDirection());
if (!keyListObj.keySortList) return;
if (gUserList.getAttribute("sortResource") === "pepBlacklistCol") {
let sortDirection = (gUserList.getAttribute("sortDirection") === "ascending" ? 1 : -1);
keyListObj.keySortList.sort(function(a, b) {
let i1 = gPepKeyBlacklist.indexOf(a.fpr) >= 0 ? 1 : 0;
let i2 = gPepKeyBlacklist.indexOf(b.fpr) >= 0 ? 1 : 0;
return (i1 > i2) ? -sortDirection : sortDirection;
});
}
gKeyList = keyListObj.keyList;
gKeySortList = keyListObj.keySortList;
gKeyListView.keysRefreshed();
return;
}
function getSelectedKeys() {
let selList = [];
let rangeCount = gUserList.view.selection.getRangeCount();
for (let i = 0; i < rangeCount; i++) {
let start = {};
let end = {};
gUserList.view.selection.getRangeAt(i, start, end);
for (let c = start.value; c <= end.value; c++) {
try {
//selList.push(gUserList.view.getItemAtIndex(c).getAttribute("keyNum"));
selList.push(gKeyListView.getFilteredRow(c).keyNum);
}
catch (ex) {
return [];
}
}
}
return selList;
}
function getSelectedKeyIds() {
let keyList = getSelectedKeys();
let a = [];
for (let i in keyList) {
a.push(gKeyList[keyList[i]].keyId);
}
return a;
}
function enigmailKeyMenu() {
var keyList = getSelectedKeys();
if (keyList.length == 1 && gKeyList[keyList[0]].secretAvailable) {
document.getElementById("bcRevoke").removeAttribute("collapsed");
document.getElementById("bcEditKey").removeAttribute("collapsed");
}
else {
document.getElementById("bcRevoke").setAttribute("collapsed", "true");
document.getElementById("bcEditKey").setAttribute("collapsed", "true");
document.getElementById("bcUploadToWkd").setAttribute("disabled", "true");
}
if (keyList.length == 1 && gKeyList[keyList[0]].photoAvailable) {
document.getElementById("bcViewPhoto").removeAttribute("collapsed");
}
else {
document.getElementById("bcViewPhoto").setAttribute("collapsed", "true");
}
if (enigGetClipboard().length > 0) {
document.getElementById("bcClipbrd").removeAttribute("disabled");
}
else {
document.getElementById("bcClipbrd").setAttribute("disabled", "true");
}
if (keyList.length >= 1) {
document.getElementById("bcEnableKey").removeAttribute("disabled");
if (gKeyList[keyList[0]].keyUseFor.indexOf("D") > 0 ||
gKeyList[keyList[0]].keyTrust.indexOf(ENIG_KEY_DISABLED) >= 0) {
document.getElementById("bcEnableKey").setAttribute("label", EnigGetString("keyMan.enableKey"));
}
else {
document.getElementById("bcEnableKey").setAttribute("label", EnigGetString("keyMan.disableKey"));
}
}
if (keyList.length == 1) {
document.getElementById("bcSignKey").removeAttribute("disabled");
document.getElementById("bcOneKey").removeAttribute("disabled");
document.getElementById("bcDeleteKey").removeAttribute("disabled");
document.getElementById("bcNoKey").removeAttribute("disabled");
}
else {
if (keyList.length === 0) {
document.getElementById("bcNoKey").setAttribute("disabled", "true");
document.getElementById("bcEnableKey").setAttribute("disabled", "true");
}
else {
document.getElementById("bcNoKey").removeAttribute("disabled");
}
document.getElementById("bcSignKey").setAttribute("disabled", "true");
document.getElementById("bcOneKey").setAttribute("disabled", "true");
document.getElementById("bcDeleteKey").setAttribute("disabled", "true");
}
}
function onListClick(event) {
if (event.detail > 2) return;
if (event.type === "click") {
// Mouse event
let row = {};
let col = {};
let elt = {};
gUserList.treeBoxObject.getCellAt(event.clientX, event.clientY, row, col, elt);
if (!col.value) // not clicked on a valid column (e.g. scrollbar)
return;
if ((event.detail === 1) && (col.value.id === "pepBlacklistCol")) {
pEpHandleBlacklistClick(row.value);
}
}
if (event.detail != 2) {
return;
}
// do not propagate double clicks
event.stopPropagation();
var keyList = getSelectedKeys();
var keyType = "";
var uatNum = "";
if (keyList.length == 1) {
var rangeCount = gUserList.view.selection.getRangeCount();
var start = {};
var end = {};
gUserList.view.selection.getRangeAt(0, start, end);
try {
keyType = gUserList.view.getItemAtIndex(start.value).getAttribute("keytype");
uatNum = gUserList.view.getItemAtIndex(start.value).getAttribute("uatNum");
}
catch (ex) {}
}
if (keyType == "uat") {
enigShowSpecificPhoto(Number(uatNum));
}
else {
enigmailKeyDetails();
}
}
function enigmailSelectAllKeys() {
gUserList.view.selection.selectAll();
}
function enigmailKeyDetails() {
var keyList = getSelectedKeys();
if (keyList.length > 0) {
if (EnigmailWindows.openKeyDetails(window, gKeyList[keyList[0]].keyId, false)) {
refreshKeys();
}
}
}
function pEpLoadBlacklist() {
let inspector = Cc["@mozilla.org/jsinspector;1"].createInstance(Ci.nsIJSInspector);
EnigmailPEPAdapter.pep.blacklistGetKeyList().then(
function _ok(retObj) {
if (retObj && typeof(retObj) === "object" && "result" in retObj) {
gPepKeyBlacklist = retObj.result.outParams[0].map(
function _upperCase(x) {
return x.toUpperCase();
});
}
if (inspector && inspector.eventLoopNestLevel > 0) {
// unblock the waiting lock in finishCryptoEncapsulation
inspector.exitNestedEventLoop();
}
}
).catch(function _err(retObj) {
gPepKeyBlacklist = [];
if (inspector && inspector.eventLoopNestLevel > 0) {
// unblock the waiting lock in finishCryptoEncapsulation
inspector.exitNestedEventLoop();
}
});
inspector.enterNestedEventLoop(0);
}
function pEpHandleBlacklistClick(rowNum) {
let action = 0;
let msg = "";
let button = "";
let key;
let keyList = getSelectedKeys();
if (keyList.length == 1) {
key = gKeyList[keyList[0]];
if (gPepKeyBlacklist.indexOf(key.fpr) >= 0) {
action = -1;
msg = EnigmailLocale.getString("keyman.removeBlacklistKey.msg", [key.userId, key.fprFormatted]);
button = EnigmailLocale.getString("keyman.removeBlacklistKey.button");
}
else {
action = 1;
msg = EnigmailLocale.getString("keyman.addBlacklistKey.msg", [key.userId, key.fprFormatted]);
button = EnigmailLocale.getString("keyman.addBlacklistKey.button");
}
}
else return;
if (EnigmailDialog.confirmDlg(window, msg, button)) {
let blacklistOp;
if (action > 0) {
blacklistOp = EnigmailPEPAdapter.pep.blacklistAddKey.bind(EnigmailPEPAdapter.pep);
}
else {
blacklistOp = EnigmailPEPAdapter.pep.blacklistDeleteKey.bind(EnigmailPEPAdapter.pep);
}
blacklistOp(key.fpr).then(function _f(x) {
EnigmailLog.DEBUG("enigmailKeyManager.js: pEpHandleBlacklistClick: success\n");
pEpLoadBlacklist();
gUserList.treeBoxObject.invalidateRow(rowNum);
}).
catch(function _err(x) {
EnigmailLog.DEBUG("enigmailKeyManager.js: pEpHandleBlacklistClick: got Error: " + JSON.stringify(x) + "\n");
});
}
}
function enigmailDeleteKey() {
var keyList = getSelectedKeys();
var deleteSecret = false;
var enigmailSvc = GetEnigmailSvc();
if (!enigmailSvc)
return;
if (keyList.length == 1) {
// one key selected
var userId = gKeyList[keyList[0]].userId;
if (gKeyList[keyList[0]].secretAvailable) {
if (!EnigConfirm(EnigGetString("deleteSecretKey", userId), EnigGetString("dlg.button.delete"))) return;
deleteSecret = true;
}
else {
if (!EnigConfirm(EnigGetString("deletePubKey", userId), EnigGetString("dlg.button.delete"))) return;
}
}
else {
// several keys selected
for (var i = 0; i < keyList.length; i++) {
if (gKeyList[keyList[i]].secretAvailable) deleteSecret = true;
}
if (deleteSecret) {
if (!EnigConfirm(EnigGetString("deleteMix"), EnigGetString("dlg.button.delete"))) return;
}
else {
if (!EnigConfirm(EnigGetString("deleteSelectedPubKey"), EnigGetString("dlg.button.delete"))) return;
}
}
let fprArr = [];
for (let j in keyList) {
fprArr.push("0x" + gKeyList[keyList[j]].fpr);
}
EnigmailKeyEditor.deleteKey(window, fprArr.join(" "), deleteSecret,
function(exitCode, errorMsg) {
if (exitCode !== 0) {
EnigAlert(EnigGetString("deleteKeyFailed") + "\n\n" + errorMsg);
return;
}
refreshKeys();
});
}
function enigmailEnableKey() {
var enigmailSvc = GetEnigmailSvc();
if (!enigmailSvc)
return;
var keyList = getSelectedKeys();
var disableKey = (gKeyList[keyList[0]].keyUseFor.indexOf("D") < 0 &&
gKeyList[keyList[0]].keyTrust.indexOf(ENIG_KEY_DISABLED) < 0);
var keyIndex = 0;
function processNextKey() {
EnigmailKeyEditor.enableDisableKey(window, "0x" + gKeyList[keyList[keyIndex]].keyId, disableKey, function _enDisCb(exitCode, errorMsg) {
if (exitCode === 0) {
++keyIndex;
if (keyIndex < keyList.length) {
processNextKey();
return;
}
else {
refreshKeys();
}
}
else {
EnigAlert(EnigGetString("enableKeyFailed") + "\n\n" + errorMsg);
if (keyIndex > 0) refreshKeys();
}
});
}
processNextKey();
}
function enigShowPhoto() {
var keyList = getSelectedKeys();
var keyType = "";
var uatNum = "";
if (keyList.length == 1) {
var rangeCount = gUserList.view.selection.getRangeCount();
var start = {};
var end = {};
gUserList.view.selection.getRangeAt(0, start, end);
try {
keyType = gUserList.view.getItemAtIndex(start.value).getAttribute("keytype");
uatNum = gUserList.view.getItemAtIndex(start.value).getAttribute("uatNum");
}
catch (ex) {}
if (keyType == "uat") {
enigShowSpecificPhoto(uatNum);
return;
}
}
enigShowSpecificPhoto(null);
}
function enigShowSpecificPhoto(uatNumber) {
var keyList = getSelectedKeys();
EnigShowPhoto(gKeyList[keyList[0]].keyId, gKeyList[keyList[0]].userId, uatNumber);
}
function enigmailAddPhoto() {
var keyList = getSelectedKeys();
keyMgrAddPhoto(gKeyList[keyList[0]].userId, gKeyList[keyList[0]].keyId);
}
function keyMgrAddPhoto(userId, keyId) {
var enigmailSvc = GetEnigmailSvc();
if (!enigmailSvc)
return;
var inFile;
var validFile = false;
while (!validFile) {
inFile = EnigFilePicker(EnigGetString("keyMan.addphoto.filepicker.title"),
"", false, "*.jpg",
null, ["JPG", "*.jpg", "JPEG", "*.jpeg"]);
if (!inFile) return;
var jpgHeader = EnigReadFileContents(inFile, 10);
validFile = (jpgHeader.charCodeAt(0) == 0xFF &&
jpgHeader.charCodeAt(1) == 0xD8 &&
jpgHeader.substr(6, 4) == "JFIF");
if (!validFile) {
EnigAlert(EnigGetString("keyMan.addphoto.noJpegFile"));
}
}
if (inFile.fileSize > 25600) {
// warn if file size > 25 kB
if (!EnigConfirm(EnigGetString("keyMan.addphoto.warnLargeFile"), EnigGetString("dlg.button.continue"), EnigGetString("dlg.button.cancel")))
return;
}
var ioServ = enigGetService(IOSERVICE_CONTRACTID, "nsIIOService");
var photoUri = ioServ.newFileURI(inFile).spec;
var argsObj = {
photoUri: photoUri,
userId: userId,
keyId: keyId,
okPressed: false
};
window.openDialog("chrome://enigmail/content/enigmailImportPhoto.xul", inFile, "chrome,modal=1,resizable=1,dialog=1,centerscreen", argsObj);
if (!argsObj.okPressed) return;
EnigmailKeyEditor.addPhoto(window, "0x" + keyId, inFile,
function(exitCode, errorMsg) {
if (exitCode !== 0) {
EnigAlert(EnigGetString("keyMan.addphoto.failed") + "\n\n" + errorMsg);
return;
}
refreshKeys();
});
}
function enigCreateKeyMsg() {
var enigmailSvc = GetEnigmailSvc();
if (!enigmailSvc)
return;
var keyList = getSelectedKeyIds();
if (keyList.length === 0) {
EnigAlert(EnigGetString("noKeySelected"));
return;
}
var tmpDir = EnigGetTempDir();
var tmpFile;
try {
tmpFile = Cc[ENIG_LOCAL_FILE_CONTRACTID].createInstance(EnigGetLocalFileApi());
tmpFile.initWithPath(tmpDir);
if (!(tmpFile.isDirectory() && tmpFile.isWritable())) {
EnigAlert(EnigGetString("noTempDir"));
return;
}
}
catch (ex) {}
tmpFile.append("key.asc");
tmpFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0x180); // equals 0600
// save file
var exitCodeObj = {};
var errorMsgObj = {};
EnigmailKeyRing.extractKey(false, "0x" + keyList.join(" 0x"), tmpFile, exitCodeObj, errorMsgObj);
if (exitCodeObj.value !== 0) {
EnigAlert(errorMsgObj.value);
return;
}
// create attachment
var ioServ = Cc[IOSERVICE_CONTRACTID].getService(Ci.nsIIOService);
var tmpFileURI = ioServ.newFileURI(tmpFile);
var keyAttachment = Cc["@mozilla.org/messengercompose/attachment;1"].createInstance(Ci.nsIMsgAttachment);
keyAttachment.url = tmpFileURI.spec;
if (keyList.length == 1) {
keyAttachment.name = "0x" + keyList[0] + ".asc";
}
else {
keyAttachment.name = "pgpkeys.asc";
}
keyAttachment.temporary = true;
keyAttachment.contentType = "application/pgp-keys";
// create Msg
var msgCompFields = Cc["@mozilla.org/messengercompose/composefields;1"].createInstance(Ci.nsIMsgCompFields);
msgCompFields.addAttachment(keyAttachment);
var acctManager = Cc["@mozilla.org/messenger/account-manager;1"].createInstance(Ci.nsIMsgAccountManager);
var msgCompSvc = Cc["@mozilla.org/messengercompose;1"].getService(Ci.nsIMsgComposeService);
var msgCompParam = Cc["@mozilla.org/messengercompose/composeparams;1"].createInstance(Ci.nsIMsgComposeParams);
msgCompParam.composeFields = msgCompFields;
msgCompParam.identity = acctManager.defaultAccount.defaultIdentity;
msgCompParam.type = Ci.nsIMsgCompType.New;
msgCompParam.format = Ci.nsIMsgCompFormat.Default;
msgCompParam.originalMsgURI = "";
msgCompSvc.OpenComposeWindowWithParams("", msgCompParam);
}
function createNewMail() {
var keyList = getSelectedKeys();
if (keyList.length === 0) {
EnigmailDialog.info(window, EnigGetString("noKeySelected"));
return;
}
var addresses = [];
var rangeCount = gUserList.view.selection.getRangeCount();
var start = {};
var end = {};
var keyType, keyNum, r, i;
for (i = 0; i < rangeCount; i++) {
gUserList.view.selection.getRangeAt(i, start, end);
for (r = start.value; r <= end.value; r++) {
try {
keyType = gUserList.view.getItemAtIndex(r).getAttribute("keytype");
keyNum = gUserList.view.getItemAtIndex(r).getAttribute("keyNum");
if (keyType == "uid") {
var uidNum = Number(gUserList.view.getItemAtIndex(r).getAttribute("uidNum"));
addresses.push(gKeyList[keyNum].userIds[uidNum].userId);
}
else
addresses.push(gKeyList[keyNum].userId);
}
catch (ex) {}
}
}
// create Msg
var msgCompFields = Cc["@mozilla.org/messengercompose/composefields;1"].createInstance(Ci.nsIMsgCompFields);
msgCompFields.to = addresses.join(", ");
var acctManager = Cc["@mozilla.org/messenger/account-manager;1"].createInstance(Ci.nsIMsgAccountManager);
var msgCompSvc = Cc["@mozilla.org/messengercompose;1"].getService(Ci.nsIMsgComposeService);
var msgCompParam = Cc["@mozilla.org/messengercompose/composeparams;1"].createInstance(Ci.nsIMsgComposeParams);
msgCompParam.composeFields = msgCompFields;
msgCompParam.identity = acctManager.defaultAccount.defaultIdentity;
msgCompParam.type = Ci.nsIMsgCompType.New;
msgCompParam.format = Ci.nsIMsgCompFormat.Default;
msgCompParam.originalMsgURI = "";
msgCompSvc.OpenComposeWindowWithParams("", msgCompParam);
}
function enigEditKeyTrust() {
var keyList = getSelectedKeys();
if (keyList.length === 0) {
EnigmailDialog.info(window, EnigGetString("noKeySelected"));
return;
}
var userIdList = [];
var keyIds = [];
for (var i = 0; i < keyList.length; i++) {
userIdList.push(gKeyList[keyList[i]].userId);
keyIds.push(gKeyList[keyList[i]].keyId);
}
if (EnigEditKeyTrust(userIdList, keyIds)) {
refreshKeys();
}
}
function enigEditKeyExpiry() {
var keyList = getSelectedKeys();
if (keyList.length === 0) {
EnigmailDialog.info(window, EnigGetString("noKeySelected"));
return;
}
var userIdList = [];
var keyIds = [];
for (var i = 0; i < keyList.length; i++) {
userIdList.push(gKeyList[keyList[i]].userId);
keyIds.push(gKeyList[keyList[i]].keyId);
}
if (EnigEditKeyExpiry(userIdList, keyIds)) {
refreshKeys();
}
}
function enigSignKey() {
var keyList = getSelectedKeys();
if (keyList.length === 0) {
EnigmailDialog.info(window, EnigGetString("noKeySelected"));
return;
}
if (EnigSignKey(gKeyList[keyList[0]].userId, gKeyList[keyList[0]].keyId, null)) {
refreshKeys();
}
}
function enigmailRevokeKey() {
var keyList = getSelectedKeys();
EnigRevokeKey(gKeyList[keyList[0]].keyId, gKeyList[keyList[0]].userId, function _revokeKeyCb(success) {
if (success) refreshKeys();
});
}
function enigCreateRevokeCert() {
var keyList = getSelectedKeys();
EnigCreateRevokeCert(gKeyList[keyList[0]].keyId, gKeyList[keyList[0]].userId);
}
function enigmailExportKeys() {
var keyList = getSelectedKeys();
if (keyList.length === 0) {
EnigmailDialog.info(window, EnigGetString("noKeySelected"));
return;
}
// check whether we want to export a private key anywhere in the key list
var secretFound = false;
for (var i = 0; i < keyList.length && !secretFound; ++i) {
if (gKeyList[keyList[i]].secretAvailable) {
secretFound = true;
}
}
var exportSecretKey = false;
if (secretFound) {
// double check that also the pivate keys shall be exportet
var r = EnigmailDialog.msgBox(window, {
msgtext: EnigGetString("exportSecretKey"),
dialogTitle: EnigGetString("enigConfirm"),
button1: EnigGetString("keyMan.button.exportPubKey"),
button2: EnigGetString("keyMan.button.exportSecKey"),
cancelButton: ":cancel",
iconType: EnigmailConstants.ICONTYPE_QUESTION
});
switch (r) {
case 0: // export pub key only
break;
case 1: // export secret key
exportSecretKey = true;
break;
default: // cancel
return;
}
}
var enigmailSvc = GetEnigmailSvc();
if (!enigmailSvc)
return;
var defaultFileName;
if (keyList.length == 1) {
defaultFileName = gKeyList[keyList[0]].userId.replace(/[<>]/g, "");
if (exportSecretKey) {
defaultFileName = EnigGetString("specificPubSecKeyFilename", defaultFileName, gKeyList[keyList[0]].keyId) + ".asc";
}
else {
defaultFileName = EnigGetString("specificPubKeyFilename", defaultFileName, gKeyList[keyList[0]].keyId) + ".asc";
}
}
else {
if (exportSecretKey) {
defaultFileName = EnigGetString("defaultPubSecKeyFilename") + ".asc";
}
else {
defaultFileName = EnigGetString("defaultPubKeyFilename") + ".asc";
}
}
var FilePickerLabel = "";
if (exportSecretKey) {
FilePickerLabel = EnigGetString("exportKeypairToFile");
}
else {
FilePickerLabel = EnigGetString("exportToFile");
}
var outFile = EnigFilePicker(FilePickerLabel,
"", true, "*.asc",
defaultFileName, [EnigGetString("asciiArmorFile"), "*.asc"]);
if (!outFile) return;
var keyListStr = "0x" + getSelectedKeyIds().join(" 0x");
var exitCodeObj = {};
var errorMsgObj = {};
EnigmailKeyRing.extractKey(exportSecretKey, keyListStr, outFile, exitCodeObj, errorMsgObj);
if (exitCodeObj.value !== 0) {
EnigAlert(EnigGetString("saveKeysFailed") + "\n\n" + errorMsgObj.value);
}
else {
EnigmailDialog.info(window, EnigGetString("saveKeysOK"));
}
}
function enigmailImportKeysFromFile() {
var enigmailSvc = GetEnigmailSvc();
if (!enigmailSvc)
return;
var inFile = EnigFilePicker(EnigGetString("importKeyFile"),
"", false, "*.asc", "", [EnigGetString("gnupgFile"), "*.asc;*.gpg;*.pgp"]);
if (!inFile) return;
var errorMsgObj = {};
// preview
var preview = EnigmailKey.getKeyListFromKeyFile(inFile, errorMsgObj);
if (errorMsgObj.value && errorMsgObj.value.length > 0) {
EnigmailDialog.alert(window, errorMsgObj.value);
return;
}
var exitStatus = -1;
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) {
// import
var keyListObj = {};
var exitCode = EnigmailKeyRing.importKeyFromFile(inFile, errorMsgObj, keyListObj);
if (exitCode !== 0) {
EnigAlert(EnigGetString("importKeysFailed") + "\n\n" + errorMsgObj.value);
}
else {
var keyList = preview.map(function(a) {
return a.id;
});
EnigmailDialog.keyImportDlg(window, keyList);
}
refreshKeys();
}
}
else {
if (EnigmailKeyRing.getCacheEmpty()) {
refreshKeys();
}
}
}
function enigmailManageUids() {
var keyList = getSelectedKeys();
var inputObj = {
keyId: gKeyList[keyList[0]].keyId,
ownKey: gKeyList[keyList[0]].secretAvailable
};
var resultObj = {
refresh: false
};
window.openDialog("chrome://enigmail/content/enigmailManageUidDlg.xul",
"", "dialog,modal,centerscreen,resizable=yes", inputObj, resultObj);
if (resultObj.refresh) {
refreshKeys();
}
}
function enigmailChangePwd() {
var keyList = getSelectedKeys();
EnigChangeKeyPwd(gKeyList[keyList[0]].keyId, gKeyList[keyList[0]].userId);
}
function enigGetClipboard() {
return EnigmailClipboard.getClipboardContent(window, Ci.nsIClipboard.kGlobalClipboard);
}
function enigmailImportFromClipbrd() {
var enigmailSvc = GetEnigmailSvc();
if (!enigmailSvc)
return;
if (!EnigConfirm(EnigGetString("importFromClip"), EnigGetString("keyMan.button.import"))) {
return;
}
var cBoardContent = enigGetClipboard();
var errorMsgObj = {};
var preview = EnigmailKey.getKeyListFromKeyBlock(cBoardContent, errorMsgObj);
var exitStatus = -1;
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) {
// import
var r = EnigmailKeyRing.importKey(window, false, cBoardContent, "", errorMsgObj);
var keyList = preview.map(function(a) {
return a.id;
});
EnigmailDialog.keyImportDlg(window, keyList);
refreshKeys();
}
}
}
function enigmailCopyToClipbrd() {
var enigmailSvc = GetEnigmailSvc();
if (!enigmailSvc)
return;
var keyList = getSelectedKeyIds();
if (keyList.length === 0) {
EnigmailDialog.info(window, EnigGetString("noKeySelected"));
return;
}
var exitCodeObj = {};
var errorMsgObj = {};
var keyData = EnigmailKeyRing.extractKey(0, "0x" + keyList.join(" 0x"), null, exitCodeObj, errorMsgObj);
if (exitCodeObj.value !== 0) {
EnigAlert(EnigGetString("copyToClipbrdFailed") + "\n\n" + errorMsgObj.value);
return;
}
if (EnigmailClipboard.setClipboardContent(keyData)) {
EnigmailLog.DEBUG("enigmailKeyManager.js: enigmailImportFromClipbrd: set clipboard data\n");
EnigmailDialog.info(window, EnigGetString("copyToClipbrdOK"));
}
else {
EnigAlert(EnigGetString("copyToClipbrdFailed"));
}
}
function enigmailSearchKey() {
var inputObj = {
searchList: null
};
var resultObj = {};
EnigDownloadKeys(inputObj, resultObj);
if (resultObj.importedKeys > 0) {
refreshKeys();
}
}
function enigmailUploadKeys() {
enigmailKeyServerAccess(nsIEnigmail.UPLOAD_KEY, enigmailUploadKeysCb);
}
function enigmailUploadKeysCb(exitCode, errorMsg, msgBox) {
if (msgBox) {
if (exitCode !== 0) {
EnigAlert(EnigGetString("sendKeysFailed") + "\n" + errorMsg);
}
}
else {
return (EnigGetString(exitCode === 0 ? "sendKeysOk" : "sendKeysFailed"));
}
return "";
}
function enigmailUploadToWkd() {
enigmailKeyServerAccess(nsIEnigmail.UPLOAD_WKD, enigmailUploadToWkdCb);
}
function enigmailUploadToWkdCb(exitCode, errorMsg, msgBox) {
if (msgBox) {
if (exitCode !== 0) {
EnigAlert(EnigGetString("sendKeysFailed") + "\n" + errorMsg);
}
}
else {
return (EnigGetString(exitCode === 0 ? "sendKeysOk" : "sendKeysFailed"));
}
return "";
}
function enigmailReceiveKey() {
enigmailKeyServerAccess(nsIEnigmail.DOWNLOAD_KEY, enigmailReceiveKeyCb);
}
function userAcceptsWarning(warningMessage) {
if (!EnigGetPref("warnRefreshAll")) {
return true;
}
let checkedObj = {};
let confirm = EnigmailDialog.msgBox(window, {
msgtext: warningMessage,
checkboxLabel: EnigGetString("dlgNoPrompt"),
button1: EnigGetString("dlg.button.continue"),
cancelButton: ":cancel",
iconType: EnigmailConstants.ICONTYPE_QUESTION,
dialogTitle: EnigmailLocale.getString("enigConfirm")
},
checkedObj) === 0;
if (checkedObj.value)
EnigSetPref("warnRefreshAll", false);
return confirm;
}
function userAcceptsRefreshWarning() {
if (EnigmailPrefs.getPref("keyRefreshOn") === true) {
return userAcceptsWarning(EnigGetString("refreshKeyServiceOn.warn"));
}
return userAcceptsWarning(EnigGetString("refreshKey.warn"));
}
function enigmailRefreshAllKeys() {
if (userAcceptsRefreshWarning() === true) {
enigmailKeyServerAccess(nsIEnigmail.REFRESH_KEY, enigmailReceiveKeyCb);
}
}
// Iterate through contact emails and download them
function enigmailDowloadContactKeysEngine() {
let abManager = Cc["@mozilla.org/abmanager;1"].getService(Ci.nsIAbManager);
let allAddressBooks = abManager.directories;
let emails = [];
while (allAddressBooks.hasMoreElements()) {
let addressBook = allAddressBooks.getNext().QueryInterface(Ci.nsIAbDirectory);
if (addressBook instanceof Ci.nsIAbDirectory) { // or nsIAbItem or nsIAbCollection
// ask for confirmation for each address book:
var doIt = EnigmailDialog.confirmDlg(window,
EnigGetString("downloadContactsKeys.importFrom", addressBook.dirName),
EnigGetString("dlgYes"),
EnigGetString("dlg.button.skip"));
if (!doIt) {
continue; // SKIP this address book
}
let allChildCards = addressBook.childCards;
while (allChildCards.hasMoreElements()) {
let card = allChildCards.getNext().QueryInterface(Ci.nsIAbCard);
try {
let email = card.getPropertyAsAString("PrimaryEmail");
if (email && email.indexOf("@") >= 0) {
emails.push(email);
}
}
catch (e) {}
try {
let email = card.getPropertyAsAString("SecondEmail");
if (email && email.indexOf("@") >= 0) {
emails.push(email);
}
}
catch (e) {}
}
}
}
// list of emails might be emoty here, in which case we do nothing
if (emails.length <= 0) {
return;
}
// sort the e-mail array
emails.sort();
//remove duplicates
var i = 0;
while (i < emails.length - 1) {
if (emails[i] == emails[i + 1]) {
emails.splice(i, 1);
}
else {
i = i + 1;
}
}
var inputObj = {
searchList: emails,
autoKeyServer: EnigmailPrefs.getPref("autoKeyServerSelection") ? EnigmailPrefs.getPref("keyserver").split(/[ ,;]/g)[0] : null
};
var resultObj = {};
EnigmailWindows.downloadKeys(window, inputObj, resultObj);
if (resultObj.importedKeys > 0) {
refreshKeys();
}
}
function enigmailDownloadContactKeys() {
var doIt = EnigmailDialog.confirmPref(window,
EnigGetString("downloadContactsKeys.warn"),
"warnDownloadContactKeys",
EnigGetString("dlg.button.continue"),
EnigGetString("dlg.button.cancel"));
if (doIt) enigmailDowloadContactKeysEngine();
}
function displayResult(arrayOfMsgText) {
EnigmailDialog.info(window, arrayOfMsgText.join("\n"));
}
function enigmailReceiveKeyCb(exitCode, errorMsg, msgBox) {
EnigmailLog.DEBUG("enigmailKeyManager.js: enigmailReceiveKeyCb\n");
if (msgBox) {
if (exitCode === 0) {
refreshKeys();
EnigmailEvents.dispatchEvent(displayResult, 100, [EnigGetString("receiveKeysOk"), errorMsg]);
}
else {
EnigmailEvents.dispatchEvent(displayResult, 100, [EnigGetString("receiveKeysFailed"), errorMsg]);
}
}
else {
return (EnigGetString(exitCode === 0 ? "receiveKeysOk" : "receiveKeysFailed"));
}
return "";
}
function addToPRRule() {
var keyList = getSelectedKeys();
if (keyList.length === 0) {
EnigmailDialog.info(window, EnigGetString("noKeySelected"));
return;
}
var enigmailSvc = GetEnigmailSvc();
if (!enigmailSvc)
return;
var inputObj = {
keyId: gKeyList[keyList[0]].keyId,
userId: gKeyList[keyList[0]].userId
};
window.openDialog("chrome://enigmail/content/enigmailSelectRule.xul",
"", "dialog,modal,centerscreen", inputObj);
}
function enigmailImportKeysFromUrl() {
var value = {
"value": ""
};
if (EnigmailDialog.promptValue(window, EnigGetString("importFromUrl"), value)) {
var p = new Promise(
function(resolve, reject) {
var cbFunc = function _cb(data) {
EnigmailLog.DEBUG("enigmailImportKeysFromUrl: _cbFunc()\n");
var errorMsgObj = {};
// preview
var preview = EnigmailKey.getKeyListFromKeyBlock(data, errorMsgObj);
var exitStatus = -1;
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) {
EnigmailKeyRing.importKey(window, false, data, "", errorMsgObj);
errorMsgObj.preview = preview;
resolve(errorMsgObj);
}
}
};
try {
var bufferListener = EnigmailStreams.newStringStreamListener(cbFunc);
var ioServ = Cc[IOSERVICE_CONTRACTID].getService(Components.interfaces.nsIIOService);
var msgUri = ioServ.newURI(value.value, null, null);
var channel = EnigmailStreams.createChannelFromURI(msgUri);
channel.asyncOpen(bufferListener, msgUri);
}
catch (ex) {
var err = {
value: ex
};
reject(err);
}
}
);
p.then(function(errorMsgObj) {
var keyList = errorMsgObj.preview.map(function(a) {
return a.id;
});
EnigmailDialog.keyImportDlg(window, keyList);
refreshKeys();
})
.catch(function(reason) {
EnigmailDialog.alert(window, EnigGetString("generalError", [reason.value]));
});
}
}
//
// ----- key filtering functionality -----
//
function onSearchInput() {
gKeyListView.applyFilter(0);
}
function enigmailToggleShowAll() {
EnigSetPref("keyManShowAllKeys", displayFullList());
if (!gSearchInput.value || gSearchInput.value.length === 0) {
gKeyListView.applyFilter(0);
}
}
function determineHiddenKeys(keyObj, showInvalidKeys, showUntrustedKeys, showOthersKeys) {
var show = true;
const INVALID_KEYS = "ierdD";
const UNTRUSTED_KEYS = "n-";
if ((!showInvalidKeys) && INVALID_KEYS.indexOf(EnigGetTrustCode(keyObj)) >= 0) show = false;
if ((!showUntrustedKeys) && UNTRUSTED_KEYS.indexOf(keyObj.ownerTrust) >= 0) show = false;
if ((!showOthersKeys) && (!keyObj.secretAvailable)) show = false;
return show;
}
//
// ----- keyserver related functionality ----
//
function enigmailKeyServerAccess(accessType, callbackFunc) {
var enigmailSvc = GetEnigmailSvc();
if (!enigmailSvc)
return;
var resultObj = {};
- var inputObj = {};
- if (accessType == nsIEnigmail.UPLOAD_KEY) {
- inputObj.upload = true;
- }
-
var selKeyList = getSelectedKeys();
if (accessType != nsIEnigmail.REFRESH_KEY && selKeyList.length === 0) {
if (EnigConfirm(EnigGetString("refreshAllQuestion"), EnigGetString("keyMan.button.refreshAll"))) {
accessType = nsIEnigmail.REFRESH_KEY;
EnigAlertPref(EnigGetString("refreshKey.warn"), "warnRefreshAll");
}
else {
return;
}
}
var keyList = [];
- var keyIds = [];
for (var i = 0; i < selKeyList.length; i++) {
- keyIds.push(gKeyList[selKeyList[i]].keyId);
- }
- if (accessType != nsIEnigmail.REFRESH_KEY) {
- inputObj.keyId = keyIds.join(", ");
- }
- else {
- inputObj.keyId = "";
- }
-
- let autoKeyServer = EnigmailPrefs.getPref("autoKeyServerSelection") ? EnigmailPrefs.getPref("keyserver").split(/[ ,;]/g)[0] : null;
- if (autoKeyServer) {
- resultObj.value = autoKeyServer;
- }
- else {
- window.openDialog("chrome://enigmail/content/enigmailKeyserverDlg.xul",
- "", "dialog,modal,centerscreen", inputObj, resultObj);
- }
-
- if (!resultObj.value) {
- return;
- }
-
- var keyDlObj = {
- accessType: accessType,
- keyServer: resultObj.value,
- keyList: "0x" + keyIds.join(" 0x"),
- fprList: [],
- senderIdentities: [],
- cbFunc: callbackFunc
- };
-
- // UPLOAD_WKD needs a nsIMsgIdentity
- if (accessType == nsIEnigmail.UPLOAD_WKD) {
- try {
- let key = gKeyList[selKeyList[0]];
-
- for (let uid of key.userIds) {
- let email = EnigmailFuncs.stripEmail(uid.userId);
- let maybeIdent = EnigmailStdlib.getIdentityForEmail(email);
-
- if (maybeIdent && maybeIdent.identity) {
- keyDlObj.senderIdentities.push(maybeIdent.identity);
- keyDlObj.fprList.push(key.fpr);
- }
- }
-
- if (keyDlObj.senderIdentities.length === 0) {
- let uids = key.userIds.map(function(x) {
- return " - " + x.userId;
- }).join("\n");
- EnigAlert(EnigmailLocale.getString("noWksIdentity", [uids]));
- return;
- }
- }
- catch (ex) {
- EnigmailLog.DEBUG(ex + "\n");
- }
+ keyList.push(gKeyList[selKeyList[i]]);
}
- window.openDialog("chrome://enigmail/content/enigRetrieveProgress.xul",
- "", "dialog,modal,centerscreen", keyDlObj, resultObj);
+ EnigmailKeyServer.keyServerUpDownload(window, keyList, accessType, callbackFunc, resultObj);
if (accessType != nsIEnigmail.UPLOAD_KEY && resultObj.result) {
refreshKeys();
}
}
function getSortDirection() {
return gUserList.getAttribute("sortDirection") == "ascending" ? 1 : -1;
}
function sortTree(column) {
var columnName;
var order = getSortDirection();
//if the column is passed and it's already sorted by that column, reverse sort
if (column) {
columnName = column.id;
if (gUserList.getAttribute("sortResource") == columnName) {
order *= -1;
}
else {
document.getElementById(gUserList.getAttribute("sortResource")).removeAttribute("sortDirection");
order = 1;
}
}
else {
columnName = gUserList.getAttribute("sortResource");
}
gUserList.setAttribute("sortDirection", order == 1 ? "ascending" : "descending");
let col = document.getElementById(columnName);
if (col) {
col.setAttribute("sortDirection", order == 1 ? "ascending" : "descending");
gUserList.setAttribute("sortResource", columnName);
}
else {
gUserList.setAttribute("sortResource", "enigUserNameCol");
}
buildKeyList(false);
}
function getSortColumn() {
switch (gUserList.getAttribute("sortResource")) {
case "enigUserNameCol":
return "userid";
case "keyCol":
return "keyid";
case "typeCol":
return "keytype";
case "validityCol":
return "validity";
case "trustCol":
return "trust"; // ownerTrust
case "expCol":
return "expiry";
case "fprCol":
return "fpr";
default:
return "?";
}
}
/***************************** TreeView for user list ***********************************/
/**
* gKeyListView implements the nsITreeView interface for the displayed list.
*
* For speed reasons, we use two lists:
* - keyViewList: contains the full list of pointers to all keys and rows that are
* potentially displayed ordered according to the sort column
* - keyFilterList: contains the indexes to keyViewList of the keys that are displayed
* according to the current filter criteria.
*/
var gKeyListView = {
keyViewList: [],
keyFilterList: [],
//// nsITreeView implementation
rowCount: 0,
selection: null,
canDrop: function(index, orientation, dataTransfer) {
return false;
},
cycleCell: function(row, col) {},
cycleHeader: function(col) {},
drop: function(row, orientation, dataTransfer) {},
getCellProperties: function(row, col) {
let r = this.getFilteredRow(row);
if (!r) return "";
let keyObj = gKeyList[r.keyNum];
let keyTrustStyle = "";
switch (r.rowType) {
case "key":
case "uid":
case "uat":
switch (keyObj.keyTrust) {
case 'q':
keyTrustStyle = "enigmail_keyValid_unknown";
break;
case 'i':
keyTrustStyle = "enigmail_keyValid_invalid";
break;
case 'd':
keyTrustStyle = "enigmail_keyValid_disabled";
break;
case 'r':
keyTrustStyle = "enigmail_keyValid_revoked";
break;
case 'e':
keyTrustStyle = "enigmail_keyValid_expired";
break;
case 'n':
keyTrustStyle = "enigmail_keyTrust_untrusted";
break;
case 'm':
keyTrustStyle = "enigmail_keyTrust_marginal";
break;
case 'f':
keyTrustStyle = "enigmail_keyTrust_full";
break;
case 'u':
keyTrustStyle = "enigmail_keyTrust_ultimate";
break;
case '-':
keyTrustStyle = "enigmail_keyTrust_unknown";
break;
default:
keyTrustStyle = "enigmail_keyTrust_unknown";
break;
}
if (keyObj.keyUseFor.indexOf("D") >= 0) {
keyTrustStyle = "enigmail_keyValid_disabled";
}
if ((keyObj.keyTrust.length > 0) &&
(ENIG_KEY_NOT_VALID.indexOf(keyObj.keyTrust.charAt(0)) >= 0) ||
(keyObj.keyUseFor.indexOf("D") >= 0)) {
keyTrustStyle += " enigKeyInactive";
}
if (r.rowType === "key" && keyObj.secretAvailable) {
keyTrustStyle += " enigmailOwnKey";
}
break;
}
return keyTrustStyle;
},
getCellText: function(row, col) {
let r = this.getFilteredRow(row);
if (!r) return "";
let keyObj = gKeyList[r.keyNum];
switch (r.rowType) {
case "key":
switch (col.id) {
case "enigUserNameCol":
return keyObj.userId;
case "keyCol":
return keyObj.keyId;
case "typeCol":
if (keyObj.secretAvailable) {
return EnigmailLocale.getString("keyType.publicAndSec");
}
return EnigmailLocale.getString("keyType.public");
case "validityCol":
if (keyObj.keyUseFor.indexOf("D") >= 0) {
return EnigmailLocale.getString("keyValid.disabled");
}
return EnigGetTrustLabel(keyObj.keyTrust);
case "trustCol":
return EnigGetTrustLabel(keyObj.ownerTrust);
case "expCol":
return keyObj.expiry;
case "fprCol":
return keyObj.fprFormatted;
}
break;
case "uid":
switch (col.id) {
case "enigUserNameCol":
return keyObj.userIds[r.uidNum].userId;
case "validityCol":
if (keyObj.keyUseFor.indexOf("D") >= 0) {
return EnigmailLocale.getString("keyValid.disabled");
}
return EnigGetTrustLabel(keyObj.userIds[r.uidNum].keyTrust);
case "trustCol":
return EnigGetTrustLabel(keyObj.ownerTrust);
}
break;
case "uidHdr":
if (col.id === "enigUserNameCol") {
return EnigmailLocale.getString("keylist.hasOtherUids");
}
break;
case "noUidHdr":
if (col.id === "enigUserNameCol") {
return EnigmailLocale.getString("keylist.noOtherUids");
}
break;
case "uat":
if (col.id === "enigUserNameCol") {
return EnigmailLocale.getString("userAtt.photo");
}
break;
case "uatHdr":
if (col.id === "enigUserNameCol") {
return EnigmailLocale.getString("keylist.hasPhotos");
}
break;
case "noUatHdr":
if (col.id === "enigUserNameCol") {
return EnigmailLocale.getString("keylist.noPhotos");
}
break;
}
return "";
},
getCellValue: function(row, col) {
return "";
},
getColumnProperties: function(col) {
return "";
},
getImageSrc: function(row, col) {
let r = this.getFilteredRow(row);
if (!r) return null;
let keyObj = gKeyList[r.keyNum];
if (r.rowType === "key" && col.id === "pepBlacklistCol") {
if (gPepKeyBlacklist.indexOf(keyObj.fpr) >= 0) {
return "chrome://enigmail/content/check1.png";
}
else {
return "chrome://enigmail/content/check0.png";
}
}
return null;
},
/**
* indentation level for rows
*/
getLevel: function(row) {
let r = this.getFilteredRow(row);
if (!r) return 0;
switch (r.rowType) {
case "key":
return 0;
case "uidHdr":
case "noUidHdr":
case "uatHdr":
case "noUatHdr":
return 1;
case "uid":
case "uat":
return 2;
}
return 0;
},
getParentIndex: function(idx) {
return -1;
},
getProgressMode: function(row, col) {},
getRowProperties: function(row) {
return "";
},
hasNextSibling(rowIndex, afterIndex) {
return false;
},
isContainer: function(row) {
let r = this.getFilteredRow(row);
if (!r) return false;
switch (r.rowType) {
case "key":
return true;
}
return false;
},
isContainerEmpty: function(row) {
let r = this.getFilteredRow(row);
if (!r) return true;
switch (r.rowType) {
case "key":
return false;
case "uidHdr":
return r.isOpen;
}
return true;
},
isContainerOpen: function(row) {
return this.getFilteredRow(row).isOpen;
},
isEditable: function(row, col) {
return false;
},
isSelectable: function(row, col) {
return true;
},
isSeparator: function(index) {
return false;
},
isSorted: function() {
return false;
},
performAction: function(action) {},
performActionOnCell: function(action, row, col) {},
performActionOnRow: function(action, row) {},
selectionChanged: function() {},
// void setCellText(in long row, in nsITreeColumn col, in AString value);
// void setCellValue(in long row, in nsITreeColumn col, in AString value);
setTree: function(treebox) {
this.treebox = treebox;
},
toggleOpenState: function(row) {
let r = this.getFilteredRow(row);
if (!r) return;
let realRow = this.keyFilterList[row];
switch (r.rowType) {
case "key":
if (r.isOpen) {
let i = 0;
while (this.getFilteredRow(row + 1 + i) && this.getFilteredRow(row + 1 + i).keyNum === r.keyNum) {
++i;
}
this.keyViewList.splice(realRow + 1, i);
r.isOpen = false;
this.applyFilter(row);
}
else {
let numUid = this.appendUids("uid", r.keyNum, realRow, this.keyViewList[row]);
if (numUid > 0) {
this.appendHdr(realRow, "uidHdr", true);
}
else {
this.appendHdr(realRow, "noUidHdr", false);
}
let numPhoto = this.appendUids("uat", r.keyNum, realRow + numUid + 1, this.keyViewList[row]);
if (numPhoto > 0) {
this.appendHdr(realRow + numUid + 1, "uatHdr", true);
}
else {
this.appendHdr(realRow + numUid + 1, "noUatHdr", false);
}
r.isOpen = true;
this.applyFilter(row);
}
break;
}
},
/**
* add UIDs for a given key to key view
*
* @param uidType: String - one of uid (user ID), uat (photo)
* @param keyNum: Number - index of key in gKeyList
* @param realRow: Number - index of row in keyViewList (i.e. without filter)
*
* @return Number: number of UIDs added
*/
appendUids: function(uidType, keyNum, realRow, parentRow) {
let keyObj = gKeyList[keyNum];
let uidAdded = 0;
for (let i = 1; i < keyObj.userIds.length; i++) {
if (keyObj.userIds[i].type === uidType) {
++uidAdded;
this.keyViewList.splice(realRow + uidAdded, 0, {
rowType: uidType,
keyNum: keyNum,
parent: parentRow,
uidNum: i
});
}
}
return uidAdded;
},
/**
* add header row (e.g. "also known as") to tree view
*
* @param realRow: Number - index of row in keyViewList (i.e. without filter)
* @param headerType: String - one of uid (user ID), uat (photo)
* @param hasChildren: Boolean - whether or not there are rows underneath the header
*/
appendHdr: function(realRow, headerType, hasChildren) {
let r = this.keyViewList[realRow];
this.keyViewList.splice(realRow + 1, 0, {
rowType: headerType,
isOpen: hasChildren,
keyNum: r.keyNum,
parent: this.keyViewList[realRow]
});
},
/**
* Reload key list entirely
*/
keysRefreshed: function() {
this.keyViewList = [];
this.keyFilterList = [];
for (let i = 0; i < gKeySortList.length; i++) {
this.keyViewList.push({
row: i,
rowType: "key",
fpr: gKeySortList[i].fpr,
keyNum: gKeySortList[i].keyNum,
isOpen: false
});
}
this.applyFilter(0);
let oldRowCount = this.rowCount;
this.rowCount = this.keyViewList.length;
this.treebox.rowCountChanged(0, this.rowCount - oldRowCount);
},
/**
* If no search term is entered, decide which keys to display
*
* @return array of keyNums (= display some keys) or null (= display ALL keys)
*/
showOrHideAllKeys: function() {
var hideNode = !displayFullList();
var initHint = document.getElementById("emptyTree");
var showInvalidKeys = gShowInvalidKeys.getAttribute("checked") == "true";
var showUntrustedKeys = gShowUntrustedKeys.getAttribute("checked") == "true";
var showOthersKeys = gShowOthersKeys.getAttribute("checked") == "true";
document.getElementById("nothingFound").hidePopup();
if (hideNode) {
initHint.showPopup(gTreeChildren, -1, -1, "tooltip", "after_end", "");
return [];
}
else {
initHint.hidePopup();
}
if (showInvalidKeys && showUntrustedKeys && showOthersKeys) {
return null;
}
let keyShowList = [];
for (let i = 0; i < gKeyList.length; i++) {
if (determineHiddenKeys(gKeyList[i], showInvalidKeys, showUntrustedKeys, showOthersKeys)) {
keyShowList.push(i);
}
}
return keyShowList;
},
/**
* Search for keys that match filter criteria
*
* @return array of keyNums (= display some keys) or null (= display ALL keys)
*/
getFilteredKeys: function() {
let searchTxt = gSearchInput.value;
let nothingFoundElem = document.getElementById("nothingFound");
nothingFoundElem.hidePopup();
if (!searchTxt || searchTxt.length === 0) {
return this.showOrHideAllKeys();
}
if (!gKeyList) return [];
let showInvalidKeys = gShowInvalidKeys.getAttribute("checked") == "true";
let showUntrustedKeys = gShowUntrustedKeys.getAttribute("checked") == "true";
let showOthersKeys = gShowOthersKeys.getAttribute("checked") == "true";
document.getElementById("emptyTree").hidePopup();
// skip leading 0x in case we search for a key:
if (searchTxt.length > 2 && searchTxt.substr(0, 2).toLowerCase() == "0x") {
searchTxt = searchTxt.substr(2);
}
searchTxt = searchTxt.toLowerCase();
searchTxt = searchTxt.replace(/^(\s*)(.*)/, "$2").replace(/\s+$/, ""); // trim spaces
// check if we search for a full fingerprint (with optional spaces every 4 letters)
var fpr = null;
if (searchTxt.length == 49) { // possible fingerprint with spaces?
if (searchTxt.search(/^[0-9a-f ]*$/) >= 0 && searchTxt[4] == ' ' && searchTxt[9] == ' ' && searchTxt[14] == ' ' &&
searchTxt[19] == ' ' && searchTxt[24] == ' ' && searchTxt[29] == ' ' &&
searchTxt[34] == ' ' && searchTxt[39] == ' ' && searchTxt[44] == ' ') {
fpr = searchTxt.replace(/ /g, "");
}
}
else if (searchTxt.length == 40) { // possible fingerprint without spaces
if (searchTxt.search(/^[0-9a-f ]*$/) >= 0) {
fpr = searchTxt;
}
}
let foundResult = false;
let keyShowList = [];
for (let i = 0; i < gKeyList.length; i++) {
let keyObj = gKeyList[i];
let uid = keyObj.userId;
let showKey = false;
// does a user ID (partially) match?
for (let idx = 0; idx < keyObj.userIds.length; idx++) {
uid = keyObj.userIds[idx].userId;
if (uid.toLowerCase().indexOf(searchTxt) >= 0) {
showKey = true;
}
}
// does the full fingerprint (without spaces) match?
// - no partial match check because this is special for the collapsed spaces inside the fingerprint
if (showKey === false && fpr && keyObj.fpr.toLowerCase() == fpr) {
showKey = true;
}
// does the fingerprint (partially) match?
if (showKey === false && keyObj.fpr.toLowerCase().indexOf(searchTxt) >= 0) {
showKey = true;
}
// does a sub key of (partially) match?
if (showKey === false) {
for (let subKeyIdx = 0; subKeyIdx < keyObj.subKeys.length; subKeyIdx++) {
let subkey = keyObj.subKeys[subKeyIdx].keyId;
if (subkey.toLowerCase().indexOf(searchTxt) >= 0) {
showKey = true;
}
}
}
// take option to show invalid/untrusted... keys into account
let hideKey = true;
if (showKey && determineHiddenKeys(keyObj, showInvalidKeys, showUntrustedKeys, showOthersKeys)) {
keyShowList.push(i);
foundResult = true;
}
}
if (!foundResult) {
nothingFoundElem.showPopup(gTreeChildren, -1, -1, "tooltip", "after_end", "");
}
return keyShowList;
},
/**
* Trigger re-displaying the list of keys and apply a filter
*
* @param selectedRow: Number - the row that is currently selected or
* clicked on
*/
applyFilter: function(selectedRow) {
let keyDisplayList = this.getFilteredKeys();
this.keyFilterList = [];
if (keyDisplayList === null) {
for (let i = 0; i < this.keyViewList.length; i++) {
this.keyFilterList.push(i);
}
this.adjustRowCount(this.keyViewList.length, selectedRow);
}
else {
for (let i = 0; i < this.keyViewList.length; i++) {
if (keyDisplayList.indexOf(this.keyViewList[i].keyNum) >= 0) {
this.keyFilterList.push(i);
}
}
this.adjustRowCount(this.keyFilterList.length, selectedRow);
}
},
/**
* Re-calculate the row count and instruct the view to update
*/
adjustRowCount: function(newRowCount, selectedRow) {
if (this.rowCount === newRowCount) {
this.treebox.invalidate();
return;
}
let delta = newRowCount - this.rowCount;
this.rowCount = newRowCount;
this.treebox.rowCountChanged(selectedRow, delta);
},
/**
* Determine the row object from the a filtered row number
*
* @param row: Number - row number of displayed (=filtered) list
*
* @return Object: keyViewList entry of corresponding row
*/
getFilteredRow: function(row) {
let r = this.keyFilterList[row];
if (r !== undefined) {
return this.keyViewList[r];
}
return null;
},
treebox: null
};
diff --git a/ui/content/enigmailSetupWizard.js b/ui/content/enigmailSetupWizard.js
index 1cc73c85..92e4a9fb 100644
--- a/ui/content/enigmailSetupWizard.js
+++ b/ui/content/enigmailSetupWizard.js
@@ -1,1416 +1,1518 @@
/*global Components: false*/
/*
* 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 Ec is already defined in enigmailKeygen.js
// modules
/* global EnigmailData: false, EnigmailLog: false, EnigmailLocale: false, EnigmailGpg: false, EnigmailKeyEditor: false */
/* global EnigmailOS: false, EnigmailPrefs: false, EnigmailGpgAgent: false, EnigmailDialog: false */
// variables from enigmailKeygen.js and enigmailCommon.js */
/* global EnigGetWindowOptions: false, gKeygenRequest: true, gGeneratedKey: true, EnigConfirm: false, EnigGetString: false*/
/* global enigmailKeygenCloseRequest: true, EnigLongAlert: false, EnigAlert: false, gEnigmailSvc: true, gAllData: true */
/* global EnigGetPref: false, EnigSetPref: false, EnigFilePicker: false, EnigGetFilePath: false, KEYGEN_CANCELLED: false */
/* global ENIG_C: false, ENIG_I: false, ENIG_ENIGMAIL_CONTRACTID: false, EnigGetVersion: false, ENIG_KEYTYPE_RSA: false */
/* global genAndSaveRevCert: false, ENIG_ACCOUNT_MANAGER_CONTRACTID: false, enigmailCheckPassphrase: false */
"use strict";
Components.utils.import("resource://enigmail/files.jsm"); /* global EnigmailFiles: false */
Components.utils.import("resource://enigmail/configBackup.jsm"); /*global EnigmailConfigBackup: false */
Components.utils.import("resource://enigmail/keyRing.jsm"); /*global EnigmailKeyRing: false */
Components.utils.import("resource://enigmail/installGnuPG.jsm"); /*global InstallGnuPG: false */
Components.utils.import("resource://enigmail/passwordCheck.jsm"); /*global EnigmailPasswordCheck: false */
+Components.utils.import("resource://enigmail/execution.jsm"); /*global EnigmailExecution: false */
+Components.utils.import("resource://enigmail/gpgAgent.jsm"); /*global EnigmailGpgAgent: false */
+Components.utils.import("resource://enigmail/funcs.jsm"); /*global EnigmailFuncs: false */
+Components.utils.import("resource://enigmail/stdlib.jsm"); /*global EnigmailStdlib: false */
+Components.utils.import("resource://enigmail/webKey.jsm"); /*global EnigmailWks: false */
+Components.utils.import("resource://enigmail/windows.jsm"); /*global EnigmailWindows: false */
+Components.utils.import("resource://enigmail/keyserver.jsm"); /*global EnigmailKeyServer: false */
const Cc = Components.classes;
const Ci = Components.interfaces;
var gLastDirection = 0;
var gWizardUserMode = "beginner";
var gEnigAccountMgr;
var gPubkeyFile = {
value: null
};
var gSeckeyFile = {
value: null
};
var gImportSettingsFile = {
value: null
};
var gCreateNewKey = false;
var gDownoadObj = null;
var gPassPhraseQuality = null;
var gPageStack = []; // required for correct stepping back
function onLoad() {
EnigmailLog.DEBUG("enigmailSetupWizard.js: onLoad()\n");
gEnigAccountMgr = Components.classes["@mozilla.org/messenger/account-manager;1"].getService(Components.interfaces.nsIMsgAccountManager);
fillIdentities('checkbox');
let winOptions = EnigGetWindowOptions();
if ("skipIntro" in winOptions) {
if (winOptions.skipIntro == "true") {
let wizard = getWizard();
wizard.goTo("pgWelcome");
}
}
else if ("doRestore" in winOptions) {
if (winOptions.doRestore == "true") {
let wizard = getWizard();
gWizardUserMode = "import";
wizard.goTo("pgImportSettings");
}
}
}
function onCancel() {
if (gKeygenRequest) {
if (EnigConfirm(EnigGetString("keyAbort"), EnigGetString("keyMan.button.generateKeyAbort"), EnigGetString("keyMan.button.generateKeyContinue"))) {
enigmailKeygenCloseRequest();
return true;
}
else {
return false;
}
}
else {
let doCancel = EnigConfirm(EnigGetString("setupWizard.reallyCancel"), EnigGetString("dlg.button.close"), EnigGetString("dlg.button.continue"));
if (doCancel && gDownoadObj) {
gDownoadObj.abort();
gDownoadObj = null;
}
return doCancel;
}
}
function getWizard() {
return document.getElementById("enigmailSetupWizard");
}
function setLastPage() {
var wizard = getWizard();
if (wizard.currentPage) {
gPageStack.push(wizard.currentPage.id);
}
}
function onBack() {
EnigmailLog.DEBUG("onBack");
var wizard = getWizard();
gLastDirection = -1;
gPageStack.pop();
}
function onPageShow() {
var wizard = getWizard();
wizard.canRewind = (gPageStack.length > 0);
}
/***
* State machine to decide which is the next page to show in the wizard.
* This function is called when the "Next" button is pressed, before the
* next page is opened, allowing to still modify the wiazrd's sequence.
*/
function onNext() {
var enableNext = true;
// private function to se the next page of the wizard
function setNextPage(pageId) {
if (pageId === "") {
enableNext = false;
}
else {
let wizard = getWizard();
wizard.currentPage.next = pageId;
enableNext = true;
}
}
EnigmailLog.DEBUG("enigmailSetupWizard.js: onNext()\n");
gLastDirection = 1;
setLastPage();
var wizard = getWizard();
if (wizard.currentPage) {
switch (wizard.currentPage.pageid) {
case "pgWelcome":
setNextPage(onAfterPgWelcome());
break;
case "pgInstallGnuPG":
setNextPage(onAfterPgInstallGnuPG());
break;
case "pgSelectId":
setNextPage(onAfterPgSelectId());
break;
case "pgKeySel":
setNextPage(onAfterPgKeySel());
break;
case "pgNoKeyFound":
setNextPage(onAfterPgNoKeyFound());
break;
case "pgKeyImport":
setNextPage(onAfterPgKeyImport());
break;
case "pgKeyCreate":
setNextPage(onAfterPgKeyCreate());
break;
case "pgKeygen":
setNextPage(onAfterPgKeygen());
break;
+ case "pgUpload":
+ setNextPage(onAfterPgUpload());
+ break;
}
}
return enableNext;
}
/**** State machine helper functions ****
*
* All functions:
* return the next page ID or "" in case the 'Next' button should be disabled
*/
function onAfterPgWelcome() {
if (checkGnupgInstallation()) {
let hasSecretKeys = checkSecretKeys();
switch (gWizardUserMode) {
case "beginner":
if (hasSecretKeys) {
loadKeys();
return "pgKeySel";
}
return "pgKeyCreate";
case "advanced":
if (countIdentities() > 1) {
return "pgSelectId";
}
else {
if (hasSecretKeys) {
loadKeys();
return "pgKeySel";
}
else {
return "pgNoKeyFound";
}
}
case "expert":
return "pgExpert";
case "import":
return "pgImportSettings";
}
}
return "pgInstallGnuPG";
}
function onAfterPgInstallGnuPG() {
let hasSecretKeys = checkSecretKeys();
switch (gWizardUserMode) {
case "beginner":
if (hasSecretKeys) {
loadKeys();
return "pgKeySel";
}
else {
return "pgKeyCreate";
}
case "advanced":
if (countIdentities() > 1) {
return "pgSelectId";
}
else {
if (hasSecretKeys) {
loadKeys();
return "pgKeySel";
}
else {
return "pgNoKeyFound";
}
}
case "expert":
return "pgExpert";
}
return null;
}
function onAfterPgSelectId() {
let hasSecretKeys = checkSecretKeys();
if (hasSecretKeys) {
loadKeys();
return "pgKeySel";
}
else {
return "pgNoKeyFound";
}
}
function onAfterPgKeySel() {
if (gCreateNewKey) {
return "pgKeyCreate";
}
else {
- return "pgComplete";
+ if (gWizardUserMode == "advanced") {
+ return "pgUpload";
+ }
+ else {
+ return "pgComplete";
+ }
}
}
function onAfterPgNoKeyFound() {
if (gCreateNewKey) {
return "pgKeyCreate";
}
else {
return "pgKeyImport";
}
}
function onAfterPgKeyImport() {
return "pgKeySel";
}
function onAfterPgKeyCreate() {
if (checkPassphrase()) {
return "pgKeygen";
}
return "";
}
function onAfterPgKeygen() {
+ if (gWizardUserMode == "advanced") {
+ return "pgUpload";
+ }
+ else {
+ return "pgComplete";
+ }
+}
+
+function onAfterPgUpload() {
return "pgComplete";
}
/**
* Check if GnuPG is available
*/
function checkGnupgInstallation() {
var s = enigGetSvc(true);
return (s ? true : false);
}
/**
* Check if secret keys are available
*/
function checkSecretKeys() {
EnigmailLog.DEBUG("enigmailSetupWizard.js: checkSecretKeys\n");
var keyList = EnigmailKeyRing.getAllSecretKeys(true);
if (keyList && keyList.length > 0) {
return true;
}
return false;
}
/**
* Enable or disable the "Next" (or "Done") button
*
* disable: boolean: true = button is disabled / false = button is enabled
*/
function disableNext(disable) {
var wizard = getWizard();
wizard.canAdvance = !disable;
}
function countSelectedId() {
var idCount = 0;
var node = document.getElementById("idSelection").firstChild;
while (node) {
if (node.checked) {
++idCount;
}
node = node.nextSibling;
}
return idCount;
}
function onShowPgInstallGnuPG() {
var ok = enigGetSvc(true);
disableNext(!ok);
if (InstallGnuPG.checkAvailability()) {
document.getElementById("installBox").removeAttribute("collapsed");
}
else {
document.getElementById("findGpgBox").removeAttribute("collapsed");
}
}
function installGnuPG() {
var progressBox = document.getElementById("progressBox");
var downloadProgress = document.getElementById("downloadProgress");
var installLabel = document.getElementById("installLabel");
var installProgress = document.getElementById("installProgress");
var btnInstallGnupg = document.getElementById("btnInstallGnupg");
var btnLocateGnuPG = document.getElementById("btnLocateGnuPG");
btnInstallGnupg.setAttribute("disabled", true);
btnLocateGnuPG.setAttribute("disabled", true);
progressBox.removeAttribute("collapsed");
InstallGnuPG.startInstaller({
onStart: function(reqObj) {
gDownoadObj = reqObj;
},
onError: function(errorMessage) {
if (typeof(errorMessage) == "object") {
var s = EnigGetString("errorType." + errorMessage.type);
if (errorMessage.type.startsWith("Security")) {
s += "\n" + EnigGetString("setupWizard.downloadForbidden");
}
else
s += "\n" + EnigGetString("setupWizard.downloadImpossible");
EnigAlert(s);
}
else {
EnigAlert(EnigGetString(errorMessage));
}
this.returnToDownload();
},
onWarning: function(message) {
var ret = false;
if (message == "hashSumMismatch") {
ret = EnigConfirm(EnigGetString("setupWizard.hashSumError"), EnigGetString("dlgYes"),
EnigGetString("dlgNo"));
}
if (!ret) this.returnToDownload();
return ret;
},
onProgress: function(event) {
if (event.lengthComputable) {
var percentComplete = event.loaded / event.total * 100;
downloadProgress.setAttribute("value", percentComplete);
}
else {
downloadProgress.setAttribute("mode", "undetermined");
}
},
onDownloaded: function() {
gDownoadObj = null;
downloadProgress.setAttribute("value", 100);
installLabel.removeAttribute("collapsed");
installProgress.removeAttribute("collapsed");
},
returnToDownload: function() {
btnInstallGnupg.removeAttribute("disabled");
btnLocateGnuPG.removeAttribute("disabled");
progressBox.setAttribute("collapsed", "true");
downloadProgress.setAttribute("value", 0);
installLabel.setAttribute("collapsed", "true");
installProgress.setAttribute("collapsed", "true");
},
onLoaded: function() {
installProgress.setAttribute("value", 100);
installProgress.setAttribute("mode", "determined");
document.getElementById("installComplete").removeAttribute("collapsed");
var origPath = EnigGetPref("agentPath");
EnigSetPref("agentPath", "");
var s = enigGetSvc(true);
if (s) {
disableNext(false);
}
else {
EnigSetPref("agentPath", origPath);
this.returnToDownload();
EnigAlert(EnigGetString("setupWizard.installFailed"));
}
}
});
}
function browseKeyFile(referencedId, referencedVar) {
var filePath = EnigFilePicker(EnigGetString("importKeyFile"),
"", false, "*.asc", "", [EnigGetString("gnupgFile"), "*.asc;*.gpg;*.pgp"]);
if (filePath) {
document.getElementById(referencedId).value = EnigGetFilePath(filePath);
referencedVar.value = filePath;
}
}
function browseBackupFile(referencedId, referencedVar) {
var filePath = EnigFilePicker(EnigGetString("setupWizard.importSettingsFile"),
"", false, "*.zip", EnigmailLocale.getString("defaultBackupFileName") + ".zip", [EnigmailLocale.getString("enigmailSettings"), "*.zip"]);
if (filePath) {
document.getElementById(referencedId).value = EnigGetFilePath(filePath);
referencedVar.value = filePath;
getWizard().canAdvance = true;
}
}
function importKeyFiles() {
EnigmailLog.DEBUG("enigmailSetupWizard.js: importKeyFiles\n");
if (document.getElementById("publicKeysFile").value.length === 0) {
EnigmailDialog.info(window, EnigGetString("setupWizard.specifyFile"));
return false;
}
var importedKeys;
var exitCode;
var enigmailSvc = enigGetSvc(false);
if (!enigmailSvc) return false;
disableNext(true);
var errorMsgObj = {};
var keyListObj = {};
exitCode = EnigmailKeyRing.importKeyFromFile(gPubkeyFile.value, errorMsgObj, keyListObj);
if (exitCode !== 0) {
EnigAlert(EnigGetString("importKeysFailed") + "\n\n" + errorMsgObj.value);
return false;
}
importedKeys = keyListObj.value;
if (document.getElementById("privateKeysFile").value.trim().length > 0) {
EnigmailLog.DEBUG("enigmailSetupWizard.js: importKeyFiles - private Keys\n");
exitCode = EnigmailKeyRing.importKeyFromFile(gSeckeyFile.value, errorMsgObj, keyListObj);
if (exitCode !== 0) {
EnigAlert(EnigGetString("importKeysFailed") + "\n\n" + errorMsgObj.value);
return false;
}
importedKeys += keyListObj.value;
}
exitCode = 0;
var keyList = importedKeys.split(/;/);
EnigmailLog.DEBUG("enigmailSetupWizard.js: importKeyFiles - importing " + keyList.length + " keys\n");
setKeyTrustNextKey(keyList, 0);
return true;
}
function setKeyTrustNextKey(keyList, index) {
EnigmailLog.DEBUG("enigmailSetupWizard.js: setKeyTrustNextKey(" + index + ")\n");
if (index == keyList.length) {
// end of list reached
EnigmailGpg.recalcTrustDb();
loadKeys();
return;
}
var aKey = keyList[index].split(/:/);
let keyType;
try {
keyType = Number(aKey[1]);
}
catch (ex) {
keyType = 0;
}
if (keyType & 16) {
// imported key contains secret key
EnigmailKeyEditor.setKeyTrust(window, aKey[0], 5,
function(exitCode, errorMsg) {
if (exitCode !== 0) {
return;
}
if (index < keyList.length) {
setKeyTrustNextKey(keyList, index + 1);
}
}
);
}
else {
if (index < keyList.length) {
setKeyTrustNextKey(keyList, index + 1);
}
}
}
function displayKeyCreate() {
if (gLastDirection == 1) {
fillIdentities('menulist');
}
gPassPhraseQuality = document.getElementById("passphraseQuality");
// gpg 2.1.0 and 2.1.1 queries passphrase only gpg-agent only
if (!EnigmailGpg.getGpgFeature("keygen-passphrase")) {
document.getElementById("keyCreateDescSec1").setAttribute("collapsed", "true");
document.getElementById("passphraseBox").setAttribute("collapsed", "true");
document.getElementById("keyCreateDescSec2").removeAttribute("collapsed");
}
else {
checkPassphrasesEqual();
}
if (countSelectedId() == 1) {
var node = document.getElementById("idSelection").firstChild;
while (node) {
if (node.checked) {
var identity = gEnigAccountMgr.getIdentity(node.getAttribute("account-id"));
var idName = identity.identityName;
var serverList = queryISupArray(
getServersForIdentity(gEnigAccountMgr, identity),
Components.interfaces.nsIMsgIncomingServer);
if (serverList.length > 0) {
var inServer = serverList[0];
idName += " - " + inServer.prettyName;
}
document.getElementById("userIdentityLabel").value = idName;
break;
}
node = node.nextSibling;
}
document.getElementById("userIdentity").setAttribute("collapsed", "true");
document.getElementById("userIdentityLabel").removeAttribute("collapsed");
}
else {
document.getElementById("userIdentityLabel").setAttribute("collapsed", "true");
document.getElementById("userIdentity").removeAttribute("collapsed");
}
}
function checkPassphraseOnChange(passphrase) {
if (passphrase.value.length > 0) {
var qualityCheck = EnigmailPasswordCheck.checkQuality(passphrase.value);
var qualityError = document.getElementById("passphraseError");
var passRepeat = document.getElementById("passphraseRepeat").value;
var passImg = document.getElementById("passphraseErrorImg");
if (!qualityCheck.valid) {
qualityError.hidden = false;
passImg.hidden = false;
}
else {
qualityError.hidden = true;
passImg.hidden = true;
}
//qualityError never checked, only length
if (passphrase.value.length < 8) {
qualityError.hidden = false;
passImg.hidden = false;
}
else {
qualityError.hidden = true;
passImg.hidden = true;
}
}
}
function checkPassphraseQuality(txtBox) {
var qualityRes = EnigmailPasswordCheck.checkQuality(txtBox.value);
if (qualityRes.valid) {
gPassPhraseQuality.value = qualityRes.complexity;
}
else if (txtBox.value.length > 0) {
gPassPhraseQuality.value = (qualityRes.complexity / 2);
}
else {
gPassPhraseQuality.value = 0;
}
checkPassphrasesEqual();
}
/**
* Check if entered passphrases are equal. If yes, enable the next button
*/
function checkPassphrasesEqual() {
let p1 = document.getElementById("passphrase").value;
let p2 = document.getElementById("passphraseRepeat").value;
var repeatError = document.getElementById("passphraseErrorRepeat");
var passRepImg = document.getElementById("passphraseErrorRepImg");
if (p1 != p2 && p1.length > 0 && p2.length > 0) {
repeatError.hidden = false;
passRepImg.hidden = false;
}
else {
repeatError.hidden = true;
passRepImg.hidden = true;
}
disableNext(p1.length < 8 || p1 != p2);
}
function displayKeySel() {
var uidChildren = document.getElementById("uidSelectionChildren");
if (document.getElementById("createPgpKey").value == "0") {
setUseKey();
}
else {
setNewKey();
}
}
function clearKeyListEntries() {
EnigmailLog.DEBUG("enigmailSetupWizard.js: clearKeyListEntries\n");
// remove all rows
var treeChildren = document.getElementById("uidSelectionChildren");
while (treeChildren.firstChild) {
treeChildren.removeChild(treeChildren.firstChild);
}
}
function onSetStartNow(mode) {
var wizard = getWizard();
if (mode === 0) {
wizard.lastPage = true;
wizard.getButton("next").hidden = true;
wizard.getButton("finish").hidden = false;
wizard.currentPage.next = "";
}
else {
wizard.lastPage = false;
wizard.getButton("next").hidden = false;
wizard.getButton("finish").hidden = true;
wizard.currentPage.next = "pgWelcome";
}
}
function onSetSelectMode(userMode) {
gWizardUserMode = userMode;
}
function onKeySelected() {
var wizard = getWizard();
var uidSel = document.getElementById("uidSelection");
if (uidSel.view.selection.count == 1) {
var currIndex = uidSel.view.selection.currentIndex;
var currItem = uidSel.view.getItemAtIndex(currIndex);
gGeneratedKey = currItem.getAttribute("keyId");
}
else {
gGeneratedKey = null;
}
disableNext(uidSel.view.selection.count === 0);
}
function wizardSetFocus() {
document.getElementById("selectMode").focus();
disableNext(false);
}
function loadKeys() {
EnigmailLog.DEBUG("enigmailSetupWizard.js: loadKeys\n");
var enigmailSvc = enigGetSvc(false);
if (!enigmailSvc) {
return;
}
clearKeyListEntries();
var exitCodeObj = {};
var statusFlagsObj = {};
var errorMsgObj = {};
EnigmailKeyRing.clearCache();
var keyList = EnigmailKeyRing.getAllSecretKeys(true);
if (!keyList) {
return;
}
var uidChildren = document.getElementById("uidSelectionChildren");
for (let i = 0; i < keyList.length; i++) {
var item = uidChildren.appendChild(document.createElement('treeitem'));
item.setAttribute("keyId", keyList[i].keyId);
var row = item.appendChild(document.createElement('treerow'));
var cell = row.appendChild(document.createElement('treecell'));
cell.setAttribute('label', keyList[i].userId);
cell.setAttribute('observes', "bcKeyEnabled");
cell = row.appendChild(document.createElement('treecell'));
cell.setAttribute('label', "0x" + keyList[i].keyId);
cell.setAttribute('observes', "bcKeyEnabled");
cell = row.appendChild(document.createElement('treecell'));
cell.setAttribute('label', keyList[i].created);
cell.setAttribute('observes', "bcKeyEnabled");
}
// if there is only one key available, select it.
if (keyList.length == 1) {
var uidSel = document.getElementById("uidSelection");
uidSel.view.selection.select(0);
}
onKeySelected();
return;
}
function enigGetSvc(resetCheck) {
// Lazy initialization of enigmail JS component (for efficiency)
// variant of GetEnigmailSvc function
if (resetCheck) gEnigmailSvc = null;
if (gEnigmailSvc) {
return gEnigmailSvc.initialized ? gEnigmailSvc : null;
}
try {
gEnigmailSvc = ENIG_C[ENIG_ENIGMAIL_CONTRACTID].createInstance(ENIG_I.nsIEnigmail);
}
catch (ex) {
EnigmailLog.ERROR("enigmailWizard.js: Error in instantiating EnigmailService\n");
return null;
}
EnigmailLog.DEBUG("enigmailWizard.js: gEnigmailSvc = " + gEnigmailSvc + "\n");
if (!gEnigmailSvc.initialized) {
// Try to initialize enigmail
try {
// Initialize enigmail
gEnigmailSvc.initialize(window, EnigGetVersion());
try {
// Reset alert count to default value
EnigmailPrefs.getPrefBranch().clearUserPref("initAlert");
}
catch (ex) {}
}
catch (ex) {
return null;
}
var configuredVersion = EnigGetPref("configuredVersion");
EnigmailLog.DEBUG("enigmailWizard.js: enigGetSvc: " + configuredVersion + "\n");
}
return gEnigmailSvc.initialized ? gEnigmailSvc : null;
}
function wizardLocateGpg() {
var fileName = "gpg";
var ext = "";
if (EnigmailOS.isDosLike) {
ext = ".exe";
}
var filePath = EnigFilePicker(EnigGetString("locateGpg"),
"", false, ext,
fileName + ext, null);
if (filePath) {
EnigSetPref("agentPath", EnigGetFilePath(filePath));
var svc = enigGetSvc(true);
if (!svc) {
EnigAlert(EnigGetString("setupWizard.invalidGpg"));
}
else {
document.getElementById("gpgFoundBox").removeAttribute("collapsed");
disableNext(false);
}
}
}
function checkPassphrase() {
// gpg >= 2.1 queries passphrase using gpg-agent only
if (EnigmailGpg.getGpgFeature("keygen-passphrase")) {
var passphrase = enigmailCheckPassphrase();
if (!passphrase) return false;
if (passphrase.length < 8) {
EnigmailDialog.info(window, EnigGetString("passphrase.min8keys"));
return false;
}
}
return true;
}
function wizardGenKey() {
var wizard = getWizard();
disableNext(true);
wizard.canRewind = false;
var passphrase = document.getElementById("passphrase").value;
// gpg >= 2.1 queries passphrase using gpg-agent only
if (!EnigmailGpg.getGpgFeature("keygen-passphrase")) {
passphrase = "";
}
var curId = wizardGetSelectedIdentity();
var userName = curId.fullName;
var userEmail = curId.email;
var ipcRequest = null;
var listener = {
onStartRequest: function() {},
onStopRequest: function(status) {
wizardKeygenTerminate(status);
},
onDataAvailable: function(data) {
EnigmailLog.DEBUG("enigmailSetupWizard.js: genKey - onDataAvailable() " + data + "\n");
gAllData += data;
var keyCreatedIndex = gAllData.indexOf("[GNUPG:] KEY_CREATED");
if (keyCreatedIndex > 0) {
gGeneratedKey = gAllData.substr(keyCreatedIndex);
gGeneratedKey = gGeneratedKey.replace(/(.*\[GNUPG:\] KEY_CREATED . )([a-fA-F0-9]+)([\n\r].*)*/, "$2");
gAllData = gAllData.replace(/\[GNUPG:\] KEY_CREATED . [a-fA-F0-9]+[\n\r]/, "");
}
gAllData = gAllData.replace(/[\r\n]*\[GNUPG:\] GOOD_PASSPHRASE/g, "").replace(/([\r\n]*\[GNUPG:\] PROGRESS primegen )(.)( \d+ \d+)/g, "$2");
var progMeter = document.getElementById("keygenProgress");
var progValue = Number(progMeter.value);
progValue += (1 + (100 - progValue) / 200);
if (progValue >= 95) progValue = 10;
progMeter.setAttribute("value", progValue);
}
};
try {
gKeygenRequest = EnigmailKeyRing.generateKey(
EnigmailData.convertFromUnicode(userName),
"",
EnigmailData.convertFromUnicode(userEmail),
365 * 5 /* 5 years */ ,
4096,
ENIG_KEYTYPE_RSA,
EnigmailData.convertFromUnicode(passphrase),
listener);
}
catch (ex) {
EnigmailLog.DEBUG("enigmailSetupWizard.js: genKey - generateKey() failed with " + ex.toString() + "\n" + ex.stack + "\n");
}
if (!gKeygenRequest) {
EnigAlert(EnigGetString("keyGenFailed"));
wizard.getButton("back").disabled = false;
return false;
}
EnigmailLog.WRITE("enigmailKeygen.js: Start: gKeygenRequest = " + gKeygenRequest + "\n");
return false;
}
function wizardKeygenTerminate(exitCode) {
EnigmailLog.DEBUG("enigmailSetupWizard.js: wizardKeygenTerminate\n");
// Give focus to this window
window.focus();
gKeygenRequest = null;
if ((!gGeneratedKey) || gGeneratedKey == KEYGEN_CANCELLED) return;
var progMeter = document.getElementById("keygenProgress");
progMeter.setAttribute("value", 100);
enigmailKeygenCloseRequest();
EnigmailKeyRing.clearCache();
document.getElementById("revCertBox").removeAttribute("hidden");
}
// create a revokation certificate
function wizardCreateRevCert() {
EnigmailLog.DEBUG("enigmailSetupWizard.js: wizardCreateRevCert\n");
let curId = wizardGetSelectedIdentity();
genAndSaveRevCert(gGeneratedKey, curId.email).then(
function _resolve() {
disableNext(false);
},
function _reject() {
disableNext(true);
}
);
}
function queryISupArray(supportsArray, iid) {
var result = [];
var i;
for (i = 0; i < supportsArray.length; i++) {
result.push(supportsArray.queryElementAt(i, iid));
}
return result;
}
function countIdentities() {
var accountManager = Components.classes[ENIG_ACCOUNT_MANAGER_CONTRACTID].getService(Components.interfaces.nsIMsgAccountManager);
var idSupports = accountManager.allIdentities;
var identities = queryISupArray(idSupports,
Components.interfaces.nsIMsgIdentity);
return identities.length;
}
function fillIdentities(fillType) {
EnigmailLog.DEBUG("enigmailSetupWizard.js: fillIdentities\n");
var defIdentity;
var parentElement;
var identities = queryISupArray(gEnigAccountMgr.allIdentities,
Components.interfaces.nsIMsgIdentity);
if (fillType == "checkbox") {
parentElement = document.getElementById("idSelection");
}
else {
parentElement = document.getElementById("userIdentityPopup");
// Find out default identity
var defIdentities = gEnigAccountMgr.defaultAccount.identities;
if (defIdentities.length >= 1) {
defIdentity = defIdentities.queryElementAt(0, Components.interfaces.nsIMsgIdentity);
}
else {
defIdentity = identities[0];
}
if (document.getElementById("activateId").value == "0") {
// try to match with selected id
var node = document.getElementById("idSelection").firstChild;
while (node) {
if (node.checked) {
var currId = gEnigAccountMgr.getIdentity(node.getAttribute("account-id"));
if (currId.key == defIdentity.key) {
break;
}
}
node = node.nextSibling;
}
// default ID wasn't selected, take 1st selected ID
if (!node) {
node = document.getElementById("idSelection").firstChild;
while (node) {
if (node.checked) {
defIdentity = gEnigAccountMgr.getIdentity(node.getAttribute("account-id"));
break;
}
node = node.nextSibling;
}
}
}
}
var child = parentElement.firstChild;
while (child) {
parentElement.removeChild(child);
child = parentElement.firstChild;
}
EnigmailLog.DEBUG("enigmailSetupWizard.js: fillIdentities: " + identities + "\n");
var disableId = document.getElementById("activateId").value == "1";
var selected = false;
for (var i = 0; i < identities.length; i++) {
var identity = identities[i];
EnigmailLog.DEBUG("id.valid=" + identity.valid + "\n");
if (!identity.valid || !identity.email)
continue;
var serverList = queryISupArray(
getServersForIdentity(gEnigAccountMgr, identity),
Components.interfaces.nsIMsgIncomingServer);
if (serverList.length > 0) {
var inServer = serverList[0];
var accountName = " - " + inServer.prettyName;
EnigmailLog.DEBUG("enigmailKeygen.js: accountName=" + accountName + "\n");
EnigmailLog.DEBUG("enigmailKeygen.js: email=" + identity.email + "\n");
var item;
if (fillType == "checkbox") {
item = document.createElement('checkbox');
item.setAttribute('checked', "true");
item.setAttribute('disabled', disableId);
item.setAttribute('oncommand', "checkIdSelection()");
}
else {
item = document.createElement('menuitem');
item.setAttribute('label', identity.identityName + accountName);
item.setAttribute('class', 'identity-popup-item');
}
item.setAttribute('label', identity.identityName + accountName);
item.setAttribute('accountname', accountName);
item.setAttribute('id', "acc-" + identity.key);
item.setAttribute('account-id', identity.key);
item.setAttribute('email', identity.email);
parentElement.appendChild(item);
if (fillType != "checkbox") {
// pre-select default ID
var idList = document.getElementById("userIdentity");
if (!selected)
idList.selectedItem = item;
if (identity.key == defIdentity.key) {
idList.selectedItem = item;
selected = true;
}
}
}
}
}
function wizardGetSelectedIdentity() {
var item = document.getElementById("userIdentity").selectedItem;
var identityKey = item.getAttribute('account-id');
return gEnigAccountMgr.getIdentity(identityKey);
}
function applyWizardSettings() {
EnigmailLog.DEBUG("enigmailSetupWizard.js: applyWizardSettings\n");
if (gWizardUserMode === "import") return;
loadLastPage();
EnigmailPrefs.setPref("encryptionModel", 0);
if (document.getElementById("activateId").value == "1") {
// activate all identities
var idSupports = gEnigAccountMgr.allIdentities;
var identities = queryISupArray(idSupports,
Components.interfaces.nsIMsgIdentity);
for (var i = 0; i < identities.length; i++) {
wizardApplyId(identities[i], gGeneratedKey);
}
}
else {
// activate selected identities
var node = document.getElementById("idSelection").firstChild;
while (node) {
if (node.checked) {
var identity = gEnigAccountMgr.getIdentity(node.getAttribute("account-id"));
wizardApplyId(identity, gGeneratedKey);
}
node = node.nextSibling;
}
}
applyMozSetting("mail.server.default.mime_parts_on_demand", false);
applyMozSetting("mailnews.send_plaintext_flowed", false);
applyMozSetting("mail.strictly_mime", false);
EnigSetPref("configuredVersion", EnigGetVersion());
EnigmailPrefs.savePrefs();
+
+ keyUploadDo();
}
function applyMozSetting(preference, newVal) {
if (typeof(newVal) == "boolean") {
EnigmailPrefs.getPrefRoot().setBoolPref(preference, newVal);
}
else if (typeof(newVal) == "number") {
EnigmailPrefs.getPrefRoot().setIntPref(preference, newVal);
}
else if (typeof(newVal) == "string") {
EnigmailPrefs.getPrefRoot().setCharPref(preference, newVal);
}
}
function wizardApplyId(identity, keyId) {
EnigmailLog.DEBUG("enigmailSetupWizard.js: wizardApplyId: identity.Key=" + identity.key + "\n");
var accountManager = Components.classes[ENIG_ACCOUNT_MANAGER_CONTRACTID].getService(Components.interfaces.nsIMsgAccountManager);
var idServers = getServersForIdentity(accountManager, identity);
var servers = queryISupArray(idServers, Components.interfaces.nsIMsgIncomingServer);
var newsServer = false;
for (var i = 0; i < servers.length; i++) {
newsServer = (servers[i].localStoreType == "news");
}
identity.setBoolAttribute("enablePgp", true);
identity.setIntAttribute("pgpKeyMode", 1);
identity.setCharAttribute("pgpkeyId", "0x" + keyId);
identity.setIntAttribute("openPgpHeaderMode", 0);
// process signing settings:
// NOTE: option defaultSigningPolicy is an INT
identity.setIntAttribute("defaultSigningPolicy", 0);
identity.setBoolAttribute("pgpSignEncrypted", false);
identity.setBoolAttribute("pgpSignPlain", false);
// process encryption settings:
// 0: convenient encryption (global preference)
// 1: by default encrypt (account preference)
// 2: by default don't encrypt (account preference)
// NOTE: option defaultEncryptionPolicy is an INT
identity.setIntAttribute("defaultEncryptionPolicy", 0);
}
function disableIdSel(doDisable) {
var idSelectionBox = document.getElementById("idSelection");
var node = idSelectionBox.firstChild;
while (node) {
node.setAttribute('disabled', doDisable);
node = node.nextSibling;
}
if (doDisable) {
disableNext(false);
}
else {
checkIdSelection();
}
}
function checkIdSelection() {
var node = document.getElementById("idSelection").firstChild;
disableNext(countSelectedId() < 1);
}
function loadLastPage() {
var wizard = getWizard();
wizard.canRewind = false;
wizard.getButton("cancel").disabled = true;
}
function setNewKey() {
disableNext(false);
gCreateNewKey = true;
document.getElementById("uidSelection").boxObject.element.setAttribute("disabled", "true");
}
function setUseKey() {
gCreateNewKey = false;
document.getElementById("uidSelection").boxObject.element.removeAttribute("disabled");
onKeySelected();
}
function setImportKeys() {
gCreateNewKey = false;
disableNext(false);
document.getElementById("uidSelection").boxObject.element.setAttribute("disabled", "true");
}
// Helper function
function getServersForIdentity(accMgr, identity) {
return accMgr.getServersForIdentity(identity);
}
// ensure GpgHomeDir exists.
function ensureGpgHomeDir() {
let homeDirPath = EnigmailGpgAgent.getGpgHomeDir();
if (!homeDirPath) throw "no gpghome dir";
let homeDir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
homeDir.initWithPath(homeDirPath);
if (!homeDir.exists()) {
homeDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0x1C0);
return {
homeDir: homeDir,
existed: false
};
}
homeDir.normalize();
if (!homeDir.isDirectory()) {
EnigmailDialog.alert(window, EnigmailLocale.getString("setupWizard.noGpgHomeDir", [homeDirPath]));
throw "not a directory";
}
return {
homeDir: homeDir,
existed: true
};
}
// import from backup file
function importSettings() {
let r = doImportSettings();
document.getElementById("importInProgress").setAttribute("hidden", "true");
if (!r) {
document.getElementById("errorMessage").removeAttribute("hidden");
}
return r;
}
function doImportSettings() {
EnigmailLog.DEBUG("enigmailSetupWizard.js: importSettings\n");
let importFile = gImportSettingsFile.value;
if (!importFile.exists()) {
EnigmailLog.DEBUG("enigmailSetupWizard.js: importSettings: Importfile doesn't exist!\n");
return false;
}
importFile.normalize();
if (!importFile.isFile()) {
EnigmailLog.DEBUG("enigmailSetupWizard.js: importSettings: Importfile is not a normal file!\n");
return false;
}
document.getElementById("errorMessage").setAttribute("hidden", "true");
document.getElementById("importInProgress").removeAttribute("hidden");
let zipR;
try {
zipR = EnigmailFiles.openZipFile(importFile);
}
catch (ex) {
EnigmailLog.DEBUG("enigmailSetupWizard.js: importSettings - openZipFile() failed with " + ex.toString() + "\n" + ex.stack + "\n");
EnigAlert(EnigGetString("setupWizard.invalidSettingsFile"));
return false;
}
let cfg;
try {
cfg = ensureGpgHomeDir();
}
catch (ex) {
EnigmailLog.DEBUG("enigmailSetupWizard.js: importSettings - ensureGpgHomeDir() failed with " + ex.toString() + "\n" + ex.stack + "\n");
return false;
}
let tmpDir = EnigmailFiles.createTempSubDir("enig-imp", true);
EnigmailLog.DEBUG("enigmailSetupWizard.js: tmpDir=" + tmpDir.path + "\n");
let files = ["keyring.asc", "ownertrust.txt", "prefs.json"];
let filesAreMissing = false;
// check if mandatory files are included
for (let i in files) {
if (!zipR.hasEntry(files[i])) {
filesAreMissing = true;
EnigmailLog.DEBUG("enigmailSetupWizard.js: importSettings: InvalidSettingsFile, missing: " + files[i] + "\n");
}
}
if (filesAreMissing) {
EnigAlert(EnigGetString("setupWizard.invalidSettingsFile"));
return false;
}
// append optional files
files.push("gpg.conf");
for (let i in files) {
if (zipR.hasEntry(files[i])) {
EnigmailLog.DEBUG("enigmailSetupWizard.js: extracting " + files[i] + "\n");
let outF = tmpDir.clone();
outF.append(files[i]);
zipR.extract(files[i], outF);
}
}
let tmpFile = tmpDir.clone();
tmpFile.append("keyring.asc");
let errorMsgObj = {},
importedKeysObj = {};
EnigmailKeyRing.importKeyFromFile(tmpFile, errorMsgObj, importedKeysObj);
tmpFile = tmpDir.clone();
tmpFile.append("ownertrust.txt");
EnigmailKeyRing.importOwnerTrust(tmpFile, errorMsgObj);
tmpFile = tmpDir.clone();
tmpFile.append("gpg.conf");
if (tmpFile.exists()) {
let doCfgFile = true;
if (cfg.existed) {
let cfgFile = cfg.homeDir.clone();
cfgFile.append("gpg.conf");
if (cfgFile.exists()) {
if (!EnigConfirm(EnigGetString("setupWizard.gpgConfExists"), EnigGetString("dlg.button.overwrite"), EnigGetString("dlg.button.skip"))) {
EnigmailLog.DEBUG("enigmailSetupWizard.js: importSettings: User has chosen to keep the already existing local gpg.conf.\n");
doCfgFile = false;
}
}
}
try {
if (doCfgFile) tmpFile.moveTo(cfg.homeDir, "gpg.conf");
}
catch (ex) {
EnigmailLog.DEBUG("enigmailSetupWizard.js: importSettings: Error with gpg.conf " + ex.toString() + "\n");
}
}
else {
EnigmailLog.DEBUG("enigmailSetupWizard.js: importSettings: Remark: no gpg.conf file in archive.\n");
}
tmpFile = tmpDir.clone();
tmpFile.append("prefs.json");
let r = EnigmailConfigBackup.restorePrefs(tmpFile);
if (r.retVal === 0 && r.unmatchedIds.length > 0) {
displayUnmatchedIds(r.unmatchedIds);
}
tmpDir.remove(true);
return true;
}
function displayUnmatchedIds(emailArr) {
EnigAlert(EnigGetString("setupWizard.unmachtedIds", ["- " + emailArr.join("\n- ")]));
}
+
+function wizardUpload() {
+ disableNext(true);
+ keyUploadCheckAvailability();
+}
+
+function keyUploadCheckAvailability() {
+ let keyId;
+
+ if (gGeneratedKey === null) {
+ let uidSel = document.getElementById("uidSelection");
+ let keyIdCol = uidSel.columns.getColumnAt(1);
+ keyId = uidSel.view.getCellText(uidSel.currentIndex, keyIdCol).toString();
+ }
+ else {
+ keyId = gGeneratedKey;
+ }
+ let key = EnigmailKeyRing.getKeyById(keyId);
+ let uid = key.userIds[0].userId;
+
+ document.getElementById("keyUploadWksDeck").selectedIndex = 0;
+ EnigmailWks.isWksSupportedAsync(uid, window, function(is_supported) {
+ document.getElementById("keyUploadWksDeck").selectedIndex = 1;
+ if (is_supported) {
+ document.getElementById("keyUploadWks").removeAttribute("disabled");
+ document.getElementById("keyUploadWks").setAttribute("checked", "true");
+ EnigmailLog.DEBUG("wks supported for " + uid + "\n");
+ }
+ else {
+ document.getElementById("keyUploadWks").setAttribute("checked", "false");
+ document.getElementById("keyUploadWks").setAttribute("disabled", "true");
+ EnigmailLog.DEBUG("wks NOT supported for " + uid + "\n");
+ }
+ disableNext(false);
+ });
+}
+
+function keyUploadDo() {
+ let keyId;
+
+ if (gGeneratedKey === null) {
+ let uidSel = document.getElementById("uidSelection");
+ let keyIdCol = uidSel.columns.getColumnAt(1);
+ keyId = uidSel.view.getCellText(uidSel.currentIndex, keyIdCol).toString();
+ }
+ else {
+ keyId = gGeneratedKey;
+ }
+ let key = EnigmailKeyRing.getKeyById(keyId);
+
+ if (key !== null) {
+ if (document.getElementById("keyUploadSks").getAttribute("checked") == "true") {
+ keyServerAccess(key, true);
+ }
+
+ if (document.getElementById("keyUploadWks").getAttribute("checked") == "true") {
+ keyServerAccess(key, false);
+ }
+ }
+}
+
+function keyServerAccess(key, useHkp) {
+ const nsIEnigmail = Components.interfaces.nsIEnigmail;
+
+ let resultObj = {};
+ let accessType = 0;
+
+ if (useHkp) {
+ accessType = nsIEnigmail.UPLOAD_KEY;
+ }
+ else {
+ accessType = nsIEnigmail.UPLOAD_WKD;
+ }
+
+ EnigmailKeyServer.keyServerUpDownload(window, [key], accessType, function() {}, resultObj);
+}
diff --git a/ui/content/enigmailSetupWizard.xul b/ui/content/enigmailSetupWizard.xul
index e651a33d..a7c0ee6d 100644
--- a/ui/content/enigmailSetupWizard.xul
+++ b/ui/content/enigmailSetupWizard.xul
@@ -1,478 +1,503 @@
%brandDTD;
%enigMailDTD;
]>
&enigmail.setupWiz.pgIntro.desc;
&enigmail.setupWiz.pgIntro.desc2;
&enigmail.setupWiz.pgWelcome.manualOrAuto;
&enigmail.setupWiz.pgInstall.desc;
&enigmail.setupWiz.pgInstall.installDesc1;
&enigmail.setupWiz.pgInstall.installDesc2;
&enigmail.setupWiz.pgInstall.locateDesc;
&enigmail.setupWiz.pgSelectId.desc2;
&enigmail.setupWiz.pgSelectId.note;
&enigmail.setupWiz.pgKeySel.desc2;
&enigmail.setupWiz.pgNoKeyFound.desc2;
&enigmail.setupWiz.pgKeyCreate.descTwoKeys;
&enigmail.setupWiz.pgKeyCreate.descPub;
&enigmail.setupWiz.pgKeyCreate.descSec1;
&enigmail.setupWiz.pgKeyCreate.descSec2;
&enigmail.setupWiz.pgKeyCreate.descPass;
&enigmail.setupWiz.pgKeyCreate.passContain;
&enigmail.setupWiz.pgKeyCreate.passQuality;
&enigmail.setupWiz.pgKeyImport.desc;
&enigmail.keygen.desc;&enigmail.setupWiz.pgKeygen.keyGenComplete;
&enigmail.setupWiz.pgKeygen.revokeCertDesc;
+
+
+
+
+ &enigmail.keyUpload.desc;
+
+
+
+
+
+
+
+
+
+
+
+ &enigmail.keyUpload.sks.desc;
+
+
+
+
&enigmail.setupWiz.pgImportSettings.desc;
&enigmail.setupWiz.pgImportSettings.importing;
&enigmail.setupWiz.pgImportSettings.error;
&enigmail.setupWiz.pgComplete.desc;
&enigmail.setupWiz.pgExpert.desc;
diff --git a/ui/locale/en-US/enigmail.dtd b/ui/locale/en-US/enigmail.dtd
index b75d363f..e5971dc8 100644
--- a/ui/locale/en-US/enigmail.dtd
+++ b/ui/locale/en-US/enigmail.dtd
@@ -1,854 +1,862 @@
Mozilla Public License 2.0.">
+
+
+
+
OpenPGP Security)">
NOTE: Key generation may take up to several minutes to complete. Do not exit the application while key generation is in progress. Actively browsing or performing disk-intensive operations during key generation will replenish the 'randomness pool' and speed-up the process. You will be alerted when key generation is completed.">
NOTE: Key generation may take up to several minutes to complete. Do not exit the application while key generation is in progress. You will be alerted when key generation is completed.">
Note: Enigmail will always verify signatures
on emails for every account or identity, regardless of whether it is enabled or not">
public key is for others to send you encrypted emails. You can distribute it to everybody.">
private key is for yourself to decrypt these emails and to send signed emails.
You should give it to nobody.">
private key is for you to decrypt these emails and to send signed emails.
You should give it to nobody.
To secure your private key, you will be prompted for a passphrase in the following two dialogs.">
passphrase is a password to protect your private key. It prevents misuse of your private key.">
not recommended.">
You will be prompted to enter your password for this.">
+
+
+
+
export your data from your old computer using the backup wizard from the Enigmail Preferencesimport the data to your new computer using this wizard.
">
Thank you for using Enigmail.">
export your data from your old computer using this wizardimport the data to your new computer using the Setup Wizard.
">