tools/gpgtar: Handle '--directory' argument.
[gnupg.git] / tools / gpgconf-comp.c
index 4906994..5e4bd58 100644 (file)
@@ -44,7 +44,6 @@
 #endif
 
 /* For log_logv(), asctimestamp(), gnupg_get_time ().  */
-#define JNLIB_NEED_LOG_LOGV
 #include "util.h"
 #include "i18n.h"
 #include "exechelp.h"
@@ -87,7 +86,7 @@ gc_error (int status, int errnum, const char *fmt, ...)
   va_list arg_ptr;
 
   va_start (arg_ptr, fmt);
-  log_logv (JNLIB_LOG_ERROR, fmt, arg_ptr);
+  log_logv (GPGRT_LOG_ERROR, fmt, arg_ptr);
   va_end (arg_ptr);
 
   if (errnum)
@@ -107,6 +106,7 @@ gc_error (int status, int errnum, const char *fmt, ...)
 /* Forward declaration.  */
 static void gpg_agent_runtime_change (int killflag);
 static void scdaemon_runtime_change (int killflag);
+static void dirmngr_runtime_change (int killflag);
 
 /* Backend configuration.  Backends are used to decide how the default
    and current value of an option can be determined, and how the
@@ -180,20 +180,20 @@ static struct
 } gc_backend[GC_BACKEND_NR] =
   {
     { NULL },          /* GC_BACKEND_ANY dummy entry.  */
-    { GNUPG_NAME, GPGNAME, GNUPG_MODULE_NAME_GPG,
-      NULL, "gpgconf-gpg.conf" },
-    { "GPGSM", GPGSM_NAME, GNUPG_MODULE_NAME_GPGSM,
-      NULL, "gpgconf-gpgsm.conf" },
-    { "GPG Agent", GPG_AGENT_NAME, GNUPG_MODULE_NAME_AGENT,
-      gpg_agent_runtime_change, "gpgconf-gpg-agent.conf" },
-    { "SCDaemon", SCDAEMON_NAME, GNUPG_MODULE_NAME_SCDAEMON,
-      scdaemon_runtime_change, "gpgconf-scdaemon.conf" },
-    { "DirMngr", DIRMNGR_NAME, GNUPG_MODULE_NAME_DIRMNGR,
-      NULL, "gpgconf-dirmngr.conf" },
-    { "DirMngr LDAP Server List", NULL, 0,
+    { GPG_DISP_NAME, GPGNAME, GNUPG_MODULE_NAME_GPG,
+      NULL, GPGCONF_NAME "-" GPG_NAME ".conf" },
+    { GPGSM_DISP_NAME, GPGSM_NAME, GNUPG_MODULE_NAME_GPGSM,
+      NULL, GPGCONF_NAME "-" GPGSM_NAME ".conf" },
+    { GPG_AGENT_DISP_NAME, GPG_AGENT_NAME, GNUPG_MODULE_NAME_AGENT,
+      gpg_agent_runtime_change, GPGCONF_NAME"-" GPG_AGENT_NAME ".conf" },
+    { SCDAEMON_DISP_NAME, SCDAEMON_NAME, GNUPG_MODULE_NAME_SCDAEMON,
+      scdaemon_runtime_change, GPGCONF_NAME"-" SCDAEMON_NAME ".conf" },
+    { DIRMNGR_DISP_NAME, DIRMNGR_NAME, GNUPG_MODULE_NAME_DIRMNGR,
+      dirmngr_runtime_change, GPGCONF_NAME "-" DIRMNGR_NAME ".conf" },
+    { DIRMNGR_DISP_NAME " LDAP Server List", NULL, 0,
       NULL, "ldapserverlist-file", "LDAP Server" },
     { "Pinentry", "pinentry", GNUPG_MODULE_NAME_PINENTRY,
-      NULL, "gpgconf-pinentry.conf" },
+      NULL, GPGCONF_NAME "-pinentry.conf" },
   };
 
 \f
@@ -357,11 +357,6 @@ static struct
    several times.  A comma separated list of arguments is used as the
    argument value.  */
 #define GC_OPT_FLAG_LIST       (1UL << 2)
