[git] GnuPG - branch, master, updated. gnupg-2.1.16-139-g48671f2

by Werner Koch cvs at cvs.gnupg.org
Fri Dec 16 16:08:01 CET 2016


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, master has been updated
       via  48671f295ff233765689b6a73021f83ab845a28f (commit)
       via  76cd64a5baf6057b199c01f7999b327f1f4a87bc (commit)
       via  6ca3c28da46873416822bf6ab7893db6c56a49d6 (commit)
      from  12a5265afa7f87ad92fb571e0882e57b07a3c267 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 48671f295ff233765689b6a73021f83ab845a28f
Author: Werner Koch <wk at gnupg.org>
Date:   Fri Dec 16 16:02:02 2016 +0100

    gpg,sm: A few more option for --gpgconf-list.
    
    * g10/gpg.c (gpgconf_list): Add --compliance and
    --default-new-key-algo.
    (parse_compliance_option):
    * sm/gpgsm.c (main) <gpgconf-list>: Add --enable-crl-checks.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/g10/gpg.c b/g10/gpg.c
index cab5d53..a8f731b 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -1844,6 +1844,8 @@ gpgconf_list (const char *configfile)
   es_printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE);
   es_printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT);
   es_printf ("group:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("compliance:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT, "gnupg");
+  es_printf ("default-new-key-algo:%lu:\n", GC_OPT_FLAG_NONE);
 
   /* The next one is an info only item and should match the macros at
      the top of keygen.c  */
diff --git a/sm/gpgsm.c b/sm/gpgsm.c
index 79508e6..e0ad3e3 100644
--- a/sm/gpgsm.c
+++ b/sm/gpgsm.c
@@ -1719,6 +1719,7 @@ main ( int argc, char **argv)
 	es_printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT);
 	es_printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE);
         es_printf ("disable-crl-checks:%lu:\n", GC_OPT_FLAG_NONE);
