static GMimeSignatureStatus get_sig_status (GMimeSignatureList *signatures) { GMimeSignatureStatus status = 0; GMimeSignature *sig; int i; if (!signatures || signatures->array->len == 0) return GMIME_SIGNATURE_STATUS_RED; for (i = 0; i < g_mime_signature_list_length (signatures); i++) { sig = g_mime_signature_list_get_signature (signatures, i); status |= g_mime_signature_get_status (sig); } return status; }
static MuMsgPartSigStatusReport* get_status_report (GMimeSignatureList *sigs) { int i; MuMsgPartSigStatus status; MuMsgPartSigStatusReport *status_report; char *report; status = MU_MSG_PART_SIG_STATUS_GOOD; /* let's start positive! */ for (i = 0, report = NULL; i != g_mime_signature_list_length (sigs); ++i) { GMimeSignature *msig; 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_ERROR: status = MU_MSG_PART_SIG_STATUS_ERROR; break; case GMIME_SIGNATURE_STATUS_BAD: status = MU_MSG_PART_SIG_STATUS_BAD; break; default: g_return_val_if_reached (NULL); } rep = get_verdict_report (msig); report = g_strdup_printf ("%s%s%d: %s", report ? report : "", report ? "; " : "", i + 1, rep); g_free (rep); } status_report = g_slice_new (MuMsgPartSigStatusReport); status_report->verdict = status; status_report->report = report; return status_report; }
GSList* mu_msg_mime_sig_infos (GMimeMultipartSigned *sigmpart, MuMsgOptions opts, GError **err) { int i; GMimeSignatureList *sigs; GMimeCryptoContext *cctx; GSList *siginfos; if (!GMIME_IS_MULTIPART_SIGNED (sigmpart)) { mu_util_g_set_error (err, MU_ERROR_IN_PARAMETERS, "not a multipart/signed part"); return NULL; /* error */ } /* dummy is good, since we don't need a password when checking * signatures */ cctx = get_crypto_context (opts, dummy_password_func, NULL, err); if (!cctx) /* return a fake siginfos with the error */ return error_sig_infos (); /* error */ sigs = g_mime_multipart_signed_verify (sigmpart, cctx, err); g_object_unref (cctx); if (!sigs) return NULL; /* error */ for (i = 0, siginfos = NULL; i != g_mime_signature_list_length (sigs); ++i) { MuMsgPartSigInfo *siginfo; siginfo = sig_info_new (g_mime_signature_list_get_signature (sigs, i)); siginfos = g_slist_prepend (siginfos, siginfo); } return siginfos; }
static void format_part_sigstatus_json (mime_node_t *node) { GMimeSignatureList *siglist = node->sig_list; printf ("["); if (!siglist) { printf ("]"); return; } void *ctx_quote = talloc_new (NULL); int i; for (i = 0; i < g_mime_signature_list_length (siglist); i++) { GMimeSignature *signature = g_mime_signature_list_get_signature (siglist, i); if (i > 0) printf (", "); printf ("{"); /* status */ GMimeSignatureStatus status = g_mime_signature_get_status (signature); printf ("\"status\": %s", json_quote_str (ctx_quote, signature_status_to_string (status))); GMimeCertificate *certificate = g_mime_signature_get_certificate (signature); if (status == GMIME_SIGNATURE_STATUS_GOOD) { if (certificate) printf (", \"fingerprint\": %s", json_quote_str (ctx_quote, g_mime_certificate_get_fingerprint (certificate))); /* these dates are seconds since the epoch; should we * provide a more human-readable format string? */ time_t created = g_mime_signature_get_created (signature); if (created != -1) printf (", \"created\": %d", (int) created); time_t expires = g_mime_signature_get_expires (signature); if (expires > 0) printf (", \"expires\": %d", (int) expires); /* output user id only if validity is FULL or ULTIMATE. */ /* note that gmime is using the term "trust" here, which * is WRONG. It's actually user id "validity". */ if (certificate) { const char *name = g_mime_certificate_get_name (certificate); GMimeCertificateTrust trust = g_mime_certificate_get_trust (certificate); if (name && (trust == GMIME_CERTIFICATE_TRUST_FULLY || trust == GMIME_CERTIFICATE_TRUST_ULTIMATE)) printf (", \"userid\": %s", json_quote_str (ctx_quote, name)); } } else if (certificate) { const char *key_id = g_mime_certificate_get_key_id (certificate); if (key_id) printf (", \"keyid\": %s", json_quote_str (ctx_quote, key_id)); } GMimeSignatureError errors = g_mime_signature_get_errors (signature); if (errors != GMIME_SIGNATURE_ERROR_NONE) { printf (", \"errors\": %d", errors); } printf ("}"); } printf ("]"); talloc_free (ctx_quote); }
/* Signature status sprinter (GMime 2.6) */ static void format_part_sigstatus_sprinter (sprinter_t *sp, mime_node_t *node) { /* Any changes to the JSON or S-Expression format should be * reflected in the file devel/schemata. */ GMimeSignatureList *siglist = node->sig_list; sp->begin_list (sp); if (!siglist) { sp->end (sp); return; } int i; for (i = 0; i < g_mime_signature_list_length (siglist); i++) { GMimeSignature *signature = g_mime_signature_list_get_signature (siglist, i); sp->begin_map (sp); /* status */ GMimeSignatureStatus status = g_mime_signature_get_status (signature); sp->map_key (sp, "status"); sp->string (sp, signature_status_to_string (status)); GMimeCertificate *certificate = g_mime_signature_get_certificate (signature); if (status == GMIME_SIGNATURE_STATUS_GOOD) { if (certificate) { sp->map_key (sp, "fingerprint"); sp->string (sp, g_mime_certificate_get_fingerprint (certificate)); } /* these dates are seconds since the epoch; should we * provide a more human-readable format string? */ time_t created = g_mime_signature_get_created (signature); if (created != -1) { sp->map_key (sp, "created"); sp->integer (sp, created); } time_t expires = g_mime_signature_get_expires (signature); if (expires > 0) { sp->map_key (sp, "expires"); sp->integer (sp, expires); } /* output user id only if validity is FULL or ULTIMATE. */ /* note that gmime is using the term "trust" here, which * is WRONG. It's actually user id "validity". */ if (certificate) { const char *name = g_mime_certificate_get_name (certificate); GMimeCertificateTrust trust = g_mime_certificate_get_trust (certificate); if (name && (trust == GMIME_CERTIFICATE_TRUST_FULLY || trust == GMIME_CERTIFICATE_TRUST_ULTIMATE)) { sp->map_key (sp, "userid"); sp->string (sp, name); } } } else if (certificate) { const char *key_id = g_mime_certificate_get_key_id (certificate); if (key_id) { sp->map_key (sp, "keyid"); sp->string (sp, key_id); } } GMimeSignatureError errors = g_mime_signature_get_errors (signature); if (errors != GMIME_SIGNATURE_ERROR_NONE) { sp->map_key (sp, "errors"); sp->integer (sp, errors); } sp->end (sp); } sp->end (sp); }