Commit 8117e073 authored by Milan Crha's avatar Milan Crha
Browse files

Bug 782438 - Check From address against digital signature author

parent c7772ba6
......@@ -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
......
......@@ -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);
......
......@@ -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") ||
......
......@@ -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);
......
......@@ -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) {
......
......@@ -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;
}
}
}
}
......@@ -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
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment