Improve error return by checking the FAILURE status.
* src/gpgme.h.in (GPGME_STATUS_FAILURE): New. * src/status-table.c (FAILURE): New. * src/op-support.c (_gpgme_parse_failure): New. * src/passphrase.c (_gpgme_passphrase_status_handler): Forward FAILURE status line to the status callback. * src/decrypt.c (op_data_t): Add field failure_code. (_gpgme_decrypt_status_handler): Parse that code and act upon it on EOF. * src/encrypt.c (op_data_t): Add field failure_code. (_gpgme_encrypt_status_handler): Parse that code and act upon it on EOF. * src/genkey.c (op_data_t): Add field failure_code. (genkey_status_handler): Parse that code and act upon it on EOF. * src/passwd.c (op_data_t): Add field failure_code. (passwd_status_handler): Parse that code and act upon it on EOF. * src/sign.c (op_data_t): Add field failure_code. (_gpgme_sign_status_handler): Parse that code and act upon it on EOF. * src/verify.c (op_data_t): Add field failure_code. (_gpgme_verify_status_handler): Parse that code and act upon it on EOF. -- This requires GnuPG 2.1.8 to actually make a difference. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
208f029746
commit
8ddc5801ad
@ -38,6 +38,9 @@ typedef struct
|
||||
{
|
||||
struct _gpgme_op_decrypt_result result;
|
||||
|
||||
/* The error code from a FAILURE status line or 0. */
|
||||
gpg_error_t failure_code;
|
||||
|
||||
int okay;
|
||||
int failed;
|
||||
|
||||
@ -192,6 +195,10 @@ _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code,
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case GPGME_STATUS_FAILURE:
|
||||
opd->failure_code = _gpgme_parse_failure (args);
|
||||
break;
|
||||
|
||||
case GPGME_STATUS_EOF:
|
||||
/* FIXME: These error values should probably be attributed to
|
||||
the underlying crypto engine (as error source). */
|
||||
@ -199,6 +206,8 @@ _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code,
|
||||
return gpg_error (GPG_ERR_DECRYPT_FAILED);
|
||||
else if (!opd->okay)
|
||||
return gpg_error (GPG_ERR_NO_DATA);
|
||||
else if (opd->failure_code)
|
||||
return opd->failure_code;
|
||||
break;
|
||||
|
||||
case GPGME_STATUS_DECRYPTION_INFO:
|
||||
|
@ -36,6 +36,9 @@ typedef struct
|
||||
{
|
||||
struct _gpgme_op_encrypt_result result;
|
||||
|
||||
/* The error code from a FAILURE status line or 0. */
|
||||
gpg_error_t failure_code;
|
||||
|
||||
/* A pointer to the next pointer of the last invalid recipient in
|
||||
the list. This makes appending new invalid recipients painless
|
||||
while preserving the order. */
|
||||
@ -114,9 +117,15 @@ _gpgme_encrypt_status_handler (void *priv, gpgme_status_code_t code,
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case GPGME_STATUS_FAILURE:
|
||||
opd->failure_code = _gpgme_parse_failure (args);
|
||||
break;
|
||||
|
||||
case GPGME_STATUS_EOF:
|
||||
if (opd->result.invalid_recipients)
|
||||
return gpg_error (GPG_ERR_UNUSABLE_PUBKEY);
|
||||
if (opd->failure_code)
|
||||
return opd->failure_code;
|
||||
break;
|
||||
|
||||
case GPGME_STATUS_INV_RECP:
|
||||
|
@ -37,6 +37,9 @@ typedef struct
|
||||
{
|
||||
struct _gpgme_op_genkey_result result;
|
||||
|
||||
/* The error code from a FAILURE status line or 0. */
|
||||
gpg_error_t failure_code;
|
||||
|
||||
/* The key parameters passed to the crypto engine. */
|
||||
gpgme_data_t key_parameter;
|
||||
} *op_data_t;
|
||||
@ -118,10 +121,16 @@ genkey_status_handler (void *priv, gpgme_status_code_t code, char *args)
|
||||
}
|
||||
break;
|
||||
|
||||
case GPGME_STATUS_FAILURE:
|
||||
opd->failure_code = _gpgme_parse_failure (args);
|
||||
break;
|
||||
|
||||
case GPGME_STATUS_EOF:
|
||||
/* FIXME: Should return some more useful error value. */
|
||||
if (!opd->result.primary && !opd->result.sub)
|
||||
return gpg_error (GPG_ERR_GENERAL);
|
||||
else if (opd->failure_code)
|
||||
return opd->failure_code;
|
||||
break;
|
||||
|
||||
case GPGME_STATUS_INQUIRE_MAXLEN:
|
||||
|
@ -548,7 +548,8 @@ typedef enum
|
||||
GPGME_STATUS_ATTRIBUTE = 89,
|
||||
GPGME_STATUS_BEGIN_SIGNING = 90,
|
||||
GPGME_STATUS_KEY_NOT_CREATED = 91,
|
||||
GPGME_STATUS_INQUIRE_MAXLEN = 92
|
||||
GPGME_STATUS_INQUIRE_MAXLEN = 92,
|
||||
GPGME_STATUS_FAILURE = 93
|
||||
}
|
||||
gpgme_status_code_t;
|
||||
|
||||
|
@ -337,3 +337,27 @@ _gpgme_parse_plaintext (char *args, char **filenamep)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Parse a FAILURE status line and return the error code. ARGS is
|
||||
modified to contain the location part. */
|
||||
gpgme_error_t
|
||||
_gpgme_parse_failure (char *args)
|
||||
{
|
||||
char *where, *which;
|
||||
|
||||
where = strchr (args, ' ');
|
||||
if (!where)
|
||||
return trace_gpg_error (GPG_ERR_INV_ENGINE);
|
||||
|
||||
*where = '\0';
|
||||
which = where + 1;
|
||||
|
||||
where = strchr (which, ' ');
|
||||
if (where)
|
||||
*where = '\0';
|
||||
|
||||
where = args;
|
||||
|
||||
return atoi (which);
|
||||
}
|
||||
|
@ -65,6 +65,10 @@ gpgme_error_t _gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key);
|
||||
FILENAMEP. */
|
||||
gpgme_error_t _gpgme_parse_plaintext (char *args, char **filenamep);
|
||||
|
||||
/* Parse a FAILURE status line and return the error code. ARGS is
|
||||
modified to contain the location part. */
|
||||
gpgme_error_t _gpgme_parse_failure (char *args);
|
||||
|
||||
|
||||
|
||||
/* From verify.c. */
|
||||
|
@ -128,6 +128,19 @@ _gpgme_passphrase_status_handler (void *priv, gpgme_status_code_t code,
|
||||
}
|
||||
break;
|
||||
|
||||
case GPGME_STATUS_FAILURE:
|
||||
/* We abuse this status handler to forward FAILURE status codes
|
||||
to the caller. This should better be done in a generic
|
||||
handler, but for now this is sufficient. */
|
||||
if (ctx->status_cb)
|
||||
{
|
||||
err = ctx->status_cb (ctx->status_cb_value, "FAILURE", args);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
/* Ignore all other codes. */
|
||||
break;
|
||||
|
@ -30,6 +30,9 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* The error code from a FAILURE status line or 0. */
|
||||
gpg_error_t failure_code;
|
||||
|
||||
int success_seen;
|
||||
int error_seen;
|
||||
} *op_data_t;
|
||||
@ -92,6 +95,10 @@ passwd_status_handler (void *priv, gpgme_status_code_t code, char *args)
|
||||
opd->success_seen = 1;
|
||||
break;
|
||||
|
||||
case GPGME_STATUS_FAILURE:
|
||||
opd->failure_code = _gpgme_parse_failure (args);
|
||||
break;
|
||||
|
||||
case GPGME_STATUS_EOF:
|
||||
/* In case the OpenPGP engine does not properly implement the
|
||||
passwd command we won't get a success status back and thus we
|
||||
@ -102,6 +109,8 @@ passwd_status_handler (void *priv, gpgme_status_code_t code, char *args)
|
||||
if (ctx->protocol == GPGME_PROTOCOL_OpenPGP
|
||||
&& !opd->error_seen && !opd->success_seen)
|
||||
err = gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||
else if (opd->failure_code)
|
||||
err = opd->failure_code;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
10
src/sign.c
10
src/sign.c
@ -39,6 +39,9 @@ typedef struct
|
||||
{
|
||||
struct _gpgme_op_sign_result result;
|
||||
|
||||
/* The error code from a FAILURE status line or 0. */
|
||||
gpg_error_t failure_code;
|
||||
|
||||
/* A pointer to the next pointer of the last invalid signer in
|
||||
the list. This makes appending new invalid signers painless
|
||||
while preserving the order. */
|
||||
@ -327,6 +330,10 @@ _gpgme_sign_status_handler (void *priv, gpgme_status_code_t code, char *args)
|
||||
opd->last_signer_p = &(*opd->last_signer_p)->next;
|
||||
break;
|
||||
|
||||
case GPGME_STATUS_FAILURE:
|
||||
opd->failure_code = _gpgme_parse_failure (args);
|
||||
break;
|
||||
|
||||
case GPGME_STATUS_EOF:
|
||||
/* The UI server does not send information about the created
|
||||
signature. This is irrelevant for this protocol and thus we
|
||||
@ -335,7 +342,7 @@ _gpgme_sign_status_handler (void *priv, gpgme_status_code_t code, char *args)
|
||||
err = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
|
||||
else if (!opd->sig_created_seen
|
||||
&& ctx->protocol != GPGME_PROTOCOL_UISERVER)
|
||||
err = gpg_error (GPG_ERR_GENERAL);
|
||||
err = opd->failure_code? opd->failure_code:gpg_error (GPG_ERR_GENERAL);
|
||||
break;
|
||||
|
||||
case GPGME_STATUS_INQUIRE_MAXLEN:
|
||||
@ -374,6 +381,7 @@ sign_init_result (gpgme_ctx_t ctx, int ignore_inv_recp)
|
||||
opd = hook;
|
||||
if (err)
|
||||
return err;
|
||||
opd->failure_code = 0;
|
||||
opd->last_signer_p = &opd->result.invalid_signers;
|
||||
opd->last_sig_p = &opd->result.signatures;
|
||||
opd->ignore_inv_recp = !!ignore_inv_recp;
|
||||
|
@ -66,6 +66,7 @@ static struct status_table_s status_table[] =
|
||||
{ "ERRSIG", GPGME_STATUS_ERRSIG },
|
||||
{ "EXPKEYSIG", GPGME_STATUS_EXPKEYSIG },
|
||||
{ "EXPSIG", GPGME_STATUS_EXPSIG },
|
||||
{ "FAILURE", GPGME_STATUS_FAILURE },
|
||||
{ "FILE_DONE", GPGME_STATUS_FILE_DONE },
|
||||
{ "FILE_ERROR", GPGME_STATUS_FILE_ERROR },
|
||||
{ "FILE_START", GPGME_STATUS_FILE_START },
|
||||
|
@ -38,6 +38,9 @@ typedef struct
|
||||
{
|
||||
struct _gpgme_op_verify_result result;
|
||||
|
||||
/* The error code from a FAILURE status line or 0. */
|
||||
gpg_error_t failure_code;
|
||||
|
||||
gpgme_signature_t current_sig;
|
||||
int did_prepare_new_sig;
|
||||
int only_newsig_seen;
|
||||
@ -769,6 +772,10 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args)
|
||||
error code if we are not ready to process this status. */
|
||||
return parse_error (sig, args, !!sig );
|
||||
|
||||
case GPGME_STATUS_FAILURE:
|
||||
opd->failure_code = _gpgme_parse_failure (args);
|
||||
break;
|
||||
|
||||
case GPGME_STATUS_EOF:
|
||||
if (sig && !opd->did_prepare_new_sig)
|
||||
calc_sig_summary (sig);
|
||||
@ -795,6 +802,8 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args)
|
||||
opd->current_sig = NULL;
|
||||
}
|
||||
opd->only_newsig_seen = 0;
|
||||
if (opd->failure_code)
|
||||
return opd->failure_code;
|
||||
break;
|
||||
|
||||
case GPGME_STATUS_PLAINTEXT:
|
||||
|
Loading…
Reference in New Issue
Block a user