From d13c5bc244ce1daed285424d920171fc2bcd7290 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 19 Apr 2021 11:33:19 +0200 Subject: [PATCH] gpg,gpgsm: Move use-keyboxd to the new conf file common.conf * common/comopt.c, common/comopt.h: New. * common/Makefile.am: Add them. * g10/gpg.c: Include comopt.h. (main): Also parse common.conf. * sm/gpgsm.c: Include comopt.h. (main): Set a flag for the --no-logfile option. Parse common.conf. * tools/gpgconf-comp.c (known_options_gpg): Remove "use-keyboxd", add pseudo option "use_keyboxd". (known_pseudo_options_gpg): Add pseudo option "use_keyboxd". (known_options_gpgsm): Remove "use-keyboxd". * tests/openpgp/defs.scm (create-gpghome): Create common.conf. * doc/examples/common.conf: New. -- Note that --use-keybox still works but prints a warning. We will eventually remove this option becuase it was marked as an experimental feature anyway. It would be too confusing if gpg and gpgsm use different key storages. Further, other components (e.g. dirmngr or gpg-wks-client) which call gpg or gpgsm need to be aware that the keyboxd is used and pass that option on the command line. Now that common.conf is always read (even if --no-options is used) those tools will work instantly. --- common/Makefile.am | 1 + common/comopt.c | 131 ++++++++++++++++++++++++++++++++++++++ common/comopt.h | 50 +++++++++++++++ doc/Makefile.am | 1 + doc/examples/README | 2 + doc/examples/common.conf | 22 +++++++ doc/gpg.texi | 9 ++- doc/gpgsm.texi | 5 ++ g10/gpg.c | 31 +++++++++ po/POTFILES.in | 1 + sm/gpgsm.c | 34 +++++++++- tests/openpgp/Makefile.am | 2 +- tests/openpgp/defs.scm | 7 +- tools/gpgconf-comp.c | 10 +-- 14 files changed, 296 insertions(+), 10 deletions(-) create mode 100644 common/comopt.c create mode 100644 common/comopt.h create mode 100644 doc/examples/common.conf diff --git a/common/Makefile.am b/common/Makefile.am index 1d29ceeb0..62bc9c90c 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -98,6 +98,7 @@ common_sources = \ recsel.c recsel.h \ ksba-io-support.c ksba-io-support.h \ openpgp-fpr.c \ + comopt.c comopt.h \ compliance.c compliance.h \ pkscreening.c pkscreening.h diff --git a/common/comopt.c b/common/comopt.c new file mode 100644 index 000000000..764df57c6 --- /dev/null +++ b/common/comopt.c @@ -0,0 +1,131 @@ +/* comopt.c - Common options for GnUPG (common.conf) + * Copyright (C) 2021 g10 Code GmbH + * + * This file is part of GnuPG. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of either + * + * - the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * or + * + * - the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * or both in parallel, as here. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * SPDX-License-Identifier: (LGPL-3.0-or-later OR GPL-2.0-or-later) + */ + +#include +#include +#include +#include + +#include "util.h" +#include "i18n.h" +#include "comopt.h" + + +enum opt_values + { + aNull = 0, + + oLogFile = 500, + oUseKeyboxd, + oKeyboxdProgram, + + oNoop + }; + +static gpgrt_opt_t opts[] = { + ARGPARSE_s_s (oLogFile, "log-file", "@"), + ARGPARSE_s_n (oUseKeyboxd, "use-keyboxd", "@"), + ARGPARSE_s_s (oKeyboxdProgram, "keyboxd-program", "@"), + + ARGPARSE_end () +}; + + + +/* Parse the common options in the homedir and etc. This needs to be + * called after the gpgrt config directories are. MODULE_ID is one of + * the GNUPG_MODULE_NAME_ constants. If verbose is true info about + * the parsing is printed. Note that this function is not + * thread-safe. */ +gpg_error_t +parse_comopt (int module_id, int verbose) +{ + gpg_error_t err = 0; + gpgrt_argparse_t pargs; + int argc = 0; + char **argv = NULL; + + /* Reset all options in case we are called a second time. */ + xfree (comopt.logfile); + xfree (comopt.keyboxd_program); + memset (&comopt, 0, sizeof comopt); + + /* Start the parser. */ + pargs.argc = &argc; + pargs.argv = &argv; + pargs.flags = (ARGPARSE_FLAG_NOVERSION + | ARGPARSE_FLAG_SYS + | ARGPARSE_FLAG_USER + ); + while (gpgrt_argparser (&pargs, opts, "common" EXTSEP_S "conf" )) + { + switch (pargs.r_opt) + { + case ARGPARSE_CONFFILE: + if (verbose) + log_info (_("reading options from '%s'\n"), + pargs.r_type? pargs.r.ret_str: "[cmdline]"); + break; + + case oLogFile: + comopt.logfile = pargs.r.ret_str; + break; + + case oUseKeyboxd: + comopt.use_keyboxd = 1; + break; + + case oKeyboxdProgram: + comopt.keyboxd_program = pargs.r.ret_str; + break; + + default: + pargs.err = ARGPARSE_PRINT_WARNING; + err = gpg_error (GPG_ERR_GENERAL); + break; + } + } + + gpgrt_argparse (NULL, &pargs, NULL); /* Release internal state. */ + + if (comopt.logfile && !(!strncmp (comopt.logfile, "socket:", 7) + || !strncmp (comopt.logfile, "tcp:", 4)) ) + { + /* Letting all modules write to the same log file is not a good + * idea. Append the module name. */ + char *p; + + p = xstrconcat (comopt.logfile, "-", gnupg_module_name (module_id), NULL); + xfree (comopt.logfile); + comopt.logfile = p; + } + + return err; +} diff --git a/common/comopt.h b/common/comopt.h new file mode 100644 index 000000000..1cdf25fe7 --- /dev/null +++ b/common/comopt.h @@ -0,0 +1,50 @@ +/* comopt.h - Common options for GnuPG (common.conf) + * Copyright (C) 2021 g10 Code GmbH + * + * This file is part of GnuPG. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of either + * + * - the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * or + * + * - the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * or both in parallel, as here. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * SPDX-License-Identifier: (LGPL-3.0-or-later OR GPL-2.0-or-later) + */ + +#ifndef GNUPG_COMOPT_H +#define GNUPG_COMOPT_H + +#include "../common/util.h" + + +/* Common options for all GnuPG components. */ +EXTERN_UNLESS_MAIN_MODULE +struct +{ + char *logfile; /* Socket used by daemons for logging. */ + int use_keyboxd; /* Use the keyboxd as storage backend. */ + char *keyboxd_program; /* Use this as keyboxd program. */ +} comopt; + + +gpg_error_t parse_comopt (int module_id, int verbose); + + +#endif /*GNUPG_COMOPT_H*/ diff --git a/doc/Makefile.am b/doc/Makefile.am index b86066917..2483601fd 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -24,6 +24,7 @@ include $(top_srcdir)/am/cmacros.am examples = examples/README examples/scd-event examples/trustlist.txt \ examples/VS-NfD.prf examples/Automatic.prf \ examples/debug.prf examples/qualified.txt \ + examples/common.conf \ examples/systemd-user/README \ examples/systemd-user/dirmngr.service \ examples/systemd-user/dirmngr.socket \ diff --git a/doc/examples/README b/doc/examples/README index 4d6a5be87..67508c471 100644 --- a/doc/examples/README +++ b/doc/examples/README @@ -11,3 +11,5 @@ gpgconf.conf A sample configuration file for gpgconf. systemd-user Sample files for a Linux-only init system. qualified.txt Sample file for qualified.txt. + +common.conf Sample file for common options. diff --git a/doc/examples/common.conf b/doc/examples/common.conf new file mode 100644 index 000000000..786feae58 --- /dev/null +++ b/doc/examples/common.conf @@ -0,0 +1,22 @@ +# common.conf - common defaults for all components. +# +# This file may provide defaults as well as options which needs to be +# synchronized between components. As usual this file is read from +# the system wide config directory (e.g. /etc/gnupg/common.conf) as +# well as from the home directory (e.g. ~/.gnupg.common.conf). + + +# Uncomment to enable the use if the keybox daemon (keyboxd) by gpg +# and gpgsm. +#use-keyboxd + +# For testing ist is somethimes useful to use a different binary +# of keybox. This option can be used to speicify this. +#keyboxd-program /foo/bar/keyboxd + +# For the daemons (gpg-agent, scdaemon, dirmngr, keyboxd) it is often +# useful to define a shared logging destination. This is either the +# standard logging socket (socket://) or a tcp server (tcp://ip:port). +# If a file name is given the name of the component is internally +# appended. +#socket:// diff --git a/doc/gpg.texi b/doc/gpg.texi index 9f2a62d0e..16a4b5851 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2476,7 +2476,8 @@ opposite meaning. The options are: signatures. Defaults to yes. @item bulk-import - When used with --use-keyboxd do the import within a single + When used the keyboxd (option "use-keyboxd" in @file{common.conf}) + do the import within a single transaction. This is an experimental feature. @item import-minimal @@ -3753,6 +3754,12 @@ current home directory (@pxref{option --homedir}). name may be changed on the command line (@pxref{gpg-option --options}). You should backup this file. + @item common.conf + @efindex common.conf + This is an optional configuration file read by @command{@gpgname} on + startup. It may contain options pertaining to all components of + GnuPG. Its current main use is for the "use-keyboxd" option. + @end table Note that on larger installations, it is useful to put predefined files diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 50a2595ae..886521076 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -853,6 +853,11 @@ may not be entered and the option may not be abbreviated. This default name may be changed on the command line (@pxref{gpgsm-option --options}). You should backup this file. +@item common.conf +@efindex common.conf +This is an optional configuration file read by @command{gpgsm} on +startup. It may contain options pertaining to all components of +GnuPG. Its current main use is for the "use-keyboxd" option. @item policies.txt @efindex policies.txt diff --git a/g10/gpg.c b/g10/gpg.c index 4ca2dcfa9..3332525d8 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -66,6 +66,7 @@ #include "../common/mbox-util.h" #include "../common/shareddefs.h" #include "../common/compliance.h" +#include "../common/comopt.h" #if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__) #define MY_O_BINARY O_BINARY @@ -1961,6 +1962,8 @@ gpgconf_list (void) es_printf ("compliance_de_vs:%lu:%d:\n", GC_OPT_FLAG_DEFAULT, 0 /*gnupg_rng_is_compliant (CO_DE_VS)*/); + es_printf ("use_keyboxd:%lu:%d:\n", GC_OPT_FLAG_DEFAULT, opt.use_keyboxd); + } @@ -3713,6 +3716,34 @@ main (int argc, char **argv) g10_exit(2); } + /* Process common component options. */ + if (parse_comopt (GNUPG_MODULE_NAME_GPG, debug_argparser)) + { + write_status_failure ("option-parser", gpg_error(GPG_ERR_GENERAL)); + g10_exit(2); + } + + if (!logfile) + { + logfile = comopt.logfile; + comopt.logfile = NULL; + } + + if (opt.use_keyboxd) + log_info ("Note: Please move option \"%s\" to \"common.conf\"\n", + "use-keyboxd"); + opt.use_keyboxd = comopt.use_keyboxd; /* Override. */ + + if (opt.keyboxd_program) + log_info ("Note: Please move option \"%s\" to \"common.conf\"\n", + "keyboxd-program"); + if (!opt.keyboxd_program && comopt.keyboxd_program) + { + opt.keyboxd_program = comopt.keyboxd_program; + comopt.keyboxd_program = NULL; + } + + /* The command --gpgconf-list is pretty simple and may be called directly after the option parsing. */ if (cmd == aGPGConfList) diff --git a/po/POTFILES.in b/po/POTFILES.in index 61b6f2d0a..2658660e0 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -26,6 +26,7 @@ common/helpfile.c common/gettime.c common/ksba-io-support.c common/ttyio.c +common/comopt.c common/utf8conv.c common/dotlock.c diff --git a/sm/gpgsm.c b/sm/gpgsm.c index fd59fc7c7..e292aa160 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -1,7 +1,7 @@ /* gpgsm.c - GnuPG for S/MIME * Copyright (C) 2001-2020 Free Software Foundation, Inc. * Copyright (C) 2001-2019 Werner Koch - * Copyright (C) 2015-2020 g10 Code GmbH + * Copyright (C) 2015-2021 g10 Code GmbH * * This file is part of GnuPG. * @@ -47,6 +47,7 @@ #include "../common/asshelp.h" #include "../common/init.h" #include "../common/compliance.h" +#include "../common/comopt.h" #include "minip12.h" #ifndef O_BINARY @@ -1005,6 +1006,7 @@ main ( int argc, char **argv) estream_t htmlauditfp = NULL; struct assuan_malloc_hooks malloc_hooks; int pwfd = -1; + int no_logfile = 0; static const char *homedirvalue; static const char *changeuser; @@ -1354,7 +1356,7 @@ main ( int argc, char **argv) break; case oLogFile: logfile = pargs.r.ret_str; break; - case oNoLogFile: logfile = NULL; break; + case oNoLogFile: logfile = NULL; no_logfile = 1; break; case oAuditLog: auditlog = pargs.r.ret_str; break; case oHtmlAuditLog: htmlauditlog = pargs.r.ret_str; break; @@ -1613,6 +1615,34 @@ main ( int argc, char **argv) gpgsm_exit(2); } + /* Process common component options. */ + if (parse_comopt (GNUPG_MODULE_NAME_GPGSM, debug_argparser)) + { + gpgsm_status_with_error (&ctrl, STATUS_FAILURE, + "option-parser", gpg_error (GPG_ERR_GENERAL)); + gpgsm_exit(2); + } + + if (!logfile && !no_logfile) + { + logfile = comopt.logfile; + comopt.logfile = NULL; + } + + if (opt.use_keyboxd) + log_info ("Note: Please move option \"%s\" to \"common.conf\"\n", + "use-keyboxd"); + opt.use_keyboxd = comopt.use_keyboxd; /* Override. */ + + if (opt.keyboxd_program) + log_info ("Note: Please move option \"%s\" to \"common.conf\"\n", + "keyboxd-program"); + if (!opt.keyboxd_program && comopt.keyboxd_program) + { + opt.keyboxd_program = comopt.keyboxd_program; + comopt.keyboxd_program = NULL; + } + if (pwfd != -1) /* Read the passphrase now. */ read_passphrase_from_fd (pwfd); diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am index 984b63f0a..106e49cdf 100644 --- a/tests/openpgp/Makefile.am +++ b/tests/openpgp/Makefile.am @@ -272,7 +272,7 @@ CLEANFILES = prepared.stamp x y yy z out err $(data_files) \ plain-1 plain-2 plain-3 trustdb.gpg *.lock .\#lk* \ *.log gpg_dearmor gpg.conf gpg-agent.conf S.gpg-agent \ pubring.gpg pubring.gpg~ pubring.kbx pubring.kbx~ \ - secring.gpg pubring.pkr secring.skr \ + common.conf secring.gpg pubring.pkr secring.skr \ gnupg-test.stop random_seed gpg-agent.log tofu.db \ passphrases sshcontrol S.gpg-agent.ssh report.xml diff --git a/tests/openpgp/defs.scm b/tests/openpgp/defs.scm index d26d38303..768d479aa 100644 --- a/tests/openpgp/defs.scm +++ b/tests/openpgp/defs.scm @@ -335,6 +335,11 @@ (if (flag "--use-keyring" *args*) (create-file "pubring.gpg")) + (create-file "common.conf" + (if (flag "--use-keyboxd" *args*) + "use-keyboxd" "#use-keyboxd") + ) + (create-file "gpg.conf" ;;"log-file socket:///tmp/S.wklog" ;;"verbose" @@ -352,8 +357,6 @@ (string-append "agent-program " (tool 'gpg-agent) "|--debug-quick-random\n") - (if (flag "--use-keyboxd" *args*) - "use-keyboxd" "#use-keyboxd") ) (create-file "keyboxd.conf" ;;"log-file socket:///tmp/S.wklog" diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index ca15aa8e4..c3ee36ad1 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -420,12 +420,11 @@ static known_option_t known_options_gpg[] = { "completes-needed", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE }, { "marginals-needed", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE }, - { "use-keyboxd", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE }, - /* The next items are pseudo options which we read via --gpgconf-list. * The meta information is taken from the table below. */ { "default_pubkey_algo", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE }, { "compliance_de_vs", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE }, + { "use_keyboxd", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE }, { NULL } }; @@ -436,6 +435,11 @@ static const char *known_pseudo_options_gpg[] = * result is valid for all components. * v-- ARGPARSE_TYPE_INT */ "compliance_de_vs:0:1:@:", + /* True is use_keyboxd is enabled. That option can be set in + * common.conf but is not direcly supported by gpgconf. Thus we + * only allow to read it out. + * v-- ARGPARSE_TYPE_INT */ + "use_keyboxd:0:1:@:", NULL }; @@ -466,8 +470,6 @@ static known_option_t known_options_gpgsm[] = { "cipher-algo", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED }, { "disable-trusted-cert-crl-check", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT }, - { "use-keyboxd", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE }, - /* Pseudo option follows. See also table below. */ { "default_pubkey_algo", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE },