scd: New option --application-priority.
authorWerner Koch <wk@gnupg.org>
Thu, 28 Mar 2019 16:05:20 +0000 (17:05 +0100)
committerWerner Koch <wk@gnupg.org>
Thu, 28 Mar 2019 16:38:05 +0000 (17:38 +0100)
* scd/scdaemon.c (oApplicationPriority): New.
(opts): Add "application_priority".
(main): Process option.
* scd/app.c (app_update_priority_list): New.
(get_supported_applications): Take apps from global list.

* tools/gpgconf-comp.c (gc_options_scdaemon): Add option.

Signed-off-by: Werner Koch <wk@gnupg.org>
doc/scdaemon.texi
scd/app-common.h
scd/app.c
scd/scdaemon.c
tools/gpgconf-comp.c

index 81af281..0c98416 100644 (file)
@@ -332,6 +332,21 @@ This option disables the use of the card application named
 @var{name}.  This is mainly useful for debugging or if a application
 with lower priority should be used by default.
 
+@item --application-priority @var{namelist}
+@opindex application-priority
+This option allows to change the order in which applications of a card
+a tried if no specific application was requested.  @var{namelist} is a
+space or comma delimited list of application names.  Unknown names are
+simply skipped.  Applications not mentioned in the list are put in the
+former order at the end of the new priority list.
+
+To get the list of current active applications, use
+@cartouche
+@smallexample
+    gpg-connect-agent 'scd getinfo app_list' /bye
+@end smallexample
+@end cartouche
+
 @end table
 
 All the long options may also be given in the configuration file after
@@ -767,4 +782,3 @@ length up to N bytes.  If N is not given a default value is used
 @command{gpg2}(1)
 @end ifset
 @include see-also-note.texi
-
index 3df8962..c53bf06 100644 (file)
@@ -133,6 +133,7 @@ size_t app_help_read_length_of_cert (int slot, int fid, size_t *r_certoff);
 
 
 /*-- app.c --*/
+void app_update_priority_list (const char *arg);
 void app_send_card_list (ctrl_t ctrl);
 char *app_get_serialno (app_t app);
 
index f0f6d7e..59a8880 100644 (file)
--- a/scd/app.c
+++ b/scd/app.c
@@ -59,6 +59,59 @@ static struct app_priority_list_s app_priority_list[] =
 
 
 \f
