** See bug #53558 (plus other fixes/cleanups)
2004-01-30 Not Zed <NotZed@Ximian.com> ** See bug #53558 (plus other fixes/cleanups) * em-format.c (emf_format_secure): default implementation, handle output of inner part, but dont output any sign/encrypt info. (emf_multipart_signed, emf_multipart_encrypted): replaced with implementations from em-format-html.c, which now call em_format_format_secure to output guts. (emf_class_init): hook-up virtual method format_secure. * em-format.[ch]: add a virtual method for outputing secured parts. Moved all validity stuff from em-format-html.[ch] to here. * mail-component.c (impl_createControls): set the session interactive too. * em-format-html-display.c: make smime stuff dependent on HAVE_NSS. (efhd_multipart_signed, efhd_application_xpkcs7mime): removed, now handled by root class. (efhd_output_secure): renamed to efhd_format_secure, and use EMFormat::format_secure to kick off. (efhd_class_init): setup format_secure virtual method. * em-format-html.c (efh_multipart_encrypted): We need to handle this here so we can properly keep track of the ciphervalidity stuff. Also do it directly using the context, not multipartencrypted part. (efh_multipart_signed): with unsupported signature format, format as multipart/mixed, not as an attachment. (efh_multipart_signed): make the smime stuff optional. (efh_multipart_signed, efh_multipart_encrypted): Moved to em-format.c. (efh_application_xpkcs7mime): moved to em-format.c (efh_output_secure): renamed to efh_format_secure, linked into virtual method. call parent class to do the validation foo then output the info if needed. (efh_format_message): fixed access to validity stuff to parent object. (efh_class_init): hook up format_secure virtual method. (*): removed some now-unused headers. svn path=/trunk/; revision=24531
This commit is contained in:
@ -1,3 +1,46 @@
|
||||
2004-01-30 Not Zed <NotZed@Ximian.com>
|
||||
|
||||
** See bug #53558 (plus other fixes/cleanups)
|
||||
|
||||
* em-format.c (emf_format_secure): default implementation, handle
|
||||
output of inner part, but dont output any sign/encrypt info.
|
||||
(emf_multipart_signed, emf_multipart_encrypted): replaced with
|
||||
implementations from em-format-html.c, which now call
|
||||
em_format_format_secure to output guts.
|
||||
(emf_class_init): hook-up virtual method format_secure.
|
||||
|
||||
* em-format.[ch]: add a virtual method for outputing secured
|
||||
parts. Moved all validity stuff from em-format-html.[ch] to here.
|
||||
|
||||
* mail-component.c (impl_createControls): set the session
|
||||
interactive too.
|
||||
|
||||
* em-format-html-display.c: make smime stuff dependent on
|
||||
HAVE_NSS.
|
||||
(efhd_multipart_signed, efhd_application_xpkcs7mime): removed, now
|
||||
handled by root class.
|
||||
(efhd_output_secure): renamed to efhd_format_secure, and use
|
||||
EMFormat::format_secure to kick off.
|
||||
(efhd_class_init): setup format_secure virtual method.
|
||||
|
||||
* em-format-html.c (efh_multipart_encrypted): We need to handle
|
||||
this here so we can properly keep track of the ciphervalidity
|
||||
stuff. Also do it directly using the context, not
|
||||
multipartencrypted part.
|
||||
(efh_multipart_signed): with unsupported signature format, format
|
||||
as multipart/mixed, not as an attachment.
|
||||
(efh_multipart_signed): make the smime stuff optional.
|
||||
(efh_multipart_signed, efh_multipart_encrypted): Moved to
|
||||
em-format.c.
|
||||
(efh_application_xpkcs7mime): moved to em-format.c
|
||||
(efh_output_secure): renamed to efh_format_secure, linked into
|
||||
virtual method. call parent class to do the validation foo then
|
||||
output the info if needed.
|
||||
(efh_format_message): fixed access to validity stuff to parent
|
||||
object.
|
||||
(efh_class_init): hook up format_secure virtual method.
|
||||
(*): removed some now-unused headers.
|
||||
|
||||
2004-01-29 Nicel KM <mnicel@novell.com>
|
||||
|
||||
* mail-component.c: removed CAMEL_PROVIDER_IS_EXTERNAL check
|
||||
|
||||
@ -64,10 +64,9 @@
|
||||
#include <camel/camel-mime-filter-tohtml.h>
|
||||
#include <camel/camel-mime-part.h>
|
||||
#include <camel/camel-multipart.h>
|
||||
#include <camel/camel-multipart-signed.h>
|
||||
#include <camel/camel-internet-address.h>
|
||||
#include <camel/camel-mime-message.h>
|
||||
#include <camel/camel-gpg-context.h>
|
||||
#include <camel/camel-cipher-context.h>
|
||||
|
||||
/* should this be in e-util rather than gal? */
|
||||
#include <gal/util/e-util.h>
|
||||
@ -76,8 +75,7 @@
|
||||
#include <e-util/e-gui-utils.h>
|
||||
#include <e-util/e-dialog-utils.h>
|
||||
|
||||
#if defined(HAVE_NSS)
|
||||
#include <camel/camel-smime-context.h>
|
||||
#ifdef HAVE_NSS
|
||||
#include "certificate-viewer.h"
|
||||
#include "e-cert-db.h"
|
||||
#endif
|
||||
@ -137,6 +135,7 @@ static void efhd_format_error(EMFormat *emf, CamelStream *stream, const char *tx
|
||||
static void efhd_format_message(EMFormat *, CamelStream *, CamelMedium *);
|
||||
static void efhd_format_source(EMFormat *, CamelStream *, CamelMimePart *);
|
||||
static void efhd_format_attachment(EMFormat *, CamelStream *, CamelMimePart *, const char *, const EMFormatHandler *);
|
||||
static void efhd_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid);
|
||||
static void efhd_complete(EMFormat *);
|
||||
|
||||
static gboolean efhd_bonobo_object(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject);
|
||||
@ -156,6 +155,7 @@ static guint efhd_signals[EFHD_LAST_SIGNAL] = { 0 };
|
||||
/* EMFormatHandler's for bonobo objects */
|
||||
static GHashTable *efhd_bonobo_handlers;
|
||||
static EMFormatHTMLClass *efhd_parent;
|
||||
static EMFormatClass *efhd_format_class;
|
||||
|
||||
static void
|
||||
efhd_gtkhtml_realise(GtkHTML *html, EMFormatHTMLDisplay *efhd)
|
||||
@ -275,6 +275,7 @@ efhd_class_init(GObjectClass *klass)
|
||||
((EMFormatClass *)klass)->format_message = efhd_format_message;
|
||||
((EMFormatClass *)klass)->format_source = efhd_format_source;
|
||||
((EMFormatClass *)klass)->format_attachment = efhd_format_attachment;
|
||||
((EMFormatClass *)klass)->format_secure = efhd_format_secure;
|
||||
((EMFormatClass *)klass)->complete = efhd_complete;
|
||||
|
||||
klass->finalize = efhd_finalise;
|
||||
@ -327,6 +328,7 @@ em_format_html_display_get_type(void)
|
||||
(GInstanceInitFunc)efhd_init
|
||||
};
|
||||
efhd_parent = g_type_class_ref(em_format_html_get_type());
|
||||
efhd_format_class = g_type_class_ref(em_format_get_type());
|
||||
type = g_type_register_static(em_format_html_get_type(), "EMFormatHTMLDisplay", &info, 0);
|
||||
|
||||
efhd_bonobo_handlers = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
@ -675,7 +677,7 @@ efhd_xpkcs7mime_info_response(GtkWidget *w, guint button, struct _smime_pobject
|
||||
po->widget = NULL;
|
||||
}
|
||||
|
||||
#if defined(HAVE_NSS)
|
||||
#ifdef HAVE_NSS
|
||||
static void
|
||||
efhd_xpkcs7mime_viewcert_clicked(GtkWidget *button, struct _smime_pobject *po)
|
||||
{
|
||||
@ -839,29 +841,12 @@ efhd_xpkcs7mime_button(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObje
|
||||
}
|
||||
|
||||
static void
|
||||
efhd_output_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid)
|
||||
efhd_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid)
|
||||
{
|
||||
CamelCipherValidity *save = ((EMFormatHTML *)emf)->valid_parent;
|
||||
int len;
|
||||
/* Note: We call EMFormatClass directly, not EMFormatHTML, our parent */
|
||||
efhd_format_class->format_secure(emf, stream, part, valid);
|
||||
|
||||
/* Note: this same logic is in efh_output_secure */
|
||||
if (((EMFormatHTML *)emf)->valid == NULL) {
|
||||
((EMFormatHTML *)emf)->valid = valid;
|
||||
} else {
|
||||
e_dlist_addtail(&((EMFormatHTML *)emf)->valid_parent->children, (EDListNode *)valid);
|
||||
camel_cipher_validity_envelope(((EMFormatHTML *)emf)->valid_parent, valid);
|
||||
}
|
||||
|
||||
((EMFormatHTML *)emf)->valid_parent = valid;
|
||||
|
||||
len = emf->part_id->len;
|
||||
g_string_append_printf(emf->part_id, ".signed");
|
||||
em_format_part(emf, stream, part);
|
||||
g_string_truncate(emf->part_id, len);
|
||||
|
||||
((EMFormatHTML *)emf)->valid_parent = save;
|
||||
|
||||
if (((EMFormatHTML *)emf)->valid == valid
|
||||
if (emf->valid == valid
|
||||
&& (valid->encrypt.status != CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE
|
||||
|| valid->sign.status != CAMEL_CIPHER_VALIDITY_SIGN_NONE)) {
|
||||
char *classid;
|
||||
@ -888,84 +873,9 @@ efhd_output_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, Came
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
efhd_application_xpkcs7mime(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
|
||||
{
|
||||
CamelCipherContext *context;
|
||||
CamelException *ex;
|
||||
extern CamelSession *session;
|
||||
CamelMimePart *opart;
|
||||
CamelCipherValidity *valid;
|
||||
|
||||
ex = camel_exception_new();
|
||||
|
||||
context = camel_smime_context_new(session);
|
||||
|
||||
opart = camel_mime_part_new();
|
||||
valid = camel_cipher_decrypt(context, part, opart, ex);
|
||||
if (valid == NULL) {
|
||||
em_format_format_error(emf, stream, ex->desc?ex->desc:_("Could not parse S/MIME message: Unknown error"));
|
||||
em_format_part_as(emf, stream, part, NULL);
|
||||
} else {
|
||||
efhd_output_secure(emf, stream, opart, valid);
|
||||
}
|
||||
|
||||
camel_object_unref(opart);
|
||||
camel_object_unref(context);
|
||||
camel_exception_free(ex);
|
||||
}
|
||||
|
||||
/* ********************************************************************** */
|
||||
|
||||
static void
|
||||
efhd_multipart_signed (EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
|
||||
{
|
||||
CamelMultipartSigned *mps;
|
||||
CamelMimePart *cpart;
|
||||
CamelCipherContext *cipher = NULL;
|
||||
|
||||
mps = (CamelMultipartSigned *)camel_medium_get_content_object((CamelMedium *)part);
|
||||
if (!CAMEL_IS_MULTIPART_SIGNED(mps)
|
||||
|| (cpart = camel_multipart_get_part((CamelMultipart *)mps, CAMEL_MULTIPART_SIGNED_CONTENT)) == NULL) {
|
||||
em_format_format_source(emf, stream, part);
|
||||
return;
|
||||
}
|
||||
|
||||
/* FIXME: Should be done via a plugin interface */
|
||||
/* FIXME: duplicated in em-format-html.c */
|
||||
if (g_ascii_strcasecmp("application/x-pkcs7-signature", mps->protocol) == 0
|
||||
|| g_ascii_strcasecmp("application/pkcs7-signature", mps->protocol) == 0)
|
||||
cipher = camel_smime_context_new(emf->session);
|
||||
else if (g_ascii_strcasecmp("application/pgp-signature", mps->protocol) == 0)
|
||||
cipher = camel_gpg_context_new(emf->session);
|
||||
|
||||
if (cipher == NULL) {
|
||||
em_format_format_error(emf, stream, _("Unsupported signature format"));
|
||||
em_format_part_as(emf, stream, part, NULL);
|
||||
} else {
|
||||
CamelException *ex = camel_exception_new();
|
||||
CamelCipherValidity *valid;
|
||||
|
||||
valid = camel_cipher_verify(cipher, part, ex);
|
||||
if (valid == NULL) {
|
||||
em_format_format_error(emf, stream, ex->desc?ex->desc:_("Unknown error verifying signature"));
|
||||
em_format_part_as(emf, stream, part, NULL);
|
||||
} else {
|
||||
efhd_output_secure(emf, stream, cpart, valid);
|
||||
}
|
||||
|
||||
camel_exception_free(ex);
|
||||
camel_object_unref(cipher);
|
||||
}
|
||||
}
|
||||
|
||||
/* ********************************************************************** */
|
||||
|
||||
static EMFormatHandler type_builtin_table[] = {
|
||||
{ "application/x-pkcs7-mime", (EMFormatFunc)efhd_application_xpkcs7mime },
|
||||
{ "application/pkcs7-mime", (EMFormatFunc)efhd_application_xpkcs7mime },
|
||||
|
||||
{ "multipart/signed", (EMFormatFunc)efhd_multipart_signed },
|
||||
};
|
||||
|
||||
static void
|
||||
|
||||
@ -50,10 +50,8 @@
|
||||
#include <camel/camel-mime-filter.h>
|
||||
#include <camel/camel-mime-filter-tohtml.h>
|
||||
#include <camel/camel-mime-filter-enriched.h>
|
||||
#include <camel/camel-cipher-context.h>
|
||||
#include <camel/camel-multipart.h>
|
||||
#include <camel/camel-multipart-signed.h>
|
||||
#include <camel/camel-gpg-context.h>
|
||||
#include <camel/camel-smime-context.h>
|
||||
#include <camel/camel-stream-mem.h>
|
||||
#include <camel/camel-url.h>
|
||||
#include <camel/camel-stream-fs.h>
|
||||
@ -98,6 +96,7 @@ static void efh_format_error(EMFormat *emf, CamelStream *stream, const char *txt
|
||||
static void efh_format_message(EMFormat *, CamelStream *, CamelMedium *);
|
||||
static void efh_format_source(EMFormat *, CamelStream *, CamelMimePart *);
|
||||
static void efh_format_attachment(EMFormat *, CamelStream *, CamelMimePart *, const char *, const EMFormatHandler *);
|
||||
static void efh_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid);
|
||||
static gboolean efh_busy(EMFormat *);
|
||||
|
||||
static void efh_builtin_init(EMFormatHTMLClass *efhc);
|
||||
@ -176,7 +175,6 @@ efh_finalise(GObject *o)
|
||||
/* FIXME: check for leaked stuff */
|
||||
|
||||
em_format_html_clear_pobject(efh);
|
||||
camel_cipher_validity_free(efh->valid);
|
||||
|
||||
efh_gtkhtml_destroy(efh->html, efh);
|
||||
|
||||
@ -202,6 +200,7 @@ efh_class_init(GObjectClass *klass)
|
||||
((EMFormatClass *)klass)->format_message = efh_format_message;
|
||||
((EMFormatClass *)klass)->format_source = efh_format_source;
|
||||
((EMFormatClass *)klass)->format_attachment = efh_format_attachment;
|
||||
((EMFormatClass *)klass)->format_secure = efh_format_secure;
|
||||
((EMFormatClass *)klass)->busy = efh_busy;
|
||||
|
||||
klass->finalize = efh_finalise;
|
||||
@ -578,29 +577,15 @@ static const struct {
|
||||
/* TODO: this could probably be virtual on em-format-html
|
||||
then we only need one version of each type handler */
|
||||
static void
|
||||
efh_output_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid)
|
||||
efh_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid)
|
||||
{
|
||||
CamelCipherValidity *save = ((EMFormatHTML *)emf)->valid_parent;
|
||||
int len;
|
||||
efh_parent->format_secure(emf, stream, part, valid);
|
||||
|
||||
/* Note: this same logic is in efhd_output_secure */
|
||||
if (((EMFormatHTML *)emf)->valid == NULL) {
|
||||
((EMFormatHTML *)emf)->valid = valid;
|
||||
} else {
|
||||
e_dlist_addtail(&((EMFormatHTML *)emf)->valid_parent->children, (EDListNode *)valid);
|
||||
camel_cipher_validity_envelope(((EMFormatHTML *)emf)->valid_parent, valid);
|
||||
}
|
||||
|
||||
((EMFormatHTML *)emf)->valid_parent = valid;
|
||||
|
||||
len = emf->part_id->len;
|
||||
g_string_append_printf(emf->part_id, ".signed");
|
||||
em_format_part(emf, stream, part);
|
||||
g_string_truncate(emf->part_id, len);
|
||||
|
||||
((EMFormatHTML *)emf)->valid_parent = save;
|
||||
|
||||
if (((EMFormatHTML *)emf)->valid == valid
|
||||
/* To explain, if the validity is the same, then we are the
|
||||
base validity and now have a combined sign/encrypt validity
|
||||
we can display. Primarily a new verification context is
|
||||
created when we have an embeded message. */
|
||||
if (emf->valid == valid
|
||||
&& (valid->encrypt.status != CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE
|
||||
|| valid->sign.status != CAMEL_CIPHER_VALIDITY_SIGN_NONE)) {
|
||||
char *classid;
|
||||
@ -631,33 +616,6 @@ efh_output_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, Camel
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
efh_application_xpkcs7mime(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
|
||||
{
|
||||
CamelCipherContext *context;
|
||||
CamelException *ex;
|
||||
extern CamelSession *session;
|
||||
CamelMimePart *opart;
|
||||
CamelCipherValidity *valid;
|
||||
|
||||
ex = camel_exception_new();
|
||||
|
||||
context = camel_smime_context_new(session);
|
||||
|
||||
opart = camel_mime_part_new();
|
||||
valid = camel_cipher_decrypt(context, part, opart, ex);
|
||||
if (valid == NULL) {
|
||||
em_format_format_error(emf, stream, ex->desc?ex->desc:_("Could not parse S/MIME message: Unknown error"));
|
||||
em_format_part_as(emf, stream, part, NULL);
|
||||
} else {
|
||||
efh_output_secure(emf, stream, opart, valid);
|
||||
}
|
||||
|
||||
camel_object_unref(opart);
|
||||
camel_object_unref(context);
|
||||
camel_exception_free(ex);
|
||||
}
|
||||
|
||||
static void
|
||||
efh_text_plain(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFormatHandler *info)
|
||||
{
|
||||
@ -1058,49 +1016,6 @@ efh_multipart_related(EMFormat *emf, CamelStream *stream, CamelMimePart *part, c
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
efh_multipart_signed(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
|
||||
{
|
||||
CamelMimePart *cpart;
|
||||
CamelMultipartSigned *mps;
|
||||
CamelCipherContext *cipher = NULL;
|
||||
|
||||
mps = (CamelMultipartSigned *)camel_medium_get_content_object((CamelMedium *)part);
|
||||
if (!CAMEL_IS_MULTIPART_SIGNED(mps)
|
||||
|| (cpart = camel_multipart_get_part((CamelMultipart *)mps, CAMEL_MULTIPART_SIGNED_CONTENT)) == NULL) {
|
||||
em_format_format_error(emf, stream, _("Could not parse MIME message. Displaying as source."));
|
||||
em_format_format_source(emf, stream, part);
|
||||
return;
|
||||
}
|
||||
|
||||
/* FIXME: Should be done via a plugin interface */
|
||||
/* FIXME: duplicated in em-format-html-display.c */
|
||||
if (g_ascii_strcasecmp("application/x-pkcs7-signature", mps->protocol) == 0
|
||||
|| g_ascii_strcasecmp("application/pkcs7-signature", mps->protocol) == 0)
|
||||
cipher = camel_smime_context_new(emf->session);
|
||||
else if (g_ascii_strcasecmp("application/pgp-signature", mps->protocol) == 0)
|
||||
cipher = camel_gpg_context_new(emf->session);
|
||||
|
||||
if (cipher == NULL) {
|
||||
em_format_format_error(emf, stream, _("Unsupported signature format"));
|
||||
em_format_part_as(emf, stream, part, NULL);
|
||||
} else {
|
||||
CamelException *ex = camel_exception_new();
|
||||
CamelCipherValidity *valid;
|
||||
|
||||
valid = camel_cipher_verify(cipher, part, ex);
|
||||
if (valid == NULL) {
|
||||
em_format_format_error(emf, stream, ex->desc?ex->desc:_("Unknown error verifying signature"));
|
||||
em_format_part_as(emf, stream, part, NULL);
|
||||
} else {
|
||||
efh_output_secure(emf, stream, cpart, valid);
|
||||
}
|
||||
|
||||
camel_exception_free(ex);
|
||||
camel_object_unref(cipher);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
efh_write_image(EMFormat *emf, CamelStream *stream, EMFormatPURI *puri)
|
||||
{
|
||||
@ -1124,9 +1039,6 @@ efh_image(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFormatH
|
||||
}
|
||||
|
||||
static EMFormatHandler type_builtin_table[] = {
|
||||
{ "application/x-pkcs7-mime", (EMFormatFunc)efh_application_xpkcs7mime },
|
||||
{ "application/pkcs7-mime", (EMFormatFunc)efh_application_xpkcs7mime },
|
||||
|
||||
{ "image/gif", (EMFormatFunc)efh_image },
|
||||
{ "image/jpeg", (EMFormatFunc)efh_image },
|
||||
{ "image/png", (EMFormatFunc)efh_image },
|
||||
@ -1148,7 +1060,6 @@ static EMFormatHandler type_builtin_table[] = {
|
||||
{ "text/richtext", (EMFormatFunc)efh_text_enriched },
|
||||
{ "text/*", (EMFormatFunc)efh_text_plain },
|
||||
{ "message/external-body", (EMFormatFunc)efh_message_external },
|
||||
{ "multipart/signed", (EMFormatFunc)efh_multipart_signed },
|
||||
{ "multipart/related", (EMFormatFunc)efh_multipart_related },
|
||||
|
||||
/* This is where one adds those busted, non-registered types,
|
||||
@ -1318,10 +1229,11 @@ efh_format_timeout(struct _format_msg *m)
|
||||
efh_parent->format_clone((EMFormat *)efh, m->folder, m->uid, m->message, m->format_source);
|
||||
em_format_html_clear_pobject(m->format);
|
||||
|
||||
if (efh->valid) {
|
||||
camel_cipher_validity_free(efh->valid);
|
||||
efh->valid = NULL;
|
||||
efh->valid_parent = NULL;
|
||||
/* FIXME: method off EMFormat? */
|
||||
if (((EMFormat *)efh)->valid) {
|
||||
camel_cipher_validity_free(((EMFormat *)efh)->valid);
|
||||
((EMFormat *)efh)->valid = NULL;
|
||||
((EMFormat *)efh)->valid_parent = NULL;
|
||||
}
|
||||
|
||||
if (m->message == NULL) {
|
||||
@ -1677,10 +1589,11 @@ em_format_html_format_headers(EMFormatHTML *efh, CamelStream *stream, CamelMediu
|
||||
static void efh_format_message(EMFormat *emf, CamelStream *stream, CamelMedium *part)
|
||||
{
|
||||
#define efh ((EMFormatHTML *)emf)
|
||||
CamelCipherValidity *save = efh->valid, *save_parent = efh->valid_parent;
|
||||
/* TODO: make this validity stuff a method */
|
||||
CamelCipherValidity *save = emf->valid, *save_parent = emf->valid_parent;
|
||||
|
||||
efh->valid = NULL;
|
||||
efh->valid_parent = NULL;
|
||||
emf->valid = NULL;
|
||||
emf->valid_parent = NULL;
|
||||
|
||||
if (emf->message != (CamelMimeMessage *)part)
|
||||
camel_stream_printf(stream, "<blockquote>\n");
|
||||
@ -1694,10 +1607,10 @@ static void efh_format_message(EMFormat *emf, CamelStream *stream, CamelMedium *
|
||||
if (emf->message != (CamelMimeMessage *)part)
|
||||
camel_stream_printf(stream, "</blockquote>\n");
|
||||
|
||||
camel_cipher_validity_free(efh->valid);
|
||||
camel_cipher_validity_free(emf->valid);
|
||||
|
||||
efh->valid = save;
|
||||
efh->valid_parent = save_parent;
|
||||
emf->valid = save;
|
||||
emf->valid_parent = save_parent;
|
||||
#undef efh
|
||||
}
|
||||
|
||||
|
||||
@ -106,9 +106,6 @@ struct _EMFormatHTML {
|
||||
|
||||
EDList pending_object_list;
|
||||
|
||||
struct _CamelCipherValidity *valid;
|
||||
struct _CamelCipherValidity *valid_parent;
|
||||
|
||||
GSList *headers;
|
||||
|
||||
guint32 text_html_flags; /* default flags for text to html conversion */
|
||||
|
||||
185
mail/em-format.c
185
mail/em-format.c
@ -60,6 +60,7 @@ static const char *emf_snoop_part(CamelMimePart *part);
|
||||
static const EMFormatHandler *emf_find_handler(EMFormat *emf, const char *mime_type);
|
||||
static void emf_format_clone(EMFormat *emf, CamelFolder *folder, const char *uid, CamelMimeMessage *msg, EMFormat *emfsource);
|
||||
static void emf_format_prefix(EMFormat *emf, CamelStream *stream);
|
||||
static void emf_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid);
|
||||
static gboolean emf_busy(EMFormat *emf);
|
||||
|
||||
enum {
|
||||
@ -93,6 +94,7 @@ emf_finalise(GObject *o)
|
||||
g_hash_table_destroy(emf->inline_table);
|
||||
|
||||
em_format_clear_headers(emf);
|
||||
camel_cipher_validity_free(emf->valid);
|
||||
g_free(emf->charset);
|
||||
g_string_free(emf->part_id, TRUE);
|
||||
|
||||
@ -118,6 +120,7 @@ emf_class_init(GObjectClass *klass)
|
||||
((EMFormatClass *)klass)->find_handler = emf_find_handler;
|
||||
((EMFormatClass *)klass)->format_clone = emf_format_clone;
|
||||
((EMFormatClass *)klass)->format_prefix = emf_format_prefix;
|
||||
((EMFormatClass *)klass)->format_secure = emf_format_secure;
|
||||
((EMFormatClass *)klass)->busy = emf_busy;
|
||||
|
||||
emf_signals[EMF_COMPLETE] =
|
||||
@ -578,6 +581,33 @@ emf_format_prefix(EMFormat *emf, CamelStream *stream)
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
static void
|
||||
emf_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid)
|
||||
{
|
||||
CamelCipherValidity *save = emf->valid_parent;
|
||||
int len;
|
||||
|
||||
/* Note that this also requires support from higher up in the class chain
|
||||
- validity needs to be cleared when you start output
|
||||
- also needs to be cleared (but saved) whenever you start a new message. */
|
||||
|
||||
if (emf->valid == NULL) {
|
||||
emf->valid = valid;
|
||||
} else {
|
||||
e_dlist_addtail(&emf->valid_parent->children, (EDListNode *)valid);
|
||||
camel_cipher_validity_envelope(emf->valid_parent, valid);
|
||||
}
|
||||
|
||||
emf->valid_parent = valid;
|
||||
|
||||
len = emf->part_id->len;
|
||||
g_string_append_printf(emf->part_id, ".secured");
|
||||
em_format_part(emf, stream, part);
|
||||
g_string_truncate(emf->part_id, len);
|
||||
|
||||
emf->valid_parent = save;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
emf_busy(EMFormat *emf)
|
||||
{
|
||||
@ -993,6 +1023,35 @@ emf_snoop_part(CamelMimePart *part)
|
||||
see bug #11778 for some discussion */
|
||||
}
|
||||
|
||||
#ifdef HAVE_NSS
|
||||
static void
|
||||
emf_application_xpkcs7mime(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
|
||||
{
|
||||
CamelCipherContext *context;
|
||||
CamelException *ex;
|
||||
extern CamelSession *session;
|
||||
CamelMimePart *opart;
|
||||
CamelCipherValidity *valid;
|
||||
|
||||
ex = camel_exception_new();
|
||||
|
||||
context = camel_smime_context_new(session);
|
||||
|
||||
opart = camel_mime_part_new();
|
||||
valid = camel_cipher_decrypt(context, part, opart, ex);
|
||||
if (valid == NULL) {
|
||||
em_format_format_error(emf, stream, ex->desc?ex->desc:_("Could not parse S/MIME message: Unknown error"));
|
||||
em_format_part_as(emf, stream, part, NULL);
|
||||
} else {
|
||||
em_format_format_secure(emf, stream, opart, valid);
|
||||
}
|
||||
|
||||
camel_object_unref(opart);
|
||||
camel_object_unref(context);
|
||||
camel_exception_free(ex);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* RFC 1740 */
|
||||
static void
|
||||
emf_multipart_appledouble(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
|
||||
@ -1081,42 +1140,34 @@ emf_multipart_alternative(EMFormat *emf, CamelStream *stream, CamelMimePart *par
|
||||
static void
|
||||
emf_multipart_encrypted(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
|
||||
{
|
||||
CamelMultipartEncrypted *mpe;
|
||||
CamelMimePart *mime_part;
|
||||
CamelCipherContext *cipher;
|
||||
CamelException ex;
|
||||
CamelCipherContext *context;
|
||||
CamelException *ex;
|
||||
const char *protocol;
|
||||
int len;
|
||||
CamelMimePart *opart;
|
||||
CamelCipherValidity *valid;
|
||||
|
||||
/* Currently we only handle RFC2015-style PGP encryption. */
|
||||
protocol = camel_content_type_param (((CamelDataWrapper *) part)->mime_type, "protocol");
|
||||
if (!protocol || strcmp (protocol, "application/pgp-encrypted") != 0)
|
||||
return emf_multipart_mixed(emf, stream, part, info);
|
||||
|
||||
mpe = (CamelMultipartEncrypted *)camel_medium_get_content_object((CamelMedium *)part);
|
||||
|
||||
if (!CAMEL_IS_MULTIPART_ENCRYPTED(mpe)) {
|
||||
em_format_format_source(emf, stream, part);
|
||||
if (!protocol || g_ascii_strcasecmp (protocol, "application/pgp-encrypted") != 0) {
|
||||
em_format_format_error(emf, stream, _("Unsupported encryption type for multipart/encrypted"));
|
||||
em_format_part_as(emf, stream, part, "multipart/mixed");
|
||||
return;
|
||||
}
|
||||
|
||||
camel_exception_init (&ex);
|
||||
cipher = camel_gpg_context_new(emf->session);
|
||||
mime_part = camel_multipart_encrypted_decrypt(mpe, cipher, &ex);
|
||||
camel_object_unref(cipher);
|
||||
|
||||
if (camel_exception_is_set(&ex)) {
|
||||
/* FIXME: error handler */
|
||||
em_format_format_error(emf, stream, camel_exception_get_description(&ex));
|
||||
camel_exception_clear(&ex);
|
||||
return;
|
||||
ex = camel_exception_new();
|
||||
context = camel_gpg_context_new(emf->session);
|
||||
opart = camel_mime_part_new();
|
||||
valid = camel_cipher_decrypt(context, part, opart, ex);
|
||||
if (valid == NULL) {
|
||||
em_format_format_error(emf, stream, ex->desc?ex->desc:_("Could not parse S/MIME message: Unknown error"));
|
||||
em_format_part_as(emf, stream, part, NULL);
|
||||
} else {
|
||||
em_format_format_secure(emf, stream, opart, valid);
|
||||
}
|
||||
|
||||
len = emf->part_id->len;
|
||||
g_string_append_printf(emf->part_id, ".encrypted");
|
||||
em_format_part(emf, stream, mime_part);
|
||||
g_string_truncate(emf->part_id, len);
|
||||
camel_object_unref(mime_part);
|
||||
camel_object_unref(opart);
|
||||
camel_object_unref(context);
|
||||
camel_exception_free(ex);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1232,69 +1283,50 @@ emf_multipart_related(EMFormat *emf, CamelStream *stream, CamelMimePart *part, c
|
||||
}
|
||||
}
|
||||
|
||||
/* this is only a fallback implementation, implementations should override */
|
||||
static void
|
||||
emf_multipart_signed(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
|
||||
{
|
||||
CamelMimePart *cpart;
|
||||
CamelMultipartSigned *mps;
|
||||
CamelCipherValidity *valid = NULL;
|
||||
CamelException ex;
|
||||
const char *message = NULL;
|
||||
gboolean good = FALSE;
|
||||
int len;
|
||||
CamelCipherContext *cipher = NULL;
|
||||
|
||||
mps = (CamelMultipartSigned *)camel_medium_get_content_object((CamelMedium *)part);
|
||||
if (!CAMEL_IS_MULTIPART_SIGNED(mps)
|
||||
|| (cpart = camel_multipart_get_part((CamelMultipart *)mps, CAMEL_MULTIPART_SIGNED_CONTENT)) == NULL) {
|
||||
em_format_format_error(emf, stream, _("Could not parse MIME message. Displaying as source."));
|
||||
em_format_format_source(emf, stream, part);
|
||||
return;
|
||||
}
|
||||
|
||||
len = emf->part_id->len;
|
||||
g_string_append_printf(emf->part_id, ".signed");
|
||||
em_format_part(emf, stream, cpart);
|
||||
g_string_truncate(emf->part_id, len);
|
||||
|
||||
/* FIXME: This sequence is also copied in em-format-html.c */
|
||||
|
||||
camel_exception_init(&ex);
|
||||
if (emf->session == NULL) {
|
||||
message = _("Session not initialised");
|
||||
} else {
|
||||
CamelCipherContext *cipher = NULL;
|
||||
|
||||
/* FIXME: Should be done via a plugin interface */
|
||||
if (g_ascii_strcasecmp("application/x-pkcs7-signature", mps->protocol) == 0
|
||||
|| g_ascii_strcasecmp("application/pkcs7-signature", mps->protocol) == 0)
|
||||
cipher = camel_smime_context_new(emf->session);
|
||||
else if (g_ascii_strcasecmp("application/pgp-signature", mps->protocol) == 0)
|
||||
/* FIXME: Should be done via a plugin interface */
|
||||
/* FIXME: duplicated in em-format-html-display.c */
|
||||
#ifdef HAVE_NSS
|
||||
if (g_ascii_strcasecmp("application/x-pkcs7-signature", mps->protocol) == 0
|
||||
|| g_ascii_strcasecmp("application/pkcs7-signature", mps->protocol) == 0)
|
||||
cipher = camel_smime_context_new(emf->session);
|
||||
else
|
||||
#endif
|
||||
if (g_ascii_strcasecmp("application/pgp-signature", mps->protocol) == 0)
|
||||
cipher = camel_gpg_context_new(emf->session);
|
||||
|
||||
if (cipher == NULL) {
|
||||
message = _("Unsupported signature format");
|
||||
if (cipher == NULL) {
|
||||
em_format_format_error(emf, stream, _("Unsupported signature format"));
|
||||
em_format_part_as(emf, stream, part, "multipart/mixed");
|
||||
} else {
|
||||
CamelException *ex = camel_exception_new();
|
||||
CamelCipherValidity *valid;
|
||||
|
||||
valid = camel_cipher_verify(cipher, part, ex);
|
||||
if (valid == NULL) {
|
||||
em_format_format_error(emf, stream, ex->desc?ex->desc:_("Unknown error verifying signature"));
|
||||
em_format_part_as(emf, stream, part, NULL);
|
||||
} else {
|
||||
valid = camel_cipher_verify(cipher, part, &ex);
|
||||
camel_object_unref(cipher);
|
||||
if (valid) {
|
||||
good = camel_cipher_validity_get_valid(valid);
|
||||
message = camel_cipher_validity_get_description(valid);
|
||||
} else {
|
||||
message = camel_exception_get_description(&ex);
|
||||
}
|
||||
em_format_format_secure(emf, stream, cpart, valid);
|
||||
}
|
||||
|
||||
camel_exception_free(ex);
|
||||
camel_object_unref(cipher);
|
||||
}
|
||||
|
||||
if (good)
|
||||
em_format_format_error(emf, stream, _("This message is digitally signed and has been found to be authentic."));
|
||||
else
|
||||
em_format_format_error(emf, stream, _("This message is digitally signed but can not be proven to be authentic."));
|
||||
|
||||
if (message)
|
||||
em_format_format_error(emf, stream, message);
|
||||
|
||||
camel_exception_clear(&ex);
|
||||
camel_cipher_validity_free(valid);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1315,6 +1347,9 @@ emf_message_rfc822(EMFormat *emf, CamelStream *stream, CamelMimePart *part, cons
|
||||
}
|
||||
|
||||
static EMFormatHandler type_builtin_table[] = {
|
||||
#ifdef HAVE_NSS
|
||||
{ "application/x-pkcs7-mime", (EMFormatFunc)emf_application_xpkcs7mime },
|
||||
#endif
|
||||
{ "multipart/alternative", emf_multipart_alternative },
|
||||
{ "multipart/appledouble", emf_multipart_appledouble },
|
||||
{ "multipart/encrypted", emf_multipart_encrypted },
|
||||
@ -1325,6 +1360,12 @@ static EMFormatHandler type_builtin_table[] = {
|
||||
{ "message/rfc822", emf_message_rfc822 },
|
||||
{ "message/news", emf_message_rfc822 },
|
||||
{ "message/*", emf_message_rfc822 },
|
||||
|
||||
/* Insert brokenly-named parts here */
|
||||
#ifdef HAVE_NSS
|
||||
{ "application/pkcs7-mime", (EMFormatFunc)emf_application_xpkcs7mime },
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
static void
|
||||
|
||||
@ -37,6 +37,7 @@ struct _CamelSession;
|
||||
struct _CamelURL;
|
||||
struct _CamelDataWrapper;
|
||||
struct _CamelMimeMessage;
|
||||
struct _CamelCipherValidity;
|
||||
|
||||
typedef struct _EMFormat EMFormat;
|
||||
typedef struct _EMFormatClass EMFormatClass;
|
||||
@ -114,6 +115,10 @@ struct _EMFormat {
|
||||
|
||||
const char *snoop_mime_type; /* if we snooped an application/octet-stream type, what we snooped */
|
||||
|
||||
/* for validity enveloping */
|
||||
struct _CamelCipherValidity *valid;
|
||||
struct _CamelCipherValidity *valid_parent;
|
||||
|
||||
/* for forcing inlining */
|
||||
GHashTable *inline_table;
|
||||
|
||||
@ -153,6 +158,8 @@ struct _EMFormatClass {
|
||||
void (*format_message)(EMFormat *, struct _CamelStream *, struct _CamelMedium *);
|
||||
/* use for unparsable content */
|
||||
void (*format_source)(EMFormat *, struct _CamelStream *, struct _CamelMimePart *);
|
||||
/* for outputing secure(d) content */
|
||||
void (*format_secure)(EMFormat *, struct _CamelStream *, struct _CamelMimePart *, struct _CamelCipherValidity *);
|
||||
|
||||
/* returns true if the formatter is still busy with pending stuff */
|
||||
gboolean (*busy)(EMFormat *);
|
||||
@ -212,6 +219,7 @@ void em_format_pull_level(EMFormat *emf);
|
||||
#define em_format_format_attachment(emf, stream, msg, type, info) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_attachment((emf), (stream), (msg), (type), (info))
|
||||
#define em_format_format_message(emf, stream, msg) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_message((emf), (stream), (msg))
|
||||
#define em_format_format_source(emf, stream, msg) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_source((emf), (stream), (msg))
|
||||
#define em_format_format_secure(emf, stream, msg, valid) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_secure((emf), (stream), (msg), (valid))
|
||||
|
||||
#define em_format_busy(emf) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->busy((emf))
|
||||
|
||||
|
||||
@ -403,8 +403,9 @@ impl_createControls (PortableServer_Servant servant,
|
||||
GtkWidget *view_widget;
|
||||
GtkWidget *statusbar_widget;
|
||||
|
||||
mail_session_set_interactive(TRUE);
|
||||
mc_startup(mail_component);
|
||||
|
||||
|
||||
view_widget = em_folder_browser_new ();
|
||||
tree_widget = (GtkWidget *) em_folder_tree_new_with_model (priv->model);
|
||||
em_folder_tree_enable_drag_and_drop ((EMFolderTree *) tree_widget);
|
||||
|
||||
Reference in New Issue
Block a user