From 419adf41afa40e5b34f646f2cb16d8aebda20048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20Kl=C3=B6cker?= Date: Mon, 23 Jan 2023 12:17:22 +0100 Subject: [PATCH] core: Allow setting the base directory when creating an archive * src/engine-gpg.c (gpg_encrypt, gpg_encrypt_sign, gpg_sign): Pass file name set in data with --directory option to gpgtar. * tests/run-encrypt.c (show_usage): New option --directory. (main): Parse new option. Set file name of input data to option value. * tests/run-sign.c (show_usage): New option --directory. (main): Parse new option. Set file name of input data to option value. -- GnuPG-bug-id: 6342 --- doc/gpgme.texi | 11 +++++++++-- src/engine-gpg.c | 46 +++++++++++++++++++++++++++++---------------- tests/run-encrypt.c | 16 ++++++++++++++++ tests/run-sign.c | 16 ++++++++++++++++ 4 files changed, 71 insertions(+), 18 deletions(-) diff --git a/doc/gpgme.texi b/doc/gpgme.texi index 8b6106af..b8b90bb1 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -2199,6 +2199,11 @@ associated with the data object. The file name will be stored in the output when encrypting or signing the data and will be returned to the user when decrypting or verifying the output data. +If a signed or encrypted archive is created, then the file name will be +interpreted as the base directory for the relative paths of the files and +directories to put into the archive. This corresponds to the --directory +option of gpgtar. + The function returns the error code @code{GPG_ERR_INV_VALUE} if @var{dh} is not a valid pointer and @code{GPG_ERR_ENOMEM} if not enough memory is available. @@ -6260,7 +6265,8 @@ If signature mode @code(GPGME_SIG_MODE_ARCHIVE) is requested, then a signed archive is created from the files and directories given as NUL-separated list in the data object @var{plain} and returned in the data object @var{sig}. The paths of the files and directories have to -be given as paths relative to the current working directory. +be given as paths relative to the current working directory or relative +to the base directory set with @code{gpgme_data_set_file_name}. After the operation completed successfully, the result can be retrieved with @code{gpgme_op_sign_result}. @@ -6437,7 +6443,8 @@ If the flag @code(GPGME_ENCRYPT_ARCHIVE) is set, then an encrypted archive is created from the files and directories given as NUL-separated list in the data object @var{plain} and returned in the data object @var{cipher}. The paths of the files and directories have to -be given as paths relative to the current working directory. +be given as paths relative to the current working directory or relative +to the base directory set with @code{gpgme_data_set_file_name}. @var{recp} must be a @code{NULL}-terminated array of keys. The user must keep references for all keys during the whole duration of the diff --git a/src/engine-gpg.c b/src/engine-gpg.c index 16dfcc48..06eb3e18 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -2369,13 +2369,15 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring, err = add_arg (gpg, "-"); if (!err) err = add_data (gpg, ciph, 1, 1); - if (gpgme_data_get_file_name (plain)) - { - if (!err) - err = add_gpg_arg_with_value (gpg, "--set-filename=", gpgme_data_get_file_name (plain), 0); - } if (gpg->flags.use_gpgtar) { + const char *file_name = gpgme_data_get_file_name (plain); + if (!err && file_name) + { + err = add_arg (gpg, "--directory"); + if (!err) + err = add_arg (gpg, file_name); + } if (!err) err = add_arg (gpg, "--files-from"); if (!err) @@ -2390,6 +2392,9 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring, } else { + const char *file_name = gpgme_data_get_file_name (plain); + if (!err && file_name) + err = add_gpg_arg_with_value (gpg, "--set-filename=", file_name, 0); if (!err) err = add_input_size_hint (gpg, plain); if (!err) @@ -2476,13 +2481,15 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[], err = add_arg (gpg, "-"); if (!err) err = add_data (gpg, ciph, 1, 1); - if (gpgme_data_get_file_name (plain)) - { - if (!err) - err = add_gpg_arg_with_value (gpg, "--set-filename=", gpgme_data_get_file_name (plain), 0); - } if (gpg->flags.use_gpgtar) { + const char *file_name = gpgme_data_get_file_name (plain); + if (!err && file_name) + { + err = add_arg (gpg, "--directory"); + if (!err) + err = add_arg (gpg, file_name); + } if (!err) err = add_arg (gpg, "--files-from"); if (!err) @@ -2497,6 +2504,9 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[], } else { + const char *file_name = gpgme_data_get_file_name (plain); + if (!err && file_name) + err = add_gpg_arg_with_value (gpg, "--set-filename=", file_name, 0); if (!err) err = add_input_size_hint (gpg, plain); if (!err) @@ -3584,15 +3594,16 @@ gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out, if (!err) err = append_args_from_sig_notations (gpg, ctx, NOTATION_FLAG_SIG); - if (gpgme_data_get_file_name (in)) - { - if (!err) - err = add_gpg_arg_with_value (gpg, "--set-filename=", gpgme_data_get_file_name (in), 0); - } - /* Tell the gpg object about the data. */ if (gpg->flags.use_gpgtar) { + const char *file_name = gpgme_data_get_file_name (in); + if (!err && file_name) + { + err = add_arg (gpg, "--directory"); + if (!err) + err = add_arg (gpg, file_name); + } if (!err) err = add_arg (gpg, "--files-from"); if (!err) @@ -3607,6 +3618,9 @@ gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out, } else { + const char *file_name = gpgme_data_get_file_name (in); + if (!err && file_name) + err = add_gpg_arg_with_value (gpg, "--set-filename=", file_name, 0); if (!err) err = add_input_size_hint (gpg, in); if (!err) diff --git a/tests/run-encrypt.c b/tests/run-encrypt.c index 82a2cead..2d1c6e9d 100644 --- a/tests/run-encrypt.c +++ b/tests/run-encrypt.c @@ -134,6 +134,7 @@ show_usage (int ex) " --wrap assume input is valid OpenPGP message\n" " --symmetric encrypt symmetric (OpenPGP only)\n" " --archive encrypt given file or directory into an archive\n" + " --directory DIR switch to directory DIR before encrypting into an archive\n" " --diagnostics print diagnostics\n" , stderr); exit (ex); @@ -157,6 +158,7 @@ main (int argc, char **argv) gpgme_key_t keys[10+1]; int keycount = 0; char *keystring = NULL; + const char *directory = NULL; int i; gpgme_encrypt_flags_t flags = GPGME_ENCRYPT_ALWAYS_TRUST; gpgme_off_t offset; @@ -266,6 +268,14 @@ main (int argc, char **argv) flags |= GPGME_ENCRYPT_ARCHIVE; argc--; argv++; } + else if (!strcmp (*argv, "--directory")) + { + argc--; argv++; + if (!argc) + show_usage (1); + directory = *argv; + argc--; argv++; + } else if (!strcmp (*argv, "--diagnostics")) { diagnostics = 1; @@ -319,6 +329,12 @@ main (int argc, char **argv) { const char *path = *argv; err = gpgme_data_new_from_mem (&in, path, strlen (path), 0); + fail_if_err (err); + if (directory) + { + err = gpgme_data_set_file_name (in, directory); + fail_if_err (err); + } } else { diff --git a/tests/run-sign.c b/tests/run-sign.c index 73a970d0..84d7c070 100644 --- a/tests/run-sign.c +++ b/tests/run-sign.c @@ -88,6 +88,7 @@ show_usage (int ex) " --include-key-block use this option with gpg\n" " --clear create a clear text signature\n" " --archive create a signed archive with the given file or directory\n" + " --directory DIR switch to directory DIR before creating the archive\n" " --diagnostics print diagnostics\n" , stderr); exit (ex); @@ -101,6 +102,7 @@ main (int argc, char **argv) gpgme_error_t err; gpgme_ctx_t ctx; const char *key_string = NULL; + const char *directory = NULL; gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP; gpgme_sig_mode_t sigmode = GPGME_SIG_MODE_NORMAL; gpgme_data_t in, out; @@ -186,6 +188,14 @@ main (int argc, char **argv) sigmode = GPGME_SIG_MODE_ARCHIVE; argc--; argv++; } + else if (!strcmp (*argv, "--directory")) + { + argc--; argv++; + if (!argc) + show_usage (1); + directory = *argv; + argc--; argv++; + } else if (!strcmp (*argv, "--diagnostics")) { diagnostics = 1; @@ -253,6 +263,12 @@ main (int argc, char **argv) { const char *path = *argv; err = gpgme_data_new_from_mem (&in, path, strlen (path), 0); + fail_if_err (err); + if (directory) + { + err = gpgme_data_set_file_name (in, directory); + fail_if_err (err); + } } else {