Index: mail/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/mail/ChangeLog,v
retrieving revision 1.3647
diff -u -p -r1.3647 ChangeLog
--- mail/ChangeLog	21 Jun 2005 05:33:47 -0000	1.3647
+++ mail/ChangeLog	24 Jun 2005 08:50:07 -0000
@@ -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-21 Brian Mury <b.mury@ieee.org>
 
 	** See bug #301466.
Index: mail/em-format-html.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-format-html.c,v
retrieving revision 1.78
diff -u -p -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	24 Jun 2005 08:50:13 -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,117 @@ efh_format_secure(EMFormat *emf, CamelSt
 }
 
 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;
@@ -1099,6 +1212,8 @@ static EMFormatHandler type_builtin_tabl
 	{ "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 -p -r1.47 em-format.c
--- mail/em-format.c	19 May 2005 06:06:35 -0000	1.47
+++ mail/em-format.c	24 Jun 2005 08:50:17 -0000
@@ -914,6 +915,8 @@ int em_format_is_attachment(EMFormat *em
 	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 -p -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	24 Jun 2005 08:50:18 -0000
@@ -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, cons
 	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, 
 				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, 
 			}
 			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, 
 				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';
