Index: mail/em-format-html.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-format-html.c,v
retrieving revision 1.78
diff -u -r1.78 em-format-html.c
--- mail/em-format-html.c	19 May 2005 06:06:35 -0000	1.78
+++ mail/em-format-html.c	30 May 2005 12:50:39 -0000
@@ -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>
@@ -644,6 +647,199 @@
 }
 
 static void
+efh_inlinepgp_signed(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFormatHandler *info)
+{
+	
+	CamelCipherContext *cipher;
+	CamelCipherValidity *valid;
+	CamelException *ex;
+	CamelMimePart *ipart=NULL;
+	CamelMimePart *opart=NULL;
+	CamelContentType *type;
+	CamelStreamFilter *filtered_stream;
+	CamelStream *ostream;
+	CamelDataWrapper *dw;
+	CamelTransferEncoding encoding;
+	
+	type = camel_mime_part_get_content_type(part);
+	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;
+	}
+
+	/* Setup output streams */
+	ostream = camel_stream_mem_new();
+	filtered_stream = camel_stream_filter_new_with_stream(ostream);
+
+	/* Check transfer encoding */
+	encoding = camel_mime_part_get_encoding(part);
+	if (encoding == CAMEL_TRANSFER_ENCODING_QUOTEDPRINTABLE) {
+		CamelMimeFilter *filter;
+		char *ptype;
+		/* Filter it to get rid of QP stuff */
+		filter = (CamelMimeFilter *)camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_QP_DEC);
+		camel_stream_filter_add(filtered_stream, filter);
+		camel_object_unref(filter);
+		dw = camel_medium_get_content_object((CamelMedium *)part);
+		ptype = camel_data_wrapper_get_mime_type(dw);
+		camel_data_wrapper_decode_to_stream(dw, (CamelStream *)filtered_stream);
+		camel_stream_flush((CamelStream *)filtered_stream);
+		camel_object_unref(filtered_stream);
+		
+		/* Extract decoded part */
+		camel_data_wrapper_construct_from_stream(dw, ostream);
+		ipart = camel_mime_part_new();
+		camel_data_wrapper_set_mime_type(dw, ptype);
+		camel_medium_set_content_object((CamelMedium *)ipart, dw);
+		camel_object_unref(ostream);
+		ostream = camel_stream_mem_new();
+		filtered_stream = camel_stream_filter_new_with_stream(ostream);
+	} else {
+		ipart = part;
+	}
+		
+	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) {
+		/* Get content of the part */
+		CamelMimeFilterPgp *pgp_filter;
+		dw = camel_medium_get_content_object((CamelMedium *)ipart);
+		/* 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);
+	} else {
+		if (!valid) {
+			/* Display an error */
+			em_format_format_error((EMFormat *)efh, stream, ex->desc ? ex->desc : 
+					_("Unknown error verifying signed messaage"));
+			return;
+		}		
+	}
+	
+	/* Pass through the filters that have been setup */
+	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 */ 
+	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);	
+	em_format_format_secure((EMFormat *)efh, stream, opart, valid);
+
+	/* Clean Up */
+	if (encoding == CAMEL_TRANSFER_ENCODING_QUOTEDPRINTABLE)
+		camel_object_unref(ipart);
+	camel_object_unref(ostream);
+	camel_object_unref(opart);
+	camel_object_unref(cipher);
+	camel_exception_free(ex);
+	
+}
+
+static void
+efh_inlinepgp_encrypted(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFormatHandler *info)
+{
+	
+	CamelCipherContext *cipher;
+	CamelCipherValidity *valid;
+	CamelException *ex;
+	CamelMimePart *ipart=NULL;
+	CamelMimePart *opart=NULL;
+	CamelMimePart *tpart=NULL;
+	CamelContentType *type;
+	CamelStreamFilter *filtered_stream;
+	CamelStream *ostream;
+	CamelDataWrapper *dw;
+	CamelTransferEncoding encoding;
+	char *mime_type = NULL;
+    
+	type = camel_mime_part_get_content_type(part);
+	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;
+	}
+
+	/* Setup output streams */
+	ostream = camel_stream_mem_new();
+	filtered_stream = camel_stream_filter_new_with_stream(ostream);
+
+	/* Check transfer encoding */
+	encoding = camel_mime_part_get_encoding(part);
+	if (encoding == CAMEL_TRANSFER_ENCODING_QUOTEDPRINTABLE) {
+		CamelMimeFilter *filter;
+		char *ptype;
+		/* Filter it to get rid of QP stuff */
+		filter = (CamelMimeFilter *)camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_QP_DEC);
+		camel_stream_filter_add(filtered_stream, filter);
+		camel_object_unref(filter);
+		dw = camel_medium_get_content_object((CamelMedium *)part);
+		ptype = camel_data_wrapper_get_mime_type(dw);
+		camel_data_wrapper_decode_to_stream(dw, (CamelStream *)filtered_stream);
+		camel_stream_flush((CamelStream *)filtered_stream);
+		camel_object_unref(filtered_stream);
+		
+		/* Extract decoded part */
+		camel_data_wrapper_construct_from_stream(dw, ostream);
+		ipart = camel_mime_part_new();
+		camel_data_wrapper_set_mime_type(dw, ptype);
+		camel_medium_set_content_object((CamelMedium *)ipart, dw);
+		camel_object_unref(ostream);
+		ostream = camel_stream_mem_new();
+		filtered_stream = camel_stream_filter_new_with_stream(ostream);
+	} else {
+		ipart = part;
+	}
+	
+	ex = camel_exception_new ();
+	cipher = camel_gpg_context_new (((EMFormat *)efh)->session);
+	/* Pass in a datawrapper as we're getting raw data not a mime part back */
+	dw = (CamelMimePart *)camel_data_wrapper_new ();
+	valid = camel_cipher_decrypt (cipher, ipart, dw, ex);	
+	/* Check for errors before proceeding */
+	if (!valid) {
+		/* Display an error */
+		em_format_format_error((EMFormat *)efh, stream, ex->desc ? ex->desc : 
+				_("Unknown error decrypting messaage"));
+		return;
+	}
+
+	/* Convert returned data to a mime type now */
+	tpart = camel_mime_part_new();
+	camel_medium_set_content_object((CamelMedium *)tpart, dw);
+	camel_object_unref(dw);
+
+	/* Snoop the new part to determine its type */
+	mime_type = em_utils_snoop_type(tpart);
+	/* I'm sure there is a more efficient way of achieving this... but I can't
+	 * figure it out :(
+	 */
+	dw = camel_medium_get_content_object((CamelMedium *)tpart);
+	camel_data_wrapper_set_mime_type(dw, mime_type);
+	opart = camel_mime_part_new();
+	camel_medium_set_content_object((CamelMedium *)opart, dw);
+	camel_object_unref(tpart);
+
+	em_format_format_secure((EMFormat *)efh, stream, opart, valid);
+
+	/* Clean Up */
+	if (encoding == CAMEL_TRANSFER_ENCODING_QUOTEDPRINTABLE)
+		camel_object_unref(ipart);
+	camel_object_unref(ostream);
+	camel_object_unref (tpart);
+	camel_object_unref (cipher);
+	camel_exception_free (ex);
+
+}
+
+	
+static void
 efh_text_plain(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFormatHandler *info)
 {
 	CamelStreamFilter *filtered_stream;
@@ -656,10 +852,6 @@
 	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);
