diff --git a/lib/mu-msg-crypto.c b/lib/mu-msg-crypto.c index c4482fd50..4c9b132c9 100644 --- a/lib/mu-msg-crypto.c +++ b/lib/mu-msg-crypto.c @@ -235,7 +235,7 @@ get_digestkey_algo_name (GMimeDigestAlgo algo) /* get data from the 'certificate' */ static char* -get_cert_data (GMimeCertificate *cert) +get_cert_details (GMimeCertificate *cert) { const char /**email,*/ *name, *digest_algo, *pubkey_algo, *keyid, *trust; @@ -274,15 +274,23 @@ get_cert_data (GMimeCertificate *cert) static char* get_verdict_report (GMimeSignature *msig) { - time_t t; - const char *status, *created, *expires; - gchar *certdata, *report; + time_t t; + const char *created, *expires, *verdict; + char *certdata, *report; switch (g_mime_signature_get_status (msig)) { - case GMIME_SIGNATURE_STATUS_GOOD: status = "good"; break; - case GMIME_SIGNATURE_STATUS_ERROR: status = "error"; break; - case GMIME_SIGNATURE_STATUS_BAD: status = "bad"; break; - default: g_return_val_if_reached (NULL); + case GMIME_SIGNATURE_STATUS_GOOD: + verdict = "good"; + break; + case GMIME_SIGNATURE_STATUS_ERROR: + verdict = "error"; + break; + case GMIME_SIGNATURE_STATUS_BAD: + verdict = "bad"; + break; + default: + g_return_val_if_reached (NULL); + return NULL; } t = g_mime_signature_get_created (msig); @@ -291,41 +299,69 @@ get_verdict_report (GMimeSignature *msig) t = g_mime_signature_get_expires (msig); expires = (t == 0 || t == (time_t)-1) ? "?" : mu_date_str_s ("%x", t); - certdata = get_cert_data (g_mime_signature_get_certificate (msig)); - report = g_strdup_printf ("%s; created:%s, expires:%s, %s", - status, created, expires, + certdata = get_cert_details (g_mime_signature_get_certificate (msig)); + report = g_strdup_printf ("%s\ncreated:%s, expires:%s, %s", + verdict, created, expires, certdata ? certdata : "?"); g_free (certdata); + return report; } +static char* +get_signers (GHashTable *signerhash) +{ + GString *gstr; + GHashTableIter iter; + const char *name; + + if (!signerhash || g_hash_table_size(signerhash) == 0) + return NULL; + + gstr = g_string_new (NULL); + g_hash_table_iter_init (&iter, signerhash); + while (g_hash_table_iter_next (&iter, (gpointer)&name, NULL)) { + if (gstr->len != 0) + g_string_append_c (gstr, ','); + gstr = g_string_append (gstr, name); + } + + return g_string_free (gstr, FALSE); +} + static MuMsgPartSigStatusReport* get_status_report (GMimeSignatureList *sigs) { - int i; - MuMsgPartSigStatus status; - MuMsgPartSigStatusReport *status_report; - char *report; + int i; + MuMsgPartSigStatus status; + MuMsgPartSigStatusReport *status_report; + char *report; + GHashTable *signerhash; - status = MU_MSG_PART_SIG_STATUS_GOOD; /* let's start positive! */ + status = MU_MSG_PART_SIG_STATUS_GOOD; /* let's start positive! */ + signerhash = g_hash_table_new (g_str_hash, g_str_equal); for (i = 0, report = NULL; i != g_mime_signature_list_length (sigs); ++i) { - GMimeSignature *msig; - GMimeSignatureStatus sigstat; - gchar *rep; + GMimeSignature *msig; + GMimeCertificate *cert; + GMimeSignatureStatus sigstat; + gchar *rep; msig = g_mime_signature_list_get_signature (sigs, i); sigstat = g_mime_signature_get_status (msig); switch (sigstat) { - case GMIME_SIGNATURE_STATUS_GOOD: break; + case GMIME_SIGNATURE_STATUS_GOOD: + break; case GMIME_SIGNATURE_STATUS_ERROR: - status = MU_MSG_PART_SIG_STATUS_ERROR; break; + status = MU_MSG_PART_SIG_STATUS_ERROR; + break; case GMIME_SIGNATURE_STATUS_BAD: - status = MU_MSG_PART_SIG_STATUS_BAD; break; + status = MU_MSG_PART_SIG_STATUS_BAD; + break; default: g_return_val_if_reached (NULL); } @@ -335,11 +371,21 @@ get_status_report (GMimeSignatureList *sigs) report ? "; " : "", i + 1, rep); g_free (rep); + + cert = g_mime_signature_get_certificate (msig); + if (cert && g_mime_certificate_get_name (cert)) + g_hash_table_add ( + signerhash, + (gpointer)g_mime_certificate_get_name (cert)); } - status_report = g_slice_new (MuMsgPartSigStatusReport); + status_report = g_slice_new0 (MuMsgPartSigStatusReport); + status_report->verdict = status; status_report->report = report; + status_report->signers = get_signers(signerhash); + + g_hash_table_unref (signerhash); return status_report; } @@ -351,6 +397,8 @@ mu_msg_part_sig_status_report_destroy (MuMsgPartSigStatusReport *report) return; g_free ((char*)report->report); + g_free ((char*)report->signers); + g_slice_free (MuMsgPartSigStatusReport, report); } diff --git a/lib/mu-msg-part.h b/lib/mu-msg-part.h index 23bfaac82..4f26ddf34 100644 --- a/lib/mu-msg-part.h +++ b/lib/mu-msg-part.h @@ -65,11 +65,11 @@ enum _MuMsgPartSigStatus { }; typedef enum _MuMsgPartSigStatus MuMsgPartSigStatus; -struct _MuMsgPartSigStatusReport { - MuMsgPartSigStatus verdict; - const char *report; -}; -typedef struct _MuMsgPartSigStatusReport MuMsgPartSigStatusReport; +typedef struct { + MuMsgPartSigStatus verdict; + const char *report; + const char *signers; +} MuMsgPartSigStatusReport; /** * destroy a MuMsgPartSignatureStatusReport object @@ -178,7 +178,7 @@ gboolean mu_msg_part_save (MuMsg *msg, MuMsgOptions opts, */ gchar* mu_msg_part_save_temp (MuMsg *msg, MuMsgOptions opts, guint partidx, GError **err) - G_GNUC_WARN_UNUSED_RESULT; + G_GNUC_WARN_UNUSED_RESULT; @@ -217,7 +217,7 @@ gchar* mu_msg_part_get_path (MuMsg *msg, MuMsgOptions opts, */ gchar* mu_msg_part_get_cache_path (MuMsg *msg, MuMsgOptions opts, guint partidx, GError **err) - G_GNUC_WARN_UNUSED_RESULT; + G_GNUC_WARN_UNUSED_RESULT; /** diff --git a/lib/mu-msg-sexp.c b/lib/mu-msg-sexp.c index 53941a6df..cef940ece 100644 --- a/lib/mu-msg-sexp.c +++ b/lib/mu-msg-sexp.c @@ -279,25 +279,40 @@ struct _PartInfo { }; typedef struct _PartInfo PartInfo; -static const char* +static char* sig_verdict (MuMsgPart *mpart) { - MuMsgPartSigStatusReport *report; + char *signers, *s; + const char *verdict; + MuMsgPartSigStatusReport *report; report = mpart->sig_status_report; if (!report) - return ""; + return g_strdup (""); switch (report->verdict) { case MU_MSG_PART_SIG_STATUS_GOOD: - return ":signature verified"; + verdict = ":signature verified"; + break; case MU_MSG_PART_SIG_STATUS_BAD: - return ":signature bad"; + verdict = ":signature bad"; + break; case MU_MSG_PART_SIG_STATUS_ERROR: - return ":signature unverified"; + verdict = ":signature unverified"; + break; default: - return ""; + verdict = ""; + break; } + + if (!report->signers) + return g_strdup (verdict); + + signers = mu_str_escape_c_literal (report->signers, TRUE); + s = g_strdup_printf ("%s :signers %s", verdict, signers); + g_free (signers); + + return s; } static const char* @@ -354,7 +369,7 @@ static void each_part (MuMsg *msg, MuMsgPart *part, PartInfo *pinfo) { char *name, *encname, *tmp, *parttype; - char *tmpfile, *cid; + char *tmpfile, *cid, *verdict; name = mu_msg_part_get_filename (part, TRUE); encname = name ? @@ -364,9 +379,11 @@ each_part (MuMsg *msg, MuMsgPart *part, PartInfo *pinfo) tmpfile = get_temp_file_maybe (msg, part, pinfo->opts); parttype = get_part_type_string (part->part_type); + verdict = sig_verdict (part); cid = mu_str_escape_c_literal(mu_msg_part_get_content_id(part), TRUE); + tmp = g_strdup_printf ("%s(:index %d :name %s :mime-type \"%s/%s\"%s%s " ":type %s " @@ -381,12 +398,13 @@ each_part (MuMsg *msg, MuMsgPart *part, PartInfo *pinfo) mu_msg_part_maybe_attachment (part) ? "t" : "nil", cid ? " :cid" : "", cid ? cid : "", (int)part->size, - sig_verdict (part), + verdict, dec_verdict (part)); g_free (encname); g_free (tmpfile); g_free (parttype); + g_free (verdict); g_free (cid); g_free (pinfo->parts);