+        es_printf ("enable-crl-checks:%lu:\n", GC_OPT_FLAG_NONE);
         es_printf ("disable-trusted-cert-crl-check:%lu:\n", GC_OPT_FLAG_NONE);
         es_printf ("enable-ocsp:%lu:\n", GC_OPT_FLAG_NONE);
         es_printf ("include-certs:%lu:%d:\n", GC_OPT_FLAG_DEFAULT,

commit 76cd64a5baf6057b199c01f7999b327f1f4a87bc
Author: Werner Koch <wk at gnupg.org>
Date:   Fri Dec 16 16:00:15 2016 +0100

    gpgconf: New command --apply-profile.
    
    * tools/gpgconf.c (aApplyProfile): New.
    (opts): New command --apply-profile.
    (main): Implement that command.
    * tools/gpgconf-comp.c (option_check_validity): Add arg VERBATIM.
    (change_options_program): Ditto.
    (change_one_value): Ditto.
    (gc_component_change_options): Ditto.
    (gc_apply_profile): New.
    
    --
    
    Here is an example for a profile
    
    --8<---------------cut here---------------start------------->8---
    # foo.prf - Sample profile
    
    [gpg]
    compliance de-vs
    default-new-key-algo brainpoolP256r1+brainpoolP256r1
    
    [gpgsm]
    enable-crl-checks
    
    [gpg-agent]
    default-cache-ttl 900
    max-cache-ttl [] 3600
    no-allow-mark-trusted
    no-allow-external-cache
    enforce-passphrase-constraints
    min-passphrase-len 9
    min-passphrase-nonalpha 0
    
    [dirmngr]
    keyserver hkp://keys.gnupg.net
    allow-ocsp
    --8<---------------cut here---------------end--------------->8---
    
    Note that flags inside of brackets are allowed after the option name.
    The only defined flag for now is "[default]".  In case the value
    starts with a bracket, it is possible to insert "[]" as a nop-flag.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/doc/Makefile.am b/doc/Makefile.am
index 5638530..0c2f2c9 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -40,6 +40,8 @@ helpfiles = help.txt help.be.txt help.ca.txt help.cs.txt		\
             help.pt_BR.txt help.ro.txt help.ru.txt help.sk.txt		\
             help.sv.txt help.tr.txt help.zh_CN.txt help.zh_TW.txt
 
+profiles =
+
 EXTRA_DIST = samplekeys.asc mksamplekeys com-certs.pem qualified.txt \
 	     gnupg-logo.eps gnupg-logo.pdf gnupg-logo.png gnupg-logo-tr.png \
 	     gnupg-module-overview.png gnupg-module-overview.pdf \
@@ -54,7 +56,7 @@ BUILT_SOURCES = gnupg-module-overview.png gnupg-module-overview.pdf \
 
 info_TEXINFOS = gnupg.texi
 
-dist_pkgdata_DATA =  $(helpfiles)
+dist_pkgdata_DATA =  $(helpfiles) $(profiles)
 
 nobase_dist_doc_DATA = FAQ DETAILS HACKING DCO TRANSLATE OpenPGP KEYSERVER \
                        $(examples)
diff --git a/doc/examples/gpgconf.conf b/doc/examples/gpgconf.conf
index ec8685a..f401602 100644
--- a/doc/examples/gpgconf.conf
+++ b/doc/examples/gpgconf.conf
@@ -8,7 +8,7 @@
 # Empty lines and comment lines, indicated by a hash mark as first non
 # white space character, are ignored.  The line is separated by white
 # space into fields. The first field is used to match the user or
-# group and must start at the first column, the file is processes
+# group and must start at the first column, the file is processed
 # sequential until a matching rule is found.  A rule may contain
 # several lines; continuation lines are indicated by a indenting them.
 #
@@ -23,7 +23,7 @@
 #   *           - Matches any user.
 # All other variants are not defined and reserved for future use.
 #
-# <component> and <option> are as specified by gpgconf. 
+# <component> and <option> are as specified by gpgconf.
 # <flag> may be one of:
 #   default     - Delete the option so that the default is used.
 #   no-change   - Mark the field as non changeable by gpgconf.
@@ -35,7 +35,7 @@
 #         gpg-agent min-passphrase-len 6
 #
 # *       gpg-agent min-passphrase-len [no-change] 8
-#         gpg-agent min-passphrase-nonalpha [no-change] 1 
+#         gpg-agent min-passphrase-nonalpha [no-change] 1
 #         gpg-agent max-passphrase-days [no-change] 700
 #         gpg-agent enable-passphrase-history [no-change]
 #         gpg-agent enforce-passphrase-constraints [default]
@@ -44,7 +44,7 @@
 #         gpg-agent max-cache-ttl-ssh [no-change] 10800
 #         gpg-agent allow-mark-trusted [default]
 #         gpg-agent allow-mark-trusted [no-change]
-#         gpgsm     enable-ocsp           
+#         gpgsm     enable-ocsp
 #===========
 # All users in the group "staff" are allowed to change the value for
 # --allow-mark-trusted; gpgconf's default is not to allow a change
diff --git a/doc/tools.texi b/doc/tools.texi
index b1ed615..d321b69 100644
--- a/doc/tools.texi
+++ b/doc/tools.texi
@@ -279,6 +279,15 @@ Change the options of the component @var{component}.
 @item --check-options @var{component}
 Check the options for the component @var{component}.
 
+ at item --apply-profile @var{file}
+Apply the configuration settings listed in @var{file} to the
+configuration files.  If @var{file} has no suffix and no slashes the
+command first tries to read a file with the suffix @code{.prf} from
+the the data directory (@code{gpgconf --list-dirs datadir}) before it
+reads the file verbatim.  A profile is divided into sections using the
+bracketed  component name.  Each section then lists the option which
+shall go into the respective configuration file.
+
 @item --apply-defaults
 Update all configuration files with values taken from the global
 configuration file (usually @file{/etc/gnupg/gpgconf.conf}).
diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
index 3fddc7c..e45857d 100644
--- a/tools/gpgconf-comp.c
+++ b/tools/gpgconf-comp.c
@@ -1,6 +1,6 @@
 /* gpgconf-comp.c - Configuration utility for GnuPG.
- * Copyright (C) 2004, 2007, 2008, 2009, 2010,
- *               2011 Free Software Foundation, Inc.
+ * Copyright (C) 2004, 2007-2011 Free Software Foundation, Inc.
+ * Copyright (C) 2016 Werner Koch
  *
  * This file is part of GnuPG.
  *
@@ -703,9 +703,15 @@ static gc_option_t gc_options_gpg[] =
    { "group", GC_OPT_FLAG_LIST, GC_LEVEL_ADVANCED,
      "gnupg", N_("|SPEC|set up email aliases"),
      GC_ARG_TYPE_ALIAS_LIST, GC_BACKEND_GPG },
-   { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
-     "gnupg", "|FILE|read options from FILE",
+   { "options", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
+     NULL, NULL,
      GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG },
+   { "compliance", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
+     NULL, NULL,
+     GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
+   { "default-new-key-algo", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
+     NULL, NULL,
+     GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
    { "default_pubkey_algo",
      (GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_NO_CHANGE), GC_LEVEL_INVISIBLE,
      NULL, NULL,
@@ -816,6 +822,9 @@ static gc_option_t gc_options_gpgsm[] =
    { "disable-crl-checks", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
      "gnupg", "never consult a CRL",
      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
+   { "enable-crl-checks", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
+     NULL, NULL,
+     GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
    { "disable-trusted-cert-crl-check", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
      "gnupg", N_("do not check CRLs for root certificates"),
      GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM },
@@ -2333,11 +2342,13 @@ gc_component_retrieve_options (int component)
 
 

 /* Perform a simple validity check based on the type.  Return in
-   NEW_VALUE_NR the value of the number in NEW_VALUE if OPTION is of
-   type GC_ARG_TYPE_NONE.  */
+ * NEW_VALUE_NR the value of the number in NEW_VALUE if OPTION is of
+ * type GC_ARG_TYPE_NONE.  If VERBATIM is set the profile parsing mode
+ * is used. */
 static void
 option_check_validity (gc_option_t *option, unsigned long flags,
-		       char *new_value, unsigned long *new_value_nr)
+		       char *new_value, unsigned long *new_value_nr,
+                       int verbatim)
 {
   char *arg;
 
@@ -2391,17 +2402,17 @@ option_check_validity (gc_option_t *option, unsigned long flags,
   arg = new_value;
   do
     {
-      if (*arg == '\0' || *arg == ',')
+      if (*arg == '\0' || (*arg == ',' && !verbatim))
 	{
 	  if (!(option->flags & GC_OPT_FLAG_ARG_OPT))
 	    gc_error (1, 0, "argument required for option %s", option->name);
 
-	  if (*arg == ',' && !(option->flags & GC_OPT_FLAG_LIST))
+	  if (*arg == ',' && !verbatim && !(option->flags & GC_OPT_FLAG_LIST))
 	    gc_error (1, 0, "list found for non-list option %s", option->name);
 	}
       else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING)
 	{
-	  if (*arg != '"')
+	  if (*arg != '"' && !verbatim)
 	    gc_error (1, 0, "string argument for option %s must begin "
 		      "with a quote (\") character", option->name);
 
@@ -2409,7 +2420,7 @@ option_check_validity (gc_option_t *option, unsigned long flags,
 	     we do not quote arguments in configuration files, and
 	     thus no argument is indistinguishable from the empty
 	     string.  */
-	  if (arg[1] == '\0' || arg[1] == ',')
+	  if (arg[1] == '\0' || (arg[1] == ',' && !verbatim))
 	    gc_error (1, 0, "empty string argument for option %s is "
 		      "currently not allowed.  Please report this!",
 		      option->name);
@@ -2426,7 +2437,7 @@ option_check_validity (gc_option_t *option, unsigned long flags,
 	    gc_error (1, errno, "invalid argument for option %s",
 		      option->name);
 
-	  if (*arg != '\0' && *arg != ',')
+	  if (*arg != '\0' && (*arg != ',' || verbatim))
 	    gc_error (1, 0, "garbage after argument for option %s",
 		      option->name);
 	}
@@ -2442,17 +2453,18 @@ option_check_validity (gc_option_t *option, unsigned long flags,
 	    gc_error (1, errno, "invalid argument for option %s",
 		      option->name);
 
-	  if (*arg != '\0' && *arg != ',')
+	  if (*arg != '\0' && (*arg != ',' || verbatim))
 	    gc_error (1, 0, "garbage after argument for option %s",
 		      option->name);
 	}
-      arg = strchr (arg, ',');
+      arg = verbatim? strchr (arg, ',') : NULL;
       if (arg)
 	arg++;
     }
   while (arg && *arg);
 }
 
+
 #ifdef HAVE_W32_SYSTEM
 int
 copy_file (const char *src_name, const char *dst_name)
@@ -2816,11 +2828,13 @@ change_options_file (gc_component_t component, gc_backend_t backend,
 
 
 /* Create and verify the new configuration file for the specified
-   backend and component.  Returns 0 on success and -1 on error.  */
+ * backend and component.  Returns 0 on success and -1 on error.  If
+ * VERBATIM is set the profile mode is used. */
 static int
 change_options_program (gc_component_t component, gc_backend_t backend,
 			char **src_filenamep, char **dest_filenamep,
-			char **orig_filenamep)
+			char **orig_filenamep,
+                        int verbatim)
 {
   static const char marker[] = "###+++--- " GPGCONF_DISP_NAME " ---+++###";
   /* True if we are within the marker in the config file.  */
@@ -3008,15 +3022,20 @@ change_options_program (gc_component_t component, gc_backend_t backend,
 		{
 		  char *end;
 
-		  assert (*arg == '"');
-		  arg++;
+                  if (!verbatim)
+                    {
+                      log_assert (*arg == '"');
+                      arg++;
 
-		  end = strchr (arg, ',');
-		  if (end)
-		    *end = '\0';
+                      end = strchr (arg, ',');
+                      if (end)
+                        *end = '\0';
+                    }
+                  else
+                    end = NULL;
 
 		  fprintf (src_file, "%s %s\n", option->name,
-			   percent_deescape (arg));
+			   verbatim? arg : percent_deescape (arg));
 		  if (ferror (src_file))
 		    goto change_one_err;
 
@@ -3117,14 +3136,15 @@ change_options_program (gc_component_t component, gc_backend_t backend,
 
 
 /* Common code for gc_component_change_options and
-   gc_process_gpgconf_conf.  */
+ * gc_process_gpgconf_conf.  If VERBATIM is set the profile parsing
+ * mode is used.  */
 static void
 change_one_value (gc_option_t *option, int *runtime,
-                  unsigned long flags, char *new_value)
+                  unsigned long flags, char *new_value, int verbatim)
 {
   unsigned long new_value_nr = 0;
 
-  option_check_validity (option, flags, new_value, &new_value_nr);
+  option_check_validity (option, flags, new_value, &new_value_nr, verbatim);
 
   if (option->flags & GC_OPT_FLAG_RUNTIME)
     runtime[option->backend] = 1;
@@ -3158,9 +3178,10 @@ change_one_value (gc_option_t *option, int *runtime,
 
 /* Read the modifications from IN and apply them.  If IN is NULL the
    modifications are expected to already have been set to the global
-   table. */
+   table.  If VERBATIM is set the profile mode is used.  */
 void
-gc_component_change_options (int component, estream_t in, estream_t out)
+gc_component_change_options (int component, estream_t in, estream_t out,
+                             int verbatim)
 {
   int err = 0;
   int runtime[GC_BACKEND_NR];
@@ -3247,7 +3268,7 @@ gc_component_change_options (int component, estream_t in, estream_t out)
               continue;
             }
 
-          change_one_value (option, runtime, flags, new_value);
+          change_one_value (option, runtime, flags, new_value, 0);
         }
     }
 
@@ -3271,7 +3292,8 @@ gc_component_change_options (int component, estream_t in, estream_t out)
 	  err = change_options_program (component, option->backend,
 					&src_filename[option->backend],
 					&dest_filename[option->backend],
-					&orig_filename[option->backend]);
+					&orig_filename[option->backend],
+                                        verbatim);
 	  if (! err)
 	    {
 	      /* External verification.  */
@@ -3789,7 +3811,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
                   xfree (option_info->new_value);
                   option_info->new_value = NULL;
                 }
-              change_one_value (option_info, runtime, newflags, value);
+              change_one_value (option_info, runtime, newflags, value, 0);
             }
         }
     }
