From bd24feaa86f8154e550107990392ac9ac05e60d4 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 19 Oct 2012 11:23:39 +0200 Subject: [PATCH] Trace the use of GPG_ERR_INV_ENGINE. * src/debug.h: Include "gpgme.h" (_gpgme_trace_gpgme_error): New. (trace_gpg_error): New macro. Use it in all files where we return GPG_ERR_INV_ENGINE; also "include debug.h" as needed. -- This is a pretty common error code but often it is hard to figure out the actual cause. With debug level 4 we now print the file name and line number where this error code is generated by gpgme. Along with the git revision printed in the first log lines, this should give us an easier way to track down the problems related to this error code. --- src/debug.h | 17 +++++++++++++++++ src/decrypt.c | 6 +++--- src/delete.c | 2 +- src/engine-gpg.c | 2 +- src/engine-gpgconf.c | 4 ++-- src/engine.c | 7 ++++--- src/gpgconf.c | 1 + src/import.c | 4 ++-- src/key.c | 1 + src/op-support.c | 3 ++- src/passphrase.c | 1 + src/passwd.c | 2 +- src/progress.c | 1 + src/sig-notation.c | 7 ++++--- src/sign.c | 14 +++++++------- src/trust-item.c | 1 + src/verify.c | 26 +++++++++++++------------- src/wait-global.c | 1 + src/wait-private.c | 1 + src/wait-user.c | 1 + 20 files changed, 65 insertions(+), 37 deletions(-) diff --git a/src/debug.h b/src/debug.h index ead92b24..c99b7003 100644 --- a/src/debug.h +++ b/src/debug.h @@ -26,6 +26,9 @@ #include #endif +#include "gpgme.h" /* Required for gpgme_error stuff. */ + + /* Indirect stringification, requires __STDC__ to work. */ #define STRINGIFY(v) #v #define XSTRINGIFY(v) STRINGIFY(v) @@ -81,6 +84,13 @@ void _gpgme_debug_buffer (int lvl, const char *const fmt, void _gpgme_debug_frame_begin (void); void _gpgme_debug_frame_end (void); +static inline gpgme_error_t +_gpgme_trace_gpgme_error (gpgme_error_t err, const char *file, int line) +{ + _gpgme_debug (DEBUG_ENGINE, "%s:%d: returning error: %s\n", + _gpgme_debug_srcname (file), line, gpgme_strerror (err)); + return err; +} /* Trace support. */ @@ -262,4 +272,11 @@ void _gpgme_debug_frame_end (void); _gpgme_debug_end (&(hlp)) #define TRACE_ENABLED(hlp) (!!(hlp)) +/* And finally a simple macro to trace the location of an error code. + This macro is independent of the other trace macros and may be used + without any preconditions. */ +#define trace_gpg_error(e) \ + _gpgme_trace_gpgme_error (gpg_error (e), __FILE__, __LINE__) + + #endif /* DEBUG_H */ diff --git a/src/decrypt.c b/src/decrypt.c index f4f95dc9..63787c70 100644 --- a/src/decrypt.c +++ b/src/decrypt.c @@ -146,7 +146,7 @@ parse_enc_to (char *args, gpgme_recipient_t *recp) if (*args != '\0' && *args != ' ') { free (rec); - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); } while (*args == ' ') @@ -160,7 +160,7 @@ parse_enc_to (char *args, gpgme_recipient_t *recp) { /* The crypto backend does not behave. */ free (rec); - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); } } @@ -283,7 +283,7 @@ _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code, } /* FIXME: Is this ok? */ if (!rec) - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); } break; diff --git a/src/delete.c b/src/delete.c index 283b3e60..37e54f89 100644 --- a/src/delete.c +++ b/src/delete.c @@ -48,7 +48,7 @@ delete_status_handler (void *priv, gpgme_status_code_t code, char *args) gpg_err_set_errno (0); problem = strtol (args, &tail, 0); if (errno || (*tail && *tail != ' ')) - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); switch (problem) { diff --git a/src/engine-gpg.c b/src/engine-gpg.c index 7cf8894a..4c7a8b2e 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -1269,7 +1269,7 @@ start (engine_gpg_t gpg) return gpg_error (GPG_ERR_INV_VALUE); if (!gpg->file_name && !_gpgme_get_gpg_path ()) - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); if (gpg->lc_ctype) { diff --git a/src/engine-gpgconf.c b/src/engine-gpgconf.c index 8de847cd..b50b6351 100644 --- a/src/engine-gpgconf.c +++ b/src/engine-gpgconf.c @@ -300,7 +300,7 @@ gpgconf_config_load_cb (void *hook, char *line) /* We require at least the first 3 fields. */ if (fields < 2) - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Find the pointer to the new component in the list. */ while (comp && comp->next) @@ -426,7 +426,7 @@ gpgconf_config_load_cb2 (void *hook, char *line) /* We require at least the first 10 fields. */ if (fields < 10) - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); opt = calloc (1, sizeof (*opt)); if (!opt) diff --git a/src/engine.c b/src/engine.c index 17d8d870..f72ce7f9 100644 --- a/src/engine.c +++ b/src/engine.c @@ -30,6 +30,7 @@ #include "util.h" #include "sema.h" #include "ops.h" +#include "debug.h" #include "engine.h" #include "engine-backend.h" @@ -166,7 +167,7 @@ gpgme_engine_check_version (gpgme_protocol_t proto) info->req_version); UNLOCK (engine_info_lock); - return result ? 0 : gpg_error (GPG_ERR_INV_ENGINE); + return result ? 0 : trace_gpg_error (GPG_ERR_INV_ENGINE); } @@ -359,7 +360,7 @@ _gpgme_set_engine_info (gpgme_engine_info_t info, gpgme_protocol_t proto, info = info->next; if (!info) - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Prepare new members. */ if (file_name) @@ -449,7 +450,7 @@ _gpgme_engine_new (gpgme_engine_info_t info, engine_t *r_engine) engine_t engine; if (!info->file_name || !info->version) - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); engine = calloc (1, sizeof *engine); if (!engine) diff --git a/src/gpgconf.c b/src/gpgconf.c index cbfd3dd4..47ef47ab 100644 --- a/src/gpgconf.c +++ b/src/gpgconf.c @@ -26,6 +26,7 @@ #include "ops.h" #include "engine.h" +#include "debug.h" #ifdef ENABLE_GPGCONF /* engine-gpgconf.c. */ diff --git a/src/import.c b/src/import.c index f599c232..d4edaba1 100644 --- a/src/import.c +++ b/src/import.c @@ -131,7 +131,7 @@ parse_import (char *args, gpgme_import_status_t *import_status, int problem) { /* The crypto backend does not behave. */ free (import); - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); } args = tail; @@ -196,7 +196,7 @@ parse_import_res (char *args, gpgme_import_result_t result) (x) = strtol (args, &tail, 0); \ if (errno || args == tail || *tail != ' ') \ /* The crypto backend does not behave. */ \ - return gpg_error (GPG_ERR_INV_ENGINE); \ + return trace_gpg_error (GPG_ERR_INV_ENGINE); \ args = tail; PARSE_NEXT (result->considered); diff --git a/src/key.c b/src/key.c index c1d8ceb5..1094f19b 100644 --- a/src/key.c +++ b/src/key.c @@ -30,6 +30,7 @@ #include "util.h" #include "ops.h" #include "sema.h" +#include "debug.h" /* Protects all reference counters in keys. All other accesses to a diff --git a/src/op-support.c b/src/op-support.c index 808eac87..d42a247b 100644 --- a/src/op-support.c +++ b/src/op-support.c @@ -31,6 +31,7 @@ #include "context.h" #include "ops.h" #include "util.h" +#include "debug.h" gpgme_error_t @@ -199,7 +200,7 @@ _gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key) { /* The crypto backend does not behave. */ free (inv_key); - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); } switch (reason) diff --git a/src/passphrase.c b/src/passphrase.c index 17f14436..7e5508eb 100644 --- a/src/passphrase.c +++ b/src/passphrase.c @@ -32,6 +32,7 @@ #include "context.h" #include "ops.h" #include "util.h" +#include "debug.h" typedef struct diff --git a/src/passwd.c b/src/passwd.c index 0ed54ba6..e832026d 100644 --- a/src/passwd.c +++ b/src/passwd.c @@ -56,7 +56,7 @@ parse_error (char *args) where = args; } else - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); err = atoi (which); diff --git a/src/progress.c b/src/progress.c index 76ec47f5..a4e48f16 100644 --- a/src/progress.c +++ b/src/progress.c @@ -28,6 +28,7 @@ #include "util.h" #include "context.h" +#include "debug.h" gpgme_error_t diff --git a/src/sig-notation.c b/src/sig-notation.c index 8386378a..46efac6d 100644 --- a/src/sig-notation.c +++ b/src/sig-notation.c @@ -30,6 +30,7 @@ #include "util.h" #include "context.h" #include "ops.h" +#include "debug.h" /* Free the signature notation object and all associated resources. @@ -159,13 +160,13 @@ _gpgme_parse_notation (gpgme_sig_notation_t *notationp, /* A few simple sanity checks. */ if (len > strlen (data)) - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); /* See below for the format of a notation subpacket. It has at least four octets of flags and two times two octets of length information. */ if (type == 20 && len < 4 + 2 + 2) - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); err = _gpgme_decode_percent_string (data, &decoded_data, 0, 1); if (err) @@ -234,7 +235,7 @@ _gpgme_parse_notation (gpgme_sig_notation_t *notationp, if (4 + 2 + 2 + name_len + value_len > len) { free (decoded_data); - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); } name = (char *) bdata; diff --git a/src/sign.c b/src/sign.c index 15092049..67280e9f 100644 --- a/src/sign.c +++ b/src/sign.c @@ -169,14 +169,14 @@ parse_sig_created (char *args, gpgme_new_signature_t *sigp) default: /* The backend engine is not behaving. */ free (sig); - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); } args++; if (*args != ' ') { free (sig); - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); } gpg_err_set_errno (0); @@ -185,7 +185,7 @@ parse_sig_created (char *args, gpgme_new_signature_t *sigp) { /* The crypto backend does not behave. */ free (sig); - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); } args = tail; @@ -194,7 +194,7 @@ parse_sig_created (char *args, gpgme_new_signature_t *sigp) { /* The crypto backend does not behave. */ free (sig); - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); } args = tail; @@ -205,7 +205,7 @@ parse_sig_created (char *args, gpgme_new_signature_t *sigp) { /* The crypto backend does not behave. */ free (sig); - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); } args = tail; @@ -214,7 +214,7 @@ parse_sig_created (char *args, gpgme_new_signature_t *sigp) { /* The crypto backend does not behave. */ free (sig); - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); } args = tail; while (*args == ' ') @@ -224,7 +224,7 @@ parse_sig_created (char *args, gpgme_new_signature_t *sigp) { /* The crypto backend does not behave. */ free (sig); - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); } tail = strchr (args, ' '); diff --git a/src/trust-item.c b/src/trust-item.c index 226298b4..5a0b5449 100644 --- a/src/trust-item.c +++ b/src/trust-item.c @@ -30,6 +30,7 @@ #include "util.h" #include "ops.h" #include "sema.h" +#include "debug.h" /* Protects all reference counters in trust items. All other accesses diff --git a/src/verify.c b/src/verify.c index a61cc950..c32241ae 100644 --- a/src/verify.c +++ b/src/verify.c @@ -346,7 +346,7 @@ parse_new_sig (op_data_t opd, gpgme_status_code_t code, char *args) /* Parse the timestamp. */ sig->timestamp = _gpgme_parse_timestamp (end, &tail); if (sig->timestamp == -1 || end == tail || (*tail && *tail != ' ')) - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); end = tail; while (*end == ' ') end++; @@ -420,12 +420,12 @@ parse_valid_sig (gpgme_signature_t sig, char *args) sig->timestamp = _gpgme_parse_timestamp (end, &tail); if (sig->timestamp == -1 || end == tail || (*tail && *tail != ' ')) - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); end = tail; sig->exp_timestamp = _gpgme_parse_timestamp (end, &tail); if (sig->exp_timestamp == -1 || end == tail || (*tail && *tail != ' ')) - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); end = tail; while (*end == ' ') @@ -445,7 +445,7 @@ parse_valid_sig (gpgme_signature_t sig, char *args) gpg_err_set_errno (0); sig->pubkey_algo = strtol (end, &tail, 0); if (errno || end == tail || *tail != ' ') - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); end = tail; while (*end == ' ') @@ -458,7 +458,7 @@ parse_valid_sig (gpgme_signature_t sig, char *args) gpg_err_set_errno (0); sig->hash_algo = strtol (end, &tail, 0); if (errno || end == tail || *tail != ' ') - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); end = tail; } } @@ -491,7 +491,7 @@ parse_notation (gpgme_signature_t sig, gpgme_status_code_t code, char *args) if (notation) /* There is another notation name without data for the previous one. The crypto backend misbehaves. */ - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); err = _gpgme_sig_notation_create (¬ation, NULL, 0, NULL, 0, 0); if (err) @@ -544,7 +544,7 @@ parse_notation (gpgme_signature_t sig, gpgme_status_code_t code, char *args) if (!notation || !notation->name) /* There is notation data without a previous notation name. The crypto backend misbehaves. */ - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); if (!notation->value) { @@ -569,7 +569,7 @@ parse_notation (gpgme_signature_t sig, gpgme_status_code_t code, char *args) notation->value_len += strlen (dest); } else - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); return 0; } @@ -645,7 +645,7 @@ parse_error (gpgme_signature_t sig, char *args, int set_status) where = args; } else - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); err = atoi (which); @@ -708,7 +708,7 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args) case GPGME_STATUS_VALIDSIG: opd->only_newsig_seen = 0; return sig ? parse_valid_sig (sig, args) - : gpg_error (GPG_ERR_INV_ENGINE); + : trace_gpg_error (GPG_ERR_INV_ENGINE); case GPGME_STATUS_NODATA: opd->only_newsig_seen = 0; @@ -729,7 +729,7 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args) case GPGME_STATUS_POLICY_URL: opd->only_newsig_seen = 0; return sig ? parse_notation (sig, code, args) - : gpg_error (GPG_ERR_INV_ENGINE); + : trace_gpg_error (GPG_ERR_INV_ENGINE); case GPGME_STATUS_TRUST_UNDEFINED: case GPGME_STATUS_TRUST_NEVER: @@ -738,7 +738,7 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args) case GPGME_STATUS_TRUST_ULTIMATE: opd->only_newsig_seen = 0; return sig ? parse_trust (sig, code, args) - : gpg_error (GPG_ERR_INV_ENGINE); + : trace_gpg_error (GPG_ERR_INV_ENGINE); case GPGME_STATUS_PKA_TRUST_BAD: case GPGME_STATUS_PKA_TRUST_GOOD: @@ -746,7 +746,7 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args) /* Check that we only get one of these status codes per signature; if not the crypto backend misbehaves. */ if (!sig || sig->pka_trust || sig->pka_address) - return gpg_error (GPG_ERR_INV_ENGINE); + return trace_gpg_error (GPG_ERR_INV_ENGINE); sig->pka_trust = code == GPGME_STATUS_PKA_TRUST_GOOD? 2 : 1; end = strchr (args, ' '); if (end) diff --git a/src/wait-global.c b/src/wait-global.c index f3aa399b..9a194b0d 100644 --- a/src/wait-global.c +++ b/src/wait-global.c @@ -34,6 +34,7 @@ #include "wait.h" #include "priv-io.h" #include "ops.h" +#include "debug.h" /* The global event loop is used for all asynchronous operations (except key listing) for which no user I/O callbacks are specified. diff --git a/src/wait-private.c b/src/wait-private.c index d0552cea..aab8fb7f 100644 --- a/src/wait-private.c +++ b/src/wait-private.c @@ -31,6 +31,7 @@ #include "ops.h" #include "priv-io.h" #include "util.h" +#include "debug.h" /* The private event loops are used for all blocking operations, and diff --git a/src/wait-user.c b/src/wait-user.c index 42bb3a5b..ba287617 100644 --- a/src/wait-user.c +++ b/src/wait-user.c @@ -29,6 +29,7 @@ #include "priv-io.h" #include "wait.h" #include "ops.h" +#include "debug.h" /* The user event loops are used for all asynchronous operations for