mirror of https://github.com/djcb/mu.git
* restore mu-verify (WIP)
This commit is contained in:
parent
90290a132c
commit
14661a6d7b
|
@ -145,50 +145,207 @@ get_crypto_context (MuMsgOptions opts, MuMsgPartPasswordFunc password_func,
|
||||||
return cctx;
|
return cctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char*
|
||||||
static MuMsgPartSigStatus
|
get_pubkey_algo_name (GMimePubKeyAlgo algo)
|
||||||
get_verdict (GMimeSignatureList *sigs)
|
|
||||||
{
|
{
|
||||||
int i;
|
switch (algo) {
|
||||||
MuMsgPartSigStatus status;
|
case GMIME_PUBKEY_ALGO_DEFAULT:
|
||||||
|
return "default";
|
||||||
|
case GMIME_PUBKEY_ALGO_RSA:
|
||||||
|
return "RSA";
|
||||||
|
case GMIME_PUBKEY_ALGO_RSA_E:
|
||||||
|
return "RSA (encryption only)";
|
||||||
|
case GMIME_PUBKEY_ALGO_RSA_S:
|
||||||
|
return "RSA (signing only)";
|
||||||
|
case GMIME_PUBKEY_ALGO_ELG_E:
|
||||||
|
return "ElGamal (encryption only)";
|
||||||
|
case GMIME_PUBKEY_ALGO_DSA:
|
||||||
|
return "DSA";
|
||||||
|
case GMIME_PUBKEY_ALGO_ELG:
|
||||||
|
return "ElGamal";
|
||||||
|
default:
|
||||||
|
return "unknown pubkey algorithm";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
status = MU_MSG_PART_SIG_STATUS_GOOD; /* let's start positive! */
|
static const gchar*
|
||||||
|
get_digestkey_algo_name (GMimeDigestAlgo algo)
|
||||||
|
{
|
||||||
|
switch (algo) {
|
||||||
|
case GMIME_DIGEST_ALGO_DEFAULT:
|
||||||
|
return "default";
|
||||||
|
case GMIME_DIGEST_ALGO_MD5:
|
||||||
|
return "MD5";
|
||||||
|
case GMIME_DIGEST_ALGO_SHA1:
|
||||||
|
return "SHA-1";
|
||||||
|
case GMIME_DIGEST_ALGO_RIPEMD160:
|
||||||
|
return "RIPEMD160";
|
||||||
|
case GMIME_DIGEST_ALGO_MD2:
|
||||||
|
return "MD2";
|
||||||
|
case GMIME_DIGEST_ALGO_TIGER192:
|
||||||
|
return "TIGER-192";
|
||||||
|
case GMIME_DIGEST_ALGO_HAVAL5160:
|
||||||
|
return "HAVAL-5-160";
|
||||||
|
case GMIME_DIGEST_ALGO_SHA256:
|
||||||
|
return "SHA-256";
|
||||||
|
case GMIME_DIGEST_ALGO_SHA384:
|
||||||
|
return "SHA-384";
|
||||||
|
case GMIME_DIGEST_ALGO_SHA512:
|
||||||
|
return "SHA-512";
|
||||||
|
case GMIME_DIGEST_ALGO_SHA224:
|
||||||
|
return "SHA-224";
|
||||||
|
case GMIME_DIGEST_ALGO_MD4:
|
||||||
|
return "MD4";
|
||||||
|
default:
|
||||||
|
return "unknown digest algorithm";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i != g_mime_signature_list_length (sigs); ++i) {
|
|
||||||
|
|
||||||
GMimeSignature *msig;
|
/* get data from the 'certificate' */
|
||||||
GMimeSignatureStatus sigstat;
|
static char*
|
||||||
msig = g_mime_signature_list_get_signature (sigs, i);
|
get_cert_data (GMimeCertificate *cert)
|
||||||
sigstat = g_mime_signature_get_status (msig);
|
{
|
||||||
|
const char /*issuer_name, *issuer_serial, ,*fprint*/
|
||||||
|
*email, *name,
|
||||||
|
*digest_algo, *pubkey_algo,
|
||||||
|
*keyid, *trust;
|
||||||
|
|
||||||
switch (sigstat) {
|
/* issuer_name = g_mime_certificate_get_issuer_name (cert); */
|
||||||
case GMIME_SIGNATURE_STATUS_GOOD: continue;
|
/* issuer_serial = g_mime_certificate_get_issuer_serial (cert); */
|
||||||
case GMIME_SIGNATURE_STATUS_ERROR: return MU_MSG_PART_SIG_STATUS_ERROR;
|
email = g_mime_certificate_get_email (cert);
|
||||||
case GMIME_SIGNATURE_STATUS_BAD: return MU_MSG_PART_SIG_STATUS_BAD;
|
name = g_mime_certificate_get_name (cert);
|
||||||
}
|
/* fprint = g_mime_certificate_get_fingerprint (cert); */
|
||||||
|
keyid = g_mime_certificate_get_key_id (cert);
|
||||||
|
|
||||||
|
digest_algo = get_digestkey_algo_name
|
||||||
|
(g_mime_certificate_get_digest_algo (cert));
|
||||||
|
pubkey_algo = get_pubkey_algo_name
|
||||||
|
(g_mime_certificate_get_pubkey_algo (cert));
|
||||||
|
|
||||||
|
switch (g_mime_certificate_get_trust (cert)) {
|
||||||
|
case GMIME_CERTIFICATE_TRUST_NONE: trust = "none"; break;
|
||||||
|
case GMIME_CERTIFICATE_TRUST_NEVER: trust = "never"; break;
|
||||||
|
case GMIME_CERTIFICATE_TRUST_UNDEFINED: trust = "undefined"; break;
|
||||||
|
case GMIME_CERTIFICATE_TRUST_MARGINAL: trust= "marginal"; break;
|
||||||
|
case GMIME_CERTIFICATE_TRUST_FULLY: trust = "full"; break;
|
||||||
|
case GMIME_CERTIFICATE_TRUST_ULTIMATE: trust = "ultimate"; break;
|
||||||
|
default:
|
||||||
|
g_return_val_if_reached (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return g_strdup_printf (
|
||||||
|
"signed by: %s <%s>; " /*; issued by %s (%s); */
|
||||||
|
"algos: <%s,%s>; key-id: %s; trust: %s",
|
||||||
|
name ? name : "?", email ? email : "?",
|
||||||
|
/* issuer_name, issuer_serial */
|
||||||
|
pubkey_algo, digest_algo, keyid, trust);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
MuMsgPartSigStatus
|
/* get a human-readable report about the signature */
|
||||||
|
static char*
|
||||||
|
get_verdict_report (GMimeSignature *msig)
|
||||||
|
{
|
||||||
|
time_t t;
|
||||||
|
const char *status, *created, *expires;
|
||||||
|
gchar *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);
|
||||||
|
}
|
||||||
|
|
||||||
|
t = g_mime_signature_get_created (msig);
|
||||||
|
created = (t == 0 || t == (time_t)-1) ? "?" : mu_date_str_s ("%x", t);
|
||||||
|
|
||||||
|
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 ("status: %s; created: %s, expires: %s (%s)",
|
||||||
|
status, created, expires,
|
||||||
|
certdata ? certdata : "?");
|
||||||
|
g_free (certdata);
|
||||||
|
return report;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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, rep);
|
||||||
|
g_free (rep);
|
||||||
|
}
|
||||||
|
|
||||||
|
status_report = g_slice_new (MuMsgPartSigStatusReport);
|
||||||
|
status_report->verdict = status;
|
||||||
|
status_report->report = report;
|
||||||
|
|
||||||
|
return status_report;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mu_msg_part_sig_status_report_destroy (MuMsgPartSigStatusReport *report)
|
||||||
|
{
|
||||||
|
if (!report)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_free ((char*)report->report);
|
||||||
|
g_slice_free (MuMsgPartSigStatusReport, report);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MuMsgPartSigStatusReport*
|
||||||
mu_msg_crypto_verify_part (GMimeMultipartSigned *sig, MuMsgOptions opts,
|
mu_msg_crypto_verify_part (GMimeMultipartSigned *sig, MuMsgOptions opts,
|
||||||
GError **err)
|
GError **err)
|
||||||
{
|
{
|
||||||
MuMsgPartSigStatus sigstat;
|
MuMsgPartSigStatusReport *report;
|
||||||
GMimeCryptoContext *ctx;
|
GMimeCryptoContext *ctx;
|
||||||
GMimeSignatureList *sigs;
|
GMimeSignatureList *sigs;
|
||||||
|
|
||||||
g_return_val_if_fail (GMIME_IS_MULTIPART_SIGNED(sig),
|
g_return_val_if_fail (GMIME_IS_MULTIPART_SIGNED(sig), NULL);
|
||||||
MU_MSG_PART_SIG_STATUS_FAIL);
|
|
||||||
|
|
||||||
ctx = get_crypto_context (opts, NULL, NULL, err);
|
ctx = get_crypto_context (opts, NULL, NULL, err);
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
mu_util_g_set_error (err, MU_ERROR_CRYPTO,
|
mu_util_g_set_error (err, MU_ERROR_CRYPTO,
|
||||||
"failed to get crypto context");
|
"failed to get crypto context");
|
||||||
return MU_MSG_PART_SIG_STATUS_FAIL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sigs = g_mime_multipart_signed_verify (sig, ctx, err);
|
sigs = g_mime_multipart_signed_verify (sig, ctx, err);
|
||||||
|
@ -197,13 +354,13 @@ mu_msg_crypto_verify_part (GMimeMultipartSigned *sig, MuMsgOptions opts,
|
||||||
if (err && !*err)
|
if (err && !*err)
|
||||||
mu_util_g_set_error (err, MU_ERROR_CRYPTO,
|
mu_util_g_set_error (err, MU_ERROR_CRYPTO,
|
||||||
"verification failed");
|
"verification failed");
|
||||||
return MU_MSG_PART_SIG_STATUS_FAIL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sigstat = get_verdict (sigs);
|
report = get_status_report (sigs);
|
||||||
g_mime_signature_list_clear (sigs);
|
g_mime_signature_list_clear (sigs);
|
||||||
|
|
||||||
return sigstat;
|
return report;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,7 @@
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <mu-msg.h>
|
#include <mu-msg.h>
|
||||||
|
|
||||||
|
|
||||||
struct _MuMsgDecryptedPart;
|
struct _MuMsgDecryptedPart;
|
||||||
typedef struct _MuMsgDecryptedPart MuMsgDecryptedPart;
|
typedef struct _MuMsgDecryptedPart MuMsgDecryptedPart;
|
||||||
|
|
||||||
|
|
||||||
#endif /*__MU_MSG_CRYPTO_H__*/
|
#endif /*__MU_MSG_CRYPTO_H__*/
|
||||||
|
|
|
@ -297,27 +297,28 @@ get_disposition (GMimeObject *mobj)
|
||||||
return MU_MSG_PART_TYPE_NONE;
|
return MU_MSG_PART_TYPE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SIG_STATUS "sig-status"
|
#define SIG_STATUS_REPORT "sig-status-report"
|
||||||
|
|
||||||
/* call 'func' with information about this MIME-part */
|
/* call 'func' with information about this MIME-part */
|
||||||
static gboolean
|
static gboolean
|
||||||
check_signature (MuMsg *msg, GMimeMultipartSigned *part, MuMsgOptions opts)
|
check_signature (MuMsg *msg, GMimeMultipartSigned *part, MuMsgOptions opts)
|
||||||
{
|
{
|
||||||
/* the signature status */
|
/* the signature status */
|
||||||
MuMsgPartSigStatus sigstat;
|
MuMsgPartSigStatusReport *sigrep;
|
||||||
GError *err;
|
GError *err;
|
||||||
|
|
||||||
err = NULL;
|
err = NULL;
|
||||||
sigstat = mu_msg_crypto_verify_part (part, opts, &err);
|
sigrep = mu_msg_crypto_verify_part (part, opts, &err);
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
g_warning ("error verifying signature: %s", err->message);
|
g_warning ("error verifying signature: %s", err->message);
|
||||||
g_clear_error (&err);
|
g_clear_error (&err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tag this part with the signature status check */
|
/* tag this part with the signature status check */
|
||||||
g_object_set_data (G_OBJECT(part), SIG_STATUS,
|
g_object_set_data_full
|
||||||
GSIZE_TO_POINTER(sigstat));
|
(G_OBJECT(part), SIG_STATUS_REPORT,
|
||||||
|
sigrep,
|
||||||
|
(GDestroyNotify)mu_msg_part_sig_status_report_destroy);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -348,12 +349,6 @@ handle_part (MuMsg *msg, GMimePart *part, GMimeObject *parent,
|
||||||
msgpart.part_type = MU_MSG_PART_TYPE_LEAF;
|
msgpart.part_type = MU_MSG_PART_TYPE_LEAF;
|
||||||
msgpart.part_type |= get_disposition ((GMimeObject*)part);
|
msgpart.part_type |= get_disposition ((GMimeObject*)part);
|
||||||
|
|
||||||
/* get the sig status from the parent */
|
|
||||||
msgpart.sig_status =
|
|
||||||
(MuMsgPartSigStatus)
|
|
||||||
GPOINTER_TO_SIZE(g_object_get_data (G_OBJECT(parent),
|
|
||||||
SIG_STATUS));
|
|
||||||
|
|
||||||
ct = g_mime_object_get_content_type ((GMimeObject*)part);
|
ct = g_mime_object_get_content_type ((GMimeObject*)part);
|
||||||
if (GMIME_IS_CONTENT_TYPE(ct)) {
|
if (GMIME_IS_CONTENT_TYPE(ct)) {
|
||||||
msgpart.type = g_mime_content_type_get_media_type (ct);
|
msgpart.type = g_mime_content_type_get_media_type (ct);
|
||||||
|
@ -366,6 +361,14 @@ handle_part (MuMsg *msg, GMimePart *part, GMimeObject *parent,
|
||||||
msgpart.part_type |= MU_MSG_PART_TYPE_TEXT_HTML;
|
msgpart.part_type |= MU_MSG_PART_TYPE_TEXT_HTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* get the sig status from the parent, but don't set if for
|
||||||
|
* the signature part itself */
|
||||||
|
msgpart.sig_status_report = NULL;
|
||||||
|
if (g_ascii_strcasecmp (msgpart.subtype, "pgp-signature") != 0)
|
||||||
|
msgpart.sig_status_report =
|
||||||
|
(MuMsgPartSigStatusReport*)
|
||||||
|
g_object_get_data (G_OBJECT(parent), SIG_STATUS_REPORT);
|
||||||
|
|
||||||
msgpart.data = (gpointer)part;
|
msgpart.data = (gpointer)part;
|
||||||
msgpart.index = index;
|
msgpart.index = index;
|
||||||
|
|
||||||
|
@ -419,7 +422,8 @@ handle_mime_object (MuMsg *msg,
|
||||||
return handle_message_part
|
return handle_message_part
|
||||||
(msg, GMIME_MESSAGE_PART(mobj),
|
(msg, GMIME_MESSAGE_PART(mobj),
|
||||||
parent, opts, index, func, user_data);
|
parent, opts, index, func, user_data);
|
||||||
else if (GMIME_IS_MULTIPART_SIGNED (mobj))
|
else if ((opts & MU_MSG_OPTION_VERIFY) &&
|
||||||
|
GMIME_IS_MULTIPART_SIGNED (mobj))
|
||||||
return check_signature
|
return check_signature
|
||||||
(msg, GMIME_MULTIPART_SIGNED (mobj), opts);
|
(msg, GMIME_MULTIPART_SIGNED (mobj), opts);
|
||||||
else if (GMIME_IS_MULTIPART_ENCRYPTED (mobj))
|
else if (GMIME_IS_MULTIPART_ENCRYPTED (mobj))
|
||||||
|
|
|
@ -63,6 +63,19 @@ enum _MuMsgPartSigStatus {
|
||||||
};
|
};
|
||||||
typedef enum _MuMsgPartSigStatus MuMsgPartSigStatus;
|
typedef enum _MuMsgPartSigStatus MuMsgPartSigStatus;
|
||||||
|
|
||||||
|
struct _MuMsgPartSigStatusReport {
|
||||||
|
MuMsgPartSigStatus verdict;
|
||||||
|
const char *report;
|
||||||
|
};
|
||||||
|
typedef struct _MuMsgPartSigStatusReport MuMsgPartSigStatusReport;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* destroy a MuMsgPartSignatureStatusReport object
|
||||||
|
*
|
||||||
|
* @param report a MuMsgPartSignatureStatusReport object
|
||||||
|
*/
|
||||||
|
void mu_msg_part_sig_status_report_destroy (MuMsgPartSigStatusReport *report);
|
||||||
|
|
||||||
|
|
||||||
struct _MuMsgPart {
|
struct _MuMsgPart {
|
||||||
|
|
||||||
|
@ -81,9 +94,8 @@ struct _MuMsgPart {
|
||||||
|
|
||||||
gpointer data; /* opaque data */
|
gpointer data; /* opaque data */
|
||||||
|
|
||||||
MuMsgPartType part_type;
|
MuMsgPartType part_type;
|
||||||
MuMsgPartSigStatus sig_status;
|
MuMsgPartSigStatusReport *sig_status_report;
|
||||||
|
|
||||||
};
|
};
|
||||||
typedef struct _MuMsgPart MuMsgPart;
|
typedef struct _MuMsgPart MuMsgPart;
|
||||||
|
|
||||||
|
|
|
@ -129,12 +129,11 @@ typedef char* (*MuMsgPartPasswordFunc) (const char *user_id, const char *promp
|
||||||
* @param opts message options
|
* @param opts message options
|
||||||
* @param err receive error information
|
* @param err receive error information
|
||||||
*
|
*
|
||||||
* @return the verification status, or MU_MSG_PART_SIG_STATUS_FAIL in
|
* @return a status report object, free with mu_msg_part_sig_status_report_destroy
|
||||||
* case of some internal error
|
|
||||||
*/
|
*/
|
||||||
MuMsgPartSigStatus mu_msg_crypto_verify_part (GMimeMultipartSigned *sig, MuMsgOptions opts,
|
MuMsgPartSigStatusReport* mu_msg_crypto_verify_part (GMimeMultipartSigned *sig,
|
||||||
GError **err);
|
MuMsgOptions opts,
|
||||||
|
GError **err);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* decrypt the given encrypted mime multipart
|
* decrypt the given encrypted mime multipart
|
||||||
|
|
99
mu/mu-cmd.c
99
mu/mu-cmd.c
|
@ -285,7 +285,6 @@ mu_cmd_mkdir (MuConfig *opts, GError **err)
|
||||||
FALSE, err))
|
FALSE, err))
|
||||||
return err && *err ? (*err)->code :
|
return err && *err ? (*err)->code :
|
||||||
MU_ERROR_FILE_CANNOT_MKDIR;
|
MU_ERROR_FILE_CANNOT_MKDIR;
|
||||||
|
|
||||||
return MU_OK;
|
return MU_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,22 +400,74 @@ mu_cmd_remove (MuStore *store, MuConfig *opts, GError **err)
|
||||||
|
|
||||||
|
|
||||||
#ifdef BUILD_CRYPTO
|
#ifdef BUILD_CRYPTO
|
||||||
static void
|
|
||||||
each_sig (MuMsg *msg, MuMsgPart *part, MuMsgPartSigStatus *sigstat)
|
struct _VData {
|
||||||
|
MuMsgPartSigStatus combined_status;
|
||||||
|
char *report;
|
||||||
|
};
|
||||||
|
typedef struct _VData VData;
|
||||||
|
|
||||||
|
static void
|
||||||
|
each_sig (MuMsg *msg, MuMsgPart *part, VData *vdata)
|
||||||
{
|
{
|
||||||
if (*sigstat == MU_MSG_PART_SIG_STATUS_BAD ||
|
MuMsgPartSigStatusReport *report;
|
||||||
*sigstat == MU_MSG_PART_SIG_STATUS_ERROR)
|
report = part->sig_status_report;
|
||||||
|
if (!report)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
*sigstat = part->sig_status;
|
vdata->report = g_strdup_printf
|
||||||
|
("%s%s%s",
|
||||||
|
vdata->report ? vdata->report : "",
|
||||||
|
vdata->report ? "; " : "",
|
||||||
|
report->report);
|
||||||
|
|
||||||
|
if (vdata->combined_status == MU_MSG_PART_SIG_STATUS_BAD ||
|
||||||
|
vdata->combined_status == MU_MSG_PART_SIG_STATUS_ERROR)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vdata->combined_status = report->verdict;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_verdict (VData *vdata, gboolean color)
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
switch (vdata->combined_status) {
|
||||||
|
|
||||||
|
case MU_MSG_PART_SIG_STATUS_UNSIGNED:
|
||||||
|
str = g_strdup ("no signature found");
|
||||||
|
break;
|
||||||
|
case MU_MSG_PART_SIG_STATUS_GOOD:
|
||||||
|
str = g_strdup_printf ("signature verified; %s",
|
||||||
|
vdata->report);
|
||||||
|
break;
|
||||||
|
case MU_MSG_PART_SIG_STATUS_BAD:
|
||||||
|
str = g_strdup_printf ("bad signature; %s",
|
||||||
|
vdata->report);
|
||||||
|
break;
|
||||||
|
case MU_MSG_PART_SIG_STATUS_ERROR:
|
||||||
|
str = g_strdup_printf ("verification failed; %s",
|
||||||
|
vdata->report);
|
||||||
|
break;
|
||||||
|
case MU_MSG_PART_SIG_STATUS_FAIL:
|
||||||
|
str = g_strdup ("error in verification process");
|
||||||
|
break;
|
||||||
|
default: g_return_if_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
print_field ("verdict", str, color);
|
||||||
|
g_free (str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
MuError
|
MuError
|
||||||
mu_cmd_verify (MuConfig *opts, GError **err)
|
mu_cmd_verify (MuConfig *opts, GError **err)
|
||||||
{
|
{
|
||||||
MuMsg *msg;
|
MuMsg *msg;
|
||||||
MuMsgOptions msgopts;
|
MuMsgOptions msgopts;
|
||||||
MuMsgPartSigStatus sigstat;
|
VData vdata;
|
||||||
|
|
||||||
g_return_val_if_fail (opts, MU_ERROR_INTERNAL);
|
g_return_val_if_fail (opts, MU_ERROR_INTERNAL);
|
||||||
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_VERIFY,
|
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_VERIFY,
|
||||||
|
@ -426,36 +477,20 @@ mu_cmd_verify (MuConfig *opts, GError **err)
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return MU_ERROR;
|
return MU_ERROR;
|
||||||
|
|
||||||
msgopts = mu_config_get_msg_options (opts);
|
msgopts = mu_config_get_msg_options (opts) | MU_MSG_OPTION_VERIFY;
|
||||||
|
vdata.report = NULL;
|
||||||
sigstat = MU_MSG_PART_SIG_STATUS_UNSIGNED;
|
vdata.combined_status = MU_MSG_PART_SIG_STATUS_UNSIGNED;
|
||||||
mu_msg_part_foreach (msg, msgopts,
|
mu_msg_part_foreach (msg, msgopts,
|
||||||
(MuMsgPartForeachFunc)each_sig, &sigstat);
|
(MuMsgPartForeachFunc)each_sig, &vdata);
|
||||||
|
|
||||||
if (!opts->quiet) {
|
if (!opts->quiet)
|
||||||
const char *verdict;
|
print_verdict (&vdata, !opts->nocolor);
|
||||||
|
|
||||||
switch (sigstat) {
|
|
||||||
case MU_MSG_PART_SIG_STATUS_UNSIGNED:
|
|
||||||
verdict = "no signature found"; break;
|
|
||||||
case MU_MSG_PART_SIG_STATUS_GOOD:
|
|
||||||
verdict = "signature verified"; break;
|
|
||||||
case MU_MSG_PART_SIG_STATUS_BAD:
|
|
||||||
verdict = "signature not verified"; break;
|
|
||||||
case MU_MSG_PART_SIG_STATUS_ERROR:
|
|
||||||
verdict = "failed to verify signature"; break;
|
|
||||||
case MU_MSG_PART_SIG_STATUS_FAIL:
|
|
||||||
verdict = "error in verification process"; break;
|
|
||||||
default:
|
|
||||||
g_return_val_if_reached (MU_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_print ("verdict: %s\n", verdict);
|
|
||||||
}
|
|
||||||
|
|
||||||
mu_msg_unref (msg);
|
mu_msg_unref (msg);
|
||||||
|
g_free (vdata.report);
|
||||||
|
|
||||||
return sigstat == MU_MSG_PART_SIG_STATUS_GOOD ? MU_OK : MU_ERROR;
|
return vdata.combined_status == MU_MSG_PART_SIG_STATUS_GOOD ?
|
||||||
|
MU_OK : MU_ERROR;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
MuError
|
MuError
|
||||||
|
|
Loading…
Reference in New Issue