json: Add code to gpg_error based messages
* src/gpgme-json.c (gpg_error_object): New. (error_object_v): Extend to take error. -- Having the error code is helpful, especially as the strerrors are localized. E.g. to detect an ERROR_CANCELED.
This commit is contained in:
parent
61f4532ba9
commit
9fca7c8406
138
src/gpgme-json.c
138
src/gpgme-json.c
@ -61,7 +61,8 @@ int main (void){fputs ("Build with Libgpg-error >= 1.28!\n", stderr);return 1;}
|
|||||||
|
|
||||||
static void xoutofcore (const char *type) GPGRT_ATTR_NORETURN;
|
static void xoutofcore (const char *type) GPGRT_ATTR_NORETURN;
|
||||||
static cjson_t error_object_v (cjson_t json, const char *message,
|
static cjson_t error_object_v (cjson_t json, const char *message,
|
||||||
va_list arg_ptr) GPGRT_ATTR_PRINTF(2,0);
|
va_list arg_ptr, gpg_error_t err)
|
||||||
|
GPGRT_ATTR_PRINTF(2,0);
|
||||||
static cjson_t error_object (cjson_t json, const char *message,
|
static cjson_t error_object (cjson_t json, const char *message,
|
||||||
...) GPGRT_ATTR_PRINTF(2,3);
|
...) GPGRT_ATTR_PRINTF(2,3);
|
||||||
static char *error_object_string (const char *message,
|
static char *error_object_string (const char *message,
|
||||||
@ -189,6 +190,16 @@ xjson_AddBoolToObject (cjson_t object, const char *name, int abool)
|
|||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Wrapper around cJSON_AddNumberToObject which terminates the process
|
||||||
|
* in case of an error. */
|
||||||
|
static void
|
||||||
|
xjson_AddNumberToObject (cjson_t object, const char *name, double dbl)
|
||||||
|
{
|
||||||
|
if (!cJSON_AddNumberToObject (object, name, dbl))
|
||||||
|
xoutofcore ("cJSON_AddNumberToObject");
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
/* This is similar to cJSON_AddStringToObject but takes (DATA,
|
/* This is similar to cJSON_AddStringToObject but takes (DATA,
|
||||||
* DATALEN) and adds it under NAME as a base 64 encoded string to
|
* DATALEN) and adds it under NAME as a base 64 encoded string to
|
||||||
* OBJECT. */
|
* OBJECT. */
|
||||||
@ -266,7 +277,8 @@ add_base64_to_object (cjson_t object, const char *name,
|
|||||||
/* Create a JSON error object. If JSON is not NULL the error message
|
/* Create a JSON error object. If JSON is not NULL the error message
|
||||||
* is appended to that object. An existing "type" item will be replaced. */
|
* is appended to that object. An existing "type" item will be replaced. */
|
||||||
static cjson_t
|
static cjson_t
|
||||||
error_object_v (cjson_t json, const char *message, va_list arg_ptr)
|
error_object_v (cjson_t json, const char *message, va_list arg_ptr,
|
||||||
|
gpg_error_t err)
|
||||||
{
|
{
|
||||||
cjson_t response, j_tmp;
|
cjson_t response, j_tmp;
|
||||||
char *msg;
|
char *msg;
|
||||||
@ -287,8 +299,10 @@ error_object_v (cjson_t json, const char *message, va_list arg_ptr)
|
|||||||
cJSON_ReplaceItemInObject (response, "type", j_tmp);
|
cJSON_ReplaceItemInObject (response, "type", j_tmp);
|
||||||
}
|
}
|
||||||
xjson_AddStringToObject (response, "msg", msg);
|
xjson_AddStringToObject (response, "msg", msg);
|
||||||
|
|
||||||
xfree (msg);
|
xfree (msg);
|
||||||
|
|
||||||
|
xjson_AddNumberToObject (response, "code", err);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +326,20 @@ error_object (cjson_t json, const char *message, ...)
|
|||||||
va_list arg_ptr;
|
va_list arg_ptr;
|
||||||
|
|
||||||
va_start (arg_ptr, message);
|
va_start (arg_ptr, message);
|
||||||
response = error_object_v (json, message, arg_ptr);
|
response = error_object_v (json, message, arg_ptr, 0);
|
||||||
|
va_end (arg_ptr);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static cjson_t
|
||||||
|
gpg_error_object (cjson_t json, gpg_error_t err, const char *message, ...)
|
||||||
|
{
|
||||||
|
cjson_t response;
|
||||||
|
va_list arg_ptr;
|
||||||
|
|
||||||
|
va_start (arg_ptr, message);
|
||||||
|
response = error_object_v (json, message, arg_ptr, err);
|
||||||
va_end (arg_ptr);
|
va_end (arg_ptr);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
@ -326,7 +353,7 @@ error_object_string (const char *message, ...)
|
|||||||
char *msg;
|
char *msg;
|
||||||
|
|
||||||
va_start (arg_ptr, message);
|
va_start (arg_ptr, message);
|
||||||
response = error_object_v (NULL, message, arg_ptr);
|
response = error_object_v (NULL, message, arg_ptr, 0);
|
||||||
va_end (arg_ptr);
|
va_end (arg_ptr);
|
||||||
|
|
||||||
msg = xjson_Print (response);
|
msg = xjson_Print (response);
|
||||||
@ -666,7 +693,8 @@ add_signature_to_object (cjson_t result, gpgme_signature_t sig)
|
|||||||
{
|
{
|
||||||
gpg_error_t err = 0;
|
gpg_error_t err = 0;
|
||||||
|
|
||||||
if (!cJSON_AddStringToObject (result, "status", gpgme_strerror (sig->status)))
|
if (!cJSON_AddStringToObject (result, "status",
|
||||||
|
gpgme_strerror (sig->status)))
|
||||||
{
|
{
|
||||||
err = gpg_error_from_syserror ();
|
err = gpg_error_from_syserror ();
|
||||||
goto leave;
|
goto leave;
|
||||||
@ -1003,7 +1031,8 @@ op_encrypt (cjson_t request, cjson_t result)
|
|||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
/* Provide a custom error response. */
|
/* Provide a custom error response. */
|
||||||
error_object (result, "Error getting keys: %s", gpg_strerror (err));
|
gpg_error_object (result, err, "Error getting keys: %s",
|
||||||
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1025,8 +1054,8 @@ op_encrypt (cjson_t request, cjson_t result)
|
|||||||
err = data_from_base64_string (&input, j_input);
|
err = data_from_base64_string (&input, j_input);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Error decoding Base-64 encoded 'data': %s",
|
gpg_error_object (result, err, "Error decoding Base-64 encoded "
|
||||||
gpg_strerror (err));
|
"'data': %s", gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1036,7 +1065,8 @@ op_encrypt (cjson_t request, cjson_t result)
|
|||||||
strlen (j_input->valuestring), 0);
|
strlen (j_input->valuestring), 0);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Error getting 'data': %s", gpg_strerror (err));
|
gpg_error_object (result, err, "Error getting 'data': %s",
|
||||||
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1048,7 +1078,7 @@ op_encrypt (cjson_t request, cjson_t result)
|
|||||||
err = gpgme_data_new (&output);
|
err = gpgme_data_new (&output);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Error creating output data object: %s",
|
gpg_error_object (result, err, "Error creating output data object: %s",
|
||||||
gpg_strerror (err));
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
@ -1059,7 +1089,8 @@ op_encrypt (cjson_t request, cjson_t result)
|
|||||||
/* encrypt_result = gpgme_op_encrypt_result (ctx); */
|
/* encrypt_result = gpgme_op_encrypt_result (ctx); */
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Encryption failed: %s", gpg_strerror (err));
|
gpg_error_object (result, err, "Encryption failed: %s",
|
||||||
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
gpgme_data_release (input);
|
gpgme_data_release (input);
|
||||||
@ -1139,7 +1170,8 @@ op_decrypt (cjson_t request, cjson_t result)
|
|||||||
err = data_from_base64_string (&input, j_input);
|
err = data_from_base64_string (&input, j_input);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Error decoding Base-64 encoded 'data': %s",
|
gpg_error_object (result, err,
|
||||||
|
"Error decoding Base-64 encoded 'data': %s",
|
||||||
gpg_strerror (err));
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
@ -1150,7 +1182,8 @@ op_decrypt (cjson_t request, cjson_t result)
|
|||||||
strlen (j_input->valuestring), 0);
|
strlen (j_input->valuestring), 0);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Error getting 'data': %s", gpg_strerror (err));
|
gpg_error_object (result, err, "Error getting 'data': %s",
|
||||||
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1159,7 +1192,8 @@ op_decrypt (cjson_t request, cjson_t result)
|
|||||||
err = gpgme_data_new (&output);
|
err = gpgme_data_new (&output);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Error creating output data object: %s",
|
gpg_error_object (result, err,
|
||||||
|
"Error creating output data object: %s",
|
||||||
gpg_strerror (err));
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
@ -1170,7 +1204,8 @@ op_decrypt (cjson_t request, cjson_t result)
|
|||||||
decrypt_result = gpgme_op_decrypt_result (ctx);
|
decrypt_result = gpgme_op_decrypt_result (ctx);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Decryption failed: %s", gpg_strerror (err));
|
gpg_error_object (result, err, "Decryption failed: %s",
|
||||||
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
gpgme_data_release (input);
|
gpgme_data_release (input);
|
||||||
@ -1187,7 +1222,8 @@ op_decrypt (cjson_t request, cjson_t result)
|
|||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Info output failed: %s", gpg_strerror (err));
|
gpg_error_object (result, err, "Info output failed: %s",
|
||||||
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1196,7 +1232,8 @@ op_decrypt (cjson_t request, cjson_t result)
|
|||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Plaintext output failed: %s", gpg_strerror (err));
|
gpg_error_object (result, err, "Plaintext output failed: %s",
|
||||||
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1290,7 +1327,8 @@ op_sign (cjson_t request, cjson_t result)
|
|||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
/* Provide a custom error response. */
|
/* Provide a custom error response. */
|
||||||
error_object (result, "Error getting keys: %s", gpg_strerror (err));
|
gpg_error_object (result, err, "Error getting keys: %s",
|
||||||
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1303,14 +1341,16 @@ op_sign (cjson_t request, cjson_t result)
|
|||||||
err = gpgme_op_keylist_start (ctx, keystring, 1);
|
err = gpgme_op_keylist_start (ctx, keystring, 1);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Error listing keys: %s", gpg_strerror (err));
|
gpg_error_object (result, err, "Error listing keys: %s",
|
||||||
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
while (!(err = gpgme_op_keylist_next (ctx, &key)))
|
while (!(err = gpgme_op_keylist_next (ctx, &key)))
|
||||||
{
|
{
|
||||||
if ((err = gpgme_signers_add (ctx, key)))
|
if ((err = gpgme_signers_add (ctx, key)))
|
||||||
{
|
{
|
||||||
error_object (result, "Error adding signer: %s", gpg_strerror (err));
|
gpg_error_object (result, err, "Error adding signer: %s",
|
||||||
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
gpgme_key_unref (key);
|
gpgme_key_unref (key);
|
||||||
@ -1334,7 +1374,8 @@ op_sign (cjson_t request, cjson_t result)
|
|||||||
err = data_from_base64_string (&input, j_input);
|
err = data_from_base64_string (&input, j_input);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Error decoding Base-64 encoded 'data': %s",
|
gpg_error_object (result, err,
|
||||||
|
"Error decoding Base-64 encoded 'data': %s",
|
||||||
gpg_strerror (err));
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
@ -1345,7 +1386,8 @@ op_sign (cjson_t request, cjson_t result)
|
|||||||
strlen (j_input->valuestring), 0);
|
strlen (j_input->valuestring), 0);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Error getting 'data': %s", gpg_strerror (err));
|
gpg_error_object (result, err, "Error getting 'data': %s",
|
||||||
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1354,7 +1396,7 @@ op_sign (cjson_t request, cjson_t result)
|
|||||||
err = gpgme_data_new (&output);
|
err = gpgme_data_new (&output);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Error creating output data object: %s",
|
gpg_error_object (result, err, "Error creating output data object: %s",
|
||||||
gpg_strerror (err));
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
@ -1363,7 +1405,8 @@ op_sign (cjson_t request, cjson_t result)
|
|||||||
err = gpgme_op_sign (ctx, input, output, mode);
|
err = gpgme_op_sign (ctx, input, output, mode);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Signing failed: %s", gpg_strerror (err));
|
gpg_error_object (result, err, "Signing failed: %s",
|
||||||
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1383,8 +1426,6 @@ op_sign (cjson_t request, cjson_t result)
|
|||||||
gpgme_data_release (output);
|
gpgme_data_release (output);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const char hlp_verify[] =
|
static const char hlp_verify[] =
|
||||||
"op: \"verify\"\n"
|
"op: \"verify\"\n"
|
||||||
@ -1445,8 +1486,8 @@ op_verify (cjson_t request, cjson_t result)
|
|||||||
err = data_from_base64_string (&input, j_input);
|
err = data_from_base64_string (&input, j_input);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Error decoding Base-64 encoded 'data': %s",
|
gpg_error_object (result, err, "Error decoding Base-64 encoded "
|
||||||
gpg_strerror (err));
|
"'data': %s", gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1456,7 +1497,8 @@ op_verify (cjson_t request, cjson_t result)
|
|||||||
strlen (j_input->valuestring), 0);
|
strlen (j_input->valuestring), 0);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Error getting 'data': %s", gpg_strerror (err));
|
gpg_error_object (result, err, "Error getting 'data': %s",
|
||||||
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1470,8 +1512,8 @@ op_verify (cjson_t request, cjson_t result)
|
|||||||
err = data_from_base64_string (&signature, j_signature);
|
err = data_from_base64_string (&signature, j_signature);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Error decoding Base-64 encoded 'signature': %s",
|
gpg_error_object (result, err, "Error decoding Base-64 encoded "
|
||||||
gpg_strerror (err));
|
"'signature': %s", gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1482,7 +1524,7 @@ op_verify (cjson_t request, cjson_t result)
|
|||||||
0);
|
0);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Error getting 'signature': %s",
|
gpg_error_object (result, err, "Error getting 'signature': %s",
|
||||||
gpg_strerror (err));
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
@ -1493,17 +1535,26 @@ op_verify (cjson_t request, cjson_t result)
|
|||||||
err = gpgme_data_new (&output);
|
err = gpgme_data_new (&output);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Error creating output data object: %s",
|
gpg_error_object (result, err, "Error creating output data object: %s",
|
||||||
gpg_strerror (err));
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decrypt. */
|
gpgme_data_rewind (input);
|
||||||
err = gpgme_op_verify (ctx, signature,
|
gpgme_data_rewind (signature);
|
||||||
input, output);
|
|
||||||
|
/* Verify. */
|
||||||
|
if (signature)
|
||||||
|
{
|
||||||
|
err = gpgme_op_verify (ctx, signature, input, output);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = gpgme_op_verify (ctx, input, 0, output);
|
||||||
|
}
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Verify failed: %s", gpg_strerror (err));
|
gpg_error_object (result, err, "Verify failed: %s", gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
gpgme_data_release (input);
|
gpgme_data_release (input);
|
||||||
@ -1519,7 +1570,8 @@ op_verify (cjson_t request, cjson_t result)
|
|||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Info output failed: %s", gpg_strerror (err));
|
gpg_error_object (result, err, "Info output failed: %s",
|
||||||
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1528,7 +1580,8 @@ op_verify (cjson_t request, cjson_t result)
|
|||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_object (result, "Plaintext output failed: %s", gpg_strerror (err));
|
gpg_error_object (result, err, "Plaintext output failed: %s",
|
||||||
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1621,7 +1674,8 @@ op_getmore (cjson_t request, cjson_t result)
|
|||||||
if (!pending_data.buffer)
|
if (!pending_data.buffer)
|
||||||
{
|
{
|
||||||
err = gpg_error (GPG_ERR_NO_DATA);
|
err = gpg_error (GPG_ERR_NO_DATA);
|
||||||
error_object (result, "Operation not possible: %s", gpg_strerror (err));
|
gpg_error_object (result, err, "Operation not possible: %s",
|
||||||
|
gpg_strerror (err));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1801,7 +1855,7 @@ process_request (const char *request)
|
|||||||
|| strcmp (j_tmp->valuestring, "error"))
|
|| strcmp (j_tmp->valuestring, "error"))
|
||||||
{
|
{
|
||||||
/* No error type response - provide a generic one. */
|
/* No error type response - provide a generic one. */
|
||||||
error_object (response, "Operation failed: %s",
|
gpg_error_object (response, err, "Operation failed: %s",
|
||||||
gpg_strerror (err));
|
gpg_strerror (err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user