[evolution] Bug 782438 - Check From address against digital signature author



commit 8117e07334da49f81eb1dc73535e37aae49dfca4
Author: Milan Crha <mcrha redhat com>
Date:   Thu May 18 11:26:10 2017 +0200

    Bug 782438 - Check From address against digital signature author

 src/em-format/e-mail-formatter-enums.h          |    4 +-
 src/em-format/e-mail-formatter-secure-button.c  |   63 ++++++++++++++++-------
 src/em-format/e-mail-parser-application-smime.c |    2 +-
 src/em-format/e-mail-parser-message.c           |   16 ++++++
 src/em-format/e-mail-part-utils.c               |   11 +++-
 src/em-format/e-mail-part.c                     |   39 ++++++++++++++-
 src/em-format/e-mail-part.h                     |    3 +
 7 files changed, 114 insertions(+), 24 deletions(-)
---
diff --git a/src/em-format/e-mail-formatter-enums.h b/src/em-format/e-mail-formatter-enums.h
index de64568..f357d91 100644
--- a/src/em-format/e-mail-formatter-enums.h
+++ b/src/em-format/e-mail-formatter-enums.h
@@ -79,7 +79,9 @@ typedef enum { /*< flags >*/
        E_MAIL_PART_VALIDITY_PGP = 1 << 0,
        E_MAIL_PART_VALIDITY_SMIME = 1 << 1,
        E_MAIL_PART_VALIDITY_SIGNED = 1 << 2,
-       E_MAIL_PART_VALIDITY_ENCRYPTED = 1 << 3
+       E_MAIL_PART_VALIDITY_ENCRYPTED = 1 << 3,
+       E_MAIL_PART_VALIDITY_SENDER_SIGNER_MISMATCH = 1 << 4,
+       E_MAIL_PART_VALIDITY_VERIFIED = 1 << 5
 } EMailPartValidityFlags;
 
 G_END_DECLS