@@ -727,10 +919,14 @@
 
 		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);
@@ -739,7 +935,6 @@
 	}
 
 	camel_object_unref(filtered_stream);
-	camel_stream_write_string(stream, "</div>\n");
 }
 
 static void
@@ -1099,6 +1294,8 @@
 	{ "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
Index: mail/em-format.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-format.c,v
retrieving revision 1.47
diff -u -r1.47 em-format.c
--- mail/em-format.c	19 May 2005 06:06:35 -0000	1.47
+++ mail/em-format.c	30 May 2005 12:50:41 -0000
@@ -604,6 +604,7 @@
 
 	dw = camel_medium_get_content_object((CamelMedium *)part);
 	mime_type = camel_data_wrapper_get_mime_type(dw);
+    printf("In format_part, type is %s\n", mime_type);
 	if (mime_type) {
 		camel_strdown(mime_type);
 		em_format_part_as(emf, stream, part, mime_type);
@@ -914,6 +915,8 @@
 	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));
 }
Index: mail/em-inline-filter.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-inline-filter.c,v
retrieving revision 1.8
diff -u -r1.8 em-inline-filter.c
--- mail/em-inline-filter.c	28 Feb 2005 04:51:26 -0000	1.8
+++ mail/em-inline-filter.c	30 May 2005 12:50:42 -0000
@@ -102,6 +102,7 @@
 	EMIF_BINHEX,
 	EMIF_POSTSCRIPT,
 	EMIF_PGPSIGNED,
+	EMIF_PGPENCRYPTED,
 };
 const struct {
 	const char *name;
@@ -112,7 +113,8 @@
 	{ "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 @@
 	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_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 @@
 			}
 			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->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';
