diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /comm/mail/extensions/openpgp/content/modules/wksMimeHandler.jsm | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'comm/mail/extensions/openpgp/content/modules/wksMimeHandler.jsm')
-rw-r--r-- | comm/mail/extensions/openpgp/content/modules/wksMimeHandler.jsm | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/comm/mail/extensions/openpgp/content/modules/wksMimeHandler.jsm b/comm/mail/extensions/openpgp/content/modules/wksMimeHandler.jsm new file mode 100644 index 0000000000..40a8d221f0 --- /dev/null +++ b/comm/mail/extensions/openpgp/content/modules/wksMimeHandler.jsm @@ -0,0 +1,262 @@ +/* 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/. */ + +"use strict"; + +const EXPORTED_SYMBOLS = ["EnigmailWksMimeHandler"]; + +const { XPCOMUtils } = ChromeUtils.importESModule( + "resource://gre/modules/XPCOMUtils.sys.mjs" +); + +const lazy = {}; + +XPCOMUtils.defineLazyModuleGetters(lazy, { + EnigmailConstants: "chrome://openpgp/content/modules/constants.jsm", + EnigmailDecryption: "chrome://openpgp/content/modules/decryption.jsm", + EnigmailLog: "chrome://openpgp/content/modules/log.jsm", + EnigmailSingletons: "chrome://openpgp/content/modules/singletons.jsm", + EnigmailVerify: "chrome://openpgp/content/modules/mimeVerify.jsm", +}); + +XPCOMUtils.defineLazyGetter(lazy, "l10n", () => { + return new Localization(["messenger/openpgp/openpgp.ftl"], true); +}); + +/** + * Module for handling response messages from OpenPGP Web Key Service + */ + +var gDebugLog = false; + +var EnigmailWksMimeHandler = { + /*** + * register a PGP/MIME verify object the same way PGP/MIME encrypted mail is handled + */ + registerContentTypeHandler() { + lazy.EnigmailLog.DEBUG( + "wksMimeHandler.jsm: registerContentTypeHandler()\n" + ); + let reg = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); + + let pgpMimeClass = Cc["@mozilla.org/mimecth;1?type=multipart/encrypted"]; + + reg.registerFactory( + pgpMimeClass, + "Enigmail WKD Response Handler", + "@mozilla.org/mimecth;1?type=application/vnd.gnupg.wks", + null + ); + }, + + newHandler() { + lazy.EnigmailLog.DEBUG("wksMimeHandler.jsm: newHandler()\n"); + + let v = new PgpWkdHandler(); + return v; + }, +}; + +// MimeVerify Constructor +function PgpWkdHandler(protocol) { + this.inStream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance( + Ci.nsIScriptableInputStream + ); +} + +// PgpWkdHandler implementation +PgpWkdHandler.prototype = { + data: "", + mimePartNumber: "", + uri: null, + backgroundJob: false, + + QueryInterface: ChromeUtils.generateQI(["nsIStreamListener"]), + + onStartRequest(request, ctxt) { + lazy.EnigmailLog.DEBUG("wksMimeHandler.jsm: onStartRequest\n"); // always log this one + + this.mimeSvc = request.QueryInterface(Ci.nsIPgpMimeProxy); + if ("messageURI" in this.mimeSvc) { + this.uri = this.mimeSvc.messageURI; + } else { + this.uri = ctxt; + } + + if ("mimePart" in this.mimeSvc) { + this.mimePartNumber = this.mimeSvc.mimePart; + } else { + this.mimePartNumber = ""; + } + this.data = ""; + this.msgWindow = lazy.EnigmailVerify.lastWindow; + this.backgroundJob = false; + + if (this.uri) { + this.backgroundJob = + this.uri.spec.search(/[&?]header=(print|quotebody)/) >= 0; + } + }, + + onDataAvailable(req, dummy, stream, offset, count) { + if ("messageURI" in this.mimeSvc) { + // TB >= 67 + stream = dummy; + count = offset; + } + + LOCAL_DEBUG("wksMimeHandler.jsm: onDataAvailable: " + count + "\n"); + if (count > 0) { + this.inStream.init(stream); + let data = this.inStream.read(count); + this.data += data; + } + }, + + onStopRequest() { + lazy.EnigmailLog.DEBUG("wksMimeHandler.jsm: onStopRequest\n"); + + if (this.data.search(/-----BEGIN PGP MESSAGE-----/i) >= 0) { + this.decryptChallengeData(); + } + + let jsonStr = this.requestToJsonString(this.data); + + if (this.data.search(/^\s*type:\s+confirmation-request/im) >= 0) { + lazy.l10n.formatValue("wkd-message-body-req").then(value => { + this.returnData(value); + }); + } else { + lazy.l10n.formatValue("wkd-message-body-process").then(value => { + this.returnData(value); + }); + } + + this.displayStatus(jsonStr); + }, + + decryptChallengeData() { + lazy.EnigmailLog.DEBUG("wksMimeHandler.jsm: decryptChallengeData()\n"); + let windowManager = Services.wm; + let win = windowManager.getMostRecentWindow(null); + let statusFlagsObj = {}; + + let res = lazy.EnigmailDecryption.decryptMessage( + win, + 0, + this.data, + null, // date + {}, + {}, + statusFlagsObj, + {}, + {}, + {}, + {}, + {}, + {} + ); + + if (statusFlagsObj.value & lazy.EnigmailConstants.DECRYPTION_OKAY) { + this.data = res; + } + lazy.EnigmailLog.DEBUG( + "wksMimeHandler.jsm: decryptChallengeData: decryption result: " + + res + + "\n" + ); + }, + + // convert request data into JSON-string and parse it + requestToJsonString() { + // convert + let lines = this.data.split(/\r?\n/); + let s = "{"; + for (let l of lines) { + let m = l.match(/^([^\s:]+)(:\s*)([^\s].+)$/); + if (m && m.length >= 4) { + s += '"' + m[1].trim().toLowerCase() + '": "' + m[3].trim() + '",'; + } + } + + s = s.substr(0, s.length - 1) + "}"; + + return s; + }, + + // return data to libMime + returnData(message) { + lazy.EnigmailLog.DEBUG("wksMimeHandler.jsm: returnData():\n"); + + let msg = + 'Content-Type: text/plain; charset="utf-8"\r\n' + + "Content-Transfer-Encoding: 8bit\r\n\r\n" + + message + + "\r\n"; + + if ("outputDecryptedData" in this.mimeSvc) { + this.mimeSvc.outputDecryptedData(msg, msg.length); + } else { + let gConv = Cc["@mozilla.org/io/string-input-stream;1"].createInstance( + Ci.nsIStringInputStream + ); + gConv.setData(msg, msg.length); + try { + this.mimeSvc.onStartRequest(null); + this.mimeSvc.onDataAvailable(null, gConv, 0, msg.length); + this.mimeSvc.onStopRequest(null, 0); + } catch (ex) { + lazy.EnigmailLog.ERROR( + "wksMimeHandler.jsm: returnData(): mimeSvc.onDataAvailable failed:\n" + + ex.toString() + ); + } + } + }, + + displayStatus(jsonStr) { + lazy.EnigmailLog.DEBUG("wksMimeHandler.jsm: displayStatus\n"); + if (this.msgWindow === null || this.backgroundJob) { + return; + } + + try { + LOCAL_DEBUG("wksMimeHandler.jsm: displayStatus displaying result\n"); + let headerSink = lazy.EnigmailSingletons.messageReader; + + if (headerSink) { + headerSink.processDecryptionResult( + this.uri, + "wksConfirmRequest", + jsonStr, + this.mimePartNumber + ); + } + } catch (ex) { + lazy.EnigmailLog.writeException("wksMimeHandler.jsm", ex); + } + }, +}; + +//////////////////////////////////////////////////////////////////// +// General-purpose functions, not exported + +function LOCAL_DEBUG(str) { + if (gDebugLog) { + lazy.EnigmailLog.DEBUG(str); + } +} + +function initModule() { + let nspr_log_modules = Services.env.get("NSPR_LOG_MODULES"); + let matches = nspr_log_modules.match(/wksMimeHandler:(\d+)/); + + if (matches && matches.length > 1) { + if (matches[1] > 2) { + gDebugLog = true; + } + } +} + +initModule(); |