mu: include signers in signature report
Include the names/email address of signer in the reports, so we can use them in mu4e.
This commit is contained in:
@ -235,7 +235,7 @@ get_digestkey_algo_name (GMimeDigestAlgo algo)
|
|||||||
|
|
||||||
/* get data from the 'certificate' */
|
/* get data from the 'certificate' */
|
||||||
static char*
|
static char*
|
||||||
get_cert_data (GMimeCertificate *cert)
|
get_cert_details (GMimeCertificate *cert)
|
||||||
{
|
{
|
||||||
const char /**email,*/ *name, *digest_algo, *pubkey_algo,
|
const char /**email,*/ *name, *digest_algo, *pubkey_algo,
|
||||||
*keyid, *trust;
|
*keyid, *trust;
|
||||||
@ -274,15 +274,23 @@ get_cert_data (GMimeCertificate *cert)
|
|||||||
static char*
|
static char*
|
||||||
get_verdict_report (GMimeSignature *msig)
|
get_verdict_report (GMimeSignature *msig)
|
||||||
{
|
{
|
||||||
time_t t;
|
time_t t;
|
||||||
const char *status, *created, *expires;
|
const char *created, *expires, *verdict;
|
||||||
gchar *certdata, *report;
|
char *certdata, *report;
|
||||||
|
|
||||||
switch (g_mime_signature_get_status (msig)) {
|
switch (g_mime_signature_get_status (msig)) {
|
||||||
case GMIME_SIGNATURE_STATUS_GOOD: status = "good"; break;
|
case GMIME_SIGNATURE_STATUS_GOOD:
|
||||||
case GMIME_SIGNATURE_STATUS_ERROR: status = "error"; break;
|
verdict = "good";
|
||||||
case GMIME_SIGNATURE_STATUS_BAD: status = "bad"; break;
|
break;
|
||||||
default: g_return_val_if_reached (NULL);
|
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);
|
t = g_mime_signature_get_created (msig);
|
||||||
@ -291,41 +299,69 @@ get_verdict_report (GMimeSignature *msig)
|
|||||||
t = g_mime_signature_get_expires (msig);
|
t = g_mime_signature_get_expires (msig);
|
||||||
expires = (t == 0 || t == (time_t)-1) ? "?" : mu_date_str_s ("%x", t);
|
expires = (t == 0 || t == (time_t)-1) ? "?" : mu_date_str_s ("%x", t);
|
||||||
|
|
||||||
certdata = get_cert_data (g_mime_signature_get_certificate (msig));
|
certdata = get_cert_details (g_mime_signature_get_certificate (msig));
|
||||||
report = g_strdup_printf ("%s; created:%s, expires:%s, %s",
|
report = g_strdup_printf ("%s\ncreated:%s, expires:%s, %s",
|
||||||
status, created, expires,
|
verdict, created, expires,
|
||||||
certdata ? certdata : "?");
|
certdata ? certdata : "?");
|
||||||
g_free (certdata);
|
g_free (certdata);
|
||||||
|
|
||||||
return report;
|
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*
|
static MuMsgPartSigStatusReport*
|
||||||
get_status_report (GMimeSignatureList *sigs)
|
get_status_report (GMimeSignatureList *sigs)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
MuMsgPartSigStatus status;
|
MuMsgPartSigStatus status;
|
||||||
MuMsgPartSigStatusReport *status_report;
|
MuMsgPartSigStatusReport *status_report;
|
||||||
char *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);
|
for (i = 0, report = NULL; i != g_mime_signature_list_length (sigs);
|
||||||
++i) {
|
++i) {
|
||||||
|
|
||||||
GMimeSignature *msig;
|
GMimeSignature *msig;
|
||||||
GMimeSignatureStatus sigstat;
|
GMimeCertificate *cert;
|
||||||
gchar *rep;
|
GMimeSignatureStatus sigstat;
|
||||||
|
gchar *rep;
|
||||||
|
|
||||||
msig = g_mime_signature_list_get_signature (sigs, i);
|
msig = g_mime_signature_list_get_signature (sigs, i);
|
||||||
sigstat = g_mime_signature_get_status (msig);
|
sigstat = g_mime_signature_get_status (msig);
|
||||||
|
|
||||||
switch (sigstat) {
|
switch (sigstat) {
|
||||||
case GMIME_SIGNATURE_STATUS_GOOD: break;
|
case GMIME_SIGNATURE_STATUS_GOOD:
|
||||||
|
break;
|
||||||
case GMIME_SIGNATURE_STATUS_ERROR:
|
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:
|
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);
|
default: g_return_val_if_reached (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,11 +371,21 @@ get_status_report (GMimeSignatureList *sigs)
|
|||||||
report ? "; " : "", i + 1,
|
report ? "; " : "", i + 1,
|
||||||
rep);
|
rep);
|
||||||
g_free (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->verdict = status;
|
||||||
status_report->report = report;
|
status_report->report = report;
|
||||||
|
status_report->signers = get_signers(signerhash);
|
||||||
|
|
||||||
|
g_hash_table_unref (signerhash);
|
||||||
|
|
||||||
return status_report;
|
return status_report;
|
||||||
}
|
}
|
||||||
@ -351,6 +397,8 @@ mu_msg_part_sig_status_report_destroy (MuMsgPartSigStatusReport *report)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
g_free ((char*)report->report);
|
g_free ((char*)report->report);
|
||||||
|
g_free ((char*)report->signers);
|
||||||
|
|
||||||
g_slice_free (MuMsgPartSigStatusReport, report);
|
g_slice_free (MuMsgPartSigStatusReport, report);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -65,11 +65,11 @@ enum _MuMsgPartSigStatus {
|
|||||||
};
|
};
|
||||||
typedef enum _MuMsgPartSigStatus MuMsgPartSigStatus;
|
typedef enum _MuMsgPartSigStatus MuMsgPartSigStatus;
|
||||||
|
|
||||||
struct _MuMsgPartSigStatusReport {
|
typedef struct {
|
||||||
MuMsgPartSigStatus verdict;
|
MuMsgPartSigStatus verdict;
|
||||||
const char *report;
|
const char *report;
|
||||||
};
|
const char *signers;
|
||||||
typedef struct _MuMsgPartSigStatusReport MuMsgPartSigStatusReport;
|
} MuMsgPartSigStatusReport;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* destroy a MuMsgPartSignatureStatusReport object
|
* 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,
|
gchar* mu_msg_part_save_temp (MuMsg *msg, MuMsgOptions opts,
|
||||||
guint partidx, GError **err)
|
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,
|
gchar* mu_msg_part_get_cache_path (MuMsg *msg, MuMsgOptions opts,
|
||||||
guint partidx, GError **err)
|
guint partidx, GError **err)
|
||||||
G_GNUC_WARN_UNUSED_RESULT;
|
G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -279,25 +279,40 @@ struct _PartInfo {
|
|||||||
};
|
};
|
||||||
typedef struct _PartInfo PartInfo;
|
typedef struct _PartInfo PartInfo;
|
||||||
|
|
||||||
static const char*
|
static char*
|
||||||
sig_verdict (MuMsgPart *mpart)
|
sig_verdict (MuMsgPart *mpart)
|
||||||
{
|
{
|
||||||
MuMsgPartSigStatusReport *report;
|
char *signers, *s;
|
||||||
|
const char *verdict;
|
||||||
|
MuMsgPartSigStatusReport *report;
|
||||||
|
|
||||||
report = mpart->sig_status_report;
|
report = mpart->sig_status_report;
|
||||||
if (!report)
|
if (!report)
|
||||||
return "";
|
return g_strdup ("");
|
||||||
|
|
||||||
switch (report->verdict) {
|
switch (report->verdict) {
|
||||||
case MU_MSG_PART_SIG_STATUS_GOOD:
|
case MU_MSG_PART_SIG_STATUS_GOOD:
|
||||||
return ":signature verified";
|
verdict = ":signature verified";
|
||||||
|
break;
|
||||||
case MU_MSG_PART_SIG_STATUS_BAD:
|
case MU_MSG_PART_SIG_STATUS_BAD:
|
||||||
return ":signature bad";
|
verdict = ":signature bad";
|
||||||
|
break;
|
||||||
case MU_MSG_PART_SIG_STATUS_ERROR:
|
case MU_MSG_PART_SIG_STATUS_ERROR:
|
||||||
return ":signature unverified";
|
verdict = ":signature unverified";
|
||||||
|
break;
|
||||||
default:
|
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*
|
static const char*
|
||||||
@ -354,7 +369,7 @@ static void
|
|||||||
each_part (MuMsg *msg, MuMsgPart *part, PartInfo *pinfo)
|
each_part (MuMsg *msg, MuMsgPart *part, PartInfo *pinfo)
|
||||||
{
|
{
|
||||||
char *name, *encname, *tmp, *parttype;
|
char *name, *encname, *tmp, *parttype;
|
||||||
char *tmpfile, *cid;
|
char *tmpfile, *cid, *verdict;
|
||||||
|
|
||||||
name = mu_msg_part_get_filename (part, TRUE);
|
name = mu_msg_part_get_filename (part, TRUE);
|
||||||
encname = name ?
|
encname = name ?
|
||||||
@ -364,9 +379,11 @@ each_part (MuMsg *msg, MuMsgPart *part, PartInfo *pinfo)
|
|||||||
|
|
||||||
tmpfile = get_temp_file_maybe (msg, part, pinfo->opts);
|
tmpfile = get_temp_file_maybe (msg, part, pinfo->opts);
|
||||||
parttype = get_part_type_string (part->part_type);
|
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),
|
cid = mu_str_escape_c_literal(mu_msg_part_get_content_id(part),
|
||||||
TRUE);
|
TRUE);
|
||||||
|
|
||||||
|
|
||||||
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 "
|
||||||
@ -381,12 +398,13 @@ each_part (MuMsg *msg, MuMsgPart *part, PartInfo *pinfo)
|
|||||||
mu_msg_part_maybe_attachment (part) ? "t" : "nil",
|
mu_msg_part_maybe_attachment (part) ? "t" : "nil",
|
||||||
cid ? " :cid" : "", cid ? cid : "",
|
cid ? " :cid" : "", cid ? cid : "",
|
||||||
(int)part->size,
|
(int)part->size,
|
||||||
sig_verdict (part),
|
verdict,
|
||||||
dec_verdict (part));
|
dec_verdict (part));
|
||||||
|
|
||||||
g_free (encname);
|
g_free (encname);
|
||||||
g_free (tmpfile);
|
g_free (tmpfile);
|
||||||
g_free (parttype);
|
g_free (parttype);
|
||||||
|
g_free (verdict);
|
||||||
g_free (cid);
|
g_free (cid);
|
||||||
|
|
||||||
g_free (pinfo->parts);
|
g_free (pinfo->parts);
|
||||||
|
|||||||
Reference in New Issue
Block a user