From 29e53d2ebad0722edcc7a6a84cfb971cffd38588 Mon Sep 17 00:00:00 2001 From: "Foivos S. Zakkak" Date: Fri, 10 Oct 2014 07:40:37 +0300 Subject: [PATCH] Fix gpg decryption (#186) After a multipart/encrypted part gets decrypted the result is usually a `multipart/mixed` part (see enigmail). Before this commit mime multiparts where handled only by `g_mime_message_foreach`. As a result the decrypted mime multiparts where not processed. This patch handles mime multiparts explicitly by removing the `g_mime_message_foreach` invocations. This might come at the cost of reduced maintainability, in the case of radical gmime changes. However, gmime is pretty stable and that scenario is highly unlikely. TODO: After decryption make any attachments available --- lib/mu-msg-part.c | 120 +++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 66 deletions(-) diff --git a/lib/mu-msg-part.c b/lib/mu-msg-part.c index f0b60b62..7fe838de 100644 --- a/lib/mu-msg-part.c +++ b/lib/mu-msg-part.c @@ -30,10 +30,6 @@ #include "mu-msg-priv.h" #include "mu-msg-part.h" -static gboolean handle_children (MuMsg *msg, - GMimeMessage *mime_msg, MuMsgOptions opts, - unsigned index, MuMsgPartForeachFunc func, - gpointer user_data); struct _DoData { GMimeObject *mime_obj; unsigned index; @@ -151,6 +147,13 @@ accumulate_text (MuMsg *msg, MuMsgPart *part, GString **gstrp) accumulate_text_part (msg, part, gstrp); } +/* declaration, so we can use it earlier */ +static gboolean handle_mime_object (MuMsg *msg, + GMimeObject *mobj, GMimeObject *parent, + MuMsgOptions opts, + unsigned index, MuMsgPartForeachFunc func, + gpointer user_data); + static char* get_text_from_mime_msg (MuMsg *msg, GMimeMessage *mmsg, MuMsgOptions opts, unsigned index) @@ -158,9 +161,13 @@ get_text_from_mime_msg (MuMsg *msg, GMimeMessage *mmsg, MuMsgOptions opts, GString *gstr; gstr = g_string_sized_new (4096); - handle_children (msg, mmsg, opts, index, - (MuMsgPartForeachFunc)accumulate_text, - &gstr); + handle_mime_object (msg, + mmsg->mime_part, + (GMimeObject *) mmsg, + opts, + 0, + (MuMsgPartForeachFunc)accumulate_text, + &gstr); return g_string_free (gstr, FALSE); } @@ -304,13 +311,6 @@ get_disposition (GMimeObject *mobj) return MU_MSG_PART_TYPE_NONE; } -/* declaration, so we can use it in handle_encrypted_part */ -static gboolean handle_mime_object (MuMsg *msg, - GMimeObject *mobj, GMimeObject *parent, - MuMsgOptions opts, - unsigned index, MuMsgPartForeachFunc func, - gpointer user_data); - #define SIG_STATUS_REPORT "sig-status-report" /* call 'func' with information about this MIME-part */ @@ -418,7 +418,7 @@ handle_part (MuMsg *msg, GMimePart *part, GMimeObject *parent, msgpart.size = get_part_size (part); msgpart.part_type = MU_MSG_PART_TYPE_LEAF; - msgpart.part_type |= get_disposition ((GMimeObject*)part); + msgpart.part_type |= get_disposition ((GMimeObject*)part); ct = g_mime_object_get_content_type ((GMimeObject*)part); if (GMIME_IS_CONTENT_TYPE(ct)) { @@ -474,14 +474,37 @@ handle_message_part (MuMsg *msg, GMimeMessagePart *mimemsgpart, GMimeObject *par GMimeMessage *mmsg; /* this may return NULL for some messages */ mmsg = g_mime_message_part_get_message (mimemsgpart); if (mmsg) - return handle_children - (msg, mmsg, - opts, index, func, user_data); + return handle_mime_object (msg, + mmsg->mime_part, + (GMimeObject *) mmsg, + opts, + index, + func, + user_data); } return TRUE; } +static gboolean +handle_multipart (MuMsg *msg, + GMimeMultipart *mpart, GMimeObject *parent, MuMsgOptions opts, + unsigned index, MuMsgPartForeachFunc func, gpointer user_data) +{ + gboolean res; + GMimeObject *part; + guint i; + + res = TRUE; + for (i = 0; i < mpart->children->len; i++) { + part = (GMimeObject *) mpart->children->pdata[i]; + res &= handle_mime_object (msg, part, (GMimeObject *) mpart, + opts, ++index, func, user_data); + } + + return res; +} + static gboolean handle_mime_object (MuMsg *msg, @@ -497,58 +520,18 @@ handle_mime_object (MuMsg *msg, (msg, GMIME_MESSAGE_PART(mobj), parent, opts, index, func, user_data); else if ((opts & MU_MSG_OPTION_VERIFY) && - GMIME_IS_MULTIPART_SIGNED (mobj)) + GMIME_IS_MULTIPART_SIGNED (mobj)) return check_signature (msg, GMIME_MULTIPART_SIGNED (mobj), opts); else if ((opts & MU_MSG_OPTION_DECRYPT) && - GMIME_IS_MULTIPART_ENCRYPTED (mobj)) + GMIME_IS_MULTIPART_ENCRYPTED (mobj)) return handle_encrypted_part (msg, GMIME_MULTIPART_ENCRYPTED (mobj), parent, opts, index, func, user_data); - return TRUE; -} - -struct _ForeachData { - MuMsgPartForeachFunc func; - gpointer user_data; - MuMsg *msg; - unsigned index; - MuMsgOptions opts; - -}; -typedef struct _ForeachData ForeachData; - -static void -each_child (GMimeObject *parent, GMimeObject *part, - ForeachData *fdata) -{ - handle_mime_object (fdata->msg, - part, - parent, - fdata->opts, - fdata->index++, - fdata->func, - fdata->user_data); -} - - -static gboolean -handle_children (MuMsg *msg, - GMimeMessage *mime_msg, MuMsgOptions opts, - unsigned index, MuMsgPartForeachFunc func, - gpointer user_data) -{ - ForeachData fdata; - - fdata.func = func; - fdata.user_data = user_data; - fdata.opts = opts; - fdata.msg = msg; - fdata.index = 0; - - g_mime_message_foreach (mime_msg, (GMimeObjectForeachFunc)each_child, - &fdata); - + else if (GMIME_IS_MULTIPART (mobj)) + return handle_multipart + (msg, GMIME_MULTIPART (mobj), + parent, opts, index, func, user_data); return TRUE; } @@ -562,8 +545,13 @@ mu_msg_part_foreach (MuMsg *msg, MuMsgOptions opts, if (!mu_msg_load_msg_file (msg, NULL)) return FALSE; - return handle_children (msg, msg->_file->_mime_msg, - opts, 0, func, user_data); + return handle_mime_object (msg, + msg->_file->_mime_msg->mime_part, + (GMimeObject *) msg->_file->_mime_msg, + opts, + 0, + func, + user_data); }