aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/decrypt.c9
-rw-r--r--src/encrypt.c9
-rw-r--r--src/genkey.c9
-rw-r--r--src/gpgme.h.in3
-rw-r--r--src/op-support.c24
-rw-r--r--src/ops.h4
-rw-r--r--src/passphrase.c13
-rw-r--r--src/passwd.c9
-rw-r--r--src/sign.c10
-rw-r--r--src/status-table.c1
-rw-r--r--src/verify.c9
11 files changed, 98 insertions, 2 deletions
diff --git a/src/decrypt.c b/src/decrypt.c
index 4fd92c61..4db68a10 100644
--- a/src/decrypt.c
+++ b/src/decrypt.c
@@ -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:
diff --git a/src/encrypt.c b/src/encrypt.c
index 792c25c5..9f5134de 100644
--- a/src/encrypt.c
+++ b/src/encrypt.c
@@ -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:
diff --git a/src/genkey.c b/src/genkey.c
index 18765dde..3afd3b41 100644
--- a/src/genkey.c
+++ b/src/genkey.c
@@ -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:
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index 76055708..432d18a1 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -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;
diff --git a/src/op-support.c b/src/op-support.c
index 2bcb3a35..02940efd 100644
--- a/src/op-support.c
+++ b/src/op-support.c
@@ -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);
+}
diff --git a/src/ops.h b/src/ops.h
index 782265e4..3662d571 100644
--- a/src/ops.h
+++ b/src/ops.h
@@ -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. */
diff --git a/src/passphrase.c b/src/passphrase.c
index 5d656b17..c88e57d2 100644
--- a/src/passphrase.c
+++ b/src/passphrase.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;
diff --git a/src/passwd.c b/src/passwd.c
index e832026d..ff30df01 100644
--- a/src/passwd.c
+++ b/src/passwd.c
@@ -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:
diff --git a/src/sign.c b/src/sign.c
index 9e22fdb8..6c9fc03a 100644
--- a/src/sign.c
+++ b/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;
diff --git a/src/status-table.c b/src/status-table.c
index c85fa951..6d428d71 100644
--- a/src/status-table.c
+++ b/src/status-table.c
@@ -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 },
diff --git a/src/verify.c b/src/verify.c
index 84487ee4..75914e22 100644
--- a/src/verify.c
+++ b/src/verify.c
@@ -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: