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; ]>