1 /* gpgconf-comp.c - Configuration utility for GnuPG.
2 * Copyright (C) 2004, 2007-2011 Free Software Foundation, Inc.
3 * Copyright (C) 2016 Werner Koch
5 * This file is part of GnuPG.
7 * GnuPG is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * GnuPG is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GnuPG; if not, see <https://www.gnu.org/licenses/>.
29 #include <sys/types.h>
38 #ifdef HAVE_W32_SYSTEM
39 # define WIN32_LEAN_AND_MEAN 1
46 /* For log_logv(), asctimestamp(), gnupg_get_time (). */
47 #include "../common/util.h"
48 #include "../common/i18n.h"
49 #include "../common/exechelp.h"
50 #include "../common/sysutils.h"
52 #include "../common/gc-opt-flags.h"
55 /* There is a problem with gpg 1.4 under Windows: --gpgconf-list
56 returns a plain filename without escaping. As long as we have not
57 fixed that we need to use gpg2. */
58 #if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
59 #define GPGNAME "gpg2"
61 #define GPGNAME GPG_NAME
66 Components: Add more components and their options.
67 Robustness: Do more validation. Call programs to do validation for us.
68 Add options to change backend binary path.
69 Extract binary path for some backends from gpgsm/gpg config.
73 #if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ))
74 void gc_error (int status, int errnum, const char *fmt, ...) \
75 __attribute__ ((format (printf, 3, 4)));
78 /* Output a diagnostic message. If ERRNUM is not 0, then the output
79 is followed by a colon, a white space, and the error string for the
80 error number ERRNUM. In any case the output is finished by a
81 newline. The message is prepended by the program name, a colon,
82 and a whitespace. The output may be further formatted or
83 redirected by the jnlib logging facility. */
85 gc_error (int status, int errnum, const char *fmt, ...)
89 va_start (arg_ptr, fmt);
90 log_logv (GPGRT_LOG_ERROR, fmt, arg_ptr);
94 log_printf (": %s\n", strerror (errnum));
101 log_printf ("fatal error (exit status %i)\n", status);
107 /* Forward declaration. */
108 static void gpg_agent_runtime_change (int killflag);
109 static void scdaemon_runtime_change (int killflag);
110 static void dirmngr_runtime_change (int killflag);
112 /* Backend configuration. Backends are used to decide how the default
113 and current value of an option can be determined, and how the
114 option can be changed. To every option in every component belongs
115 exactly one backend that controls and determines the option. Some
116 backends are programs from the GPG system. Others might be
117 implemented by GPGConf itself. If you change this enum, don't
118 forget to update GC_BACKEND below. */
121 /* Any backend, used for find_option (). */
124 /* The Gnu Privacy Guard. */
127 /* The Gnu Privacy Guard for S/MIME. */
131 GC_BACKEND_GPG_AGENT,
133 /* The GnuPG SCDaemon. */
136 /* The GnuPG directory manager. */
139 /* The LDAP server list file for the director manager. */
140 GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST,
142 /* The Pinentry (not a part of GnuPG, proper). */
145 /* The number of the above entries. */
150 /* To be able to implement generic algorithms for the various
151 backends, we collect all information about them in this struct. */
154 /* The name of the backend. */
157 /* The name of the program that acts as the backend. Some backends
158 don't have an associated program, but are implemented directly by
159 GPGConf. In this case, PROGRAM is NULL. */
162 /* The module name (GNUPG_MODULE_NAME_foo) as defined by
163 ../common/util.h. This value is used to get the actual installed
164 path of the program. 0 is used if no backend program is
168 /* The runtime change callback. If KILLFLAG is true the component
169 is killed and not just reloaded. */
170 void (*runtime_change) (int killflag);
172 /* The option name for the configuration filename of this backend.
173 This must be an absolute filename. It can be an option from a
174 different backend (but then ordering of the options might
175 matter). Note: This must be unique among all components. */
176 const char *option_config_filename;
178 /* If this is a file backend rather than a program backend, then
179 this is the name of the option associated with the file. */
180 const char *option_name;
181 } gc_backend[GC_BACKEND_NR] =
183 { NULL }, /* GC_BACKEND_ANY dummy entry. */
184 { GPG_DISP_NAME, GPGNAME, GNUPG_MODULE_NAME_GPG,
185 NULL, GPGCONF_NAME "-" GPG_NAME ".conf" },
186 { GPGSM_DISP_NAME, GPGSM_NAME, GNUPG_MODULE_NAME_GPGSM,
187 NULL, GPGCONF_NAME "-" GPGSM_NAME ".conf" },
188 { GPG_AGENT_DISP_NAME, GPG_AGENT_NAME, GNUPG_MODULE_NAME_AGENT,
189 gpg_agent_runtime_change, GPGCONF_NAME"-" GPG_AGENT_NAME ".conf" },
190 { SCDAEMON_DISP_NAME, SCDAEMON_NAME, GNUPG_MODULE_NAME_SCDAEMON,
191 scdaemon_runtime_change, GPGCONF_NAME"-" SCDAEMON_NAME ".conf" },
192 { DIRMNGR_DISP_NAME, DIRMNGR_NAME, GNUPG_MODULE_NAME_DIRMNGR,
193 dirmngr_runtime_change, GPGCONF_NAME "-" DIRMNGR_NAME ".conf" },
194 { DIRMNGR_DISP_NAME " LDAP Server List", NULL, 0,
195 NULL, "ldapserverlist-file", "LDAP Server" },
196 { "Pinentry", "pinentry", GNUPG_MODULE_NAME_PINENTRY,
197 NULL, GPGCONF_NAME "-pinentry.conf" },
201 /* Option configuration. */
203 /* An option might take an argument, or not. Argument types can be
204 basic or complex. Basic types are generic and easy to validate.
205 Complex types provide more specific information about the intended
206 use, but can be difficult to validate. If you add to this enum,
207 don't forget to update GC_ARG_TYPE below. YOU MUST NOT CHANGE THE
208 NUMBERS OF THE EXISTING ENTRIES, AS THEY ARE PART OF THE EXTERNAL
212 /* Basic argument types. */
215 GC_ARG_TYPE_NONE = 0,
217 /* A String argument. */
218 GC_ARG_TYPE_STRING = 1,
220 /* A signed integer argument. */
221 GC_ARG_TYPE_INT32 = 2,
223 /* An unsigned integer argument. */
224 GC_ARG_TYPE_UINT32 = 3,
226 /* ADD NEW BASIC TYPE ENTRIES HERE. */
228 /* Complex argument types. */
230 /* A complete filename. */
231 GC_ARG_TYPE_FILENAME = 32,
233 /* An LDAP server in the format
234 HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN. */
235 GC_ARG_TYPE_LDAP_SERVER = 33,
237 /* A 40 character fingerprint. */
238 GC_ARG_TYPE_KEY_FPR = 34,
240 /* A user ID or key ID or fingerprint for a certificate. */
241 GC_ARG_TYPE_PUB_KEY = 35,
243 /* A user ID or key ID or fingerprint for a certificate with a key. */
244 GC_ARG_TYPE_SEC_KEY = 36,
246 /* A alias list made up of a key, an equal sign and a space
247 separated list of values. */
248 GC_ARG_TYPE_ALIAS_LIST = 37,
250 /* ADD NEW COMPLEX TYPE ENTRIES HERE. */
252 /* The number of the above entries. */
257 /* For every argument, we record some information about it in the
261 /* For every argument type exists a basic argument type that can be
262 used as a fallback for input and validation purposes. */
263 gc_arg_type_t fallback;
265 /* Human-readable name of the type. */
267 } gc_arg_type[GC_ARG_TYPE_NR] =
269 /* The basic argument types have their own types as fallback. */
270 { GC_ARG_TYPE_NONE, "none" },
271 { GC_ARG_TYPE_STRING, "string" },
272 { GC_ARG_TYPE_INT32, "int32" },
273 { GC_ARG_TYPE_UINT32, "uint32" },
275 /* Reserved basic type entries for future extension. */
276 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
277 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
278 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
279 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
280 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
281 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
282 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
283 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
284 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
285 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
286 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
287 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
288 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
289 { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
291 /* The complex argument types have a basic type as fallback. */
292 { GC_ARG_TYPE_STRING, "filename" },
293 { GC_ARG_TYPE_STRING, "ldap server" },
294 { GC_ARG_TYPE_STRING, "key fpr" },
295 { GC_ARG_TYPE_STRING, "pub key" },
296 { GC_ARG_TYPE_STRING, "sec key" },
297 { GC_ARG_TYPE_STRING, "alias list" },
301 /* Every option has an associated expert level, than can be used to
302 hide advanced and expert options from beginners. If you add to
303 this list, don't forget to update GC_LEVEL below. YOU MUST NOT
304 CHANGE THE NUMBERS OF THE EXISTING ENTRIES, AS THEY ARE PART OF THE
305 EXTERNAL INTERFACE. */
308 /* The basic options should always be displayed. */
311 /* The advanced options may be hidden from beginners. */
314 /* The expert options should only be displayed to experts. */
317 /* The invisible options should normally never be displayed. */
320 /* The internal options are never exported, they mark options that
321 are recorded for internal use only. */
324 /* ADD NEW ENTRIES HERE. */
326 /* The number of the above entries. */
330 /* A description for each expert level. */
344 /* Option flags. The flags which are used by the backends are defined
345 by gc-opt-flags.h, included above.
347 YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING FLAGS, AS THEY ARE
348 PART OF THE EXTERNAL INTERFACE. */
350 /* Some entries in the option list are not options, but mark the
351 beginning of a new group of options. These entries have the GROUP
353 #define GC_OPT_FLAG_GROUP (1UL << 0)
354 /* The ARG_OPT flag for an option indicates that the argument is
355 optional. This is never set for GC_ARG_TYPE_NONE options. */
356 #define GC_OPT_FLAG_ARG_OPT (1UL << 1)
357 /* The LIST flag for an option indicates that the option can occur
358 several times. A comma separated list of arguments is used as the
360 #define GC_OPT_FLAG_LIST (1UL << 2)
363 /* A human-readable description for each flag. */
380 /* To each option, or group marker, the information in the GC_OPTION
381 struct is provided. If you change this, don't forget to update the
382 option list of each component. */
385 /* If this is NULL, then this is a terminator in an array of unknown
386 length. Otherwise, if this entry is a group marker (see FLAGS),
387 then this is the name of the group described by this entry.
388 Otherwise it is the name of the option described by this
389 entry. The name must not contain a colon. */
392 /* The option flags. If the GROUP flag is set, then this entry is a
393 group marker, not an option, and only the fields LEVEL,
394 DESC_DOMAIN and DESC are valid. In all other cases, this entry
395 describes a new option and all fields are valid. */
398 /* The expert level. This field is valid for options and groups. A
399 group has the expert level of the lowest-level option in the
401 gc_expert_level_t level;
403 /* A gettext domain in which the following description can be found.
404 If this is NULL, then DESC is not translated. Valid for groups
407 Note that we try to keep the description of groups within the
410 IMPORTANT: If you add a new domain please make sure to add a code
411 set switching call to the function my_dgettext further below. */
412 const char *desc_domain;
414 /* A gettext description for this group or option. If it starts
415 with a '|', then the string up to the next '|' describes the
416 argument, and the description follows the second '|'.
418 In general enclosing these description in N_() is not required
419 because the description should be identical to the one in the
420 help menu of the respective program. */
423 /* The following fields are only valid for options. */
425 /* The type of the option argument. */
426 gc_arg_type_t arg_type;
428 /* The backend that implements this option. */
429 gc_backend_t backend;
431 /* The following fields are set to NULL at startup (because all
432 option's are declared as static variables). They are at the end
433 of the list so that they can be omitted from the option
436 /* This is true if the option is supported by this version of the
440 /* The default value for this option. This is NULL if the option is
441 not present in the backend, the empty string if no default is
442 available, and otherwise a quoted string. */
445 /* The default argument is only valid if the "optional arg" flag is
446 set, and specifies the default argument (value) that is used if
447 the argument is omitted. */
450 /* The current value of this option. */
453 /* The new flags for this option. The only defined flag is actually
454 GC_OPT_FLAG_DEFAULT, and it means that the option should be
455 deleted. In this case, NEW_VALUE is NULL. */
456 unsigned long new_flags;
458 /* The new value of this option. */
461 typedef struct gc_option gc_option_t;
463 /* Use this macro to terminate an option list. */
464 #define GC_OPTION_NULL { NULL }
467 #ifndef BUILD_WITH_AGENT
468 #define gc_options_gpg_agent NULL
470 /* The options of the GC_COMPONENT_GPG_AGENT component. */
471 static gc_option_t gc_options_gpg_agent[] =
473 /* The configuration file to which we write the changes. */
474 { GPGCONF_NAME"-" GPG_AGENT_NAME ".conf",
475 GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
476 NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG_AGENT },
479 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
480 "gnupg", N_("Options controlling the diagnostic output") },
481 { "verbose", GC_OPT_FLAG_LIST|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
483 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
484 { "quiet", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
485 "gnupg", "be somewhat more quiet",
486 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
487 { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
489 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
492 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
493 "gnupg", N_("Options controlling the configuration") },
494 { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
495 "gnupg", "|FILE|read options from FILE",
496 GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG_AGENT },
497 { "disable-scdaemon", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
498 "gnupg", "do not use the SCdaemon",
499 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
500 { "enable-ssh-support", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
501 "gnupg", "enable ssh support",
502 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
503 { "ssh-fingerprint-digest",
504 GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT,
505 "gnupg", "|ALGO|use ALGO to show ssh fingerprints",
506 GC_ARG_TYPE_STRING, GC_BACKEND_GPG_AGENT },
507 { "enable-putty-support", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
508 "gnupg", "enable putty support",
509 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
510 { "enable-extended-key-format", GC_OPT_FLAG_RUNTIME, GC_LEVEL_INVISIBLE,
512 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
515 GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
516 "gnupg", N_("Options useful for debugging") },
517 { "debug-level", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED,
518 "gnupg", "|LEVEL|set the debugging level to LEVEL",
519 GC_ARG_TYPE_STRING, GC_BACKEND_GPG_AGENT },
520 { "log-file", GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED,
521 "gnupg", N_("|FILE|write server mode logs to FILE"),
522 GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG_AGENT },
523 { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
525 GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
528 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
529 "gnupg", N_("Options controlling the security") },
530 { "default-cache-ttl", GC_OPT_FLAG_RUNTIME,
531 GC_LEVEL_BASIC, "gnupg",
532 "|N|expire cached PINs after N seconds",
533 GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
534 { "default-cache-ttl-ssh", GC_OPT_FLAG_RUNTIME,
535 GC_LEVEL_ADVANCED, "gnupg",
536 N_("|N|expire SSH keys after N seconds"),
537 GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
538 { "max-cache-ttl", GC_OPT_FLAG_RUNTIME,
539 GC_LEVEL_EXPERT, "gnupg",
540 N_("|N|set maximum PIN cache lifetime to N seconds"),
541 GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
542 { "max-cache-ttl-ssh", GC_OPT_FLAG_RUNTIME,
543 GC_LEVEL_EXPERT, "gnupg",
544 N_("|N|set maximum SSH key lifetime to N seconds"),
545 GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
546 { "ignore-cache-for-signing", GC_OPT_FLAG_RUNTIME,
547 GC_LEVEL_BASIC, "gnupg", "do not use the PIN cache when signing",
548 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
549 { "allow-emacs-pinentry", GC_OPT_FLAG_RUNTIME,
551 "gnupg", "allow passphrase to be prompted through Emacs",
552 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
553 { "no-allow-external-cache", GC_OPT_FLAG_RUNTIME,
554 GC_LEVEL_BASIC, "gnupg", "disallow the use of an external password cache",
555 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
556 { "no-allow-mark-trusted", GC_OPT_FLAG_RUNTIME,
557 GC_LEVEL_ADVANCED, "gnupg", "disallow clients to mark keys as \"trusted\"",
558 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
559 { "no-allow-loopback-pinentry", GC_OPT_FLAG_RUNTIME,
560 GC_LEVEL_EXPERT, "gnupg", "disallow caller to override the pinentry",
561 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
562 { "no-grab", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT,
563 "gnupg", "do not grab keyboard and mouse",
564 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
566 { "Passphrase policy",
567 GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
568 "gnupg", N_("Options enforcing a passphrase policy") },
569 { "enforce-passphrase-constraints", GC_OPT_FLAG_RUNTIME,
570 GC_LEVEL_EXPERT, "gnupg",
571 N_("do not allow bypassing the passphrase policy"),
572 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
573 { "min-passphrase-len", GC_OPT_FLAG_RUNTIME,
574 GC_LEVEL_ADVANCED, "gnupg",
575 N_("|N|set minimal required length for new passphrases to N"),
576 GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
577 { "min-passphrase-nonalpha", GC_OPT_FLAG_RUNTIME,
578 GC_LEVEL_EXPERT, "gnupg",
579 N_("|N|require at least N non-alpha characters for a new passphrase"),
580 GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
581 { "check-passphrase-pattern", GC_OPT_FLAG_RUNTIME,
583 "gnupg", N_("|FILE|check new passphrases against pattern in FILE"),
584 GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG_AGENT },
585 { "max-passphrase-days", GC_OPT_FLAG_RUNTIME,
586 GC_LEVEL_EXPERT, "gnupg",
587 N_("|N|expire the passphrase after N days"),
588 GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
589 { "enable-passphrase-history", GC_OPT_FLAG_RUNTIME,
590 GC_LEVEL_EXPERT, "gnupg",
591 N_("do not allow the reuse of old passphrases"),
592 GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
593 { "pinentry-timeout", GC_OPT_FLAG_RUNTIME,
594 GC_LEVEL_ADVANCED, "gnupg",
595 N_("|N|set the Pinentry timeout to N seconds"),
596 GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
600 #endif /*BUILD_WITH_AGENT*/
603 #ifndef BUILD_WITH_SCDAEMON
604 #define gc_options_scdaemon NULL
606 /* The options of the GC_COMPONENT_SCDAEMON component. */
607 static gc_option_t gc_options_scdaemon[] =
609 /* The configuration file to which we write the changes. */
610 { GPGCONF_NAME"-"SCDAEMON_NAME".conf",
611 GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
612 NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_SCDAEMON },
615 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
616 "gnupg", N_("Options controlling the diagnostic output") },
617 { "verbose", GC_OPT_FLAG_LIST|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
619 GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
620 { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
621 "gnupg", "be somewhat more quiet",
622 GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
623 { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
625 GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
628 GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
629 "gnupg", N_("Options controlling the configuration") },
630 { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
631 "gnupg", "|FILE|read options from FILE",
632 GC_ARG_TYPE_FILENAME, GC_BACKEND_SCDAEMON },
633 { "reader-port", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
634 "gnupg", "|N|connect to reader at port N",
635 GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON },
636 { "ctapi-driver", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED,
637 "gnupg", "|NAME|use NAME as ct-API driver",
638 GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON },
639 { "pcsc-driver", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED,
640 "gnupg", "|NAME|use NAME as PC/SC driver",
641 GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON },
642 { "disable-ccid", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT,
643 "gnupg", "do not use the internal CCID driver",
644 GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
645 { "disable-pinpad", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
646 "gnupg", "do not use a reader's pinpad",
647 GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
648 { "enable-pinpad-varlen",
649 GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
650 "gnupg", "use variable length input for pinpad",
651 GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
652 { "card-timeout", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
653 "gnupg", "|N|disconnect the card after N seconds of inactivity",
654 GC_ARG_TYPE_UINT32, GC_BACKEND_SCDAEMON },
657 GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
658 "gnupg", N_("Options useful for debugging") },
659 { "debug-level", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED,
660 "gnupg", "|LEVEL|set the debugging level to LEVEL",
661 GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON },
662 { "log-file", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED,
663 "gnupg", N_("|FILE|write a log to FILE"),
664 GC_ARG_TYPE_FILENAME, GC_BACKEND_SCDAEMON },
667 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
668 "gnupg", N_("Options controlling the security") },
669 { "deny-admin", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
670 "gnupg", "deny the use of admin card commands",
671 GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
676 #endif /*BUILD_WITH_SCDAEMON*/
678 #ifndef BUILD_WITH_GPG
679 #define gc_options_gpg NULL
681 /* The options of the GC_COMPONENT_GPG component. */
682 static gc_option_t gc_options_gpg[] =
684 /* The configuration file to which we write the changes. */
685 { GPGCONF_NAME"-"GPG_NAME".conf",
686 GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
687 NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG },
690 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
691 "gnupg", N_("Options controlling the diagnostic output") },
692 { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
694 GC_ARG_TYPE_NONE, GC_BACKEND_GPG },
695 { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
696 "gnupg", "be somewhat more quiet",
697 GC_ARG_TYPE_NONE, GC_BACKEND_GPG },
698 { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
700 GC_ARG_TYPE_NONE, GC_BACKEND_GPG },
703 GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
704 "gnupg", N_("Options controlling the configuration") },
705 { "default-key", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
706 "gnupg", N_("|NAME|use NAME as default secret key"),
707 GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
708 { "encrypt-to", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
709 "gnupg", N_("|NAME|encrypt to user ID NAME as well"),
710 GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
711 { "group", GC_OPT_FLAG_LIST, GC_LEVEL_ADVANCED,
712 "gnupg", N_("|SPEC|set up email aliases"),
713 GC_ARG_TYPE_ALIAS_LIST, GC_BACKEND_GPG },
714 { "options", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
716 GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG },
717 { "compliance", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
719 GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
720 { "default-new-key-algo", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
722 GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
723 { "default_pubkey_algo",
724 (GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_NO_CHANGE), GC_LEVEL_INVISIBLE,
726 GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
728 GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
730 GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
734 GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
735 "gnupg", N_("Options useful for debugging") },
736 { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
737 "gnupg", "|LEVEL|set the debugging level to LEVEL",
738 GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
739 { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
740 "gnupg", N_("|FILE|write server mode logs to FILE"),
741 GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG },
742 /* { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, */
744 /* GC_ARG_TYPE_UINT32, GC_BACKEND_GPG }, */
747 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
748 "gnupg", N_("Configuration for Keyservers") },
749 { "keyserver", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
750 "gnupg", N_("|URL|use keyserver at URL"), /* Deprecated - use dirmngr */
751 GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
752 { "allow-pka-lookup", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
753 "gnupg", N_("allow PKA lookups (DNS requests)"),
754 GC_ARG_TYPE_NONE, GC_BACKEND_GPG },
755 { "auto-key-locate", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
756 "gnupg", N_("|MECHANISMS|use MECHANISMS to locate keys by mail address"),
757 GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
758 { "auto-key-retrieve", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
759 NULL, NULL, GC_ARG_TYPE_NONE, GC_BACKEND_GPG },
764 #endif /*BUILD_WITH_GPG*/
767 #ifndef BUILD_WITH_GPGSM
768 #define gc_options_gpgsm NULL
770 /* The options of the GC_COMPONENT_GPGSM component. */
771 static gc_option_t gc_options_gpgsm[] =
773 /* The configuration file to which we write the changes. */
774 { GPGCONF_NAME"-"GPGSM_NAME".conf",
775 GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
776 NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_GPGSM },
779 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
780 "gnupg", N_("Options controlling the diagnostic output") },
781 { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
783 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
784 { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
785 "gnupg", "be somewhat more quiet",
786 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
787 { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
789 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
792 GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
793 "gnupg", N_("Options controlling the configuration") },
794 { "default-key", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
795 "gnupg", N_("|NAME|use NAME as default secret key"),
796 GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
797 { "encrypt-to", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
798 "gnupg", N_("|NAME|encrypt to user ID NAME as well"),
799 GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
800 { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
801 "gnupg", "|FILE|read options from FILE",
802 GC_ARG_TYPE_FILENAME, GC_BACKEND_GPGSM },
803 { "prefer-system-dirmngr", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
804 "gnupg", "use system's dirmngr if available",
805 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
806 { "disable-dirmngr", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
807 "gnupg", N_("disable all access to the dirmngr"),
808 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
809 { "p12-charset", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
810 "gnupg", N_("|NAME|use encoding NAME for PKCS#12 passphrases"),
811 GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
812 { "keyserver", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
813 "gnupg", N_("|SPEC|use this keyserver to lookup keys"),
814 GC_ARG_TYPE_LDAP_SERVER, GC_BACKEND_GPGSM },
815 { "default_pubkey_algo",
816 (GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_NO_CHANGE), GC_LEVEL_INVISIBLE,
818 GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
821 GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
822 "gnupg", N_("Options useful for debugging") },
823 { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
824 "gnupg", "|LEVEL|set the debugging level to LEVEL",
825 GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
826 { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
827 "gnupg", N_("|FILE|write server mode logs to FILE"),
828 GC_ARG_TYPE_FILENAME, GC_BACKEND_GPGSM },
829 { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
831 GC_ARG_TYPE_UINT32, GC_BACKEND_GPGSM },
834 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
835 "gnupg", N_("Options controlling the security") },
836 { "disable-crl-checks", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
837 "gnupg", "never consult a CRL",
838 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
839 { "enable-crl-checks", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
841 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
842 { "disable-trusted-cert-crl-check", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
843 "gnupg", N_("do not check CRLs for root certificates"),
844 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
845 { "enable-ocsp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
846 "gnupg", "check validity using OCSP",
847 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
848 { "include-certs", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
849 "gnupg", "|N|number of certificates to include",
850 GC_ARG_TYPE_INT32, GC_BACKEND_GPGSM },
851 { "disable-policy-checks", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
852 "gnupg", "do not check certificate policies",
853 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
854 { "auto-issuer-key-retrieve", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
855 "gnupg", "fetch missing issuer certificates",
856 GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
857 { "cipher-algo", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
858 "gnupg", "|NAME|use cipher algorithm NAME",
859 GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM },
863 #endif /*BUILD_WITH_GPGSM*/
866 #ifndef BUILD_WITH_DIRMNGR
867 #define gc_options_dirmngr NULL
869 /* The options of the GC_COMPONENT_DIRMNGR component. */
870 static gc_option_t gc_options_dirmngr[] =
872 /* The configuration file to which we write the changes. */
873 { GPGCONF_NAME"-"DIRMNGR_NAME".conf",
874 GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
875 NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_DIRMNGR },
878 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
879 "gnupg", N_("Options controlling the diagnostic output") },
880 { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
881 "dirmngr", "verbose",
882 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
883 { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
884 "dirmngr", "be somewhat more quiet",
885 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
886 { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
888 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
891 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
892 "gnupg", N_("Options controlling the format of the output") },
893 { "sh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
894 "dirmngr", "sh-style command output",
895 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
896 { "csh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
897 "dirmngr", "csh-style command output",
898 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
901 GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
902 "gnupg", N_("Options controlling the configuration") },
903 { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
904 "dirmngr", "|FILE|read options from FILE",
905 GC_ARG_TYPE_FILENAME, GC_BACKEND_DIRMNGR },
906 { "resolver-timeout", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
908 GC_ARG_TYPE_INT32, GC_BACKEND_DIRMNGR },
909 { "nameserver", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
911 GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
914 GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
915 "gnupg", N_("Options useful for debugging") },
916 { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED,
917 "dirmngr", "|LEVEL|set the debugging level to LEVEL",
918 GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
919 { "no-detach", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
920 "dirmngr", "do not detach from the console",
921 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
922 { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
923 "dirmngr", N_("|FILE|write server mode logs to FILE"),
924 GC_ARG_TYPE_FILENAME, GC_BACKEND_DIRMNGR },
925 { "debug-wait", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
927 GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
928 { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
930 GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
933 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
934 "gnupg", N_("Options controlling the interactivity and enforcement") },
935 { "batch", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
936 "dirmngr", "run without asking a user",
937 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
938 { "force", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
939 "dirmngr", "force loading of outdated CRLs",
940 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
941 { "allow-version-check", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
942 "dirmngr", "allow online software version check",
943 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
946 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
947 "gnupg", N_("Options controlling the use of Tor") },
948 { "use-tor", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
949 "dirmngr", "route all network traffic via TOR",
950 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
953 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
954 "gnupg", N_("Configuration for Keyservers") },
955 { "keyserver", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
956 "gnupg", N_("|URL|use keyserver at URL"),
957 GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
960 GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
961 "gnupg", N_("Configuration for HTTP servers") },
962 { "disable-http", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
963 "dirmngr", "inhibit the use of HTTP",
964 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
965 { "ignore-http-dp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
966 "dirmngr", "ignore HTTP CRL distribution points",
967 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
968 { "http-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
969 "dirmngr", "|URL|redirect all HTTP requests to URL",
970 GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
971 { "honor-http-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
972 "gnupg", N_("use system's HTTP proxy setting"),
973 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
976 GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
977 "gnupg", N_("Configuration of LDAP servers to use") },
978 { "disable-ldap", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
979 "dirmngr", "inhibit the use of LDAP",
980 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
981 { "ignore-ldap-dp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
982 "dirmngr", "ignore LDAP CRL distribution points",
983 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
984 { "ldap-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
985 "dirmngr", "|HOST|use HOST for LDAP queries",
986 GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
987 { "only-ldap-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
988 "dirmngr", "do not use fallback hosts with --ldap-proxy",
989 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
990 { "add-servers", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
991 "dirmngr", "add new servers discovered in CRL distribution points"
992 " to serverlist", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
993 { "ldaptimeout", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
994 "dirmngr", "|N|set LDAP timeout to N seconds",
995 GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
996 /* The following entry must not be removed, as it is required for
997 the GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST. */
998 { "ldapserverlist-file",
999 GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
1000 "dirmngr", "|FILE|read LDAP server list from FILE",
1001 GC_ARG_TYPE_FILENAME, GC_BACKEND_DIRMNGR },
1002 /* This entry must come after at least one entry for
1003 GC_BACKEND_DIRMNGR in this component, so that the entry for
1004 "ldapserverlist-file will be initialized before this one. */
1005 { "LDAP Server", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
1006 "gnupg", N_("LDAP server list"),
1007 GC_ARG_TYPE_LDAP_SERVER, GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST },
1008 { "max-replies", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
1009 "dirmngr", "|N|do not return more than N items in one query",
1010 GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR },
1013 GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
1014 "gnupg", N_("Configuration for OCSP") },
1015 { "allow-ocsp", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
1016 "dirmngr", "allow sending OCSP requests",
1017 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
1018 { "ignore-ocsp-service-url", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
1019 "dirmngr", "ignore certificate contained OCSP service URLs",
1020 GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
1021 { "ocsp-responder", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
1022 "dirmngr", "|URL|use OCSP responder at URL",
1023 GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
1024 { "ocsp-signer", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
1025 "dirmngr", "|FPR|OCSP response signed by FPR",
1026 GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
1031 #endif /*BUILD_WITH_DIRMNGR*/
1034 /* The options of the GC_COMPONENT_PINENTRY component. */
1035 static gc_option_t gc_options_pinentry[] =
1037 /* A dummy option to allow gc_component_list_components to find the
1038 pinentry backend. Needs to be a conf file. */
1039 { GPGCONF_NAME"-pinentry.conf",
1040 GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
1041 NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_PINENTRY },
1048 /* Component system. Each component is a set of options that can be
1049 configured at the same time. If you change this, don't forget to
1050 update GC_COMPONENT below. */
1053 /* The classic GPG for OpenPGP. */
1056 /* The GPG Agent. */
1057 GC_COMPONENT_GPG_AGENT,
1059 /* The Smardcard Daemon. */
1060 GC_COMPONENT_SCDAEMON,
1062 /* GPG for S/MIME. */
1065 /* The LDAP Directory Manager for CRLs. */
1066 GC_COMPONENT_DIRMNGR,
1068 /* The external Pinentry. */
1069 GC_COMPONENT_PINENTRY,
1071 /* The number of components. */
1076 /* The information associated with each component. */
1079 /* The name of this component. Must not contain a colon (':')
1083 /* The gettext domain for the description DESC. If this is NULL,
1084 then the description is not translated. */
1085 const char *desc_domain;
1087 /* The description for this domain. */
1090 /* The list of options for this component, terminated by
1092 gc_option_t *options;
1095 { "gpg", "gnupg", N_("OpenPGP"), gc_options_gpg },
1096 { "gpg-agent","gnupg", N_("Private Keys"), gc_options_gpg_agent },
1097 { "scdaemon", "gnupg", N_("Smartcards"), gc_options_scdaemon },
1098 { "gpgsm", "gnupg", N_("S/MIME"), gc_options_gpgsm },
1099 { "dirmngr", "gnupg", N_("Network"), gc_options_dirmngr },
1100 { "pinentry", "gnupg", N_("Passphrase Entry"), gc_options_pinentry }
1105 /* Structure used to collect error output of the backend programs. */
1106 struct error_line_s;
1107 typedef struct error_line_s *error_line_t;
1110 error_line_t next; /* Link to next item. */
1111 const char *fname; /* Name of the config file (points into BUFFER). */
1112 unsigned int lineno; /* Line number of the config file. */
1113 const char *errtext; /* Text of the error message (points into BUFFER). */
1114 char buffer[1]; /* Helper buffer. */
1120 /* Initialization and finalization. */
1123 gc_option_free (gc_option_t *o)
1125 if (o == NULL || o->name == NULL)
1129 gc_option_free (o + 1);
1133 gc_components_free (void)
1136 for (i = 0; i < DIM (gc_component); i++)
1137 gc_option_free (gc_component[i].options);
1141 gc_components_init (void)
1143 atexit (gc_components_free);
1148 /* Engine specific support. */
1150 gpg_agent_runtime_change (int killflag)
1152 gpg_error_t err = 0;
1153 const char *pgmname;
1154 const char *argv[5];
1155 pid_t pid = (pid_t)(-1);
1156 char *abs_homedir = NULL;
1159 pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
1160 if (!gnupg_default_homedir_p ())
1162 abs_homedir = make_absfilename_try (gnupg_homedir (), NULL);
1164 err = gpg_error_from_syserror ();
1166 argv[i++] = "--homedir";
1167 argv[i++] = abs_homedir;
1169 argv[i++] = "--no-autostart";
1170 argv[i++] = killflag? "KILLAGENT" : "RELOADAGENT";
1174 err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
1176 err = gnupg_wait_process (pgmname, pid, 1, NULL);
1178 gc_error (0, 0, "error running '%s %s': %s",
1179 pgmname, argv[1], gpg_strerror (err));
1180 gnupg_release_process (pid);
1181 xfree (abs_homedir);
1186 scdaemon_runtime_change (int killflag)
1188 gpg_error_t err = 0;
1189 const char *pgmname;
1190 const char *argv[9];
1191 pid_t pid = (pid_t)(-1);
1192 char *abs_homedir = NULL;
1195 (void)killflag; /* For scdaemon kill and reload are synonyms. */
1197 /* We use "GETINFO app_running" to see whether the agent is already
1198 running and kill it only in this case. This avoids an explicit
1199 starting of the agent in case it is not yet running. There is
1200 obviously a race condition but that should not harm too much. */
1202 pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
1203 if (!gnupg_default_homedir_p ())
1205 abs_homedir = make_absfilename_try (gnupg_homedir (), NULL);
1207 err = gpg_error_from_syserror ();
1209 argv[i++] = "--homedir";
1210 argv[i++] = abs_homedir;
1213 argv[i++] = "--no-autostart";
1214 argv[i++] = "GETINFO scd_running";
1215 argv[i++] = "/if ${! $?}";
1216 argv[i++] = "scd killscd";
1221 err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
1223 err = gnupg_wait_process (pgmname, pid, 1, NULL);
1225 gc_error (0, 0, "error running '%s %s': %s",
1226 pgmname, argv[4], gpg_strerror (err));
1227 gnupg_release_process (pid);
1228 xfree (abs_homedir);
1233 dirmngr_runtime_change (int killflag)
1235 gpg_error_t err = 0;
1236 const char *pgmname;
1237 const char *argv[6];
1238 pid_t pid = (pid_t)(-1);
1239 char *abs_homedir = NULL;
1241 pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
1242 argv[0] = "--no-autostart";
1243 argv[1] = "--dirmngr";
1244 argv[2] = killflag? "KILLDIRMNGR" : "RELOADDIRMNGR";
1245 if (gnupg_default_homedir_p ())
1249 abs_homedir = make_absfilename_try (gnupg_homedir (), NULL);
1251 err = gpg_error_from_syserror ();
1253 argv[3] = "--homedir";
1254 argv[4] = abs_homedir;
1259 err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
1261 err = gnupg_wait_process (pgmname, pid, 1, NULL);
1263 gc_error (0, 0, "error running '%s %s': %s",
1264 pgmname, argv[2], gpg_strerror (err));
1265 gnupg_release_process (pid);
1266 xfree (abs_homedir);
1270 /* Launch the gpg-agent or the dirmngr if not already running. */
1272 gc_component_launch (int component)
1275 const char *pgmname;
1276 const char *argv[3];
1282 err = gc_component_launch (GC_COMPONENT_GPG_AGENT);
1284 err = gc_component_launch (GC_COMPONENT_DIRMNGR);
1288 if (!(component == GC_COMPONENT_GPG_AGENT
1289 || component == GC_COMPONENT_DIRMNGR))
1291 es_fputs (_("Component not suitable for launching"), es_stderr);
1292 es_putc ('\n', es_stderr);
1296 pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
1298 if (component == GC_COMPONENT_DIRMNGR)
1299 argv[i++] = "--dirmngr";
1303 err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
1305 err = gnupg_wait_process (pgmname, pid, 1, NULL);
1307 gc_error (0, 0, "error running '%s%s%s': %s",
1309 component == GC_COMPONENT_DIRMNGR? " --dirmngr":"",
1311 gpg_strerror (err));
1312 gnupg_release_process (pid);
1317 /* Unconditionally restart COMPONENT. */
1319 gc_component_kill (int component)
1321 int runtime[GC_BACKEND_NR];
1322 gc_option_t *option;
1323 gc_backend_t backend;
1325 /* Set a flag for the backends to be reloaded. */
1326 for (backend = 0; backend < GC_BACKEND_NR; backend++)
1327 runtime[backend] = 0;
1331 for (component = 0; component < GC_COMPONENT_NR; component++)
1333 option = gc_component[component].options;
1334 for (; option && option->name; option++)
1335 runtime[option->backend] = 1;
1340 assert (component < GC_COMPONENT_NR);
1341 option = gc_component[component].options;
1342 for (; option && option->name; option++)
1343 runtime[option->backend] = 1;
1346 /* Do the restart for the selected backends. */
1347 for (backend = 0; backend < GC_BACKEND_NR; backend++)
1349 if (runtime[backend] && gc_backend[backend].runtime_change)
1350 (*gc_backend[backend].runtime_change) (1);
1355 /* Unconditionally reload COMPONENT or all components if COMPONENT is -1. */
1357 gc_component_reload (int component)
1359 int runtime[GC_BACKEND_NR];
1360 gc_option_t *option;
1361 gc_backend_t backend;
1363 /* Set a flag for the backends to be reloaded. */
1364 for (backend = 0; backend < GC_BACKEND_NR; backend++)
1365 runtime[backend] = 0;
1369 for (component = 0; component < GC_COMPONENT_NR; component++)
1371 option = gc_component[component].options;
1372 for (; option && option->name; option++)
1373 runtime[option->backend] = 1;
1378 assert (component < GC_COMPONENT_NR);
1379 option = gc_component[component].options;
1380 for (; option && option->name; option++)
1381 runtime[option->backend] = 1;
1384 /* Do the reload for all selected backends. */
1385 for (backend = 0; backend < GC_BACKEND_NR; backend++)
1387 if (runtime[backend] && gc_backend[backend].runtime_change)
1388 (*gc_backend[backend].runtime_change) (0);
1394 /* More or less Robust version of dgettext. It has the side effect of
1395 switching the codeset to utf-8 because this is what we want to
1396 output. In theory it is possible to keep the original code set and
1397 switch back for regular disgnostic output (redefine "_(" for that)
1398 but given the natur of this tool, being something invoked from
1399 other pograms, it does not make much sense. */
1401 my_dgettext (const char *domain, const char *msgid)
1403 #ifdef USE_SIMPLE_GETTEXT
1406 static int switched_codeset;
1409 if (!switched_codeset)
1411 switched_codeset = 1;
1412 gettext_use_utf8 (1);
1415 if (!strcmp (domain, "gnupg"))
1416 domain = PACKAGE_GT;
1418 /* FIXME: we have no dgettext, thus we can't switch. */
1420 text = (char*)gettext (msgid);
1421 return text ? text : msgid;
1425 #elif defined(ENABLE_NLS)
1428 static int switched_codeset;
1431 if (!switched_codeset)
1433 switched_codeset = 1;
1434 bind_textdomain_codeset (PACKAGE_GT, "utf-8");
1436 bindtextdomain (DIRMNGR_NAME, LOCALEDIR);
1437 bind_textdomain_codeset (DIRMNGR_NAME, "utf-8");
1441 /* Note: This is a hack to actually use the gnupg2 domain as
1442 long we are in a transition phase where gnupg 1.x and 1.9 may
1444 if (!strcmp (domain, "gnupg"))
1445 domain = PACKAGE_GT;
1447 text = dgettext (domain, msgid);
1448 return text ? text : msgid;
1459 /* Percent-Escape special characters. The string is valid until the
1460 next invocation of the function. */
1462 gc_percent_escape (const char *src)
1464 static char *esc_str;
1465 static int esc_str_len;
1466 int new_len = 3 * strlen (src) + 1;
1469 if (esc_str_len < new_len)
1471 char *new_esc_str = realloc (esc_str, new_len);
1473 gc_error (1, errno, "can not escape string");
1474 esc_str = new_esc_str;
1475 esc_str_len = new_len;
1487 else if (*src == ':')
1489 /* The colon is used as field separator. */
1494 else if (*src == ',')
1496 /* The comma is used as list separator. */
1501 else if (*src == '\n')
1503 /* The newline is problematic in a line-based format. */
1518 /* Percent-Deescape special characters. The string is valid until the
1519 next invocation of the function. */
1521 percent_deescape (const char *src)
1525 int new_len = 3 * strlen (src) + 1;
1528 if (str_len < new_len)
1530 char *new_str = realloc (str, new_len);
1532 gc_error (1, errno, "can not deescape string");
1542 int val = hextobyte (src + 1);
1545 gc_error (1, 0, "malformed end of string %s", src);
1547 *(dst++) = (char) val;
1551 *(dst++) = *(src++);
1558 /* List all components that are available. */
1560 gc_component_list_components (estream_t out)
1562 gc_component_t component;
1563 gc_option_t *option;
1564 gc_backend_t backend;
1565 int backend_seen[GC_BACKEND_NR];
1567 const char *pgmname;
1569 for (component = 0; component < GC_COMPONENT_NR; component++)
1571 option = gc_component[component].options;
1574 for (backend = 0; backend < GC_BACKEND_NR; backend++)
1575 backend_seen[backend] = 0;
1578 for (; option && option->name; option++)
1580 if ((option->flags & GC_OPT_FLAG_GROUP))
1582 backend = option->backend;
1583 if (backend_seen[backend])
1585 backend_seen[backend] = 1;
1586 assert (backend != GC_BACKEND_ANY);
1587 if (gc_backend[backend].program
1588 && !gc_backend[backend].module_name)
1590 pgmname = gnupg_module_name (gc_backend[backend].module_name);
1594 desc = gc_component[component].desc;
1595 desc = my_dgettext (gc_component[component].desc_domain, desc);
1596 es_fprintf (out, "%s:%s:",
1597 gc_component[component].name, gc_percent_escape (desc));
1598 es_fprintf (out, "%s\n", gc_percent_escape (pgmname));
1606 all_digits_p (const char *p, size_t len)
1610 for (; len; len--, p++)
1611 if (!isascii (*p) || !isdigit (*p))
1613 return 1; /* Yes. */
1617 /* Collect all error lines from stream FP. Only lines prefixed with
1618 TAG are considered. Returns a list of error line items (which may
1619 be empty). There is no error return. */
1621 collect_error_output (estream_t fp, const char *tag)
1627 error_line_t eitem, errlines, *errlines_tail;
1628 size_t taglen = strlen (tag);
1631 errlines_tail = &errlines;
1634 while ((c=es_getc (fp)) != EOF)
1637 if (pos >= sizeof buffer - 5 || c == '\n')
1639 buffer[pos - (c == '\n')] = 0;
1641 ; /*Ignore continuations of previous line. */
1642 else if (!strncmp (buffer, tag, taglen) && buffer[taglen] == ':')
1644 /* "gpgsm: foo:4: bla" */
1645 /* Yep, we are interested in this line. */
1646 p = buffer + taglen + 1;
1647 while (*p == ' ' || *p == '\t')
1649 trim_trailing_spaces (p); /* Get rid of extra CRs. */
1651 ; /* Empty lines are ignored. */
1652 else if ( (p2 = strchr (p, ':')) && (p3 = strchr (p2+1, ':'))
1653 && all_digits_p (p2+1, p3 - (p2+1)))
1655 /* Line in standard compiler format. */
1657 while (*p3 == ' ' || *p3 == '\t')
1659 eitem = xmalloc (sizeof *eitem + strlen (p));
1661 strcpy (eitem->buffer, p);
1662 eitem->fname = eitem->buffer;
1663 eitem->buffer[p2-p] = 0;
1664 eitem->errtext = eitem->buffer + (p3 - p);
1665 /* (we already checked that there are only ascii
1666 digits followed by a colon) */
1668 for (p2++; isdigit (*p2); p2++)
1669 eitem->lineno = eitem->lineno*10 + (*p2 - '0');
1670 *errlines_tail = eitem;
1671 errlines_tail = &eitem->next;
1675 /* Other error output. */
1676 eitem = xmalloc (sizeof *eitem + strlen (p));
1678 strcpy (eitem->buffer, p);
1679 eitem->fname = NULL;
1680 eitem->errtext = eitem->buffer;
1682 *errlines_tail = eitem;
1683 errlines_tail = &eitem->next;
1687 /* If this was not a complete line mark that we are in a
1689 cont_line = (c != '\n');
1693 /* We ignore error lines not terminated by a LF. */
1698 /* Check the options of a single component. Returns 0 if everything
1701 gc_component_check_options (int component, estream_t out, const char *conf_file)
1704 unsigned int result;
1705 int backend_seen[GC_BACKEND_NR];
1706 gc_backend_t backend;
1707 gc_option_t *option;
1708 const char *pgmname;
1709 const char *argv[4];
1714 error_line_t errlines;
1716 for (backend = 0; backend < GC_BACKEND_NR; backend++)
1717 backend_seen[backend] = 0;
1719 option = gc_component[component].options;
1720 for (; option && option->name; option++)
1722 if ((option->flags & GC_OPT_FLAG_GROUP))
1724 backend = option->backend;
1725 if (backend_seen[backend])
1727 backend_seen[backend] = 1;
1728 assert (backend != GC_BACKEND_ANY);
1729 if (!gc_backend[backend].program)
1731 if (!gc_backend[backend].module_name)
1736 if (! option || ! option->name)
1739 pgmname = gnupg_module_name (gc_backend[backend].module_name);
1743 argv[i++] = "--options";
1744 argv[i++] = conf_file;
1746 if (component == GC_COMPONENT_PINENTRY)
1747 argv[i++] = "--version";
1749 argv[i++] = "--gpgconf-test";
1754 err = gnupg_spawn_process (pgmname, argv, NULL, NULL, 0,
1755 NULL, NULL, &errfp, &pid);
1757 result |= 1; /* Program could not be run. */
1760 errlines = collect_error_output (errfp,
1761 gc_component[component].name);
1762 if (gnupg_wait_process (pgmname, pid, 1, &exitcode))
1765 result |= 1; /* Program could not be run or it
1766 terminated abnormally. */
1767 result |= 2; /* Program returned an error. */
1769 gnupg_release_process (pid);
1773 /* If the program could not be run, we can't tell whether
1774 the config file is good. */
1781 error_line_t errptr;
1783 desc = gc_component[component].desc;
1784 desc = my_dgettext (gc_component[component].desc_domain, desc);
1785 es_fprintf (out, "%s:%s:",
1786 gc_component[component].name, gc_percent_escape (desc));
1787 es_fputs (gc_percent_escape (pgmname), out);
1788 es_fprintf (out, ":%d:%d:", !(result & 1), !(result & 2));
1789 for (errptr = errlines; errptr; errptr = errptr->next)
1791 if (errptr != errlines)
1792 es_fputs ("\n:::::", out); /* Continuation line. */
1794 es_fputs (gc_percent_escape (errptr->fname), out);
1797 es_fprintf (out, "%u", errptr->lineno);
1799 es_fputs (gc_percent_escape (errptr->errtext), out);
1802 es_putc ('\n', out);
1807 error_line_t tmp = errlines->next;
1817 /* Check all components that are available. */
1819 gc_check_programs (estream_t out)
1821 gc_component_t component;
1823 for (component = 0; component < GC_COMPONENT_NR; component++)
1824 gc_component_check_options (component, out, NULL);
1829 /* Find the component with the name NAME. Returns -1 if not
1832 gc_component_find (const char *name)
1836 for (idx = 0; idx < GC_COMPONENT_NR; idx++)
1838 if (gc_component[idx].options
1839 && !strcmp (name, gc_component[idx].name))
1846 /* List the option OPTION. */
1848 list_one_option (const gc_option_t *option, estream_t out)
1850 const char *desc = NULL;
1851 char *arg_name = NULL;
1855 desc = my_dgettext (option->desc_domain, option->desc);
1859 const char *arg_tail = strchr (&desc[1], '|');
1863 int arg_len = arg_tail - &desc[1];
1864 arg_name = xmalloc (arg_len + 1);
1865 memcpy (arg_name, &desc[1], arg_len);
1866 arg_name[arg_len] = '\0';
1867 desc = arg_tail + 1;
1873 /* YOU MUST NOT REORDER THE FIELDS IN THIS OUTPUT, AS THEIR ORDER IS
1874 PART OF THE EXTERNAL INTERFACE. YOU MUST NOT REMOVE ANY
1877 /* The name field. */
1878 es_fprintf (out, "%s", option->name);
1880 /* The flags field. */
1881 es_fprintf (out, ":%lu", option->flags);
1887 es_fprintf (out, "none");
1890 unsigned long flags = option->flags;
1891 unsigned long flag = 0;
1892 unsigned long first = 1;
1902 es_fprintf (out, "%s", gc_flag[flag].name);
1910 /* The level field. */
1911 es_fprintf (out, ":%u", option->level);
1913 es_fprintf (out, " %s", gc_level[option->level].name);
1915 /* The description field. */
1916 es_fprintf (out, ":%s", desc ? gc_percent_escape (desc) : "");
1918 /* The type field. */
1919 es_fprintf (out, ":%u", option->arg_type);
1921 es_fprintf (out, " %s", gc_arg_type[option->arg_type].name);
1923 /* The alternate type field. */
1924 es_fprintf (out, ":%u", gc_arg_type[option->arg_type].fallback);
1926 es_fprintf (out, " %s",
1927 gc_arg_type[gc_arg_type[option->arg_type].fallback].name);
1929 /* The argument name field. */
1930 es_fprintf (out, ":%s", arg_name ? gc_percent_escape (arg_name) : "");
1933 /* The default value field. */
1934 es_fprintf (out, ":%s", option->default_value ? option->default_value : "");
1936 /* The default argument field. */
1937 es_fprintf (out, ":%s", option->default_arg ? option->default_arg : "");
1939 /* The value field. */
1940 if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE
1941 && (option->flags & GC_OPT_FLAG_LIST)
1943 /* The special format "1,1,1,1,...,1" is converted to a number
1945 es_fprintf (out, ":%u", (unsigned int)((strlen (option->value) + 1) / 2));
1947 es_fprintf (out, ":%s", option->value ? option->value : "");
1949 /* ADD NEW FIELDS HERE. */
1951 es_putc ('\n', out);
1955 /* List all options of the component COMPONENT. */
1957 gc_component_list_options (int component, estream_t out)
1959 const gc_option_t *option = gc_component[component].options;
1961 while (option && option->name)
1963 /* Do not output unknown or internal options. */
1964 if (!(option->flags & GC_OPT_FLAG_GROUP)
1965 && (!option->active || option->level == GC_LEVEL_INTERNAL))
1971 if (option->flags & GC_OPT_FLAG_GROUP)
1973 const gc_option_t *group_option = option + 1;
1974 gc_expert_level_t level = GC_LEVEL_NR;
1976 /* The manual states that the group level is always the
1977 minimum of the levels of all contained options. Due to
1978 different active options, and because it is hard to
1979 maintain manually, we calculate it here. The value in
1980 the global static table is ignored. */
1982 while (group_option->name)
1984 if (group_option->flags & GC_OPT_FLAG_GROUP)
1986 if (group_option->level < level)
1987 level = group_option->level;
1991 /* Check if group is empty. */
1992 if (level != GC_LEVEL_NR)
1994 gc_option_t opt_copy;
1996 /* Fix up the group level. */
1997 memcpy (&opt_copy, option, sizeof (opt_copy));
1998 opt_copy.level = level;
1999 list_one_option (&opt_copy, out);
2003 list_one_option (option, out);
2010 /* Find the option NAME in component COMPONENT, for the backend
2011 BACKEND. If BACKEND is GC_BACKEND_ANY, any backend will match. */
2012 static gc_option_t *
2013 find_option (gc_component_t component, const char *name,
2014 gc_backend_t backend)
2016 gc_option_t *option = gc_component[component].options;
2017 while (option->name)
2019 if (!(option->flags & GC_OPT_FLAG_GROUP)
2020 && !strcmp (option->name, name)
2021 && (backend == GC_BACKEND_ANY || option->backend == backend))
2025 return option->name ? option : NULL;
2029 /* Determine the configuration filename for the component COMPONENT
2030 and backend BACKEND. */
2032 get_config_filename (gc_component_t component, gc_backend_t backend)
2034 char *filename = NULL;
2035 gc_option_t *option = find_option
2036 (component, gc_backend[backend].option_config_filename, GC_BACKEND_ANY);
2038 assert (option->arg_type == GC_ARG_TYPE_FILENAME);
2039 assert (!(option->flags & GC_OPT_FLAG_LIST));
2041 if (!option->active || !option->default_value)
2042 gc_error (1, 0, "Option %s, needed by backend %s, was not initialized",
2043 gc_backend[backend].option_config_filename,
2044 gc_backend[backend].name);
2046 if (option->value && *option->value)
2047 filename = percent_deescape (&option->value[1]);
2048 else if (option->default_value && *option->default_value)
2049 filename = percent_deescape (&option->default_value[1]);
2053 #if HAVE_W32CE_SYSTEM
2054 if (!(filename[0] == '/' || filename[0] == '\\'))
2055 #elif defined(HAVE_DOSISH_SYSTEM)
2057 && filename[1] == ':'
2058 && (filename[2] == '/' || filename[2] == '\\')))
2060 if (filename[0] != '/')
2062 gc_error (1, 0, "Option %s, needed by backend %s, is not absolute",
2063 gc_backend[backend].option_config_filename,
2064 gc_backend[backend].name);
2070 /* Retrieve the options for the component COMPONENT from backend
2071 BACKEND, which we already know is a program-type backend. */
2073 retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
2076 const char *pgmname;
2077 const char *argv[2];
2082 size_t line_len = 0;
2085 char *config_filename;
2087 pgmname = (gc_backend[backend].module_name
2088 ? gnupg_module_name (gc_backend[backend].module_name)
2089 : gc_backend[backend].program );
2090 argv[0] = "--gpgconf-list";
2093 err = gnupg_spawn_process (pgmname, argv, NULL, NULL, 0,
2094 NULL, &outfp, NULL, &pid);
2097 gc_error (1, 0, "could not gather active options from '%s': %s",
2098 pgmname, gpg_strerror (err));
2101 while ((length = es_read_line (outfp, &line, &line_len, NULL)) > 0)
2103 gc_option_t *option;
2105 unsigned long flags = 0;
2106 char *default_value = NULL;
2108 /* Strip newline and carriage return, if present. */
2110 && (line[length - 1] == '\n' || line[length - 1] == '\r'))
2111 line[--length] = '\0';
2113 linep = strchr (line, ':');
2117 /* Extract additional flags. Default to none. */
2123 end = strchr (linep, ':');
2127 gpg_err_set_errno (0);
2128 flags = strtoul (linep, &tail, 0);
2130 gc_error (1, errno, "malformed flags in option %s from %s",
2132 if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
2133 gc_error (1, 0, "garbage after flags in option %s from %s",
2139 /* Extract default value, if present. Default to empty if
2145 end = strchr (linep, ':');
2149 if (flags & GC_OPT_FLAG_DEFAULT)
2150 default_value = linep;
2155 /* Look up the option in the component and install the
2156 configuration data. */
2157 option = find_option (component, line, backend);
2161 gc_error (1, errno, "option %s returned twice from %s",
2165 option->flags |= flags;
2166 if (default_value && *default_value)
2167 option->default_value = xstrdup (default_value);
2170 if (length < 0 || es_ferror (outfp))
2171 gc_error (1, errno, "error reading from %s", pgmname);
2172 if (es_fclose (outfp))
2173 gc_error (1, errno, "error closing %s", pgmname);
2175 err = gnupg_wait_process (pgmname, pid, 1, &exitcode);
2177 gc_error (1, 0, "running %s failed (exitcode=%d): %s",
2178 pgmname, exitcode, gpg_strerror (err));
2179 gnupg_release_process (pid);
2182 /* At this point, we can parse the configuration file. */
2183 config_filename = get_config_filename (component, backend);
2185 config = es_fopen (config_filename, "r");
2188 if (errno != ENOENT)
2189 gc_error (0, errno, "warning: can not open config file %s",
2194 while ((length = es_read_line (config, &line, &line_len, NULL)) > 0)
2198 gc_option_t *option;
2201 while (*name == ' ' || *name == '\t')
2203 if (!*name || *name == '#' || *name == '\r' || *name == '\n')
2207 while (*value && *value != ' ' && *value != '\t'
2208 && *value != '#' && *value != '\r' && *value != '\n')
2210 if (*value == ' ' || *value == '\t')
2215 while (*value == ' ' || *value == '\t')
2219 while (*end && *end != '#' && *end != '\r' && *end != '\n')
2221 while (end > value && (end[-1] == ' ' || end[-1] == '\t'))
2228 /* Look up the option in the component and install the
2229 configuration data. */
2230 option = find_option (component, line, backend);
2235 if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE)
2239 "warning: ignoring argument %s for option %s",
2241 opt_value = xstrdup ("1");
2243 else if (gc_arg_type[option->arg_type].fallback
2244 == GC_ARG_TYPE_STRING)
2245 opt_value = xasprintf ("\"%s", gc_percent_escape (value));
2248 /* FIXME: Verify that the number is sane. */
2249 opt_value = xstrdup (value);
2252 /* Now enter the option into the table. */
2253 if (!(option->flags & GC_OPT_FLAG_LIST))
2256 xfree (option->value);
2257 option->value = opt_value;
2262 option->value = opt_value;
2265 char *old = option->value;
2266 option->value = xasprintf ("%s,%s", old, opt_value);
2274 if (length < 0 || es_ferror (config))
2275 gc_error (1, errno, "error reading from %s", config_filename);
2276 if (es_fclose (config))
2277 gc_error (1, errno, "error closing %s", config_filename);
2284 /* Retrieve the options for the component COMPONENT from backend
2285 BACKEND, which we already know is of type file list. */
2287 retrieve_options_from_file (gc_component_t component, gc_backend_t backend)
2289 gc_option_t *list_option;
2290 gc_option_t *config_option;
2291 char *list_filename;
2292 gpgrt_stream_t list_file;
2294 size_t line_len = 0;
2298 list_option = find_option (component,
2299 gc_backend[backend].option_name, GC_BACKEND_ANY);
2300 assert (list_option);
2301 assert (!list_option->active);
2303 list_filename = get_config_filename (component, backend);
2304 list_file = gpgrt_fopen (list_filename, "r");
2306 gc_error (0, errno, "warning: can not open list file %s", list_filename);
2310 while ((length = gpgrt_read_line (list_file, &line, &line_len, NULL)) > 0)
2317 while (*start == ' ' || *start == '\t')
2319 if (!*start || *start == '#' || *start == '\r' || *start == '\n')
2323 while (*end && *end != '#' && *end != '\r' && *end != '\n')
2325 /* Walk back to skip trailing white spaces. Looks evil, but
2326 works because of the conditions on START and END imposed
2327 at this point (END is at least START + 1, and START is
2328 not a whitespace character). */
2329 while (*(end - 1) == ' ' || *(end - 1) == '\t')
2332 /* FIXME: Oh, no! This is so lame! Should use realloc and
2336 new_list = xasprintf ("%s,\"%s", list, gc_percent_escape (start));
2341 list = xasprintf ("\"%s", gc_percent_escape (start));
2343 if (length < 0 || gpgrt_ferror (list_file))
2344 gc_error (1, errno, "can not read list file %s", list_filename);
2347 list_option->active = 1;
2348 list_option->value = list;
2350 /* Fix up the read-only flag. */
2351 config_option = find_option
2352 (component, gc_backend[backend].option_config_filename, GC_BACKEND_ANY);
2353 if (config_option->flags & GC_OPT_FLAG_NO_CHANGE)
2354 list_option->flags |= GC_OPT_FLAG_NO_CHANGE;
2356 if (list_file && gpgrt_fclose (list_file))
2357 gc_error (1, errno, "error closing %s", list_filename);
2362 /* Retrieve the currently active options and their defaults from all
2363 involved backends for this component. Using -1 for component will
2364 retrieve all options from all components. */
2366 gc_component_retrieve_options (int component)
2368 int process_all = 0;
2369 int backend_seen[GC_BACKEND_NR];
2370 gc_backend_t backend;
2371 gc_option_t *option;
2373 for (backend = 0; backend < GC_BACKEND_NR; backend++)
2374 backend_seen[backend] = 0;
2376 if (component == -1)
2380 assert (component < GC_COMPONENT_NR);
2385 if (component == GC_COMPONENT_PINENTRY)
2386 continue; /* Skip this dummy component. */
2388 option = gc_component[component].options;
2390 while (option && option->name)
2392 if (!(option->flags & GC_OPT_FLAG_GROUP))
2394 backend = option->backend;
2396 if (backend_seen[backend])
2401 backend_seen[backend] = 1;
2403 assert (backend != GC_BACKEND_ANY);
2405 if (gc_backend[backend].program)
2406 retrieve_options_from_program (component, backend);
2408 retrieve_options_from_file (component, backend);
2413 while (process_all && ++component < GC_COMPONENT_NR);
2419 /* Perform a simple validity check based on the type. Return in
2420 * NEW_VALUE_NR the value of the number in NEW_VALUE if OPTION is of
2421 * type GC_ARG_TYPE_NONE. If VERBATIM is set the profile parsing mode
2424 option_check_validity (gc_option_t *option, unsigned long flags,
2425 char *new_value, unsigned long *new_value_nr,
2430 if (!option->active)
2431 gc_error (1, 0, "option %s not supported by backend %s",
2432 option->name, gc_backend[option->backend].name);
2434 if (option->new_flags || option->new_value)
2435 gc_error (1, 0, "option %s already changed", option->name);
2437 if (flags & GC_OPT_FLAG_DEFAULT)
2440 gc_error (1, 0, "argument %s provided for deleted option %s",
2441 new_value, option->name);
2446 /* GC_ARG_TYPE_NONE options have special list treatment. */
2447 if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE)
2451 gpg_err_set_errno (0);
2452 *new_value_nr = strtoul (new_value, &tail, 0);
2455 gc_error (1, errno, "invalid argument for option %s",
2458 gc_error (1, 0, "garbage after argument for option %s",
2461 if (!(option->flags & GC_OPT_FLAG_LIST))
2463 if (*new_value_nr != 1)
2464 gc_error (1, 0, "argument for non-list option %s of type 0 "
2465 "(none) must be 1", option->name);
2469 if (*new_value_nr == 0)
2470 gc_error (1, 0, "argument for option %s of type 0 (none) "
2471 "must be positive", option->name);
2480 if (*arg == '\0' || (*arg == ',' && !verbatim))
2482 if (!(option->flags & GC_OPT_FLAG_ARG_OPT))
2483 gc_error (1, 0, "argument required for option %s", option->name);
2485 if (*arg == ',' && !verbatim && !(option->flags & GC_OPT_FLAG_LIST))
2486 gc_error (1, 0, "list found for non-list option %s", option->name);
2488 else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING)
2490 if (*arg != '"' && !verbatim)
2491 gc_error (1, 0, "string argument for option %s must begin "
2492 "with a quote (\") character", option->name);
2494 /* FIXME: We do not allow empty string arguments for now, as
2495 we do not quote arguments in configuration files, and
2496 thus no argument is indistinguishable from the empty
2498 if (arg[1] == '\0' || (arg[1] == ',' && !verbatim))
2499 gc_error (1, 0, "empty string argument for option %s is "
2500 "currently not allowed. Please report this!",
2503 else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32)
2507 gpg_err_set_errno (0);
2508 res = strtol (arg, &arg, 0);
2512 gc_error (1, errno, "invalid argument for option %s",
2515 if (*arg != '\0' && (*arg != ',' || verbatim))
2516 gc_error (1, 0, "garbage after argument for option %s",
2519 else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_UINT32)
2523 gpg_err_set_errno (0);
2524 res = strtoul (arg, &arg, 0);
2528 gc_error (1, errno, "invalid argument for option %s",
2531 if (*arg != '\0' && (*arg != ',' || verbatim))
2532 gc_error (1, 0, "garbage after argument for option %s",
2535 arg = verbatim? strchr (arg, ',') : NULL;
2539 while (arg && *arg);
2542 #ifdef HAVE_W32_SYSTEM
2544 copy_file (const char *src_name, const char *dst_name)
2546 #define BUF_LEN 4096
2547 char buffer[BUF_LEN];
2552 src = gpgrt_fopen (src_name, "r");
2556 dst = gpgrt_fopen (dst_name, "w");
2559 int saved_err = errno;
2561 gpg_err_set_errno (saved_err);
2569 len = gpgrt_fread (buffer, 1, BUF_LEN, src);
2572 written = gpgrt_fwrite (buffer, 1, len, dst);
2576 while (! gpgrt_feof (src) && ! gpgrt_ferror (src) && ! gpgrt_ferror (dst));
2578 if (gpgrt_ferror (src) || gpgrt_ferror (dst) || ! gpgrt_feof (src))
2580 int saved_errno = errno;
2584 gpg_err_set_errno (saved_errno);
2588 if (gpgrt_fclose (dst))
2589 gc_error (1, errno, "error closing %s", dst_name);
2590 if (gpgrt_fclose (src))
2591 gc_error (1, errno, "error closing %s", src_name);
2595 #endif /* HAVE_W32_SYSTEM */
2598 /* Create and verify the new configuration file for the specified
2599 * backend and component. Returns 0 on success and -1 on error. This
2600 * function may store pointers to malloced strings in SRC_FILENAMEP,
2601 * DEST_FILENAMEP, and ORIG_FILENAMEP. Those must be freed by the
2602 * caller. The strings refer to three versions of the configuration
2605 * SRC_FILENAME: The updated configuration is written to this file.
2606 * DEST_FILENAME: Name of the configuration file read by the
2608 * ORIG_FILENAME: A backup of the previous configuration file.
2610 * To apply the configuration change, rename SRC_FILENAME to
2611 * DEST_FILENAME. To revert to the previous configuration, rename
2612 * ORIG_FILENAME to DEST_FILENAME. */
2614 change_options_file (gc_component_t component, gc_backend_t backend,
2615 char **src_filenamep, char **dest_filenamep,
2616 char **orig_filenamep)
2618 static const char marker[] = "###+++--- " GPGCONF_DISP_NAME " ---+++###";
2619 /* True if we are within the marker in the config file. */
2621 gc_option_t *option;
2627 gpgrt_stream_t src_file = NULL;
2628 gpgrt_stream_t dest_file = NULL;
2630 char *dest_filename;
2631 char *orig_filename;
2633 char *cur_arg = NULL;
2635 option = find_option (component,
2636 gc_backend[backend].option_name, GC_BACKEND_ANY);
2638 assert (option->active);
2639 assert (gc_arg_type[option->arg_type].fallback != GC_ARG_TYPE_NONE);
2641 /* FIXME. Throughout the function, do better error reporting. */
2642 /* Note that get_config_filename() calls percent_deescape(), so we
2643 call this before processing the arguments. */
2644 dest_filename = xstrdup (get_config_filename (component, backend));
2645 src_filename = xasprintf ("%s.%s.%i.new",
2646 dest_filename, GPGCONF_NAME, (int)getpid ());
2647 orig_filename = xasprintf ("%s.%s.%i.bak",
2648 dest_filename, GPGCONF_NAME, (int)getpid ());
2650 arg = option->new_value;
2651 if (arg && arg[0] == '\0')
2658 end = strchr (arg, ',');
2662 cur_arg = percent_deescape (arg);
2672 #ifdef HAVE_W32_SYSTEM
2673 res = copy_file (dest_filename, orig_filename);
2675 res = link (dest_filename, orig_filename);
2677 if (res < 0 && errno != ENOENT)
2679 xfree (dest_filename);
2680 xfree (src_filename);
2681 xfree (orig_filename);
2686 xfree (orig_filename);
2687 orig_filename = NULL;
2690 /* We now initialize the return strings, so the caller can do the
2692 *src_filenamep = src_filename;
2693 *dest_filenamep = dest_filename;
2694 *orig_filenamep = orig_filename;
2696 /* Use open() so that we can use O_EXCL. */
2697 fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
2700 src_file = gpgrt_fdopen (fd, "w");
2704 gpg_err_set_errno (res);
2708 /* Only if ORIG_FILENAME is not NULL did the configuration file
2709 exist already. In this case, we will copy its content into the
2710 new configuration file, changing it to our liking in the
2714 dest_file = gpgrt_fopen (dest_filename, "r");
2716 goto change_file_one_err;
2718 while ((length = gpgrt_read_line (dest_file, &line, &line_len, NULL)) > 0)
2723 if (!strncmp (marker, line, sizeof (marker) - 1))
2732 while (*start == ' ' || *start == '\t')
2734 if (*start && *start != '\r' && *start != '\n' && *start != '#')
2743 /* Search for the end of the line. */
2744 while (*endp && *endp != '#' && *endp != '\r' && *endp != '\n')
2747 if (*endp && *endp != ' ' && *endp != '\t'
2748 && *endp != '\r' && *endp != '\n' && *endp != '#')
2754 if ((option->new_flags & GC_OPT_FLAG_DEFAULT)
2755 || !cur_arg || strcmp (start, cur_arg))
2759 /* Find next argument. */
2765 arg_end = strchr (arg, ',');
2769 cur_arg = percent_deescape (arg);
2789 gpgrt_fprintf (src_file,
2790 "# %s disabled this option here at %s\n",
2791 GPGCONF_DISP_NAME, asctimestamp (gnupg_get_time ()));
2792 if (gpgrt_ferror (src_file))
2793 goto change_file_one_err;
2794 gpgrt_fprintf (src_file, "# %s", line);
2795 if (gpgrt_ferror (src_file))
2796 goto change_file_one_err;
2801 gpgrt_fprintf (src_file, "%s", line);
2802 if (gpgrt_ferror (src_file))
2803 goto change_file_one_err;
2806 if (length < 0 || gpgrt_ferror (dest_file))
2807 goto change_file_one_err;
2812 /* There was no marker. This is the first time we edit the
2813 file. We add our own marker at the end of the file and
2814 proceed. Note that we first write a newline, this guards us
2815 against files which lack the newline at the end of the last
2816 line, while it doesn't hurt us in all other cases. */
2817 gpgrt_fprintf (src_file, "\n%s\n", marker);
2818 if (gpgrt_ferror (src_file))
2819 goto change_file_one_err;
2822 /* At this point, we have copied everything up to the end marker
2823 into the new file, except for the arguments we are going to add.
2824 Now, dump the new arguments and write the end marker, possibly
2825 followed by the rest of the original file. */
2828 gpgrt_fprintf (src_file, "%s\n", cur_arg);
2830 /* Find next argument. */
2836 end = strchr (arg, ',');
2840 cur_arg = percent_deescape (arg);
2853 gpgrt_fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ()));
2854 if (gpgrt_ferror (src_file))
2855 goto change_file_one_err;
2859 gpgrt_fprintf (src_file, "# %s edited this configuration file.\n",
2861 if (gpgrt_ferror (src_file))
2862 goto change_file_one_err;
2863 gpgrt_fprintf (src_file, "# It will disable options before this marked "
2864 "block, but it will\n");
2865 if (gpgrt_ferror (src_file))
2866 goto change_file_one_err;
2867 gpgrt_fprintf (src_file, "# never change anything below these lines.\n");
2868 if (gpgrt_ferror (src_file))
2869 goto change_file_one_err;
2873 while ((length = gpgrt_read_line (dest_file, &line, &line_len, NULL)) > 0)
2875 gpgrt_fprintf (src_file, "%s", line);
2876 if (gpgrt_ferror (src_file))
2877 goto change_file_one_err;
2879 if (length < 0 || gpgrt_ferror (dest_file))
2880 goto change_file_one_err;
2885 res = gpgrt_fclose (src_file);
2891 gpgrt_fclose (dest_file);
2892 gpg_err_set_errno (res);
2898 res = gpgrt_fclose (dest_file);
2904 change_file_one_err:
2909 gpgrt_fclose (src_file);
2913 gpgrt_fclose (dest_file);
2914 gpg_err_set_errno (res);
2919 /* Create and verify the new configuration file for the specified
2920 * backend and component. Returns 0 on success and -1 on error. If
2921 * VERBATIM is set the profile mode is used. This function may store
2922 * pointers to malloced strings in SRC_FILENAMEP, DEST_FILENAMEP, and
2923 * ORIG_FILENAMEP. Those must be freed by the caller. The strings
2924 * refer to three versions of the configuration file:
2926 * SRC_FILENAME: The updated configuration is written to this file.
2927 * DEST_FILENAME: Name of the configuration file read by the
2929 * ORIG_FILENAME: A backup of the previous configuration file.
2931 * To apply the configuration change, rename SRC_FILENAME to
2932 * DEST_FILENAME. To revert to the previous configuration, rename
2933 * ORIG_FILENAME to DEST_FILENAME. */
2935 change_options_program (gc_component_t component, gc_backend_t backend,
2936 char **src_filenamep, char **dest_filenamep,
2937 char **orig_filenamep,
2940 static const char marker[] = "###+++--- " GPGCONF_DISP_NAME " ---+++###";
2941 /* True if we are within the marker in the config file. */
2943 gc_option_t *option;
2949 gpgrt_stream_t src_file = NULL;
2950 gpgrt_stream_t dest_file = NULL;
2952 char *dest_filename;
2953 char *orig_filename;
2954 /* Special hack for gpg, see below. */
2955 int utf8strings_seen = 0;
2957 /* FIXME. Throughout the function, do better error reporting. */
2958 dest_filename = xstrdup (get_config_filename (component, backend));
2959 src_filename = xasprintf ("%s.%s.%i.new",
2960 dest_filename, GPGCONF_NAME, (int)getpid ());
2961 orig_filename = xasprintf ("%s.%s.%i.bak",
2962 dest_filename, GPGCONF_NAME, (int)getpid ());
2964 #ifdef HAVE_W32_SYSTEM
2965 res = copy_file (dest_filename, orig_filename);
2967 res = link (dest_filename, orig_filename);
2969 if (res < 0 && errno != ENOENT)
2971 xfree (dest_filename);
2972 xfree (src_filename);
2973 xfree (orig_filename);
2978 xfree (orig_filename);
2979 orig_filename = NULL;
2982 /* We now initialize the return strings, so the caller can do the
2984 *src_filenamep = src_filename;
2985 *dest_filenamep = dest_filename;
2986 *orig_filenamep = orig_filename;
2988 /* Use open() so that we can use O_EXCL. */
2989 fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
2992 src_file = gpgrt_fdopen (fd, "w");
2996 gpg_err_set_errno (res);
3000 /* Only if ORIG_FILENAME is not NULL did the configuration file
3001 exist already. In this case, we will copy its content into the
3002 new configuration file, changing it to our liking in the
3006 dest_file = gpgrt_fopen (dest_filename, "r");
3008 goto change_one_err;
3010 while ((length = gpgrt_read_line (dest_file, &line, &line_len, NULL)) > 0)
3015 if (!strncmp (marker, line, sizeof (marker) - 1))
3022 else if (backend == GC_BACKEND_GPG && in_marker
3023 && ! strcmp ("utf8-strings\n", line))
3025 /* Strip duplicated entries. */
3026 if (utf8strings_seen)
3029 utf8strings_seen = 1;
3033 while (*start == ' ' || *start == '\t')
3035 if (*start && *start != '\r' && *start != '\n' && *start != '#')
3041 while (*end && *end != ' ' && *end != '\t'
3042 && *end != '\r' && *end != '\n' && *end != '#')
3047 option = find_option (component, start, backend);
3049 if (option && ((option->new_flags & GC_OPT_FLAG_DEFAULT)
3050 || option->new_value))
3057 gpgrt_fprintf (src_file,
3058 "# %s disabled this option here at %s\n",
3059 GPGCONF_DISP_NAME, asctimestamp (gnupg_get_time ()));
3060 if (gpgrt_ferror (src_file))
3061 goto change_one_err;
3062 gpgrt_fprintf (src_file, "# %s", line);
3063 if (gpgrt_ferror (src_file))
3064 goto change_one_err;
3069 gpgrt_fprintf (src_file, "%s", line);
3070 if (gpgrt_ferror (src_file))
3071 goto change_one_err;
3074 if (length < 0 || gpgrt_ferror (dest_file))
3075 goto change_one_err;
3080 /* There was no marker. This is the first time we edit the
3081 file. We add our own marker at the end of the file and
3082 proceed. Note that we first write a newline, this guards us
3083 against files which lack the newline at the end of the last
3084 line, while it doesn't hurt us in all other cases. */
3085 gpgrt_fprintf (src_file, "\n%s\n", marker);
3086 if (gpgrt_ferror (src_file))
3087 goto change_one_err;
3089 /* At this point, we have copied everything up to the end marker
3090 into the new file, except for the options we are going to change.
3091 Now, dump the changed options (except for those we are going to
3092 revert to their default), and write the end marker, possibly
3093 followed by the rest of the original file. */
3095 /* We have to turn on UTF8 strings for GnuPG. */
3096 if (backend == GC_BACKEND_GPG && ! utf8strings_seen)
3097 gpgrt_fprintf (src_file, "utf8-strings\n");
3099 option = gc_component[component].options;
3100 while (option->name)
3102 if (!(option->flags & GC_OPT_FLAG_GROUP)
3103 && option->backend == backend
3104 && option->new_value)
3106 char *arg = option->new_value;
3110 if (*arg == '\0' || *arg == ',')
3112 gpgrt_fprintf (src_file, "%s\n", option->name);
3113 if (gpgrt_ferror (src_file))
3114 goto change_one_err;
3116 else if (gc_arg_type[option->arg_type].fallback
3117 == GC_ARG_TYPE_NONE)
3119 assert (*arg == '1');
3120 gpgrt_fprintf (src_file, "%s\n", option->name);
3121 if (gpgrt_ferror (src_file))
3122 goto change_one_err;
3126 else if (gc_arg_type[option->arg_type].fallback
3127 == GC_ARG_TYPE_STRING)
3133 log_assert (*arg == '"');
3136 end = strchr (arg, ',');
3143 gpgrt_fprintf (src_file, "%s %s\n", option->name,
3144 verbatim? arg : percent_deescape (arg));
3145 if (gpgrt_ferror (src_file))
3146 goto change_one_err;
3156 end = strchr (arg, ',');
3160 gpgrt_fprintf (src_file, "%s %s\n", option->name, arg);
3161 if (gpgrt_ferror (src_file))
3162 goto change_one_err;
3169 assert (arg == NULL || *arg == '\0' || *arg == ',');
3170 if (arg && *arg == ',')
3173 while (arg && *arg);
3178 gpgrt_fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ()));
3179 if (gpgrt_ferror (src_file))
3180 goto change_one_err;
3184 gpgrt_fprintf (src_file, "# %s edited this configuration file.\n",
3186 if (gpgrt_ferror (src_file))
3187 goto change_one_err;
3188 gpgrt_fprintf (src_file, "# It will disable options before this marked "
3189 "block, but it will\n");
3190 if (gpgrt_ferror (src_file))
3191 goto change_one_err;
3192 gpgrt_fprintf (src_file, "# never change anything below these lines.\n");
3193 if (gpgrt_ferror (src_file))
3194 goto change_one_err;
3198 while ((length = gpgrt_read_line (dest_file, &line, &line_len, NULL)) > 0)
3200 gpgrt_fprintf (src_file, "%s", line);
3201 if (gpgrt_ferror (src_file))
3202 goto change_one_err;
3204 if (length < 0 || gpgrt_ferror (dest_file))
3205 goto change_one_err;
3210 res = gpgrt_fclose (src_file);
3216 gpgrt_fclose (dest_file);
3217 gpg_err_set_errno (res);
3223 res = gpgrt_fclose (dest_file);
3234 gpgrt_fclose (src_file);
3238 gpgrt_fclose (dest_file);
3239 gpg_err_set_errno (res);
3244 /* Common code for gc_component_change_options and
3245 * gc_process_gpgconf_conf. If VERBATIM is set the profile parsing
3248 change_one_value (gc_option_t *option, int *runtime,
3249 unsigned long flags, char *new_value, int verbatim)
3251 unsigned long new_value_nr = 0;
3253 option_check_validity (option, flags, new_value, &new_value_nr, verbatim);
3255 if (option->flags & GC_OPT_FLAG_RUNTIME)
3256 runtime[option->backend] = 1;
3258 option->new_flags = flags;
3259 if (!(flags & GC_OPT_FLAG_DEFAULT))
3261 if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE
3262 && (option->flags & GC_OPT_FLAG_LIST))
3266 /* We convert the number to a list of 1's for convenient
3268 assert (new_value_nr > 0);
3269 option->new_value = xmalloc ((2 * (new_value_nr - 1) + 1) + 1);
3270 str = option->new_value;
3272 while (--new_value_nr > 0)
3280 option->new_value = xstrdup (new_value);
3285 /* Read the modifications from IN and apply them. If IN is NULL the
3286 modifications are expected to already have been set to the global
3287 table. If VERBATIM is set the profile mode is used. */
3289 gc_component_change_options (int component, estream_t in, estream_t out,
3294 int runtime[GC_BACKEND_NR];
3295 char *src_filename[GC_BACKEND_NR];
3296 char *dest_filename[GC_BACKEND_NR];
3297 char *orig_filename[GC_BACKEND_NR];
3298 gc_backend_t backend;
3299 gc_option_t *option;
3301 size_t line_len = 0;
3304 if (component == GC_COMPONENT_PINENTRY)
3305 return; /* Dummy component for now. */
3307 for (backend = 0; backend < GC_BACKEND_NR; backend++)
3309 runtime[backend] = 0;
3310 src_filename[backend] = NULL;
3311 dest_filename[backend] = NULL;
3312 orig_filename[backend] = NULL;
3317 /* Read options from the file IN. */
3318 while ((length = es_read_line (in, &line, &line_len, NULL)) > 0)
3321 unsigned long flags = 0;
3322 char *new_value = "";
3324 /* Strip newline and carriage return, if present. */
3326 && (line[length - 1] == '\n' || line[length - 1] == '\r'))
3327 line[--length] = '\0';
3329 linep = strchr (line, ':');
3333 /* Extract additional flags. Default to none. */
3339 end = strchr (linep, ':');
3343 gpg_err_set_errno (0);
3344 flags = strtoul (linep, &tail, 0);
3346 gc_error (1, errno, "malformed flags in option %s", line);
3347 if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
3348 gc_error (1, 0, "garbage after flags in option %s", line);
3353 /* Don't allow setting of the no change flag. */
3354 flags &= ~GC_OPT_FLAG_NO_CHANGE;
3356 /* Extract default value, if present. Default to empty if not. */
3360 end = strchr (linep, ':');
3367 option = find_option (component, line, GC_BACKEND_ANY);
3369 gc_error (1, 0, "unknown option %s", line);
3371 if ((option->flags & GC_OPT_FLAG_NO_CHANGE))
3373 gc_error (0, 0, "ignoring new value for option %s",
3378 change_one_value (option, runtime, flags, new_value, 0);
3380 if (length < 0 || gpgrt_ferror (in))
3381 gc_error (1, errno, "error reading stream 'in'");
3384 /* Now that we have collected and locally verified the changes,
3385 write them out to new configuration files, verify them
3386 externally, and then commit them. */
3387 option = gc_component[component].options;
3388 while (option && option->name)
3390 /* Go on if we have already seen this backend, or if there is
3392 if (src_filename[option->backend]
3393 || !(option->new_flags || option->new_value))
3399 if (gc_backend[option->backend].program)
3401 err = change_options_program (component, option->backend,
3402 &src_filename[option->backend],
3403 &dest_filename[option->backend],
3404 &orig_filename[option->backend],
3408 /* External verification. */
3409 err = gc_component_check_options (component, out,
3410 src_filename[option->backend]);
3414 _("External verification of component %s failed"),
3415 gc_component[component].name);
3416 gpg_err_set_errno (EINVAL);
3422 err = change_options_file (component, option->backend,
3423 &src_filename[option->backend],
3424 &dest_filename[option->backend],
3425 &orig_filename[option->backend]);
3433 /* We are trying to atomically commit all changes. Unfortunately,
3434 we cannot rely on gnupg_rename_file to manage the signals for us,
3435 doing so would require us to pass NULL as BLOCK to any subsequent
3436 call to it. Instead, we just manage the signal handling
3439 gnupg_block_all_signals ();
3441 if (! err && ! opt.dry_run)
3445 for (i = 0; i < GC_BACKEND_NR; i++)
3447 if (src_filename[i])
3449 /* FIXME: Make a verification here. */
3451 assert (dest_filename[i]);
3453 if (orig_filename[i])
3454 err = gnupg_rename_file (src_filename[i], dest_filename[i], NULL);
3457 #ifdef HAVE_W32_SYSTEM
3458 /* We skip the unlink if we expect the file not to
3460 err = gnupg_rename_file (src_filename[i], dest_filename[i], NULL);
3461 #else /* HAVE_W32_SYSTEM */
3462 /* This is a bit safer than rename() because we
3463 expect DEST_FILENAME not to be there. If it
3464 happens to be there, this will fail. */
3465 err = link (src_filename[i], dest_filename[i]);
3467 err = unlink (src_filename[i]);
3468 #endif /* !HAVE_W32_SYSTEM */
3472 xfree (src_filename[i]);
3473 src_filename[i] = NULL;
3478 if (err || opt.dry_run)
3481 int saved_errno = errno;
3483 /* An error occurred or a dry-run is requested. */
3484 for (i = 0; i < GC_BACKEND_NR; i++)
3486 if (src_filename[i])
3488 /* The change was not yet committed. */
3489 unlink (src_filename[i]);
3490 if (orig_filename[i])
3491 unlink (orig_filename[i]);
3495 /* The changes were already committed. FIXME: This is a
3496 tad dangerous, as we don't know if we don't overwrite
3497 a version of the file that is even newer than the one
3498 we just installed. */
3499 if (orig_filename[i])
3500 gnupg_rename_file (orig_filename[i], dest_filename[i], NULL);
3502 unlink (dest_filename[i]);
3506 gc_error (1, saved_errno, "could not commit changes");
3508 /* Fall-through for dry run. */
3512 /* If it all worked, notify the daemons of the changes. */
3514 for (backend = 0; backend < GC_BACKEND_NR; backend++)
3516 if (runtime[backend] && gc_backend[backend].runtime_change)
3517 (*gc_backend[backend].runtime_change) (0);
3520 /* Move the per-process backup file into its place. */
3521 for (backend = 0; backend < GC_BACKEND_NR; backend++)
3522 if (orig_filename[backend])
3524 char *backup_filename;
3526 assert (dest_filename[backend]);
3528 backup_filename = xasprintf ("%s.%s.bak",
3529 dest_filename[backend], GPGCONF_NAME);
3530 gnupg_rename_file (orig_filename[backend], backup_filename, NULL);
3531 xfree (backup_filename);
3536 gnupg_unblock_all_signals ();
3538 for (backend = 0; backend < GC_BACKEND_NR; backend++)
3540 xfree (src_filename[backend]);
3541 xfree (dest_filename[backend]);
3542 xfree (orig_filename[backend]);
3547 /* Check whether USER matches the current user of one of its group.
3548 This function may change USER. Returns true is there is a
3551 key_matches_user_or_group (char *user)
3555 if (*user == '*' && user[1] == 0)
3556 return 1; /* A single asterisk matches all users. */
3558 group = strchr (user, ':');
3562 #ifdef HAVE_W32_SYSTEM
3563 /* Under Windows we don't support groups. */
3564 if (group && *group)
3565 gc_error (0, 0, _("Note that group specifications are ignored\n"));
3566 #ifndef HAVE_W32CE_SYSTEM
3569 static char *my_name;
3576 GetUserNameA (tmp, &size);
3577 my_name = xmalloc (size);
3578 if (!GetUserNameA (my_name, &size))
3579 gc_error (1,0, "error getting current user name: %s",
3583 if (!strcmp (user, my_name))
3584 return 1; /* Found. */
3586 #endif /*HAVE_W32CE_SYSTEM*/
3587 #else /*!HAVE_W32_SYSTEM*/
3588 /* First check whether the user matches. */
3591 static char *my_name;
3595 struct passwd *pw = getpwuid ( getuid () );
3597 gc_error (1, errno, "getpwuid failed for current user");
3598 my_name = xstrdup (pw->pw_name);
3600 if (!strcmp (user, my_name))
3601 return 1; /* Found. */
3604 /* If that failed, check whether a group matches. */
3605 if (group && *group)
3607 static char *my_group;
3608 static char **my_supgroups;
3613 struct group *gr = getgrgid ( getgid () );
3615 gc_error (1, errno, "getgrgid failed for current user");
3616 my_group = xstrdup (gr->gr_name);
3618 if (!strcmp (group, my_group))
3619 return 1; /* Found. */
3626 ngids = getgroups (0, NULL);
3627 gids = xcalloc (ngids+1, sizeof *gids);
3628 ngids = getgroups (ngids, gids);
3630 gc_error (1, errno, "getgroups failed for current user");
3631 my_supgroups = xcalloc (ngids+1, sizeof *my_supgroups);
3632 for (n=0; n < ngids; n++)
3634 struct group *gr = getgrgid ( gids[n] );
3636 gc_error (1, errno, "getgrgid failed for supplementary group");
3637 my_supgroups[n] = xstrdup (gr->gr_name);
3642 for (n=0; my_supgroups[n]; n++)
3643 if (!strcmp (group, my_supgroups[n]))
3644 return 1; /* Found. */
3646 #endif /*!HAVE_W32_SYSTEM*/
3647 return 0; /* No match. */
3652 /* Read and process the global configuration file for gpgconf. This
3653 optional file is used to update our internal tables at runtime and
3654 may also be used to set new default values. If FNAME is NULL the
3655 default name will be used. With UPDATE set to true the internal
3656 tables are actually updated; if not set, only a syntax check is
3657 done. If DEFAULTS is true the global options are written to the
3658 configuration files. If LISTFP is set, no changes are done but the
3659 configuration file is printed to LISTFP in a colon separated format.
3661 Returns 0 on success or if the config file is not present; -1 is
3662 returned on error. */
3664 gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
3669 size_t line_len = 0;
3671 gpgrt_stream_t config;
3675 int runtime[GC_BACKEND_NR];
3676 int backend_id, component_id;
3680 fname = xstrdup (fname_arg);
3682 fname = make_filename (gnupg_sysconfdir (), GPGCONF_NAME EXTSEP_S "conf",
3685 for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)
3686 runtime[backend_id] = 0;
3688 config = gpgrt_fopen (fname, "r");
3691 /* Do not print an error if the file is not available, except
3692 when running in syntax check mode. */
3693 if (errno != ENOENT || !update)
3695 gc_error (0, errno, "can not open global config file '%s'", fname);
3702 while ((length = gpgrt_read_line (config, &line, &line_len, NULL)) > 0)
3704 char *key, *component, *option, *flags, *value;
3706 gc_option_t *option_info = NULL;
3708 int is_continuation;
3712 while (*key == ' ' || *key == '\t')
3714 if (!*key || *key == '#' || *key == '\r' || *key == '\n')
3717 is_continuation = (key != line);
3719 /* Parse the key field. */
3720 if (!is_continuation && got_match)
3721 break; /* Finish after the first match. */
3722 else if (!is_continuation)
3725 for (p=key+1; *p && !strchr (" \t\r\n", *p); p++)
3729 gc_error (0, 0, "missing rule at '%s', line %d", fname, lineno);
3738 gc_error (0, 0, "continuation but no rule at '%s', line %d",
3751 /* Parse the component. */
3752 while (*component == ' ' || *component == '\t')
3754 for (p=component; *p && !strchr (" \t\r\n", *p); p++)
3758 gc_error (0, 0, "missing component at '%s', line %d",
3766 component_id = gc_component_find (component);
3767 if (component_id < 0)
3769 gc_error (0, 0, "unknown component at '%s', line %d",
3774 /* Parse the option name. */
3775 while (*option == ' ' || *option == '\t')
3777 for (p=option; *p && !strchr (" \t\r\n", *p); p++)
3781 gc_error (0, 0, "missing option at '%s', line %d",
3788 if ( component_id != -1)
3790 option_info = find_option (component_id, option, GC_BACKEND_ANY);
3793 gc_error (0, 0, "unknown option at '%s', line %d",
3800 /* Parse the optional flags. */
3801 while (*flags == ' ' || *flags == '\t')
3806 p = strchr (flags, ']');
3809 gc_error (0, 0, "syntax error in rule at '%s', line %d",
3817 else /* No flags given. */
3823 /* Parse the optional value. */
3824 while (*value == ' ' || *value == '\t')
3826 for (p=value; *p && !strchr ("\r\n", *p); p++)
3829 value = empty; /* No value given; let it point to an empty string. */
3832 /* Strip trailing white space. */
3834 for (p--; p > value && (*p == ' ' || *p == '\t'); p--)
3838 /* Check flag combinations. */
3841 else if (!strcmp (flags, "default"))
3845 gc_error (0, 0, "flag \"default\" may not be combined "
3846 "with a value at '%s', line %d",
3851 else if (!strcmp (flags, "change"))
3853 else if (!strcmp (flags, "no-change"))
3857 gc_error (0, 0, "unknown flag at '%s', line %d",
3862 /* In list mode we print out all records. */
3863 if (listfp && !result)
3865 /* If this is a new ruleset, print a key record. */
3866 if (!is_continuation)
3868 char *group = strchr (key, ':');
3872 if ((p = strchr (group, ':')))
3873 *p = 0; /* We better strip any extra stuff. */
3876 es_fprintf (listfp, "k:%s:", gc_percent_escape (key));
3877 es_fprintf (listfp, "%s\n", group? gc_percent_escape (group):"");
3880 /* All other lines are rule records. */
3881 es_fprintf (listfp, "r:::%s:%s:%s:",
3882 gc_component[component_id].name,
3883 option_info->name? option_info->name : "",
3886 es_fprintf (listfp, "\"%s", gc_percent_escape (value));
3888 es_putc ('\n', listfp);
3891 /* Check whether the key matches but do this only if we are not
3892 running in syntax check mode. */
3894 && !result && !listfp
3895 && (got_match || (key && key_matches_user_or_group (key))) )
3901 /* Apply the flags from gpgconf.conf. */
3904 else if (!strcmp (flags, "default"))
3905 newflags |= GC_OPT_FLAG_DEFAULT;
3906 else if (!strcmp (flags, "no-change"))
3907 option_info->flags |= GC_OPT_FLAG_NO_CHANGE;
3908 else if (!strcmp (flags, "change"))
3909 option_info->flags &= ~GC_OPT_FLAG_NO_CHANGE;
3913 /* Here we explicitly allow updating the value again. */
3916 option_info->new_flags = 0;
3920 xfree (option_info->new_value);
3921 option_info->new_value = NULL;
3923 change_one_value (option_info, runtime, newflags, value, 0);
3928 if (length < 0 || gpgrt_ferror (config))
3930 gc_error (0, errno, "error reading from '%s'", fname);
3933 if (gpgrt_fclose (config))
3934 gc_error (0, errno, "error closing '%s'", fname);
3938 /* If it all worked, process the options. */
3939 if (!result && update && defaults && !listfp)
3941 /* We need to switch off the runtime update, so that we can do
3942 it later all at once. */
3943 int save_opt_runtime = opt.runtime;
3946 for (component_id = 0; component_id < GC_COMPONENT_NR; component_id++)
3948 gc_component_change_options (component_id, NULL, NULL, 0);
3950 opt.runtime = save_opt_runtime;
3954 for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)
3955 if (runtime[backend_id] && gc_backend[backend_id].runtime_change)
3956 (*gc_backend[backend_id].runtime_change) (0);
3966 * Apply the profile FNAME to all known configure files.
3969 gc_apply_profile (const char *fname)
3972 char *fname_buffer = NULL;
3974 size_t line_len = 0;
3978 int runtime[GC_BACKEND_NR];
3980 int component_id = -1;
3981 int skip_section = 0;
3982 int error_count = 0;
3988 for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)
3989 runtime[backend_id] = 0;
3992 if (!(!strcmp (fname, "-")
3993 || strchr (fname, '/')
3994 #ifdef HAVE_W32_SYSTEM
3995 || strchr (fname, '\\')
3997 || strchr (fname, '.')))
3999 /* FNAME looks like a standard profile name. Check whether one
4000 * is installed and use that instead of the given file name. */
4001 fname_buffer = xstrconcat (gnupg_datadir (), DIRSEP_S,
4002 fname, ".prf", NULL);
4003 if (!access (fname_buffer, F_OK))
4004 fname = fname_buffer;
4007 fp = !strcmp (fname, "-")? es_stdin : es_fopen (fname, "r");
4010 err = gpg_error_from_syserror ();
4011 log_error ("can't open '%s': %s\n", fname, gpg_strerror (err));
4016 log_info ("applying profile '%s'\n", fname);
4019 while ((length = es_read_line (fp, &line, &line_len, NULL)) > 0)
4021 char *name, *flags, *value;
4022 gc_option_t *option_info = NULL;
4027 while (*name == ' ' || *name == '\t')
4029 if (!*name || *name == '#' || *name == '\r' || *name == '\n')
4031 trim_trailing_spaces (name);
4033 /* Check whether this is a new section. */
4038 /* New section: Get the name of the component. */
4039 p = strchr (name, ']');
4043 log_info ("%s:%d:%d: error: syntax error in section tag\n",
4044 fname, lineno, (int)(name - line));
4050 log_info ("%s:%d:%d: warning: garbage after section tag\n",
4051 fname, lineno, (int)(p - line));
4054 component_id = gc_component_find (name);
4055 if (component_id < 0)
4057 log_info ("%s:%d:%d: warning: skipping unknown section '%s'\n",
4058 fname, lineno, (int)(name - line), name );
4066 if (component_id < 0)
4069 log_info ("%s:%d:%d: error: not in a valid section\n",
4070 fname, lineno, (int)(name - line));
4075 /* Parse the option name. */
4076 for (p = name; *p && !spacep (p); p++)
4081 option_info = find_option (component_id, name, GC_BACKEND_ANY);
4085 log_info ("%s:%d:%d: error: unknown option '%s' in section '%s'\n",
4086 fname, lineno, (int)(name - line),
4087 name, gc_component[component_id].name);
4091 /* Parse the optional flags. */
4092 trim_spaces (value);
4097 p = strchr (flags, ']');
4100 log_info ("%s:%d:%d: warning: invalid flag specification\n",
4101 fname, lineno, (int)(p - line));
4106 trim_spaces (value);
4108 else /* No flags given. */
4111 /* Set required defaults. */
4112 if (gc_arg_type[option_info->arg_type].fallback == GC_ARG_TYPE_NONE
4116 /* Check and save this option. */
4118 if (flags && !strcmp (flags, "default"))
4119 newflags |= GC_OPT_FLAG_DEFAULT;
4122 option_info->new_flags = 0;
4125 xfree (option_info->new_value);
4126 option_info->new_value = NULL;
4128 change_one_value (option_info, runtime, newflags, value, 1);
4131 if (length < 0 || es_ferror (fp))
4133 err = gpg_error_from_syserror ();
4135 log_error (_("%s:%u: read error: %s\n"),
4136 fname, lineno, gpg_strerror (err));
4139 log_error (_("error closing '%s'\n"), fname);
4141 log_error (_("error parsing '%s'\n"), fname);
4145 /* If it all worked, process the options. */
4148 /* We need to switch off the runtime update, so that we can do
4149 it later all at once. */
4150 int save_opt_runtime = opt.runtime;
4153 for (component_id = 0; component_id < GC_COMPONENT_NR; component_id++)
4155 gc_component_change_options (component_id, NULL, NULL, 1);
4157 opt.runtime = save_opt_runtime;
4161 for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)
4162 if (runtime[backend_id] && gc_backend[backend_id].runtime_change)
4163 (*gc_backend[backend_id].runtime_change) (0);
4167 xfree (fname_buffer);