* crypto: better handling of crypto errors
This commit is contained in:
@ -43,7 +43,7 @@ dummy_password_requester (GMimeCryptoContext *ctx, const char *user_id,
|
|||||||
|
|
||||||
|
|
||||||
GMimeCryptoContext*
|
GMimeCryptoContext*
|
||||||
get_crypto_context (MuMsgPartOptions opts, GError **err)
|
get_gpg_crypto_context (MuMsgPartOptions opts, GError **err)
|
||||||
{
|
{
|
||||||
GMimeCryptoContext *ctx;
|
GMimeCryptoContext *ctx;
|
||||||
const char *prog;
|
const char *prog;
|
||||||
@ -64,9 +64,9 @@ get_crypto_context (MuMsgPartOptions opts, GError **err)
|
|||||||
path);
|
path);
|
||||||
g_free (path);
|
g_free (path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
mu_util_g_set_error (err, MU_ERROR, "failed to get crypto context");
|
mu_util_g_set_error (err, MU_ERROR,
|
||||||
|
"failed to get GPG crypto context");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,15 +74,38 @@ get_crypto_context (MuMsgPartOptions opts, GError **err)
|
|||||||
(GMIME_GPG_CONTEXT(ctx),
|
(GMIME_GPG_CONTEXT(ctx),
|
||||||
opts & MU_MSG_PART_OPTION_USE_AGENT);
|
opts & MU_MSG_PART_OPTION_USE_AGENT);
|
||||||
g_mime_gpg_context_set_always_trust
|
g_mime_gpg_context_set_always_trust
|
||||||
(GMIME_GPG_CONTEXT(ctx), FALSE);
|
(GMIME_GPG_CONTEXT(ctx),
|
||||||
|
opts & MU_MSG_PART_OPTION_TRUST_ALWAYS);
|
||||||
g_mime_gpg_context_set_auto_key_retrieve
|
g_mime_gpg_context_set_auto_key_retrieve
|
||||||
(GMIME_GPG_CONTEXT(ctx),
|
(GMIME_GPG_CONTEXT(ctx),
|
||||||
opts & MU_MSG_PART_OPTION_AUTO_RETRIEVE_KEY);
|
opts & MU_MSG_PART_OPTION_AUTO_RETRIEVE_KEY);
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GMimeCryptoContext*
|
||||||
|
get_pkcs7_crypto_context (MuMsgPartOptions opts, GError **err)
|
||||||
|
{
|
||||||
|
GMimeCryptoContext *ctx;
|
||||||
|
|
||||||
|
ctx = g_mime_pkcs7_context_new
|
||||||
|
((GMimePasswordRequestFunc)dummy_password_requester);
|
||||||
|
if (!ctx) {
|
||||||
|
mu_util_g_set_error (err, MU_ERROR,
|
||||||
|
"failed to get PKCS7 crypto context");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_mime_pkcs7_context_set_always_trust
|
||||||
|
(GMIME_PKCS7_CONTEXT(ctx),
|
||||||
|
opts & MU_MSG_PART_OPTION_TRUST_ALWAYS);
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
get_pubkey_algo_name (GMimePubKeyAlgo algo)
|
get_pubkey_algo_name (GMimePubKeyAlgo algo)
|
||||||
{
|
{
|
||||||
@ -216,6 +239,19 @@ sig_info_destroy (MuMsgPartSigInfo *siginfo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* we create a fake siginfo when things go wrong */
|
||||||
|
static GSList*
|
||||||
|
error_sig_infos (void)
|
||||||
|
{
|
||||||
|
MuMsgPartSigInfo *sig_info;
|
||||||
|
|
||||||
|
sig_info = g_new0 (MuMsgPartSigInfo, 1);
|
||||||
|
sig_info->status = MU_MSG_PART_SIG_STATUS_FAIL;
|
||||||
|
|
||||||
|
return g_slist_prepend (NULL, sig_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GSList*
|
GSList*
|
||||||
mu_msg_mime_sig_infos (GMimeMultipartSigned *sigmpart, MuMsgPartOptions opts,
|
mu_msg_mime_sig_infos (GMimeMultipartSigned *sigmpart, MuMsgPartOptions opts,
|
||||||
@ -223,7 +259,7 @@ mu_msg_mime_sig_infos (GMimeMultipartSigned *sigmpart, MuMsgPartOptions opts,
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
GMimeSignatureList *sigs;
|
GMimeSignatureList *sigs;
|
||||||
GMimeCryptoContext *gpgctx;
|
GMimeCryptoContext *cctx;
|
||||||
GSList *siginfos;
|
GSList *siginfos;
|
||||||
|
|
||||||
if (!GMIME_IS_MULTIPART_SIGNED (sigmpart)) {
|
if (!GMIME_IS_MULTIPART_SIGNED (sigmpart)) {
|
||||||
@ -232,20 +268,23 @@ mu_msg_mime_sig_infos (GMimeMultipartSigned *sigmpart, MuMsgPartOptions opts,
|
|||||||
return NULL; /* error */
|
return NULL; /* error */
|
||||||
}
|
}
|
||||||
|
|
||||||
gpgctx = get_crypto_context (opts, err);
|
if (opts & MU_MSG_PART_OPTION_USE_PKCS7)
|
||||||
if (!gpgctx)
|
cctx = get_pkcs7_crypto_context (opts, err);
|
||||||
return NULL; /* error */
|
else
|
||||||
|
cctx = get_gpg_crypto_context (opts, err);
|
||||||
|
|
||||||
sigs = g_mime_multipart_signed_verify (sigmpart, gpgctx, err);
|
/* return a fake siginfos with the error */
|
||||||
g_object_unref (gpgctx);
|
if (!cctx)
|
||||||
|
return error_sig_infos (); /* error */
|
||||||
|
|
||||||
|
sigs = g_mime_multipart_signed_verify (sigmpart, cctx, err);
|
||||||
|
g_object_unref (cctx);
|
||||||
if (!sigs)
|
if (!sigs)
|
||||||
return NULL; /* error */
|
return NULL; /* error */
|
||||||
|
|
||||||
for (i = 0, siginfos = NULL; i != g_mime_signature_list_length (sigs); ++i) {
|
for (i = 0, siginfos = NULL; i != g_mime_signature_list_length (sigs); ++i) {
|
||||||
|
|
||||||
MuMsgPartSigInfo *siginfo;
|
MuMsgPartSigInfo *siginfo;
|
||||||
|
|
||||||
siginfo = sig_info_new
|
siginfo = sig_info_new
|
||||||
(g_mime_signature_list_get_signature (sigs, i));
|
(g_mime_signature_list_get_signature (sigs, i));
|
||||||
|
|
||||||
@ -270,13 +309,15 @@ mu_msg_part_sig_status_to_string (MuMsgPartSigStatus status)
|
|||||||
{
|
{
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case MU_MSG_PART_SIG_STATUS_UNKNOWN:
|
case MU_MSG_PART_SIG_STATUS_UNKNOWN:
|
||||||
return "unknown";
|
return "no signed part found";
|
||||||
case MU_MSG_PART_SIG_STATUS_GOOD:
|
case MU_MSG_PART_SIG_STATUS_GOOD:
|
||||||
return "good";
|
return "good";
|
||||||
case MU_MSG_PART_SIG_STATUS_BAD:
|
case MU_MSG_PART_SIG_STATUS_BAD:
|
||||||
return "bad signature";
|
return "bad signature";
|
||||||
case MU_MSG_PART_SIG_STATUS_ERROR:
|
case MU_MSG_PART_SIG_STATUS_ERROR:
|
||||||
return "error verifying signature";
|
return "error verifying signature";
|
||||||
|
case MU_MSG_PART_SIG_STATUS_FAIL:
|
||||||
|
return "crypto failed";
|
||||||
case MU_MSG_PART_SIG_STATUS_EXPSIG:
|
case MU_MSG_PART_SIG_STATUS_EXPSIG:
|
||||||
return "signature is expired";
|
return "signature is expired";
|
||||||
case MU_MSG_PART_SIG_STATUS_NO_PUBKEY:
|
case MU_MSG_PART_SIG_STATUS_NO_PUBKEY:
|
||||||
@ -296,7 +337,7 @@ mu_msg_part_sig_status_to_string (MuMsgPartSigStatus status)
|
|||||||
|
|
||||||
|
|
||||||
char*
|
char*
|
||||||
mu_msg_part_sig_info_to_string (MuMsgPartSigInfo *info)
|
mu_msg_part_sig_statuses_to_string (MuMsgPartSigStatus status)
|
||||||
{
|
{
|
||||||
unsigned u;
|
unsigned u;
|
||||||
GString *gstr;
|
GString *gstr;
|
||||||
@ -306,6 +347,7 @@ mu_msg_part_sig_info_to_string (MuMsgPartSigInfo *info)
|
|||||||
MU_MSG_PART_SIG_STATUS_GOOD,
|
MU_MSG_PART_SIG_STATUS_GOOD,
|
||||||
MU_MSG_PART_SIG_STATUS_BAD,
|
MU_MSG_PART_SIG_STATUS_BAD,
|
||||||
MU_MSG_PART_SIG_STATUS_ERROR,
|
MU_MSG_PART_SIG_STATUS_ERROR,
|
||||||
|
MU_MSG_PART_SIG_STATUS_FAIL,
|
||||||
MU_MSG_PART_SIG_STATUS_EXPSIG,
|
MU_MSG_PART_SIG_STATUS_EXPSIG,
|
||||||
MU_MSG_PART_SIG_STATUS_NO_PUBKEY,
|
MU_MSG_PART_SIG_STATUS_NO_PUBKEY,
|
||||||
MU_MSG_PART_SIG_STATUS_EXPKEYSIG,
|
MU_MSG_PART_SIG_STATUS_EXPKEYSIG,
|
||||||
@ -313,14 +355,15 @@ mu_msg_part_sig_info_to_string (MuMsgPartSigInfo *info)
|
|||||||
MU_MSG_PART_SIG_STATUS_UNSUPP_ALGO
|
MU_MSG_PART_SIG_STATUS_UNSUPP_ALGO
|
||||||
};
|
};
|
||||||
|
|
||||||
g_return_val_if_fail (info, NULL);
|
if (status == MU_MSG_PART_SIG_STATUS_UNKNOWN)
|
||||||
|
return g_strdup
|
||||||
|
(mu_msg_part_sig_status_to_string (status));
|
||||||
|
|
||||||
gstr = g_string_sized_new (128);
|
gstr = g_string_sized_new (128);
|
||||||
|
|
||||||
for (u = 0; u != G_N_ELEMENTS(statuses); ++u) {
|
for (u = 0; u != G_N_ELEMENTS(statuses); ++u) {
|
||||||
const gchar *statstr;
|
const gchar *statstr;
|
||||||
|
if (!(status & statuses[u]))
|
||||||
if (!(info->status & statuses[u]))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
statstr = mu_msg_part_sig_status_to_string (statuses[u]);
|
statstr = mu_msg_part_sig_status_to_string (statuses[u]);
|
||||||
@ -330,9 +373,27 @@ mu_msg_part_sig_info_to_string (MuMsgPartSigInfo *info)
|
|||||||
gstr = g_string_append (gstr, statstr);
|
gstr = g_string_append (gstr, statstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
gstr = g_string_prepend (gstr, "status: ");
|
return g_string_free (gstr, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
if (info->status & MU_MSG_PART_SIG_STATUS_ERROR)
|
|
||||||
|
|
||||||
|
char*
|
||||||
|
mu_msg_part_sig_info_to_string (MuMsgPartSigInfo *info)
|
||||||
|
{
|
||||||
|
GString *gstr;
|
||||||
|
gchar *statuses;
|
||||||
|
|
||||||
|
g_return_val_if_fail (info, NULL);
|
||||||
|
|
||||||
|
gstr = g_string_sized_new (128);
|
||||||
|
|
||||||
|
statuses = mu_msg_part_sig_statuses_to_string (info->status);
|
||||||
|
g_string_append_printf (gstr, "status: %s", statuses);
|
||||||
|
g_free (statuses);
|
||||||
|
|
||||||
|
if (info->status & MU_MSG_PART_SIG_STATUS_ERROR ||
|
||||||
|
info->status & MU_MSG_PART_SIG_STATUS_FAIL)
|
||||||
return g_string_free (gstr, FALSE);
|
return g_string_free (gstr, FALSE);
|
||||||
|
|
||||||
g_string_append_printf (gstr, "; algorithms (P/D) (%s, %s)",
|
g_string_append_printf (gstr, "; algorithms (P/D) (%s, %s)",
|
||||||
|
|||||||
@ -33,11 +33,14 @@ enum _MuMsgPartSigStatus {
|
|||||||
MU_MSG_PART_SIG_STATUS_BAD = 1 << 1,
|
MU_MSG_PART_SIG_STATUS_BAD = 1 << 1,
|
||||||
MU_MSG_PART_SIG_STATUS_ERROR = 1 << 2,
|
MU_MSG_PART_SIG_STATUS_ERROR = 1 << 2,
|
||||||
|
|
||||||
MU_MSG_PART_SIG_STATUS_EXPSIG = 1 << 3, /* expired sig */
|
/* status when crypto does not work */
|
||||||
MU_MSG_PART_SIG_STATUS_NO_PUBKEY = 1 << 4, /* no public key */
|
MU_MSG_PART_SIG_STATUS_FAIL = 1 << 3,
|
||||||
MU_MSG_PART_SIG_STATUS_EXPKEYSIG = 1 << 5, /* key expired */
|
|
||||||
MU_MSG_PART_SIG_STATUS_REVKEYSIG = 1 << 6, /* revoked key */
|
MU_MSG_PART_SIG_STATUS_EXPSIG = 1 << 4, /* expired sig */
|
||||||
MU_MSG_PART_SIG_STATUS_UNSUPP_ALGO = 1 << 7 /* unsupp'd algo */
|
MU_MSG_PART_SIG_STATUS_NO_PUBKEY = 1 << 5, /* no public key */
|
||||||
|
MU_MSG_PART_SIG_STATUS_EXPKEYSIG = 1 << 6, /* key expired */
|
||||||
|
MU_MSG_PART_SIG_STATUS_REVKEYSIG = 1 << 7, /* revoked key */
|
||||||
|
MU_MSG_PART_SIG_STATUS_UNSUPP_ALGO = 1 << 8 /* unsupp'd algo */
|
||||||
};
|
};
|
||||||
typedef enum _MuMsgPartSigStatus MuMsgPartSigStatus;
|
typedef enum _MuMsgPartSigStatus MuMsgPartSigStatus;
|
||||||
|
|
||||||
@ -57,6 +60,8 @@ struct _MuMsgPartSigInfo {
|
|||||||
const char *pubkey_algo; /* public key algorithm */
|
const char *pubkey_algo; /* public key algorithm */
|
||||||
const char *digest_algo; /* digest algorithm */
|
const char *digest_algo; /* digest algorithm */
|
||||||
|
|
||||||
|
const char *errmsg; /* errmsg when status ==
|
||||||
|
* MU_MSG_PART_SIG_STATUS_FAIL */
|
||||||
/* don't touch */
|
/* don't touch */
|
||||||
gpointer _cert;
|
gpointer _cert;
|
||||||
};
|
};
|
||||||
@ -74,6 +79,17 @@ typedef struct _MuMsgPartSigInfo MuMsgPartSigInfo;
|
|||||||
const char* mu_msg_part_sig_status_to_string (MuMsgPartSigStatus status);
|
const char* mu_msg_part_sig_status_to_string (MuMsgPartSigStatus status);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert the bitwise-OR'ed statuses to a string
|
||||||
|
*
|
||||||
|
* @param statuses bitwise-OR'ed statuses
|
||||||
|
*
|
||||||
|
* @return newly allocated string (g_free)
|
||||||
|
*/
|
||||||
|
char* mu_msg_part_sig_statuses_to_string (MuMsgPartSigStatus statuses)
|
||||||
|
G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get a human readable-description of siginfo
|
* get a human readable-description of siginfo
|
||||||
*
|
*
|
||||||
@ -81,7 +97,8 @@ const char* mu_msg_part_sig_status_to_string (MuMsgPartSigStatus status);
|
|||||||
*
|
*
|
||||||
* @return a newly allocated string (g_free)
|
* @return a newly allocated string (g_free)
|
||||||
*/
|
*/
|
||||||
char* mu_msg_part_sig_info_to_string (MuMsgPartSigInfo *info);
|
char* mu_msg_part_sig_info_to_string (MuMsgPartSigInfo *info)
|
||||||
|
G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* free the list of MuMsgPartSigInfo structures
|
* free the list of MuMsgPartSigInfo structures
|
||||||
|
|||||||
@ -248,19 +248,27 @@ check_signature_maybe (GMimeObject *parent, GMimeObject *mobj, MuMsgPart *pi,
|
|||||||
MuMsgPartOptions opts)
|
MuMsgPartOptions opts)
|
||||||
{
|
{
|
||||||
#ifdef BUILD_CRYPTO
|
#ifdef BUILD_CRYPTO
|
||||||
|
|
||||||
|
GMimeContentType *ctype;
|
||||||
GError *err;
|
GError *err;
|
||||||
err = NULL;
|
gboolean pkcs7;
|
||||||
|
|
||||||
if (!GMIME_IS_MULTIPART_SIGNED (parent))
|
if (!GMIME_IS_MULTIPART_SIGNED (parent))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* we're interested in the signed thing here, not the
|
ctype = g_mime_object_get_content_type (mobj);
|
||||||
* signature itself */
|
if (g_mime_content_type_is_type
|
||||||
if (g_mime_content_type_is_type (
|
(ctype, "application", "pgp-signature"))
|
||||||
g_mime_object_get_content_type (mobj),
|
pkcs7 = FALSE;
|
||||||
"application", "pgp-signature"))
|
else if (g_mime_content_type_is_type
|
||||||
return;
|
(ctype, "application", "x-pkcs7-signature"))
|
||||||
|
pkcs7 = TRUE;
|
||||||
|
else return; /* don't know how to handle other kinds */
|
||||||
|
|
||||||
|
if (pkcs7)
|
||||||
|
opts |= MU_MSG_PART_OPTION_USE_PKCS7; /* gpg is the default */
|
||||||
|
|
||||||
|
err = NULL;
|
||||||
pi->sig_infos = mu_msg_mime_sig_infos
|
pi->sig_infos = mu_msg_mime_sig_infos
|
||||||
(GMIME_MULTIPART_SIGNED (parent), opts, &err);
|
(GMIME_MULTIPART_SIGNED (parent), opts, &err);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|||||||
@ -219,7 +219,9 @@ enum _MuMsgPartOptions {
|
|||||||
* if mu was built with crypto support */
|
* if mu was built with crypto support */
|
||||||
MU_MSG_PART_OPTION_CHECK_SIGNATURES = 1 << 1,
|
MU_MSG_PART_OPTION_CHECK_SIGNATURES = 1 << 1,
|
||||||
MU_MSG_PART_OPTION_AUTO_RETRIEVE_KEY = 1 << 2,
|
MU_MSG_PART_OPTION_AUTO_RETRIEVE_KEY = 1 << 2,
|
||||||
MU_MSG_PART_OPTION_USE_AGENT = 1 << 3
|
MU_MSG_PART_OPTION_USE_AGENT = 1 << 3,
|
||||||
|
MU_MSG_PART_OPTION_TRUST_ALWAYS = 1 << 4,
|
||||||
|
MU_MSG_PART_OPTION_USE_PKCS7 = 1 << 5 /* gpg is the default */
|
||||||
};
|
};
|
||||||
typedef enum _MuMsgPartOptions MuMsgPartOptions;
|
typedef enum _MuMsgPartOptions MuMsgPartOptions;
|
||||||
|
|
||||||
|
|||||||
54
mu/mu-cmd.c
54
mu/mu-cmd.c
@ -397,22 +397,39 @@ mu_cmd_remove (MuStore *store, MuConfig *opts, GError **err)
|
|||||||
|
|
||||||
|
|
||||||
#ifdef BUILD_CRYPTO
|
#ifdef BUILD_CRYPTO
|
||||||
static void print_signatures (MuMsg *msg, MuMsgPart *part, MuConfig *opts)
|
struct _VData {
|
||||||
|
MuMsgPartSigStatus status;
|
||||||
|
MuConfig*opts;
|
||||||
|
gchar *msg;
|
||||||
|
};
|
||||||
|
typedef struct _VData VData;
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
each_sig (MuMsg *msg, MuMsgPart *part, VData *vdata)
|
||||||
{
|
{
|
||||||
GSList *cur;
|
GSList *cur;
|
||||||
|
|
||||||
if (!part->sig_infos)
|
if (!part->sig_infos)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_print ("MIME-part %u has %u signature(s): ",
|
if (vdata->opts->verbose)
|
||||||
part->index, g_slist_length (part->sig_infos));
|
g_print ("MIME-part %u has %u signature(s): ",
|
||||||
|
part->index, g_slist_length (part->sig_infos));
|
||||||
|
|
||||||
for (cur = part->sig_infos; cur; cur = g_slist_next (cur)) {
|
for (cur = part->sig_infos; cur; cur = g_slist_next (cur)) {
|
||||||
char *descr;
|
|
||||||
descr = mu_msg_part_sig_info_to_string
|
MuMsgPartSigInfo *sig_info;
|
||||||
((MuMsgPartSigInfo*)cur->data);
|
sig_info = (MuMsgPartSigInfo*)cur->data;
|
||||||
g_print ("%s\n", descr);
|
|
||||||
g_free (descr);
|
if (vdata->opts->verbose) {
|
||||||
|
char *descr;
|
||||||
|
descr = mu_msg_part_sig_info_to_string (sig_info);
|
||||||
|
g_print ("%s\n", descr);
|
||||||
|
g_free (descr);
|
||||||
|
}
|
||||||
|
|
||||||
|
vdata->status |= sig_info->status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -421,6 +438,7 @@ mu_cmd_verify (MuConfig *opts, GError **err)
|
|||||||
{
|
{
|
||||||
MuMsg *msg;
|
MuMsg *msg;
|
||||||
MuMsgPartOptions partopts;
|
MuMsgPartOptions partopts;
|
||||||
|
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,
|
||||||
@ -436,12 +454,28 @@ mu_cmd_verify (MuConfig *opts, GError **err)
|
|||||||
if (opts->use_agent)
|
if (opts->use_agent)
|
||||||
partopts |= MU_MSG_PART_OPTION_USE_AGENT;
|
partopts |= MU_MSG_PART_OPTION_USE_AGENT;
|
||||||
|
|
||||||
mu_msg_part_foreach (msg,(MuMsgPartForeachFunc)print_signatures, opts,
|
vdata.status = MU_MSG_PART_SIG_STATUS_UNKNOWN;
|
||||||
|
vdata.opts = opts;
|
||||||
|
vdata.msg = NULL;
|
||||||
|
|
||||||
|
mu_msg_part_foreach (msg,(MuMsgPartForeachFunc)each_sig, &vdata,
|
||||||
partopts);
|
partopts);
|
||||||
|
|
||||||
|
/* if there's anything bad, all goodness goes away */
|
||||||
|
if (vdata.status & MU_MSG_PART_SIG_STATUS_BAD ||
|
||||||
|
vdata.status & MU_MSG_PART_SIG_STATUS_ERROR)
|
||||||
|
vdata.status &= ~MU_MSG_PART_SIG_STATUS_GOOD;
|
||||||
|
|
||||||
|
if (!opts->quiet) {
|
||||||
|
gchar *str;
|
||||||
|
str = mu_msg_part_sig_statuses_to_string (vdata.status);
|
||||||
|
g_print ("verdict: %s\n", str);
|
||||||
|
g_free (str);
|
||||||
|
}
|
||||||
|
|
||||||
mu_msg_unref (msg);
|
mu_msg_unref (msg);
|
||||||
|
|
||||||
return MU_OK;
|
return vdata.status == MU_MSG_PART_SIG_STATUS_GOOD ? MU_OK : MU_ERROR;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
MuError
|
MuError
|
||||||
|
|||||||
Reference in New Issue
Block a user