diff --git a/src/em-format/e-mail-formatter-secure-button.c b/src/em-format/e-mail-formatter-secure-button.c
index 7eca64f..ceb8dce 100644
--- a/src/em-format/e-mail-formatter-secure-button.c
+++ b/src/em-format/e-mail-formatter-secure-button.c
@@ -39,16 +39,31 @@ static const gchar *formatter_mime_types[] = {
 };
 
 static const struct {
-       const gchar *icon, *shortdesc, *description;
+       const gchar *icon, *shortdesc, *shortdesc_mismatch, *description;
 } smime_sign_table[5] = {
-       { "stock_signature-bad", N_("Unsigned"), N_("This message is not signed. There is no guarantee that 
this message is authentic.") },
-       { "stock_signature-ok", N_("Valid signature"), N_("This message is signed and is valid meaning that 
it is very likely that this message is authentic.") },
-       { "stock_signature-bad", N_("Invalid signature"), N_("The signature of this message cannot be 
verified, it may have been altered in transit.") },
-       { "stock_signature", N_("Valid signature, but cannot verify sender"), N_("This message is signed with 
a valid signature, but the sender of the message cannot be verified.") },
-       { "stock_signature-bad", N_("This message is signed, but the public key is not in your keyring"), 
N_("This message was digitally signed, but the corresponding"
-                               " public key is not present in your keyring. If you want to be able to verify 
the authenticity of messages from this person, you should"
-                               " obtain the public key through a trusted method and add it to your keyring. 
Until then, there is no guarantee that this message truly"
-                               " came from that person and that it arrived unaltered.") }
+       { "stock_signature-bad",
+         N_("Unsigned"),
+         NULL,
+         N_("This message is not signed. There is no guarantee that this message is authentic.") },
+       { "stock_signature-ok",
+         N_("Valid signature"),
+         N_("Valid signature, but sender address and signer address do not match"),
+         N_("This message is signed and is valid meaning that it is very likely that this message is 
authentic.") },
+       { "stock_signature-bad",
+         N_("Invalid signature"),
+         NULL,
+         N_("The signature of this message cannot be verified, it may have been altered in transit.") },
+       { "stock_signature",
+         N_("Valid signature, but cannot verify sender"),
+         NULL,
+         N_("This message is signed with a valid signature, but the sender of the message cannot be 
verified.") },
+       { "stock_signature-bad",
+         N_("This message is signed, but the public key is not in your keyring"),
+         NULL,
+         N_("This message was digitally signed, but the corresponding"
+               " public key is not present in your keyring. If you want to be able to verify the 
authenticity of messages from this person, you should"
+               " obtain the public key through a trusted method and add it to your keyring. Until then, 
there is no guarantee that this message truly"
+               " came from that person and that it arrived unaltered.") }
 };
 
 static const struct {
@@ -92,7 +107,7 @@ e_mail_formatter_secure_button_get_encrypt_description (CamelCipherValidityEncry
 
 static void
 format_cert_infos (GQueue *cert_infos,
-                   GString *output_buffer)
+                  GString *output_buffer)
 {
        GQueue valid = G_QUEUE_INIT;
        GList *head, *link;
@@ -178,12 +193,14 @@ add_photo_cb (gpointer data,
 
 static void
 secure_button_format_validity (EMailPart *part,
+                              gboolean sender_signer_mismatch,
                               CamelCipherValidity *validity,
                               GString *html)
 {
        const gchar *icon_name;
        gchar *description;
        gint icon_width, icon_height;
+       gint info_index;
        GString *buffer;
 
        g_return_if_fail (validity != NULL);
@@ -191,15 +208,19 @@ secure_button_format_validity (EMailPart *part,
        buffer = g_string_new ("");
 
        if (validity->sign.status != CAMEL_CIPHER_VALIDITY_SIGN_NONE) {
-               const gchar *desc;
+               const gchar *desc = NULL;
                gint status;
 
                status = validity->sign.status;
-               desc = smime_sign_table[status].shortdesc;
-
-               g_string_append (buffer, gettext (desc));
 
                format_cert_infos (&validity->sign.signers, buffer);
+
+               if (sender_signer_mismatch)
+                       desc = smime_sign_table[status].shortdesc_mismatch;
+               if (!desc)
+                       desc = smime_sign_table[status].shortdesc;
+
+               g_string_prepend (buffer, gettext (desc));
        }
 
        if (validity->encrypt.status != CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE) {
@@ -216,9 +237,13 @@ secure_button_format_validity (EMailPart *part,
 
        description = g_string_free (buffer, FALSE);
 
+       info_index = validity->sign.status;
+       if (sender_signer_mismatch && info_index == CAMEL_CIPHER_VALIDITY_SIGN_GOOD)
+               info_index = CAMEL_CIPHER_VALIDITY_SIGN_UNKNOWN;
+
        /* FIXME: need to have it based on encryption and signing too */
        if (validity->sign.status != CAMEL_CIPHER_VALIDITY_SIGN_NONE)
-               icon_name = smime_sign_table[validity->sign.status].icon;
+               icon_name = smime_sign_table[info_index].icon;
        else
                icon_name = smime_encrypt_table[validity->encrypt.status].icon;
 
@@ -229,9 +254,9 @@ secure_button_format_validity (EMailPart *part,
 
        g_string_append (html, "<table width=\"100%\" style=\"vertical-align:middle;");
        if (validity->sign.status != CAMEL_CIPHER_VALIDITY_SIGN_NONE &&
-           smime_sign_colour[validity->sign.status].alpha > 1e-9)
+           smime_sign_colour[info_index].alpha > 1e-9)
                g_string_append_printf (html, " background:#%06x;",
-                       e_rgba_to_value (&smime_sign_colour[validity->sign.status]));
+                       e_rgba_to_value (&smime_sign_colour[info_index]));
        g_string_append (html, "\"><tr>");
 
        g_string_append_printf (html,
@@ -269,11 +294,13 @@ emfe_secure_button_format (EMailFormatterExtension *extension,
 
        for (link = head; link != NULL; link = g_list_next (link)) {
                EMailPartValidityPair *pair = link->data;
+               gboolean sender_signer_mismatch;
 
                if (!pair)
                        continue;
 
-               secure_button_format_validity (part, pair->validity, html);
+               sender_signer_mismatch = (pair->validity_type & E_MAIL_PART_VALIDITY_SENDER_SIGNER_MISMATCH) 
!= 0;
+               secure_button_format_validity (part, sender_signer_mismatch, pair->validity, html);
        }
 
        g_output_stream_write_all (stream, html->str, html->len, NULL, cancellable, NULL);
diff --git a/src/em-format/e-mail-parser-application-smime.c b/src/em-format/e-mail-parser-application-smime.c
index c7e631b..87f25b3 100644
--- a/src/em-format/e-mail-parser-application-smime.c
+++ b/src/em-format/e-mail-parser-application-smime.c
@@ -56,8 +56,8 @@ empe_app_smime_parse (EMailParserExtension *extension,
        CamelCipherContext *context;
        CamelMimePart *opart;
        CamelCipherValidity *valid;
-       GError *local_error = NULL;
        CamelContentType *ct;
+       GError *local_error = NULL;
 
        ct = camel_mime_part_get_content_type (part);
        if (camel_content_type_is (ct, "application", "pkcs7-signature") ||
diff --git a/src/em-format/e-mail-parser-message.c b/src/em-format/e-mail-parser-message.c
index ab18eba..4d195b4 100644
--- a/src/em-format/e-mail-parser-message.c
+++ b/src/em-format/e-mail-parser-message.c
@@ -101,6 +101,22 @@ empe_message_parse (EMailParserExtension *extension,
                }
        }
 
+       if (CAMEL_IS_MIME_MESSAGE (part)) {
+               CamelInternetAddress *from_address;
+
+               from_address = camel_mime_message_get_from (CAMEL_MIME_MESSAGE (part));
+               if (from_address) {
+                       GList *link;
+
+                       for (link = g_queue_peek_head_link (&work_queue); link; link = g_list_next (link)) {
+                               mail_part = link->data;
+
+                               if (mail_part)
+                                       e_mail_part_verify_validity_sender (mail_part, from_address);
+                       }
+               }
+       }
+
        e_queue_transfer (&work_queue, out_mail_parts);
 
        g_free (mime_type);
diff --git a/src/em-format/e-mail-part-utils.c b/src/em-format/e-mail-part-utils.c
index edcd639..f9b369f 100644
--- a/src/em-format/e-mail-part-utils.c
+++ b/src/em-format/e-mail-part-utils.c
@@ -59,10 +59,13 @@ const gchar *
 e_mail_part_get_frame_security_style (EMailPart *part)
 {
        const gchar *frame_style = NULL;
+       guint32 flags;
 
        g_return_val_if_fail (part != NULL, "-e-mail-formatter-frame-security-none");
 
-       if (e_mail_part_get_validity_flags (part) == E_MAIL_PART_VALIDITY_NONE) {
+       flags = e_mail_part_get_validity_flags (part);
+
+       if (flags == E_MAIL_PART_VALIDITY_NONE) {
                return "-e-mail-formatter-frame-security-none";
        } else {
                GList *head, *link;
@@ -75,8 +78,10 @@ e_mail_part_get_frame_security_style (EMailPart *part)
                                return "-e-mail-formatter-frame-security-bad";
                        } else if (pair->validity->sign.status == CAMEL_CIPHER_VALIDITY_SIGN_UNKNOWN) {
                                frame_style = "-e-mail-formatter-frame-security-unknown";
-                       } else if (frame_style == NULL &&
-                               pair->validity->sign.status == CAMEL_CIPHER_VALIDITY_SIGN_NEED_PUBLIC_KEY) {
+                       } else if (frame_style == NULL && (
+                               pair->validity->sign.status == CAMEL_CIPHER_VALIDITY_SIGN_NEED_PUBLIC_KEY || (
+                               pair->validity->sign.status == CAMEL_CIPHER_VALIDITY_SIGN_GOOD &&
+                               (flags & E_MAIL_PART_VALIDITY_SENDER_SIGNER_MISMATCH) != 0))) {
                                frame_style = "-e-mail-formatter-frame-security-need-key";
                        } else if (frame_style == NULL &&
                                pair->validity->sign.status == CAMEL_CIPHER_VALIDITY_SIGN_GOOD) {
diff --git a/src/em-format/e-mail-part.c b/src/em-format/e-mail-part.c
index 4aca446..650e869 100644
--- a/src/em-format/e-mail-part.c
+++ b/src/em-format/e-mail-part.c
@@ -639,8 +639,8 @@ mail_part_find_validity_pair (EMailPart *part,
 /**
  * e_mail_part_update_validity:
  * @part: An #EMailPart
- * @validity_type: E_MAIL_PART_VALIDITY_* flags
  * @validity: a #CamelCipherValidity
+ * @validity_type: E_MAIL_PART_VALIDITY_* flags
  *
  * Updates validity of the @part. When the part already has some validity
  * set, the new @validity and @validity_type are just appended, preserving
@@ -656,6 +656,7 @@ e_mail_part_update_validity (EMailPart *part,
        EMailPartValidityFlags mask;
 
        g_return_if_fail (E_IS_MAIL_PART (part));
+       g_return_if_fail (validity != NULL);
 
        mask = E_MAIL_PART_VALIDITY_PGP | E_MAIL_PART_VALIDITY_SMIME;
 
@@ -725,3 +726,39 @@ e_mail_part_get_validity_flags (EMailPart *part)
        return flags;
 }
 
+void
+e_mail_part_verify_validity_sender (EMailPart *part,
+                                   CamelInternetAddress *from_address)
+{
+       GList *link;
+
+       g_return_if_fail (E_IS_MAIL_PART (part));
+
+       if (!from_address)
+               return;
+
+       for (link = g_queue_peek_head_link (&part->validities); link; link = g_list_next (link)) {
+               EMailPartValidityPair *pair = link->data;
+
+               if (pair && pair->validity && !(pair->validity_type & E_MAIL_PART_VALIDITY_VERIFIED)) {
+                       pair->validity_type |= E_MAIL_PART_VALIDITY_VERIFIED;
+
+                       if (pair->validity->sign.status != CAMEL_CIPHER_VALIDITY_SIGN_NONE) {
+                               GList *link2;
+                               gboolean from_matches_signer = FALSE;
+
+                               for (link2 = g_queue_peek_head_link (&pair->validity->sign.signers); link2 && 
!from_matches_signer; link2 = g_list_next (link2)) {
+                                       CamelCipherCertInfo *cinfo = link2->data;
+
+                                       if (cinfo->email && *cinfo->email) {
+                                               from_matches_signer = from_matches_signer ||
+                                                       (from_address && camel_internet_address_find_address 
(from_address, cinfo->email, NULL) >= 0);
+                                       }
+                               }
+
+                               if (!from_matches_signer)
+                                       pair->validity_type |= E_MAIL_PART_VALIDITY_SENDER_SIGNER_MISMATCH;
+                       }
+               }
+       }
+}
diff --git a/src/em-format/e-mail-part.h b/src/em-format/e-mail-part.h
index db13f05..9cc2fc0 100644
--- a/src/em-format/e-mail-part.h
+++ b/src/em-format/e-mail-part.h
@@ -138,6 +138,9 @@ CamelCipherValidity *
 gboolean       e_mail_part_has_validity        (EMailPart *part);
 EMailPartValidityFlags
                e_mail_part_get_validity_flags  (EMailPart *part);
+void           e_mail_part_verify_validity_sender
+                                               (EMailPart *part,
+                                                CamelInternetAddress *from_address);
 
 G_END_DECLS
 


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