-/* The NO_CHANGE flag for an option indicates that the user should not
-   be allowed to change this option using the standard gpgconf method.
-   Frontends using gpgconf should grey out such options, so that only
-   the current value is displayed.  */
-#define GC_OPT_FLAG_NO_CHANGE   (1UL <<7)
 
 
 /* A human-readable description for each flag.  */
@@ -475,7 +470,8 @@ typedef struct gc_option gc_option_t;
 static gc_option_t gc_options_gpg_agent[] =
  {
    /* The configuration file to which we write the changes.  */
-   { "gpgconf-gpg-agent.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
+   { GPGCONF_NAME"-" GPG_AGENT_NAME ".conf",
+     GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
      NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG_AGENT },
 
    { "Monitor",
@@ -542,9 +538,19 @@ static gc_option_t gc_options_gpg_agent[] =
    { "ignore-cache-for-signing", GC_OPT_FLAG_RUNTIME,
      GC_LEVEL_BASIC, "gnupg", "do not use the PIN cache when signing",
      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
+   { "allow-emacs-pinentry", GC_OPT_FLAG_RUNTIME,
+     GC_LEVEL_ADVANCED,
+     "gnupg", "allow passphrase to be prompted through Emacs",
+     GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
+   { "no-allow-external-cache", GC_OPT_FLAG_RUNTIME,
+     GC_LEVEL_BASIC, "gnupg", "disallow the use of an external password cache",
+     GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
    { "no-allow-mark-trusted", GC_OPT_FLAG_RUNTIME,
      GC_LEVEL_ADVANCED, "gnupg", "disallow clients to mark keys as \"trusted\"",
      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
+   { "allow-loopback-pinentry", GC_OPT_FLAG_RUNTIME,
+     GC_LEVEL_EXPERT, "gnupg", "allow caller to override the pinentry",
+     GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
    { "no-grab", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT,
      "gnupg", "do not grab keyboard and mouse",
      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
@@ -589,7 +595,8 @@ static gc_option_t gc_options_gpg_agent[] =
 static gc_option_t gc_options_scdaemon[] =
  {
    /* The configuration file to which we write the changes.  */
-   { "gpgconf-scdaemon.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
+   { GPGCONF_NAME"-"SCDAEMON_NAME".conf",
+     GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
      NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_SCDAEMON },
 
    { "Monitor",
@@ -663,7 +670,8 @@ static gc_option_t gc_options_scdaemon[] =
 static gc_option_t gc_options_gpg[] =
  {
    /* The configuration file to which we write the changes.  */
-   { "gpgconf-gpg.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
+   { GPGCONF_NAME"-"GPG_NAME".conf",
+     GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
      NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG },
 
    { "Monitor",
@@ -716,8 +724,8 @@ static gc_option_t gc_options_gpg[] =
    { "Keyserver",
      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
      "gnupg", N_("Configuration for Keyservers") },
-   { "keyserver", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
-     "gnupg", N_("|URL|use keyserver at URL"),
+   { "keyserver", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
+     "gnupg", N_("|URL|use keyserver at URL"), /* Deprecated - use dirmngr */
      GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
    { "allow-pka-lookup", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
      "gnupg", N_("allow PKA lookups (DNS requests)"),
@@ -727,8 +735,6 @@ static gc_option_t gc_options_gpg[] =
      GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
 
 
-
-
    GC_OPTION_NULL
  };
 #endif /*BUILD_WITH_GPG*/
@@ -741,7 +747,8 @@ static gc_option_t gc_options_gpg[] =
 static gc_option_t gc_options_gpgsm[] =
  {
    /* The configuration file to which we write the changes.  */
-   { "gpgconf-gpgsm.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
+   { GPGCONF_NAME"-"GPGSM_NAME".conf",
+     GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
      NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_GPGSM },
 
    { "Monitor",
@@ -836,7 +843,8 @@ static gc_option_t gc_options_gpgsm[] =
 static gc_option_t gc_options_dirmngr[] =
  {
    /* The configuration file to which we write the changes.  */
-   { "gpgconf-dirmngr.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
+   { GPGCONF_NAME"-"DIRMNGR_NAME".conf",
+     GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
      NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_DIRMNGR },
 
    { "Monitor",
@@ -898,6 +906,20 @@ static gc_option_t gc_options_dirmngr[] =
      "dirmngr", "force loading of outdated CRLs",
      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
 
+   { "Tor",
+     GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
+     "gnupg", N_("Options controlling the use of Tor") },
+   { "use-tor", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE,
+     "dirmngr", "route all network traffic via TOR",
+      GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
+
+   { "Keyserver",
+     GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
+     "gnupg", N_("Configuration for Keyservers") },
+   { "keyserver", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
+     "gnupg", N_("|URL|use keyserver at URL"),
+     GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR },
+
    { "HTTP",
      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
      "gnupg", N_("Configuration for HTTP servers") },
@@ -978,7 +1000,8 @@ static gc_option_t gc_options_pinentry[] =
  {
    /* A dummy option to allow gc_component_list_components to find the
       pinentry backend.  Needs to be a conf file. */
-   { "gpgconf-pinentry.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
+   { GPGCONF_NAME"-pinentry.conf",
+     GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL,
      NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_PINENTRY },
 
    GC_OPTION_NULL
@@ -1037,7 +1060,7 @@ static struct
     { "gpg-agent","gnupg", N_("GPG Agent"), gc_options_gpg_agent },
     { "scdaemon", "gnupg", N_("Smartcard Daemon"), gc_options_scdaemon },
     { "gpgsm",    "gnupg", N_("GPG for S/MIME"), gc_options_gpgsm },
-    { "dirmngr",  "gnupg", N_("Directory Manager"), gc_options_dirmngr },
+    { "dirmngr",  "gnupg", N_("Key Acquirer"), gc_options_dirmngr },
     { "pinentry", "gnupg", N_("PIN and Passphrase Entry"), gc_options_pinentry }
   };
 
@@ -1063,19 +1086,20 @@ gpg_agent_runtime_change (int killflag)
 {
   gpg_error_t err;
   const char *pgmname;
-  const char *argv[2];
+  const char *argv[3];
   pid_t pid;
 
   pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
-  argv[0] = killflag? "KILLAGENT" : "RELOADAGENT";
-  argv[1] = NULL;
+  argv[0] = "--no-autostart";
+  argv[1] = killflag? "KILLAGENT" : "RELOADAGENT";
+  argv[2] = NULL;
 
   err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
   if (!err)
     err = gnupg_wait_process (pgmname, pid, 1, NULL);
   if (err)
-    gc_error (0, 0, "error running '%s%s': %s",
-              pgmname, " reloadagent", gpg_strerror (err));
+    gc_error (0, 0, "error running '%s %s': %s",
+              pgmname, argv[1], gpg_strerror (err));
   gnupg_release_process (pid);
 }
 
@@ -1085,7 +1109,7 @@ scdaemon_runtime_change (int killflag)
 {
   gpg_error_t err;
   const char *pgmname;
-  const char *argv[6];
+  const char *argv[7];
   pid_t pid;
 
   (void)killflag;  /* For scdaemon kill and reload are synonyms.  */
@@ -1097,22 +1121,86 @@ scdaemon_runtime_change (int killflag)
 
   pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
   argv[0] = "-s";
-  argv[1] = "GETINFO scd_running";
-  argv[2] = "/if ${! $?}";
-  argv[3] = "scd killscd";
-  argv[4] = "/end";
-  argv[5] = NULL;
+  argv[1] = "--no-autostart";
+  argv[2] = "GETINFO scd_running";
+  argv[3] = "/if ${! $?}";
+  argv[4] = "scd killscd";
+  argv[5] = "/end";
+  argv[6] = NULL;
 
   err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
   if (!err)
     err = gnupg_wait_process (pgmname, pid, 1, NULL);
   if (err)
-    gc_error (0, 0, "error running '%s%s': %s",
-              pgmname, " scd killscd", gpg_strerror (err));
+    gc_error (0, 0, "error running '%s %s': %s",
+              pgmname, argv[4], gpg_strerror (err));
   gnupg_release_process (pid);
 }
 
 
+static void
+dirmngr_runtime_change (int killflag)
+{
+  gpg_error_t err;
+  const char *pgmname;
+  const char *argv[4];
+  pid_t pid;
+
+  pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
+  argv[0] = "--no-autostart";
+  argv[1] = "--dirmngr";
+  argv[2] = killflag? "KILLDIRMNGR" : "RELOADDIRMNGR";
+  argv[3] = NULL;
+
+  err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
+  if (!err)
+    err = gnupg_wait_process (pgmname, pid, 1, NULL);
+  if (err)
+    gc_error (0, 0, "error running '%s %s': %s",
+              pgmname, argv[2], gpg_strerror (err));
+  gnupg_release_process (pid);
+}
+
+
+/* Launch the gpg-agent or the dirmngr if not already running.  */
+gpg_error_t
+gc_component_launch (int component)
+{
+  gpg_error_t err;
+  const char *pgmname;
+  const char *argv[3];
+  int i;
+  pid_t pid;
+
+  if (!(component == GC_COMPONENT_GPG_AGENT
+        || component == GC_COMPONENT_DIRMNGR))
+    {
+      es_fputs (_("Component not suitable for launching"), es_stderr);
+      es_putc ('\n', es_stderr);
+      exit (1);
+    }
+
+  pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
+  i = 0;
+  if (component == GC_COMPONENT_DIRMNGR)
+    argv[i++] = "--dirmngr";
+  argv[i++] = "NOP";
+  argv[i] = NULL;
+
+  err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
+  if (!err)
+    err = gnupg_wait_process (pgmname, pid, 1, NULL);
+  if (err)
+    gc_error (0, 0, "error running '%s%s%s': %s",
+              pgmname,
+              component == GC_COMPONENT_DIRMNGR? " --dirmngr":"",
+              " NOP",
+              gpg_strerror (err));
+  gnupg_release_process (pid);
+  return err;
+}
+
+
 /* Unconditionally restart COMPONENT.  */
 void
 gc_component_kill (int component)
@@ -1183,7 +1271,7 @@ gc_component_reload (int component)
 \f
 /* More or less Robust version of dgettext.  It has the side effect of
    switching the codeset to utf-8 because this is what we want to
-   output.  In theory it is posible to keep the orginal code set and
+   output.  In theory it is posible to keep the original code set and
    switch back for regular disgnostic output (redefine "_(" for that)
    but given the natur of this tool, being something invoked from
    other pograms, it does not make much sense.  */
@@ -1210,6 +1298,8 @@ my_dgettext (const char *domain, const char *msgid)
       text = (char*)gettext (msgid);
       return text ? text : msgid;
     }
+  else
+    return msgid;
 #elif defined(ENABLE_NLS)
   if (domain)
     {
@@ -2293,7 +2383,7 @@ option_check_validity (gc_option_t *option, unsigned long flags,
            gc_error (1, 0, "garbage after argument for option %s",
                      option->name);
        }
-      else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32)
+      else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_UINT32)
        {
          unsigned long res;
 
@@ -2379,7 +2469,7 @@ change_options_file (gc_component_t component, gc_backend_t backend,
                     char **src_filenamep, char **dest_filenamep,
                     char **orig_filenamep)
 {
-  static const char marker[] = "###+++--- GPGConf ---+++###";
+  static const char marker[] = "###+++--- " GPGCONF_DISP_NAME " ---+++###";
   /* True if we are within the marker in the config file.  */
   int in_marker = 0;
   gc_option_t *option;
@@ -2406,8 +2496,10 @@ change_options_file (gc_component_t component, gc_backend_t backend,
   /* Note that get_config_filename() calls percent_deescape(), so we
      call this before processing the arguments.  */
   dest_filename = xstrdup (get_config_filename (component, backend));
-  src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, (int)getpid ());
-  orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename,(int)getpid ());
+  src_filename = xasprintf ("%s.%s.%i.new",
+                            dest_filename, GPGCONF_NAME, (int)getpid ());
+  orig_filename = xasprintf ("%s.%s.%i.bak",
+                             dest_filename, GPGCONF_NAME, (int)getpid ());
 
   arg = option->new_value;
   if (arg && arg[0] == '\0')
@@ -2437,7 +2529,10 @@ change_options_file (gc_component_t component, gc_backend_t backend,
   res = link (dest_filename, orig_filename);
 #endif
   if (res < 0 && errno != ENOENT)
-    return -1;
+    {
+      xfree (dest_filename);
+      return -1;
+    }
   if (res < 0)
     {
       xfree (orig_filename);
@@ -2544,8 +2639,8 @@ change_options_file (gc_component_t component, gc_backend_t backend,
              if (!in_marker)
                {
                  fprintf (src_file,
-                          "# GPGConf disabled this option here at %s\n",
-                          asctimestamp (gnupg_get_time ()));
+                          "# %s disabled this option here at %s\n",
+                          GPGCONF_DISP_NAME, asctimestamp (gnupg_get_time ()));
                  if (ferror (src_file))
                    goto change_file_one_err;
                  fprintf (src_file, "# %s", line);
@@ -2613,7 +2708,8 @@ change_options_file (gc_component_t component, gc_backend_t backend,
 
   if (!in_marker)
     {
-      fprintf (src_file, "# GPGConf edited this configuration file.\n");
+      fprintf (src_file, "# %s edited this configuration file.\n",
+               GPGCONF_DISP_NAME);
       if (ferror (src_file))
        goto change_file_one_err;
       fprintf (src_file, "# It will disable options before this marked "
@@ -2679,7 +2775,7 @@ change_options_program (gc_component_t component, gc_backend_t backend,
                        char **src_filenamep, char **dest_filenamep,
                        char **orig_filenamep)
 {
-  static const char marker[] = "###+++--- GPGConf ---+++###";
+  static const char marker[] = "###+++--- " GPGCONF_DISP_NAME " ---+++###";
   /* True if we are within the marker in the config file.  */
   int in_marker = 0;
   gc_option_t *option;
@@ -2698,8 +2794,10 @@ change_options_program (gc_component_t component, gc_backend_t backend,
 
   /* FIXME.  Throughout the function, do better error reporting.  */
   dest_filename = xstrdup (get_config_filename (component, backend));
-  src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, (int)getpid ());
-  orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename,(int)getpid ());
+  src_filename = xasprintf ("%s.%s.%i.new",
+                            dest_filename, GPGCONF_NAME, (int)getpid ());
+  orig_filename = xasprintf ("%s.%s.%i.bak",
+                             dest_filename, GPGCONF_NAME, (int)getpid ());
 
 #ifdef HAVE_W32_SYSTEM
   res = copy_file (dest_filename, orig_filename);
@@ -2790,8 +2888,8 @@ change_options_program (gc_component_t component, gc_backend_t backend,
              if (!in_marker)
                {
                  fprintf (src_file,
-                          "# GPGConf disabled this option here at %s\n",
-                          asctimestamp (gnupg_get_time ()));
+                          "# %s disabled this option here at %s\n",
+                          GPGCONF_DISP_NAME, asctimestamp (gnupg_get_time ()));
                  if (ferror (src_file))
                    goto change_one_err;
                  fprintf (src_file, "# %s", line);
@@ -2911,7 +3009,8 @@ change_options_program (gc_component_t component, gc_backend_t backend,
 
   if (!in_marker)
     {
-      fprintf (src_file, "# GPGConf edited this configuration file.\n");
+      fprintf (src_file, "# %s edited this configuration file.\n",
+               GPGCONF_DISP_NAME);
       if (ferror (src_file))
        goto change_one_err;
       fprintf (src_file, "# It will disable options before this marked "
@@ -3201,7 +3300,7 @@ gc_component_change_options (int component, estream_t in, estream_t out)
       int i;
       int saved_errno = errno;
 
-      /* An error occured or a dry-run is requested.  */
+      /* An error occurred or a dry-run is requested.  */
       for (i = 0; i < GC_BACKEND_NR; i++)
        {
          if (src_filename[i])
@@ -3252,7 +3351,8 @@ gc_component_change_options (int component, estream_t in, estream_t out)
 
        assert (dest_filename[backend]);
 
-       backup_filename = xasprintf ("%s.gpgconf.bak", dest_filename[backend]);
+       backup_filename = xasprintf ("%s.%s.bak",
+                                     dest_filename[backend], GPGCONF_NAME);
 
 #ifdef HAVE_W32_SYSTEM
        /* There is no atomic update on W32.  */
@@ -3401,7 +3501,8 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
   if (fname_arg)
     fname = xstrdup (fname_arg);
   else
-    fname = make_filename (gnupg_sysconfdir (), "gpgconf.conf", NULL);
+    fname = make_filename (gnupg_sysconfdir (), GPGCONF_NAME EXTSEP_S "conf",
+                           NULL);
 
   for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)
     runtime[backend_id] = 0;