+/* Initialization function to change the default app_priority_list.
+ * LIST is a list of comma or space separated strings with application
+ * names.  Unknown names will only result in warning message.
+ * Application not mentioned in LIST are used in their original order
+ * after the given once.  */
+void
+app_update_priority_list (const char *arg)
+{
+  struct app_priority_list_s save;
+  char **names;
+  int i, j, idx;
+
+  names = strtokenize (arg, ", ");
+  if (!names)
+    log_fatal ("strtokenize failed: %s\n",
+               gpg_strerror (gpg_error_from_syserror ()));
+
+  idx = 0;
+  for (i=0; names[i]; i++)
+    {
+      ascii_strlwr (names[i]);
+      for (j=0; j < i; j++)
+        if (!strcmp (names[j], names[i]))
+          break;
+      if (j < i)
+        {
+          log_info ("warning: duplicate application '%s' in priority list\n",
+                    names[i]);
+          continue;
+        }
+
+      for (j=idx; app_priority_list[j].name; j++)
+        if (!strcmp (names[i], app_priority_list[j].name))
+          break;
+      if (!app_priority_list[j].name)
+        {
+          log_info ("warning: unknown application '%s' in priority list\n",
+                    names[i]);
+          continue;
+        }
+      save = app_priority_list[idx];
+      app_priority_list[idx] = app_priority_list[j];
+      app_priority_list[j] = save;
+      idx++;
+    }
+  log_assert (idx < DIM (app_priority_list));
+
+  xfree (names);
+  for (i=0; app_priority_list[i].name; i++)
+    log_info ("app priority %d: %s\n", i, app_priority_list[i].name);
+}
+
+
 static void
 print_progress_line (void *opaque, const char *what, int pc, int cur, int tot)
 {
@@ -511,32 +564,21 @@ select_application (ctrl_t ctrl, const char *name, app_t *r_app,
 char *
 get_supported_applications (void)
 {
-  const char *list[] = {
-    "openpgp",
-    "piv",
-    "nks",
-    "p15",
-    "geldkarte",
-    "dinsig",
-    "sc-hsm",
-    /* Note: "undefined" is not listed here because it needs special
-       treatment by the client.  */
-    NULL
-  };
   int idx;
   size_t nbytes;
   char *buffer, *p;
+  const char *s;
 
-  for (nbytes=1, idx=0; list[idx]; idx++)
-    nbytes += strlen (list[idx]) + 1 + 1;
+  for (nbytes=1, idx=0; (s=app_priority_list[idx].name); idx++)
+    nbytes += strlen (s) + 1 + 1;
 
   buffer = xtrymalloc (nbytes);
   if (!buffer)
     return NULL;
 
-  for (p=buffer, idx=0; list[idx]; idx++)
-    if (is_app_allowed (list[idx]))
-      p = stpcpy (stpcpy (p, list[idx]), ":\n");
+  for (p=buffer, idx=0; (s=app_priority_list[idx].name); idx++)
+    if (is_app_allowed (s))
+      p = stpcpy (stpcpy (p, s), ":\n");
   *p = 0;
 
   return buffer;
index 507108d..42efb4c 100644 (file)
@@ -98,6 +98,7 @@ enum cmd_and_opt_values
   oAllowAdmin,
   oDenyAdmin,
   oDisableApplication,
+  oApplicationPriority,
   oEnablePinpadVarlen,
   oListenBacklog
 };
@@ -154,6 +155,8 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oDenyAdmin, "deny-admin",
                 N_("deny the use of admin card commands")),
   ARGPARSE_s_s (oDisableApplication, "disable-application", "@"),
+  ARGPARSE_s_s (oApplicationPriority, "application-priority",
+                N_("|LIST|Change the application priority to LIST")),
   ARGPARSE_s_n (oEnablePinpadVarlen, "enable-pinpad-varlen",
                 N_("use variable length input for pinpad")),
   ARGPARSE_s_s (oHomedir,    "homedir",      "@"),
@@ -436,6 +439,7 @@ main (int argc, char **argv )
   struct assuan_malloc_hooks malloc_hooks;
   int res;
   npth_t pipecon_handler;
+  const char *application_priority = NULL;
 
   early_system_init ();
   set_strusage (my_strusage);
@@ -616,6 +620,10 @@ main (int argc, char **argv )
           add_to_strlist (&opt.disabled_applications, pargs.r.ret_str);
           break;
 
+        case oApplicationPriority:
+          application_priority = pargs.r.ret_str;
+          break;
+
         case oEnablePinpadVarlen: opt.enable_pinpad_varlen = 1; break;
 
         case oListenBacklog:
@@ -720,6 +728,7 @@ main (int argc, char **argv )
       es_printf ("disable-pinpad:%lu:\n", GC_OPT_FLAG_NONE );
       es_printf ("card-timeout:%lu:%d:\n", GC_OPT_FLAG_DEFAULT, 0);
       es_printf ("enable-pinpad-varlen:%lu:\n", GC_OPT_FLAG_NONE );
+      es_printf ("application-priority:%lu:\n", GC_OPT_FLAG_NONE );
 
       scd_exit (0);
     }
@@ -739,6 +748,9 @@ main (int argc, char **argv )
       log_debug ("... okay\n");
     }
 
+  if (application_priority)
+    app_update_priority_list (application_priority);
+
   if (pipe_server)
     {
       /* This is the simple pipe based server */
index 2ae79d9..272b757 100644 (file)
@@ -653,6 +653,10 @@ static gc_option_t gc_options_scdaemon[] =
    { "card-timeout", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC,
      "gnupg", "|N|disconnect the card after N seconds of inactivity",
      GC_ARG_TYPE_UINT32, GC_BACKEND_SCDAEMON },
+   { "application-priority",
+     GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED,
+     "gnupg", "|LIST|Change the application priority to LIST",
+     GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON },
 
    { "Debug",
      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,