From 4a41b976e379063d1431aec8d12bc77734f4a84f Mon Sep 17 00:00:00 2001 From: Packit Service Date: Dec 09 2020 13:10:25 +0000 Subject: Apply patch evolution-3.28.5-cve-2018-15587-reposition-signature-bar.patch patch_name: evolution-3.28.5-cve-2018-15587-reposition-signature-bar.patch present_in_specfile: true --- diff --git a/src/em-format/e-mail-formatter-utils.c b/src/em-format/e-mail-formatter-utils.c index abd5155..50dae71 100644 --- a/src/em-format/e-mail-formatter-utils.c +++ b/src/em-format/e-mail-formatter-utils.c @@ -549,71 +549,136 @@ e_mail_formatter_format_security_header (EMailFormatter *formatter, EMailPart *part, guint32 flags) { - const gchar* part_id; - gchar* part_id_prefix; - GString* tmp; + struct _validity_flags { + guint32 flags; + const gchar *description_complete; + const gchar *description_partial; + } validity_flags[] = { + { E_MAIL_PART_VALIDITY_PGP | E_MAIL_PART_VALIDITY_SIGNED, N_("GPG signed"), N_("partially GPG signed") }, + { E_MAIL_PART_VALIDITY_PGP | E_MAIL_PART_VALIDITY_ENCRYPTED, N_("GPG encrypted"), N_("partially GPG encrypted") }, + { E_MAIL_PART_VALIDITY_SMIME | E_MAIL_PART_VALIDITY_SIGNED, N_("S/MIME signed"), N_("partially S/MIME signed") }, + { E_MAIL_PART_VALIDITY_SMIME | E_MAIL_PART_VALIDITY_ENCRYPTED, N_("S/MIME encrypted"), N_("partially S/MIME encrypted") } + }; + const gchar *part_id; + gchar *part_id_prefix; GQueue queue = G_QUEUE_INIT; GList *head, *link; + guint32 check_valid_flags = 0; + gint part_id_prefix_len; + gboolean is_partial = FALSE; + guint ii; g_return_if_fail (E_IS_MAIL_PART_HEADERS (part)); /* Get prefix of this PURI */ part_id = e_mail_part_get_id (part); part_id_prefix = g_strndup (part_id, g_strrstr (part_id, ".") - part_id); - - /* Add encryption/signature header */ - tmp = g_string_new (""); + part_id_prefix_len = strlen (part_id_prefix); e_mail_part_list_queue_parts (context->part_list, NULL, &queue); head = g_queue_peek_head_link (&queue); - /* Find first secured part. */ - for (link = head; link != NULL; link = g_list_next(link)) { + /* Ignore the main message, the headers and the end parts */ + #define should_skip_part(_id) \ + (g_strcmp0 (_id, part_id_prefix) == 0 || \ + (_id && g_str_has_suffix (_id, ".rfc822.end")) || \ + (_id && strlen (_id) == part_id_prefix_len + 8 /* strlen (".headers") */ && \ + g_strcmp0 (_id + part_id_prefix_len, ".headers") == 0)) + + /* Check parts for this ID. */ + for (link = head; link != NULL; link = g_list_next (link)) { EMailPart *mail_part = link->data; + const gchar *id = e_mail_part_get_id (mail_part); - if (!e_mail_part_has_validity (mail_part)) + if (!e_mail_part_id_has_prefix (mail_part, part_id_prefix)) continue; - if (!e_mail_part_id_has_prefix (mail_part, part_id_prefix)) + if (should_skip_part (id)) continue; - 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 (!e_mail_part_has_validity (mail_part)) { + /* A part without validity, thus it's partially signed/encrypted */ + is_partial = TRUE; + } else { + guint32 validies = 0; + for (ii = 0; ii < G_N_ELEMENTS (validity_flags); ii++) { + if (e_mail_part_get_validity (mail_part, validity_flags[ii].flags)) + validies |= validity_flags[ii].flags; + } + check_valid_flags |= validies; } - 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 encrypted")); - } + /* Do not traverse sub-messages */ + if (g_str_has_suffix (e_mail_part_get_id (mail_part), ".rfc822") && + !g_str_equal (e_mail_part_get_id (mail_part), part_id_prefix)) + link = e_mail_formatter_find_rfc822_end_iter (link); + } + + if (check_valid_flags) { + GString *tmp; + + if (!is_partial) { + for (link = head; link != NULL && !is_partial; link = g_list_next (link)) { + EMailPart *mail_part = link->data; + const gchar *id = e_mail_part_get_id (mail_part); - 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 (!e_mail_part_id_has_prefix (mail_part, part_id_prefix)) + continue; + + if (should_skip_part (id)) + continue; + + if (!e_mail_part_has_validity (mail_part)) { + /* A part without validity, thus it's partially signed/encrypted */ + is_partial = TRUE; + break; + } + + is_partial = !e_mail_part_get_validity (mail_part, check_valid_flags); + + /* Do not traverse sub-messages */ + if (g_str_has_suffix (e_mail_part_get_id (mail_part), ".rfc822") && + !g_str_equal (e_mail_part_get_id (mail_part), part_id_prefix)) + link = e_mail_formatter_find_rfc822_end_iter (link); + } } - 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 encrypted")); + /* Add encryption/signature header */ + tmp = g_string_new (""); + + for (link = head; link; link = g_list_next (link)) { + EMailPart *mail_part = link->data; + const gchar *id = e_mail_part_get_id (mail_part); + + if (!e_mail_part_has_validity (mail_part) || + !e_mail_part_id_has_prefix (mail_part, part_id_prefix)) + continue; + + if (should_skip_part (id)) + continue; + + for (ii = 0; ii < G_N_ELEMENTS (validity_flags); ii++) { + if (e_mail_part_get_validity (mail_part, validity_flags[ii].flags)) { + if (tmp->len > 0) + g_string_append (tmp, ", "); + g_string_append (tmp, is_partial ? _(validity_flags[ii].description_partial) : _(validity_flags[ii].description_complete)); + } + } + + break; } - break; - } + if (tmp->len > 0) + e_mail_formatter_format_header (formatter, buffer, _("Security"), tmp->str, flags, "UTF-8"); - if (tmp->len > 0) { - e_mail_formatter_format_header ( - formatter, buffer, - _("Security"), tmp->str, - flags, - "UTF-8"); + g_string_free (tmp, TRUE); } + #undef should_skip_part + while (!g_queue_is_empty (&queue)) g_object_unref (g_queue_pop_head (&queue)); - g_string_free (tmp, TRUE); g_free (part_id_prefix); } diff --git a/src/em-format/e-mail-parser-application-smime.c b/src/em-format/e-mail-parser-application-smime.c index 87f25b3..e569cd7 100644 --- a/src/em-format/e-mail-parser-application-smime.c +++ b/src/em-format/e-mail-parser-application-smime.c @@ -22,6 +22,7 @@ #include +#include "e-mail-formatter-utils.h" #include "e-mail-parser-extension.h" #include "e-mail-part-utils.h" @@ -104,6 +105,10 @@ empe_app_smime_parse (EMailParserExtension *extension, mail_part, valid, E_MAIL_PART_VALIDITY_ENCRYPTED | E_MAIL_PART_VALIDITY_SMIME); + + /* Do not traverse sub-messages */ + if (g_str_has_suffix (e_mail_part_get_id (mail_part), ".rfc822")) + link = e_mail_formatter_find_rfc822_end_iter (link); } e_queue_transfer (&work_queue, out_mail_parts); diff --git a/src/em-format/e-mail-parser-inlinepgp-encrypted.c b/src/em-format/e-mail-parser-inlinepgp-encrypted.c index c66195c..e342825 100644 --- a/src/em-format/e-mail-parser-inlinepgp-encrypted.c +++ b/src/em-format/e-mail-parser-inlinepgp-encrypted.c @@ -22,6 +22,7 @@ #include +#include "e-mail-formatter-utils.h" #include "e-mail-parser-extension.h" #include "e-mail-part-utils.h" @@ -135,6 +136,10 @@ empe_inlinepgp_encrypted_parse (EMailParserExtension *extension, mail_part, valid, E_MAIL_PART_VALIDITY_ENCRYPTED | E_MAIL_PART_VALIDITY_PGP); + + /* Do not traverse sub-messages */ + if (g_str_has_suffix (e_mail_part_get_id (mail_part), ".rfc822")) + link = e_mail_formatter_find_rfc822_end_iter (link); } e_queue_transfer (&work_queue, out_mail_parts); diff --git a/src/em-format/e-mail-parser-inlinepgp-signed.c b/src/em-format/e-mail-parser-inlinepgp-signed.c index 2ac8c3a..3235a1c 100644 --- a/src/em-format/e-mail-parser-inlinepgp-signed.c +++ b/src/em-format/e-mail-parser-inlinepgp-signed.c @@ -22,6 +22,7 @@ #include +#include "e-mail-formatter-utils.h" #include "e-mail-parser-extension.h" #include "e-mail-part-utils.h" @@ -142,6 +143,10 @@ empe_inlinepgp_signed_parse (EMailParserExtension *extension, mail_part, valid, E_MAIL_PART_VALIDITY_SIGNED | E_MAIL_PART_VALIDITY_PGP); + + /* Do not traverse sub-messages */ + if (g_str_has_suffix (e_mail_part_get_id (mail_part), ".rfc822")) + link = e_mail_formatter_find_rfc822_end_iter (link); } e_queue_transfer (&work_queue, out_mail_parts); diff --git a/src/em-format/e-mail-parser-multipart-encrypted.c b/src/em-format/e-mail-parser-multipart-encrypted.c index 2baa98f..818214c 100644 --- a/src/em-format/e-mail-parser-multipart-encrypted.c +++ b/src/em-format/e-mail-parser-multipart-encrypted.c @@ -21,6 +21,7 @@ #include +#include "e-mail-formatter-utils.h" #include "e-mail-parser-extension.h" #include "e-mail-part-utils.h" @@ -126,6 +127,10 @@ empe_mp_encrypted_parse (EMailParserExtension *extension, mail_part, valid, E_MAIL_PART_VALIDITY_ENCRYPTED | E_MAIL_PART_VALIDITY_PGP); + + /* Do not traverse sub-messages */ + if (g_str_has_suffix (e_mail_part_get_id (mail_part), ".rfc822")) + link = e_mail_formatter_find_rfc822_end_iter (link); } e_queue_transfer (&work_queue, out_mail_parts); diff --git a/src/em-format/e-mail-parser-multipart-signed.c b/src/em-format/e-mail-parser-multipart-signed.c index a76ca61..ca0133a 100644 --- a/src/em-format/e-mail-parser-multipart-signed.c +++ b/src/em-format/e-mail-parser-multipart-signed.c @@ -21,6 +21,7 @@ #include +#include "e-mail-formatter-utils.h" #include "e-mail-parser-extension.h" #include "e-mail-part-utils.h" @@ -170,6 +171,10 @@ empe_mp_signed_parse (EMailParserExtension *extension, e_mail_part_update_validity ( mail_part, valid, validity_type | E_MAIL_PART_VALIDITY_SIGNED); + + /* Do not traverse sub-messages */ + if (g_str_has_suffix (e_mail_part_get_id (mail_part), ".rfc822")) + link = e_mail_formatter_find_rfc822_end_iter (link); } e_queue_transfer (&work_queue, out_mail_parts); diff --git a/src/em-format/e-mail-parser.c b/src/em-format/e-mail-parser.c index 96c603f..b1f1511 100644 --- a/src/em-format/e-mail-parser.c +++ b/src/em-format/e-mail-parser.c @@ -79,6 +79,67 @@ GType e_mail_parser_application_smime_get_type (void); static gpointer parent_class; static void +mail_parser_move_security_before_headers (GQueue *part_queue) +{ + GList *link, *last_headers = NULL; + GSList *headers_stack = NULL; + + link = g_queue_peek_head_link (part_queue); + while (link) { + EMailPart *part = link->data; + const gchar *id; + + if (!part) { + link = g_list_next (link); + continue; + } + + id = e_mail_part_get_id (part); + if (!id) { + link = g_list_next (link); + continue; + } + + if (g_str_has_suffix (id, ".rfc822")) { + headers_stack = g_slist_prepend (headers_stack, last_headers); + last_headers = NULL; + } else if (g_str_has_suffix (id, ".rfc822.end")) { + g_warn_if_fail (headers_stack != NULL); + + if (headers_stack) { + last_headers = headers_stack->data; + headers_stack = g_slist_remove (headers_stack, last_headers); + } else { + last_headers = NULL; + } + } + + if (g_strcmp0 (e_mail_part_get_mime_type (part), "application/vnd.evolution.headers") == 0) { + last_headers = link; + link = g_list_next (link); + } else if (g_strcmp0 (e_mail_part_get_mime_type (part), "application/vnd.evolution.secure-button") == 0) { + g_warn_if_fail (last_headers != NULL); + + if (last_headers) { + GList *next = g_list_next (link); + + g_warn_if_fail (g_queue_remove (part_queue, part)); + g_queue_insert_before (part_queue, last_headers, part); + + link = next; + } else { + link = g_list_next (link); + } + } else { + link = g_list_next (link); + } + } + + g_warn_if_fail (headers_stack == NULL); + g_slist_free (headers_stack); +} + +static void mail_parser_run (EMailParser *parser, EMailPartList *part_list, GCancellable *cancellable) @@ -132,6 +193,8 @@ mail_parser_run (EMailParser *parser, break; } + mail_parser_move_security_before_headers (&mail_part_queue); + while (!g_queue_is_empty (&mail_part_queue)) { mail_part = g_queue_pop_head (&mail_part_queue); e_mail_part_list_add_part (part_list, mail_part); diff --git a/src/em-format/e-mail-part.c b/src/em-format/e-mail-part.c index 135005e..03271ce 100644 --- a/src/em-format/e-mail-part.c +++ b/src/em-format/e-mail-part.c @@ -662,6 +662,15 @@ e_mail_part_update_validity (EMailPart *part, mask = E_MAIL_PART_VALIDITY_PGP | E_MAIL_PART_VALIDITY_SMIME; + /* Auto-add flags when the related part is present */ + if (!(validity_type & E_MAIL_PART_VALIDITY_SIGNED) && + validity->sign.status != CAMEL_CIPHER_VALIDITY_SIGN_NONE) + validity_type |= E_MAIL_PART_VALIDITY_SIGNED; + + if (!(validity_type & E_MAIL_PART_VALIDITY_ENCRYPTED) && + validity->encrypt.status != CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE) + validity_type |= E_MAIL_PART_VALIDITY_ENCRYPTED; + pair = mail_part_find_validity_pair (part, validity_type & mask); if (pair != NULL) { pair->validity_type |= validity_type;