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
This commit is contained in:
Ingo Klöcker 2023-01-23 12:17:22 +01:00
parent 4c872b6741
commit 419adf41af
No known key found for this signature in database
GPG Key ID: F5A5D1692277A1E9
4 changed files with 71 additions and 18 deletions

View File

@ -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 output when encrypting or signing the data and will be returned to the
user when decrypting or verifying the output data. 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 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 @var{dh} is not a valid pointer and @code{GPG_ERR_ENOMEM} if not
enough memory is available. 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 signed archive is created from the files and directories given as
NUL-separated list in the data object @var{plain} and returned in the 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 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 After the operation completed successfully, the result can be
retrieved with @code{gpgme_op_sign_result}. 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 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 list in the data object @var{plain} and returned in the data object
@var{cipher}. The paths of the files and directories have to @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 @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 must keep references for all keys during the whole duration of the

View File

@ -2369,13 +2369,15 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring,
err = add_arg (gpg, "-"); err = add_arg (gpg, "-");
if (!err) if (!err)
err = add_data (gpg, ciph, 1, 1); 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) 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) if (!err)
err = add_arg (gpg, "--files-from"); err = add_arg (gpg, "--files-from");
if (!err) if (!err)
@ -2390,6 +2392,9 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring,
} }
else 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) if (!err)
err = add_input_size_hint (gpg, plain); err = add_input_size_hint (gpg, plain);
if (!err) if (!err)
@ -2476,13 +2481,15 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
err = add_arg (gpg, "-"); err = add_arg (gpg, "-");
if (!err) if (!err)
err = add_data (gpg, ciph, 1, 1); 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) 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) if (!err)
err = add_arg (gpg, "--files-from"); err = add_arg (gpg, "--files-from");
if (!err) if (!err)
@ -2497,6 +2504,9 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
} }
else 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) if (!err)
err = add_input_size_hint (gpg, plain); err = add_input_size_hint (gpg, plain);
if (!err) if (!err)
@ -3584,15 +3594,16 @@ gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
if (!err) if (!err)
err = append_args_from_sig_notations (gpg, ctx, NOTATION_FLAG_SIG); 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. */ /* Tell the gpg object about the data. */
if (gpg->flags.use_gpgtar) 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) if (!err)
err = add_arg (gpg, "--files-from"); err = add_arg (gpg, "--files-from");
if (!err) if (!err)
@ -3607,6 +3618,9 @@ gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
} }
else 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) if (!err)
err = add_input_size_hint (gpg, in); err = add_input_size_hint (gpg, in);
if (!err) if (!err)

View File

@ -134,6 +134,7 @@ show_usage (int ex)
" --wrap assume input is valid OpenPGP message\n" " --wrap assume input is valid OpenPGP message\n"
" --symmetric encrypt symmetric (OpenPGP only)\n" " --symmetric encrypt symmetric (OpenPGP only)\n"
" --archive encrypt given file or directory into an archive\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" " --diagnostics print diagnostics\n"
, stderr); , stderr);
exit (ex); exit (ex);
@ -157,6 +158,7 @@ main (int argc, char **argv)
gpgme_key_t keys[10+1]; gpgme_key_t keys[10+1];
int keycount = 0; int keycount = 0;
char *keystring = NULL; char *keystring = NULL;
const char *directory = NULL;
int i; int i;
gpgme_encrypt_flags_t flags = GPGME_ENCRYPT_ALWAYS_TRUST; gpgme_encrypt_flags_t flags = GPGME_ENCRYPT_ALWAYS_TRUST;
gpgme_off_t offset; gpgme_off_t offset;
@ -266,6 +268,14 @@ main (int argc, char **argv)
flags |= GPGME_ENCRYPT_ARCHIVE; flags |= GPGME_ENCRYPT_ARCHIVE;
argc--; argv++; argc--; argv++;
} }
else if (!strcmp (*argv, "--directory"))
{
argc--; argv++;
if (!argc)
show_usage (1);
directory = *argv;
argc--; argv++;
}
else if (!strcmp (*argv, "--diagnostics")) else if (!strcmp (*argv, "--diagnostics"))
{ {
diagnostics = 1; diagnostics = 1;
@ -319,6 +329,12 @@ main (int argc, char **argv)
{ {
const char *path = *argv; const char *path = *argv;
err = gpgme_data_new_from_mem (&in, path, strlen (path), 0); 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 else
{ {

View File

@ -88,6 +88,7 @@ show_usage (int ex)
" --include-key-block use this option with gpg\n" " --include-key-block use this option with gpg\n"
" --clear create a clear text signature\n" " --clear create a clear text signature\n"
" --archive create a signed archive with the given file or directory\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" " --diagnostics print diagnostics\n"
, stderr); , stderr);
exit (ex); exit (ex);
@ -101,6 +102,7 @@ main (int argc, char **argv)
gpgme_error_t err; gpgme_error_t err;
gpgme_ctx_t ctx; gpgme_ctx_t ctx;
const char *key_string = NULL; const char *key_string = NULL;
const char *directory = NULL;
gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP; gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
gpgme_sig_mode_t sigmode = GPGME_SIG_MODE_NORMAL; gpgme_sig_mode_t sigmode = GPGME_SIG_MODE_NORMAL;
gpgme_data_t in, out; gpgme_data_t in, out;
@ -186,6 +188,14 @@ main (int argc, char **argv)
sigmode = GPGME_SIG_MODE_ARCHIVE; sigmode = GPGME_SIG_MODE_ARCHIVE;
argc--; argv++; argc--; argv++;
} }
else if (!strcmp (*argv, "--directory"))
{
argc--; argv++;
if (!argc)
show_usage (1);
directory = *argv;
argc--; argv++;
}
else if (!strcmp (*argv, "--diagnostics")) else if (!strcmp (*argv, "--diagnostics"))
{ {
diagnostics = 1; diagnostics = 1;
@ -253,6 +263,12 @@ main (int argc, char **argv)
{ {
const char *path = *argv; const char *path = *argv;
err = gpgme_data_new_from_mem (&in, path, strlen (path), 0); 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 else
{ {