From 97feef8ee94a5e1cb9daba82f108eb62122c7910 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 28 Mar 2019 17:05:20 +0100 Subject: [PATCH] scd: New option --application-priority. * 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 --- doc/scdaemon.texi | 16 +++++++++- scd/app-common.h | 1 + scd/app.c | 76 ++++++++++++++++++++++++++++++++++---------- scd/scdaemon.c | 12 +++++++ tools/gpgconf-comp.c | 4 +++ 5 files changed, 91 insertions(+), 18 deletions(-) diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi index 81af28105..0c984162c 100644 --- a/doc/scdaemon.texi +++ b/doc/scdaemon.texi @@ -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 - diff --git a/scd/app-common.h b/scd/app-common.h index 3df896228..c53bf06ca 100644 --- a/scd/app-common.h +++ b/scd/app-common.h @@ -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); diff --git a/scd/app.c b/scd/app.c index f0f6d7ecb..59a8880db 100644 --- a/scd/app.c +++ b/scd/app.c @@ -59,6 +59,59 @@ static struct app_priority_list_s app_priority_list[] = +/* 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; diff --git a/scd/scdaemon.c b/scd/scdaemon.c index 507108db0..42efb4c37 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -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 */ diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 2ae79d91d..272b7571e 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -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,