From abdefcaa26ca7116bfc5b7aaa9ee2f04de533ecb Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Wed, 21 Nov 2012 17:57:07 +0100 Subject: 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 +++- 5 files changed, 177 insertions(+), 65 deletions(-) (limited to 'em-format') diff --git a/em-format/e-mail-formatter-attachment.c b/em-format/e-mail-formatter-attachment.c index ffe16347c0..62fa65e597 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 a74b94f2cd..a16264b9bf 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 d95670cc9c..8d6df161fd 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 a0d493afe4..c0a57271b4 100644 --- a/em-format/e-mail-part.c +++ b/em-format/e-mail-part.c @@ -38,6 +38,18 @@ struct _EMailPartPrivate { GFreeFunc free_func; }; +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) { @@ -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 3d2e9628eb..82e417cb80 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 -- cgit