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 },