mirror of https://github.com/djcb/mu.git
Add Decryption field
Add a decryption field of the form Decryption: 2 part(s) decrypted 1 part(s) failed Meaning that 2 encrypted mime parts where successfully decrypted and 1 part failed. Note that the number 2 refers to the number of successfully decrypted mime parts and not the number of successfully decrypted encryptes multiparts, i.e., if an encrypted multipart contains 4 parts and decryption is successful the field will be Decryption: 4 part(s) decrypted TODO: Add details button listing the names and indexes of the decrypted (or not) mime-parts
This commit is contained in:
parent
ae75060b6a
commit
2d843ca887
|
@ -153,11 +153,10 @@ accumulate_text (MuMsg *msg, MuMsgPart *part, GString **gstrp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* declaration, so we can use it earlier */
|
/* declaration, so we can use it earlier */
|
||||||
static gboolean handle_mime_object (MuMsg *msg,
|
static gboolean
|
||||||
GMimeObject *mobj, GMimeObject *parent,
|
handle_mime_object (MuMsg *msg, GMimeObject *mobj, GMimeObject *parent,
|
||||||
MuMsgOptions opts,
|
MuMsgOptions opts, unsigned *index, gboolean decrypted,
|
||||||
unsigned *index, MuMsgPartForeachFunc func,
|
MuMsgPartForeachFunc func, gpointer user_data);
|
||||||
gpointer user_data);
|
|
||||||
|
|
||||||
static char*
|
static char*
|
||||||
get_text_from_mime_msg (MuMsg *msg, GMimeMessage *mmsg, MuMsgOptions opts)
|
get_text_from_mime_msg (MuMsg *msg, GMimeMessage *mmsg, MuMsgOptions opts)
|
||||||
|
@ -172,6 +171,7 @@ get_text_from_mime_msg (MuMsg *msg, GMimeMessage *mmsg, MuMsgOptions opts)
|
||||||
(GMimeObject *) mmsg,
|
(GMimeObject *) mmsg,
|
||||||
opts,
|
opts,
|
||||||
&index,
|
&index,
|
||||||
|
FALSE,
|
||||||
(MuMsgPartForeachFunc)accumulate_text,
|
(MuMsgPartForeachFunc)accumulate_text,
|
||||||
&gstr);
|
&gstr);
|
||||||
|
|
||||||
|
@ -375,8 +375,7 @@ get_console_pw (const char* user_id, const char *prompt_ctx,
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
handle_encrypted_part (MuMsg *msg,
|
handle_encrypted_part (MuMsg *msg, GMimeMultipartEncrypted *part,
|
||||||
GMimeMultipartEncrypted *part, GMimeObject *parent,
|
|
||||||
MuMsgOptions opts, unsigned *index,
|
MuMsgOptions opts, unsigned *index,
|
||||||
MuMsgPartForeachFunc func, gpointer user_data)
|
MuMsgPartForeachFunc func, gpointer user_data)
|
||||||
{
|
{
|
||||||
|
@ -399,20 +398,20 @@ handle_encrypted_part (MuMsg *msg,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dec) {
|
if (dec) {
|
||||||
rv = handle_mime_object (msg, dec, parent, opts,
|
rv = handle_mime_object (msg, dec, (GMimeObject *) part,
|
||||||
index, func, user_data);
|
opts, index, TRUE, func, user_data);
|
||||||
g_object_unref (dec);
|
g_object_unref (dec);
|
||||||
} else {
|
} else {
|
||||||
// On failure to decrypt, list the encrypted part as
|
// On failure to decrypt list the encrypted part as an
|
||||||
// an attachment
|
// attachment
|
||||||
GMimeObject *encrypted;
|
GMimeObject *encrypted;
|
||||||
|
|
||||||
encrypted = g_mime_multipart_get_part (GMIME_MULTIPART (part), 1);
|
encrypted = g_mime_multipart_get_part (GMIME_MULTIPART (part), 1);
|
||||||
|
|
||||||
g_return_val_if_fail (GMIME_IS_PART(encrypted), FALSE);
|
g_return_val_if_fail (GMIME_IS_PART(encrypted), FALSE);
|
||||||
|
|
||||||
rv = handle_mime_object (msg, encrypted, parent, opts,
|
rv = handle_mime_object (msg, encrypted, (GMimeObject *) part,
|
||||||
index, func, user_data);
|
opts, index, FALSE, func, user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -423,7 +422,7 @@ handle_encrypted_part (MuMsg *msg,
|
||||||
/* call 'func' with information about this MIME-part */
|
/* call 'func' with information about this MIME-part */
|
||||||
static gboolean
|
static gboolean
|
||||||
handle_part (MuMsg *msg, GMimePart *part, GMimeObject *parent,
|
handle_part (MuMsg *msg, GMimePart *part, GMimeObject *parent,
|
||||||
MuMsgOptions opts, unsigned *index,
|
MuMsgOptions opts, unsigned *index, gboolean decrypted,
|
||||||
MuMsgPartForeachFunc func, gpointer user_data)
|
MuMsgPartForeachFunc func, gpointer user_data)
|
||||||
{
|
{
|
||||||
GMimeContentType *ct;
|
GMimeContentType *ct;
|
||||||
|
@ -434,6 +433,12 @@ handle_part (MuMsg *msg, GMimePart *part, GMimeObject *parent,
|
||||||
msgpart.size = get_part_size (part);
|
msgpart.size = get_part_size (part);
|
||||||
msgpart.part_type = MU_MSG_PART_TYPE_LEAF;
|
msgpart.part_type = MU_MSG_PART_TYPE_LEAF;
|
||||||
msgpart.part_type |= get_disposition ((GMimeObject*)part);
|
msgpart.part_type |= get_disposition ((GMimeObject*)part);
|
||||||
|
if (decrypted)
|
||||||
|
msgpart.part_type |= MU_MSG_PART_TYPE_DECRYPTED;
|
||||||
|
else if ((opts & MU_MSG_OPTION_DECRYPT) &&
|
||||||
|
GMIME_IS_MULTIPART_ENCRYPTED (parent))
|
||||||
|
msgpart.part_type |= MU_MSG_PART_TYPE_ENCRYPTED;
|
||||||
|
|
||||||
|
|
||||||
ct = g_mime_object_get_content_type ((GMimeObject*)part);
|
ct = g_mime_object_get_content_type ((GMimeObject*)part);
|
||||||
if (GMIME_IS_CONTENT_TYPE(ct)) {
|
if (GMIME_IS_CONTENT_TYPE(ct)) {
|
||||||
|
@ -466,7 +471,7 @@ handle_part (MuMsg *msg, GMimePart *part, GMimeObject *parent,
|
||||||
/* call 'func' with information about this MIME-part */
|
/* call 'func' with information about this MIME-part */
|
||||||
static gboolean
|
static gboolean
|
||||||
handle_message_part (MuMsg *msg, GMimeMessagePart *mimemsgpart, GMimeObject *parent,
|
handle_message_part (MuMsg *msg, GMimeMessagePart *mimemsgpart, GMimeObject *parent,
|
||||||
MuMsgOptions opts, unsigned *index,
|
MuMsgOptions opts, unsigned *index, gboolean decrypted,
|
||||||
MuMsgPartForeachFunc func, gpointer user_data)
|
MuMsgPartForeachFunc func, gpointer user_data)
|
||||||
{
|
{
|
||||||
MuMsgPart msgpart;
|
MuMsgPart msgpart;
|
||||||
|
@ -494,6 +499,7 @@ handle_message_part (MuMsg *msg, GMimeMessagePart *mimemsgpart, GMimeObject *par
|
||||||
(GMimeObject *) mmsg,
|
(GMimeObject *) mmsg,
|
||||||
opts,
|
opts,
|
||||||
index,
|
index,
|
||||||
|
decrypted,
|
||||||
func,
|
func,
|
||||||
user_data);
|
user_data);
|
||||||
}
|
}
|
||||||
|
@ -503,7 +509,8 @@ handle_message_part (MuMsg *msg, GMimeMessagePart *mimemsgpart, GMimeObject *par
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
handle_multipart (MuMsg *msg, GMimeMultipart *mpart, MuMsgOptions opts,
|
handle_multipart (MuMsg *msg, GMimeMultipart *mpart, MuMsgOptions opts,
|
||||||
unsigned *index, MuMsgPartForeachFunc func, gpointer user_data)
|
unsigned *index, gboolean decrypted,
|
||||||
|
MuMsgPartForeachFunc func, gpointer user_data)
|
||||||
{
|
{
|
||||||
gboolean res;
|
gboolean res;
|
||||||
GMimeObject *part;
|
GMimeObject *part;
|
||||||
|
@ -513,7 +520,8 @@ handle_multipart (MuMsg *msg, GMimeMultipart *mpart, MuMsgOptions opts,
|
||||||
for (i = 0; i < mpart->children->len; i++) {
|
for (i = 0; i < mpart->children->len; i++) {
|
||||||
part = (GMimeObject *) mpart->children->pdata[i];
|
part = (GMimeObject *) mpart->children->pdata[i];
|
||||||
res &= handle_mime_object (msg, part, (GMimeObject *) mpart,
|
res &= handle_mime_object (msg, part, (GMimeObject *) mpart,
|
||||||
opts, index, func, user_data);
|
opts, index, decrypted,
|
||||||
|
func, user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -521,18 +529,18 @@ handle_multipart (MuMsg *msg, GMimeMultipart *mpart, MuMsgOptions opts,
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
handle_mime_object (MuMsg *msg,
|
handle_mime_object (MuMsg *msg, GMimeObject *mobj, GMimeObject *parent,
|
||||||
GMimeObject *mobj, GMimeObject *parent, MuMsgOptions opts,
|
MuMsgOptions opts, unsigned *index, gboolean decrypted,
|
||||||
unsigned *index, MuMsgPartForeachFunc func, gpointer user_data)
|
MuMsgPartForeachFunc func, gpointer user_data)
|
||||||
{
|
{
|
||||||
if (GMIME_IS_PART (mobj))
|
if (GMIME_IS_PART (mobj))
|
||||||
return handle_part
|
return handle_part
|
||||||
(msg, GMIME_PART(mobj), parent,
|
(msg, GMIME_PART(mobj), parent,
|
||||||
opts, index, func, user_data);
|
opts, index, decrypted, func, user_data);
|
||||||
else if (GMIME_IS_MESSAGE_PART (mobj))
|
else if (GMIME_IS_MESSAGE_PART (mobj))
|
||||||
return handle_message_part
|
return handle_message_part
|
||||||
(msg, GMIME_MESSAGE_PART(mobj),
|
(msg, GMIME_MESSAGE_PART(mobj),
|
||||||
parent, opts, index, func, user_data);
|
parent, opts, index, decrypted, func, user_data);
|
||||||
else if ((opts & MU_MSG_OPTION_VERIFY) &&
|
else if ((opts & MU_MSG_OPTION_VERIFY) &&
|
||||||
GMIME_IS_MULTIPART_SIGNED (mobj)) {
|
GMIME_IS_MULTIPART_SIGNED (mobj)) {
|
||||||
gboolean verified, signedpart;
|
gboolean verified, signedpart;
|
||||||
|
@ -543,18 +551,18 @@ handle_mime_object (MuMsg *msg,
|
||||||
// Only process the first part (the second one is the signature)
|
// Only process the first part (the second one is the signature)
|
||||||
signedpart = handle_mime_object
|
signedpart = handle_mime_object
|
||||||
(msg, g_mime_multipart_get_part (GMIME_MULTIPART (mobj), 0),
|
(msg, g_mime_multipart_get_part (GMIME_MULTIPART (mobj), 0),
|
||||||
mobj, opts, index, func, user_data);
|
mobj, opts, index, decrypted, func, user_data);
|
||||||
|
|
||||||
return verified && signedpart;
|
return verified && signedpart;
|
||||||
} else if ((opts & MU_MSG_OPTION_DECRYPT) &&
|
} else if ((opts & MU_MSG_OPTION_DECRYPT) &&
|
||||||
GMIME_IS_MULTIPART_ENCRYPTED (mobj))
|
GMIME_IS_MULTIPART_ENCRYPTED (mobj))
|
||||||
return handle_encrypted_part
|
return handle_encrypted_part
|
||||||
(msg, GMIME_MULTIPART_ENCRYPTED (mobj),
|
(msg, GMIME_MULTIPART_ENCRYPTED (mobj),
|
||||||
parent, opts, index, func, user_data);
|
opts, index, func, user_data);
|
||||||
else if (GMIME_IS_MULTIPART (mobj))
|
else if (GMIME_IS_MULTIPART (mobj))
|
||||||
return handle_multipart
|
return handle_multipart
|
||||||
(msg, GMIME_MULTIPART (mobj),
|
(msg, GMIME_MULTIPART (mobj), opts,
|
||||||
opts, index, func, user_data);
|
index, decrypted, func, user_data);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -576,6 +584,7 @@ mu_msg_part_foreach (MuMsg *msg, MuMsgOptions opts,
|
||||||
(GMimeObject *) msg->_file->_mime_msg,
|
(GMimeObject *) msg->_file->_mime_msg,
|
||||||
opts,
|
opts,
|
||||||
&index,
|
&index,
|
||||||
|
FALSE,
|
||||||
func,
|
func,
|
||||||
user_data);
|
user_data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -300,6 +300,21 @@ sig_verdict (MuMsgPart *mpart)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char*
|
||||||
|
dec_verdict (MuMsgPart *mpart)
|
||||||
|
{
|
||||||
|
MuMsgPartType ptype;
|
||||||
|
|
||||||
|
ptype = mpart->part_type;
|
||||||
|
|
||||||
|
if (ptype & MU_MSG_PART_TYPE_DECRYPTED)
|
||||||
|
return ":decryption succeeded";
|
||||||
|
else if (ptype & MU_MSG_PART_TYPE_ENCRYPTED)
|
||||||
|
return ":decryption failed";
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
get_part_type_string (MuMsgPartType ptype)
|
get_part_type_string (MuMsgPartType ptype)
|
||||||
|
@ -348,7 +363,7 @@ each_part (MuMsg *msg, MuMsgPart *part, PartInfo *pinfo)
|
||||||
tmp = g_strdup_printf
|
tmp = g_strdup_printf
|
||||||
("%s(:index %d :name \"%s\" :mime-type \"%s/%s\"%s%s "
|
("%s(:index %d :name \"%s\" :mime-type \"%s/%s\"%s%s "
|
||||||
":type %s "
|
":type %s "
|
||||||
":attachment %s :size %i %s)",
|
":attachment %s :size %i %s %s)",
|
||||||
pinfo->parts ? pinfo->parts: "",
|
pinfo->parts ? pinfo->parts: "",
|
||||||
part->index,
|
part->index,
|
||||||
name ? name : "noname",
|
name ? name : "noname",
|
||||||
|
@ -358,7 +373,8 @@ each_part (MuMsg *msg, MuMsgPart *part, PartInfo *pinfo)
|
||||||
parttype,
|
parttype,
|
||||||
mu_msg_part_maybe_attachment (part) ? "t" : "nil",
|
mu_msg_part_maybe_attachment (part) ? "t" : "nil",
|
||||||
(int)part->size,
|
(int)part->size,
|
||||||
sig_verdict (part));
|
sig_verdict (part),
|
||||||
|
dec_verdict (part));
|
||||||
|
|
||||||
g_free (pinfo->parts);
|
g_free (pinfo->parts);
|
||||||
pinfo->parts = tmp;
|
pinfo->parts = tmp;
|
||||||
|
|
|
@ -625,6 +625,11 @@ mu4e-compose-mode."
|
||||||
:shortname "Sgn"
|
:shortname "Sgn"
|
||||||
:help "Check for the cryptographic signature"
|
:help "Check for the cryptographic signature"
|
||||||
:sortable nil))
|
:sortable nil))
|
||||||
|
(:decryption .
|
||||||
|
( :name "Decryption"
|
||||||
|
:shortname "Dec"
|
||||||
|
:help "Check the cryptographic decryption status"
|
||||||
|
:sortable nil))
|
||||||
(:size .
|
(:size .
|
||||||
( :name "Size"
|
( :name "Size"
|
||||||
:shortname "Size"
|
:shortname "Size"
|
||||||
|
|
|
@ -50,7 +50,8 @@
|
||||||
:group 'mu4e)
|
:group 'mu4e)
|
||||||
|
|
||||||
(defcustom mu4e-view-fields
|
(defcustom mu4e-view-fields
|
||||||
'(:from :to :cc :subject :flags :date :maildir :mailing-list :tags :attachments :signature)
|
'(:from :to :cc :subject :flags :date :maildir :mailing-list :tags
|
||||||
|
:attachments :signature :decryption)
|
||||||
"Header fields to display in the message view buffer.
|
"Header fields to display in the message view buffer.
|
||||||
For the complete list of available headers, see `mu4e-header-info'."
|
For the complete list of available headers, see `mu4e-header-info'."
|
||||||
:type (list 'symbol)
|
:type (list 'symbol)
|
||||||
|
@ -227,6 +228,8 @@ found."
|
||||||
(:attachments (mu4e~view-construct-attachments-header msg))
|
(:attachments (mu4e~view-construct-attachments-header msg))
|
||||||
;; pgp-signatures
|
;; pgp-signatures
|
||||||
(:signature (mu4e~view-construct-signature-header msg))
|
(:signature (mu4e~view-construct-signature-header msg))
|
||||||
|
;; pgp-decryption
|
||||||
|
(:decryption (mu4e~view-construct-decryption-header msg))
|
||||||
(t (mu4e~view-construct-header field
|
(t (mu4e~view-construct-header field
|
||||||
(mu4e~view-custom-field msg field))))))
|
(mu4e~view-custom-field msg field))))))
|
||||||
mu4e-view-fields "")
|
mu4e-view-fields "")
|
||||||
|
@ -403,6 +406,28 @@ add text-properties to VAL."
|
||||||
(val (when val (concat val " (" btn ")"))))
|
(val (when val (concat val " (" btn ")"))))
|
||||||
(mu4e~view-construct-header :signature val t)))
|
(mu4e~view-construct-header :signature val t)))
|
||||||
|
|
||||||
|
(defun mu4e~view-construct-decryption-header (msg)
|
||||||
|
"Construct a Decryption: header, if there are any encrypted parts."
|
||||||
|
(let* ((parts (mu4e-message-field msg :parts))
|
||||||
|
(verdicts
|
||||||
|
(remove-if 'null
|
||||||
|
(mapcar (lambda (part) (mu4e-message-part-field part :decryption))
|
||||||
|
parts)))
|
||||||
|
(succeeded (remove-if (lambda (v) (eq v 'failed)) verdicts))
|
||||||
|
(failed (remove-if (lambda (v) (eq v 'succeeded)) verdicts))
|
||||||
|
(succ (when succeeded
|
||||||
|
(propertize
|
||||||
|
(concat (number-to-string (length succeeded))
|
||||||
|
" part(s) decrypted")
|
||||||
|
'face 'mu4e-ok-face)))
|
||||||
|
(fail (when failed
|
||||||
|
(propertize
|
||||||
|
(concat (number-to-string (length failed))
|
||||||
|
" part(s) failed")
|
||||||
|
'face 'mu4e-warning-face)))
|
||||||
|
(val (concat succ fail)))
|
||||||
|
(mu4e~view-construct-header :decryption val t)))
|
||||||
|
|
||||||
(defun mu4e~view-open-attach-from-binding ()
|
(defun mu4e~view-open-attach-from-binding ()
|
||||||
"Open the attachement at point, or click location."
|
"Open the attachement at point, or click location."
|
||||||
(interactive)
|
(interactive)
|
||||||
|
|
Loading…
Reference in New Issue