From f7700a016926f0d8e9cb3c0337837deb7fe01079 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 12 Apr 2018 09:17:27 +0200 Subject: [PATCH] core: Add new context flag "no-symkey-cache". * src/gpgme.c (gpgme_set_ctx_flag): Set flag. (gpgme_get_ctx_flag): Get flag. * src/context.h (struct gpgme_context): Add field no_symkey_cache. * src/engine-gpg.c (struct engine_gpg): Ditto. (gpg_set_engine_flags): Set flag. (build_argv): Pass option --no-symkey-cache to gpg. * tests/run-decrypt.c (print_result): Fix segv for symmetric messages. (main): New option --no-symkey-cache. * tests/run-encrypt.c (main): New option --no-symkey-cache. Signed-off-by: Werner Koch --- NEWS | 2 ++ doc/gpgme.texi | 8 +++++++- src/context.h | 3 +++ src/engine-gpg.c | 23 ++++++++++++++++++++++- src/gpgme.c | 8 ++++++++ tests/run-decrypt.c | 20 +++++++++++++++++++- tests/run-encrypt.c | 39 ++++++++++++++++++++++++++++----------- 7 files changed, 89 insertions(+), 14 deletions(-) diff --git a/NEWS b/NEWS index 7b6fdd9c..a8d73a50 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ Noteworthy changes in version 1.10.1 (unreleased) ------------------------------------------------- + * New context flag "no-symkey-cache". + * Interface changes relative to the 1.10.0 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ gpgme_import_result_t EXTENDED: New field 'skipped_v3_keys' diff --git a/doc/gpgme.texi b/doc/gpgme.texi index ab554d86..cbb0e649 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -3069,7 +3069,13 @@ the time when you verified the signature. The string given in @var{value} is passed to the GnuPG engines to request restrictions based on the origin of the request. Valid values are documented in the GnuPG manual and the gpg man page under the -option ``--request-origin''. +option ``--request-origin''. Requires at least GnuPG 2.2.6 to have an +effect. + +@item "no-symkey-cache" +For OpenPGP disable the passphrase cache used for symmetrical en- and +decryption. This cache is based on the message specific salt value. +Requires at least GnuPG 2.2.7 to have an effect. @end table diff --git a/src/context.h b/src/context.h index 202cf168..c8e75ba0 100644 --- a/src/context.h +++ b/src/context.h @@ -121,6 +121,9 @@ struct gpgme_context /* True if the option --auto-key-retrieve shall be passed to gpg. */ unsigned int auto_key_retrieve : 1; + /* Do not use the symmtric encryption passphrase cache. */ + unsigned int no_symkey_cache : 1; + /* Flags for keylist mode. */ gpgme_keylist_mode_t keylist_mode; diff --git a/src/engine-gpg.c b/src/engine-gpg.c index 3b9a6ff5..a37d1f7b 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -145,6 +145,10 @@ struct engine_gpg gpgme_pinentry_mode_t pinentry_mode; char request_origin[10]; + struct { + unsigned int no_symkey_cache : 1; + } flags; + /* NULL or the data object fed to --override_session_key-fd. */ gpgme_data_t override_session_key; }; @@ -642,6 +646,10 @@ gpg_set_engine_flags (void *engine, const gpgme_ctx_t ctx) else strcpy (gpg->request_origin, ctx->request_origin); } + else if (ctx->no_symkey_cache && have_gpg_version (gpg, "2.2.7")) + { + gpg->flags.no_symkey_cache = 1; + } else *gpg->request_origin = 0; } @@ -875,7 +883,7 @@ build_argv (engine_gpg_t gpg, const char *pgmname) argc++; if (!gpg->cmd.used) argc++; /* --batch */ - argc += 2; /* --no-sk-comments, --request-origin */ + argc += 3; /* --no-sk-comments, --request-origin, --no-symkey-cache */ argv = calloc (argc + 1, sizeof *argv); if (!argv) @@ -937,6 +945,19 @@ build_argv (engine_gpg_t gpg, const char *pgmname) argc++; } + if (gpg->flags.no_symkey_cache) + { + argv[argc] = strdup ("--no-symkey-cache"); + if (!argv[argc]) + { + int saved_err = gpg_error_from_syserror (); + free (fd_data_map); + free_argv (argv); + return saved_err; + } + argc++; + } + if (gpg->pinentry_mode && have_gpg_version (gpg, "2.1.0")) { const char *s = NULL; diff --git a/src/gpgme.c b/src/gpgme.c index 9e65c50a..82d67478 100644 --- a/src/gpgme.c +++ b/src/gpgme.c @@ -538,6 +538,10 @@ gpgme_set_ctx_flag (gpgme_ctx_t ctx, const char *name, const char *value) if (!ctx->request_origin) err = gpg_error_from_syserror (); } + else if (!strcmp (name, "no-symkey-cache")) + { + ctx->no_symkey_cache = abool; + } else err = gpg_error (GPG_ERR_UNKNOWN_NAME); @@ -583,6 +587,10 @@ gpgme_get_ctx_flag (gpgme_ctx_t ctx, const char *name) { return ctx->request_origin? ctx->request_origin : ""; } + else if (!strcmp (name, "no-symkey-cache")) + { + return ctx->no_symkey_cache? "1":""; + } else return NULL; } diff --git a/tests/run-decrypt.c b/tests/run-decrypt.c index f4c47544..a2e82a0e 100644 --- a/tests/run-decrypt.c +++ b/tests/run-decrypt.c @@ -60,7 +60,7 @@ print_result (gpgme_decrypt_result_t result) if (result->session_key) printf ("Session key: %s\n", result->session_key); - for (recp = result->recipients; recp->next; recp = recp->next) + for (recp = result->recipients; recp && recp->next; recp = recp->next) { printf ("recipient %d\n", count++); printf (" status ....: %s\n", gpgme_strerror (recp->status)); @@ -82,6 +82,7 @@ show_usage (int ex) " --export-session-key show the session key\n" " --override-session-key STRING use STRING as session key\n" " --request-origin STRING use STRING as request origin\n" + " --no-symkey-cache disable the use of that cache\n" " --unwrap remove only the encryption layer\n" , stderr); exit (ex); @@ -104,6 +105,7 @@ main (int argc, char **argv) int export_session_key = 0; const char *override_session_key = NULL; const char *request_origin = NULL; + int no_symkey_cache = 0; int raw_output = 0; if (argc) @@ -160,6 +162,11 @@ main (int argc, char **argv) request_origin = *argv; argc--; argv++; } + else if (!strcmp (*argv, "--no-symkey-cache")) + { + no_symkey_cache = 1; + argc--; argv++; + } else if (!strcmp (*argv, "--unwrap")) { flags |= GPGME_DECRYPT_UNWRAP; @@ -226,6 +233,17 @@ main (int argc, char **argv) } } + if (no_symkey_cache) + { + err = gpgme_set_ctx_flag (ctx, "no-symkey-cache", "1"); + if (err) + { + fprintf (stderr, PGM ": error setting no-symkey-cache: %s\n", + gpgme_strerror (err)); + exit (1); + } + } + err = gpgme_data_new_from_stream (&in, fp_in); if (err) { diff --git a/tests/run-encrypt.c b/tests/run-encrypt.c index e949d760..51e2d60f 100644 --- a/tests/run-encrypt.c +++ b/tests/run-encrypt.c @@ -80,17 +80,18 @@ show_usage (int ex) { fputs ("usage: " PGM " [options] FILE\n\n" "Options:\n" - " --verbose run in verbose mode\n" - " --status print status lines from the backend\n" - " --progress print progress info\n" - " --openpgp use the OpenPGP protocol (default)\n" - " --cms use the CMS protocol\n" - " --uiserver use the UI server\n" - " --loopback use a loopback pinentry\n" - " --key NAME encrypt to key NAME\n" - " --throw-keyids use this option\n" - " --wrap assume input is valid OpenPGP message\n" - " --symmetric encrypt symmetric (OpenPGP only)\n" + " --verbose run in verbose mode\n" + " --status print status lines from the backend\n" + " --progress print progress info\n" + " --openpgp use the OpenPGP protocol (default)\n" + " --cms use the CMS protocol\n" + " --uiserver use the UI server\n" + " --loopback use a loopback pinentry\n" + " --key NAME encrypt to key NAME\n" + " --throw-keyids use this option\n" + " --no-symkey-cache disable the use of that cache\n" + " --wrap assume input is valid OpenPGP message\n" + " --symmetric encrypt symmetric (OpenPGP only)\n" , stderr); exit (ex); } @@ -115,6 +116,7 @@ main (int argc, char **argv) int i; gpgme_encrypt_flags_t flags = GPGME_ENCRYPT_ALWAYS_TRUST; gpgme_off_t offset; + int no_symkey_cache = 0; if (argc) { argc--; argv++; } @@ -192,6 +194,11 @@ main (int argc, char **argv) flags |= GPGME_ENCRYPT_SYMMETRIC; argc--; argv++; } + else if (!strcmp (*argv, "--no-symkey-cache")) + { + no_symkey_cache = 1; + argc--; argv++; + } else if (!strncmp (*argv, "--", 2)) show_usage (1); @@ -227,6 +234,16 @@ main (int argc, char **argv) gpgme_set_pinentry_mode (ctx, GPGME_PINENTRY_MODE_LOOPBACK); gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL); } + if (no_symkey_cache) + { + err = gpgme_set_ctx_flag (ctx, "no-symkey-cache", "1"); + if (err) + { + fprintf (stderr, PGM ": error setting no-symkey-cache: %s\n", + gpgme_strerror (err)); + exit (1); + } + } for (i=0; i < keycount; i++) {