summaryrefslogtreecommitdiffstats
path: root/comm/mail/extensions/openpgp/content/modules/webKey.jsm
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mail/extensions/openpgp/content/modules/webKey.jsm')
-rw-r--r--comm/mail/extensions/openpgp/content/modules/webKey.jsm293
1 files changed, 293 insertions, 0 deletions
diff --git a/comm/mail/extensions/openpgp/content/modules/webKey.jsm b/comm/mail/extensions/openpgp/content/modules/webKey.jsm
new file mode 100644
index 0000000000..76bd316e63
--- /dev/null
+++ b/comm/mail/extensions/openpgp/content/modules/webKey.jsm
@@ -0,0 +1,293 @@
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+/**
+ * This module serves to integrate WKS (Webkey service) into Enigmail
+ */
+
+"use strict";
+
+var EXPORTED_SYMBOLS = ["EnigmailWks"];
+
+const { XPCOMUtils } = ChromeUtils.importESModule(
+ "resource://gre/modules/XPCOMUtils.sys.mjs"
+);
+const { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+
+const lazy = {};
+XPCOMUtils.defineLazyModuleGetters(lazy, {
+ EnigmailFuncs: "chrome://openpgp/content/modules/funcs.jsm",
+ EnigmailLog: "chrome://openpgp/content/modules/log.jsm",
+});
+
+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
+ * @returns : Object - NULL or a process handle
+ */
+ getWksClientPathAsync(window, cb) {
+ lazy.EnigmailLog.DEBUG("webKey.jsm: getWksClientPathAsync\n");
+ throw new Error("Not implemented");
+ },
+
+ /**
+ * 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
+ * @returns : Object - process handle
+ */
+ isWksSupportedAsync(email, window, cb) {
+ lazy.EnigmailLog.DEBUG(
+ "webKey.jsm: isWksSupportedAsync: email = " + email + "\n"
+ );
+ throw new Error("Not implemented");
+ },
+
+ /**
+ * Submit a set of keys to the Web Key Server (WKD)
+ *
+ * @param keys: Array of KeyObj
+ * @param win: parent Window for displaying dialogs
+ * @param observer: Object (KeySrvListener API)
+ * Object implementing:
+ * - onProgress: function(percentComplete) [only implemented for download()]
+ * - onCancel: function() - the body will be set by the callee
+ *
+ * @returns Promise<...>
+ */
+ wksUpload(keys, win, observer = null) {
+ lazy.EnigmailLog.DEBUG(`webKey.jsm: wksUpload(): keys = ${keys.length}\n`);
+ let ids = getWkdIdentities(keys);
+
+ if (observer === null) {
+ observer = {
+ onProgress() {},
+ };
+ }
+
+ observer.isCanceled = false;
+ observer.onCancel = function () {
+ this.isCanceled = true;
+ };
+
+ if (!ids) {
+ throw new Error("error");
+ }
+
+ if (ids.senderIdentities.length === 0) {
+ return new Promise(resolve => {
+ resolve([]);
+ });
+ }
+
+ return performWkdUpload(ids.senderIdentities, win, observer);
+ },
+
+ /**
+ * 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
+ * @returns : Object - process handle
+ */
+
+ submitKey(ident, key, window, cb) {
+ lazy.EnigmailLog.DEBUG(
+ "webKey.jsm: submitKey(): email = " + ident.email + "\n"
+ );
+ throw new Error("Not implemented");
+ },
+
+ /**
+ * 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
+ * @returns : Object - process handle
+ */
+
+ confirmKey(ident, body, window, cb) {
+ lazy.EnigmailLog.DEBUG(
+ "webKey.jsm: confirmKey: ident=" + ident.email + "\n"
+ );
+ throw new Error("Not implemented");
+ },
+};
+
+/**
+ * Check if a file exists and is executable
+ *
+ * @param path: String - directory name
+ * @param execFileName: String - executable name
+ *
+ * @returns Object - nsIFile if file exists; NULL otherwise
+ */
+
+function getWkdIdentities(keys) {
+ lazy.EnigmailLog.DEBUG(
+ `webKey.jsm: getWkdIdentities(): keys = ${keys.length}\n`
+ );
+ let senderIdentities = [],
+ notFound = [];
+
+ for (let key of keys) {
+ try {
+ let found = false;
+ for (let uid of key.userIds) {
+ let email = lazy.EnigmailFuncs.stripEmail(uid.userId).toLowerCase();
+ let identity = MailServices.accounts.allIdentities.find(
+ id => id.email?.toLowerCase() == email
+ );
+
+ if (identity) {
+ senderIdentities.push({
+ identity,
+ fpr: key.fpr,
+ });
+ }
+ }
+ if (!found) {
+ notFound.push(key);
+ }
+ } catch (ex) {
+ lazy.EnigmailLog.DEBUG(ex + "\n");
+ return null;
+ }
+ }
+
+ return {
+ senderIdentities,
+ notFound,
+ };
+}
+
+/**
+ * Do the WKD upload and interact with a progress receiver
+ *
+ * @param keyList: Object:
+ * - fprList (String - fingerprint)
+ * - senderIdentities (nsIMsgIdentity)
+ * @param win: nsIWindow - parent window
+ * @param observer: Object:
+ * - onProgress: function(percentComplete [0 .. 100])
+ * called after processing of every key (independent of status)
+ * - onUpload: function(fpr)
+ * called after successful uploading of a key
+ * - onFinished: function(completionStatus, errorMessage, displayError)
+ * - isCanceled: Boolean - used to determine if process is canceled
+ */
+function performWkdUpload(keyList, win, observer) {
+ lazy.EnigmailLog.DEBUG(
+ `webKey.jsm: performWkdUpload: keyList.length=${keyList.length}\n`
+ );
+
+ let uploads = [];
+
+ let numKeys = keyList.length;
+
+ // For each key fpr/sender identity pair, check whenever WKS is supported
+ // Result is an array of booleans
+ for (let i = 0; i < numKeys; i++) {
+ let keyFpr = keyList[i].fpr;
+ let senderIdent = keyList[i].identity;
+
+ let was_uploaded = new Promise(function (resolve, reject) {
+ lazy.EnigmailLog.DEBUG(
+ "webKey.jsm: performWkdUpload: _isSupported(): ident=" +
+ senderIdent.email +
+ ", key=" +
+ keyFpr +
+ "\n"
+ );
+ EnigmailWks.isWksSupportedAsync(
+ senderIdent.email,
+ win,
+ function (is_supported) {
+ if (observer.isCanceled) {
+ lazy.EnigmailLog.DEBUG(
+ "webKey.jsm: performWkdUpload: canceled by user\n"
+ );
+ reject("canceled");
+ }
+
+ lazy.EnigmailLog.DEBUG(
+ "webKey.jsm: performWkdUpload: ident=" +
+ senderIdent.email +
+ ", supported=" +
+ is_supported +
+ "\n"
+ );
+ resolve(is_supported);
+ }
+ );
+ }).then(function (is_supported) {
+ lazy.EnigmailLog.DEBUG(
+ `webKey.jsm: performWkdUpload: _submitKey ${is_supported}\n`
+ );
+ if (is_supported) {
+ return new Promise(function (resolve, reject) {
+ EnigmailWks.submitKey(
+ senderIdent,
+ {
+ fpr: keyFpr,
+ },
+ win,
+ function (success) {
+ observer.onProgress(((i + 1) / numKeys) * 100);
+ if (success) {
+ resolve(senderIdent);
+ } else {
+ reject("submitFailed");
+ }
+ }
+ );
+ });
+ }
+
+ observer.onProgress(((i + 1) / numKeys) * 100);
+ return Promise.resolve(null);
+ });
+
+ uploads.push(was_uploaded);
+ }
+
+ return Promise.all(uploads)
+ .catch(function (reason) {
+ //let errorMsg = "Could not upload your key to the Web Key Service";
+ return [];
+ })
+ .then(function (senders) {
+ let uploaded_uids = [];
+ if (senders) {
+ senders.forEach(function (val) {
+ if (val !== null) {
+ uploaded_uids.push(val.email);
+ }
+ });
+ }
+ observer.onProgress(100);
+
+ return uploaded_uids;
+ });
+}