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;
|
struct _gpgme_op_decrypt_result result;
|
||||||
|
|
||||||
|
/* The error code from a FAILURE status line or 0. */
|
||||||
|
gpg_error_t failure_code;
|
||||||
|
|
||||||
int okay;
|
int okay;
|
||||||
int failed;
|
int failed;
|
||||||
|
|
||||||
@ -192,6 +195,10 @@ _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code,
|
|||||||
|
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
|
case GPGME_STATUS_FAILURE:
|
||||||
|
opd->failure_code = _gpgme_parse_failure (args);
|
||||||
|
break;
|
||||||
|
|
||||||
case GPGME_STATUS_EOF:
|
case GPGME_STATUS_EOF:
|
||||||
/* FIXME: These error values should probably be attributed to
|
/* FIXME: These error values should probably be attributed to
|
||||||
the underlying crypto engine (as error source). */
|
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);
|
return gpg_error (GPG_ERR_DECRYPT_FAILED);
|
||||||
else if (!opd->okay)
|
else if (!opd->okay)
|
||||||
return gpg_error (GPG_ERR_NO_DATA);
|
return gpg_error (GPG_ERR_NO_DATA);
|
||||||
|
else if (opd->failure_code)
|
||||||
|
return opd->failure_code;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPGME_STATUS_DECRYPTION_INFO:
|
case GPGME_STATUS_DECRYPTION_INFO:
|
||||||
|
@ -36,6 +36,9 @@ typedef struct
|
|||||||
{
|
{
|
||||||
struct _gpgme_op_encrypt_result result;
|
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
|
/* A pointer to the next pointer of the last invalid recipient in
|
||||||
the list. This makes appending new invalid recipients painless
|
the list. This makes appending new invalid recipients painless
|
||||||
while preserving the order. */
|
while preserving the order. */
|
||||||
@ -114,9 +117,15 @@ _gpgme_encrypt_status_handler (void *priv, gpgme_status_code_t code,
|
|||||||
|
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
|
case GPGME_STATUS_FAILURE:
|
||||||
|
opd->failure_code = _gpgme_parse_failure (args);
|
||||||
|
break;
|
||||||
|
|
||||||
case GPGME_STATUS_EOF:
|
case GPGME_STATUS_EOF:
|
||||||
if (opd->result.invalid_recipients)
|
if (opd->result.invalid_recipients)
|
||||||
return gpg_error (GPG_ERR_UNUSABLE_PUBKEY);
|
return gpg_error (GPG_ERR_UNUSABLE_PUBKEY);
|
||||||
|
if (opd->failure_code)
|
||||||
|
return opd->failure_code;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPGME_STATUS_INV_RECP:
|
case GPGME_STATUS_INV_RECP:
|
||||||
|
@ -37,6 +37,9 @@ typedef struct
|
|||||||
{
|
{
|
||||||
struct _gpgme_op_genkey_result result;
|
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. */
|
/* The key parameters passed to the crypto engine. */
|
||||||
gpgme_data_t key_parameter;
|
gpgme_data_t key_parameter;
|
||||||
} *op_data_t;
|
} *op_data_t;
|
||||||
@ -118,10 +121,16 @@ genkey_status_handler (void *priv, gpgme_status_code_t code, char *args)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GPGME_STATUS_FAILURE:
|
||||||
|
opd->failure_code = _gpgme_parse_failure (args);
|
||||||
|
break;
|
||||||
|
|
||||||
case GPGME_STATUS_EOF:
|
case GPGME_STATUS_EOF:
|
||||||
/* FIXME: Should return some more useful error value. */
|
/* FIXME: Should return some more useful error value. */
|
||||||
if (!opd->result.primary && !opd->result.sub)
|
if (!opd->result.primary && !opd->result.sub)
|
||||||
return gpg_error (GPG_ERR_GENERAL);
|
return gpg_error (GPG_ERR_GENERAL);
|
||||||
|
else if (opd->failure_code)
|
||||||
|
return opd->failure_code;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPGME_STATUS_INQUIRE_MAXLEN:
|
case GPGME_STATUS_INQUIRE_MAXLEN:
|
||||||
|
@ -548,7 +548,8 @@ typedef enum
|
|||||||
GPGME_STATUS_ATTRIBUTE = 89,
|
GPGME_STATUS_ATTRIBUTE = 89,
|
||||||
GPGME_STATUS_BEGIN_SIGNING = 90,
|
GPGME_STATUS_BEGIN_SIGNING = 90,
|
||||||
GPGME_STATUS_KEY_NOT_CREATED = 91,
|
GPGME_STATUS_KEY_NOT_CREATED = 91,
|
||||||
GPGME_STATUS_INQUIRE_MAXLEN = 92
|
GPGME_STATUS_INQUIRE_MAXLEN = 92,
|
||||||
|
GPGME_STATUS_FAILURE = 93
|
||||||
}
|
}
|
||||||
gpgme_status_code_t;
|
gpgme_status_code_t;
|
||||||
|
|
||||||
|
@ -337,3 +337,27 @@ _gpgme_parse_plaintext (char *args, char **filenamep)
|
|||||||
}
|
}
|
||||||
return 0;
|
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. */
|
FILENAMEP. */
|
||||||
gpgme_error_t _gpgme_parse_plaintext (char *args, char **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. */
|
/* From verify.c. */
|
||||||
|
@ -128,6 +128,19 @@ _gpgme_passphrase_status_handler (void *priv, gpgme_status_code_t code,
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
/* Ignore all other codes. */
|
/* Ignore all other codes. */
|
||||||
break;
|
break;
|
||||||
|
@ -30,6 +30,9 @@
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
/* The error code from a FAILURE status line or 0. */
|
||||||
|
gpg_error_t failure_code;
|
||||||
|
|
||||||
int success_seen;
|
int success_seen;
|
||||||
int error_seen;
|
int error_seen;
|
||||||
} *op_data_t;
|
} *op_data_t;
|
||||||
@ -92,6 +95,10 @@ passwd_status_handler (void *priv, gpgme_status_code_t code, char *args)
|
|||||||
opd->success_seen = 1;
|
opd->success_seen = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GPGME_STATUS_FAILURE:
|
||||||
|
opd->failure_code = _gpgme_parse_failure (args);
|
||||||
|
break;
|
||||||
|
|
||||||
case GPGME_STATUS_EOF:
|
case GPGME_STATUS_EOF:
|
||||||
/* In case the OpenPGP engine does not properly implement the
|
/* In case the OpenPGP engine does not properly implement the
|
||||||
passwd command we won't get a success status back and thus we
|
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
|
if (ctx->protocol == GPGME_PROTOCOL_OpenPGP
|
||||||
&& !opd->error_seen && !opd->success_seen)
|
&& !opd->error_seen && !opd->success_seen)
|
||||||
err = gpg_error (GPG_ERR_NOT_SUPPORTED);
|
err = gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||||
|
else if (opd->failure_code)
|
||||||
|
err = opd->failure_code;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
10
src/sign.c
10
src/sign.c
@ -39,6 +39,9 @@ typedef struct
|
|||||||
{
|
{
|
||||||
struct _gpgme_op_sign_result result;
|
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
|
/* A pointer to the next pointer of the last invalid signer in
|
||||||
the list. This makes appending new invalid signers painless
|
the list. This makes appending new invalid signers painless
|
||||||
while preserving the order. */
|
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;
|
opd->last_signer_p = &(*opd->last_signer_p)->next;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GPGME_STATUS_FAILURE:
|
||||||
|
opd->failure_code = _gpgme_parse_failure (args);
|
||||||
|
break;
|
||||||
|
|
||||||
case GPGME_STATUS_EOF:
|
case GPGME_STATUS_EOF:
|
||||||
/* The UI server does not send information about the created
|
/* The UI server does not send information about the created
|
||||||
signature. This is irrelevant for this protocol and thus we
|
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);
|
err = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
|
||||||
else if (!opd->sig_created_seen
|
else if (!opd->sig_created_seen
|
||||||
&& ctx->protocol != GPGME_PROTOCOL_UISERVER)
|
&& ctx->protocol != GPGME_PROTOCOL_UISERVER)
|
||||||
err = gpg_error (GPG_ERR_GENERAL);
|
err = opd->failure_code? opd->failure_code:gpg_error (GPG_ERR_GENERAL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPGME_STATUS_INQUIRE_MAXLEN:
|
case GPGME_STATUS_INQUIRE_MAXLEN:
|
||||||
@ -374,6 +381,7 @@ sign_init_result (gpgme_ctx_t ctx, int ignore_inv_recp)
|
|||||||
opd = hook;
|
opd = hook;
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
opd->failure_code = 0;
|
||||||
opd->last_signer_p = &opd->result.invalid_signers;
|
opd->last_signer_p = &opd->result.invalid_signers;
|
||||||
opd->last_sig_p = &opd->result.signatures;
|
opd->last_sig_p = &opd->result.signatures;
|
||||||
opd->ignore_inv_recp = !!ignore_inv_recp;
|
opd->ignore_inv_recp = !!ignore_inv_recp;
|
||||||
|
@ -66,6 +66,7 @@ static struct status_table_s status_table[] =
|
|||||||
{ "ERRSIG", GPGME_STATUS_ERRSIG },
|
{ "ERRSIG", GPGME_STATUS_ERRSIG },
|
||||||
{ "EXPKEYSIG", GPGME_STATUS_EXPKEYSIG },
|
{ "EXPKEYSIG", GPGME_STATUS_EXPKEYSIG },
|
||||||
{ "EXPSIG", GPGME_STATUS_EXPSIG },
|
{ "EXPSIG", GPGME_STATUS_EXPSIG },
|
||||||
|
{ "FAILURE", GPGME_STATUS_FAILURE },
|
||||||
{ "FILE_DONE", GPGME_STATUS_FILE_DONE },
|
{ "FILE_DONE", GPGME_STATUS_FILE_DONE },
|
||||||
{ "FILE_ERROR", GPGME_STATUS_FILE_ERROR },
|
{ "FILE_ERROR", GPGME_STATUS_FILE_ERROR },
|
||||||
{ "FILE_START", GPGME_STATUS_FILE_START },
|
{ "FILE_START", GPGME_STATUS_FILE_START },
|
||||||
|
@ -38,6 +38,9 @@ typedef struct
|
|||||||
{
|
{
|
||||||
struct _gpgme_op_verify_result result;
|
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;
|
gpgme_signature_t current_sig;
|
||||||
int did_prepare_new_sig;
|
int did_prepare_new_sig;
|
||||||
int only_newsig_seen;
|
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. */
|
error code if we are not ready to process this status. */
|
||||||
return parse_error (sig, args, !!sig );
|
return parse_error (sig, args, !!sig );
|
||||||
|
|
||||||
|
case GPGME_STATUS_FAILURE:
|
||||||
|
opd->failure_code = _gpgme_parse_failure (args);
|
||||||
|
break;
|
||||||
|
|
||||||
case GPGME_STATUS_EOF:
|
case GPGME_STATUS_EOF:
|
||||||
if (sig && !opd->did_prepare_new_sig)
|
if (sig && !opd->did_prepare_new_sig)
|
||||||
calc_sig_summary (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->current_sig = NULL;
|
||||||
}
|
}
|
||||||
opd->only_newsig_seen = 0;
|
opd->only_newsig_seen = 0;
|
||||||
|
if (opd->failure_code)
|
||||||
|
return opd->failure_code;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPGME_STATUS_PLAINTEXT:
|
case GPGME_STATUS_PLAINTEXT:
|
||||||
|
Loading…
Reference in New Issue
Block a user