aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mail/ChangeLog128
-rw-r--r--mail/mail-display.c281
-rw-r--r--mail/mail-format.c626
3 files changed, 495 insertions, 540 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 87ced53bdf..dcd356683e 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,5 +1,49 @@
2001-10-22 Dan Winship <danw@ximian.com>
+ PGP verification UI changes to make it not HTML spoofable.
+
+ * mail-format.c (handle_application_pgp): Remove this unused
+ hack.
+ (mail_format_mime_message): Initialize a fourth hash table, used
+ to keep track of fake MIME parts.
+ (mail_part_set_default_displayed_inline): New routine to set the
+ default disposition of a part (doesn't change it if the user has
+ already overridden it).
+ (format_mime_part): Wrap a blockquote around the error text (moved
+ here from mail_error_write since it doesn't apply in other cases).
+ (write_hr): Write a <hr> with appropriate padding between MIME
+ parts.
+ (write_one_text_plain_chunk): Write some plain text with
+ appropriate margins.
+ (handle_text_plain): Use write_one_text_plain_chunk. Update for
+ inline specials handler API change.
+ (fake_mime_part_from_data): Use the "fake_parts" hash to avoid
+ recreating the same fake parts again if the message is
+ redisplayed. Lets you toggle the shown/hiddenness of uudecode
+ parts, and do the new pgp verification thing for inline pgp
+ signatures.
+ (try_inline_pgp): Don't do any actual PGP handling here: Just
+ rewrite as a multipart/encrypted.
+ (try_inline_pgp_sig): Likewise, just do a multipart/signed (with
+ the x-inline-pgp-hack parameter set).
+ (try_uudecoding, try_inline_binhex): Update for API changes.
+ (handle_multipart_signed): Exciting and new. Use <object> to
+ create a button which the user must click to do the
+ verification. Change the formatting of the gpg output text a bit.
+
+ * mail-display.c (on_link_clicked): Remove x-evolution-decode-pgp
+ hack, which is no longer used.
+ (pixbuf_gen_idle): Add a hack for the PGP verification button.
+ (do_attachment_header, do_external_viewer): Split out of
+ on_object_requeested for clarity.
+ (do_signature): New routine to do the PGP verification button.
+ (on_object_requested): Now just dispatches to
+ do_attachment_header, do_external_viewer, or do_signature.
+ (mail_error_write): Don't do <blockquote> here. Fixed the problem
+ that was trying to fix elsewhere.
+
+2001-10-22 Dan Winship <danw@ximian.com>
+
* mail-callbacks.c (transfer_msg): Fix these functions so they
don't crash evolution-mail. Too bad it still crashes in the
shell.
@@ -14220,48 +14264,48 @@ End of branch
current_message = NULL, which shouldn't happen, but has happened
to me.
-2000-07-25 Dan Winship <danw@helixcode.com>
-
- * message-thread.c (group_root_set): Don't group together messages
- with the same non-Re: subject and no References/In-Reply-To. More
- often than not, they're unrelated. (eg, "[No subject]".)
- (thread_messages): Handle messages with no Message-Id. "This
- shouldn't happen", but it does sometimes, and it's not much code
- to make it just work.
-
-2000-07-25 Ettore Perazzoli <ettore@helixcode.com>
-
- * mail-config.c (create_service_page): Call
- `gtk_option_menu_set_menu()' as the last thing, as `GtkOptionMenu'
- is fscking broken. Also, `gtk_widget_show()' the individual menu
- items.
-
-2000-07-24 Dan Winship <danw@helixcode.com>
-
- * message-list.c (mark_msg_seen, ml_tree_set_value_at,
- message_list_regenerate): Update for CamelFolder API changes.
- (Certain functions no longer take a CamelException.)
-
- * mail-ops.c (real_fetch_mail, real_send_mail, real_delete_msg):
- ditto
-
- * component-factory.c (real_create_imap_storage,
- real_create_news_storage): ditto
-
-2000-07-24 Dan Winship <danw@helixcode.com>
-
- * component-factory.c, folder-browser-factory.c, test-mail.c:
- Remove GOAD support.
-
- * main.c: Remove GOAD support.
- (main): More "guess the build mistake" fun, this time for the
- failure to initialize Bonobo case.
-
-2000-07-24 Peter Williams <peterw@helixcode.com>
-
- * mail-tools.c (mail_tool_set_uid_flags): Change
- function to faithfully pass parameters to
- camel_folder_set_message_flags; this function is
+2000-07-25 Dan Wnihspi d<na@wehilcxdo.eoc>m
+
+* m seasegt-rhae.d cg(orpur_oo_tes)t :oD'n trguo poteghtrem seaseg
+sw ti hht easemn noR-:es buejtca dnn oeRefercnseI/-neRlp-yoT .oMer
+foet nhtnan to ,htyer' enueralet.d( ge ,["oNs buejtc"]).
+t(rhae_demssgase:)H nald eemssgasew ti honM seasegI-.d" hTsi
+hsuodl'n tahppne,"b tui todses motemise ,na dtis'n tom cu hoced
+otm ka etij su towkr
+.2
+00-0702- 5E ttro eeParzzlo i< teoterh@lexiocedc.mo
+>
+ *amlic-noif.g cc(erta_eesvrci_eapeg:)C la
+l` tg_kpoitnom_ne_ues_temun)( 'sat ehl sa thtni,ga sG`ktpOitnoeMun
+'i ssfkcni grbkone .A sl,o` tg_kiwgdtes_oh(w')t ehi dnvidiau lemun
+time.s
+
+02000--742 aD niWsnih p< adwnh@lexiocedc.mo
+>
+ *emssga-eiltsc.( amkrm_gss_ee,nm _lrtees_tev_laeua_,t
+emssga_eiltsr_genereta)e :pUadetf roC maleoFdlreA IPc ahgnse
+.( eCtria nufcnitno sonl noeg rateka C malexEectpoi.n
+)
+ *amlio-spc.( erlaf_tehcm_ia,lr ae_lesdnm_ia,lr ae_ledeletm_gs:)
+idtt
+o
+ *ocpmnone-taftcro.y cr(ae_lrcaeeti_am_ptsroga,e
+erlac_erta_eensws_otareg:)d tiot
+
+02000--742 aD niWsnih p< adwnh@lexiocedc.mo
+>
+ *ocpmnone-taftcro.y,cf loed-rrbwoes-raftcro.y,ct se-tamlic.
+:R mevo eOGDAs puoptr
+.
+ *amnic. :eRomevG AO Dusppro.t
+m(ia)n :oMer" ugse sht eubli dimtska"ef nu ,htsit mi eof rht
+ef iaulert onitiaiilezB nobo oaces
+.2
+00-0702- 4P tereW liilma s< epetwrh@lexiocedc.mo
+>
+ *amlit-ooslc.( amlit_oo_les_tiu_dlfga)s :hCnaeg
+ufcnitnot oaftifhluylp sa saparemetsrt
+oc malef_loed_res_temssga_elfga;st ih sufnction is
somewhat useless now. Other files synced with
API change.
diff --git a/mail/mail-display.c b/mail/mail-display.c
index 3dbd12523c..ebe1a5147c 100644
--- a/mail/mail-display.c
+++ b/mail/mail-display.c
@@ -218,11 +218,7 @@ on_link_clicked (GtkHTML *html, const char *url, MailDisplay *md)
g_warning ("Can't handle news URLs yet.");
else if (!g_strncasecmp (url, "mailto:", 7))
send_to_url (url);
- else if (!strcmp (url, "x-evolution-decode-pgp:")) {
- g_datalist_set_data (md->data, "show_pgp",
- GINT_TO_POINTER (1));
- mail_display_queue_redisplay (md);
- } else if (*url == '#')
+ else if (*url == '#')
mail_display_jump_to_anchor (md, url);
else
gnome_url_show (url);
@@ -580,9 +576,12 @@ pixbuf_gen_idle (struct _PixbufLoader *pbl)
error = TRUE;
}
- if (error || !pbl->mstream)
- pixbuf = pixbuf_for_mime_type (pbl->type);
- else
+ if (error || !pbl->mstream) {
+ if (pbl->type)
+ pixbuf = pixbuf_for_mime_type (pbl->type);
+ else
+ pixbuf = gdk_pixbuf_new_from_file (EVOLUTION_ICONSDIR "/pgp-signature-nokey.png");
+ } else
pixbuf = gdk_pixbuf_loader_get_pixbuf (pbl->loader);
width = gdk_pixbuf_get_width (pixbuf);
@@ -776,138 +775,94 @@ save_url (MailDisplay *md, const char *url)
}
static gboolean
-on_object_requested (GtkHTML *html, GtkHTMLEmbedded *eb, gpointer data)
+do_attachment_header (GtkHTML *html, GtkHTMLEmbedded *eb,
+ CamelMimePart *part, MailDisplay *md)
{
- MailDisplay *md = data;
- GHashTable *urls;
- CamelMedium *medium;
- CamelDataWrapper *wrapper;
- OAF_ServerInfo *component;
- GtkWidget *embedded;
- BonoboObjectClient *server;
- Bonobo_PersistStream persist;
- CORBA_Environment ev;
- GByteArray *ba;
- CamelStream *cstream;
- BonoboStream *bstream;
- char *cid;
+ GtkWidget *button, *mainbox, *hbox, *arrow, *popup;
+ MailMimeHandler *handler;
+ struct _PixbufLoader *pbl;
- cid = eb->classid;
+ pbl = g_new0 (struct _PixbufLoader, 1);
+ if (g_strncasecmp (eb->type, "image/", 6) == 0) {
+ CamelDataWrapper *content;
- if (!strncmp (cid, "popup:", 6))
- cid += 6;
- if (strncmp (cid, "cid:", 4) != 0)
- return FALSE;
+ content = camel_medium_get_content_object (CAMEL_MEDIUM (part));
+ if (!camel_data_wrapper_is_offline (content)) {
+ pbl->mstream = camel_stream_mem_new ();
+ camel_data_wrapper_write_to_stream (content, pbl->mstream);
+ camel_stream_reset (pbl->mstream);
+ }
+ }
+ pbl->type = g_strdup (eb->type);
+ pbl->cid = g_strdup (eb->classid + 6);
+ pbl->pixmap = bonobo_ui_toolbar_icon_new ();
+ pbl->eb = eb;
+ pbl->destroy_id = gtk_signal_connect (GTK_OBJECT (eb), "destroy",
+ embeddable_destroy_cb, pbl);
- urls = g_datalist_get_data (md->data, "part_urls");
- g_return_val_if_fail (urls != NULL, FALSE);
+ g_idle_add_full (G_PRIORITY_LOW, (GSourceFunc)pixbuf_gen_idle,
+ pbl, NULL);
- medium = g_hash_table_lookup (urls, cid);
- g_return_val_if_fail (CAMEL_IS_MEDIUM (medium), FALSE);
+ mainbox = gtk_hbox_new (FALSE, 0);
- if (cid != eb->classid) {
- /* This is a part wrapper */
-#ifdef USE_OLD_DISPLAY_STYLE
- GtkWidget *ebox;
-#else
- GtkWidget *button, *mainbox, *hbox, *arrow, *popup;
- MailMimeHandler *handler;
-#endif
- struct _PixbufLoader *pbl;
+ button = gtk_button_new ();
+ gtk_object_set_data (GTK_OBJECT (button), "MailDisplay", md);
- pbl = g_new0 (struct _PixbufLoader, 1);
- if (g_strncasecmp (eb->type, "image/", 6) == 0) {
- CamelDataWrapper *content;
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (button_press), part);
- content = camel_medium_get_content_object (medium);
- if (!camel_data_wrapper_is_offline (content)) {
- pbl->mstream = camel_stream_mem_new ();
- camel_data_wrapper_write_to_stream (content, pbl->mstream);
- camel_stream_reset (pbl->mstream);
- }
- }
- pbl->type = g_strdup (eb->type);
- pbl->cid = g_strdup (cid);
- pbl->pixmap = bonobo_ui_toolbar_icon_new ();
- pbl->eb = eb;
- pbl->destroy_id = gtk_signal_connect (GTK_OBJECT (eb),
- "destroy",
- embeddable_destroy_cb,
- pbl);
-
- g_idle_add_full (G_PRIORITY_LOW, (GSourceFunc)pixbuf_gen_idle,
- pbl, NULL);
+ hbox = gtk_hbox_new (FALSE, 2);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 2);
-#ifdef USE_OLD_DISPLAY_STYLE
- ebox = gtk_event_box_new ();
- gtk_widget_set_sensitive (GTK_WIDGET (ebox), TRUE);
- gtk_widget_add_events (GTK_WIDGET (ebox),
- GDK_BUTTON_PRESS_MASK);
- gtk_object_set_data (GTK_OBJECT (ebox), "MailDisplay", md);
- gtk_object_set_data (GTK_OBJECT (ebox), "CamelMimePart",
- medium);
- gtk_object_set_data_full (GTK_OBJECT (ebox), "mime_type",
- g_strdup (eb->type),
- (GDestroyNotify)g_free);
-
- gtk_signal_connect (GTK_OBJECT (ebox), "button_press_event",
- GTK_SIGNAL_FUNC (pixmap_press), md->scroll);
-
- gtk_container_add (GTK_CONTAINER (ebox), pbl->pixmap);
- gtk_widget_show_all (ebox);
- gtk_container_add (GTK_CONTAINER (eb), ebox);
-#else
- mainbox = gtk_hbox_new (FALSE, 0);
-
- button = gtk_button_new ();
- gtk_object_set_data (GTK_OBJECT (button), "MailDisplay", md);
-
- gtk_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (button_press), medium);
-
- hbox = gtk_hbox_new (FALSE, 2);
- gtk_container_set_border_width (GTK_CONTAINER (hbox), 2);
-
- if (mail_part_is_displayed_inline (CAMEL_MIME_PART (medium), md)) {
- arrow = gnome_stock_new_with_icon (GNOME_STOCK_PIXMAP_DOWN);
- } else {
- arrow = gnome_stock_new_with_icon (GNOME_STOCK_PIXMAP_FORWARD);
- }
- gtk_box_pack_start (GTK_BOX (hbox), arrow, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (hbox), pbl->pixmap, TRUE, TRUE, 0);
- gtk_container_add (GTK_CONTAINER (button), hbox);
-
- popup = gtk_button_new ();
- gtk_container_add (GTK_CONTAINER (popup),
- gtk_arrow_new (GTK_ARROW_DOWN,
- GTK_SHADOW_ETCHED_IN));
-
- gtk_object_set_data (GTK_OBJECT (popup), "MailDisplay", md);
- gtk_object_set_data (GTK_OBJECT (popup), "CamelMimePart",
- medium);
- gtk_object_set_data_full (GTK_OBJECT (popup), "mime_type",
- g_strdup (eb->type),
- (GDestroyNotify)g_free);
-
- gtk_signal_connect (GTK_OBJECT (popup), "button_press_event",
- GTK_SIGNAL_FUNC (pixmap_press), md->scroll);
-
- gtk_box_pack_start (GTK_BOX (mainbox), button, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (mainbox), popup, TRUE, TRUE, 0);
- gtk_widget_show_all (mainbox);
-
- handler = mail_lookup_handler (eb->type);
- if (handler && handler->builtin) {
- gtk_widget_set_sensitive (button, TRUE);
- } else {
- gtk_widget_set_sensitive (button, FALSE);
- }
+ if (mail_part_is_displayed_inline (part, md))
+ arrow = gnome_stock_new_with_icon (GNOME_STOCK_PIXMAP_DOWN);
+ else
+ arrow = gnome_stock_new_with_icon (GNOME_STOCK_PIXMAP_FORWARD);
+ gtk_box_pack_start (GTK_BOX (hbox), arrow, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), pbl->pixmap, TRUE, TRUE, 0);
+ gtk_container_add (GTK_CONTAINER (button), hbox);
+
+ popup = gtk_button_new ();
+ gtk_container_add (GTK_CONTAINER (popup),
+ gtk_arrow_new (GTK_ARROW_DOWN,
+ GTK_SHADOW_ETCHED_IN));
+
+ gtk_object_set_data (GTK_OBJECT (popup), "MailDisplay", md);
+ gtk_object_set_data (GTK_OBJECT (popup), "CamelMimePart", part);
+ gtk_object_set_data_full (GTK_OBJECT (popup), "mime_type",
+ g_strdup (eb->type), (GDestroyNotify)g_free);
+
+ gtk_signal_connect (GTK_OBJECT (popup), "button_press_event",
+ GTK_SIGNAL_FUNC (pixmap_press), md->scroll);
+
+ gtk_box_pack_start (GTK_BOX (mainbox), button, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (mainbox), popup, TRUE, TRUE, 0);
+ gtk_widget_show_all (mainbox);
+
+ handler = mail_lookup_handler (eb->type);
+ if (handler && handler->builtin)
+ gtk_widget_set_sensitive (button, TRUE);
+ else
+ gtk_widget_set_sensitive (button, FALSE);
- gtk_container_add (GTK_CONTAINER (eb), mainbox);
-#endif
+ gtk_container_add (GTK_CONTAINER (eb), mainbox);
- return TRUE;
- }
+ return TRUE;
+}
+
+static gboolean
+do_external_viewer (GtkHTML *html, GtkHTMLEmbedded *eb,
+ CamelMimePart *part, MailDisplay *md)
+{
+ CamelDataWrapper *wrapper;
+ OAF_ServerInfo *component;
+ GtkWidget *embedded;
+ BonoboObjectClient *server;
+ Bonobo_PersistStream persist;
+ CORBA_Environment ev;
+ GByteArray *ba;
+ CamelStream *cstream;
+ BonoboStream *bstream;
component = gnome_vfs_mime_get_default_component (eb->type);
if (!component)
@@ -929,7 +884,7 @@ on_object_requested (GtkHTML *html, GtkHTMLEmbedded *eb, gpointer data)
/* Write the data to a CamelStreamMem... */
ba = g_byte_array_new ();
cstream = camel_stream_mem_new_with_byte_array (ba);
- wrapper = camel_medium_get_content_object (medium);
+ wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (part));
camel_data_wrapper_write_to_stream (wrapper, cstream);
/* ...convert the CamelStreamMem to a BonoboStreamMem... */
@@ -958,6 +913,66 @@ on_object_requested (GtkHTML *html, GtkHTMLEmbedded *eb, gpointer data)
return TRUE;
}
+
+static gboolean
+do_signature (GtkHTML *html, GtkHTMLEmbedded *eb,
+ CamelMimePart *part, MailDisplay *md)
+{
+ GtkWidget *button;
+ struct _PixbufLoader *pbl;
+
+ pbl = g_new0 (struct _PixbufLoader, 1);
+ pbl->type = NULL;
+ pbl->cid = g_strdup (eb->classid);
+ pbl->pixmap = bonobo_ui_toolbar_icon_new ();
+ pbl->eb = eb;
+ pbl->destroy_id = gtk_signal_connect (GTK_OBJECT (eb), "destroy",
+ embeddable_destroy_cb, pbl);
+
+ g_idle_add_full (G_PRIORITY_LOW, (GSourceFunc)pixbuf_gen_idle,
+ pbl, NULL);
+
+ button = gtk_button_new ();
+ gtk_object_set_data (GTK_OBJECT (button), "MailDisplay", md);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (button_press), part);
+ gtk_container_add (GTK_CONTAINER (button), pbl->pixmap);
+ gtk_widget_show_all (button);
+ gtk_container_add (GTK_CONTAINER (eb), button);
+
+ return TRUE;
+}
+
+static gboolean
+on_object_requested (GtkHTML *html, GtkHTMLEmbedded *eb, gpointer data)
+{
+ MailDisplay *md = data;
+ GHashTable *urls;
+ CamelMimePart *part;
+
+ urls = g_datalist_get_data (md->data, "part_urls");
+ if (!urls)
+ return FALSE;
+
+ if (!strncmp (eb->classid, "popup:", 6)) {
+ part = g_hash_table_lookup (urls, eb->classid + 6);
+ if (!CAMEL_IS_MIME_PART (part))
+ return FALSE;
+ return do_attachment_header (html, eb, part, md);
+ } else if (!strncmp (eb->classid, "signature:", 10)) {
+ part = g_hash_table_lookup (urls, eb->classid);
+ if (!CAMEL_IS_MIME_PART (part))
+ return FALSE;
+ return do_signature (html, eb, part, md);
+ } else if (!strncmp (eb->classid, "cid:", 4)) {
+ part = g_hash_table_lookup (urls, eb->classid);
+ if (!CAMEL_IS_MIME_PART (part))
+ return FALSE;
+ return do_external_viewer (html, eb, part, md);
+ }
+
+ return FALSE;
+}
static void
load_http (MailDisplay *md, gpointer data)
@@ -1336,9 +1351,9 @@ mail_error_write (GtkHTML *html, GtkHTMLStream *stream,
htmltext = e_text_to_html (buf, E_TEXT_TO_HTML_CONVERT_NL | E_TEXT_TO_HTML_CONVERT_URLS);
g_free (buf);
- gtk_html_stream_printf (stream, "<blockquote><em><font color=red>");
+ gtk_html_stream_printf (stream, "<em><font color=red>");
gtk_html_stream_write (stream, htmltext, strlen (htmltext));
- gtk_html_stream_printf (stream, "</font></em></blockquote>");
+ gtk_html_stream_printf (stream, "</font></em>");
g_free (htmltext);
}
@@ -1540,11 +1555,13 @@ link_open_in_browser (GtkWidget *w, MailDisplay *mail_display)
mail_display);
}
+#if 0
static void
link_save_as (GtkWidget *w, MailDisplay *mail_display)
{
g_print ("FIXME save %s\n", mail_display->html->pointer_url);
}
+#endif
static void
link_copy_location (GtkWidget *w, MailDisplay *mail_display)
diff --git a/mail/mail-format.c b/mail/mail-format.c
index 91545cd97a..00be9a5a14 100644
--- a/mail/mail-format.c
+++ b/mail/mail-format.c
@@ -42,6 +42,7 @@
#include <camel/camel-stream-null.h>
#include <shell/e-setup.h>
#include <e-util/e-html-utils.h>
+#include <e-util/e-unicode-i18n.h>
#include "mail.h"
#include "mail-tools.h"
@@ -49,12 +50,14 @@
#include "mail-mt.h"
#include "mail-crypto.h"
-static char *try_inline_pgp (char *start, CamelMimePart *part, MailDisplay *md);
-static char *try_inline_pgp_sig (char *start, CamelMimePart *part, MailDisplay *md);
-static char *try_uudecoding (char *start, CamelMimePart *part, MailDisplay *md);
-static char *try_inline_binhex (char *start, CamelMimePart *part, MailDisplay *md);
-
-static void decode_pgp (CamelStream *ciphertext, CamelStream *plaintext, MailDisplay *md);
+static char *try_inline_pgp (char *start, CamelMimePart *part,
+ guint offset, MailDisplay *md);
+static char *try_inline_pgp_sig (char *start, CamelMimePart *part,
+ guint offset, MailDisplay *md);
+static char *try_uudecoding (char *start, CamelMimePart *part,
+ guint offset, MailDisplay *md);
+static char *try_inline_binhex (char *start, CamelMimePart *part,
+ guint offset, MailDisplay *md);
static gboolean handle_text_plain (CamelMimePart *part,
const char *mime_type,
@@ -95,12 +98,6 @@ static gboolean handle_message_external_body (CamelMimePart *part,
const char *mime_type,
MailDisplay *md);
-#ifdef APPLICATION_PGP_IS_NO_LONGER_SUPPORTED
-static gboolean handle_application_pgp (CamelMimePart *part,
- const char *mime_type,
- MailDisplay *md);
-#endif /* APPLICATION_PGP_IS_NO_LONGER_SUPPORTED */
-
static gboolean handle_via_bonobo (CamelMimePart *part,
const char *mime_type,
MailDisplay *md);
@@ -159,28 +156,33 @@ add_url (const char *kind, char *url, gpointer data, MailDisplay *md)
void
mail_format_mime_message (CamelMimeMessage *mime_message, MailDisplay *md)
{
- GHashTable *urls;
+ GHashTable *hash;
g_return_if_fail (CAMEL_IS_MIME_MESSAGE (mime_message));
- urls = g_datalist_get_data (md->data, "part_urls");
- if (!urls) {
- urls = g_hash_table_new (g_str_hash, g_str_equal);
- g_datalist_set_data_full (md->data, "part_urls", urls,
+ hash = g_datalist_get_data (md->data, "part_urls");
+ if (!hash) {
+ hash = g_hash_table_new (g_str_hash, g_str_equal);
+ g_datalist_set_data_full (md->data, "part_urls", hash,
free_part_urls);
}
- urls = g_datalist_get_data (md->data, "data_urls");
- if (!urls) {
- urls = g_hash_table_new (g_str_hash, g_str_equal);
- g_datalist_set_data_full (md->data, "data_urls", urls,
+ hash = g_datalist_get_data (md->data, "data_urls");
+ if (!hash) {
+ hash = g_hash_table_new (g_str_hash, g_str_equal);
+ g_datalist_set_data_full (md->data, "data_urls", hash,
free_data_urls);
}
- /* ok, so they're not urls. so sue me. */
- urls = g_datalist_get_data (md->data, "attachment_states");
- if (!urls) {
- urls = g_hash_table_new (g_direct_hash, g_direct_equal);
- g_datalist_set_data_full (md->data, "attachment_states", urls,
+ hash = g_datalist_get_data (md->data, "attachment_states");
+ if (!hash) {
+ hash = g_hash_table_new (NULL, NULL);
+ g_datalist_set_data_full (md->data, "attachment_states", hash,
+ (GDestroyNotify) g_hash_table_destroy);
+ }
+ hash = g_datalist_get_data (md->data, "fake_parts");
+ if (!hash) {
+ hash = g_hash_table_new (NULL, NULL);
+ g_datalist_set_data_full (md->data, "fake_parts", hash,
(GDestroyNotify) g_hash_table_destroy);
}
@@ -358,15 +360,6 @@ setup_mime_tables (void)
g_hash_table_insert (mime_function_table, "multipart/signed",
handle_multipart_signed);
-#ifdef APPLICATION_PGP_IS_NO_LONGER_SUPPORTED
- /* Some broken mailers, such as The Bat! send pgp
- * signed/encrypted messages with a content-type of
- * application/pgp which basically means it's a text/plain but
- * either signed or encrypted. */
- g_hash_table_insert (mime_function_table, "application/pgp",
- handle_application_pgp);
-#endif /* APPLICATION_PGP_IS_NO_LONGER_SUPPORTED */
-
/* RFC 2046 says unrecognized text subtypes can be treated
* as text/plain (as long as you recognize the character set),
* and unrecognized multipart subtypes as multipart/mixed. */
@@ -531,15 +524,6 @@ mail_part_is_inline (CamelMimePart *part)
if (!header_content_type_is (content_type, "message", "*"))
return TRUE;
-#ifdef APPLICATION_PGP_IS_NO_LONGER_SUPPORTED
- /* The Bat! and possibly a few other broken mailers send application/pgp
- * parts instead of following rfc2015 because they SUCK!!! Since this part
- * is really a text/plain part, we should show it inline.
- */
- if (!header_content_type_is (content_type, "application", "pgp"))
- return TRUE;
-#endif /* APPLICATION_PGP_IS_NO_LONGER_SUPPORTED */
-
/* Otherwise, display it inline if it's "anonymous", and
* as an attachment otherwise.
*/
@@ -610,6 +594,19 @@ mail_part_toggle_displayed (CamelMimePart *part, MailDisplay *md)
g_hash_table_insert (asht, part, GINT_TO_POINTER (state));
}
+static void
+mail_part_set_default_displayed_inline (CamelMimePart *part, MailDisplay *md,
+ gboolean displayed)
+{
+ GHashTable *asht = g_datalist_get_data (md->data, "attachment_states");
+ gint state;
+
+ if (g_hash_table_lookup (asht, part))
+ return;
+
+ state = I_VALID | (displayed ? I_DISPLAYED : 0);
+ g_hash_table_insert (asht, part, GINT_TO_POINTER (state));
+}
static void
attachment_header (CamelMimePart *part, const char *mime_type, MailDisplay *md)
@@ -652,14 +649,6 @@ attachment_header (CamelMimePart *part, const char *mime_type, MailDisplay *md)
g_free (htmlinfo);
}
-#if 0
- /* Describe the click action, if any. */
- if (action) {
- mail_html_write (md->html, md->stream,
- "<br>Click on the icon to %s.", action);
- }
-#endif
-
mail_html_write (md->html, md->stream,
"</font></td></tr><tr><td height=10><table height=10 cellspacing=0 cellpadding=0>"
"<tr><td></td></tr></table></td></tr></table>\n");
@@ -685,7 +674,8 @@ format_mime_part (CamelMimePart *part, MailDisplay *md)
char *mesg;
mesg = e_utf8_from_locale_string (_("Could not parse MIME message. Displaying as source."));
- mail_error_write (md->html, md->stream, "%s", mesg);
+ mail_error_write (md->html, md->stream,
+ "<blockquote>%s</blockquote>", mesg);
g_free (mesg);
if (mail_content_loaded (wrapper, md, TRUE, NULL, NULL))
handle_text_plain (part, "text/plain", md);
@@ -1103,13 +1093,22 @@ mail_format_get_data_wrapper_text (CamelDataWrapper *wrapper, MailDisplay *mail_
return ba;
}
+static void
+write_hr (MailDisplay *md)
+{
+ mail_html_write (md->html, md->stream,
+ "<table cellspacing=0 cellpadding=10 width=\"100%%\"><tr><td width=\"100%%\">"
+ "<hr noshadow size=1></td></tr></table>\n");
+}
+
/*----------------------------------------------------------------------*
* Mime handling functions
*----------------------------------------------------------------------*/
struct {
char *start;
- char * (*handler) (char *start, CamelMimePart *part, MailDisplay *md);
+ char * (*handler) (char *start, CamelMimePart *part,
+ guint offset, MailDisplay *md);
} text_specials[] = {
{ "-----BEGIN PGP MESSAGE-----\n", try_inline_pgp },
{ "-----BEGIN PGP SIGNED MESSAGE-----\n", try_inline_pgp_sig },
@@ -1118,6 +1117,14 @@ struct {
};
#define NSPECIALS (sizeof (text_specials) / sizeof (*text_specials))
+static void
+write_one_text_plain_chunk (const char *text, int len, MailDisplay *md)
+{
+ mail_html_write (md->html, md->stream, "<table cellspacing=0 cellpadding=10 width=\"100%%\"><tr><td>\n");
+ mail_text_write (md->html, md->stream, "%.*s", len, text);
+ mail_html_write (md->html, md->stream, "</td></tr></table>\n");
+}
+
static gboolean
handle_text_plain (CamelMimePart *part, const char *mime_type,
MailDisplay *md)
@@ -1145,10 +1152,6 @@ handle_text_plain (CamelMimePart *part, const char *mime_type,
if (format && !g_strcasecmp (format, "flowed"))
return handle_text_plain_flowed (text, md);
- mail_html_write (md->html, md->stream,
- "\n<!-- text/plain -->\n"
- "<table cellspacing=0 cellpadding=10 width=\"100%%\"><tr><td>\n");
-
/* Only look for binhex and stuff if this is real text/plain.
* (and not, say, application/mac-binhex40 that mail-identify
* has decided to call text/plain because it starts with English
@@ -1168,12 +1171,10 @@ handle_text_plain (CamelMimePart *part, const char *mime_type,
break;
/* Deal with special case */
- if (start != p) {
- /* the %.*s thing just grabs upto start-p chars; go read ANSI C */
- mail_text_write (md->html, md->stream, "%.*s", start-p, p);
- }
+ if (start != p)
+ write_one_text_plain_chunk (p, start - p, md);
- p = text_specials[i].handler (start, part, md);
+ p = text_specials[i].handler (start, part, start - text, md);
if (p == start) {
/* Oops. That failed. Output this line normally and
* skip over it.
@@ -1185,77 +1186,19 @@ handle_text_plain (CamelMimePart *part, const char *mime_type,
break;
}
p++;
- mail_text_write (md->html, md->stream, "%.*s", p-start, start);
+ write_one_text_plain_chunk (start, p - start, md);
} else if (p)
- mail_html_write (md->html, md->stream, "<hr>");
+ write_hr (md);
}
/* Finish up (or do the whole thing if there were no specials). */
if (p)
- mail_text_write (md->html, md->stream, "%s", p);
+ write_one_text_plain_chunk (p, strlen (p), md);
g_free (text);
- mail_html_write (md->html, md->stream, "</td></tr></table>\n");
return TRUE;
}
-#ifdef APPLICATION_PGP_IS_NO_LONGER_SUPPORTED
-/* This is a special-case hack from broken mailers such as The Bat! */
-static gboolean
-handle_application_pgp (CamelMimePart *part, const char *mime_type,
- MailDisplay *md)
-{
- CamelDataWrapper *wrapper =
- camel_medium_get_content_object (CAMEL_MEDIUM (part));
- const char *format, *xaction;
- CamelMimePart *mime_part;
- CamelContentType *type;
- GByteArray *bytes;
-
- /* Check the format and x-action parameters. */
- type = camel_mime_part_get_content_type (part);
- format = header_content_type_param (type, "format");
- xaction = header_content_type_param (type, "x-action");
-
- /* We don't know how to handle non-text broken-pgp'd mime parts */
- if (g_strcasecmp (format, "text") != 0)
- return FALSE;
-
- bytes = mail_format_get_data_wrapper_text (wrapper, md);
- if (!bytes)
- return FALSE;
-
- mime_part = camel_mime_part_new ();
- if (!g_strcasecmp (xaction, "sign")) {
- camel_mime_part_set_content (mime_part, bytes->data, bytes->len, "text/plain");
- } else {
- CamelStream *ciphertext, *plaintext;
- GByteArray *buffer;
-
- ciphertext = camel_stream_mem_new ();
- camel_stream_write (ciphertext, bytes->data, bytes->len);
- camel_stream_reset (ciphertext);
-
- plaintext = camel_stream_mem_new ();
- decode_pgp (ciphertext, plaintext, md);
- camel_object_unref (CAMEL_OBJECT (ciphertext));
-
- buffer = CAMEL_STREAM_MEM (plaintext)->buffer;
-
- camel_mime_part_set_content (mime_part, buffer->data, buffer->len, "text/plain");
- camel_object_unref (CAMEL_OBJECT (plaintext));
- }
-
- g_byte_array_free (bytes, TRUE);
-
- camel_medium_set_content_object (CAMEL_MEDIUM (part),
- camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)));
- camel_object_unref (CAMEL_OBJECT (mime_part));
-
- return handle_text_plain (part, "text/plain", md);
-}
-#endif /* APPLICATION_PGP_IS_NO_LONGER_SUPPORTED */
-
static gboolean
handle_text_plain_flowed (char *buf, MailDisplay *md)
{
@@ -1336,12 +1279,18 @@ handle_text_plain_flowed (char *buf, MailDisplay *md)
}
static CamelMimePart *
-fake_mime_part_from_data (const char *data, int len, const char *type)
+fake_mime_part_from_data (const char *data, int len, const char *type,
+ guint offset, MailDisplay *md)
{
+ GHashTable *fake_parts = g_datalist_get_data (md->data, "fake_parts");
CamelStream *memstream;
CamelDataWrapper *wrapper;
CamelMimePart *part;
+ part = g_hash_table_lookup (fake_parts, GUINT_TO_POINTER (offset));
+ if (part)
+ return part;
+
memstream = camel_stream_mem_new_with_buffer (data, len);
wrapper = camel_data_wrapper_new ();
camel_data_wrapper_construct_from_stream (wrapper, memstream);
@@ -1351,6 +1300,8 @@ fake_mime_part_from_data (const char *data, int len, const char *type)
camel_medium_set_content_object (CAMEL_MEDIUM (part), wrapper);
camel_object_unref (CAMEL_OBJECT (wrapper));
camel_mime_part_set_disposition (part, "inline");
+
+ g_hash_table_insert (fake_parts, GUINT_TO_POINTER (offset), part);
return part;
}
@@ -1360,229 +1311,118 @@ destroy_part (CamelObject *root, gpointer event_data, gpointer user_data)
camel_object_unref (user_data);
}
-static void
-decode_pgp (CamelStream *ciphertext, CamelStream *plaintext, MailDisplay *md)
-{
- CamelException ex;
-
- camel_exception_init (&ex);
-
- /* FIXME: multipart parts */
- if (g_datalist_get_data (md->data, "show_pgp")) {
- CamelPgpContext *ctx;
-
- ctx = camel_pgp_context_new (session, mail_config_get_pgp_type (),
- mail_config_get_pgp_path ());
-
- if (ctx) {
- camel_pgp_decrypt (ctx, ciphertext, plaintext, &ex);
- camel_object_unref (CAMEL_OBJECT (ctx));
- camel_stream_reset (plaintext);
- } else {
- camel_exception_setv (&ex, CAMEL_EXCEPTION_SYSTEM,
- _("No GPG/PGP program configured."));
- }
-
- if (!camel_exception_is_set (&ex))
- return;
- }
-
- mail_html_write (md->html, md->stream,
- "<table><tr valign=top><td>"
- "<a href=\"x-evolution-decode-pgp:\">"
- "<img src=\"%s\"></a></td><td>",
- get_url_for_icon ("gnome-lockscreen.png", md));
-
- if (camel_exception_is_set (&ex)) {
- char *str;
-
- str = e_utf8_from_locale_string (_("Encrypted message not displayed"));
- mail_html_write (md->html, md->stream, "%s<br><br>\n", str);
- g_free (str);
-
- str = e_utf8_from_locale_string (camel_exception_get_description (&ex));
- mail_error_write (md->html, md->stream, "%s", str);
- camel_exception_clear (&ex);
- g_free (str);
- } else {
- char *str1, *str2;
-
- str1 = e_utf8_from_locale_string (_("Encrypted message"));
- str2 = e_utf8_from_locale_string (_("Click icon to decrypt."));
- mail_html_write (md->html, md->stream, "%s<br><br>\n%s",
- str1, str2);
- g_free (str1);
- g_free (str2);
- }
-
- mail_html_write (md->html, md->stream, "</td></tr></table>");
-}
-
static char *
-try_inline_pgp (char *start, CamelMimePart *part, MailDisplay *md)
+try_inline_pgp (char *start, CamelMimePart *mime_part,
+ guint offset, MailDisplay *md)
{
- CamelStream *ciphertext, *plaintext;
- GByteArray *buffer;
+ CamelMimePart *part;
+ CamelMultipart *multipart;
char *end;
-
+
end = strstr (start, "-----END PGP MESSAGE-----");
if (!end)
return start;
-
- end += strlen ("-----END PGP MESSAGE-----") - 1;
-
- mail_html_write (md->html, md->stream, "<hr>");
-
- ciphertext = camel_stream_mem_new ();
- camel_stream_write (ciphertext, start, end - start);
- camel_stream_reset (ciphertext);
-
- plaintext = camel_stream_mem_new ();
- decode_pgp (ciphertext, plaintext, md);
- camel_object_unref (CAMEL_OBJECT (ciphertext));
-
- buffer = CAMEL_STREAM_MEM (plaintext)->buffer;
- if (buffer && buffer->len) {
- mail_html_write (md->html, md->stream,
- "<table width=\"100%%\" border=2 "
- "cellpadding=4><tr><td>");
- mail_text_write (md->html, md->stream, "%.*s", buffer->len, buffer->data);
- mail_html_write (md->html, md->stream, "</td></tr></table>");
- }
-
- camel_object_unref (CAMEL_OBJECT (plaintext));
-
- return end;
-}
-static void
-mail_write_authenticity (MailDisplay *md, CamelCipherValidity *valid)
-{
- char *str;
-
- /* Now display the "seal-of-authenticity" or something... */
- if (valid && camel_cipher_validity_get_valid (valid)) {
- str = e_utf8_from_locale_string (
- _("This message is digitally signed and "
- "has been found to be authentic."));
- mail_html_write (md->html, md->stream,
- "<hr>\n<table><tr valign=top>"
- "<td><img src=\"%s\"></td>"
- "<td><font size=-1>%s<br><br>",
- get_url_for_icon (EVOLUTION_ICONSDIR "/pgp-signature-ok.png", md),
- str);
- g_free (str);
- } else {
- str = e_utf8_from_locale_string (
- _("This message is digitally signed but can "
- "not be proven to be authentic."));
- mail_html_write (md->html, md->stream,
- "<hr>\n<table><tr valign=top>"
- "<td><img src=\"%s\"></td>"
- "<td><font size=-1>%s<br><br>",
- get_url_for_icon (EVOLUTION_ICONSDIR "/pgp-signature-bad.png", md),
- str);
- g_free (str);
- }
+ end += sizeof ("-----END PGP MESSAGE-----") - 1;
- if (valid && camel_cipher_validity_get_description (valid)) {
- mail_error_write (md->html, md->stream, "%s",
- camel_cipher_validity_get_description (valid));
- mail_html_write (md->html, md->stream, "<br><br>");
- }
+ multipart = camel_multipart_new ();
+ camel_data_wrapper_set_mime_type (CAMEL_DATA_WRAPPER (multipart),
+ "multipart/encrypted; "
+ "protocol=\"application/pgp-encrypted\"");
+
+ part = fake_mime_part_from_data ("Version: 1\n",
+ sizeof ("Version: 1\n") - 1,
+ "application/pgp-encrypted",
+ offset + 1, md);
+ camel_multipart_add_part (multipart, part);
+ camel_object_unref (CAMEL_OBJECT (part));
+
+ part = fake_mime_part_from_data (start, end - start + 1,
+ "application/octet-stream",
+ offset, md);
+ camel_multipart_add_part (multipart, part);
+ camel_object_unref (CAMEL_OBJECT (part));
+
+ part = camel_mime_part_new ();
+ camel_medium_set_content_object (CAMEL_MEDIUM (part),
+ CAMEL_DATA_WRAPPER (multipart));
+
+ camel_object_hook_event (CAMEL_OBJECT (md->current_message),
+ "finalize", destroy_part, part);
+
+ write_hr (md);
+ format_mime_part (part, md);
+
+ return end;
}
static char *
-try_inline_pgp_sig (char *start, CamelMimePart *part, MailDisplay *md)
+try_inline_pgp_sig (char *start, CamelMimePart *mime_part,
+ guint offset, MailDisplay *md)
{
- CamelCipherValidity *valid = NULL;
- CamelPgpContext *context;
- char *msg_start, *pgp_start, *sig_start, *sig_end;
-
- pgp_start = strstr (start, "-----BEGIN PGP SIGNED MESSAGE-----");
- if (pgp_start) {
- /* skip over -----BEGIN PGP SIGNED MESSAGE----- */
- msg_start = strchr (pgp_start, '\n');
- if (!msg_start++)
- return start;
-
- /* skip over Hash: header */
- msg_start = strchr (msg_start, '\n');
- if (!msg_start++)
- return start;
- } else {
- /* Some MUAs don't enclose the signed text in
- -----BEGIN PGP SIGNED MESSAGE----- */
- msg_start = start;
- }
-
- /* find the beginning of the signature block */
- sig_start = strstr (msg_start, "-----BEGIN PGP SIGNATURE-----");
- if (!sig_start)
+ CamelMimePart *part;
+ CamelMultipart *multipart;
+ char *msg_start, *msg_end, *sig_start, *sig_end;
+ CamelContentType *type;
+ char *type_str;
+
+ /* We know start points to "-----BEGIN PGP SIGNED MESSAGE-----" */
+ msg_start = start + sizeof ("-----BEGIN PGP SIGNED MESSAGE-----") - 1;
+ if (*msg_start++ != '\n')
return start;
-
- /* find the end of the pgp signature block */
+ /* Skip 'One or more "Hash" Armor Headers' followed by
+ * 'Exactly one empty line'.
+ */
+ msg_start = strstr (msg_start, "\n\n");
+ if (!msg_start)
+ return start;
+ msg_start += 2;
+ msg_end = strstr (msg_start, "-----BEGIN PGP SIGNATURE-----");
+ if (!msg_end)
+ return start;
+ msg_end--;
+
+ sig_start = msg_end;
sig_end = strstr (sig_start, "-----END PGP SIGNATURE-----");
if (!sig_end)
return start;
-
- sig_end += strlen ("-----END PGP SIGNATURE-----") + 1;
-
- mail_html_write (md->html, md->stream, "<hr>");
-
- context = camel_pgp_context_new (session, mail_config_get_pgp_type (),
- mail_config_get_pgp_path ());
-
- if (context) {
- CamelMimeFilterCharset *charset_filter;
- CamelStreamFilter *filtered_stream;
- CamelStream *ciphertext;
- CamelContentType *type;
- const char *charset;
- CamelException *ex;
-
- ex = camel_exception_new ();
-
- ciphertext = camel_stream_mem_new ();
-
- type = camel_mime_part_get_content_type (part);
- charset = header_content_type_param (type, "charset");
- if (!charset)
- charset = mail_config_get_default_charset ();
-
- filtered_stream = camel_stream_filter_new_with_stream (ciphertext);
- charset_filter = camel_mime_filter_charset_new_convert ("utf-8", charset);
- if (charset_filter) {
- camel_stream_filter_add (filtered_stream, CAMEL_MIME_FILTER (charset_filter));
- camel_object_unref (CAMEL_OBJECT (charset_filter));
- }
-
- camel_stream_write (CAMEL_STREAM (filtered_stream), pgp_start, sig_end - pgp_start);
- camel_stream_flush (CAMEL_STREAM (filtered_stream));
- camel_object_unref (CAMEL_OBJECT (filtered_stream));
-
- camel_stream_reset (ciphertext);
-
- valid = camel_pgp_verify (context, ciphertext, NULL, ex);
- camel_object_unref (CAMEL_OBJECT (ciphertext));
- camel_object_unref (CAMEL_OBJECT (context));
-
- camel_exception_free (ex);
- }
-
- mail_text_write (md->html, md->stream, "%.*s", sig_start - msg_start, msg_start);
-
- mail_write_authenticity (md, valid);
-
- mail_html_write (md->html, md->stream, "</font></td></table>");
-
- camel_cipher_validity_free (valid);
-
+ sig_end += sizeof ("-----END PGP SIGNATURE-----") - 1;
+
+ multipart = camel_multipart_new ();
+ camel_data_wrapper_set_mime_type (CAMEL_DATA_WRAPPER (multipart),
+ "multipart/signed; micalg=pgp-md5"
+ "; x-inline-pgp-hack=true");
+
+ type = camel_mime_part_get_content_type (mime_part);
+ type_str = header_content_type_format (type);
+ part = fake_mime_part_from_data (msg_start, msg_end - msg_start,
+ type_str, offset, md);
+ g_free (type_str);
+ camel_multipart_add_part (multipart, part);
+ camel_object_unref (CAMEL_OBJECT (part));
+
+ part = fake_mime_part_from_data (sig_start, sig_end - sig_start,
+ "application/pgp-signature",
+ offset + 1, md);
+ camel_multipart_add_part (multipart, part);
+ camel_object_unref (CAMEL_OBJECT (part));
+
+ part = camel_mime_part_new ();
+ camel_medium_set_content_object (CAMEL_MEDIUM (part),
+ CAMEL_DATA_WRAPPER (multipart));
+
+ camel_object_hook_event (CAMEL_OBJECT (md->current_message),
+ "finalize", destroy_part, part);
+
+ write_hr (md);
+ format_mime_part (part, md);
+
return sig_end;
}
static char *
-try_uudecoding (char *start, CamelMimePart *mime_part, MailDisplay *md)
+try_uudecoding (char *start, CamelMimePart *mime_part,
+ guint offset, MailDisplay *md)
{
int mode, len, state = 0;
char *filename, *estart, *p, *out, uulen = 0;
@@ -1613,21 +1453,23 @@ try_uudecoding (char *start, CamelMimePart *mime_part, MailDisplay *md)
out = g_malloc (p - estart);
len = uudecode_step (estart, p - estart, out, &state, &save, &uulen);
- part = fake_mime_part_from_data (out, len, "application/octet-stream");
+ part = fake_mime_part_from_data (out, len, "application/octet-stream",
+ offset, md);
g_free (out);
camel_mime_part_set_filename (part, filename);
g_free (filename);
camel_object_hook_event (CAMEL_OBJECT (md->current_message),
"finalize", destroy_part, part);
- mail_html_write (md->html, md->stream, "<hr>");
+ write_hr (md);
format_mime_part (part, md);
return p + 4;
}
static char *
-try_inline_binhex (char *start, CamelMimePart *mime_part, MailDisplay *md)
+try_inline_binhex (char *start, CamelMimePart *mime_part,
+ guint offset, MailDisplay *md)
{
char *p;
CamelMimePart *part;
@@ -1644,11 +1486,12 @@ try_inline_binhex (char *start, CamelMimePart *mime_part, MailDisplay *md)
p += 2;
part = fake_mime_part_from_data (start, p - start,
- "application/mac-binhex40");
+ "application/mac-binhex40",
+ offset, md);
camel_object_hook_event (CAMEL_OBJECT (md->current_message),
"finalize", destroy_part, part);
- mail_html_write (md->html, md->stream, "<hr>");
+ write_hr (md);
format_mime_part (part, md);
return p;
@@ -1855,9 +1698,7 @@ handle_multipart_mixed (CamelMimePart *part, const char *mime_type,
nparts = camel_multipart_get_number (mp);
for (i = 0; i < nparts; i++) {
if (i != 0 && output)
- mail_html_write (md->html, md->stream,
- "<table cellspacing=0 cellpadding=10 width=\"100%%\"><tr><td width=\"100%%\">"
- "<hr noshadow size=1></td></tr></table>\n");
+ write_hr (md);
part = camel_multipart_get_part (mp, i);
@@ -1906,52 +1747,105 @@ static gboolean
handle_multipart_signed (CamelMimePart *part, const char *mime_type,
MailDisplay *md)
{
+ CamelMimePart *subpart;
CamelDataWrapper *wrapper;
CamelMultipart *mp;
- CamelException *ex;
gboolean output = FALSE;
- CamelCipherValidity *valid;
int nparts, i;
-
+
wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (part));
g_return_val_if_fail (CAMEL_IS_MULTIPART (wrapper), FALSE);
- ex = camel_exception_new ();
-
- if (camel_pgp_mime_is_rfc2015_signed (part)) {
- valid = mail_crypto_pgp_mime_part_verify (part, ex);
- } else {
- camel_exception_free (ex);
- return handle_multipart_mixed (part, mime_type, md);
- }
-
- if (!valid) {
- camel_exception_free (ex);
- return handle_multipart_mixed (part, mime_type, md);
- }
-
- camel_exception_free (ex);
-
- /* now display all the subparts (there should be only 1) *except* the signature (last part) */
+ /* Display all the subparts (there should be only 1)
+ * except the signature (last part).
+ */
mp = CAMEL_MULTIPART (wrapper);
nparts = camel_multipart_get_number (mp);
for (i = 0; i < nparts - 1; i++) {
if (i != 0 && output)
- mail_html_write (md->html, md->stream,
- "<table cellspacing=0 cellpadding=10 width=\"100%%\"><tr><td width=\"100%%\">"
- "<hr noshadow size=1></td></tr></table>\n");
+ write_hr (md);
- part = camel_multipart_get_part (mp, i);
+ subpart = camel_multipart_get_part (mp, i);
- output = format_mime_part (part, md);
+ output = format_mime_part (subpart, md);
+ }
+
+ subpart = camel_multipart_get_part (mp, i);
+ mail_part_set_default_displayed_inline (subpart, md, FALSE);
+
+ if (!mail_part_is_displayed_inline (subpart, md)) {
+ char *url;
+
+ /* Write out the click-for-info object */
+ url = g_strdup_printf ("signature:%p/%lu", subpart,
+ (unsigned long)time (NULL));
+ add_url ("part_urls", url, subpart, md);
+ mail_html_write (md->html, md->stream,
+ "<br><table cellspacing=0 cellpadding=0>"
+ "<tr><td><table width=10 cellspacing=0 cellpadding=0><tr><td></td></tr></table></td>"
+ "<td><object classid=\"%s\"></object></td>"
+ "<td><table width=3 cellspacing=0 cellpadding=0><tr><td></td></tr></table></td>"
+ "<td><font size=-1>", url);
+
+ mail_html_write (md->html, md->stream, "%s",
+ U_("This message is digitally signed. "
+ "Click the lock icon for more information."));
+
+ mail_html_write (md->html, md->stream,
+ "</font></td></tr><tr><td height=10><table height=10 cellspacing=0 cellpadding=0>"
+ "<tr><td></td></tr></table></td></tr></table>\n");
+ } else {
+ CamelCipherValidity *valid = NULL;
+ CamelException ex;
+ const char *message = NULL;
+ gboolean good = FALSE;
+
+ /* Write out the verification results */
+
+ camel_exception_init (&ex);
+ if (camel_pgp_mime_is_rfc2015_signed (part)) {
+ valid = mail_crypto_pgp_mime_part_verify (part, &ex);
+ if (!valid) {
+ message = camel_exception_get_description (&ex);
+ } else {
+ good = camel_cipher_validity_get_valid (valid);
+ message = camel_cipher_validity_get_description (valid);
+ }
+ } else
+ message = U_("Evolution does not recognize this type of signed message.");
+
+ if (good) {
+ mail_html_write (md->html, md->stream,
+ "<table><tr valign=top>"
+ "<td><img src=\"%s\"></td>"
+ "<td>%s<br><br>",
+ get_url_for_icon (EVOLUTION_ICONSDIR "/pgp-signature-ok.png", md),
+ U_("This message is digitally signed and "
+ "has been found to be authentic."));
+ } else {
+ mail_html_write (md->html, md->stream,
+ "<table><tr valign=top>"
+ "<td><img src=\"%s\"></td>"
+ "<td>%s<br><br>",
+ get_url_for_icon (EVOLUTION_ICONSDIR "/pgp-signature-bad.png", md),
+ U_("This message is digitally signed but can "
+ "not be proven to be authentic."));
+ }
+
+ if (message) {
+ mail_html_write (md->html, md->stream,
+ "<font size=-1 %s>",
+ good ? "" : "color=red");
+ mail_text_write (md->html, md->stream, "%s", message);
+ mail_html_write (md->html, md->stream, "</font>");
+ }
+
+ mail_html_write (md->html, md->stream, "</td></tr></table>");
+ camel_exception_clear (&ex);
+ camel_cipher_validity_free (valid);
}
-
- mail_write_authenticity (md, valid);
- camel_cipher_validity_free (valid);
-
- mail_html_write (md->html, md->stream, "</font></td></table>");
return TRUE;
}