@@ -3814,7 +3836,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
 
       for (component_id = 0; component_id < GC_COMPONENT_NR; component_id++)
         {
-          gc_component_change_options (component_id, NULL, NULL);
+          gc_component_change_options (component_id, NULL, NULL, 0);
         }
       opt.runtime = save_opt_runtime;
 
@@ -3829,3 +3851,210 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
   xfree (fname);
   return result;
 }
+
+
+/*
+ * Apply the profile FNAME to all known configure files.
+ */
+gpg_error_t
+gc_apply_profile (const char *fname)
+{
+  gpg_error_t err;
+  char *fname_buffer = NULL;
+  char *line = NULL;
+  size_t line_len = 0;
+  ssize_t length;
+  estream_t fp;
+  int lineno = 0;
+  int runtime[GC_BACKEND_NR];
+  int backend_id;
+  int component_id = -1;
+  int skip_section = 0;
+  int error_count = 0;
+  int newflags;
+
+  if (!fname)
+    fname = "-";
+
+  for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)
+    runtime[backend_id] = 0;
+
+
+  if (!(!strcmp (fname, "-")
+        || strchr (fname, '/')
+#ifdef HAVE_W32_SYSTEM
+        || strchr (fname, '\\')
+#endif
+        || strchr (fname, '.')))
+    {
+      /* FNAME looks like a standard profile name.  Check whether one
+       * is installed and use that instead of the given file name.  */
+      fname_buffer = xstrconcat (gnupg_datadir (), DIRSEP_S,
+                                 fname, ".prf", NULL);
+      if (!access (fname_buffer, F_OK))
+        fname = fname_buffer;
+    }
+
+  fp = !strcmp (fname, "-")? es_stdin : es_fopen (fname, "r");
+  if (!fp)
+    {
+      err = gpg_error_from_syserror ();
+      log_error ("can't open '%s': %s\n", fname, gpg_strerror (err));
+      return err;
+    }
+
+  if (opt.verbose)
+    log_info ("applying profile '%s'\n", fname);
+
+  err = 0;
+  while ((length = es_read_line (fp, &line, &line_len, NULL)) > 0)
+    {
+      char *name, *flags, *value;
+      gc_option_t *option_info = NULL;
+      char *p;
+
+      lineno++;
+      name = line;
+      while (*name == ' ' || *name == '\t')
+        name++;
+      if (!*name || *name == '#' || *name == '\r' || *name == '\n')
+        continue;
+      trim_trailing_spaces (name);
+
+      /* Check whether this is a new section.  */
+      if (*name == '[')
+        {
+          name++;
+          skip_section = 0;
+          /* New section: Get the name of the component.  */
+          p = strchr (name, ']');
+          if (!p)
+            {
+              error_count++;
+              log_info ("%s:%d:%d: error: syntax error in section tag\n",
+                        fname, lineno, (int)(name - line));
+              skip_section = 1;
+              continue;
+            }
+          *p++ = 0;
+          if (*p)
+            log_info ("%s:%d:%d: warning: garbage after section tag\n",
+                      fname, lineno, (int)(p - line));
+
+          trim_spaces (name);
+          component_id = gc_component_find (name);
+          if (component_id < 0)
+            {
+              log_info ("%s:%d:%d: warning: skipping unknown section '%s'\n",
+                        fname, lineno, (int)(name - line), name );
+              skip_section = 1;
+            }
+          continue;
+        }
+
+      if (skip_section)
+        continue;
+      if (component_id < 0)
+        {
+          error_count++;
+          log_info ("%s:%d:%d: error: not in a valid section\n",
+                    fname, lineno, (int)(name - line));
+          skip_section = 1;
+          continue;
+        }
+
+      /* Parse the option name.  */
+      for (p = name; *p && !spacep (p); p++)
+        ;
+      *p++ = 0;
+      value = p;
+
+      option_info = find_option (component_id, name, GC_BACKEND_ANY);
+      if (!option_info)
+        {
+          error_count++;
+          log_info ("%s:%d:%d: error: unknown option '%s' in section '%s'\n",
+                    fname, lineno, (int)(name - line),
+                    name, gc_component[component_id].name);
+          continue;
+        }
+
+      /* Parse the optional flags. */
+      trim_spaces (value);
+      flags = value;
+      if (*flags == '[')
+        {
+          flags++;
+          p = strchr (flags, ']');
+          if (!p)
+            {
+              log_info ("%s:%d:%d: warning: invalid flag specification\n",
+                        fname, lineno, (int)(p - line));
+              continue;
+            }
+          *p++ = 0;
+          value = p;
+          trim_spaces (value);
+        }
+      else /* No flags given.  */
+        flags = NULL;
+
+      /* Set required defaults.  */
+      if (gc_arg_type[option_info->arg_type].fallback == GC_ARG_TYPE_NONE
+          && !*value)
+        value = "1";
+
+      /* Check and save this option.  */
+      newflags = 0;
+      if (flags && !strcmp (flags, "default"))
+        newflags |= GC_OPT_FLAG_DEFAULT;
+
+      if (newflags)
+        option_info->new_flags = 0;
+      if (*value)
+        {
+          xfree (option_info->new_value);
+          option_info->new_value = NULL;
+        }
+      change_one_value (option_info, runtime, newflags, value, 1);
+    }
+
+  if (length < 0 || es_ferror (fp))
+    {
+      err = gpg_error_from_syserror ();
+      error_count++;
+      log_error (_("%s:%u: read error: %s\n"),
+                 fname, lineno, gpg_strerror (err));
+    }
+  if (es_fclose (fp))
+    log_error (_("error closing '%s'\n"), fname);
+  if (error_count)
+    log_error (_("error parsing '%s'\n"), fname);
+
+  xfree (line);
+
+  /* If it all worked, process the options. */
+  if (!err)
+    {
+      /* We need to switch off the runtime update, so that we can do
+         it later all at once. */
+      int save_opt_runtime = opt.runtime;
+      opt.runtime = 0;
+
+      for (component_id = 0; component_id < GC_COMPONENT_NR; component_id++)
+        {
+          gc_component_change_options (component_id, NULL, NULL, 1);
+        }
+      opt.runtime = save_opt_runtime;
+
+      if (opt.runtime)
+        {
+          for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)
+            if (runtime[backend_id] && gc_backend[backend_id].runtime_change)
+              (*gc_backend[backend_id].runtime_change) (0);
+        }
+    }
+
+  xfree (fname_buffer);
+  return err;
+}
diff --git a/tools/gpgconf.c b/tools/gpgconf.c
index d056f4f..af65424 100644
--- a/tools/gpgconf.c
+++ b/tools/gpgconf.c
@@ -60,6 +60,7 @@ enum cmd_and_opt_values
     aKill,
     aCreateSocketDir,
     aRemoveSocketDir,
