From 5732e7a8e97cebf8e850c472e644e2a9b040836f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 12 Mar 2021 09:21:57 +0100 Subject: [PATCH] scd: New option --pcsc-shared. * scd/scdaemon.h (opt): Add field opcsc_shared. * scd/scdaemon.c (opcscShared): New. (opts): Add "--pcsc-shared". (main): Set flag. * scd/apdu.c (connect_pcsc_card): Use it. (pcsc_get_status): Take flag in account. * scd/app-openpgp.c (cache_pin): Bypass in shared mode. (verify_chv2: Do not auto verify chv1 in shared mode. * scd/app-piv.c (cache_pin): By pass caceh in shared mode. -- This option should in general not be used. The patch tries to limit bad effects but using shared mode is somewhat dangerous depending on the other PC/SC users. --- doc/scdaemon.texi | 6 ++++++ scd/apdu.c | 5 +++-- scd/app-openpgp.c | 9 +++++++-- scd/app-piv.c | 3 +++ scd/scdaemon.c | 3 +++ scd/scdaemon.h | 1 + 6 files changed, 23 insertions(+), 4 deletions(-) diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi index c1ca443b9..8af42c58e 100644 --- a/doc/scdaemon.texi +++ b/doc/scdaemon.texi @@ -226,6 +226,12 @@ Append all logging output to @var{file}. This is very helpful in seeing what the agent actually does. Use @file{socket://} to log to socket. +@item --pcsc-shared +@opindex pcsc-shared +Use shared mode to access the card via PC/SC. This is a somewhat +dangerous option because Scdaemon assumes exclusivbe access to teh +card and for example caches certain information from the card. Use +this option only if you know what you are doing. @item --pcsc-driver @var{library} @opindex pcsc-driver diff --git a/scd/apdu.c b/scd/apdu.c index 68ad733cb..1ca63e41f 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -732,7 +732,8 @@ pcsc_get_status (int slot, unsigned int *status, int on_wire) mode. */ if ( (*status & (APDU_CARD_PRESENT|APDU_CARD_ACTIVE)) == (APDU_CARD_PRESENT|APDU_CARD_ACTIVE) - && !(reader_table[slot].pcsc.current_state & PCSC_STATE_INUSE) ) + && (opt.pcsc_shared + || !(reader_table[slot].pcsc.current_state & PCSC_STATE_INUSE))) *status |= APDU_CARD_USABLE; #else /* Some winscard drivers may set EXCLUSIVE and INUSE at the same @@ -856,7 +857,7 @@ connect_pcsc_card (int slot) err = pcsc_connect (pcsc.context, reader_table[slot].rdrname, - PCSC_SHARE_EXCLUSIVE, + opt.pcsc_shared? PCSC_SHARE_SHARED:PCSC_SHARE_EXCLUSIVE, PCSC_PROTOCOL_T0|PCSC_PROTOCOL_T1, &reader_table[slot].pcsc.card, &reader_table[slot].pcsc.protocol); diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 987a31be3..fcae4d713 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -2483,10 +2483,15 @@ chvno_to_keyref (int chvno) static void cache_pin (app_t app, ctrl_t ctrl, int chvno, const char *pin) { - const char *keyref = chvno_to_keyref (chvno); + const char *keyref; + if (opt.pcsc_shared) + return; + + keyref = chvno_to_keyref (chvno); if (!keyref) return; + switch (APP_CARD(app)->cardtype) { case CARDTYPE_YUBIKEY: break; @@ -2707,7 +2712,7 @@ verify_chv2 (app_t app, ctrl_t ctrl, return rc; app->did_chv2 = 1; - if (!app->did_chv1 && !app->force_chv1 && pinvalue) + if (!app->did_chv1 && !app->force_chv1 && pinvalue && !opt.pcsc_shared) { /* For convenience we verify CHV1 here too. We do this only if the card is not configured to require a verification before diff --git a/scd/app-piv.c b/scd/app-piv.c index 441475b12..ead1b1974 100644 --- a/scd/app-piv.c +++ b/scd/app-piv.c @@ -1681,6 +1681,9 @@ cache_pin (app_t app, ctrl_t ctrl, int pinno, { char pinref[20]; + if (opt.pcsc_shared) + return; + if (pinno < 0) return; switch (app->card->cardtype) diff --git a/scd/scdaemon.c b/scd/scdaemon.c index b7bbc0361..3c9e28584 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -94,6 +94,7 @@ enum cmd_and_opt_values oCardTimeout, octapiDriver, opcscDriver, + opcscShared, oDisableCCID, oDisableOpenSC, oDisablePinpad, @@ -150,6 +151,7 @@ static gpgrt_opt_t opts[] = { N_("|NAME|use NAME as ct-API driver")), ARGPARSE_s_s (opcscDriver, "pcsc-driver", N_("|NAME|use NAME as PC/SC driver")), + ARGPARSE_s_n (opcscShared, "pcsc-shared", "@"), ARGPARSE_s_n (oDisableCCID, "disable-ccid", #ifdef HAVE_LIBUSB N_("do not use the internal CCID driver") @@ -602,6 +604,7 @@ main (int argc, char **argv ) case oReaderPort: opt.reader_port = pargs.r.ret_str; break; case octapiDriver: opt.ctapi_driver = pargs.r.ret_str; break; case opcscDriver: opt.pcsc_driver = pargs.r.ret_str; break; + case opcscShared: opt.pcsc_shared = 1; break; case oDisableCCID: opt.disable_ccid = 1; break; case oDisableOpenSC: break; diff --git a/scd/scdaemon.h b/scd/scdaemon.h index 5ae656ca2..0d89f58c0 100644 --- a/scd/scdaemon.h +++ b/scd/scdaemon.h @@ -62,6 +62,7 @@ struct int enable_pinpad_varlen; /* Use variable length input for pinpad. */ int allow_admin; /* Allow the use of admin commands for certain cards. */ + int pcsc_shared; /* Use shared PC/SC access. */ strlist_t disabled_applications; /* Card applications we do not want to use. */ unsigned long card_timeout; /* Disconnect after N seconds of inactivity. */