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