+    aApplyProfile,
     aReload
   };
 
@@ -76,6 +77,8 @@ static ARGPARSE_OPTS opts[] =
     { aCheckOptions, "check-options", 256, N_("|COMPONENT|check options") },
     { aApplyDefaults, "apply-defaults", 256,
       N_("apply global default values") },
+    { aApplyProfile, "apply-profile", 256,
+      N_("|FILE|update configuration files using FILE") },
     { aListDirs, "list-dirs", 256,
       N_("get the configuration directories for @GPGCONF@") },
     { aListConfig,   "list-config", 256,
@@ -495,6 +498,7 @@ main (int argc, char **argv)
         case aChangeOptions:
         case aCheckOptions:
         case aApplyDefaults:
+        case aApplyProfile:
         case aListConfig:
         case aCheckConfig:
         case aQuerySWDB:
@@ -568,7 +572,8 @@ main (int argc, char **argv)
               if (cmd == aListOptions)
                 gc_component_list_options (idx, get_outfp (&outfp));
               else if (cmd == aChangeOptions)
-                gc_component_change_options (idx, es_stdin, get_outfp (&outfp));
+                gc_component_change_options (idx, es_stdin,
+                                             get_outfp (&outfp), 0);
             }
 	}
       break;
@@ -659,6 +664,12 @@ main (int argc, char **argv)
         exit (1);
       break;
 
