From 7c220e387d511b0cf66f99370759c36b729cc444 Mon Sep 17 00:00:00 2001 From: Andre Heinecke Date: Tue, 27 Mar 2018 11:24:55 +0200 Subject: core: Initialize key return value in gpgme_get_key * src/keylist.c (gpgme_get_key): Set r_key to NULL. -- The c++ bindings and others assumed that r_key is set to NULL on error. This is the behavior gpgme_op_keylist_next also has. Even if it is not specified what happens to r_key on error setting it to NULL should not hurt and is more expected behavior. This directly fixes an uninitialized memory access error in the c++ bindings / Kleopatra: GnuPG-Bug-Id: T3865 And will fix some additional random crashes in Kleopatra and GpgOL. --- src/keylist.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/keylist.c b/src/keylist.c index 7956935b..9c5bd4ea 100644 --- a/src/keylist.c +++ b/src/keylist.c @@ -1269,6 +1269,8 @@ gpgme_get_key (gpgme_ctx_t ctx, const char *fpr, gpgme_key_t *r_key, if (!ctx || !r_key || !fpr) return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); + *r_key = NULL; + if (strlen (fpr) < 8) /* We have at least a key ID. */ return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); -- cgit v1.2.3 From 4b2fa657d195382d14ac99be40b66327e0fc855c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 28 Mar 2018 20:50:54 +0200 Subject: json: Make native messaging work. * src/gpgme-json.c (opt_debug): New. (process_request): Add optional arg nm_mode. In this mode take the request from a "message" object. (native_messaging_repl): Add debug output and call process_request in NM_MODE. (main): Add option --debug. Parse envvar GPGME_JSON_DEBUG as an alternative way to enable this. Use a default log file. -- Note that the default log file is ~/.gnupg/S.gpgme-json.log . Thus to debug a javascript application you should start watchgnupg --time-only --force ~/.gnupg/S.gpgme-json.log in a separate tty and then use GPGME_JSON_DEBUG=1 firefox & to run firefox. Signed-off-by: Werner Koch --- src/gpgme-json.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 64 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/gpgme-json.c b/src/gpgme-json.c index e38f9d89..e5c84bb7 100644 --- a/src/gpgme-json.c +++ b/src/gpgme-json.c @@ -56,7 +56,8 @@ static char *error_object_string (const char *message, /* True if interactive mode is active. */ static int opt_interactive; - +/* True is debug mode is active. */ +static int opt_debug; /* @@ -754,9 +755,10 @@ op_help (cjson_t request, cjson_t result) /* Process a request and return the response. The response is a newly - * allocated staring or NULL in case of an error. */ + * allocated staring or NULL in case of an error. With NM_MODE set + * the actual request is taken from a "message" object. */ static char * -process_request (const char *request) +process_request (const char *request, int nm_mode) { static struct { const char *op; @@ -770,6 +772,7 @@ process_request (const char *request) { NULL } }; size_t erroff; + cjson_t json_orig; cjson_t json; cjson_t j_tmp, j_op; cjson_t response; @@ -780,7 +783,7 @@ process_request (const char *request) response = xjson_CreateObject (); - json = cJSON_Parse (request, &erroff); + json = json_orig = cJSON_Parse (request, &erroff); if (!json) { log_string (GPGRT_LOGLVL_INFO, request); @@ -788,6 +791,16 @@ process_request (const char *request) error_object (response, "invalid JSON object at offset %zu\n", erroff); goto leave; } + if (nm_mode) + { + json = cJSON_GetObjectItem (json, "message"); + if (!json) + { + log_info ("no \"message\" object in request\n"); + error_object (response, "no \"message\" object in request\n"); + goto leave; + } + } j_tmp = cJSON_GetObjectItem (json, "help"); helpmode = (j_tmp && cjson_is_true (j_tmp)); @@ -844,8 +857,7 @@ process_request (const char *request) } leave: - cJSON_Delete (json); - json = NULL; + cJSON_Delete (json_orig); if (opt_interactive) res = cJSON_Print (response); else @@ -930,7 +942,7 @@ process_meta_commands (const char *request) "\"\\nMeta commands:\\n" " ,help This help\\n" " ,quit Terminate process\"" - "}"); + "}", 0); else if (!strncmp (request, "quit", 4) && (spacep (request+4) || !request[4])) exit (0); else @@ -1029,7 +1041,7 @@ interactive_repl (void) } else if (request) { - response = process_request (request); + response = process_request (request, 0); } xfree (request); request = NULL; @@ -1072,7 +1084,7 @@ interactive_repl (void) } -/* Read and process asingle request. */ +/* Read and process a single request. */ static void read_and_process_single_request (void) { @@ -1093,7 +1105,7 @@ read_and_process_single_request (void) if (request) { xfree (response); - response = process_request (request); + response = process_request (request, 0); if (response) { es_fputs (response, es_stdout); @@ -1126,6 +1138,7 @@ native_messaging_repl (void) * binary mode. */ es_set_binary (es_stdin); es_set_binary (es_stdout); + es_setbuf (es_stdin, NULL); for (;;) { @@ -1149,7 +1162,7 @@ native_messaging_repl (void) { log_error ("error reading request: request too long (%zu MiB)\n", (size_t)nrequest / (1024*1024)); - /* Fixme: Shall we read the request t the bit bucket and + /* Fixme: Shall we read the request to the bit bucket and * return an error reponse or just return an error reponse * and terminate? Needs some testing. */ break; @@ -1181,8 +1194,12 @@ native_messaging_repl (void) } else /* Process request */ { + if (opt_debug) + log_debug ("request='%s'\n", request); xfree (response); - response = process_request (request); + response = process_request (request, 1); + if (opt_debug) + log_debug ("response='%s'\n", response); } nresponse = strlen (response); @@ -1263,12 +1280,18 @@ main (int argc, char *argv[]) enum { CMD_DEFAULT = 0, CMD_INTERACTIVE = 'i', CMD_SINGLE = 's', - CMD_LIBVERSION = 501 + CMD_LIBVERSION = 501, } cmd = CMD_DEFAULT; + enum { + OPT_DEBUG = 600 + }; + static gpgrt_opt_t opts[] = { ARGPARSE_c (CMD_INTERACTIVE, "interactive", "Interactive REPL"), ARGPARSE_c (CMD_SINGLE, "single", "Single request mode"), ARGPARSE_c (CMD_LIBVERSION, "lib-version", "Show library version"), + ARGPARSE_s_n(OPT_DEBUG, "debug", "Flyswatter"), + ARGPARSE_end() }; gpgrt_argparse_t pargs = { &argc, &argv}; @@ -1298,6 +1321,8 @@ main (int argc, char *argv[]) cmd = pargs.r_opt; break; + case OPT_DEBUG: opt_debug = 1; break; + default: pargs.err = ARGPARSE_PRINT_WARNING; break; @@ -1305,6 +1330,29 @@ main (int argc, char *argv[]) } gpgrt_argparse (NULL, &pargs, NULL); + if (!opt_debug) + { + const char *s = getenv ("GPGME_JSON_DEBUG"); + if (s && atoi (s) > 0) + opt_debug = 1; + } + + if (opt_debug) + { + const char *home = getenv ("HOME"); + char *file = xstrconcat ("socket://", + home? home:"/tmp", + "/.gnupg/S.gpgme-json.log", NULL); + log_set_file (file); + xfree (file); + } + + if (opt_debug) + { int i; + for (i=0; argv[i]; i++) + log_debug ("argv[%d]='%s'\n", i, argv[i]); + } + switch (cmd) { case CMD_DEFAULT: @@ -1327,6 +1375,9 @@ main (int argc, char *argv[]) break; } + if (opt_debug) + log_debug ("ready"); + #endif /* This is a modern libgp-error. */ return 0; } -- cgit v1.2.3 From 3345a17dda2222e3c1592235e8a1cd9493192777 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 28 Mar 2018 21:21:10 +0200 Subject: json: Remove the "message" object thingy again. * src/gpgme-json.c (process_request): Remove 'nm_mode'. -- This was an error in the javascript testing code. Thus the Mozilla specs are correct that the request is send verbatim. Signed-off-by: Werner Koch --- src/gpgme-json.c | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/gpgme-json.c b/src/gpgme-json.c index e5c84bb7..5f16daf6 100644 --- a/src/gpgme-json.c +++ b/src/gpgme-json.c @@ -755,10 +755,9 @@ op_help (cjson_t request, cjson_t result) /* Process a request and return the response. The response is a newly - * allocated staring or NULL in case of an error. With NM_MODE set - * the actual request is taken from a "message" object. */ + * allocated string or NULL in case of an error. */ static char * -process_request (const char *request, int nm_mode) +process_request (const char *request) { static struct { const char *op; @@ -772,7 +771,6 @@ process_request (const char *request, int nm_mode) { NULL } }; size_t erroff; - cjson_t json_orig; cjson_t json; cjson_t j_tmp, j_op; cjson_t response; @@ -783,7 +781,7 @@ process_request (const char *request, int nm_mode) response = xjson_CreateObject (); - json = json_orig = cJSON_Parse (request, &erroff); + json = cJSON_Parse (request, &erroff); if (!json) { log_string (GPGRT_LOGLVL_INFO, request); @@ -791,16 +789,6 @@ process_request (const char *request, int nm_mode) error_object (response, "invalid JSON object at offset %zu\n", erroff); goto leave; } - if (nm_mode) - { - json = cJSON_GetObjectItem (json, "message"); - if (!json) - { - log_info ("no \"message\" object in request\n"); - error_object (response, "no \"message\" object in request\n"); - goto leave; - } - } j_tmp = cJSON_GetObjectItem (json, "help"); helpmode = (j_tmp && cjson_is_true (j_tmp)); @@ -857,7 +845,7 @@ process_request (const char *request, int nm_mode) } leave: - cJSON_Delete (json_orig); + cJSON_Delete (json); if (opt_interactive) res = cJSON_Print (response); else @@ -942,7 +930,7 @@ process_meta_commands (const char *request) "\"\\nMeta commands:\\n" " ,help This help\\n" " ,quit Terminate process\"" - "}", 0); + "}"); else if (!strncmp (request, "quit", 4) && (spacep (request+4) || !request[4])) exit (0); else @@ -1041,7 +1029,7 @@ interactive_repl (void) } else if (request) { - response = process_request (request, 0); + response = process_request (request); } xfree (request); request = NULL; @@ -1105,7 +1093,7 @@ read_and_process_single_request (void) if (request) { xfree (response); - response = process_request (request, 0); + response = process_request (request); if (response) { es_fputs (response, es_stdout); @@ -1138,7 +1126,7 @@ native_messaging_repl (void) * binary mode. */ es_set_binary (es_stdin); es_set_binary (es_stdout); - es_setbuf (es_stdin, NULL); + es_setbuf (es_stdin, NULL); /* stdin needs to be unbuffered! */ for (;;) { @@ -1197,7 +1185,7 @@ native_messaging_repl (void) if (opt_debug) log_debug ("request='%s'\n", request); xfree (response); - response = process_request (request, 1); + response = process_request (request); if (opt_debug) log_debug ("response='%s'\n", response); } -- cgit v1.2.3 From 60d7a1e8f625ea0db455bff989534dd52f0650c7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 29 Mar 2018 15:06:47 +0200 Subject: json: Build only a dummy if libgpg-error is < 1.28 Signed-off-by: Werner Koch --- src/gpgme-json.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/gpgme-json.c b/src/gpgme-json.c index 5f16daf6..b54d9a8a 100644 --- a/src/gpgme-json.c +++ b/src/gpgme-json.c @@ -41,6 +41,10 @@ #include "cJSON.h" +#if GPGRT_VERSION_NUMBER < 0x011c00 /* 1.28 */ +int main (void){fputs ("Build with Libgpg-error >= 1.28!\n", stderr);return 1;} +#else /* libgpg-error >= 1.28 */ + /* We don't allow a request with more than 64 MiB. */ #define MAX_REQUEST_SIZE (64 * 1024 * 1024) @@ -1369,3 +1373,4 @@ main (int argc, char *argv[]) #endif /* This is a modern libgp-error. */ return 0; } +#endif /* libgpg-error >= 1.28 */ -- cgit v1.2.3