1 /* gpgconf-comp.c - Configuration utility for GnuPG.
2  * Copyright (C) 2004, 2007-2011 Free Software Foundation, Inc.
3  * Copyright (C) 2016 Werner Koch
4  * Copyright (C) 2020, 2021 g10 Code GmbH
5  *
6  * This file is part of GnuPG.
7  *
8  * GnuPG is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * GnuPG is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with GnuPG; if not, see <https://www.gnu.org/licenses/>.
20  * SPDX-License-Identifier: GPL-3.0-or-later
21  */
22 
23 #if HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31 #include <sys/types.h>
32 #include <errno.h>
33 #include <time.h>
34 #include <stdarg.h>
35 #ifdef HAVE_SIGNAL_H
36 # include <signal.h>
37 #endif
38 #include <ctype.h>
39 #ifdef HAVE_W32_SYSTEM
40 # define WIN32_LEAN_AND_MEAN 1
41 # include <windows.h>
42 #else
43 # include <pwd.h>
44 # include <grp.h>
45 #endif
46 
47 #include "../common/util.h"
48 #include "../common/i18n.h"
49 #include "../common/exechelp.h"
50 #include "../common/sysutils.h"
51 #include "../common/status.h"
52 
53 #include "../common/gc-opt-flags.h"
54 #include "gpgconf.h"
55 
56 
57 
58 
59 #if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ))
60 void gc_error (int status, int errnum, const char *fmt, ...) \
61   __attribute__ ((format (printf, 3, 4)));
62 #endif
63 
64 /* Output a diagnostic message.  If ERRNUM is not 0, then the output
65    is followed by a colon, a white space, and the error string for the
66    error number ERRNUM.  In any case the output is finished by a
67    newline.  The message is prepended by the program name, a colon,
68    and a whitespace.  The output may be further formatted or
69    redirected by the jnlib logging facility.  */
70 void
gc_error(int status,int errnum,const char * fmt,...)71 gc_error (int status, int errnum, const char *fmt, ...)
72 {
73   va_list arg_ptr;
74 
75   va_start (arg_ptr, fmt);
76   log_logv (GPGRT_LOGLVL_ERROR, fmt, arg_ptr);
77   va_end (arg_ptr);
78 
79   if (errnum)
80     log_printf (": %s\n", strerror (errnum));
81   else
82     log_printf ("\n");
83 
84   if (status)
85     {
86       log_printf (NULL);
87       log_printf ("fatal error (exit status %i)\n", status);
88       gpgconf_failure (gpg_error_from_errno (errnum));
89     }
90 }
91 
92 
93 /* Forward declaration.  */
94 static void gpg_agent_runtime_change (int killflag);
95 static void scdaemon_runtime_change (int killflag);
96 #ifdef BUILD_WITH_TPM2D
97 static void tpm2daemon_runtime_change (int killflag);
98 #endif
99 static void dirmngr_runtime_change (int killflag);
100 static void keyboxd_runtime_change (int killflag);
101 
102 
103 
104 /* STRING_ARRAY is a malloced array with malloced strings.  It is used
105  * a space to store strings so that other objects may point to these
106  * strings. It shall never be shrinked or any items changes.
107  * STRING_ARRAY itself may be reallocated to increase the size of the
108  * table.  STRING_ARRAY_USED is the number of items currently used,
109  * STRING_ARRAY_SIZE is the number of calloced slots. */
110 static char  **string_array;
111 static size_t string_array_used;
112 static size_t string_array_size;
113 
114 
115 
116 /* Option configuration.  */
117 
118 /* An option might take an argument, or not.  Argument types can be
119    basic or complex.  Basic types are generic and easy to validate.
120    Complex types provide more specific information about the intended
121    use, but can be difficult to validate.  If you add to this enum,
122    don't forget to update GC_ARG_TYPE below.  YOU MUST NOT CHANGE THE
123    NUMBERS OF THE EXISTING ENTRIES, AS THEY ARE PART OF THE EXTERNAL
124    INTERFACE.  */
125 typedef enum
126   {
127     /* Basic argument types.  */
128 
129     /* No argument.  */
130     GC_ARG_TYPE_NONE = 0,
131 
132     /* A String argument.  */
133     GC_ARG_TYPE_STRING = 1,
134 
135     /* A signed integer argument.  */
136     GC_ARG_TYPE_INT32 = 2,
137 
138     /* An unsigned integer argument.  */
139     GC_ARG_TYPE_UINT32 = 3,
140 
141     /* ADD NEW BASIC TYPE ENTRIES HERE.  */
142 
143     /* Complex argument types.  */
144 
145     /* A complete filename.  */
146     GC_ARG_TYPE_FILENAME = 32,
147 
148     /* An LDAP server in the format
149        HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN.  */
150     GC_ARG_TYPE_LDAP_SERVER = 33,
151 
152     /* A 40 character fingerprint.  */
153     GC_ARG_TYPE_KEY_FPR = 34,
154 
155     /* A user ID or key ID or fingerprint for a certificate.  */
156     GC_ARG_TYPE_PUB_KEY = 35,
157 
158     /* A user ID or key ID or fingerprint for a certificate with a key.  */
159     GC_ARG_TYPE_SEC_KEY = 36,
160 
161     /* A alias list made up of a key, an equal sign and a space
162        separated list of values.  */
163     GC_ARG_TYPE_ALIAS_LIST = 37,
164 
165     /* ADD NEW COMPLEX TYPE ENTRIES HERE.  */
166 
167     /* The number of the above entries.  */
168     GC_ARG_TYPE_NR
169   } gc_arg_type_t;
170 
171 
172 /* For every argument, we record some information about it in the
173    following struct.  */
174 static const struct
175 {
176   /* For every argument type exists a basic argument type that can be
177      used as a fallback for input and validation purposes.  */
178   gc_arg_type_t fallback;
179 
180   /* Human-readable name of the type.  */
181   const char *name;
182 } gc_arg_type[GC_ARG_TYPE_NR] =
183   {
184     /* The basic argument types have their own types as fallback.  */
185     { GC_ARG_TYPE_NONE, "none" },
186     { GC_ARG_TYPE_STRING, "string" },
187     { GC_ARG_TYPE_INT32, "int32" },
188     { GC_ARG_TYPE_UINT32, "uint32" },
189 
190     /* Reserved basic type entries for future extension.  */
191     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
192     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
193     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
194     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
195     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
196     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
197     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
198     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
199     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
200     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
201     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
202     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
203     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
204     { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL },
205 
206     /* The complex argument types have a basic type as fallback.  */
207     { GC_ARG_TYPE_STRING, "filename" },
208     { GC_ARG_TYPE_STRING, "ldap server" },
209     { GC_ARG_TYPE_STRING, "key fpr" },
210     { GC_ARG_TYPE_STRING, "pub key" },
211     { GC_ARG_TYPE_STRING, "sec key" },
212     { GC_ARG_TYPE_STRING, "alias list" },
213   };
214 
215 
216 /* Every option has an associated expert level, than can be used to
217    hide advanced and expert options from beginners.  If you add to
218    this list, don't forget to update GC_LEVEL below.  YOU MUST NOT
219    CHANGE THE NUMBERS OF THE EXISTING ENTRIES, AS THEY ARE PART OF THE
220    EXTERNAL INTERFACE.  */
221 typedef enum
222   {
223     /* The basic options should always be displayed.  */
224     GC_LEVEL_BASIC,
225 
226     /* The advanced options may be hidden from beginners.  */
227     GC_LEVEL_ADVANCED,
228 
229     /* The expert options should only be displayed to experts.  */
230     GC_LEVEL_EXPERT,
231 
232     /* The invisible options should normally never be displayed.  */
233     GC_LEVEL_INVISIBLE,
234 
235     /* The internal options are never exported, they mark options that
236        are recorded for internal use only.  */
237     GC_LEVEL_INTERNAL,
238 
239     /* ADD NEW ENTRIES HERE.  */
240 
241     /* The number of the above entries.  */
242     GC_LEVEL_NR
243   } gc_expert_level_t;
244 
245 /* A description for each expert level.  */
246 static const struct
247 {
248   const char *name;
249 } gc_level[] =
250   {
251     { "basic" },
252     { "advanced" },
253     { "expert" },
254     { "invisible" },
255     { "internal" }
256   };
257 
258 
259 /* Option flags.  The flags which are used by the components are defined
260    by gc-opt-flags.h, included above.
261 
262    YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING FLAGS, AS THEY ARE
263    PART OF THE EXTERNAL INTERFACE.  */
264 
265 /* Some entries in the emitted option list are not options, but mark
266    the beginning of a new group of options.  These entries have the
267    GROUP flag set.  Note that this is internally also known as a
268    header line. */
269 #define GC_OPT_FLAG_GROUP	(1UL << 0)
270 /* The ARG_OPT flag for an option indicates that the argument is
271    optional.  This is never set for GC_ARG_TYPE_NONE options.  */
272 #define GC_OPT_FLAG_ARG_OPT	(1UL << 1)
273 /* The LIST flag for an option indicates that the option can occur
274    several times.  A comma separated list of arguments is used as the
275    argument value.  */
276 #define GC_OPT_FLAG_LIST	(1UL << 2)
277 /* The RUNTIME flag for an option indicates that the option can be
278    changed at runtime.  */
279 #define GC_OPT_FLAG_RUNTIME	(1UL << 3)
280 
281 
282 /* A human-readable description for each flag.  */
283 static const struct
284 {
285   const char *name;
286 } gc_flag[] =
287   {
288     { "group" },
289     { "optional arg" },
290     { "list" },
291     { "runtime" },
292     { "default" },
293     { "default desc" },
294     { "no arg desc" },
295     { "no change" }
296   };
297 
298 
299 
300 /* Each option we want to support in gpgconf has the needed
301  * information in a static list per componenet.  This struct describes
302  * the info for a single option.  */
303 struct known_option_s
304 {
305   /* If this is NULL, then this is a terminator in an array of unknown
306    * length.  Otherwise it is the name of the option described by this
307    * entry.  The name must not contain a colon.  */
308   const char *name;
309 
310   /* The option flags.  */
311   unsigned long flags;
312 
313   /* The expert level.  */
314   gc_expert_level_t level;
315 
316   /* The complex type of the option argument; the default of 0 is used
317    * for a standard type as returned by --dump-option-table.  */
318   gc_arg_type_t arg_type;
319 };
320 typedef struct known_option_s known_option_t;
321 
322 
323 /* The known options of the GC_COMPONENT_GPG_AGENT component.  */
324 static known_option_t known_options_gpg_agent[] =
325   {
326    { "verbose", GC_OPT_FLAG_LIST|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC },
327    { "quiet", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC },
328    { "disable-scdaemon", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED },
329    { "enable-ssh-support", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
330    { "ssh-fingerprint-digest", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT },
331    { "enable-putty-support", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
332    { "enable-extended-key-format", GC_OPT_FLAG_RUNTIME, GC_LEVEL_INVISIBLE },
333    { "debug-level", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED},
334    { "log-file", GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED,
335      /**/        GC_ARG_TYPE_FILENAME },
336    { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE },
337 
338    { "default-cache-ttl", GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC },
339    { "default-cache-ttl-ssh", GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED },
340    { "max-cache-ttl", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT },
341    { "max-cache-ttl-ssh", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT },
342    { "ignore-cache-for-signing", GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC },
343    { "allow-emacs-pinentry", GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED },
344    { "grab", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT },
345    { "no-allow-external-cache", GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC },
346    { "no-allow-mark-trusted", GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED },
347    { "no-allow-loopback-pinentry", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT },
348 
349    { "enforce-passphrase-constraints", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT },
350    { "min-passphrase-len", GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED },
351    { "min-passphrase-nonalpha", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT },
352    { "check-passphrase-pattern", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT,
353      /**/                        GC_ARG_TYPE_FILENAME },
354    { "check-sym-passphrase-pattern", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT,
355      /**/                        GC_ARG_TYPE_FILENAME },
356    { "max-passphrase-days", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT },
357    { "enable-passphrase-history", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT },
358    { "pinentry-timeout", GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED },
359 
360    { NULL }
361  };
362 
363 
364 /* The known options of the GC_COMPONENT_SCDAEMON component.  */
365 static known_option_t known_options_scdaemon[] =
366   {
367    { "verbose", GC_OPT_FLAG_LIST|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC },
368    { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
369    { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE },
370    { "reader-port",  GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC },
371    { "ctapi-driver", GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED },
372    { "pcsc-driver",  GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED },
373    { "disable-ccid", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT },
374    { "disable-pinpad", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC },
375    { "enable-pinpad-varlen", GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC },
376    { "card-timeout",         GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC },
377    { "application-priority", GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED },
378    { "debug-level", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED},
379    { "log-file",    GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED,
380      GC_ARG_TYPE_FILENAME },
381    { "deny-admin",  GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC },
382 
383    { NULL }
384  };
385 
386 #ifdef BUILD_WITH_TPM2D
387 /* The known options of the GC_COMPONENT_TPM2DAEMON component.  */
388 static known_option_t known_options_tpm2daemon[] =
389   {
390    { "verbose", GC_OPT_FLAG_LIST|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC },
391    { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
392    { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE },
393    { "debug-level", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED},
394    { "log-file",    GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED,
395      GC_ARG_TYPE_FILENAME },
396    { "deny-admin",  GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC },
397    { "parent",  GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED },
398 
399    { NULL }
400  };
401 #endif
402 
403 
404 /* The known options of the GC_COMPONENT_GPG component.  */
405 static known_option_t known_options_gpg[] =
406   {
407    { "verbose",              GC_OPT_FLAG_LIST, GC_LEVEL_BASIC },
408    { "quiet",                GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
409    { "no-greeting",          GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE },
410    { "default-key",          GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
411    { "encrypt-to",           GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
412    { "group",                GC_OPT_FLAG_LIST, GC_LEVEL_ADVANCED,
413      GC_ARG_TYPE_ALIAS_LIST},
414    { "compliance",           GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT },
415    { "default-new-key-algo", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE },
416    { "trust-model",          GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE },
417    { "debug-level",          GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED },
418    { "log-file",             GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
419      GC_ARG_TYPE_FILENAME },
420    { "auto-key-locate",      GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED },
421    { "auto-key-import",      GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
422    { "auto-key-retrieve",    GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT },
423    { "include-key-block",    GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
424    { "disable-dirmngr",      GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT },
425    { "max-cert-depth",       GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE },
426    { "completes-needed",     GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE },
427    { "marginals-needed",     GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE },
428 
429    /* The next items are pseudo options which we read via --gpgconf-list.
430     * The meta information is taken from the table below.  */
431    { "default_pubkey_algo",  GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE },
432    { "compliance_de_vs",     GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE },
433    { "use_keyboxd",          GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE },
434 
435    { NULL }
436  };
437 static const char *known_pseudo_options_gpg[] =
438   {/*                     v-- ARGPARSE_TYPE_STRING */
439    "default_pubkey_algo:0:2:@:",
440    /* A basic compliance check for gpg.  We use gpg here but the
441     * result is valid for all components.
442     *                  v-- ARGPARSE_TYPE_INT */
443    "compliance_de_vs:0:1:@:",
444    /* True is use_keyboxd is enabled.  That option can be set in
445     * common.conf but is not direcly supported by gpgconf.  Thus we
446     * only allow to read it out.
447     *                  v-- ARGPARSE_TYPE_INT */
448    "use_keyboxd:0:1:@:",
449    NULL
450  };
451 
452 
453 /* The known options of the GC_COMPONENT_GPGSM component.  */
454 static known_option_t known_options_gpgsm[] =
455  {
456    { "verbose",           GC_OPT_FLAG_LIST, GC_LEVEL_BASIC },
457    { "quiet",             GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
458    { "no-greeting",       GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE },
459    { "default-key",       GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
460    { "encrypt-to",        GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
461    { "disable-dirmngr",   GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT },
462    { "p12-charset",       GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED },
463    { "keyserver",         GC_OPT_FLAG_LIST, GC_LEVEL_BASIC,
464                           GC_ARG_TYPE_LDAP_SERVER },
465    { "compliance",        GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT },
466    { "debug-level",       GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED },
467    { "log-file",          GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
468                           GC_ARG_TYPE_FILENAME },
469    { "faked-system-time",              GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE },
470    { "disable-crl-checks",             GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
471    { "enable-crl-checks",              GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE },
472    { "enable-ocsp",                    GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED },
473    { "include-certs",                  GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT },
474    { "disable-policy-checks",          GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED },
475    { "auto-issuer-key-retrieve",       GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
476    { "cipher-algo",                    GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED },
477    { "disable-trusted-cert-crl-check", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT },
478 
479    /* Pseudo option follows.  See also table below. */
480    { "default_pubkey_algo",            GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE },
481 
482    { NULL }
483  };
484 static const char *known_pseudo_options_gpgsm[] =
485   {/*                     v-- ARGPARSE_TYPE_STRING */
486    "default_pubkey_algo:0:2:@:",
487    NULL
488  };
489 
490 
491 /* The known options of the GC_COMPONENT_DIRMNGR component.  */
492 static known_option_t known_options_dirmngr[] =
493  {
494    { "verbose",           GC_OPT_FLAG_LIST, GC_LEVEL_BASIC },
495    { "quiet",             GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
496    { "no-greeting",       GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE },
497    { "resolver-timeout",  GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE },
498    { "nameserver",        GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE },
499    { "debug-level",       GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED },
500    { "log-file",          GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
501                           GC_ARG_TYPE_FILENAME },
502    { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE },
503    { "batch",             GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
504    { "force",             GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
505    { "use-tor",           GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
506    { "keyserver",         GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
507    { "disable-http",      GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED },
508    { "ignore-http-dp",    GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED },
509    { "http-proxy",        GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED },
510    { "honor-http-proxy",  GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED },
511    { "disable-ldap",      GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED },
512    { "ignore-ldap-dp",    GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED },
513    { "ldap-proxy",        GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
514    { "only-ldap-proxy",   GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED },
515    { "add-servers",       GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT },
516    { "ldaptimeout",       GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
517    { "max-replies",       GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
518    { "allow-ocsp",        GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
519    { "ocsp-responder",    GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED },
520    { "ocsp-signer",       GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED },
521    { "allow-version-check",     GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
522    { "ignore-ocsp-service-url", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED },
523 
524 
525    { NULL }
526  };
527 
528 /* The known options of the GC_COMPONENT_KEYBOXD component.  */
529 static known_option_t known_options_keyboxd[] =
530  {
531    { "verbose",           GC_OPT_FLAG_LIST, GC_LEVEL_BASIC },
532    { "quiet",             GC_OPT_FLAG_NONE, GC_LEVEL_BASIC },
533    { "log-file",          GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
534                           GC_ARG_TYPE_FILENAME },
535    { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE },
536 
537    { NULL }
538  };
539 
540 
541 /* The known options of the GC_COMPONENT_PINENTRY component.  */
542 static known_option_t known_options_pinentry[] =
543  {
544   { NULL }
545  };
546 
547 
548 
549 /* Our main option info object.  We copy all required information from the
550  * gpgrt_opt_t items but convert the flags value to bit flags.  */
551 struct gc_option_s
552 {
553   const char *name;            /* The same as gpgrt_opt_t.long_opt.     */
554   const char *desc;            /* The same as gpgrt_opt_t.description.  */
555 
556   unsigned int is_header:1;    /* This is a header item.   */
557   unsigned int is_list:1;      /* This is a list style option.  */
558   unsigned int opt_arg:1;      /* The option's argument is optional.    */
559   unsigned int runtime:1;      /* The option is runtime changeable.  */
560 
561   unsigned int gpgconf_list:1; /* Mentioned by --gpgconf-list.  */
562 
563   unsigned int has_default:1;  /* The option has a default value.  */
564   unsigned int def_in_desc:1;  /* The default is in the descrition.  */
565   unsigned int no_arg_desc:1;  /* The argument has a default  ???.  */
566   unsigned int no_change:1;    /* User shall not change the option.   */
567 
568   unsigned int attr_ignore:1;  /* The ARGPARSE_ATTR_IGNORE.  */
569   unsigned int attr_force:1;   /* The ARGPARSE_ATTR_FORCE.  */
570 
571   /* The expert level - copied from known_options.  */
572   gc_expert_level_t level;
573 
574   /* The complex type - copied from known_options.  */
575   gc_arg_type_t arg_type;
576 
577   /* The default value for this option.  This is NULL if the option is
578      not present in the component, the empty string if no default is
579      available, and otherwise a quoted string.  This is currently
580      malloced.*/
581   char *default_value;
582 
583   /* The current value of this option. */
584   char *value;
585 
586   /* The new flags for this option.  The only defined flag is actually
587      GC_OPT_FLAG_DEFAULT, and it means that the option should be
588      deleted.  In this case, NEW_VALUE is NULL.  */
589   unsigned long new_flags;
590 
591   /* The new value of this option.  */
592   char *new_value;
593 };
594 typedef struct gc_option_s gc_option_t;
595 
596 
597 
598 /* The information associated with each component.  */
599 static struct
600 {
601   /* The name of the component.  Some components don't have an
602    * associated program, but are implemented directly by GPGConf.  In
603    * this case, PROGRAM is NULL.  */
604   char *program;
605 
606   /* The displayed name of this component.  Must not contain a colon
607    * (':') character.  */
608   const char *name;
609 
610   /* The gettext domain for the description DESC.  If this is NULL,
611      then the description is not translated.  */
612   const char *desc_domain;
613 
614   /* The description of this component.  */
615   const char *desc;
616 
617   /* The module name (GNUPG_MODULE_NAME_foo) as defined by
618    * ../common/util.h.  This value is used to get the actual installed
619    * path of the program.  0 is used if no program for the component
620    * is available. */
621   char module_name;
622 
623   /* The name for the configuration filename of this component.  */
624   const char *option_config_filename;
625 
626   /* The static table of known options for this component.  */
627   known_option_t *known_options;
628 
629   /* The static table of known pseudo options for this component or NULL.  */
630   const char **known_pseudo_options;
631 
632   /* The runtime change callback.  If KILLFLAG is true the component
633      is killed and not just reloaded.  */
634   void (*runtime_change) (int killflag);
635 
636   /* The table of known options as read from the component including
637    * header lines and such.  This is suitable to be passed to
638    * gpgrt_argparser.  Will be filled in by
639    * retrieve_options_from_program. */
640   gpgrt_opt_t *opt_table;
641 
642   /* The full table including data from OPT_TABLE.  The end of the
643    * table is marked by NULL entry for NAME.  Will be filled in by
644    * retrieve_options_from_program.  */
645   gc_option_t *options;
646 
647 } gc_component[GC_COMPONENT_NR] =
648   {
649    /* Note: The order of the items must match the order given in the
650     * gc_component_id_t enumeration.  The order is often used by
651     * frontends to display the backend options thus do not change the
652     * order without considering the user experience.  */
653    { NULL },   /* DUMMY for GC_COMPONENT_ANY */
654 
655    { GPG_NAME,  GPG_DISP_NAME,     "gnupg",  N_("OpenPGP"),
656      GNUPG_MODULE_NAME_GPG, GPG_NAME ".conf",
657      known_options_gpg, known_pseudo_options_gpg },
658 
659    { GPGSM_NAME, GPGSM_DISP_NAME,  "gnupg",  N_("S/MIME"),
660      GNUPG_MODULE_NAME_GPGSM, GPGSM_NAME ".conf",
661      known_options_gpgsm, known_pseudo_options_gpgsm },
662 
663    { KEYBOXD_NAME, KEYBOXD_DISP_NAME, "gnupg", N_("Public Keys"),
664      GNUPG_MODULE_NAME_KEYBOXD, KEYBOXD_NAME ".conf",
665      known_options_keyboxd, NULL, keyboxd_runtime_change },
666 
667    { GPG_AGENT_NAME, GPG_AGENT_DISP_NAME, "gnupg", N_("Private Keys"),
668      GNUPG_MODULE_NAME_AGENT, GPG_AGENT_NAME ".conf",
669      known_options_gpg_agent, NULL, gpg_agent_runtime_change },
670 
671    { SCDAEMON_NAME, SCDAEMON_DISP_NAME, "gnupg", N_("Smartcards"),
672      GNUPG_MODULE_NAME_SCDAEMON, SCDAEMON_NAME ".conf",
673      known_options_scdaemon, NULL, scdaemon_runtime_change},
674 
675 #ifdef BUILD_WITH_TPM2D
676    { TPM2DAEMON_NAME, TPM2DAEMON_DISP_NAME, "gnupg", N_("TPM"),
677      GNUPG_MODULE_NAME_TPM2DAEMON, TPM2DAEMON_NAME ".conf",
678      known_options_tpm2daemon, NULL, tpm2daemon_runtime_change},
679 #else
680      { NULL }, /* Another dummy, to keep the enum in sync with this table */
681 #endif
682 
683    { DIRMNGR_NAME, DIRMNGR_DISP_NAME, "gnupg",   N_("Network"),
684      GNUPG_MODULE_NAME_DIRMNGR, DIRMNGR_NAME ".conf",
685      known_options_dirmngr, NULL, dirmngr_runtime_change },
686 
687    { "pinentry", "Pinentry", "gnupg", N_("Passphrase Entry"),
688      GNUPG_MODULE_NAME_PINENTRY, NULL,
689      known_options_pinentry }
690   };
691 
692 
693 
694 /* Structure used to collect error output of the component programs.  */
695 struct error_line_s;
696 typedef struct error_line_s *error_line_t;
697 struct error_line_s
698 {
699   error_line_t next;   /* Link to next item.  */
700   const char *fname;   /* Name of the config file (points into BUFFER).  */
701   unsigned int lineno; /* Line number of the config file.  */
702   const char *errtext; /* Text of the error message (points into BUFFER).  */
703   char buffer[1];  /* Helper buffer.  */
704 };
705 
706 
707 
708 
709 /* Initialization and finalization.  */
710 
711 static void
gc_option_free(gc_option_t * o)712 gc_option_free (gc_option_t *o)
713 {
714   if (o == NULL || o->name == NULL)
715     return;
716 
717   xfree (o->value);
718   gc_option_free (o + 1);
719 }
720 
721 static void
gc_components_free(void)722 gc_components_free (void)
723 {
724   int i;
725   for (i = 0; i < DIM (gc_component); i++)
726     gc_option_free (gc_component[i].options);
727 }
728 
729 void
gc_components_init(void)730 gc_components_init (void)
731 {
732   atexit (gc_components_free);
733 }
734 
735 
736 
737 /* Engine specific support.  */
738 static void
gpg_agent_runtime_change(int killflag)739 gpg_agent_runtime_change (int killflag)
740 {
741   gpg_error_t err = 0;
742   const char *pgmname;
743   const char *argv[5];
744   pid_t pid = (pid_t)(-1);
745   int i = 0;
746   int cmdidx;
747 
748   pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
749   if (!gnupg_default_homedir_p ())
750     {
751       argv[i++] = "--homedir";
752       argv[i++] = gnupg_homedir ();
753     }
754   argv[i++] = "--no-autostart";
755   cmdidx = i;
756   argv[i++] = killflag? "KILLAGENT" : "RELOADAGENT";
757   argv[i] = NULL;
758   log_assert (i < DIM(argv));
759 
760   if (!err)
761     err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
762   if (!err)
763     err = gnupg_wait_process (pgmname, pid, 1, NULL);
764   if (err)
765     gc_error (0, 0, "error running '%s %s': %s",
766               pgmname, argv[cmdidx], gpg_strerror (err));
767   gnupg_release_process (pid);
768 }
769 
770 
771 static void
scdaemon_runtime_change(int killflag)772 scdaemon_runtime_change (int killflag)
773 {
774   gpg_error_t err = 0;
775   const char *pgmname;
776   const char *argv[9];
777   pid_t pid = (pid_t)(-1);
778   int i = 0;
779   int cmdidx;
780 
781   (void)killflag;  /* For scdaemon kill and reload are synonyms.  */
782 
783   /* We use "GETINFO app_running" to see whether the agent is already
784      running and kill it only in this case.  This avoids an explicit
785      starting of the agent in case it is not yet running.  There is
786      obviously a race condition but that should not harm too much.  */
787 
788   pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
789   if (!gnupg_default_homedir_p ())
790     {
791       argv[i++] = "--homedir";
792       argv[i++] = gnupg_homedir ();
793     }
794   argv[i++] = "-s";
795   argv[i++] = "--no-autostart";
796   argv[i++] = "GETINFO scd_running";
797   argv[i++] = "/if ${! $?}";
798   cmdidx = i;
799   argv[i++] = "scd killscd";
800   argv[i++] = "/end";
801   argv[i] = NULL;
802   log_assert (i < DIM(argv));
803 
804   if (!err)
805     err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
806   if (!err)
807     err = gnupg_wait_process (pgmname, pid, 1, NULL);
808   if (err)
809     gc_error (0, 0, "error running '%s %s': %s",
810               pgmname, argv[cmdidx], gpg_strerror (err));
811   gnupg_release_process (pid);
812 }
813 
814 
815 #ifdef BUILD_WITH_TPM2D
816 static void
tpm2daemon_runtime_change(int killflag)817 tpm2daemon_runtime_change (int killflag)
818 {
819   gpg_error_t err = 0;
820   const char *pgmname;
821   const char *argv[9];
822   pid_t pid = (pid_t)(-1);
823   int i = 0;
824   int cmdidx;
825 
826   (void)killflag;  /* For scdaemon kill and reload are synonyms.  */
827 
828   /* We use "GETINFO app_running" to see whether the agent is already
829      running and kill it only in this case.  This avoids an explicit
830      starting of the agent in case it is not yet running.  There is
831      obviously a race condition but that should not harm too much.  */
832 
833   pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
834   if (!gnupg_default_homedir_p ())
835     {
836       argv[i++] = "--homedir";
837       argv[i++] = gnupg_homedir ();
838     }
839   argv[i++] = "-s";
840   argv[i++] = "--no-autostart";
841   argv[i++] = "GETINFO tpm2d_running";
842   argv[i++] = "/if ${! $?}";
843   cmdidx = i;
844   argv[i++] = "scd killtpm2cd";
845   argv[i++] = "/end";
846   argv[i] = NULL;
847   log_assert (i < DIM(argv));
848 
849   if (!err)
850     err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
851   if (!err)
852     err = gnupg_wait_process (pgmname, pid, 1, NULL);
853   if (err)
854     gc_error (0, 0, "error running '%s %s': %s",
855               pgmname, argv[cmdidx], gpg_strerror (err));
856   gnupg_release_process (pid);
857 }
858 #endif
859 
860 
861 static void
dirmngr_runtime_change(int killflag)862 dirmngr_runtime_change (int killflag)
863 {
864   gpg_error_t err = 0;
865   const char *pgmname;
866   const char *argv[6];
867   pid_t pid = (pid_t)(-1);
868   int i = 0;
869   int cmdidx;
870 
871   pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
872   if (!gnupg_default_homedir_p ())
873     {
874       argv[i++] = "--homedir";
875       argv[i++] = gnupg_homedir ();
876     }
877   argv[i++] = "--no-autostart";
878   argv[i++] = "--dirmngr";
879   cmdidx = i;
880   argv[i++] = killflag? "KILLDIRMNGR" : "RELOADDIRMNGR";
881   argv[i] = NULL;
882   log_assert (i < DIM(argv));
883 
884   if (!err)
885     err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
886   if (!err)
887     err = gnupg_wait_process (pgmname, pid, 1, NULL);
888   if (err)
889     gc_error (0, 0, "error running '%s %s': %s",
890               pgmname, argv[cmdidx], gpg_strerror (err));
891   gnupg_release_process (pid);
892 }
893 
894 
895 static void
keyboxd_runtime_change(int killflag)896 keyboxd_runtime_change (int killflag)
897 {
898   gpg_error_t err = 0;
899   const char *pgmname;
900   const char *argv[6];
901   pid_t pid = (pid_t)(-1);
902   int i = 0;
903   int cmdidx;
904 
905   pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
906   argv[i++] = "--no-autostart";
907   argv[i++] = "--keyboxd";
908   cmdidx = i;
909   argv[i++] = killflag? "KILLKEYBOXD" : "RELOADKEYBOXD";
910   if (!gnupg_default_homedir_p ())
911     {
912       argv[i++] = "--homedir";
913       argv[i++] = gnupg_homedir ();
914     }
915   argv[i] = NULL;
916   log_assert (i < DIM(argv));
917 
918   if (!err)
919     err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
920   if (!err)
921     err = gnupg_wait_process (pgmname, pid, 1, NULL);
922   if (err)
923     gc_error (0, 0, "error running '%s %s': %s",
924               pgmname, argv[cmdidx], gpg_strerror (err));
925   gnupg_release_process (pid);
926 }
927 
928 
929 /* Launch the gpg-agent or the dirmngr if not already running.  */
930 gpg_error_t
gc_component_launch(int component)931 gc_component_launch (int component)
932 {
933   gpg_error_t err;
934   const char *pgmname;
935   const char *argv[6];
936   int i;
937   pid_t pid;
938 
939   if (component < 0)
940     {
941       err = gc_component_launch (GC_COMPONENT_GPG_AGENT);
942       if (!err)
943         err = gc_component_launch (GC_COMPONENT_KEYBOXD);
944       if (!err)
945         err = gc_component_launch (GC_COMPONENT_DIRMNGR);
946       return err;
947     }
948 
949   if (!(component == GC_COMPONENT_GPG_AGENT
950         || component == GC_COMPONENT_KEYBOXD
951         || component == GC_COMPONENT_DIRMNGR))
952     {
953       log_error ("%s\n", _("Component not suitable for launching"));
954       gpgconf_failure (0);
955     }
956 
957   if (gc_component_check_options (component, NULL, NULL))
958     {
959       log_error (_("Configuration file of component %s is broken\n"),
960                  gc_component[component].name);
961       if (!opt.quiet)
962         log_info (_("Note: Use the command \"%s%s\" to get details.\n"),
963                   gc_component[component].program
964                   ? gc_component[component].program
965                   : gc_component[component].name,
966                   " --gpgconf-test");
967       gpgconf_failure (0);
968     }
969 
970   pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
971   i = 0;
972   if (!gnupg_default_homedir_p ())
973     {
974       argv[i++] = "--homedir";
975       argv[i++] = gnupg_homedir ();
976     }
977   if (component == GC_COMPONENT_DIRMNGR)
978     argv[i++] = "--dirmngr";
979   else if (component == GC_COMPONENT_KEYBOXD)
980     argv[i++] = "--keyboxd";
981   argv[i++] = "NOP";
982   argv[i] = NULL;
983   log_assert (i < DIM(argv));
984 
985   err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
986   if (!err)
987     err = gnupg_wait_process (pgmname, pid, 1, NULL);
988   if (err)
989     gc_error (0, 0, "error running '%s%s%s': %s",
990               pgmname,
991               component == GC_COMPONENT_DIRMNGR? " --dirmngr"
992               : component == GC_COMPONENT_KEYBOXD? " --keyboxd":"",
993               " NOP",
994               gpg_strerror (err));
995   gnupg_release_process (pid);
996   return err;
997 }
998 
999 
1000 static void
do_runtime_change(int component,int killflag)1001 do_runtime_change (int component, int killflag)
1002 {
1003   int runtime[GC_COMPONENT_NR] =  { 0 };
1004 
1005   if (component < 0)
1006     {
1007       for (component = 0; component < GC_COMPONENT_NR; component++)
1008         runtime [component] = 1;
1009     }
1010   else
1011     {
1012       log_assert (component >= 0 && component < GC_COMPONENT_NR);
1013       runtime [component] = 1;
1014     }
1015 
1016   /* Do the restart for the selected components.  */
1017   for (component = GC_COMPONENT_NR-1; component >= 0; component--)
1018     {
1019       if (runtime[component] && gc_component[component].runtime_change)
1020         (*gc_component[component].runtime_change) (killflag);
1021     }
1022 }
1023 
1024 
1025 /* Unconditionally restart COMPONENT.  */
1026 void
gc_component_kill(int component)1027 gc_component_kill (int component)
1028 {
1029   do_runtime_change (component, 1);
1030 }
1031 
1032 
1033 /* Unconditionally reload COMPONENT or all components if COMPONENT is -1.  */
1034 void
gc_component_reload(int component)1035 gc_component_reload (int component)
1036 {
1037   do_runtime_change (component, 0);
1038 }
1039 
1040 
1041 
1042 /* More or less Robust version of dgettext.  It has the side effect of
1043    switching the codeset to utf-8 because this is what we want to
1044    output.  In theory it is possible to keep the original code set and
1045    switch back for regular diagnostic output (redefine "_(" for that)
1046    but given the nature of this tool, being something invoked from
1047    other programs, it does not make much sense.  */
1048 static const char *
my_dgettext(const char * domain,const char * msgid)1049 my_dgettext (const char *domain, const char *msgid)
1050 {
1051   if (!msgid || !*msgid)
1052     return msgid;  /* Shortcut form "" which has the PO files meta data.  */
1053 
1054 #ifdef USE_SIMPLE_GETTEXT
1055   if (domain)
1056     {
1057       static int switched_codeset;
1058       char *text;
1059 
1060       if (!switched_codeset)
1061         {
1062           switched_codeset = 1;
1063           gettext_use_utf8 (1);
1064         }
1065 
1066       if (!strcmp (domain, "gnupg"))
1067         domain = PACKAGE_GT;
1068 
1069       /* FIXME: we have no dgettext, thus we can't switch.  */
1070 
1071       text = (char*)gettext (msgid);
1072       return text ? text : msgid;
1073     }
1074   else
1075     return msgid;
1076 #elif defined(ENABLE_NLS)
1077   if (domain)
1078     {
1079       static int switched_codeset;
1080       char *text;
1081 
1082       if (!switched_codeset)
1083         {
1084           switched_codeset = 1;
1085           bind_textdomain_codeset (PACKAGE_GT, "utf-8");
1086 
1087           bindtextdomain (DIRMNGR_NAME, gnupg_localedir ());
1088           bind_textdomain_codeset (DIRMNGR_NAME, "utf-8");
1089 
1090         }
1091 
1092       /* Note: This is a hack to actually use the gnupg2 domain as
1093          long we are in a transition phase where gnupg 1.x and 1.9 may
1094          coexist. */
1095       if (!strcmp (domain, "gnupg"))
1096         domain = PACKAGE_GT;
1097 
1098       text = dgettext (domain, msgid);
1099       return text ? text : msgid;
1100     }
1101   else
1102     return msgid;
1103 #else
1104   (void)domain;
1105   return msgid;
1106 #endif
1107 }
1108 
1109 
1110 /* Percent-Escape special characters.  The string is valid until the
1111    next invocation of the function.  */
1112 char *
gc_percent_escape(const char * src)1113 gc_percent_escape (const char *src)
1114 {
1115   static char *esc_str;
1116   static int esc_str_len;
1117   int new_len = 3 * strlen (src) + 1;
1118   char *dst;
1119 
1120   if (esc_str_len < new_len)
1121     {
1122       char *new_esc_str = xrealloc (esc_str, new_len);
1123       esc_str = new_esc_str;
1124       esc_str_len = new_len;
1125     }
1126 
1127   dst = esc_str;
1128   while (*src)
1129     {
1130       if (*src == '%')
1131 	{
1132 	  *(dst++) = '%';
1133 	  *(dst++) = '2';
1134 	  *(dst++) = '5';
1135 	}
1136       else if (*src == ':')
1137 	{
1138 	  /* The colon is used as field separator.  */
1139 	  *(dst++) = '%';
1140 	  *(dst++) = '3';
1141 	  *(dst++) = 'a';
1142 	}
1143       else if (*src == ',')
1144 	{
1145 	  /* The comma is used as list separator.  */
1146 	  *(dst++) = '%';
1147 	  *(dst++) = '2';
1148 	  *(dst++) = 'c';
1149 	}
1150       else if (*src == '\n')
1151 	{
1152 	  /* The newline is problematic in a line-based format.  */
1153 	  *(dst++) = '%';
1154 	  *(dst++) = '0';
1155 	  *(dst++) = 'a';
1156 	}
1157       else
1158 	*(dst++) = *(src);
1159       src++;
1160     }
1161   *dst = '\0';
1162   return esc_str;
1163 }
1164 
1165 
1166 
1167 /* Percent-Deescape special characters.  The string is valid until the
1168    next invocation of the function.  */
1169 static char *
percent_deescape(const char * src)1170 percent_deescape (const char *src)
1171 {
1172   static char *str;
1173   static int str_len;
1174   int new_len = 3 * strlen (src) + 1;
1175   char *dst;
1176 
1177   if (str_len < new_len)
1178     {
1179       char *new_str = xrealloc (str, new_len);
1180       str = new_str;
1181       str_len = new_len;
1182     }
1183 
1184   dst = str;
1185   while (*src)
1186     {
1187       if (*src == '%')
1188 	{
1189 	  int val = hextobyte (src + 1);
1190 
1191 	  if (val < 0)
1192 	    gc_error (1, 0, "malformed end of string %s", src);
1193 
1194 	  *(dst++) = (char) val;
1195 	  src += 3;
1196 	}
1197       else
1198 	*(dst++) = *(src++);
1199     }
1200   *dst = '\0';
1201   return str;
1202 }
1203 
1204 
1205 /* List all components that are available.  */
1206 void
gc_component_list_components(estream_t out)1207 gc_component_list_components (estream_t out)
1208 {
1209   gc_component_id_t component;
1210   const char *desc;
1211   const char *pgmname;
1212 
1213   for (component = 0; component < GC_COMPONENT_NR; component++)
1214     {
1215       if (!gc_component[component].program)
1216         continue;
1217       if (gc_component[component].module_name)
1218         pgmname = gnupg_module_name (gc_component[component].module_name);
1219       else
1220         pgmname = "";
1221 
1222       desc = gc_component[component].desc;
1223       desc = my_dgettext (gc_component[component].desc_domain, desc);
1224       es_fprintf (out, "%s:%s:",
1225                   gc_component[component].program, gc_percent_escape (desc));
1226       es_fprintf (out, "%s\n",  gc_percent_escape (pgmname));
1227     }
1228 }
1229 
1230 
1231 
1232 static int
all_digits_p(const char * p,size_t len)1233 all_digits_p (const char *p, size_t len)
1234 {
1235   if (!len)
1236     return 0; /* No. */
1237   for (; len; len--, p++)
1238     if (!isascii (*p) || !isdigit (*p))
1239       return 0; /* No.  */
1240   return 1; /* Yes.  */
1241 }
1242 
1243 
1244 /* Collect all error lines from stream FP. Only lines prefixed with
1245    TAG are considered.  Returns a list of error line items (which may
1246    be empty).  There is no error return.  */
1247 static error_line_t
collect_error_output(estream_t fp,const char * tag)1248 collect_error_output (estream_t fp, const char *tag)
1249 {
1250   char buffer[1024];
1251   char *p, *p2, *p3;
1252   int c, cont_line;
1253   unsigned int pos;
1254   error_line_t eitem, errlines, *errlines_tail;
1255   size_t taglen = strlen (tag);
1256 
1257   errlines = NULL;
1258   errlines_tail = &errlines;
1259   pos = 0;
1260   cont_line = 0;
1261   while ((c=es_getc (fp)) != EOF)
1262     {
1263       buffer[pos++] = c;
1264       if (pos >= sizeof buffer - 5 || c == '\n')
1265         {
1266           buffer[pos - (c == '\n')] = 0;
1267           if (cont_line)
1268             ; /*Ignore continuations of previous line. */
1269           else if (!strncmp (buffer, tag, taglen) && buffer[taglen] == ':')
1270             {
1271               /* "gpgsm: foo:4: bla" */
1272               /* Yep, we are interested in this line.  */
1273               p = buffer + taglen + 1;
1274               while (*p == ' ' || *p == '\t')
1275                 p++;
1276               trim_trailing_spaces (p); /* Get rid of extra CRs.  */
1277               if (!*p)
1278                 ; /* Empty lines are ignored.  */
1279               else if ( (p2 = strchr (p, ':')) && (p3 = strchr (p2+1, ':'))
1280                         && all_digits_p (p2+1, p3 - (p2+1)))
1281                 {
1282                   /* Line in standard compiler format.  */
1283                   p3++;
1284                   while (*p3 == ' ' || *p3 == '\t')
1285                     p3++;
1286                   eitem = xmalloc (sizeof *eitem + strlen (p));
1287                   eitem->next = NULL;
1288                   strcpy (eitem->buffer, p);
1289                   eitem->fname = eitem->buffer;
1290                   eitem->buffer[p2-p] = 0;
1291                   eitem->errtext = eitem->buffer + (p3 - p);
1292                   /* (we already checked that there are only ascii
1293                      digits followed by a colon) */
1294                   eitem->lineno = 0;
1295                   for (p2++; isdigit (*p2); p2++)
1296                     eitem->lineno = eitem->lineno*10 + (*p2 - '0');
1297                   *errlines_tail = eitem;
1298                   errlines_tail = &eitem->next;
1299                 }
1300               else
1301                 {
1302                   /* Other error output.  */
1303                   eitem = xmalloc (sizeof *eitem + strlen (p));
1304                   eitem->next = NULL;
1305                   strcpy (eitem->buffer, p);
1306                   eitem->fname = NULL;
1307                   eitem->errtext = eitem->buffer;
1308                   eitem->lineno = 0;
1309                   *errlines_tail = eitem;
1310                   errlines_tail = &eitem->next;
1311                 }
1312             }
1313           pos = 0;
1314           /* If this was not a complete line mark that we are in a
1315              continuation.  */
1316           cont_line = (c != '\n');
1317         }
1318     }
1319 
1320   /* We ignore error lines not terminated by a LF.  */
1321   return errlines;
1322 }
1323 
1324 
1325 /* Check the options of a single component.  If CONF_FILE is NULL the
1326  * standard config file is used.  If OUT is not NULL the output is
1327  * written to that stream.  Returns 0 if everything is OK.  */
1328 int
gc_component_check_options(int component,estream_t out,const char * conf_file)1329 gc_component_check_options (int component, estream_t out, const char *conf_file)
1330 {
1331   gpg_error_t err;
1332   unsigned int result;
1333   const char *pgmname;
1334   const char *argv[6];
1335   int i;
1336   pid_t pid;
1337   int exitcode;
1338   estream_t errfp;
1339   error_line_t errlines;
1340 
1341   log_assert (component >= 0 && component < GC_COMPONENT_NR);
1342 
1343   if (!gc_component[component].program)
1344     return 0;
1345   if (!gc_component[component].module_name)
1346     return 0;
1347 
1348   pgmname = gnupg_module_name (gc_component[component].module_name);
1349   i = 0;
1350   if (!gnupg_default_homedir_p ()
1351       && component != GC_COMPONENT_PINENTRY)
1352     {
1353       argv[i++] = "--homedir";
1354       argv[i++] = gnupg_homedir ();
1355     }
1356   if (conf_file)
1357     {
1358       argv[i++] = "--options";
1359       argv[i++] = conf_file;
1360     }
1361   if (component == GC_COMPONENT_PINENTRY)
1362     argv[i++] = "--version";
1363   else
1364     argv[i++] = "--gpgconf-test";
1365   argv[i] = NULL;
1366   log_assert (i < DIM(argv));
1367 
1368   result = 0;
1369   errlines = NULL;
1370   err = gnupg_spawn_process (pgmname, argv, NULL, NULL, 0,
1371                              NULL, NULL, &errfp, &pid);
1372   if (err)
1373     result |= 1; /* Program could not be run.  */
1374   else
1375     {
1376       errlines = collect_error_output (errfp,
1377 				       gc_component[component].name);
1378       if (gnupg_wait_process (pgmname, pid, 1, &exitcode))
1379 	{
1380 	  if (exitcode == -1)
1381 	    result |= 1; /* Program could not be run or it
1382 			    terminated abnormally.  */
1383 	  result |= 2; /* Program returned an error.  */
1384 	}
1385       gnupg_release_process (pid);
1386       es_fclose (errfp);
1387     }
1388 
1389   /* If the program could not be run, we can't tell whether
1390      the config file is good.  */
1391   if (result & 1)
1392     result |= 2;
1393 
1394   if (out)
1395     {
1396       const char *desc;
1397       error_line_t errptr;
1398 
1399       desc = gc_component[component].desc;
1400       desc = my_dgettext (gc_component[component].desc_domain, desc);
1401       es_fprintf (out, "%s:%s:",
1402                   gc_component[component].program, gc_percent_escape (desc));
1403       es_fputs (gc_percent_escape (pgmname), out);
1404       es_fprintf (out, ":%d:%d:", !(result & 1), !(result & 2));
1405       for (errptr = errlines; errptr; errptr = errptr->next)
1406 	{
1407 	  if (errptr != errlines)
1408 	    es_fputs ("\n:::::", out); /* Continuation line.  */
1409 	  if (errptr->fname)
1410 	    es_fputs (gc_percent_escape (errptr->fname), out);
1411 	  es_putc (':', out);
1412 	  if (errptr->fname)
1413 	    es_fprintf (out, "%u", errptr->lineno);
1414 	  es_putc (':', out);
1415 	  es_fputs (gc_percent_escape (errptr->errtext), out);
1416 	  es_putc (':', out);
1417 	}
1418       es_putc ('\n', out);
1419     }
1420 
1421   while (errlines)
1422     {
1423       error_line_t tmp = errlines->next;
1424       xfree (errlines);
1425       errlines = tmp;
1426     }
1427 
1428   return result;
1429 }
1430 
1431 
1432 
1433 /* Check all components that are available.  */
1434 void
gc_check_programs(estream_t out)1435 gc_check_programs (estream_t out)
1436 {
1437   gc_component_id_t component;
1438 
1439   for (component = 0; component < GC_COMPONENT_NR; component++)
1440     gc_component_check_options (component, out, NULL);
1441 }
1442 
1443 
1444 
1445 /* Find the component with the name NAME.  Returns -1 if not
1446    found.  */
1447 int
gc_component_find(const char * name)1448 gc_component_find (const char *name)
1449 {
1450   gc_component_id_t idx;
1451 
1452   for (idx = 0; idx < GC_COMPONENT_NR; idx++)
1453     {
1454       if (gc_component[idx].program
1455           && !strcmp (name, gc_component[idx].program))
1456 	return idx;
1457     }
1458   return -1;
1459 }
1460 
1461 
1462 /* List the option OPTION.  */
1463 static void
list_one_option(gc_component_id_t component,const gc_option_t * option,estream_t out)1464 list_one_option (gc_component_id_t component,
1465                  const gc_option_t *option, estream_t out)
1466 {
1467   const char *desc = NULL;
1468   char *arg_name = NULL;
1469   unsigned long flags;
1470   const char *desc_domain = gc_component[component].desc_domain;
1471 
1472   if (option->desc)
1473     {
1474       desc = my_dgettext (desc_domain, option->desc);
1475 
1476       if (*desc == '|')
1477 	{
1478 	  const char *arg_tail = strchr (&desc[1], '|');
1479 
1480 	  if (arg_tail)
1481 	    {
1482 	      int arg_len = arg_tail - &desc[1];
1483 	      arg_name = xmalloc (arg_len + 1);
1484 	      memcpy (arg_name, &desc[1], arg_len);
1485 	      arg_name[arg_len] = '\0';
1486 	      desc = arg_tail + 1;
1487 	    }
1488 	}
1489     }
1490 
1491 
1492   /* YOU MUST NOT REORDER THE FIELDS IN THIS OUTPUT, AS THEIR ORDER IS
1493      PART OF THE EXTERNAL INTERFACE.  YOU MUST NOT REMOVE ANY
1494      FIELDS.  */
1495 
1496   /* The name field.  */
1497   es_fprintf (out, "%s", option->name);
1498 
1499   /* The flags field.  */
1500   flags = 0;
1501   if (option->is_header)   flags |= GC_OPT_FLAG_GROUP;
1502   if (option->is_list)     flags |= GC_OPT_FLAG_LIST;
1503   if (option->runtime)     flags |= GC_OPT_FLAG_RUNTIME;
1504   if (option->has_default) flags |= GC_OPT_FLAG_DEFAULT;
1505   if (option->def_in_desc) flags |= GC_OPT_FLAG_DEF_DESC;
1506   if (option->no_arg_desc) flags |= GC_OPT_FLAG_NO_ARG_DESC;
1507   if (option->no_change)   flags |= GC_OPT_FLAG_NO_CHANGE;
1508   es_fprintf (out, ":%lu", flags);
1509   if (opt.verbose)
1510     {
1511       es_putc (' ', out);
1512 
1513       if (!flags)
1514 	es_fprintf (out, "none");
1515       else
1516 	{
1517 	  unsigned long flag = 0;
1518 	  unsigned long first = 1;
1519 
1520 	  while (flags)
1521 	    {
1522 	      if (flags & 1)
1523 		{
1524 		  if (first)
1525 		    first = 0;
1526 		  else
1527 		    es_putc (',', out);
1528 		  es_fprintf (out, "%s", gc_flag[flag].name);
1529 		}
1530 	      flags >>= 1;
1531 	      flag++;
1532 	    }
1533 	}
1534     }
1535 
1536   /* The level field.  */
1537   es_fprintf (out, ":%u", option->level);
1538   if (opt.verbose)
1539     es_fprintf (out, " %s", gc_level[option->level].name);
1540 
1541   /* The description field.  */
1542   es_fprintf (out, ":%s", desc ? gc_percent_escape (desc) : "");
1543 
1544   /* The type field.  */
1545   es_fprintf (out, ":%u", option->arg_type);
1546   if (opt.verbose)
1547     es_fprintf (out, " %s", gc_arg_type[option->arg_type].name);
1548 
1549   /* The alternate type field.  */
1550   es_fprintf (out, ":%u", gc_arg_type[option->arg_type].fallback);
1551   if (opt.verbose)
1552     es_fprintf (out, " %s",
1553                 gc_arg_type[gc_arg_type[option->arg_type].fallback].name);
1554 
1555   /* The argument name field.  */
1556   es_fprintf (out, ":%s", arg_name ? gc_percent_escape (arg_name) : "");
1557   xfree (arg_name);
1558 
1559   /* The default value field.  */
1560   es_fprintf (out, ":%s", option->default_value ? option->default_value : "");
1561 
1562   /* The default argument field.  This was never used and is thus empty.  */
1563   es_fprintf (out, ":");
1564 
1565   /* The value field.  */
1566   if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE
1567       && option->is_list && option->value)
1568     {
1569       /* The special format "1,1,1,1,...,1" is converted to a number
1570          here.  */
1571       es_fprintf (out, ":%u", (unsigned int)((strlen (option->value) + 1) / 2));
1572     }
1573   else
1574     es_fprintf (out, ":%s", option->value ? option->value : "");
1575 
1576   /* ADD NEW FIELDS HERE.  */
1577 
1578   es_putc ('\n', out);
1579 }
1580 
1581 
1582 /* List all options of the component COMPONENT.  */
1583 void
gc_component_list_options(int component,estream_t out)1584 gc_component_list_options (int component, estream_t out)
1585 {
1586   const gc_option_t *option = gc_component[component].options;
1587 
1588   for ( ; option && option->name; option++)
1589     {
1590       /* Do not output unknown or internal options.  */
1591       if (!option->is_header
1592 	  && option->level == GC_LEVEL_INTERNAL)
1593 	  continue;
1594 
1595       if (option->is_header)
1596 	{
1597 	  const gc_option_t *group_option = option + 1;
1598 	  gc_expert_level_t level = GC_LEVEL_NR;
1599 
1600 	  /* The manual states that the group level is always the
1601 	     minimum of the levels of all contained options.  Due to
1602 	     different active options, and because it is hard to
1603 	     maintain manually, we calculate it here.  The value in
1604 	     the global static table is ignored.  */
1605 
1606 	  for ( ; group_option->name; group_option++)
1607 	    {
1608 	      if (group_option->is_header)
1609 		break;
1610 	      if (group_option->level < level)
1611 		level = group_option->level;
1612 	    }
1613 
1614 	  /* Check if group is empty.  */
1615 	  if (level != GC_LEVEL_NR)
1616 	    {
1617 	      gc_option_t opt_copy;
1618 
1619 	      /* Fix up the group level.  */
1620 	      opt_copy = *option;
1621 	      opt_copy.level = level;
1622 	      list_one_option (component, &opt_copy, out);
1623 	    }
1624 	}
1625       else
1626 	list_one_option (component, option, out);
1627     }
1628 }
1629 
1630 
1631 /* Return true if the option NAME is known and that we want it as
1632  * gpgconf managed option.  */
1633 static known_option_t *
is_known_option(gc_component_id_t component,const char * name)1634 is_known_option (gc_component_id_t component, const char *name)
1635 {
1636   known_option_t *option = gc_component[component].known_options;
1637   if (option)
1638     {
1639       for (; option->name; option++)
1640         if (!strcmp (option->name, name))
1641           break;
1642     }
1643   return (option && option->name)? option : NULL;
1644 }
1645 
1646 
1647 /* Find the option NAME in component COMPONENT.  Returns pointer to
1648  * the option descriptor or NULL if not found.  */
1649 static gc_option_t *
find_option(gc_component_id_t component,const char * name)1650 find_option (gc_component_id_t component, const char *name)
1651 {
1652   gc_option_t *option = gc_component[component].options;
1653 
1654   if (option)
1655     {
1656       for (; option->name; option++)
1657         {
1658           if (!option->is_header
1659               && !strcmp (option->name, name))
1660             return option;
1661         }
1662     }
1663   return NULL;
1664 }
1665 
1666 
1667 
1668 
1669 struct read_line_wrapper_parm_s
1670 {
1671   const char *pgmname;
1672   estream_t fp;
1673   char *line;
1674   size_t line_len;
1675   const char **extra_lines;
1676   int extra_lines_idx;
1677   char *extra_line_buffer;
1678 };
1679 
1680 
1681 /* Helper for retrieve_options_from_program.  */
1682 static ssize_t
read_line_wrapper(struct read_line_wrapper_parm_s * parm)1683 read_line_wrapper (struct read_line_wrapper_parm_s *parm)
1684 {
1685   ssize_t length;
1686   const char *extra_line;
1687 
1688   if (parm->fp)
1689     {
1690       length = es_read_line (parm->fp, &parm->line, &parm->line_len, NULL);
1691       if (length > 0)
1692         return length;
1693       if (length < 0 || es_ferror (parm->fp))
1694         gc_error (1, errno, "error reading from %s", parm->pgmname);
1695       if (es_fclose (parm->fp))
1696         gc_error (1, errno, "error closing %s", parm->pgmname);
1697       /* EOF seen.  */
1698       parm->fp = NULL;
1699     }
1700   /* Return the made up lines.  */
1701   if (!parm->extra_lines
1702       || !(extra_line = parm->extra_lines[parm->extra_lines_idx]))
1703     return -1;  /* This is really the EOF.  */
1704   parm->extra_lines_idx++;
1705   xfree (parm->extra_line_buffer);
1706   parm->extra_line_buffer = xstrdup (extra_line);
1707   return strlen (parm->extra_line_buffer);
1708 }
1709 
1710 /* Retrieve the options for the component COMPONENT.  With
1711  * ONLY_INSTALLED set components which are not installed are silently
1712  * ignored. */
1713 static void
retrieve_options_from_program(gc_component_id_t component,int only_installed)1714 retrieve_options_from_program (gc_component_id_t component, int only_installed)
1715 {
1716   gpg_error_t err;
1717   const char *pgmname;
1718   const char *argv[2];
1719   estream_t outfp;
1720   int exitcode;
1721   pid_t pid;
1722   known_option_t *known_option;
1723   gc_option_t *option;
1724   char *line = NULL;
1725   size_t line_len;
1726   ssize_t length;
1727   const char *config_name;
1728   gpgrt_argparse_t pargs;
1729   int dummy_argc;
1730   char *twopartconfig_name = NULL;
1731   gpgrt_opt_t *opt_table = NULL;      /* A malloced option table.    */
1732   size_t opt_table_used = 0;          /* Its current length.         */
1733   size_t opt_table_size = 0;          /* Its allocated length.       */
1734   gc_option_t *opt_info = NULL;       /* A malloced options table.  */
1735   size_t opt_info_used = 0;           /* Its current length.         */
1736   size_t opt_info_size = 0;           /* Its allocated length.       */
1737   int i;
1738   struct read_line_wrapper_parm_s read_line_parm;
1739   int pseudo_count;
1740 
1741   pgmname = (gc_component[component].module_name
1742              ? gnupg_module_name (gc_component[component].module_name)
1743              : gc_component[component].program );
1744 
1745   if (only_installed && gnupg_access (pgmname, X_OK))
1746     {
1747       return;  /* The component is not installed.  */
1748     }
1749 
1750 
1751   /* First we need to read the option table from the program.  */
1752   argv[0] = "--dump-option-table";
1753   argv[1] = NULL;
1754   err = gnupg_spawn_process (pgmname, argv, NULL, NULL, 0,
1755                              NULL, &outfp, NULL, &pid);
1756   if (err)
1757     {
1758       gc_error (1, 0, "could not gather option table from '%s': %s",
1759                 pgmname, gpg_strerror (err));
1760     }
1761 
1762   read_line_parm.pgmname = pgmname;
1763   read_line_parm.fp = outfp;
1764   read_line_parm.line = line;
1765   read_line_parm.line_len = line_len = 0;
1766   read_line_parm.extra_line_buffer = NULL;
1767   read_line_parm.extra_lines = gc_component[component].known_pseudo_options;
1768   read_line_parm.extra_lines_idx = 0;
1769   pseudo_count = 0;
1770   while ((length = read_line_wrapper (&read_line_parm)) > 0)
1771     {
1772       const char *fields[4];
1773       const char *optname, *optdesc;
1774       unsigned int optflags;
1775       int short_opt;
1776       gc_arg_type_t arg_type;
1777       int pseudo = 0;
1778 
1779 
1780       if (read_line_parm.extra_line_buffer)
1781         {
1782           line = read_line_parm.extra_line_buffer;
1783           pseudo = 1;
1784           pseudo_count++;
1785         }
1786       else
1787         line = read_line_parm.line;
1788 
1789       /* Strip newline and carriage return, if present.  */
1790       while (length > 0
1791 	     && (line[length - 1] == '\n' || line[length - 1] == '\r'))
1792 	line[--length] = '\0';
1793 
1794       if (split_fields_colon (line, fields, DIM (fields)) < 4)
1795         {
1796           gc_error (0,0, "WARNING: invalid line in option table of '%s'\n",
1797                     pgmname);
1798           continue;
1799         }
1800 
1801       optname = fields[0];
1802       short_opt = atoi (fields[1]);
1803       if (short_opt < 1 && !pseudo)
1804         {
1805           gc_error (0,0, "WARNING: bad short option in option table of '%s'\n",
1806                     pgmname);
1807           continue;
1808         }
1809 
1810       optflags = strtoul (fields[2], NULL, 10);
1811       if ((optflags & ARGPARSE_OPT_HEADER))
1812         known_option = NULL; /* We want all header-only options.  */
1813       else if ((known_option = is_known_option (component, optname)))
1814         ; /* Yes we want this one.  */
1815       else
1816         continue; /* No need to store this option description.  */
1817 
1818       /* The +1 here is to make sure that we will have a zero item at
1819        * the end of the table.  */
1820       if (opt_table_used + 1 >= opt_table_size)
1821         {
1822           /* Note that this also does the initial allocation.  */
1823           opt_table_size += 128;
1824           opt_table = xreallocarray (opt_table,
1825                                      opt_table_used,
1826                                      opt_table_size,
1827                                      sizeof *opt_table);
1828         }
1829       /* The +1 here is to make sure that we will have a zero item at
1830        * the end of the table.  */
1831       if (opt_info_used + 1 >= opt_info_size)
1832         {
1833           /* Note that this also does the initial allocation.  */
1834           opt_info_size += 128;
1835           opt_info = xreallocarray (opt_info,
1836                                     opt_info_used,
1837                                     opt_info_size,
1838                                     sizeof *opt_info);
1839         }
1840        /* The +1 here accounts for the two items we are going to add to
1841         * the global string table.  */
1842       if (string_array_used + 1 >= string_array_size)
1843         {
1844           string_array_size += 256;
1845           string_array = xreallocarray (string_array,
1846                                         string_array_used,
1847                                         string_array_size,
1848                                         sizeof *string_array);
1849         }
1850       optname = string_array[string_array_used++] = xstrdup (fields[0]);
1851       optdesc = string_array[string_array_used++] = xstrdup (fields[3]);
1852 
1853       /* Create an option table which can then be supplied to
1854        * gpgrt_parser.  Unfortunately there is no private pointer in
1855        * the public option table struct so that we can't add extra
1856        * data we need here.  Thus we need to build up another table
1857        * for such info and for ease of use we also copy the tehre the
1858        * data from the option table.  It is not possible to use the
1859        * known_option_s for this because that one does not carry
1860        * header lines and it might also be problematic to use such
1861        * static tables for caching options and default values.  */
1862       if (!pseudo)
1863         {
1864           opt_table[opt_table_used].long_opt = optname;
1865           opt_table[opt_table_used].short_opt = short_opt;
1866           opt_table[opt_table_used].description = optdesc;
1867           opt_table[opt_table_used].flags = optflags;
1868           opt_table_used++;
1869         }
1870 
1871       /* Note that as per argparser specs the opt_table uses "@" to
1872        * specifify an empty description.  In the DESC script of
1873        * options (opt_info_t) we want to have a real empty string.  */
1874       opt_info[opt_info_used].name = optname;
1875       if (*optdesc == '@' && !optdesc[1])
1876         opt_info[opt_info_used].desc = optdesc+1;
1877       else
1878         opt_info[opt_info_used].desc = optdesc;
1879 
1880       /* Unfortunately we need to remap the types.  */
1881       switch ((optflags & ARGPARSE_TYPE_MASK))
1882         {
1883         case ARGPARSE_TYPE_INT:    arg_type = GC_ARG_TYPE_INT32;  break;
1884         case ARGPARSE_TYPE_LONG:   arg_type = GC_ARG_TYPE_INT32;  break;
1885         case ARGPARSE_TYPE_ULONG:  arg_type = GC_ARG_TYPE_UINT32; break;
1886         case ARGPARSE_TYPE_STRING: arg_type = GC_ARG_TYPE_STRING; break;
1887         default:                   arg_type = GC_ARG_TYPE_NONE;   break;
1888         }
1889       opt_info[opt_info_used].arg_type = arg_type;
1890       if (pseudo) /* Pseudo options are always no_change.  */
1891         opt_info[opt_info_used].no_change = 1;
1892 
1893 
1894       if ((optflags & ARGPARSE_OPT_HEADER))
1895         opt_info[opt_info_used].is_header = 1;
1896       if (known_option)
1897         {
1898           if ((known_option->flags & GC_OPT_FLAG_LIST))
1899             opt_info[opt_info_used].is_list = 1;
1900           /* FIXME: The next can also be taken from opt_table->flags.
1901            * We need to check the code whether both specifications match.  */
1902           if ((known_option->flags & GC_OPT_FLAG_ARG_OPT))
1903             opt_info[opt_info_used].opt_arg = 1;
1904 
1905           if ((known_option->flags & GC_OPT_FLAG_RUNTIME))
1906             opt_info[opt_info_used].runtime = 1;
1907 
1908           opt_info[opt_info_used].level = known_option->level;
1909           /* Override the received argtype by a complex type.  */
1910           if (known_option->arg_type)
1911             opt_info[opt_info_used].arg_type = known_option->arg_type;
1912         }
1913       opt_info_used++;
1914     }
1915   xfree (read_line_parm.extra_line_buffer);
1916   line = read_line_parm.line;
1917   line_len = read_line_parm.line_len;
1918   log_assert (opt_table_used + pseudo_count == opt_info_used);
1919 
1920 
1921   err = gnupg_wait_process (pgmname, pid, 1, &exitcode);
1922   if (err)
1923     gc_error (1, 0, "running %s failed (exitcode=%d): %s",
1924               pgmname, exitcode, gpg_strerror (err));
1925   gnupg_release_process (pid);
1926 
1927   /* Make the gpgrt option table and the internal option table available.  */
1928   gc_component[component].opt_table = opt_table;
1929   gc_component[component].options = opt_info;
1930 
1931 
1932   /* Now read the default options.  */
1933   argv[0] = "--gpgconf-list";
1934   argv[1] = NULL;
1935   err = gnupg_spawn_process (pgmname, argv, NULL, NULL, 0,
1936                              NULL, &outfp, NULL, &pid);
1937   if (err)
1938     {
1939       gc_error (1, 0, "could not gather active options from '%s': %s",
1940                 pgmname, gpg_strerror (err));
1941     }
1942 
1943   while ((length = es_read_line (outfp, &line, &line_len, NULL)) > 0)
1944     {
1945       char *linep;
1946       unsigned long flags = 0;
1947       char *default_value = NULL;
1948 
1949       /* Strip newline and carriage return, if present.  */
1950       while (length > 0
1951 	     && (line[length - 1] == '\n' || line[length - 1] == '\r'))
1952 	line[--length] = '\0';
1953 
1954       linep = strchr (line, ':');
1955       if (linep)
1956 	*(linep++) = '\0';
1957 
1958       /* Extract additional flags.  Default to none.  */
1959       if (linep)
1960 	{
1961 	  char *end;
1962 	  char *tail;
1963 
1964 	  end = strchr (linep, ':');
1965 	  if (end)
1966 	    *(end++) = '\0';
1967 
1968 	  gpg_err_set_errno (0);
1969 	  flags = strtoul (linep, &tail, 0);
1970 	  if (errno)
1971 	    gc_error (1, errno, "malformed flags in option %s from %s",
1972                       line, pgmname);
1973 	  if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
1974 	    gc_error (1, 0, "garbage after flags in option %s from %s",
1975                       line, pgmname);
1976 
1977 	  linep = end;
1978 	}
1979 
1980       /* Extract default value, if present.  Default to empty if
1981 	 not.  */
1982       if (linep)
1983 	{
1984 	  char *end;
1985 
1986 	  end = strchr (linep, ':');
1987 	  if (end)
1988 	    *(end++) = '\0';
1989 
1990 	  if ((flags & GC_OPT_FLAG_DEFAULT))
1991 	    default_value = linep;
1992 
1993 	  linep = end;
1994 	}
1995 
1996       /* Look up the option in the component and install the
1997 	 configuration data.  */
1998       option = find_option (component, line);
1999       if (option)
2000 	{
2001 	  if (option->gpgconf_list)
2002 	    gc_error (1, errno,
2003                       "option %s returned twice from \"%s --gpgconf-list\"",
2004 		      line, pgmname);
2005 	  option->gpgconf_list = 1;
2006 
2007           if ((flags & GC_OPT_FLAG_DEFAULT))
2008             option->has_default = 1;
2009           if ((flags & GC_OPT_FLAG_DEF_DESC))
2010             option->def_in_desc = 1;
2011           if ((flags & GC_OPT_FLAG_NO_ARG_DESC))
2012             option->no_arg_desc = 1;
2013           if ((flags & GC_OPT_FLAG_NO_CHANGE))
2014             option->no_change = 1;
2015 
2016 	  if (default_value && *default_value)
2017 	    option->default_value = xstrdup (default_value);
2018 	}
2019     }
2020   if (length < 0 || es_ferror (outfp))
2021     gc_error (1, errno, "error reading from %s", pgmname);
2022   if (es_fclose (outfp))
2023     gc_error (1, errno, "error closing %s", pgmname);
2024 
2025   err = gnupg_wait_process (pgmname, pid, 1, &exitcode);
2026   if (err)
2027     gc_error (1, 0, "running %s failed (exitcode=%d): %s",
2028               pgmname, exitcode, gpg_strerror (err));
2029   gnupg_release_process (pid);
2030 
2031 
2032   /* At this point, we can parse the configuration file.  */
2033   config_name = gc_component[component].option_config_filename;
2034   if (!config_name)
2035     gc_error (1, 0, "name of config file for %s is not known\n", pgmname);
2036 
2037   if (!gnupg_default_homedir_p ())
2038     {
2039       /* This is not the default homedir.  We need to take an absolute
2040        * config name for the user config file; gpgrt_argparser
2041        * fortunately supports this.  */
2042       char *tmp = make_filename (gnupg_homedir (), config_name, NULL);
2043       twopartconfig_name = xstrconcat (config_name, PATHSEP_S, tmp, NULL);
2044       xfree (tmp);
2045       config_name = twopartconfig_name;
2046     }
2047 
2048   memset (&pargs, 0, sizeof pargs);
2049   dummy_argc = 0;
2050   pargs.argc = &dummy_argc;
2051   pargs.flags = (ARGPARSE_FLAG_KEEP
2052                  | ARGPARSE_FLAG_SYS
2053                  | ARGPARSE_FLAG_USER
2054                  | ARGPARSE_FLAG_WITHATTR);
2055   if (opt.verbose)
2056     pargs.flags |= ARGPARSE_FLAG_VERBOSE;
2057 
2058   while (gpgrt_argparser (&pargs, opt_table, config_name))
2059     {
2060       char *opt_value;
2061 
2062       if (pargs.r_type & ARGPARSE_OPT_IGNORE)
2063         {
2064           /* log_debug ("ignored\n"); */
2065           continue;
2066         }
2067       if (pargs.r_opt == ARGPARSE_CONFFILE)
2068         {
2069           /* log_debug ("current conffile='%s'\n", */
2070           /*            pargs.r_type? pargs.r.ret_str: "[cmdline]"); */
2071           continue;
2072         }
2073 
2074       /* We only have the short option.  Search in the option table
2075        * for the long option name.  */
2076       for (i=0; opt_table[i].short_opt; i++)
2077         if (opt_table[i].short_opt == pargs.r_opt)
2078           break;
2079       if (!opt_table[i].short_opt || !opt_table[i].long_opt)
2080         continue;  /* No or only a short option - ignore.  */
2081 
2082       /* Look up the option from the config file in our list of
2083        * supported options.  */
2084       option= find_option (component, opt_table[i].long_opt);
2085       if (!option)
2086         continue;  /* We don't want to handle this option.  */
2087 
2088       option->attr_ignore = !!(pargs.r_type & ARGPARSE_ATTR_IGNORE);
2089       option->attr_force  = !!(pargs.r_type & ARGPARSE_ATTR_FORCE);
2090 
2091       switch ((pargs.r_type & ARGPARSE_TYPE_MASK))
2092         {
2093         case ARGPARSE_TYPE_INT:
2094           opt_value = xasprintf ("%d", pargs.r.ret_int);
2095           break;
2096         case ARGPARSE_TYPE_LONG:
2097           opt_value = xasprintf ("%ld", pargs.r.ret_long);
2098           break;
2099         case ARGPARSE_TYPE_ULONG:
2100           opt_value = xasprintf ("%lu", pargs.r.ret_ulong);
2101           break;
2102         case ARGPARSE_TYPE_STRING:
2103           opt_value = xasprintf ("\"%s", gc_percent_escape (pargs.r.ret_str));
2104           break;
2105         default: /* ARGPARSE_TYPE_NONE or any unknown type.  */
2106           opt_value = xstrdup ("1");  /* Make sure we have some value.  */
2107           break;
2108         }
2109 
2110       /* Now enter the value read from the config file into the table.  */
2111       if (!option->is_list)
2112         {
2113           xfree (option->value);
2114           option->value = opt_value;
2115         }
2116       else if (!option->value)  /* LIST but first item.  */
2117         option->value = opt_value;
2118       else
2119         {
2120           char *old = option->value;
2121           option->value = xstrconcat (old, ",", opt_value, NULL);
2122           xfree (old);
2123           xfree (opt_value);
2124         }
2125     }
2126 
2127   xfree (line);
2128   xfree (twopartconfig_name);
2129 }
2130 
2131 
2132 
2133 /* Retrieve the currently active options and their defaults for this
2134    component.  Using -1 for component will retrieve all options from
2135    all installed components. */
2136 void
gc_component_retrieve_options(int component)2137 gc_component_retrieve_options (int component)
2138 {
2139   int process_all = 0;
2140 
2141   if (component == -1)
2142     {
2143       process_all = 1;
2144       component = 0;
2145     }
2146 
2147   do
2148     {
2149       if (component == GC_COMPONENT_PINENTRY)
2150         continue; /* Skip this dummy component.  */
2151 
2152       if (gc_component[component].program)
2153         retrieve_options_from_program (component, process_all);
2154     }
2155   while (process_all && ++component < GC_COMPONENT_NR);
2156 
2157 }
2158 
2159 
2160 
2161 /* Perform a simple validity check based on the type.  Return in
2162  * NEW_VALUE_NR the value of the number in NEW_VALUE if OPTION is of
2163  * type GC_ARG_TYPE_NONE.  If VERBATIM is set the profile parsing mode
2164  * is used. */
2165 static void
option_check_validity(gc_component_id_t component,gc_option_t * option,unsigned long flags,char * new_value,unsigned long * new_value_nr,int verbatim)2166 option_check_validity (gc_component_id_t component,
2167                        gc_option_t *option, unsigned long flags,
2168 		       char *new_value, unsigned long *new_value_nr,
2169                        int verbatim)
2170 {
2171   char *arg;
2172 
2173   (void)component;
2174 
2175   if (option->new_flags || option->new_value)
2176     gc_error (1, 0, "option %s already changed", option->name);
2177 
2178   if (flags & GC_OPT_FLAG_DEFAULT)
2179     {
2180       if (*new_value)
2181 	gc_error (1, 0, "argument %s provided for deleted option %s",
2182 		  new_value, option->name);
2183 
2184       return;
2185     }
2186 
2187   /* GC_ARG_TYPE_NONE options have special list treatment.  */
2188   if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE)
2189     {
2190       char *tail;
2191 
2192       gpg_err_set_errno (0);
2193       *new_value_nr = strtoul (new_value, &tail, 0);
2194 
2195       if (errno)
2196 	gc_error (1, errno, "invalid argument for option %s",
2197 		  option->name);
2198       if (*tail)
2199 	gc_error (1, 0, "garbage after argument for option %s",
2200 		      option->name);
2201 
2202       if (!option->is_list)
2203 	{
2204 	  if (*new_value_nr != 1)
2205 	    gc_error (1, 0, "argument for non-list option %s of type 0 "
2206 		      "(none) must be 1", option->name);
2207 	}
2208       else
2209 	{
2210 	  if (*new_value_nr == 0)
2211 	    gc_error (1, 0, "argument for option %s of type 0 (none) "
2212 		      "must be positive", option->name);
2213 	}
2214 
2215       return;
2216     }
2217 
2218   arg = new_value;
2219   do
2220     {
2221       if (*arg == '\0' || (*arg == ',' && !verbatim))
2222 	{
2223 	  if (!option->opt_arg)
2224 	    gc_error (1, 0, "argument required for option %s", option->name);
2225 
2226 	  if (*arg == ',' && !verbatim && !option->is_list)
2227 	    gc_error (1, 0, "list found for non-list option %s", option->name);
2228 	}
2229       else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING)
2230 	{
2231 	  if (*arg != '"' && !verbatim)
2232 	    gc_error (1, 0, "string argument for option %s must begin "
2233 		      "with a quote (\") character", option->name);
2234 
2235 	  /* FIXME: We do not allow empty string arguments for now, as
2236 	     we do not quote arguments in configuration files, and
2237 	     thus no argument is indistinguishable from the empty
2238 	     string.  */
2239 	  if (arg[1] == '\0' || (arg[1] == ',' && !verbatim))
2240 	    gc_error (1, 0, "empty string argument for option %s is "
2241 		      "currently not allowed.  Please report this!",
2242 		      option->name);
2243 	}
2244       else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32)
2245 	{
2246 	  long res;
2247 
2248 	  gpg_err_set_errno (0);
2249 	  res = strtol (arg, &arg, 0);
2250 	  (void) res;
2251 
2252 	  if (errno)
2253 	    gc_error (1, errno, "invalid argument for option %s",
2254 		      option->name);
2255 
2256 	  if (*arg != '\0' && (*arg != ',' || verbatim))
2257 	    gc_error (1, 0, "garbage after argument for option %s",
2258 		      option->name);
2259 	}
2260       else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_UINT32)
2261 	{
2262 	  unsigned long res;
2263 
2264 	  gpg_err_set_errno (0);
2265 	  res = strtoul (arg, &arg, 0);
2266 	  (void) res;
2267 
2268 	  if (errno)
2269 	    gc_error (1, errno, "invalid argument for option %s",
2270 		      option->name);
2271 
2272 	  if (*arg != '\0' && (*arg != ',' || verbatim))
2273 	    gc_error (1, 0, "garbage after argument for option %s",
2274 		      option->name);
2275 	}
2276       arg = verbatim? strchr (arg, ',') : NULL;
2277       if (arg)
2278 	arg++;
2279     }
2280   while (arg && *arg);
2281 }
2282 
2283 #ifdef HAVE_W32_SYSTEM
2284 int
copy_file(const char * src_name,const char * dst_name)2285 copy_file (const char *src_name, const char *dst_name)
2286 {
2287 #define BUF_LEN 4096
2288   char buffer[BUF_LEN];
2289   int len;
2290   gpgrt_stream_t src;
2291   gpgrt_stream_t dst;
2292 
2293   src = gpgrt_fopen (src_name, "r");
2294   if (src == NULL)
2295     return -1;
2296 
2297   dst = gpgrt_fopen (dst_name, "w");
2298   if (dst == NULL)
2299     {
2300       int saved_err = errno;
2301       gpgrt_fclose (src);
2302       gpg_err_set_errno (saved_err);
2303       return -1;
2304     }
2305 
2306   do
2307     {
2308       int written;
2309 
2310       len = gpgrt_fread (buffer, 1, BUF_LEN, src);
2311       if (len == 0)
2312 	break;
2313       written = gpgrt_fwrite (buffer, 1, len, dst);
2314       if (written != len)
2315 	break;
2316     }
2317   while (! gpgrt_feof (src) && ! gpgrt_ferror (src) && ! gpgrt_ferror (dst));
2318 
2319   if (gpgrt_ferror (src) || gpgrt_ferror (dst) || ! gpgrt_feof (src))
2320     {
2321       int saved_errno = errno;
2322       gpgrt_fclose (src);
2323       gpgrt_fclose (dst);
2324       unlink (dst_name);
2325       gpg_err_set_errno (saved_errno);
2326       return -1;
2327     }
2328 
2329   if (gpgrt_fclose (dst))
2330     gc_error (1, errno, "error closing %s", dst_name);
2331   if (gpgrt_fclose (src))
2332     gc_error (1, errno, "error closing %s", src_name);
2333 
2334   return 0;
2335 }
2336 #endif /* HAVE_W32_SYSTEM */
2337 
2338 
2339 /* Create and verify the new configuration file for the specified
2340  *  component.  Returns 0 on success and -1 on error.  If
2341  * VERBATIM is set the profile mode is used.  This function may store
2342  * pointers to malloced strings in SRC_FILENAMEP, DEST_FILENAMEP, and
2343  * ORIG_FILENAMEP.  Those must be freed by the caller.  The strings
2344  * refer to three versions of the configuration file:
2345  *
2346  * SRC_FILENAME:  The updated configuration is written to this file.
2347  * DEST_FILENAME: Name of the configuration file read by the
2348  *                component.
2349  * ORIG_FILENAME: A backup of the previous configuration file.
2350  *
2351  * To apply the configuration change, rename SRC_FILENAME to
2352  * DEST_FILENAME.  To revert to the previous configuration, rename
2353  * ORIG_FILENAME to DEST_FILENAME.  */
2354 static int
change_options_program(gc_component_id_t component,char ** src_filenamep,char ** dest_filenamep,char ** orig_filenamep,int verbatim)2355 change_options_program (gc_component_id_t component,
2356 			char **src_filenamep, char **dest_filenamep,
2357 			char **orig_filenamep,
2358                         int verbatim)
2359 {
2360   static const char marker[] = "###+++--- " GPGCONF_DISP_NAME " ---+++###";
2361   /* True if we are within the marker in the config file.  */
2362   int in_marker = 0;
2363   gc_option_t *option;
2364   char *line = NULL;
2365   size_t line_len;
2366   ssize_t length;
2367   int res;
2368   int fd;
2369   gpgrt_stream_t src_file = NULL;
2370   gpgrt_stream_t dest_file = NULL;
2371   char *src_filename;
2372   char *dest_filename;
2373   char *orig_filename;
2374   /* Special hack for gpg, see below.  */
2375   int utf8strings_seen = 0;
2376 
2377 
2378   /* FIXME.  Throughout the function, do better error reporting.  */
2379   if (!gc_component[component].option_config_filename)
2380     gc_error (1, 0, "name of config file for %s is not known\n",
2381               gc_component[component].name);
2382 
2383   dest_filename = make_absfilename
2384     (gnupg_homedir (), gc_component[component].option_config_filename, NULL);
2385   src_filename = xasprintf ("%s.%s.%i.new",
2386                             dest_filename, GPGCONF_NAME, (int)getpid ());
2387   orig_filename = xasprintf ("%s.%s.%i.bak",
2388                              dest_filename, GPGCONF_NAME, (int)getpid ());
2389 
2390 #ifdef HAVE_W32_SYSTEM
2391   res = copy_file (dest_filename, orig_filename);
2392 #else
2393   res = link (dest_filename, orig_filename);
2394 #endif
2395   if (res < 0 && errno != ENOENT)
2396     {
2397       xfree (dest_filename);
2398       xfree (src_filename);
2399       xfree (orig_filename);
2400       return -1;
2401     }
2402   if (res < 0)
2403     {
2404       xfree (orig_filename);
2405       orig_filename = NULL;
2406     }
2407 
2408   /* We now initialize the return strings, so the caller can do the
2409      cleanup for us.  */
2410   *src_filenamep = src_filename;
2411   *dest_filenamep = dest_filename;
2412   *orig_filenamep = orig_filename;
2413 
2414   /* Use open() so that we can use O_EXCL.
2415    * FIXME: gpgrt has an x flag for quite some time now - use that.  */
2416   fd = gnupg_open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644);
2417   if (fd < 0)
2418     return -1;
2419   src_file = gpgrt_fdopen (fd, "w");
2420   res = errno;
2421   if (!src_file)
2422     {
2423       gpg_err_set_errno (res);
2424       return -1;
2425     }
2426 
2427   /* Only if ORIG_FILENAME is not NULL did the configuration file
2428      exist already.  In this case, we will copy its content into the
2429      new configuration file, changing it to our liking in the
2430      process.  */
2431   if (orig_filename)
2432     {
2433       dest_file = gpgrt_fopen (dest_filename, "r");
2434       if (!dest_file)
2435 	goto change_one_err;
2436 
2437       while ((length = gpgrt_read_line (dest_file, &line, &line_len, NULL)) > 0)
2438 	{
2439 	  int disable = 0;
2440 	  char *start;
2441 
2442 	  if (!strncmp (marker, line, sizeof (marker) - 1))
2443 	    {
2444 	      if (!in_marker)
2445 		in_marker = 1;
2446 	      else
2447 		break;
2448 	    }
2449 	  else if (component == GC_COMPONENT_GPG && in_marker
2450 		   && ! strcmp ("utf8-strings\n", line))
2451 	    {
2452 	      /* Strip duplicated entries.  */
2453 	      if (utf8strings_seen)
2454 		disable = 1;
2455 	      else
2456 		utf8strings_seen = 1;
2457 	    }
2458 
2459 	  start = line;
2460 	  while (*start == ' ' || *start == '\t')
2461 	    start++;
2462 	  if (*start && *start != '\r' && *start != '\n' && *start != '#')
2463 	    {
2464 	      char *end;
2465 	      char saved_end;
2466 
2467 	      end = start;
2468 	      while (*end && *end != ' ' && *end != '\t'
2469 		     && *end != '\r' && *end != '\n' && *end != '#')
2470 		end++;
2471 	      saved_end = *end;
2472 	      *end = '\0';
2473 
2474 	      option = find_option (component, start);
2475 	      *end = saved_end;
2476 	      if (option && ((option->new_flags & GC_OPT_FLAG_DEFAULT)
2477 			     || option->new_value))
2478 		disable = 1;
2479 	    }
2480 	  if (disable)
2481 	    {
2482 	      if (!in_marker)
2483 		{
2484 		  gpgrt_fprintf (src_file,
2485 			   "# %s disabled this option here at %s\n",
2486 			   GPGCONF_DISP_NAME, asctimestamp (gnupg_get_time ()));
2487 		  if (gpgrt_ferror (src_file))
2488 		    goto change_one_err;
2489 		  gpgrt_fprintf (src_file, "# %s", line);
2490 		  if (gpgrt_ferror (src_file))
2491 		    goto change_one_err;
2492 		}
2493 	    }
2494 	  else
2495 	    {
2496 	      gpgrt_fprintf (src_file, "%s", line);
2497 	      if (gpgrt_ferror (src_file))
2498 		goto change_one_err;
2499 	    }
2500 	}
2501       if (length < 0 || gpgrt_ferror (dest_file))
2502 	goto change_one_err;
2503     }
2504 
2505   if (!in_marker)
2506     {
2507       /* There was no marker.  This is the first time we edit the
2508 	 file.  We add our own marker at the end of the file and
2509 	 proceed.  Note that we first write a newline, this guards us
2510 	 against files which lack the newline at the end of the last
2511 	 line, while it doesn't hurt us in all other cases.  */
2512       gpgrt_fprintf (src_file, "\n%s\n", marker);
2513       if (gpgrt_ferror (src_file))
2514 	goto change_one_err;
2515     }
2516   /* At this point, we have copied everything up to the end marker
2517      into the new file, except for the options we are going to change.
2518      Now, dump the changed options (except for those we are going to
2519      revert to their default), and write the end marker, possibly
2520      followed by the rest of the original file.  */
2521 
2522   /* We have to turn on UTF8 strings for GnuPG.  */
2523   if (component == GC_COMPONENT_GPG && ! utf8strings_seen)
2524     gpgrt_fprintf (src_file, "utf8-strings\n");
2525 
2526   option = gc_component[component].options;
2527   for ( ; option->name; option++)
2528     {
2529       if (!option->is_header && option->new_value)
2530 	{
2531 	  char *arg = option->new_value;
2532 
2533 	  do
2534 	    {
2535 	      if (*arg == '\0' || *arg == ',')
2536 		{
2537 		  gpgrt_fprintf (src_file, "%s\n", option->name);
2538 		  if (gpgrt_ferror (src_file))
2539 		    goto change_one_err;
2540 		}
2541 	      else if (gc_arg_type[option->arg_type].fallback
2542 		       == GC_ARG_TYPE_NONE)
2543 		{
2544 		  log_assert (*arg == '1');
2545 		  gpgrt_fprintf (src_file, "%s\n", option->name);
2546 		  if (gpgrt_ferror (src_file))
2547 		    goto change_one_err;
2548 
2549 		  arg++;
2550 		}
2551 	      else if (gc_arg_type[option->arg_type].fallback
2552 		       == GC_ARG_TYPE_STRING)
2553 		{
2554 		  char *end;
2555 
2556                   if (!verbatim)
2557                     {
2558                       log_assert (*arg == '"');
2559                       arg++;
2560 
2561                       end = strchr (arg, ',');
2562                       if (end)
2563                         *end = '\0';
2564                     }
2565                   else
2566                     end = NULL;
2567 
2568 		  gpgrt_fprintf (src_file, "%s %s\n", option->name,
2569 			   verbatim? arg : percent_deescape (arg));
2570 		  if (gpgrt_ferror (src_file))
2571 		    goto change_one_err;
2572 
2573 		  if (end)
2574 		    *end = ',';
2575 		  arg = end;
2576 		}
2577 	      else
2578 		{
2579 		  char *end;
2580 
2581 		  end = strchr (arg, ',');
2582 		  if (end)
2583 		    *end = '\0';
2584 
2585 		  gpgrt_fprintf (src_file, "%s %s\n", option->name, arg);
2586 		  if (gpgrt_ferror (src_file))
2587 		    goto change_one_err;
2588 
2589 		  if (end)
2590 		    *end = ',';
2591 		  arg = end;
2592 		}
2593 
2594 	      log_assert (arg == NULL || *arg == '\0' || *arg == ',');
2595 	      if (arg && *arg == ',')
2596 		arg++;
2597 	    }
2598 	  while (arg && *arg);
2599 	}
2600     }
2601 
2602   gpgrt_fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ()));
2603   if (gpgrt_ferror (src_file))
2604     goto change_one_err;
2605 
2606   if (!in_marker)
2607     {
2608       gpgrt_fprintf (src_file, "# %s edited this configuration file.\n",
2609                GPGCONF_DISP_NAME);
2610       if (gpgrt_ferror (src_file))
2611 	goto change_one_err;
2612       gpgrt_fprintf (src_file, "# It will disable options before this marked "
2613 	       "block, but it will\n");
2614       if (gpgrt_ferror (src_file))
2615 	goto change_one_err;
2616       gpgrt_fprintf (src_file, "# never change anything below these lines.\n");
2617       if (gpgrt_ferror (src_file))
2618 	goto change_one_err;
2619     }
2620   if (dest_file)
2621     {
2622       while ((length = gpgrt_read_line (dest_file, &line, &line_len, NULL)) > 0)
2623 	{
2624 	  gpgrt_fprintf (src_file, "%s", line);
2625 	  if (gpgrt_ferror (src_file))
2626 	    goto change_one_err;
2627 	}
2628       if (length < 0 || gpgrt_ferror (dest_file))
2629 	goto change_one_err;
2630     }
2631   xfree (line);
2632   line = NULL;
2633 
2634   res = gpgrt_fclose (src_file);
2635   if (res)
2636     {
2637       res = errno;
2638       close (fd);
2639       if (dest_file)
2640 	gpgrt_fclose (dest_file);
2641       gpg_err_set_errno (res);
2642       return -1;
2643     }
2644   close (fd);
2645   if (dest_file)
2646     {
2647       res = gpgrt_fclose (dest_file);
2648       if (res)
2649 	return -1;
2650     }
2651   return 0;
2652 
2653  change_one_err:
2654   xfree (line);
2655   res = errno;
2656   if (src_file)
2657     {
2658       gpgrt_fclose (src_file);
2659       close (fd);
2660     }
2661   if (dest_file)
2662     gpgrt_fclose (dest_file);
2663   gpg_err_set_errno (res);
2664   return -1;
2665 }
2666 
2667 
2668 /* Common code for gc_component_change_options and
2669  * gc_process_gpgconf_conf.  If VERBATIM is set the profile parsing
2670  * mode is used.  */
2671 static void
change_one_value(gc_component_id_t component,gc_option_t * option,int * r_runtime,unsigned long flags,char * new_value,int verbatim)2672 change_one_value (gc_component_id_t component,
2673                   gc_option_t *option, int *r_runtime,
2674                   unsigned long flags, char *new_value, int verbatim)
2675 {
2676   unsigned long new_value_nr = 0;
2677 
2678   option_check_validity (component, option,
2679                          flags, new_value, &new_value_nr, verbatim);
2680 
2681   if (option->runtime)
2682     *r_runtime = 1;
2683 
2684   option->new_flags = flags;
2685   if (!(flags & GC_OPT_FLAG_DEFAULT))
2686     {
2687       if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE
2688           && option->is_list)
2689         {
2690           char *str;
2691 
2692           /* We convert the number to a list of 1's for convenient
2693              list handling.  */
2694           log_assert (new_value_nr > 0);
2695           option->new_value = xmalloc ((2 * (new_value_nr - 1) + 1) + 1);
2696           str = option->new_value;
2697           *(str++) = '1';
2698           while (--new_value_nr > 0)
2699             {
2700               *(str++) = ',';
2701               *(str++) = '1';
2702             }
2703           *(str++) = '\0';
2704         }
2705       else
2706         option->new_value = xstrdup (new_value);
2707     }
2708 }
2709 
2710 
2711 /* Read the modifications from IN and apply them.  If IN is NULL the
2712    modifications are expected to already have been set to the global
2713    table.  If VERBATIM is set the profile mode is used.  */
2714 void
gc_component_change_options(int component,estream_t in,estream_t out,int verbatim)2715 gc_component_change_options (int component, estream_t in, estream_t out,
2716                              int verbatim)
2717 {
2718   int err = 0;
2719   int block = 0;
2720   int runtime = 0;
2721   char *src_filename = NULL;
2722   char *dest_filename = NULL;
2723   char *orig_filename = NULL;
2724   gc_option_t *option;
2725   char *line = NULL;
2726   size_t line_len = 0;
2727   ssize_t length;
2728 
2729   if (component == GC_COMPONENT_PINENTRY)
2730     return; /* Dummy component for now.  */
2731 
2732   if (in)
2733     {
2734       /* Read options from the file IN.  */
2735       while ((length = es_read_line (in, &line, &line_len, NULL)) > 0)
2736         {
2737           char *linep;
2738           unsigned long flags = 0;
2739           char *new_value = "";
2740 
2741           /* Strip newline and carriage return, if present.  */
2742           while (length > 0
2743                  && (line[length - 1] == '\n' || line[length - 1] == '\r'))
2744             line[--length] = '\0';
2745 
2746           linep = strchr (line, ':');
2747           if (linep)
2748             *(linep++) = '\0';
2749 
2750           /* Extract additional flags.  Default to none.  */
2751           if (linep)
2752             {
2753               char *end;
2754               char *tail;
2755 
2756               end = strchr (linep, ':');
2757               if (end)
2758                 *(end++) = '\0';
2759 
2760               gpg_err_set_errno (0);
2761               flags = strtoul (linep, &tail, 0);
2762               if (errno)
2763                 gc_error (1, errno, "malformed flags in option %s", line);
2764               if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
2765                 gc_error (1, 0, "garbage after flags in option %s", line);
2766 
2767               linep = end;
2768             }
2769 
2770           /* Don't allow setting of the no change flag.  */
2771           flags &= ~GC_OPT_FLAG_NO_CHANGE;
2772 
2773           /* Extract default value, if present.  Default to empty if not.  */
2774           if (linep)
2775             {
2776               char *end;
2777               end = strchr (linep, ':');
2778               if (end)
2779                 *(end++) = '\0';
2780               new_value = linep;
2781               linep = end;
2782             }
2783 
2784           option = find_option (component, line);
2785           if (!option)
2786             gc_error (1, 0, "unknown option %s", line);
2787 
2788           if (option->no_change)
2789             {
2790               gc_error (0, 0, "ignoring new value for option %s",
2791                         option->name);
2792               continue;
2793             }
2794 
2795           change_one_value (component, option, &runtime, flags, new_value, 0);
2796         }
2797       if (length < 0 || gpgrt_ferror (in))
2798 	gc_error (1, errno, "error reading stream 'in'");
2799     }
2800 
2801   /* Now that we have collected and locally verified the changes,
2802      write them out to new configuration files, verify them
2803      externally, and then commit them.  */
2804   option = gc_component[component].options;
2805   while (option && option->name)
2806     {
2807       /* Go on if there is nothing to do.  */
2808       if (src_filename || !(option->new_flags || option->new_value))
2809 	{
2810 	  option++;
2811 	  continue;
2812 	}
2813 
2814       if (gc_component[component].program)
2815 	{
2816 	  err = change_options_program (component,
2817 					&src_filename,
2818 					&dest_filename,
2819 					&orig_filename,
2820                                         verbatim);
2821 	  if (! err)
2822 	    {
2823 	      /* External verification.  */
2824 	      err = gc_component_check_options (component, out, src_filename);
2825 	      if (err)
2826 		{
2827 		  gc_error (0, 0,
2828 			    _("External verification of component %s failed"),
2829 			    gc_component[component].name);
2830 		  gpg_err_set_errno (EINVAL);
2831 		}
2832 	    }
2833 
2834 	}
2835       if (err)
2836 	break;
2837 
2838       option++;
2839     }
2840 
2841   /* We are trying to atomically commit all changes.  Unfortunately,
2842      we cannot rely on gnupg_rename_file to manage the signals for us,
2843      doing so would require us to pass NULL as BLOCK to any subsequent
2844      call to it.  Instead, we just manage the signal handling
2845      manually.  */
2846   block = 1;
2847   gnupg_block_all_signals ();
2848 
2849   if (!err && !opt.dry_run)
2850     {
2851       if (src_filename)
2852         {
2853           /* FIXME: Make a verification here.  */
2854 
2855           log_assert (dest_filename);
2856 
2857           if (orig_filename)
2858             err = gnupg_rename_file (src_filename, dest_filename, NULL);
2859           else
2860             {
2861 #ifdef HAVE_W32_SYSTEM
2862               /* We skip the unlink if we expect the file not to be
2863                * there.  */
2864               err = gnupg_rename_file (src_filename, dest_filename, NULL);
2865 #else /* HAVE_W32_SYSTEM */
2866               /* This is a bit safer than rename() because we expect
2867                * DEST_FILENAME not to be there.  If it happens to be
2868                * there, this will fail.  */
2869               err = link (src_filename, dest_filename);
2870               if (!err)
2871                 err = unlink (src_filename);
2872 #endif /* !HAVE_W32_SYSTEM */
2873             }
2874           if (!err)
2875             {
2876               xfree (src_filename);
2877               src_filename = NULL;
2878             }
2879         }
2880     }
2881 
2882   if (err || opt.dry_run)
2883     {
2884       int saved_errno = errno;
2885 
2886       /* An error occurred or a dry-run is requested.  */
2887       if (src_filename)
2888         {
2889           /* The change was not yet committed.  */
2890           unlink (src_filename);
2891           if (orig_filename)
2892             unlink (orig_filename);
2893         }
2894       else
2895         {
2896           /* The changes were already committed.  FIXME: This is a tad
2897              dangerous, as we don't know if we don't overwrite a
2898              version of the file that is even newer than the one we
2899              just installed.  */
2900           if (orig_filename)
2901             gnupg_rename_file (orig_filename, dest_filename, NULL);
2902           else
2903             unlink (dest_filename);
2904         }
2905       if (err)
2906 	gc_error (1, saved_errno, "could not commit changes");
2907 
2908       /* Fall-through for dry run.  */
2909       goto leave;
2910     }
2911 
2912   /* If it all worked, notify the daemons of the changes.  */
2913   if (opt.runtime)
2914     do_runtime_change (component, 0);
2915 
2916 
2917   /* Move the per-process backup file into its place.  */
2918   if (orig_filename)
2919     {
2920       char *backup_filename;
2921 
2922       log_assert (dest_filename);
2923 
2924       backup_filename = xasprintf ("%s.%s.bak",
2925                                    dest_filename, GPGCONF_NAME);
2926       gnupg_rename_file (orig_filename, backup_filename, NULL);
2927       xfree (backup_filename);
2928     }
2929 
2930  leave:
2931   if (block)
2932     gnupg_unblock_all_signals ();
2933   xfree (line);
2934   xfree (src_filename);
2935   xfree (dest_filename);
2936   xfree (orig_filename);
2937 }
2938 
2939 
2940 /* Check whether USER matches the current user or one of its group.
2941    This function may change USER.  Returns true is there is a
2942    match.  */
2943 static int
key_matches_user_or_group(char * user)2944 key_matches_user_or_group (char *user)
2945 {
2946   char *group;
2947 
2948   if (*user == '*' && user[1] == 0)
2949     return 1; /* A single asterisk matches all users.  */
2950 
2951   group = strchr (user, ':');
2952   if (group)
2953     *group++ = 0;
2954 
2955 #ifdef HAVE_W32_SYSTEM
2956   /* Under Windows we don't support groups. */
2957   if (group && *group)
2958     gc_error (0, 0, _("Note that group specifications are ignored\n"));
2959 #ifndef HAVE_W32CE_SYSTEM
2960   if (*user)
2961     {
2962       static char *my_name;
2963 
2964       if (!my_name)
2965         {
2966           char tmp[1];
2967           DWORD size = 1;
2968 
2969           GetUserNameA (tmp, &size);
2970           my_name = xmalloc (size);
2971           if (!GetUserNameA (my_name, &size))
2972             gc_error (1,0, "error getting current user name: %s",
2973                       w32_strerror (-1));
2974         }
2975 
2976       if (!strcmp (user, my_name))
2977         return 1; /* Found.  */
2978     }
2979 #endif /*HAVE_W32CE_SYSTEM*/
2980 #else /*!HAVE_W32_SYSTEM*/
2981   /* First check whether the user matches.  */
2982   if (*user)
2983     {
2984       static char *my_name;
2985 
2986       if (!my_name)
2987         {
2988           struct passwd *pw = getpwuid ( getuid () );
2989           if (!pw)
2990             gc_error (1, errno, "getpwuid failed for current user");
2991           my_name = xstrdup (pw->pw_name);
2992         }
2993       if (!strcmp (user, my_name))
2994         return 1; /* Found.  */
2995     }
2996 
2997   /* If that failed, check whether a group matches.  */
2998   if (group && *group)
2999     {
3000       static char *my_group;
3001       static char **my_supgroups;
3002       int n;
3003 
3004       if (!my_group)
3005         {
3006           struct group *gr = getgrgid ( getgid () );
3007           if (!gr)
3008             gc_error (1, errno, "getgrgid failed for current user");
3009           my_group = xstrdup (gr->gr_name);
3010         }
3011       if (!strcmp (group, my_group))
3012         return 1; /* Found.  */
3013 
3014       if (!my_supgroups)
3015         {
3016           int ngids;
3017           gid_t *gids;
3018 
3019           ngids = getgroups (0, NULL);
3020           gids  = xcalloc (ngids+1, sizeof *gids);
3021           ngids = getgroups (ngids, gids);
3022           if (ngids < 0)
3023             gc_error (1, errno, "getgroups failed for current user");
3024           my_supgroups = xcalloc (ngids+1, sizeof *my_supgroups);
3025           for (n=0; n < ngids; n++)
3026             {
3027               struct group *gr = getgrgid ( gids[n] );
3028               if (!gr)
3029                 gc_error (1, errno, "getgrgid failed for supplementary group");
3030               my_supgroups[n] = xstrdup (gr->gr_name);
3031             }
3032           xfree (gids);
3033         }
3034 
3035       for (n=0; my_supgroups[n]; n++)
3036         if (!strcmp (group, my_supgroups[n]))
3037           return 1; /* Found.  */
3038     }
3039 #endif /*!HAVE_W32_SYSTEM*/
3040   return 0; /* No match.  */
3041 }
3042 
3043 
3044 
3045 /* Read and process the global configuration file for gpgconf.  This
3046    optional file is used to update our internal tables at runtime and
3047    may also be used to set new default values.  If FNAME is NULL the
3048    default name will be used.  With UPDATE set to true the internal
3049    tables are actually updated; if not set, only a syntax check is
3050    done.  If DEFAULTS is true the global options are written to the
3051    configuration files.  If LISTFP is set, no changes are done but the
3052    configuration file is printed to LISTFP in a colon separated format.
3053 
3054    Returns 0 on success or if the config file is not present; -1 is
3055    returned on error. */
3056 int
gc_process_gpgconf_conf(const char * fname_arg,int update,int defaults,estream_t listfp)3057 gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
3058                          estream_t listfp)
3059 {
3060   int result = 0;
3061   char *line = NULL;
3062   size_t line_len = 0;
3063   ssize_t length;
3064   gpgrt_stream_t config;
3065   int lineno = 0;
3066   int in_rule = 0;
3067   int got_match = 0;
3068   int runtime[GC_COMPONENT_NR] = { 0 };
3069   int component_id;
3070   char *fname;
3071 
3072   if (fname_arg)
3073     fname = xstrdup (fname_arg);
3074   else
3075     fname = make_filename (gnupg_sysconfdir (), GPGCONF_NAME EXTSEP_S "conf",
3076                            NULL);
3077 
3078   config = gpgrt_fopen (fname, "r");
3079   if (!config)
3080     {
3081       /* Do not print an error if the file is not available, except
3082          when running in syntax check mode.  */
3083       if (errno != ENOENT || !update)
3084         {
3085           gc_error (0, errno, "can't open global config file '%s'", fname);
3086           result = -1;
3087         }
3088       xfree (fname);
3089       return result;
3090     }
3091 
3092   while ((length = gpgrt_read_line (config, &line, &line_len, NULL)) > 0)
3093     {
3094       char *key, *compname, *option, *flags, *value;
3095       char *empty;
3096       gc_option_t *option_info = NULL;
3097       char *p;
3098       int is_continuation;
3099 
3100       lineno++;
3101       key = line;
3102       while (*key == ' ' || *key == '\t')
3103         key++;
3104       if (!*key || *key == '#' || *key == '\r' || *key == '\n')
3105         continue;
3106 
3107       is_continuation = (key != line);
3108 
3109       /* Parse the key field.  */
3110       if (!is_continuation && got_match)
3111         break;  /* Finish after the first match.  */
3112       else if (!is_continuation)
3113         {
3114           in_rule = 0;
3115           for (p=key+1; *p && !strchr (" \t\r\n", *p); p++)
3116             ;
3117           if (!*p)
3118             {
3119               gc_error (0, 0, "missing rule at '%s', line %d", fname, lineno);
3120               result = -1;
3121               gpgconf_write_status (STATUS_WARNING,
3122                                     "gpgconf.conf %d file '%s' line %d "
3123                                     "missing rule",
3124                                     GPG_ERR_SYNTAX, fname, lineno);
3125               continue;
3126             }
3127           *p++ = 0;
3128           compname = p;
3129         }
3130       else if (!in_rule)
3131         {
3132           gc_error (0, 0, "continuation but no rule at '%s', line %d",
3133                     fname, lineno);
3134           result = -1;
3135           continue;
3136         }
3137       else
3138         {
3139           compname = key;
3140           key = NULL;
3141         }
3142 
3143       in_rule = 1;
3144 
3145       /* Parse the component.  */
3146       while (*compname == ' ' || *compname == '\t')
3147         compname++;
3148       for (p=compname; *p && !strchr (" \t\r\n", *p); p++)
3149         ;
3150       if (p == compname)
3151         {
3152           gc_error (0, 0, "missing component at '%s', line %d",
3153                     fname, lineno);
3154           gpgconf_write_status (STATUS_WARNING,
3155                                 "gpgconf.conf %d file '%s' line %d "
3156                                 " missing component",
3157                                 GPG_ERR_NO_NAME, fname, lineno);
3158           result = -1;
3159           continue;
3160         }
3161       empty = p;
3162       *p++ = 0;
3163       option = p;
3164       component_id = gc_component_find (compname);
3165       if (component_id < 0)
3166         {
3167           gc_error (0, 0, "unknown component at '%s', line %d",
3168                     fname, lineno);
3169           gpgconf_write_status (STATUS_WARNING,
3170                                 "gpgconf.conf %d file '%s' line %d "
3171                                 "unknown component",
3172                                 GPG_ERR_UNKNOWN_NAME, fname, lineno);
3173           result = -1;
3174         }
3175 
3176       /* Parse the option name.  */
3177       while (*option == ' ' || *option == '\t')
3178         option++;
3179       for (p=option; *p && !strchr (" \t\r\n", *p); p++)
3180         ;
3181       if (p == option)
3182         {
3183           gc_error (0, 0, "missing option at '%s', line %d",
3184                     fname, lineno);
3185           gpgconf_write_status (STATUS_WARNING,
3186                                 "gpgconf.conf %d file '%s' line %d "
3187                                 "missing option",
3188                                 GPG_ERR_INV_NAME, fname, lineno);
3189           result = -1;
3190           continue;
3191         }
3192       *p++ = 0;
3193       flags = p;
3194       if ( component_id != -1)
3195         {
3196           /* We need to make sure that we got the option list for the
3197            * component.  */
3198           if (!gc_component[component_id].options)
3199             gc_component_retrieve_options (component_id);
3200           option_info = find_option (component_id, option);
3201           if (!option_info)
3202             {
3203               gc_error (0, 0, "unknown option '%s' at '%s', line %d",
3204                         option, fname, lineno);
3205               gpgconf_write_status (STATUS_WARNING,
3206                                     "gpgconf.conf %d file '%s' line %d "
3207                                     "unknown option",
3208                                     GPG_ERR_UNKNOWN_OPTION, fname, lineno);
3209               result = -1;
3210             }
3211         }
3212 
3213 
3214       /* Parse the optional flags.  */
3215       while (*flags == ' ' || *flags == '\t')
3216         flags++;
3217       if (*flags == '[')
3218         {
3219           flags++;
3220           p = strchr (flags, ']');
3221           if (!p)
3222             {
3223               gc_error (0, 0, "syntax error in rule at '%s', line %d",
3224                         fname, lineno);
3225               gpgconf_write_status (STATUS_WARNING,
3226                                     "gpgconf.conf %d file '%s' line %d "
3227                                     "syntax error in rule",
3228                                     GPG_ERR_SYNTAX, fname, lineno);
3229               result = -1;
3230               continue;
3231             }
3232           *p++ = 0;
3233           value = p;
3234         }
3235       else  /* No flags given.  */
3236         {
3237           value = flags;
3238           flags = NULL;
3239         }
3240 
3241       /* Parse the optional value.  */
3242       while (*value == ' ' || *value == '\t')
3243        value++;
3244       for (p=value; *p && !strchr ("\r\n", *p); p++)
3245         ;
3246       if (p == value)
3247         value = empty; /* No value given; let it point to an empty string.  */
3248       else
3249         {
3250           /* Strip trailing white space.  */
3251           *p = 0;
3252           for (p--; p > value && (*p == ' ' || *p == '\t'); p--)
3253             *p = 0;
3254         }
3255 
3256       /* Check flag combinations.  */
3257       if (!flags)
3258         ;
3259       else if (!strcmp (flags, "default"))
3260         {
3261           if (*value)
3262             {
3263               gc_error (0, 0, "flag \"default\" may not be combined "
3264                         "with a value at '%s', line %d",
3265                         fname, lineno);
3266               result = -1;
3267             }
3268         }
3269       else if (!strcmp (flags, "change"))
3270         ;
3271       else if (!strcmp (flags, "no-change"))
3272         ;
3273       else
3274         {
3275           gc_error (0, 0, "unknown flag at '%s', line %d",
3276                     fname, lineno);
3277           result = -1;
3278         }
3279 
3280       /* In list mode we print out all records.  */
3281       if (listfp && !result)
3282         {
3283           /* If this is a new ruleset, print a key record.  */
3284           if (!is_continuation)
3285             {
3286               char *group = strchr (key, ':');
3287               if (group)
3288                 {
3289                   *group++ = 0;
3290                   if ((p = strchr (group, ':')))
3291                     *p = 0; /* We better strip any extra stuff. */
3292                 }
3293 
3294               es_fprintf (listfp, "k:%s:", gc_percent_escape (key));
3295               es_fprintf (listfp, "%s\n", group? gc_percent_escape (group):"");
3296             }
3297 
3298           /* All other lines are rule records.  */
3299           es_fprintf (listfp, "r:::%s:%s:%s:",
3300                       gc_component[component_id].name,
3301                       option_info->name? option_info->name : "",
3302                       flags? flags : "");
3303           if (value != empty)
3304             es_fprintf (listfp, "\"%s", gc_percent_escape (value));
3305 
3306           es_putc ('\n', listfp);
3307         }
3308 
3309       /* Check whether the key matches but do this only if we are not
3310          running in syntax check mode. */
3311       if ( update
3312            && !result && !listfp
3313            && (got_match || (key && key_matches_user_or_group (key))) )
3314         {
3315           int newflags = 0;
3316 
3317           got_match = 1;
3318 
3319           /* Apply the flags from gpgconf.conf.  */
3320           if (!flags)
3321             ;
3322           else if (!strcmp (flags, "default"))
3323             newflags |= GC_OPT_FLAG_DEFAULT;
3324           else if (!strcmp (flags, "no-change"))
3325             option_info->no_change = 1;
3326           else if (!strcmp (flags, "change"))
3327             option_info->no_change = 0;
3328 
3329           if (defaults)
3330             {
3331               /* Here we explicitly allow updating the value again.  */
3332               if (newflags)
3333                 {
3334                   option_info->new_flags = 0;
3335                 }
3336               if (*value)
3337                 {
3338                   xfree (option_info->new_value);
3339                   option_info->new_value = NULL;
3340                 }
3341               change_one_value (component_id, option_info,
3342                                 runtime, newflags, value, 0);
3343             }
3344         }
3345     }
3346 
3347   if (length < 0 || gpgrt_ferror (config))
3348     {
3349       gc_error (0, errno, "error reading from '%s'", fname);
3350       result = -1;
3351     }
3352   if (gpgrt_fclose (config))
3353     gc_error (0, errno, "error closing '%s'", fname);
3354 
3355   xfree (line);
3356 
3357   /* If it all worked, process the options. */
3358   if (!result && update && defaults && !listfp)
3359     {
3360       /* We need to switch off the runtime update, so that we can do
3361          it later all at once. */
3362       int save_opt_runtime = opt.runtime;
3363       opt.runtime = 0;
3364 
3365       for (component_id = 0; component_id < GC_COMPONENT_NR; component_id++)
3366         {
3367           gc_component_change_options (component_id, NULL, NULL, 0);
3368         }
3369       opt.runtime = save_opt_runtime;
3370 
3371       if (opt.runtime)
3372         {
3373           for (component_id = 0; component_id < GC_COMPONENT_NR; component_id++)
3374             if (runtime[component_id]
3375                 && gc_component[component_id].runtime_change)
3376               (*gc_component[component_id].runtime_change) (0);
3377         }
3378     }
3379 
3380   xfree (fname);
3381   return result;
3382 }
3383 
3384 
3385 /*
3386  * Apply the profile FNAME to all known configure files.
3387  */
3388 gpg_error_t
gc_apply_profile(const char * fname)3389 gc_apply_profile (const char *fname)
3390 {
3391   gpg_error_t err;
3392   char *fname_buffer = NULL;
3393   char *line = NULL;
3394   size_t line_len = 0;
3395   ssize_t length;
3396   estream_t fp;
3397   int lineno = 0;
3398   int runtime[GC_COMPONENT_NR] =  { 0 };
3399   int component_id = -1;
3400   int skip_section = 0;
3401   int error_count = 0;
3402   int newflags;
3403 
3404   if (!fname)
3405     fname = "-";
3406 
3407 
3408   if (!(!strcmp (fname, "-")
3409         || strchr (fname, '/')
3410 #ifdef HAVE_W32_SYSTEM
3411         || strchr (fname, '\\')
3412 #endif
3413         || strchr (fname, '.')))
3414     {
3415       /* FNAME looks like a standard profile name.  Check whether one
3416        * is installed and use that instead of the given file name.  */
3417       fname_buffer = xstrconcat (gnupg_datadir (), DIRSEP_S,
3418                                  fname, ".prf", NULL);
3419       if (!gnupg_access (fname_buffer, F_OK))
3420         fname = fname_buffer;
3421     }
3422 
3423   fp = !strcmp (fname, "-")? es_stdin : es_fopen (fname, "r");
3424   if (!fp)
3425     {
3426       err = gpg_error_from_syserror ();
3427       log_error ("can't open '%s': %s\n", fname, gpg_strerror (err));
3428       return err;
3429     }
3430 
3431   if (opt.verbose)
3432     log_info ("applying profile '%s'\n", fname);
3433 
3434   err = 0;
3435   while ((length = es_read_line (fp, &line, &line_len, NULL)) > 0)
3436     {
3437       char *name, *flags, *value;
3438       gc_option_t *option_info = NULL;
3439       char *p;
3440 
3441       lineno++;
3442       name = line;
3443       while (*name == ' ' || *name == '\t')
3444         name++;
3445       if (!*name || *name == '#' || *name == '\r' || *name == '\n')
3446         continue;
3447       trim_trailing_spaces (name);
3448 
3449       /* Check whether this is a new section.  */
3450       if (*name == '[')
3451         {
3452           name++;
3453           skip_section = 0;
3454           /* New section: Get the name of the component.  */
3455           p = strchr (name, ']');
3456           if (!p)
3457             {
3458               error_count++;
3459               log_info ("%s:%d:%d: error: syntax error in section tag\n",
3460                         fname, lineno, (int)(name - line));
3461               skip_section = 1;
3462               continue;
3463             }
3464           *p++ = 0;
3465           if (*p)
3466             log_info ("%s:%d:%d: warning: garbage after section tag\n",
3467                       fname, lineno, (int)(p - line));
3468 
3469           trim_spaces (name);
3470           component_id = gc_component_find (name);
3471           if (component_id < 0)
3472             {
3473               log_info ("%s:%d:%d: warning: skipping unknown section '%s'\n",
3474                         fname, lineno, (int)(name - line), name );
3475               skip_section = 1;
3476             }
3477           continue;
3478         }
3479 
3480       if (skip_section)
3481         continue;
3482       if (component_id < 0)
3483         {
3484           error_count++;
3485           log_info ("%s:%d:%d: error: not in a valid section\n",
3486                     fname, lineno, (int)(name - line));
3487           skip_section = 1;
3488           continue;
3489         }
3490 
3491       /* Parse the option name.  */
3492       for (p = name; *p && !spacep (p); p++)
3493         ;
3494       *p++ = 0;
3495       value = p;
3496 
3497       option_info = find_option (component_id, name);
3498       if (!option_info)
3499         {
3500           error_count++;
3501           log_info ("%s:%d:%d: error: unknown option '%s' in section '%s'\n",
3502                     fname, lineno, (int)(name - line),
3503                     name, gc_component[component_id].name);
3504           continue;
3505         }
3506 
3507       /* Parse the optional flags. */
3508       trim_spaces (value);
3509       flags = value;
3510       if (*flags == '[')
3511         {
3512           flags++;
3513           p = strchr (flags, ']');
3514           if (!p)
3515             {
3516               log_info ("%s:%d:%d: warning: invalid flag specification\n",
3517                         fname, lineno, (int)(p - line));
3518               continue;
3519             }
3520           *p++ = 0;
3521           value = p;
3522           trim_spaces (value);
3523         }
3524       else /* No flags given.  */
3525         flags = NULL;
3526 
3527       /* Set required defaults.  */
3528       if (gc_arg_type[option_info->arg_type].fallback == GC_ARG_TYPE_NONE
3529           && !*value)
3530         value = "1";
3531 
3532       /* Check and save this option.  */
3533       newflags = 0;
3534       if (flags && !strcmp (flags, "default"))
3535         newflags |= GC_OPT_FLAG_DEFAULT;
3536 
3537       if (newflags)
3538         option_info->new_flags = 0;
3539       if (*value)
3540         {
3541           xfree (option_info->new_value);
3542           option_info->new_value = NULL;
3543         }
3544       change_one_value (component_id, option_info, runtime, newflags, value, 1);
3545     }
3546 
3547   if (length < 0 || es_ferror (fp))
3548     {
3549       err = gpg_error_from_syserror ();
3550       error_count++;
3551       log_error (_("%s:%u: read error: %s\n"),
3552                  fname, lineno, gpg_strerror (err));
3553     }
3554   if (es_fclose (fp))
3555     log_error (_("error closing '%s'\n"), fname);
3556   if (error_count)
3557     log_error (_("error parsing '%s'\n"), fname);
3558 
3559   xfree (line);
3560 
3561   /* If it all worked, process the options. */
3562   if (!err)
3563     {
3564       /* We need to switch off the runtime update, so that we can do
3565          it later all at once. */
3566       int save_opt_runtime = opt.runtime;
3567       opt.runtime = 0;
3568 
3569       for (component_id = 0; component_id < GC_COMPONENT_NR; component_id++)
3570         {
3571           gc_component_change_options (component_id, NULL, NULL, 1);
3572         }
3573       opt.runtime = save_opt_runtime;
3574 
3575       if (opt.runtime)
3576         {
3577           for (component_id = 0; component_id < GC_COMPONENT_NR; component_id++)
3578             if (runtime[component_id]
3579                 && gc_component[component_id].runtime_change)
3580               (*gc_component[component_id].runtime_change) (0);
3581         }
3582     }
3583 
3584   xfree (fname_buffer);
3585   return err;
3586 }
3587