+    case aApplyProfile:
+      gc_component_retrieve_options (-1);
+      if (gc_apply_profile (fname))
+        exit (1);
+      break;
+
     case aListDirs:
       /* Show the system configuration directories for gpgconf.  */
       get_outfp (&outfp);
diff --git a/tools/gpgconf.h b/tools/gpgconf.h
index e99042f..39d34b6 100644
--- a/tools/gpgconf.h
+++ b/tools/gpgconf.h
@@ -72,7 +72,8 @@ void gc_component_retrieve_options (int component);
 void gc_component_list_options (int component, estream_t out);
 
 /* Read the modifications from IN and apply them.  */
-void gc_component_change_options (int component, estream_t in, estream_t out);
+void gc_component_change_options (int component, estream_t in, estream_t out,
+                                  int verbatim);
 
 /* Check the options of a single component.  Returns 0 if everything
    is OK.  */
@@ -83,5 +84,8 @@ int gc_component_check_options (int component, estream_t out,
 int gc_process_gpgconf_conf (const char *fname, int update, int defaults,
                              estream_t listfp);
 
+/* Apply a profile.  */
+gpg_error_t gc_apply_profile (const char *fname);
+
 
 #endif /*GPGCONF_H*/

commit 6ca3c28da46873416822bf6ab7893db6c56a49d6
Author: Werner Koch <wk at gnupg.org>
Date:   Fri Dec 16 14:25:47 2016 +0100

    gpgconf: Fix --apply-defaults.
    
    * tools/gpgconf-comp.c: Skip pinentry also in process_all mode.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
index cd99c81..3fddc7c 100644
--- a/tools/gpgconf-comp.c
+++ b/tools/gpgconf-comp.c
@@ -2286,9 +2286,6 @@ gc_component_retrieve_options (int component)
   gc_backend_t backend;
   gc_option_t *option;
 
-  if (component == GC_COMPONENT_PINENTRY)
-    return; /* Dummy module for now.  */
-
   for (backend = 0; backend < GC_BACKEND_NR; backend++)
     backend_seen[backend] = 0;
 
@@ -2301,6 +2298,9 @@ gc_component_retrieve_options (int component)
 
   do
     {
+      if (component == GC_COMPONENT_PINENTRY)
+        continue; /* Skip this dummy component.  */
+
       option = gc_component[component].options;
 
       while (option && option->name)

-----------------------------------------------------------------------

Summary of changes:
 doc/Makefile.am           |   4 +-
 doc/examples/gpgconf.conf |   8 +-
 doc/tools.texi            |   9 ++
 g10/gpg.c                 |   2 +
 sm/gpgsm.c                |   1 +
 tools/gpgconf-comp.c      | 297 ++++++++++++++++++++++++++++++++++++++++------
 tools/gpgconf.c           |  13 +-
 tools/gpgconf.h           |   6 +-
 8 files changed, 299 insertions(+), 41 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list