--- a/mail/app/profile/all-thunderbird.js
+++ b/mail/app/profile/all-thunderbird.js
@@ -757,8 +757,11 @@ pref("mail.chat.enabled", true);
pref("mail.chat.play_notification_sound", true);
// Send typing notification in private conversations
pref("purple.conversations.im.send_typing", true);
// BigFiles
pref("mail.cloud_files.enabled", true);
pref("mail.cloud_files.inserted_urls.footer.link", "http://www.getthunderbird.com");
pref("mail.cloud_files.learn_more_url", "https://support.mozillamessaging.com/kb/filelink-large-attachments");
+
+// PgpMime Proxy
+pref("mail.pgpmime.addon_url", "https://addons.mozilla.org/thunderbird/addon/enigmail/");
new file mode 100644
--- /dev/null
+++ b/mail/locales/en-US/chrome/messenger/pgpmime.properties
@@ -0,0 +1,12 @@
+# 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/.
+
+#
+# The following are used by the pgpmime content type handler
+#
+
+# LOCALIZATION NOTE(pgpMimeNeedsAddon): The text can contain HTML tags.
+# %S is the url to Enigmail on AMO supplied from preferences.
+pgpMimeNeedsAddon=This is an encrypted OpenPGP message.<br>In order to decrypt this mail, you need to install an <a href="%S">OpenPGP add-on</a>.
+
--- a/mail/locales/jar.mn
+++ b/mail/locales/jar.mn
@@ -77,16 +77,17 @@
locale/@AB_CD@/messenger/searchTermOverlay.dtd (%chrome/messenger/searchTermOverlay.dtd)
locale/@AB_CD@/messenger/imapMsgs.properties (%chrome/messenger/imapMsgs.properties)
locale/@AB_CD@/messenger/localMsgs.properties (%chrome/messenger/localMsgs.properties)
locale/@AB_CD@/messenger/downloadheaders.dtd (%chrome/messenger/downloadheaders.dtd)
locale/@AB_CD@/messenger/news.properties (%chrome/messenger/news.properties)
locale/@AB_CD@/messenger/mime.properties (%chrome/messenger/mime.properties)
locale/@AB_CD@/messenger/mimeheader.properties (%chrome/messenger/mimeheader.properties)
locale/@AB_CD@/messenger/smime.properties (%chrome/messenger/smime.properties)
+ locale/@AB_CD@/messenger/pgpmime.properties (%chrome/messenger/pgpmime.properties)
locale/@AB_CD@/messenger/markByDate.dtd (%chrome/messenger/markByDate.dtd)
locale/@AB_CD@/messenger/am-mdn.dtd (%chrome/messenger/am-mdn.dtd)
locale/@AB_CD@/messenger/am-mdn.properties (%chrome/messenger/am-mdn.properties)
locale/@AB_CD@/messenger/am-archiveoptions.dtd (%chrome/messenger/am-archiveoptions.dtd)
locale/@AB_CD@/messenger/msgmdn.properties (%chrome/messenger/msgmdn.properties)
locale/@AB_CD@/messenger/mailviews.properties (%chrome/messenger/mailviews.properties)
locale/@AB_CD@/messenger/msgViewPickerOverlay.dtd (%chrome/messenger/msgViewPickerOverlay.dtd)
locale/@AB_CD@/messenger/mailViewSetup.dtd (%chrome/messenger/mailViewSetup.dtd)
--- a/mailnews/build/Makefile.in
+++ b/mailnews/build/Makefile.in
@@ -51,16 +51,17 @@ SHARED_LIBRARY_LIBS = \
../mime/src/$(LIB_PREFIX)mime_s.$(LIB_SUFFIX) \
../mime/emitters/src/$(LIB_PREFIX)emitterutil_s.$(LIB_SUFFIX) \
../extensions/bayesian-spam-filter/src/$(LIB_PREFIX)bayesflt_s.$(LIB_SUFFIX) \
../extensions/fts3/src/$(LIB_PREFIX)fts3tok_s.$(LIB_SUFFIX) \
../extensions/mailviews/src/$(LIB_PREFIX)mailview_s.$(LIB_SUFFIX) \
../extensions/mdn/src/$(LIB_PREFIX)msgmdn_s.$(LIB_SUFFIX) \
../mime/cthandlers/vcard/$(LIB_PREFIX)vcard_s.$(LIB_SUFFIX) \
../mime/cthandlers/glue/$(LIB_PREFIX)mimecthglue_s.$(LIB_SUFFIX) \
+ ../mime/cthandlers/pgpmime/$(LIB_PREFIX)pgpmime_s.$(LIB_SUFFIX) \
$(NULL)
ifdef MOZILLA_INTERNAL_API
EXTRA_DSO_LDOPTS = \
$(MOZDEPTH)/rdf/util/src/internal/$(LIB_PREFIX)rdfutil_s.$(LIB_SUFFIX) \
$(MOZ_JS_LIBS) \
$(MOZ_UNICHARUTIL_LIBS) \
$(MOZ_COMPONENT_LIBS) \
--- a/mailnews/build/nsMailModule.cpp
+++ b/mailnews/build/nsMailModule.cpp
@@ -291,16 +291,21 @@
///////////////////////////////////////////////////////////////////////////////
// FTS3 Tokenizer
///////////////////////////////////////////////////////////////////////////////
#include "nsFts3TokenizerCID.h"
#include "nsFts3Tokenizer.h"
////////////////////////////////////////////////////////////////////////////////
+// PGP/MIME includes
+////////////////////////////////////////////////////////////////////////////////
+#include "nsPgpMimeProxy.h"
+
+////////////////////////////////////////////////////////////////////////////////
// mailnews base factories
////////////////////////////////////////////////////////////////////////////////
using namespace mozilla::mailnews;
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMessengerBootstrap)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsMsgMailSession, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMessenger)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsMsgAccountManager, Init)
@@ -767,16 +772,48 @@ static nsresult nsVCardMimeContentTypeHa
NS_ADDREF(inst);
rv = inst->QueryInterface(aIID,aResult);
NS_RELEASE(inst);
return rv;
}
+////////////////////////////////////////////////////////////////////////////////
+// PGP/MIME factories
+////////////////////////////////////////////////////////////////////////////////
+
+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPgpMimeProxy, Init)
+
+NS_DEFINE_NAMED_CID(NS_PGPMIMEPROXY_CID);
+
+NS_DEFINE_NAMED_CID(NS_PGPMIME_CONTENT_TYPE_HANDLER_CID);
+
+extern "C" MimeObjectClass *
+MIME_PgpMimeCreateContentTypeHandlerClass(const char *content_type,
+ contentTypeHandlerInitStruct *initStruct);
+
+static nsresult
+nsPgpMimeMimeContentTypeHandlerConstructor(nsISupports *aOuter,
+ REFNSIID aIID,
+ void **aResult)
+{
+ NS_ENSURE_ARG_POINTER(aResult);
+ NS_ENSURE_FALSE(aOuter, NS_ERROR_NO_AGGREGATION);
+ *aResult = nsnull;
+
+ nsRefPtr<nsMimeContentTypeHandler> inst(
+ new nsMimeContentTypeHandler("mulitpart/encrypted",
+ &MIME_PgpMimeCreateContentTypeHandlerClass));
+
+ NS_ENSURE_TRUE(inst, NS_ERROR_OUT_OF_MEMORY);
+
+ return inst->QueryInterface(aIID, aResult);
+}
+
const mozilla::Module::CIDEntry kMailNewsCIDs[] = {
// MailNews Base Entries
{ &kNS_MESSENGERBOOTSTRAP_CID, false, NULL, nsMessengerBootstrapConstructor },
{ &kNS_MESSENGERWINDOWSERVICE_CID, false, NULL, nsMessengerBootstrapConstructor},
{ &kNS_MSGMAILSESSION_CID, false, NULL, nsMsgMailSessionConstructor},
{ &kNS_MESSENGER_CID, false, NULL,nsMessengerConstructor},
{ &kNS_MSGACCOUNTMANAGER_CID, false, NULL, nsMsgAccountManagerConstructor},
{ &kNS_MSGACCOUNT_CID, false, NULL, nsMsgAccountConstructor},
@@ -966,16 +1003,19 @@ const mozilla::Module::CIDEntry kMailNew
{ &kNS_NNTPARTICLELIST_CID, false, NULL, nsNNTPArticleListConstructor },
{ &kNS_NEWSDOWNLOADDIALOGARGS_CID, false, NULL, nsNewsDownloadDialogArgsConstructor },
// Mail View Entries
{ &kNS_MSGMAILVIEWLIST_CID, false, NULL, nsMsgMailViewListConstructor },
// mdn Entries
{ &kNS_MSGMDNGENERATOR_CID, false, NULL, nsMsgMdnGeneratorConstructor },
// Vcard Entries
{ &kNS_VCARD_CONTENT_TYPE_HANDLER_CID, false, NULL, nsVCardMimeContentTypeHandlerConstructor},
+ // PGP/MIME Entries
+ { &kNS_PGPMIME_CONTENT_TYPE_HANDLER_CID, false, NULL, nsPgpMimeMimeContentTypeHandlerConstructor },
+ { &kNS_PGPMIMEPROXY_CID, false, NULL, nsPgpMimeProxyConstructor },
// Tokenizer Entries
{ NULL }
};
const mozilla::Module::ContractIDEntry kMailNewsContracts[] = {
// MailNews Base Entries
{ NS_MESSENGERBOOTSTRAP_CONTRACTID, &kNS_MESSENGERBOOTSTRAP_CID },
{ NS_MESSENGERWINDOWSERVICE_CONTRACTID, &kNS_MESSENGERWINDOWSERVICE_CID },
@@ -1196,16 +1236,19 @@ const mozilla::Module::ContractIDEntry k
{ NS_NNTPARTICLELIST_CONTRACTID, &kNS_NNTPARTICLELIST_CID },
{ NS_NEWSDOWNLOADDIALOGARGS_CONTRACTID, &kNS_NEWSDOWNLOADDIALOGARGS_CID },
// Mail View Entries
{ NS_MSGMAILVIEWLIST_CONTRACTID, &kNS_MSGMAILVIEWLIST_CID },
// mdn Entries
{ NS_MSGMDNGENERATOR_CONTRACTID, &kNS_MSGMDNGENERATOR_CID },
// Vcard Entries
{ "@mozilla.org/mimecth;1?type=text/x-vcard", &kNS_VCARD_CONTENT_TYPE_HANDLER_CID },
+ // PGP/MIME Entries
+ { "@mozilla.org/mimecth;1?type=multipart/encrypted", &kNS_PGPMIME_CONTENT_TYPE_HANDLER_CID },
+ { NS_PGPMIMEPROXY_CONTRACTID, &kNS_PGPMIMEPROXY_CID },
// Tokenizer Entries
{ NULL }
};
static const mozilla::Module::CategoryEntry kMailNewsCategories[] = {
// MailNews Base Entries
{ XPCOM_DIRECTORY_PROVIDER_CATEGORY, "mail-directory-provider", NS_MAILDIRPROVIDER_CONTRACTID },
{ "content-policy", NS_MSGCONTENTPOLICY_CONTRACTID, NS_MSGCONTENTPOLICY_CONTRACTID },
--- a/mailnews/mailnews.js
+++ b/mailnews/mailnews.js
@@ -809,8 +809,11 @@ pref("mailnews.import.text.fieldmap", "+
// Section 4.8 "High-Throughput Data Service Class"
pref("mail.pop3.qos", 0);
pref("mail.smtp.qos", 0);
pref("mail.nntp.qos", 0);
// default value for IMAP4
// in a DSCP environment this should be 56 (0x38, or AF13), ibid.
pref("mail.imap.qos", 0);
+
+// PgpMime Addon
+pref("mail.pgpmime.addon_url", "https://addons.mozilla.org/addon/enigmail/");
--- a/mailnews/mime/cthandlers/Makefile.in
+++ b/mailnews/mime/cthandlers/Makefile.in
@@ -11,15 +11,18 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
ifdef MOZ_PSM
BUILD_SMIME=1
endif
PARALLEL_DIRS += glue vcard
+# pgpmime depends on glue
+DIRS += pgpmime
+
ifndef BUILD_SMIME
# smimestub always depends on glue, so always build that afterwards
DIRS += smimestub
endif
include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/mailnews/mime/cthandlers/pgpmime/Makefile.in
@@ -0,0 +1,49 @@
+# 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/.
+
+DEPTH = ../../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = pgpmime
+LIBRARY_NAME = pgpmime_s
+EXPORT_LIBRARY = 1
+IS_COMPONENT = 1
+MODULE_NAME = nsPgpMimeModule
+ifndef MOZ_INCOMPLETE_EXTERNAL_LINKAGE
+MOZILLA_INTERNAL_API = 1
+LIBXUL_LIBRARY = 1
+endif
+
+EXTRA_DSO_LIBS = mimecthglue_s
+
+CPPSRCS = \
+ nsPgpMimeProxy.cpp \
+ $(NULL)
+
+EXPORTS = \
+ nsPgpMimeProxy.h \
+ $(NULL)
+
+ifdef MOZILLA_INTERNAL_API
+EXTRA_DSO_LDOPTS = \
+ $(LIBS_DIR) \
+ $(EXTRA_DSO_LIBS) \
+ $(MOZ_COMPONENT_LIBS) \
+ $(NULL)
+else
+EXTRA_DSO_LDOPTS = \
+ $(LIBS_DIR) \
+ $(EXTRA_DSO_LIBS) \
+ $(XPCOM_GLUE_LDOPTS) \
+ $(NSPR_LIBS) \
+ $(NULL)
+endif
+
+include $(topsrcdir)/config/rules.mk
+
+LOCAL_INCLUDES = -I$(srcdir)/../glue
new file mode 100644
--- /dev/null
+++ b/mailnews/mime/cthandlers/pgpmime/nsPgpMimeProxy.cpp
@@ -0,0 +1,568 @@
+/* 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 "nsNetUtil.h"
+#include "nsIRequest.h"
+#include "nsIStringBundle.h"
+#include "nsIPrefService.h"
+#include "nsIPrefBranch.h"
+#include "mimexpcom.h"
+#include "nsMsgUtils.h"
+
+#include "nsMsgMimeCID.h"
+
+#include "mimecth.h"
+#include "mimemoz2.h"
+#include "nspr.h"
+#include "plstr.h"
+#include "nsIPgpMimeProxy.h"
+
+static NS_DEFINE_CID(kMimeObjectClassAccessCID, NS_MIME_OBJECT_CLASS_ACCESS_CID);
+
+#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 *, PRInt32, void *),
+ void *);
+static int MimePgpe_write (const char *, PRInt32, void *);
+static int MimePgpe_eof (void *, bool);
+static char* MimePgpe_generate (void *);
+static void MimePgpe_free (void *);
+
+#define PGPMIME_PROPERTIES_URL "chrome://messenger/locale/pgpmime.properties"
+#define PGPMIME_STR_NOT_SUPPORTED_ID "pgpMimeNeedsAddon"
+#define PGPMIME_URL_PREF "mail.pgpmime.addon_url"
+
+static void PgpMimeGetNeedsAddonString(nsCString &aResult)
+{
+ aResult.AssignLiteral("???");
+
+ nsCOMPtr<nsIStringBundleService> stringBundleService =
+ mozilla::services::GetStringBundleService();
+
+ 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;
+
+ nsCString url;
+ if (NS_FAILED(prefs->GetCharPref("mail.pgpmime.addon_url",
+ getter_Copies(url))))
+ return;
+
+ NS_ConvertUTF8toUTF16 url16(url);
+ const PRUnichar *formatStrings[] = { url16.get() };
+
+ nsString result;
+ rv = stringBundle->FormatStringFromName(NS_LITERAL_STRING(PGPMIME_STR_NOT_SUPPORTED_ID).get(),
+ formatStrings, 1, getter_Copies(result));
+ if (NS_FAILED(rv))
+ return;
+ aResult = NS_ConvertUTF16toUTF8(result);
+}
+
+static int
+MimeEncryptedPgpClassInitialize(MimeEncryptedPgpClass *clazz)
+{
+ MimeObjectClass *oclass = (MimeObjectClass *) clazz;
+ MimeEncryptedClass *eclass = (MimeEncryptedClass *) clazz;
+
+ NS_ASSERTION(!oclass->class_initialized, "oclass is not initialized");
+ 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, PRInt32 buf_size, void *output_closure);
+ void *output_closure;
+ MimeObject *self;
+
+ nsCOMPtr<nsIPgpMimeProxy> mimeDecrypt;
+
+ MimePgpeData()
+ : output_fn(nsnull),
+ output_closure(nsnull)
+ {
+ }
+
+ virtual ~MimePgpeData()
+ {
+ }
+};
+
+NS_IMPL_ISUPPORTS0(MimePgpeData)
+
+static void*
+MimePgpe_init(MimeObject *obj,
+ int (*output_fn) (const char *buf, PRInt32 buf_size,
+ void *output_closure),
+ void *output_closure)
+{
+ if (!(obj && obj->options && output_fn))
+ return nsnull;
+
+ MimeDisplayOptions *opts;
+ opts = obj->options;
+
+ MimePgpeData* data = new MimePgpeData();
+ NS_ENSURE_TRUE(data, nsnull);
+
+ data->self = obj;
+ data->output_fn = output_fn;
+ data->output_closure = output_closure;
+ data->mimeDecrypt = nsnull;
+
+ nsresult rv;
+ data->mimeDecrypt = do_GetService(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 nsnull;
+
+ if (NS_FAILED(data->mimeDecrypt->SetMimeCallback(output_fn, output_closure)))
+ return nsnull;
+
+ return data;
+}
+
+static int
+MimePgpe_write(const char *buf, PRInt32 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;
+
+ mime_stream_data *msd = (mime_stream_data *) (data->self->options->stream_closure);
+
+ if (NS_FAILED(data->mimeDecrypt->Finish()))
+ return -1;
+
+ data->mimeDecrypt = nsnull;
+ 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)
+{
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+NS_IMPL_THREADSAFE_ISUPPORTS5(nsPgpMimeProxy,
+ nsIPgpMimeProxy,
+ nsIRequestObserver,
+ nsIStreamListener,
+ nsIRequest,
+ nsIInputStream)
+
+// nsPgpMimeProxy implementation
+nsPgpMimeProxy::nsPgpMimeProxy()
+ : mInitialized(false),
+ mDecryptor(nsnull),
+ mLoadGroup(nsnull),
+ mLoadFlags(LOAD_NORMAL),
+ mCancelStatus(NS_OK)
+{
+ NS_INIT_ISUPPORTS();
+}
+
+nsPgpMimeProxy::~nsPgpMimeProxy()
+{
+ Finalize();
+}
+
+nsresult
+nsPgpMimeProxy::Finalize()
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::SetMimeCallback(MimeDecodeCallbackFun outputFun,
+ void* outputClosure)
+{
+ if (!outputFun || !outputClosure)
+ return NS_ERROR_NULL_POINTER;
+
+ mOutputFun = outputFun;
+ mOutputClosure = outputClosure;
+ mInitialized = true;
+
+ mStreamOffset = 0;
+ mByteBuf.Truncate();
+
+ if (mDecryptor)
+ return mDecryptor->OnStartRequest((nsIRequest*) this, nsnull);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::Init()
+{
+ mByteBuf.Truncate();
+
+ nsresult rv;
+ nsCOMPtr<nsIPrefBranch> pbi(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
+ if (NS_FAILED(rv))
+ return rv;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::Write(const char *buf, PRUint32 buf_size)
+{
+ NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
+
+ mByteBuf.Assign(buf, buf_size);
+ mStreamOffset = 0;
+
+ if (mDecryptor)
+ return mDecryptor->OnDataAvailable((nsIRequest*) this, nsnull, (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, nsnull, NS_OK);
+ }
+ else {
+ nsCString temp;
+ temp.Append("Content-Type: text/html\r\nCharset: UTF-8\r\n\r\n<html><body>");
+ temp.Append("<BR><text=\"#000000\" bgcolor=\"#FFFFFF\" link=\"#FF0000\" vlink=\"#800080\" alink=\"#0000FF\">");
+ temp.Append("<center><table BORDER=1 ><tr><td><CENTER>");
+
+ nsCString tString;
+ PgpMimeGetNeedsAddonString(tString);
+ temp.Append(tString);
+ temp.Append("</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 = nsnull;
+ 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;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// 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 = (mCancelStatus == NS_OK);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::GetStatus(nsresult *status)
+{
+ NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
+
+ *status = mCancelStatus;
+ return NS_OK;
+}
+
+// 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 (status == NS_OK)
+ return NS_ERROR_FAILURE;
+
+ if (mCancelStatus == NS_OK)
+ 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::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(PRUint32* _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, PRUint32 count,
+ PRUint32 *readCount)
+{
+ NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
+
+ if (!buf || !readCount)
+ return NS_ERROR_NULL_POINTER;
+
+ PRInt32 avail = (mByteBuf.Length() > mStreamOffset) ?
+ mByteBuf.Length() - mStreamOffset : 0;
+
+ PRUint32 readyCount = ((PRUint32) 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, PRUint32 count,
+ PRUint32 *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;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// nsIStreamListener methods
+///////////////////////////////////////////////////////////////////////////////
+
+NS_IMETHODIMP
+nsPgpMimeProxy::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPgpMimeProxy::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
+ nsresult aStatus)
+{
+ return NS_OK;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// nsIStreamListener method
+///////////////////////////////////////////////////////////////////////////////
+
+NS_IMETHODIMP
+nsPgpMimeProxy::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
+ nsIInputStream *aInputStream,
+ PRUint32 aSourceOffset,
+ PRUint32 aLength)
+{
+ NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
+
+ NS_ENSURE_ARG(aInputStream);
+ NS_ENSURE_ARG_MIN(aLength, 0);
+
+ char buf[kCharMax];
+ PRUint32 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 = nsnull;
+ return NS_ERROR_FAILURE;
+ }
+
+ aLength -= readCount;
+ }
+
+ return NS_OK;
+}
new file mode 100644
--- /dev/null
+++ b/mailnews/mime/cthandlers/pgpmime/nsPgpMimeProxy.h
@@ -0,0 +1,65 @@
+/* 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"
+
+typedef struct MimeEncryptedPgpClass MimeEncryptedPgpClass;
+typedef struct MimeEncryptedPgp MimeEncryptedPgp;
+
+struct MimeEncryptedPgpClass {
+ MimeEncryptedClass encrypted;
+};
+
+//extern MimeEncryptedPgpClass mimeEncryptedPgpClass;
+
+struct MimeEncryptedPgp {
+ MimeEncrypted encrypted;
+};
+
+class nsPgpMimeProxy : public nsIPgpMimeProxy,
+ public nsIRequest,
+ public nsIInputStream
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIPGPMIMEPROXY
+ NS_DECL_NSIREQUESTOBSERVER
+ NS_DECL_NSISTREAMLISTENER
+ NS_DECL_NSIREQUEST
+ NS_DECL_NSIINPUTSTREAM
+
+ nsPgpMimeProxy();
+ virtual ~nsPgpMimeProxy();
+
+ // Define a Create method to be used with a factory:
+ static NS_METHOD
+ Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+
+protected:
+ bool mInitialized;
+ nsCOMPtr<nsIStreamListener> mDecryptor;
+
+ MimeDecodeCallbackFun mOutputFun;
+ void* mOutputClosure;
+
+ nsCOMPtr<nsILoadGroup> mLoadGroup;
+ nsLoadFlags mLoadFlags;
+ nsresult mCancelStatus;
+
+ PRUint32 mStreamOffset;
+ nsCString mByteBuf;
+ nsCString mContentType;
+
+ nsresult Finalize();
+};
+
+#endif
--- a/mailnews/mime/public/Makefile.in
+++ b/mailnews/mime/public/Makefile.in
@@ -22,12 +22,13 @@ EXPORTS = \
XPIDLSRCS = \
nsIMimeStreamConverter.idl \
nsIMimeEmitter.idl \
nsIMsgHeaderParser.idl \
nsIMimeMiscStatus.idl \
nsIMimeHeaders.idl \
nsIMimeConverter.idl \
nsISimpleMimeConverter.idl \
+ nsIPgpMimeProxy.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk
--- a/mailnews/mime/public/nsIMimeContentTypeHandler.h
+++ b/mailnews/mime/public/nsIMimeContentTypeHandler.h
@@ -1,23 +1,23 @@
/* -*- 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
+ *
+ * libmime will then use the XPCOM Component Manager to
* locate the appropriate Content Type handler
*/
#ifndef nsIMimeContentTypeHandler_h_
#define nsIMimeContentTypeHandler_h_
typedef struct {
bool force_inline_display;
} contentTypeHandlerInitStruct;
@@ -39,23 +39,28 @@ typedef struct {
#define NS_SMIME_CONTENT_TYPE_HANDLER_CID \
{ 0x20dabdac, 0xf8b5, 0x11d2, \
{ 0xFF, 0xe0, 0x0, 0xa0, 0x24, 0xa7, 0xd1, 0x44 } }
#define NS_SIGNED_CONTENT_TYPE_HANDLER_CID \
{ 0x20dabdac, 0xf8b5, 0x11d2, \
{ 0xFF, 0xe0, 0x0, 0xaf, 0x19, 0xa7, 0xd1, 0x44 } }
+#define NS_PGPMIME_CONTENT_TYPE_HANDLER_CID \
+ { 0x212f415f, 0xf8b5, 0x11d2, \
+ { 0xFF, 0xe0, 0x0, 0xaf, 0x19, 0xa7, 0xd1, 0x44 } }
+
+
class nsIMimeContentTypeHandler : public nsISupports {
-public:
+public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMIME_CONTENT_TYPE_HANDLER_IID)
NS_IMETHOD GetContentType(char **contentType) = 0;
- NS_IMETHOD CreateContentTypeHandlerClass(const char *content_type,
- contentTypeHandlerInitStruct *initStruct,
+ NS_IMETHOD CreateContentTypeHandlerClass(const char *content_type,
+ contentTypeHandlerInitStruct *initStruct,
MimeObjectClass **objClass) = 0;
-};
+};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIMimeContentTypeHandler,
NS_IMIME_CONTENT_TYPE_HANDLER_IID)
#endif /* nsIMimeContentTypeHandler_h_ */
new file mode 100644
--- /dev/null
+++ b/mailnews/mime/public/nsIPgpMimeProxy.idl
@@ -0,0 +1,59 @@
+/* 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 "nsIStreamListener.idl"
+
+%{C++
+typedef int (*MimeDecodeCallbackFun)(const char *buf, PRInt32 buf_size, void *output_closure);
+
+#define NS_PGPMIMEPROXY_CLASSNAME "PGP/Mime Decryption"
+#define NS_PGPMIMEPROXY_CONTRACTID "@mozilla.org/mime/pgp-mime-decrypt;1"
+
+#define NS_PGPMIMEPROXY_CID \
+{ /* c200d239-6dad-434f-a614-1b58a58c61ec */ \
+ 0xc200d239, 0x6dad, 0x434f, \
+{0xa6, 0x14, 0x1b, 0x58, 0xa5, 0x8c, 0x61, 0xec } }
+%}
+
+native MimeDecodeCallbackFun(MimeDecodeCallbackFun);
+
+/**
+ * nsIPgpMimeProxy is a proxy for a (JS-)addon for OpenPGP/MIME decryption
+ */
+
+[scriptable, uuid(c200d239-6dad-434f-a614-1b58a58c61ec)]
+interface nsIPgpMimeProxy : nsIStreamListener
+{
+ /**
+ * set the decoder callback into mimelib
+ */
+ [noscript] void setMimeCallback(in MimeDecodeCallbackFun outputFun,
+ in voidPtr outputClosure);
+
+ /**
+ * init function
+ */
+ void init();
+
+ /**
+ * process encoded data received from mimelib
+ */
+ void write(in string buf, in unsigned long count);
+
+ /**
+ * finish writing (EOF) from mimelib
+ */
+ void finish();
+
+ /**
+ * the listener that receives the OpenPGP/MIME data stream and decrypts
+ * the message
+ */
+ attribute nsIStreamListener decryptor;
+
+ attribute ACString contentType;
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
new file mode 100644
--- /dev/null
+++ b/suite/locales/en-US/chrome/mailnews/pgpmime.properties
@@ -0,0 +1,13 @@
+# 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/.
+
+#
+# The following are used by the pgpmime content type handler
+#
+
+# LOCALIZATION NOTE(pgpMimeNeedsAddon): The text can contain HTML tags.
+# %S is the url to Enigmail on AMO supplied from preferences.
+pgpMimeNeedsAddon=This is an encrypted OpenPGP message.<br>In order to decrypt this mail, you need to install an <a href="%S">OpenPGP add-on</a>.
+
+
--- a/suite/locales/jar.mn
+++ b/suite/locales/jar.mn
@@ -310,16 +310,17 @@
locale/@AB_CD@/messenger/renameFolderDialog.dtd (%chrome/mailnews/renameFolderDialog.dtd)
locale/@AB_CD@/messenger/search.properties (%chrome/mailnews/search.properties)
locale/@AB_CD@/messenger/SearchDialog.dtd (%chrome/mailnews/SearchDialog.dtd)
locale/@AB_CD@/messenger/searchTermOverlay.dtd (%chrome/mailnews/searchTermOverlay.dtd)
locale/@AB_CD@/messenger/search-attributes.properties (%chrome/mailnews/search-attributes.properties)
locale/@AB_CD@/messenger/search-operators.properties (%chrome/mailnews/search-operators.properties)
locale/@AB_CD@/messenger/shutdownWindow.properties (%chrome/mailnews/shutdownWindow.properties)
locale/@AB_CD@/messenger/smime.properties (%chrome/mailnews/smime.properties)
+ locale/@AB_CD@/messenger/pgpmime.properties (%chrome/mailnews/pgpmime.properties)
locale/@AB_CD@/messenger/smtpEditOverlay.dtd (%chrome/mailnews/pref/smtpEditOverlay.dtd)
locale/@AB_CD@/messenger/start.dtd (%chrome/mailnews/start.dtd)
locale/@AB_CD@/messenger/subscribe.dtd (%chrome/mailnews/subscribe.dtd)
locale/@AB_CD@/messenger/subscribe.properties (%chrome/mailnews/subscribe.properties)
locale/@AB_CD@/messenger/textImportMsgs.properties (%chrome/mailnews/textImportMsgs.properties)
locale/@AB_CD@/messenger/threadpane.dtd (%chrome/mailnews/threadpane.dtd)
locale/@AB_CD@/messenger/vCardImportMsgs.properties (%chrome/mailnews/vCardImportMsgs.properties)
locale/@AB_CD@/messenger/viewLog.dtd (%chrome/mailnews/viewLog.dtd)