[evolution] Bug #687670 - Signing with both pgp and S/MIME shows only one signature



commit abdefcaa26ca7116bfc5b7aaa9ee2f04de533ecb
Author: Milan Crha <mcrha redhat com>
Date:   Wed Nov 21 17:57:07 2012 +0100

    Bug #687670 - Signing with both pgp and S/MIME shows only one signature

 em-format/e-mail-formatter-attachment.c    |   20 ++++--
 em-format/e-mail-formatter-print-headers.c |   24 +++---
 em-format/e-mail-formatter-secure-button.c |  101 +++++++++++++++++++---------
 em-format/e-mail-part.c                    |   83 +++++++++++++++++++----
 em-format/e-mail-part.h                    |   14 +++-
 mail/em-utils.c                            |   12 +++-
 6 files changed, 187 insertions(+), 67 deletions(-)
---
diff --git a/em-format/e-mail-formatter-attachment.c b/em-format/e-mail-formatter-attachment.c
index ffe1634..62fa65e 100644
--- a/em-format/e-mail-formatter-attachment.c
+++ b/em-format/e-mail-formatter-attachment.c
@@ -140,11 +140,21 @@ emfe_attachment_format (EMailFormatterExtension *extension,
 	if ((context->mode == E_MAIL_FORMATTER_MODE_NORMAL) ||
 	    (context->mode == E_MAIL_FORMATTER_MODE_PRINTING) ||
 	    (context->mode == E_MAIL_FORMATTER_MODE_ALL_HEADERS)) {
-		if (part->validity) {
-			e_attachment_set_signed (
-				empa->attachment, part->validity->sign.status);
-			e_attachment_set_encrypted (
-				empa->attachment, part->validity->encrypt.status);
+		if (part->validities) {
+			GSList *lst;
+
+			for (lst = part->validities; lst; lst = lst->next) {
+				EMailPartValidityPair *pair = lst->data;
+
+				if (!pair)
+					continue;
+
+				if ((pair->validity_type & E_MAIL_PART_VALIDITY_SIGNED) != 0)
+					e_attachment_set_signed (empa->attachment, pair->validity->sign.status);
+
+				if ((pair->validity_type & E_MAIL_PART_VALIDITY_ENCRYPTED) != 0)
+					e_attachment_set_encrypted (empa->attachment, pair->validity->encrypt.status);
+			}
 		}
 
 		store = find_attachment_store (context->parts, part->id);
diff --git a/em-format/e-mail-formatter-print-headers.c b/em-format/e-mail-formatter-print-headers.c
index a74b94f..a16264b 100644
--- a/em-format/e-mail-formatter-print-headers.c
+++ b/em-format/e-mail-formatter-print-headers.c
@@ -136,31 +136,31 @@ emfpe_headers_format (EMailFormatterExtension *extension,
 		if (mail_part == NULL)
 			continue;
 
-		if (mail_part->validity_type == 0)
+		if (!mail_part->validities)
 			continue;
 
 		if (!g_str_has_prefix (mail_part->id, part_id_prefix))
 			continue;
 
-		if ((mail_part->validity_type & E_MAIL_PART_VALIDITY_PGP) &&
-		    (mail_part->validity_type & E_MAIL_PART_VALIDITY_SIGNED)) {
+		if (e_mail_part_get_validity (mail_part, E_MAIL_PART_VALIDITY_PGP | E_MAIL_PART_VALIDITY_SIGNED)) {
 			g_string_append (tmp, _("GPG signed"));
 		}
-		if ((mail_part->validity_type & E_MAIL_PART_VALIDITY_PGP) &&
-		    (mail_part->validity_type & E_MAIL_PART_VALIDITY_ENCRYPTED)) {
-			if (tmp->len > 0) g_string_append (tmp, ", ");
+
+		if (e_mail_part_get_validity (mail_part, E_MAIL_PART_VALIDITY_PGP | E_MAIL_PART_VALIDITY_ENCRYPTED)) {
+			if (tmp->len > 0)
+				g_string_append (tmp, ", ");
 			g_string_append (tmp, _("GPG encrpyted"));
 		}
-		if ((mail_part->validity_type & E_MAIL_PART_VALIDITY_SMIME) &&
-		    (mail_part->validity_type & E_MAIL_PART_VALIDITY_SIGNED)) {
 
-			if (tmp->len > 0) g_string_append (tmp, ", ");
+		if (e_mail_part_get_validity (mail_part, E_MAIL_PART_VALIDITY_SMIME | E_MAIL_PART_VALIDITY_SIGNED)) {
+			if (tmp->len > 0)
+				g_string_append (tmp, ", ");
 			g_string_append (tmp, _("S/MIME signed"));
 		}
-		if ((mail_part->validity_type & E_MAIL_PART_VALIDITY_SMIME) &&
-		    (mail_part->validity_type & E_MAIL_PART_VALIDITY_ENCRYPTED)) {
 
-			if (tmp->len > 0) g_string_append (tmp, ", ");
+		if (e_mail_part_get_validity (mail_part, E_MAIL_PART_VALIDITY_SMIME | E_MAIL_PART_VALIDITY_ENCRYPTED)) {
+			if (tmp->len > 0)
+				g_string_append (tmp, ", ");
 			g_string_append (tmp, _("S/MIME encrpyted"));
 		}
 
diff --git a/em-format/e-mail-formatter-secure-button.c b/em-format/e-mail-formatter-secure-button.c
index d95670c..8d6df16 100644
--- a/em-format/e-mail-formatter-secure-button.c
+++ b/em-format/e-mail-formatter-secure-button.c
@@ -267,29 +267,31 @@ format_cert_infos (GQueue *cert_infos,
 
 static void
 secure_button_clicked_cb (GtkWidget *widget,
-                          EMailPart *part)
+                          CamelCipherValidity *validity)
 {
 	GtkBuilder *builder;
 	GtkWidget *grid, *w;
 	GtkWidget *dialog;
 
+	g_return_if_fail (validity != NULL);
+
 	builder = gtk_builder_new ();
 	e_load_ui_builder_definition (builder, "mail-dialogs.ui");
 
 	dialog = e_builder_get_widget (builder, "message_security_dialog");
 
 	grid = e_builder_get_widget (builder, "signature_grid");
-	w = gtk_label_new (_(smime_sign_table[part->validity->sign.status].description));
+	w = gtk_label_new (_(smime_sign_table[validity->sign.status].description));
 	gtk_misc_set_alignment ((GtkMisc *) w, 0.0, 0.5);
 	gtk_label_set_line_wrap ((GtkLabel *) w, TRUE);
 	gtk_container_add (GTK_CONTAINER (grid), w);
-	if (part->validity->sign.description) {
+	if (validity->sign.description) {
 		GtkTextBuffer *buffer;
 
 		buffer = gtk_text_buffer_new (NULL);
 		gtk_text_buffer_set_text (
-			buffer, part->validity->sign.description,
-			strlen (part->validity->sign.description));
+			buffer, validity->sign.description,
+			strlen (validity->sign.description));
 		w = g_object_new (
 			gtk_scrolled_window_get_type (),
 			"hscrollbar_policy", GTK_POLICY_AUTOMATIC,
@@ -309,24 +311,24 @@ secure_button_clicked_cb (GtkWidget *widget,
 		gtk_container_add (GTK_CONTAINER (grid), w);
 	}
 
-	if (!g_queue_is_empty (&part->validity->sign.signers))
+	if (!g_queue_is_empty (&validity->sign.signers))
 		add_cert_table (
-			grid, &part->validity->sign.signers, NULL);
+			grid, &validity->sign.signers, NULL);
 
 	gtk_widget_show_all (grid);
 
 	grid = e_builder_get_widget (builder, "encryption_grid");
-	w = gtk_label_new (_(smime_encrypt_table[part->validity->encrypt.status].description));
+	w = gtk_label_new (_(smime_encrypt_table[validity->encrypt.status].description));
 	gtk_misc_set_alignment ((GtkMisc *) w, 0.0, 0.5);
 	gtk_label_set_line_wrap ((GtkLabel *) w, TRUE);
 	gtk_container_add (GTK_CONTAINER (grid), w);
-	if (part->validity->encrypt.description) {
+	if (validity->encrypt.description) {
 		GtkTextBuffer *buffer;
 
 		buffer = gtk_text_buffer_new (NULL);
 		gtk_text_buffer_set_text (
-			buffer, part->validity->encrypt.description,
-			strlen (part->validity->encrypt.description));
+			buffer, validity->encrypt.description,
+			strlen (validity->encrypt.description));
 		w = g_object_new (
 			gtk_scrolled_window_get_type (),
 			"hscrollbar_policy", GTK_POLICY_AUTOMATIC,
@@ -346,8 +348,8 @@ secure_button_clicked_cb (GtkWidget *widget,
 		gtk_container_add (GTK_CONTAINER (grid), w);
 	}
 
-	if (!g_queue_is_empty (&part->validity->encrypt.encrypters))
-		add_cert_table (grid, &part->validity->encrypt.encrypters, NULL);
+	if (!g_queue_is_empty (&validity->encrypt.encrypters))
+		add_cert_table (grid, &validity->encrypt.encrypters, NULL);
 
 	gtk_widget_show_all (grid);
 
@@ -361,37 +363,37 @@ secure_button_clicked_cb (GtkWidget *widget,
 }
 
 static GtkWidget *
-emfe_secure_button_get_widget (EMailFormatterExtension *extension,
-                               EMailPartList *context,
-                               EMailPart *part,
-                               GHashTable *params)
+secure_button_get_widget_for_validity (CamelCipherValidity *validity)
 {
 	GtkWidget *box, *button, *layout, *widget;
 	const gchar *icon_name;
 	gchar *description;
 	GString *buffer;
+
+	g_return_val_if_fail (validity != NULL, NULL);
+
 	buffer = g_string_new ("");
 
-	if (part->validity->sign.status != CAMEL_CIPHER_VALIDITY_SIGN_NONE) {
+	if (validity->sign.status != CAMEL_CIPHER_VALIDITY_SIGN_NONE) {
 		const gchar *desc;
 		gint status;
 
-		status = part->validity->sign.status;
+		status = validity->sign.status;
 		desc = smime_sign_table[status].shortdesc;
 
 		g_string_append (buffer, gettext (desc));
 
-		format_cert_infos (&part->validity->sign.signers, buffer);
+		format_cert_infos (&validity->sign.signers, buffer);
 	}
 
-	if (part->validity->encrypt.status != CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE) {
+	if (validity->encrypt.status != CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE) {
 		const gchar *desc;
 		gint status;
 
-		if (part->validity->sign.status != CAMEL_CIPHER_VALIDITY_SIGN_NONE)
+		if (validity->sign.status != CAMEL_CIPHER_VALIDITY_SIGN_NONE)
 			g_string_append (buffer, "\n");
 
-		status = part->validity->encrypt.status;
+		status = validity->encrypt.status;
 		desc = smime_encrypt_table[status].shortdesc;
 		g_string_append (buffer, gettext (desc));
 	}
@@ -399,16 +401,16 @@ emfe_secure_button_get_widget (EMailFormatterExtension *extension,
 	description = g_string_free (buffer, FALSE);
 
 	/* FIXME: need to have it based on encryption and signing too */
-	if (part->validity->sign.status != 0)
-		icon_name = smime_sign_table[part->validity->sign.status].icon;
+	if (validity->sign.status != 0)
+		icon_name = smime_sign_table[validity->sign.status].icon;
 	else
-		icon_name = smime_encrypt_table[part->validity->encrypt.status].icon;
+		icon_name = smime_encrypt_table[validity->encrypt.status].icon;
 
 	box = gtk_event_box_new ();
-	if (part->validity->sign.status != 0)
+	if (validity->sign.status != 0)
 		gtk_widget_override_background_color (
 			box, GTK_STATE_FLAG_NORMAL,
-			&smime_sign_colour[part->validity->sign.status]);
+			&smime_sign_colour[validity->sign.status]);
 
 	layout = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
 	gtk_container_add (GTK_CONTAINER (box), layout);
@@ -417,7 +419,7 @@ emfe_secure_button_get_widget (EMailFormatterExtension *extension,
 	gtk_box_pack_start (GTK_BOX (layout), button, FALSE, FALSE, 0);
 	g_signal_connect (
 		button, "clicked",
-		G_CALLBACK (secure_button_clicked_cb), part);
+		G_CALLBACK (secure_button_clicked_cb), validity);
 
 	widget = gtk_image_new_from_icon_name (
 			icon_name, GTK_ICON_SIZE_LARGE_TOOLBAR);
@@ -426,12 +428,49 @@ emfe_secure_button_get_widget (EMailFormatterExtension *extension,
 	widget = gtk_label_new (description);
 	gtk_box_pack_start (GTK_BOX (layout), widget, FALSE, FALSE, 0);
 
-	gtk_widget_show_all (box);
-
 	g_free (description);
+
 	return box;
 }
 
+static GtkWidget *
+emfe_secure_button_get_widget (EMailFormatterExtension *extension,
+                               EMailPartList *context,
+                               EMailPart *part,
+                               GHashTable *params)
+{
+	GtkWidget *grid;
+	GSList *lst;
+
+	g_return_val_if_fail (part != NULL, NULL);
+
+	grid = g_object_new (GTK_TYPE_GRID,
+		"orientation", GTK_ORIENTATION_VERTICAL,
+		"row-spacing", 2,
+		"halign", GTK_ALIGN_FILL,
+		"hexpand", TRUE,
+		NULL);
+
+	for (lst = part->validities; lst; lst = lst->next) {
+		EMailPartValidityPair *pair = lst->data;
+		GtkWidget *widget;
+
+		if (!pair)
+			continue;
+
+		widget = secure_button_get_widget_for_validity (pair->validity);
+		if (widget) {
+			gtk_widget_set_halign (widget, GTK_ALIGN_FILL);
+			gtk_widget_set_hexpand (widget, TRUE);
+			gtk_container_add (GTK_CONTAINER (grid), widget);
+		}
+	}
+
+	gtk_widget_show_all (grid);
+
+	return grid;
+}
+
 static const gchar *
 emfe_secure_button_get_display_name (EMailFormatterExtension *extension)
 {
diff --git a/em-format/e-mail-part.c b/em-format/e-mail-part.c
index a0d493a..c0a5727 100644
--- a/em-format/e-mail-part.c
+++ b/em-format/e-mail-part.c
@@ -39,6 +39,18 @@ struct _EMailPartPrivate {
 };
 
 static void
+mail_part_validity_pair_free (gpointer ptr)
+{
+	EMailPartValidityPair *pair = ptr;
+
+	if (!pair)
+		return;
+
+	camel_cipher_validity_free (pair->validity);
+	g_free (pair);
+}
+
+static void
 mail_part_free (EMailPart *part)
 {
 	if (!part)
@@ -59,14 +71,9 @@ mail_part_free (EMailPart *part)
 		part->mime_type = NULL;
 	}
 
-	if (part->validity) {
-		camel_cipher_validity_free (part->validity);
-		part->validity = NULL;
-	}
-
-	if (part->validity_parent) {
-		camel_cipher_validity_free (part->validity_parent);
-		part->validity_parent = NULL;
+	if (part->validities) {
+		g_slist_free_full (part->validities, mail_part_validity_pair_free);
+		part->validities = NULL;
 	}
 
 	if (part->priv->free_func) {
@@ -169,6 +176,22 @@ e_mail_part_get_instance_size (EMailPart *part)
 	return part->priv->instance_size;
 }
 
+static EMailPartValidityPair *
+mail_part_find_validity_pair (EMailPart *part,
+			      guint32 validity_type)
+{
+	GSList *lst;
+
+	for (lst = part->validities; lst; lst = lst->next) {
+		EMailPartValidityPair *pair = lst->data;
+
+		if (pair && (pair->validity_type & validity_type) == validity_type)
+			return pair;
+	}
+
+	return NULL;
+}
+
 /**
  * e_mail_part_update_validity:
  * @part: An #EMailPart
@@ -177,20 +200,52 @@ e_mail_part_get_instance_size (EMailPart *part)
  *
  * Updates validity of the @part. When the part already has some validity
  * set, the new @validity and @validity_type are just appended, preserving
- * the original validity.
+ * the original validity. Validities of the same type (PGP or S/MIME) are
+ * merged together.
  */
 void
 e_mail_part_update_validity (EMailPart *part,
                              CamelCipherValidity *validity,
                              guint32 validity_type)
 {
-	g_return_if_fail (part != NULL);
+	EMailPartValidityPair *pair;
 
-	part->validity_type &= validity_type;
+	g_return_if_fail (part != NULL);
 
-	if (part->validity) {
-		camel_cipher_validity_envelope (part->validity, validity);
+	pair = mail_part_find_validity_pair (part, validity_type & (E_MAIL_PART_VALIDITY_PGP | E_MAIL_PART_VALIDITY_SMIME));
+	if (pair) {
+		pair->validity_type |= validity_type;
+		camel_cipher_validity_envelope (pair->validity, validity);
 	} else {
-		part->validity = camel_cipher_validity_clone (validity);
+		pair = g_new0 (EMailPartValidityPair, 1);
+		pair->validity_type = validity_type;
+		pair->validity = camel_cipher_validity_clone (validity);
+
+		part->validities = g_slist_append (part->validities, pair);
 	}
 }
+
+/**
+ * e_mail_part_get_validity:
+ * @part: An #EMailPart
+ * @validity_type: E_MAIL_PART_VALIDITY_* flags
+ *
+ * Returns, validity of @part contains any validity with the same bits
+ * as @validity_type set. It should contain all bits of it.
+ *
+ * Returns: a #CamelCipherValidity of the given type, %NULL if not found
+ *
+ * Since: 3.8
+ */
+CamelCipherValidity *
+e_mail_part_get_validity (EMailPart *part,
+			  guint32 validity_type)
+{
+	EMailPartValidityPair *pair;
+
+	g_return_val_if_fail (part != NULL, NULL);
+
+	pair = mail_part_find_validity_pair (part, validity_type);
+
+	return pair ? pair->validity : NULL;
+}
diff --git a/em-format/e-mail-part.h b/em-format/e-mail-part.h
index 3d2e962..82e417c 100644
--- a/em-format/e-mail-part.h
+++ b/em-format/e-mail-part.h
@@ -43,6 +43,13 @@ enum {
 	E_MAIL_PART_VALIDITY_ENCRYPTED	=	1 << 3
 } EMailPartValidityFlags;
 
+typedef struct _EMailPartValidityPair EMailPartValidityPair;
+
+struct _EMailPartValidityPair {
+	guint32 validity_type;	/* E_MAIL_PART_VALIDITY_ * flags */
+	CamelCipherValidity *validity;
+};
+
 struct _EMailPart {
 	EMailPartPrivate *priv;
 
@@ -53,9 +60,7 @@ struct _EMailPart {
 	gchar *cid;
 	gchar *mime_type;
 
-	guint32 validity_type;	/* E_MAIL_PART_VALIDITY_ * flags */
-	CamelCipherValidity *validity;
-	CamelCipherValidity *validity_parent;
+	GSList *validities;	/* EMailPartValidityPair pointer */
 
 	gint is_attachment: 1;
 
@@ -92,6 +97,9 @@ gsize		e_mail_part_get_instance_size	(EMailPart *part);
 void		e_mail_part_update_validity	(EMailPart *part,
 						 CamelCipherValidity *validity,
 						 guint32 validity_type);
+CamelCipherValidity *
+		e_mail_part_get_validity	(EMailPart *part,
+						 guint32 validity_type);
 
 G_END_DECLS
 
diff --git a/mail/em-utils.c b/mail/em-utils.c
index ec4401f..923b11f 100644
--- a/mail/em-utils.c
+++ b/mail/em-utils.c
@@ -1349,8 +1349,16 @@ em_utils_message_to_html (CamelSession *session,
 			hidden_text_html_part = part;
 		}
 
-		if (part->validity_type)
-			is_validity_found |= part->validity_type;
+		if (part->validities) {
+			GSList *lst;
+
+			for (lst = part->validities; lst; lst = lst->next) {
+				EMailPartValidityPair *pair = lst->data;
+
+				if (pair)
+					is_validity_found |= pair->validity_type;
+			}
+		}
 	}
 
 	if (validity_found)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]