summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/mime/cthandlers
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /comm/mailnews/mime/cthandlers
parentInitial commit. (diff)
downloadthunderbird-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/mailnews/mime/cthandlers')
-rw-r--r--comm/mailnews/mime/cthandlers/glue/mimexpcom.cpp119
-rw-r--r--comm/mailnews/mime/cthandlers/glue/mimexpcom.h92
-rw-r--r--comm/mailnews/mime/cthandlers/glue/moz.build17
-rw-r--r--comm/mailnews/mime/cthandlers/glue/nsMimeContentTypeHandler.cpp55
-rw-r--r--comm/mailnews/mime/cthandlers/glue/nsMimeContentTypeHandler.h46
-rw-r--r--comm/mailnews/mime/cthandlers/moz.build10
-rw-r--r--comm/mailnews/mime/cthandlers/pgpmime/components.conf21
-rw-r--r--comm/mailnews/mime/cthandlers/pgpmime/moz.build24
-rw-r--r--comm/mailnews/mime/cthandlers/pgpmime/nsPgpMimeMimeContentTypeHandler.h22
-rw-r--r--comm/mailnews/mime/cthandlers/pgpmime/nsPgpMimeProxy.cpp672
-rw-r--r--comm/mailnews/mime/cthandlers/pgpmime/nsPgpMimeProxy.h73
11 files changed, 1151 insertions, 0 deletions
diff --git a/comm/mailnews/mime/cthandlers/glue/mimexpcom.cpp b/comm/mailnews/mime/cthandlers/glue/mimexpcom.cpp
new file mode 100644
index 0000000000..626dc043a4
--- /dev/null
+++ b/comm/mailnews/mime/cthandlers/glue/mimexpcom.cpp
@@ -0,0 +1,119 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#include "nsIMimeObjectClassAccess.h"
+#include "nsCOMPtr.h"
+#include "nsComponentManagerUtils.h"
+
+// {403B0540-B7C3-11d2-B35E-525400E2D63A}
+#define NS_MIME_OBJECT_CLASS_ACCESS_CID \
+ { \
+ 0x403b0540, 0xb7c3, 0x11d2, { \
+ 0xb3, 0x5e, 0x52, 0x54, 0x0, 0xe2, 0xd6, 0x3a \
+ } \
+ }
+static NS_DEFINE_CID(kMimeObjectClassAccessCID,
+ NS_MIME_OBJECT_CLASS_ACCESS_CID);
+
+/*
+ * These calls are necessary to expose the object class hierarchy
+ * to externally developed content type handlers.
+ */
+extern "C" void* COM_GetmimeInlineTextClass(void) {
+ void* ptr = NULL;
+
+ nsresult res;
+ nsCOMPtr<nsIMimeObjectClassAccess> objAccess =
+ do_CreateInstance(kMimeObjectClassAccessCID, &res);
+ if (NS_SUCCEEDED(res) && objAccess) objAccess->GetmimeInlineTextClass(&ptr);
+
+ return ptr;
+}
+
+extern "C" void* COM_GetmimeLeafClass(void) {
+ void* ptr = NULL;
+
+ nsresult res;
+ nsCOMPtr<nsIMimeObjectClassAccess> objAccess =
+ do_CreateInstance(kMimeObjectClassAccessCID, &res);
+ if (NS_SUCCEEDED(res) && objAccess) objAccess->GetmimeLeafClass(&ptr);
+
+ return ptr;
+}
+
+extern "C" void* COM_GetmimeObjectClass(void) {
+ void* ptr = NULL;
+
+ nsresult res;
+ nsCOMPtr<nsIMimeObjectClassAccess> objAccess =
+ do_CreateInstance(kMimeObjectClassAccessCID, &res);
+ if (NS_SUCCEEDED(res) && objAccess) objAccess->GetmimeObjectClass(&ptr);
+
+ return ptr;
+}
+
+extern "C" void* COM_GetmimeContainerClass(void) {
+ void* ptr = NULL;
+
+ nsresult res;
+ nsCOMPtr<nsIMimeObjectClassAccess> objAccess =
+ do_CreateInstance(kMimeObjectClassAccessCID, &res);
+ if (NS_SUCCEEDED(res) && objAccess) objAccess->GetmimeContainerClass(&ptr);
+
+ return ptr;
+}
+
+extern "C" void* COM_GetmimeMultipartClass(void) {
+ void* ptr = NULL;
+
+ nsresult res;
+ nsCOMPtr<nsIMimeObjectClassAccess> objAccess =
+ do_CreateInstance(kMimeObjectClassAccessCID, &res);
+ if (NS_SUCCEEDED(res) && objAccess) objAccess->GetmimeMultipartClass(&ptr);
+
+ return ptr;
+}
+
+extern "C" void* COM_GetmimeMultipartSignedClass(void) {
+ void* ptr = NULL;
+
+ nsresult res;
+ nsCOMPtr<nsIMimeObjectClassAccess> objAccess =
+ do_CreateInstance(kMimeObjectClassAccessCID, &res);
+ if (NS_SUCCEEDED(res) && objAccess)
+ objAccess->GetmimeMultipartSignedClass(&ptr);
+
+ return ptr;
+}
+
+extern "C" int COM_MimeObject_write(void* mimeObject, char* data,
+ int32_t length, bool user_visible_p) {
+ int32_t rc = -1;
+
+ nsresult res;
+ nsCOMPtr<nsIMimeObjectClassAccess> objAccess =
+ do_CreateInstance(kMimeObjectClassAccessCID, &res);
+ if (NS_SUCCEEDED(res) && objAccess) {
+ if (NS_SUCCEEDED(objAccess->MimeObjectWrite(mimeObject, data, length,
+ user_visible_p)))
+ rc = length;
+ else
+ rc = -1;
+ }
+
+ return rc;
+}
+
+extern "C" void* COM_MimeCreate(char* content_type, void* hdrs, void* opts) {
+ void* ptr = NULL;
+
+ nsresult res;
+ nsCOMPtr<nsIMimeObjectClassAccess> objAccess =
+ do_CreateInstance(kMimeObjectClassAccessCID, &res);
+ if (NS_SUCCEEDED(res) && objAccess)
+ objAccess->MimeCreate(content_type, hdrs, opts, &ptr);
+
+ return ptr;
+}
diff --git a/comm/mailnews/mime/cthandlers/glue/mimexpcom.h b/comm/mailnews/mime/cthandlers/glue/mimexpcom.h
new file mode 100644
index 0000000000..343c7d0dc7
--- /dev/null
+++ b/comm/mailnews/mime/cthandlers/glue/mimexpcom.h
@@ -0,0 +1,92 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+/*
+ * This is the definitions for the Content Type Handler plugins to
+ * access internals of libmime via XP-COM calls
+ */
+#ifndef _MIMEXPCOM_H_
+#define _MIMEXPCOM_H_
+
+/*
+ This header exposes functions that are necessary to access the
+ object hierarchy for the mime chart. The class hierarchy is:
+
+ MimeObject (abstract)
+ |
+ |--- MimeContainer (abstract)
+ | |
+ | |--- MimeMultipart (abstract)
+ | | |
+ | | |--- MimeMultipartMixed
+ | | |
+ | | |--- MimeMultipartDigest
+ | | |
+ | | |--- MimeMultipartParallel
+ | | |
+ | | |--- MimeMultipartAlternative
+ | | |
+ | | |--- MimeMultipartRelated
+ | | |
+ | | |--- MimeMultipartAppleDouble
+ | | |
+ | | |--- MimeSunAttachment
+ | | |
+ | | |--- MimeMultipartSigned (abstract)
+ | | |
+ | | |--- MimeMultipartSigned
+ | |
+ | |--- MimeXlateed (abstract)
+ | | |
+ | | |--- MimeXlateed
+ | |
+ | |--- MimeMessage
+ | |
+ | |--- MimeUntypedText
+ |
+ |--- MimeLeaf (abstract)
+ | |
+ | |--- MimeInlineText (abstract)
+ | | |
+ | | |--- MimeInlineTextPlain
+ | | |
+ | | |--- MimeInlineTextHTML
+ | | |
+ | | |--- MimeInlineTextRichtext
+ | | | |
+ | | | |--- MimeInlineTextEnriched
+ | | |
+ | | |--- MimeInlineTextVCard
+ | |
+ | |--- MimeInlineImage
+ | |
+ | |--- MimeExternalObject
+ |
+ |--- MimeExternalBody
+ */
+
+/*
+ * These functions are exposed by libmime to be used by content type
+ * handler plugins for processing stream data.
+ */
+/*
+ * This is the write call for outputting processed stream data.
+ */
+extern "C" int COM_MimeObject_write(void* mimeObject, const char* data,
+ int32_t length, bool user_visible_p);
+/*
+ * The following group of calls expose the pointers for the object
+ * system within libmime.
+ */
+extern "C" void* COM_GetmimeInlineTextClass(void);
+extern "C" void* COM_GetmimeLeafClass(void);
+extern "C" void* COM_GetmimeObjectClass(void);
+extern "C" void* COM_GetmimeContainerClass(void);
+extern "C" void* COM_GetmimeMultipartClass(void);
+extern "C" void* COM_GetmimeMultipartSignedClass(void);
+
+extern "C" void* COM_MimeCreate(char* content_type, void* hdrs, void* opts);
+
+#endif /* _MIMEXPCOM_H_ */
diff --git a/comm/mailnews/mime/cthandlers/glue/moz.build b/comm/mailnews/mime/cthandlers/glue/moz.build
new file mode 100644
index 0000000000..4955981f3d
--- /dev/null
+++ b/comm/mailnews/mime/cthandlers/glue/moz.build
@@ -0,0 +1,17 @@
+# vim: set filetype=python:
+# 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/.
+
+EXPORTS += [
+ "nsMimeContentTypeHandler.h",
+]
+
+SOURCES += [
+ "mimexpcom.cpp",
+ "nsMimeContentTypeHandler.cpp",
+]
+
+FINAL_LIBRARY = "mail"
+
+Library("mimecthglue_s")
diff --git a/comm/mailnews/mime/cthandlers/glue/nsMimeContentTypeHandler.cpp b/comm/mailnews/mime/cthandlers/glue/nsMimeContentTypeHandler.cpp
new file mode 100644
index 0000000000..ace9c64d8c
--- /dev/null
+++ b/comm/mailnews/mime/cthandlers/glue/nsMimeContentTypeHandler.cpp
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#include <stdio.h>
+#include "nscore.h"
+#include "plstr.h"
+#include "nsMimeContentTypeHandler.h"
+
+/*
+ * The following macros actually implement addref, release and
+ * query interface for our component.
+ */
+NS_IMPL_ISUPPORTS(nsMimeContentTypeHandler, nsIMimeContentTypeHandler)
+
+/*
+ * nsIMimeEmitter definitions....
+ */
+nsMimeContentTypeHandler::nsMimeContentTypeHandler(
+ const char* aMimeType, MCTHCreateCTHClass callback) {
+ NS_ASSERTION(
+ aMimeType,
+ "nsMimeContentTypeHandler should be initialized with non-null mime type");
+ NS_ASSERTION(
+ callback,
+ "nsMimeContentTypeHandler should be initialized with non-null callback");
+ mimeType = PL_strdup(aMimeType);
+ realCreateContentTypeHandlerClass = callback;
+}
+
+nsMimeContentTypeHandler::~nsMimeContentTypeHandler(void) {
+ if (mimeType) {
+ free(mimeType);
+ mimeType = 0;
+ }
+ realCreateContentTypeHandlerClass = 0;
+}
+
+// Get the content type if necessary
+nsresult nsMimeContentTypeHandler::GetContentType(char** contentType) {
+ *contentType = PL_strdup(mimeType);
+ return NS_OK;
+}
+
+// Set the output stream for processed data.
+nsresult nsMimeContentTypeHandler::CreateContentTypeHandlerClass(
+ const char* content_type, contentTypeHandlerInitStruct* initStruct,
+ MimeObjectClass** objClass) {
+ *objClass = realCreateContentTypeHandlerClass(content_type, initStruct);
+ if (!*objClass)
+ return NS_ERROR_OUT_OF_MEMORY; /* we couldn't allocate the object */
+ else
+ return NS_OK;
+}
diff --git a/comm/mailnews/mime/cthandlers/glue/nsMimeContentTypeHandler.h b/comm/mailnews/mime/cthandlers/glue/nsMimeContentTypeHandler.h
new file mode 100644
index 0000000000..2974e98f17
--- /dev/null
+++ b/comm/mailnews/mime/cthandlers/glue/nsMimeContentTypeHandler.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+/*
+ * This interface is implemented by content type handlers that will be
+ * called upon by libmime to process various attachments types. The primary
+ * purpose of these handlers will be to represent the attached data in a
+ * viewable HTML format that is useful for the user
+ *
+ * Note: These will all register by their content type prefixed by the
+ * following: mimecth:text/vcard
+ *
+ * libmime will then use the XPCOM Component Manager to
+ * locate the appropriate Content Type handler
+ */
+#ifndef nsMimeContentTypeHandler_h_
+#define nsMimeContentTypeHandler_h_
+
+#include "mozilla/Attributes.h"
+#include "nsIMimeContentTypeHandler.h"
+
+typedef MimeObjectClass* (*MCTHCreateCTHClass)(
+ const char* content_type, contentTypeHandlerInitStruct* initStruct);
+
+class nsMimeContentTypeHandler : public nsIMimeContentTypeHandler {
+ public:
+ nsMimeContentTypeHandler(const char* aMimeType, MCTHCreateCTHClass callback);
+
+ /* this macro defines QueryInterface, AddRef and Release for this class */
+ NS_DECL_ISUPPORTS
+
+ NS_IMETHOD GetContentType(char** contentType) override;
+
+ NS_IMETHOD CreateContentTypeHandlerClass(
+ const char* content_type, contentTypeHandlerInitStruct* initStruct,
+ MimeObjectClass** objClass) override;
+
+ private:
+ virtual ~nsMimeContentTypeHandler();
+ char* mimeType;
+ MCTHCreateCTHClass realCreateContentTypeHandlerClass;
+};
+
+#endif /* nsMimeContentTypeHandler_h_ */
diff --git a/comm/mailnews/mime/cthandlers/moz.build b/comm/mailnews/mime/cthandlers/moz.build
new file mode 100644
index 0000000000..7d61b9ebf5
--- /dev/null
+++ b/comm/mailnews/mime/cthandlers/moz.build
@@ -0,0 +1,10 @@
+# vim: set filetype=python:
+# 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/.
+
+# pgpmime depends on glue.
+DIRS += [
+ "glue",
+ "pgpmime",
+]
diff --git a/comm/mailnews/mime/cthandlers/pgpmime/components.conf b/comm/mailnews/mime/cthandlers/pgpmime/components.conf
new file mode 100644
index 0000000000..a1098a43f8
--- /dev/null
+++ b/comm/mailnews/mime/cthandlers/pgpmime/components.conf
@@ -0,0 +1,21 @@
+# 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/.
+
+Classes = [
+ {
+ "cid": "{212f415f-f8b5-11d2-ffe0-00af19a7d144}",
+ "contract_ids": [
+ "@mozilla.org/mimecth;1?type=multipart/encrypted",
+ ],
+ "legacy_constructor": "nsPgpMimeMimeContentTypeHandlerConstructor",
+ "headers": ["/comm/mailnews/mime/cthandlers/pgpmime/nsPgpMimeMimeContentTypeHandler.h"],
+ },
+ {
+ "cid": "{815c4fbe-0e7c-45b6-8324-f7044c7252ac}",
+ "contract_ids": ["@mozilla.org/mime/pgp-mime-decrypt;1"],
+ "type": "nsPgpMimeProxy",
+ "init_method": "Init",
+ "headers": ["/comm/mailnews/mime/cthandlers/pgpmime/nsPgpMimeProxy.h"],
+ },
+]
diff --git a/comm/mailnews/mime/cthandlers/pgpmime/moz.build b/comm/mailnews/mime/cthandlers/pgpmime/moz.build
new file mode 100644
index 0000000000..7259395c5a
--- /dev/null
+++ b/comm/mailnews/mime/cthandlers/pgpmime/moz.build
@@ -0,0 +1,24 @@
+# vim: set filetype=python:
+# 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/.
+
+EXPORTS += [
+ "nsPgpMimeProxy.h",
+]
+
+SOURCES += [
+ "nsPgpMimeProxy.cpp",
+]
+
+FINAL_LIBRARY = "mail"
+
+Library("pgpmime_s")
+
+LOCAL_INCLUDES += [
+ "../glue",
+]
+
+XPCOM_MANIFESTS += [
+ "components.conf",
+]
diff --git a/comm/mailnews/mime/cthandlers/pgpmime/nsPgpMimeMimeContentTypeHandler.h b/comm/mailnews/mime/cthandlers/pgpmime/nsPgpMimeMimeContentTypeHandler.h
new file mode 100644
index 0000000000..bc8a432b08
--- /dev/null
+++ b/comm/mailnews/mime/cthandlers/pgpmime/nsPgpMimeMimeContentTypeHandler.h
@@ -0,0 +1,22 @@
+/* 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/. */
+
+#include "nsMimeContentTypeHandler.h"
+#include "nsPgpMimeProxy.h"
+
+extern "C" MimeObjectClass* MIME_PgpMimeCreateContentTypeHandlerClass(
+ const char* content_type, contentTypeHandlerInitStruct* initStruct);
+
+static nsresult nsPgpMimeMimeContentTypeHandlerConstructor(REFNSIID aIID,
+ void** aResult) {
+ NS_ENSURE_ARG_POINTER(aResult);
+ *aResult = nullptr;
+
+ RefPtr<nsMimeContentTypeHandler> inst(new nsMimeContentTypeHandler(
+ "multipart/encrypted", &MIME_PgpMimeCreateContentTypeHandlerClass));
+
+ NS_ENSURE_TRUE(inst, NS_ERROR_OUT_OF_MEMORY);
+
+ return inst->QueryInterface(aIID, aResult);
+}
diff --git a/comm/mailnews/mime/cthandlers/pgpmime/nsPgpMimeProxy.cpp b/comm/mailnews/mime/cthandlers/pgpmime/nsPgpMimeProxy.cpp
new file mode 100644
index 0000000000..4382ed0c1a
--- /dev/null
+++ b/comm/mailnews/mime/cthandlers/pgpmime/nsPgpMimeProxy.cpp
@@ -0,0 +1,672 @@
+/* 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/. */
+
+#include "nsPgpMimeProxy.h"
+#include "nspr.h"
+#include "plstr.h"
+#include "nsCOMPtr.h"
+#include "nsString.h"
+#include "mozilla/Components.h"
+#include "nsIRequest.h"
+#include "nsIStringBundle.h"
+#include "nsIPrefService.h"
+#include "nsIPrefBranch.h"
+#include "nsIURI.h"
+#include "mimexpcom.h"
+#include "nsMsgUtils.h"
+#include "nsNetUtil.h"
+
+#include "mimecth.h"
+#include "mimemoz2.h"
+#include "nspr.h"
+#include "plstr.h"
+#include "nsIPgpMimeProxy.h"
+#include "nsComponentManagerUtils.h"
+
+/**
+ * Overall description
+ * ===================
+ *
+ * There are three components involved here: MIME, a proxy object
+ * (nsPgpMimeProxy) and Enigmail (or any other add-on that registered a
+ * decryption object with
+ * "@mozilla.org/mime/pgp-mime-js-decrypt;1").
+ *
+ * MIME creates and initialises the proxy object in nsPgpMimeProxy::Init(). This
+ * creates a decryption object, for example EnigmailMimeDecrypt. When MIME wants
+ * to decode something, it calls the Write() method of the proxy, which in turn
+ * calls OnDataAvailable() on the decryptor. The decryptor optains the encrypted
+ * data form the proxy via the proxy's Read() method. The decryptor decrypts the
+ * data and passes the result back to the proxy, using the OutputDecryptedData()
+ * method or by passing a stream to the proxy's OnDataAvailable() method, in
+ * which the proxy will read from that stream. The proxy knows how to interface
+ * with MIME and passes the data on using some function pointers it got given
+ * via nsPgpMimeProxy::SetMimeCallback().
+ */
+
+#define MIME_SUPERCLASS mimeEncryptedClass
+MimeDefClass(MimeEncryptedPgp, MimeEncryptedPgpClass, mimeEncryptedPgpClass,
+ &MIME_SUPERCLASS);
+
+#define kCharMax 1024
+
+extern "C" MimeObjectClass* MIME_PgpMimeCreateContentTypeHandlerClass(
+ const char* content_type, contentTypeHandlerInitStruct* initStruct) {
+ MimeObjectClass* objClass = (MimeObjectClass*)&mimeEncryptedPgpClass;
+
+ initStruct->force_inline_display = false;
+
+ return objClass;
+}
+
+static void* MimePgpe_init(MimeObject*,
+ int (*output_fn)(const char*, int32_t, void*),
+ void*);
+static int MimePgpe_write(const char*, int32_t, void*);
+static int MimePgpe_eof(void*, bool);
+static char* MimePgpe_generate(void*);
+static void MimePgpe_free(void*);
+
+/* Returns a string describing the location of the part (like "2.5.3").
+ This is not a full URL, just a part-number.
+ */
+static nsCString determineMimePart(MimeObject* obj);
+
+#define PGPMIME_PROPERTIES_URL "chrome://messenger/locale/pgpmime.properties"
+#define PGPMIME_STR_NOT_SUPPORTED_ID "pgpNotAvailable"
+
+static void PgpMimeGetNeedsAddonString(nsCString& aResult) {
+ aResult.AssignLiteral("???");
+
+ nsCOMPtr<nsIStringBundleService> stringBundleService =
+ mozilla::components::StringBundle::Service();
+
+ nsCOMPtr<nsIStringBundle> stringBundle;
+ nsresult rv = stringBundleService->CreateBundle(PGPMIME_PROPERTIES_URL,
+ getter_AddRefs(stringBundle));
+ if (NS_FAILED(rv)) return;
+
+ nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
+ if (NS_FAILED(rv)) return;
+
+ nsString result;
+ rv = stringBundle->GetStringFromName(PGPMIME_STR_NOT_SUPPORTED_ID, result);
+ if (NS_FAILED(rv)) return;
+ aResult = NS_ConvertUTF16toUTF8(result);
+}
+
+static int MimeEncryptedPgpClassInitialize(MimeEncryptedPgpClass* clazz) {
+ mozilla::DebugOnly<MimeObjectClass*> oclass = (MimeObjectClass*)clazz;
+ NS_ASSERTION(!oclass->class_initialized, "oclass is not initialized");
+
+ MimeEncryptedClass* eclass = (MimeEncryptedClass*)clazz;
+
+ eclass->crypto_init = MimePgpe_init;
+ eclass->crypto_write = MimePgpe_write;
+ eclass->crypto_eof = MimePgpe_eof;
+ eclass->crypto_generate_html = MimePgpe_generate;
+ eclass->crypto_free = MimePgpe_free;
+
+ return 0;
+}
+
+class MimePgpeData : public nsISupports {
+ public:
+ NS_DECL_ISUPPORTS
+
+ int (*output_fn)(const char* buf, int32_t buf_size, void* output_closure);
+ void* output_closure;
+ MimeObject* self;
+
+ nsCOMPtr<nsIPgpMimeProxy> mimeDecrypt;
+
+ MimePgpeData() : output_fn(nullptr), output_closure(nullptr) {}
+
+ private:
+ virtual ~MimePgpeData() {}
+};
+
+NS_IMPL_ISUPPORTS0(MimePgpeData)
+
+static void* MimePgpe_init(MimeObject* obj,
+ int (*output_fn)(const char* buf, int32_t buf_size,
+ void* output_closure),
+ void* output_closure) {
+ if (!(obj && obj->options && output_fn)) return nullptr;
+
+ MimePgpeData* data = new MimePgpeData();
+ NS_ENSURE_TRUE(data, nullptr);
+
+ data->self = obj;
+ data->output_fn = output_fn;
+ data->output_closure = output_closure;
+ data->mimeDecrypt = nullptr;
+
+ // Create proxy object.
+ nsresult rv;
+ data->mimeDecrypt = do_CreateInstance(NS_PGPMIMEPROXY_CONTRACTID, &rv);
+ if (NS_FAILED(rv)) return data;
+
+ char* ct = MimeHeaders_get(obj->headers, HEADER_CONTENT_TYPE, false, false);
+
+ rv = (ct ? data->mimeDecrypt->SetContentType(nsDependentCString(ct))
+ : data->mimeDecrypt->SetContentType(EmptyCString()));
+
+ PR_Free(ct);
+
+ if (NS_FAILED(rv)) return nullptr;
+
+ nsCString mimePart = determineMimePart(obj);
+
+ rv = data->mimeDecrypt->SetMimePart(mimePart);
+ if (NS_FAILED(rv)) return nullptr;
+
+ if (mimePart.EqualsLiteral("1.1") && obj->parent &&
+ obj->parent->content_type &&
+ !strcmp(obj->parent->content_type, "multipart/signed") &&
+ ((MimeContainer*)obj->parent)->nchildren == 1) {
+ // Don't show status for the outer signature, it could be misleading,
+ // the signature could have been created by someone not knowing
+ // the contents of the inner encryption layer.
+ // Another reason is, we usually skip decrypting nested encrypted
+ // parts. However, we make an exception: If the outermost layer
+ // is a signature, and the signature wraps only a single encrypted
+ // message (no sibling MIME parts next to the encrypted part),
+ // then we allow decryption. (bug 1594253)
+ data->mimeDecrypt->SetAllowNestedDecrypt(true);
+ }
+
+ mime_stream_data* msd =
+ (mime_stream_data*)(data->self->options->stream_closure);
+ nsIChannel* channel = msd->channel;
+
+ nsCOMPtr<nsIURI> uri;
+ if (channel) channel->GetURI(getter_AddRefs(uri));
+
+ if (!uri && obj && obj->options && obj->options->url) {
+ // Allow the PGP mime decrypt code to know what message we're
+ // working with, necessary for storing into the message DB
+ // (e.g. decrypted subject). Bug 1666005.
+ NS_NewURI(getter_AddRefs(uri), obj->options->url);
+ }
+
+ // Initialise proxy object with MIME's output function, object and URI.
+ if (NS_FAILED(
+ data->mimeDecrypt->SetMimeCallback(output_fn, output_closure, uri)))
+ return nullptr;
+
+ return data;
+}
+
+static int MimePgpe_write(const char* buf, int32_t buf_size,
+ void* output_closure) {
+ MimePgpeData* data = (MimePgpeData*)output_closure;
+
+ if (!data || !data->output_fn) return -1;
+
+ if (!data->mimeDecrypt) return 0;
+
+ return (NS_SUCCEEDED(data->mimeDecrypt->Write(buf, buf_size)) ? 0 : -1);
+}
+
+static int MimePgpe_eof(void* output_closure, bool abort_p) {
+ MimePgpeData* data = (MimePgpeData*)output_closure;
+
+ if (!data || !data->output_fn) return -1;
+
+ if (NS_FAILED(data->mimeDecrypt->Finish())) return -1;
+
+ data->mimeDecrypt->RemoveMimeCallback();
+ data->mimeDecrypt = nullptr;
+ return 0;
+}
+
+static char* MimePgpe_generate(void* output_closure) {
+ const char htmlMsg[] = "<html><body><b>GEN MSG<b></body></html>";
+ char* msg = (char*)PR_MALLOC(strlen(htmlMsg) + 1);
+ if (msg) PL_strcpy(msg, htmlMsg);
+
+ return msg;
+}
+
+static void MimePgpe_free(void* output_closure) {
+ MimePgpeData* data = (MimePgpeData*)output_closure;
+ if (data->mimeDecrypt) {
+ data->mimeDecrypt->RemoveMimeCallback();
+ data->mimeDecrypt = nullptr;
+ }
+}
+
+/* Returns a string describing the location of the part (like "2.5.3").
+ This is not a full URL, just a part-number.
+ */
+static nsCString determineMimePart(MimeObject* obj) {
+ char mimePartNum[20];
+ MimeObject* kid;
+ MimeContainer* cont;
+ int32_t i;
+
+ nsCString mimePart;
+
+ while (obj->parent) {
+ cont = (MimeContainer*)obj->parent;
+ for (i = 0; i < cont->nchildren; i++) {
+ kid = cont->children[i];
+ if (kid == obj) {
+ sprintf(mimePartNum, ".%d", i + 1);
+ mimePart.Insert(mimePartNum, 0);
+ }
+ }
+ obj = obj->parent;
+ }
+
+ // remove leading "."
+ if (mimePart.Length() > 0) mimePart.Cut(0, 1);
+
+ return mimePart;
+}
+
+////////////////////////////////////////////////////////////////////////////
+NS_IMPL_ISUPPORTS(nsPgpMimeProxy, nsIPgpMimeProxy, nsIRequestObserver,
+ nsIStreamListener, nsIRequest, nsIInputStream)
+
+// nsPgpMimeProxy implementation
+nsPgpMimeProxy::nsPgpMimeProxy()
+ : mInitialized(false),
+#ifdef DEBUG
+ mOutputWasRemoved(false),
+#endif
+ mOutputFun(nullptr),
+ mOutputClosure(nullptr),
+ mLoadFlags(LOAD_NORMAL),
+ mCancelStatus(NS_OK),
+ mAllowNestedDecrypt(false) {
+}
+
+nsPgpMimeProxy::~nsPgpMimeProxy() { Finalize(); }
+
+nsresult nsPgpMimeProxy::Finalize() { return NS_OK; }
+
+NS_IMETHODIMP
+nsPgpMimeProxy::SetMimeCallback(MimeDecodeCallbackFun outputFun,
+ void* outputClosure, nsIURI* myUri) {
+ if (!outputFun || !outputClosure) return NS_ERROR_NULL_POINTER;
+
+ mOutputFun = outputFun;
+ mOutputClosure = outputClosure;
+ mInitialized = true;
+ mMessageURI = myUri;
+
+ mStreamOffset = 0;
+ mByteBuf.Truncate();
+
+ if (mDecryptor) return mDecryptor->OnStartRequest((nsIRequest*)this);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::RemoveMimeCallback() {
+ mOutputFun = nullptr;
+ mOutputClosure = nullptr;
+#ifdef DEBUG
+ mOutputWasRemoved = true;
+#endif
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::Init() {
+ mByteBuf.Truncate();
+
+ // Create add-on supplied decryption object.
+ nsresult rv;
+ mDecryptor = do_CreateInstance(PGPMIME_JS_DECRYPTOR_CONTRACTID, &rv);
+ if (NS_FAILED(rv)) mDecryptor = nullptr;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::Write(const char* buf, uint32_t buf_size) {
+ NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
+
+ mByteBuf.Assign(buf, buf_size);
+ mStreamOffset = 0;
+
+ // Pass data to the decryption object for decryption.
+ // The result is returned via OutputDecryptedData().
+ if (mDecryptor)
+ return mDecryptor->OnDataAvailable((nsIRequest*)this, (nsIInputStream*)this,
+ 0, buf_size);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::Finish() {
+ NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
+
+ if (mDecryptor) {
+ return mDecryptor->OnStopRequest((nsIRequest*)this, NS_OK);
+ } else {
+ if (!mOutputFun) return NS_ERROR_FAILURE;
+
+ nsCString temp;
+ temp.AppendLiteral(
+ "Content-Type: text/html; Charset=utf-8\r\n\r\n<html><body>");
+ temp.AppendLiteral(
+ "<BR><text=\"#000000\" bgcolor=\"#FFFFFF\" link=\"#FF0000\" "
+ "vlink=\"#800080\" alink=\"#0000FF\">");
+ temp.AppendLiteral("<center><table BORDER=1 ><tr><td><CENTER>");
+
+ nsCString tString;
+ PgpMimeGetNeedsAddonString(tString);
+ temp.Append(tString);
+ temp.AppendLiteral(
+ "</CENTER></td></tr></table></center><BR></body></html>\r\n");
+
+ PR_SetError(0, 0);
+ int status = mOutputFun(temp.get(), temp.Length(), mOutputClosure);
+ if (status < 0) {
+ PR_SetError(status, 0);
+ mOutputFun = nullptr;
+ return NS_ERROR_FAILURE;
+ }
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::GetDecryptor(nsIStreamListener** aDecryptor) {
+ NS_IF_ADDREF(*aDecryptor = mDecryptor);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::SetDecryptor(nsIStreamListener* aDecryptor) {
+ mDecryptor = aDecryptor;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::GetContentType(nsACString& aContentType) {
+ aContentType = mContentType;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::SetContentType(const nsACString& aContentType) {
+ mContentType = aContentType;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::GetMessageURI(nsIURI** aMessageURI) {
+ NS_IF_ADDREF(*aMessageURI = mMessageURI);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::GetMimePart(nsACString& aMimePart) {
+ aMimePart = mMimePart;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::SetMimePart(const nsACString& aMimePart) {
+ mMimePart = aMimePart;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::SetAllowNestedDecrypt(bool aAllowNestedDecrypt) {
+ mAllowNestedDecrypt = aAllowNestedDecrypt;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::GetAllowNestedDecrypt(bool* aAllowNestedDecrypt) {
+ *aAllowNestedDecrypt = mAllowNestedDecrypt;
+ return NS_OK;
+}
+
+/**
+ * This method is called by the add-on-supplied decryption object.
+ * It passes the decrypted data back to the proxy which calls the
+ * output function is was initialised with.
+ */
+NS_IMETHODIMP
+nsPgpMimeProxy::OutputDecryptedData(const char* buf, uint32_t buf_size) {
+ NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
+
+ NS_ENSURE_ARG(buf);
+
+#ifdef DEBUG
+ // If this assertion is hit, there might be a bug related to object
+ // lifetime, e.g. a JS MIME handler might live longer than the
+ // corresponding MIME data, e.g. bug 1665475.
+ NS_ASSERTION(!mOutputWasRemoved, "MIME data already destroyed");
+#endif
+
+ if (!mOutputFun) return NS_ERROR_FAILURE;
+
+ int status = mOutputFun(buf, buf_size, mOutputClosure);
+ if (status < 0) {
+ PR_SetError(status, 0);
+ mOutputFun = nullptr;
+ return NS_ERROR_FAILURE;
+ }
+
+ return NS_OK;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// nsIRequest methods
+///////////////////////////////////////////////////////////////////////////////
+
+NS_IMETHODIMP
+nsPgpMimeProxy::GetName(nsACString& result) {
+ result = "pgpmimeproxy";
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::IsPending(bool* result) {
+ NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
+
+ *result = NS_SUCCEEDED(mCancelStatus);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::GetStatus(nsresult* status) {
+ NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
+
+ *status = mCancelStatus;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPgpMimeProxy::SetCanceledReason(const nsACString& aReason) {
+ return SetCanceledReasonImpl(aReason);
+}
+
+NS_IMETHODIMP nsPgpMimeProxy::GetCanceledReason(nsACString& aReason) {
+ return GetCanceledReasonImpl(aReason);
+}
+
+NS_IMETHODIMP nsPgpMimeProxy::CancelWithReason(nsresult aStatus,
+ const nsACString& aReason) {
+ return CancelWithReasonImpl(aStatus, aReason);
+}
+
+// NOTE: We assume that OnStopRequest should not be called if
+// request is canceled. This may be wrong!
+NS_IMETHODIMP
+nsPgpMimeProxy::Cancel(nsresult status) {
+ NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
+
+ // Need a non-zero status code to cancel
+ if (NS_SUCCEEDED(status)) return NS_ERROR_FAILURE;
+
+ if (NS_SUCCEEDED(mCancelStatus)) mCancelStatus = status;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::Suspend(void) { return NS_ERROR_NOT_IMPLEMENTED; }
+
+NS_IMETHODIMP
+nsPgpMimeProxy::Resume(void) { return NS_ERROR_NOT_IMPLEMENTED; }
+
+NS_IMETHODIMP
+nsPgpMimeProxy::GetLoadGroup(nsILoadGroup** aLoadGroup) {
+ NS_IF_ADDREF(*aLoadGroup = mLoadGroup);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::SetLoadGroup(nsILoadGroup* aLoadGroup) {
+ mLoadGroup = aLoadGroup;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::GetTRRMode(nsIRequest::TRRMode* aTRRMode) {
+ return GetTRRModeImpl(aTRRMode);
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::SetTRRMode(nsIRequest::TRRMode aTRRMode) {
+ return SetTRRModeImpl(aTRRMode);
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::GetLoadFlags(nsLoadFlags* aLoadFlags) {
+ *aLoadFlags = mLoadFlags;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::SetLoadFlags(nsLoadFlags aLoadFlags) {
+ mLoadFlags = aLoadFlags;
+ return NS_OK;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// nsIInputStream methods
+///////////////////////////////////////////////////////////////////////////////
+
+NS_IMETHODIMP
+nsPgpMimeProxy::Available(uint64_t* _retval) {
+ NS_ENSURE_ARG(_retval);
+
+ NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
+
+ *_retval = (mByteBuf.Length() > mStreamOffset)
+ ? mByteBuf.Length() - mStreamOffset
+ : 0;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::Read(char* buf, uint32_t count, uint32_t* readCount) {
+ NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
+
+ if (!buf || !readCount) return NS_ERROR_NULL_POINTER;
+
+ int32_t avail = (mByteBuf.Length() > mStreamOffset)
+ ? mByteBuf.Length() - mStreamOffset
+ : 0;
+
+ uint32_t readyCount = ((uint32_t)avail > count) ? count : avail;
+
+ if (readyCount) {
+ memcpy(buf, mByteBuf.get() + mStreamOffset, readyCount);
+ *readCount = readyCount;
+ }
+
+ mStreamOffset += *readCount;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::ReadSegments(nsWriteSegmentFun writer, void* aClosure,
+ uint32_t count, uint32_t* readCount) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::IsNonBlocking(bool* aNonBlocking) {
+ NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
+
+ *aNonBlocking = true;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::Close() {
+ NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
+
+ mStreamOffset = 0;
+ mByteBuf.Truncate();
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPgpMimeProxy::StreamStatus() { return NS_OK; }
+
+///////////////////////////////////////////////////////////////////////////////
+// nsIStreamListener methods
+///////////////////////////////////////////////////////////////////////////////
+
+NS_IMETHODIMP
+nsPgpMimeProxy::OnStartRequest(nsIRequest* aRequest) { return NS_OK; }
+
+NS_IMETHODIMP
+nsPgpMimeProxy::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
+ return NS_OK;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// nsIStreamListener method
+///////////////////////////////////////////////////////////////////////////////
+
+NS_IMETHODIMP
+nsPgpMimeProxy::OnDataAvailable(nsIRequest* aRequest,
+ nsIInputStream* aInputStream,
+ uint64_t aSourceOffset, uint32_t aLength) {
+ NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
+ NS_ENSURE_ARG(aInputStream);
+
+ if (!mOutputFun) return NS_ERROR_FAILURE;
+
+ char buf[kCharMax];
+ uint32_t readCount, readMax;
+
+ while (aLength > 0) {
+ readMax = (aLength < kCharMax) ? aLength : kCharMax;
+
+ nsresult rv;
+ rv = aInputStream->Read((char*)buf, readMax, &readCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ int status = mOutputFun(buf, readCount, mOutputClosure);
+ if (status < 0) {
+ PR_SetError(status, 0);
+ mOutputFun = nullptr;
+ return NS_ERROR_FAILURE;
+ }
+
+ aLength -= readCount;
+ }
+
+ return NS_OK;
+}
diff --git a/comm/mailnews/mime/cthandlers/pgpmime/nsPgpMimeProxy.h b/comm/mailnews/mime/cthandlers/pgpmime/nsPgpMimeProxy.h
new file mode 100644
index 0000000000..e115be2ddd
--- /dev/null
+++ b/comm/mailnews/mime/cthandlers/pgpmime/nsPgpMimeProxy.h
@@ -0,0 +1,73 @@
+/* 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/. */
+
+#ifndef _nsPgpmimeDecrypt_h_
+#define _nsPgpmimeDecrypt_h_
+
+#include "mimecth.h"
+#include "nsIPgpMimeProxy.h"
+#include "nsCOMPtr.h"
+#include "nsIStreamListener.h"
+#include "nsIInputStream.h"
+#include "nsILoadGroup.h"
+
+#define PGPMIME_JS_DECRYPTOR_CONTRACTID \
+ "@mozilla.org/mime/pgp-mime-js-decrypt;1"
+
+typedef struct MimeEncryptedPgpClass MimeEncryptedPgpClass;
+typedef struct MimeEncryptedPgp MimeEncryptedPgp;
+
+struct MimeEncryptedPgpClass {
+ MimeEncryptedClass encrypted;
+};
+
+struct MimeEncryptedPgp {
+ MimeEncrypted encrypted;
+};
+
+class nsPgpMimeProxy : public nsIPgpMimeProxy,
+ public nsIRequest,
+ public nsIInputStream {
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIPGPMIMEPROXY
+ NS_DECL_NSIREQUESTOBSERVER
+ NS_DECL_NSISTREAMLISTENER
+ NS_DECL_NSIREQUEST
+ NS_DECL_NSIINPUTSTREAM
+
+ nsPgpMimeProxy();
+
+ // Define a Create method to be used with a factory:
+ static nsresult Create(nsISupports* aOuter, REFNSIID aIID, void** aResult);
+
+ protected:
+ virtual ~nsPgpMimeProxy();
+ bool mInitialized;
+ nsCOMPtr<nsIStreamListener> mDecryptor;
+
+#ifdef DEBUG
+ PRBool mOutputWasRemoved;
+#endif
+ MimeDecodeCallbackFun mOutputFun;
+ void* mOutputClosure;
+
+ nsCOMPtr<nsILoadGroup> mLoadGroup;
+ nsLoadFlags mLoadFlags;
+ nsresult mCancelStatus;
+
+ uint32_t mStreamOffset;
+ nsCString mByteBuf;
+ nsCString mContentType;
+ nsCString mMimePart;
+ bool mAllowNestedDecrypt;
+
+ nsCOMPtr<nsIURI> mMessageURI;
+ nsresult Finalize();
+};
+
+#define MimeEncryptedPgpClassInitializer(ITYPE, CSUPER) \
+ { MimeEncryptedClassInitializer(ITYPE, CSUPER) }
+
+#endif