aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mail/ChangeLog8
-rw-r--r--mail/em-format-html.c125
-rw-r--r--mail/em-format.c2
-rw-r--r--mail/em-inline-filter.c30
4 files changed, 152 insertions, 13 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index c5cbc39e5e..d38c8202c6 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,11 @@
+2005-06-24 Matt Brown <matt@mattb.net.nz>
+
+ * em-inline-filter.c: implement extraction of inline signed/encrypted pgp
+ parts and package them into x-inlinepgp-signed/x-inline-pgp-encrypted
+ parts.
+ * em-format-html.c: Formatters to verify/decrypt and then display the
+ parts generated by the inline filter.
+
2005-06-25 Not Zed <NotZed@Ximian.com>
** See bug #307398
diff --git a/mail/em-format-html.c b/mail/em-format-html.c
index ad26fbacad..95190101ce 100644
--- a/mail/em-format-html.c
+++ b/mail/em-format-html.c
@@ -48,6 +48,9 @@
#include <camel/camel-mime-filter.h>
#include <camel/camel-mime-filter-tohtml.h>
#include <camel/camel-mime-filter-enriched.h>
+#include <camel/camel-mime-filter-pgp.h>
+#include <camel/camel-mime-filter-basic.h>
+#include <camel/camel-gpg-context.h>
#include <camel/camel-cipher-context.h>
#include <camel/camel-multipart.h>
#include <camel/camel-stream-mem.h>
@@ -659,6 +662,117 @@ efh_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, Camel
}
static void
+efh_inlinepgp_signed(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *ipart, EMFormatHandler *info)
+{
+
+ CamelCipherContext *cipher;
+ CamelCipherValidity *valid;
+ CamelException *ex;
+ CamelMimePart *opart=NULL;
+ CamelContentType *type;
+ CamelStreamFilter *filtered_stream;
+ CamelStream *ostream;
+ CamelDataWrapper *dw;
+ CamelMimeFilterPgp *pgp_filter;
+
+ /* Check we're passed valid input */
+ type = camel_mime_part_get_content_type(ipart);
+ if (!camel_content_type_is(type, "application", "x-inlinepgp-signed")) {
+ em_format_format_error((EMFormat *)efh, stream,
+ "Invalid mime type passed to inline PGP format");
+ return;
+ }
+
+ ex = camel_exception_new();
+ cipher = camel_gpg_context_new (((EMFormat *)efh)->session);
+ /* Verify the signature of the message */
+ valid = camel_cipher_verify(cipher, ipart, ex);
+ if (!valid) {
+ /* Display an error */
+ em_format_format_error((EMFormat *)efh, stream, ex->desc ? ex->desc :
+ _("Unknown error verifying signed messaage"));
+ camel_exception_free(ex);
+ camel_object_unref(cipher);
+ return;
+ }
+
+ /* Setup output stream */
+ ostream = camel_stream_mem_new();
+ filtered_stream = camel_stream_filter_new_with_stream(ostream);
+
+ /* Add PGP header / footer filter */
+ pgp_filter = (CamelMimeFilterPgp *)camel_mime_filter_pgp_new();
+ camel_stream_filter_add(filtered_stream, (CamelMimeFilter *)pgp_filter);
+ camel_object_unref(pgp_filter);
+
+ /* Pass through the filters that have been setup */
+ dw = camel_medium_get_content_object((CamelMedium *)ipart);
+ camel_data_wrapper_decode_to_stream(dw, (CamelStream *)filtered_stream);
+ camel_stream_flush((CamelStream *)filtered_stream);
+ camel_object_unref(filtered_stream);
+
+ /* Extract new part and display it as text/plain */
+ dw = camel_data_wrapper_new();
+ camel_data_wrapper_construct_from_stream(dw, ostream);
+ camel_data_wrapper_set_mime_type(dw, "text/plain");
+ opart = camel_mime_part_new();
+ camel_medium_set_content_object((CamelMedium *)opart, dw);
+ camel_mime_part_set_content_type(opart, "text/plain");
+
+ /* Pass it off to the real formatter */
+ em_format_format_secure((EMFormat *)efh, stream, opart, valid);
+
+ /* Clean Up */
+ camel_object_unref(dw);
+ camel_object_unref(opart);
+ camel_object_unref(ostream);
+ camel_object_unref(cipher);
+ camel_exception_free(ex);
+}
+
+static void
+efh_inlinepgp_encrypted(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *ipart, EMFormatHandler *info)
+{
+ CamelCipherContext *cipher;
+ CamelCipherValidity *valid;
+ CamelException *ex;
+ CamelMimePart *opart;
+ CamelContentType *type;
+
+ /* Check we're passed valid input */
+ type = camel_mime_part_get_content_type(ipart);
+ if (!camel_content_type_is(type, "application", "x-inlinepgp-encrypted")) {
+ em_format_format_error((EMFormat *)efh, stream,
+ "Invalid mime type passed to inline PGP format encrypted");
+ return;
+ }
+
+ cipher = camel_gpg_context_new (((EMFormat *)efh)->session);
+ ex = camel_exception_new();
+ opart = camel_mime_part_new();
+ /* Decrypt the message */
+ valid = camel_cipher_decrypt (cipher, ipart, opart, ex);
+ if (!valid) {
+ /* Display an error */
+ em_format_format_error((EMFormat *)efh, stream, ex->desc ? ex->desc :
+ _("Unknown error decrypting messaage"));
+ camel_exception_free(ex);
+ camel_object_unref(cipher);
+ camel_object_unref(opart);
+ return;
+ }
+
+ /* Pass it off to the real formatter */
+ em_format_format_secure((EMFormat *)efh, stream, opart, valid);
+
+ /* Clean Up */
+ camel_object_unref(opart);
+ camel_object_unref (cipher);
+ camel_exception_free (ex);
+}
+
+
+static void
efh_text_plain(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFormatHandler *info)
{
CamelStreamFilter *filtered_stream;
@@ -671,10 +785,6 @@ efh_text_plain(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFo
int i, count, len;
struct _EMFormatHTMLCache *efhc;
- camel_stream_printf (stream,
- "<div style=\"border: solid #%06x 1px; background-color: #%06x; padding: 10px;\">\n",
- efh->frame_colour & 0xffffff, efh->content_colour & 0xffffff);
-
flags = efh->text_html_flags;
dw = camel_medium_get_content_object((CamelMedium *)part);
@@ -742,10 +852,14 @@ efh_text_plain(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFo
type = camel_mime_part_get_content_type(newpart);
if (camel_content_type_is (type, "text", "*")) {
+ camel_stream_printf (stream,
+ "<div style=\"border: solid #%06x 1px; background-color: #%06x; padding: 10px;\">\n",
+ efh->frame_colour & 0xffffff, efh->content_colour & 0xffffff);
camel_stream_write_string(stream, "<tt>\n");
em_format_format_text((EMFormat *)efh, (CamelStream *)filtered_stream, camel_medium_get_content_object((CamelMedium *)newpart));
camel_stream_flush((CamelStream *)filtered_stream);
camel_stream_write_string(stream, "</tt>\n");
+ camel_stream_write_string(stream, "</div>\n");
} else {
g_string_append_printf(((EMFormat *)efh)->part_id, ".inline.%d", i);
em_format_part((EMFormat *)efh, stream, newpart);
@@ -754,7 +868,6 @@ efh_text_plain(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFo
}
camel_object_unref(filtered_stream);
- camel_stream_write_string(stream, "</div>\n");
}
static void
@@ -1114,6 +1227,8 @@ static EMFormatHandler type_builtin_table[] = {
{ "message/external-body", (EMFormatFunc)efh_message_external },
{ "message/delivery-status", (EMFormatFunc)efh_message_deliverystatus },
{ "multipart/related", (EMFormatFunc)efh_multipart_related },
+ { "application/x-inlinepgp-signed", (EMFormatFunc)efh_inlinepgp_signed },
+ { "application/x-inlinepgp-encrypted", (EMFormatFunc)efh_inlinepgp_encrypted },
/* This is where one adds those busted, non-registered types,
that some idiot mailer writers out there decide to pull out
diff --git a/mail/em-format.c b/mail/em-format.c
index dd7cf1e084..10965148c0 100644
--- a/mail/em-format.c
+++ b/mail/em-format.c
@@ -914,6 +914,8 @@ int em_format_is_attachment(EMFormat *emf, CamelMimePart *part)
return !(camel_content_type_is (dw->mime_type, "multipart", "*")
|| camel_content_type_is(dw->mime_type, "application", "x-pkcs7-mime")
|| camel_content_type_is(dw->mime_type, "application", "pkcs7-mime")
+ || camel_content_type_is(dw->mime_type, "application", "x-inlinepgp-signed")
+ || camel_content_type_is(dw->mime_type, "application", "x-inlinepgp-encrypted")
|| (camel_content_type_is (dw->mime_type, "text", "*")
&& camel_mime_part_get_filename(part) == NULL));
}
diff --git a/mail/em-inline-filter.c b/mail/em-inline-filter.c
index 40da981d58..38cd013912 100644
--- a/mail/em-inline-filter.c
+++ b/mail/em-inline-filter.c
@@ -102,6 +102,7 @@ enum {
EMIF_BINHEX,
EMIF_POSTSCRIPT,
EMIF_PGPSIGNED,
+ EMIF_PGPENCRYPTED,
};
const struct {
const char *name;
@@ -112,7 +113,8 @@ const struct {
{ "application/octet-stream", CAMEL_TRANSFER_ENCODING_UUENCODE, },
{ "application/mac-binhex40", CAMEL_TRANSFER_ENCODING_7BIT, },
{ "application/postscript", CAMEL_TRANSFER_ENCODING_7BIT, },
- { "text/plain", CAMEL_TRANSFER_ENCODING_7BIT, 1, },
+ { "application/x-inlinepgp-signed", CAMEL_TRANSFER_ENCODING_DEFAULT, },
+ { "application/x-inlinepgp-encrypted", CAMEL_TRANSFER_ENCODING_DEFAULT, },
};
static void
@@ -124,12 +126,16 @@ emif_add_part(EMInlineFilter *emif, const char *data, int len)
CamelMimePart *part;
const char *mimetype;
- if (emif->state == EMIF_PLAIN)
+ if (emif->state == EMIF_PLAIN || emif->state == EMIF_PGPSIGNED || emif->state == EMIF_PGPENCRYPTED)
type = emif->base_encoding;
else
type = emif_types[emif->state].type;
g_byte_array_append(emif->data, data, len);
+ /* check the part will actually have content */
+ if (emif->data->len <= 0) {
+ return;
+ }
mem = camel_stream_mem_new_with_byte_array(emif->data);
emif->data = g_byte_array_new();
@@ -223,17 +229,18 @@ emif_scan(CamelMimeFilter *f, char *in, size_t len, int final)
emif_add_part(emif, data_start, start-data_start);
data_start = start;
emif->state = EMIF_POSTSCRIPT;
-#if 0
-/* This should be hooked in once someone can work out how to handle it.
- Maybe we need a multipart_gpg_inline_signed or some crap, if it
- can't be converted to a real multipart/signed */
} else if (strncmp(start, "-----BEGIN PGP SIGNED MESSAGE-----", 34) == 0) {
inptr[-1] = '\n';
emif_add_part(emif, data_start, start-data_start);
data_start = start;
emif->state = EMIF_PGPSIGNED;
-#endif
+ } else if (strncmp(start, "-----BEGIN PGP MESSAGE-----", 27) == 0) {
+ inptr[-1] = '\n';
+ emif_add_part(emif, data_start, start-data_start);
+ data_start = start;
+ emif->state = EMIF_PGPENCRYPTED;
}
+
break;
case EMIF_UUENC:
if (strcmp(start, "end") == 0) {
@@ -279,7 +286,6 @@ emif_scan(CamelMimeFilter *f, char *in, size_t len, int final)
}
break;
case EMIF_PGPSIGNED:
- /* This is currently a noop - it just turns it into a text part */
if (strcmp(start, "-----END PGP SIGNATURE-----") == 0) {
inptr[-1] = '\n';
emif_add_part(emif, data_start, inptr-data_start);
@@ -287,6 +293,14 @@ emif_scan(CamelMimeFilter *f, char *in, size_t len, int final)
emif->state = EMIF_PLAIN;
}
break;
+ case EMIF_PGPENCRYPTED:
+ if (strcmp(start, "-----END PGP MESSAGE-----") == 0) {
+ inptr[-1] = '\n';
+ emif_add_part(emif, data_start, inptr-data_start);
+ data_start = inptr;
+ emif->state = EMIF_PLAIN;
+ }
+ break;
}
inptr[-1] = '\n';