diff --git a/lib/mu-msg-part.c b/lib/mu-msg-part.c index deb99217..b52f70d3 100644 --- a/lib/mu-msg-part.c +++ b/lib/mu-msg-part.c @@ -31,6 +31,11 @@ #include "mu-msg-priv.h" #include "mu-msg-part.h" +#ifdef BUILD_CRYPTO +#include "mu-msg-crypto.h" +#endif /*BUILD_CRYPTO*/ + + struct _FindPartData { guint idx, wanted_idx; GMimeObject *part; @@ -83,7 +88,7 @@ struct _PartData { MuMsgPartForeachFunc _func; gpointer _user_data; GMimePart *_body_part; - gboolean _recurse_rfc822; + MuMsgPartOptions _opts; }; typedef struct _PartData PartData; @@ -231,9 +236,42 @@ msg_part_free (MuMsgPart *pi) g_free (pi->file_name); g_free (pi->description); + +#ifdef BUILD_CRYPTO + mu_msg_part_free_sig_infos (pi->sig_infos); +#endif /*BUILD_CRYPTO*/ } +static void +check_signature_maybe (GMimeObject *parent, GMimeObject *mobj, MuMsgPart *pi, + MuMsgPartOptions opts) +{ +#ifdef BUILD_CRYPTO + GError *err; + err = NULL; + + if (!GMIME_IS_MULTIPART_SIGNED (parent)) + return; + + /* we're interested in the signed thing here, not the + * signature itself */ + if (g_mime_content_type_is_type ( + g_mime_object_get_content_type (mobj), + "application", "pgp-signature")) + return; + + pi->sig_infos = mu_msg_mime_sig_infos + (GMIME_MULTIPART_SIGNED (parent), opts, &err); + if (err) { + g_warning ("error verifying signature: %s", err->message); + g_clear_error (&err); + } +#endif /*BUILD_CRYPTO*/ + + return; +} + static void part_foreach_cb (GMimeObject *parent, GMimeObject *mobj, PartData *pdata) @@ -260,7 +298,7 @@ part_foreach_cb (GMimeObject *parent, GMimeObject *mobj, PartData *pdata) if (!mmsg) return; rv = init_msg_part_from_mime_message_part (mmsg, &pi); - if (rv && pdata->_recurse_rfc822) + if (rv && (pdata->_opts && MU_MSG_PART_OPTION_RECURSE_RFC822)) /* NOTE: this screws up the counting (pdata->_idx) */ g_mime_message_foreach /* recurse */ (mmsg, (GMimeObjectForeachFunc)part_foreach_cb, @@ -268,6 +306,10 @@ part_foreach_cb (GMimeObject *parent, GMimeObject *mobj, PartData *pdata) } else rv = FALSE; /* ignore */ + /* if we have crypto support, check the signature if there is one */ + if (pdata->_opts & MU_MSG_PART_OPTION_CHECK_SIGNATURES) + check_signature_maybe (parent, mobj, &pi, pdata->_opts); + if (rv) pdata->_func(pdata->_msg, &pi, pdata->_user_data); @@ -276,8 +318,8 @@ part_foreach_cb (GMimeObject *parent, GMimeObject *mobj, PartData *pdata) void -mu_msg_part_foreach (MuMsg *msg, gboolean recurse_rfc822, - MuMsgPartForeachFunc func, gpointer user_data) +mu_msg_part_foreach (MuMsg *msg, MuMsgPartForeachFunc func, gpointer user_data, + MuMsgPartOptions opts) { PartData pdata; GMimeMessage *mime_msg; @@ -294,7 +336,7 @@ mu_msg_part_foreach (MuMsg *msg, gboolean recurse_rfc822, pdata._body_part = mu_msg_mime_get_body_part (mime_msg, FALSE); pdata._func = func; pdata._user_data = user_data; - pdata._recurse_rfc822 = recurse_rfc822; + pdata._opts = opts; g_mime_message_foreach (msg->_file->_mime_msg, (GMimeObjectForeachFunc)part_foreach_cb, @@ -496,7 +538,7 @@ mu_msg_part_save (MuMsg *msg, const char *fullpath, guint partidx, g_return_val_if_fail (fullpath, FALSE); g_return_val_if_fail (!overwrite||!use_cached, FALSE); - if (!mu_msg_load_msg_file (msg, NULL)) + if (!mu_msg_load_msg_file (msg, err)) return FALSE; part = find_part (msg, partidx); @@ -644,6 +686,7 @@ mu_msg_part_find_files (MuMsg *msg, const GRegex *pattern) g_return_val_if_fail (msg, NULL); g_return_val_if_fail (pattern, NULL); + if (!mu_msg_load_msg_file (msg, NULL)) return NULL; diff --git a/lib/mu-msg-part.h b/lib/mu-msg-part.h index 35e5ba80..5870199a 100644 --- a/lib/mu-msg-part.h +++ b/lib/mu-msg-part.h @@ -29,7 +29,7 @@ G_BEGIN_DECLS struct _MuMsgPart { - /* index of this message */ + /* index of this message part */ unsigned index; /* cid */ @@ -61,6 +61,9 @@ struct _MuMsgPart { * Part), not eg. a multipart/ */ gboolean is_msg; /* part is a message/rfc822 */ + /* crypto stuff */ + GSList *sig_infos; /* list of MuMsgPartSig */ + /* if TRUE, mu_msg_part_destroy will free the member vars * as well*/ gboolean own_members; @@ -206,20 +209,32 @@ GSList* mu_msg_part_find_files (MuMsg *msg, const GRegex *pattern); typedef void (*MuMsgPartForeachFunc) (MuMsg*, MuMsgPart*, gpointer); + + +enum _MuMsgPartOptions { + MU_MSG_PART_OPTION_NONE = 0, + MU_MSG_PART_OPTION_RECURSE_RFC822 = 1 << 0, /* recurse into submessages */ + + /* below options are for checking signatures; only effective + * if mu was built with crypto support */ + MU_MSG_PART_OPTION_CHECK_SIGNATURES = 1 << 1, + MU_MSG_PART_OPTION_AUTO_RETRIEVE_KEY = 1 << 2, + MU_MSG_PART_OPTION_USE_AGENT = 1 << 3 +}; +typedef enum _MuMsgPartOptions MuMsgPartOptions; + /** * call a function for each of the mime part in a message * * @param msg a valid MuMsg* instance - * @param recurse_rfc822 whether to recurse into message/rfc822 parts - * generallly, this is only needed when indexing message contents * @param func a callback function to call for each contact; when * the callback does not return TRUE, it won't be called again * @param user_data a user-provide pointer that will be passed to the callback + * @param options, bit-wise OR'ed * */ -void mu_msg_part_foreach (MuMsg *msg, gboolean recurse_rfc822, - MuMsgPartForeachFunc func, - gpointer user_data); +void mu_msg_part_foreach (MuMsg *msg, MuMsgPartForeachFunc func, gpointer user_data, + MuMsgPartOptions opts); G_END_DECLS diff --git a/lib/mu-msg-priv.h b/lib/mu-msg-priv.h index dd93a695..256e53cf 100644 --- a/lib/mu-msg-priv.h +++ b/lib/mu-msg-priv.h @@ -22,6 +22,10 @@ #ifndef __MU_MSG_PRIV_H__ #define __MU_MSG_PRIV_H__ +#if HAVE_CONFIG_H +#include "config.h" +#endif /*HAVE_CONFIG_H*/ + #include #include @@ -29,6 +33,7 @@ #include #include #include +#include "mu-msg-part.h" G_BEGIN_DECLS @@ -81,6 +86,22 @@ gchar* mu_msg_mime_part_to_string (GMimePart *part, gboolean *err); */ GMimePart* mu_msg_mime_get_body_part (GMimeMessage *msg, gboolean want_html); - G_END_DECLS + +#ifdef BUILD_CRYPTO +/** + * get signature information for the mime part + * + * @param part a multipart/sigde part + * @param opts options for the signature verification (we only use the + * crypto-related options in opts) + * @param err receives error info + * + * @return a list of MuMsgPartSig, or NULL + */ +GSList* mu_msg_mime_sig_infos (GMimeMultipartSigned *sigmpart, + MuMsgPartOptions opts, GError **err); +#endif /*BUILD_CRYPTO*/ + +G_END_DECLS #endif /*__MU_MSG_PRIV_H__*/