From 628672bc72b051e8af576ca84c6670f1a6cb5736 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Wed, 13 Jul 2022 15:20:13 +0200 Subject: [PATCH] bankd: Open PC/SC by default in EXCLUSIVE mode Let's open the cards in EXCLUSIVE mode, we don't want other applications tinkering with the card state while we have a bankd worker running on it. This change also means that no two bankd workers can trip on each other accidentially anymore. Related: OS#5527 Change-Id: I43a1c8c7bd1c0124ee5f605e2e5b04ed8f7836ab --- doc/manuals/chapters/remsim-bankd.adoc | 9 +++++++++ src/bankd/bankd.h | 4 ++++ src/bankd/bankd_main.c | 9 ++++++++- src/bankd/bankd_pcsc.c | 12 ++++++++++-- 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/doc/manuals/chapters/remsim-bankd.adoc b/doc/manuals/chapters/remsim-bankd.adoc index 7c102de..cb3061c 100644 --- a/doc/manuals/chapters/remsim-bankd.adoc +++ b/doc/manuals/chapters/remsim-bankd.adoc @@ -89,6 +89,15 @@ approach seems to make more sense. *-P, --bind-port <1-65535>*:: Specify the local TCP port to which the socket for incoming connections from `osmo-remsim-client`s is bound to. +*-s, --permit-shared-pcsc*:: + Specify whether the PC/SC readers should be accessed in SCARD_SHARE_SHARED + mode, instead of the default (SCARD_SHARE_EXCLUSIVE). Shared mode would + permit multiple application programs to access a single reader/slot/card + concurrently. This is potentially dangerous as the two programs operate + without knowledge of each other, and either of them might modify the card + state (such as the currently selected file, validated PIN, etc.) in a + way not expected by the other application. + ==== Examples .remsim-server is on 10.2.3.4, cardreader has 5 slots: diff --git a/src/bankd/bankd.h b/src/bankd/bankd.h index 9bf9bc9..0f94818 100644 --- a/src/bankd/bankd.h +++ b/src/bankd/bankd.h @@ -130,6 +130,10 @@ struct bankd { pthread_mutex_t workers_mutex; struct llist_head pcsc_slot_names; + + struct { + bool permit_shared_pcsc; + } cfg; }; int bankd_pcsc_read_slotnames(struct bankd *bankd, const char *csv_file); diff --git a/src/bankd/bankd_main.c b/src/bankd/bankd_main.c index b28eec9..c2d6e69 100644 --- a/src/bankd/bankd_main.c +++ b/src/bankd/bankd_main.c @@ -98,6 +98,8 @@ static void bankd_init(struct bankd *bankd) /* FIXME: other members of app_comp_id */ INIT_LLIST_HEAD(&bankd->pcsc_slot_names); + + bankd->cfg.permit_shared_pcsc = false; } /* create + start a new bankd_worker thread */ @@ -291,6 +293,7 @@ static void printf_help() " connections (default: INADDR_ANY)\n" " -P --bind-port <1-65535> Local TCP port to bind for incoming client\n" " connectionss (default: 9999)\n" +" -s --permit-shared-pcsc Permit SHARED access to PC/SC readers (default: exclusive)\n" ); } @@ -312,10 +315,11 @@ static void handle_options(int argc, char **argv) { "component-name", 1, 0, 'N' }, { "bind-ip", 1, 0, 'I' }, { "bind-port", 1, 0, 'P' }, + { "permit-shared-pcsc", 0, 0, 's' }, { 0, 0, 0, 0 } }; - c = getopt_long(argc, argv, "hVd:i:o:b:n:N:I:P:", long_options, &option_index); + c = getopt_long(argc, argv, "hVd:i:o:b:n:N:I:P:s", long_options, &option_index); if (c == -1) break; @@ -352,6 +356,9 @@ static void handle_options(int argc, char **argv) case 'P': g_bind_port = atoi(optarg); break; + case 's': + g_bankd->cfg.permit_shared_pcsc = true; + break; } } } diff --git a/src/bankd/bankd_pcsc.c b/src/bankd/bankd_pcsc.c index ee01c93..e1477dd 100644 --- a/src/bankd/bankd_pcsc.c +++ b/src/bankd/bankd_pcsc.c @@ -184,6 +184,14 @@ if (rv != SCARD_S_SUCCESS) { \ LOGW((w), text ": OK\n"); \ } +static DWORD bankd_share_mode(struct bankd *bankd) +{ + if (bankd->cfg.permit_shared_pcsc) + return SCARD_SHARE_SHARED; + else + return SCARD_SHARE_EXCLUSIVE; +} + static int pcsc_get_atr(struct bankd_worker *worker) { long rc; @@ -232,7 +240,7 @@ static int pcsc_connect_slot_regex(struct bankd_worker *worker) int r = regexec(&compiled_name, p, 0, NULL, 0); if (r == 0) { LOGW(worker, "Attempting to open card/slot '%s'\n", p); - rc = SCardConnect(worker->reader.pcsc.hContext, p, SCARD_SHARE_SHARED, + rc = SCardConnect(worker->reader.pcsc.hContext, p, bankd_share_mode(worker->bankd), SCARD_PROTOCOL_T0, &worker->reader.pcsc.hCard, &dwActiveProtocol); if (rc == SCARD_S_SUCCESS) @@ -289,7 +297,7 @@ static int pcsc_reset_card(struct bankd_worker *worker, bool cold_reset) LOGW(worker, "Resetting card in '%s' (%s)\n", worker->reader.name, cold_reset ? "cold reset" : "warm reset"); - rc = SCardReconnect(worker->reader.pcsc.hCard, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, + rc = SCardReconnect(worker->reader.pcsc.hCard, bankd_share_mode(worker->bankd), SCARD_PROTOCOL_T0, cold_reset ? SCARD_UNPOWER_CARD : SCARD_RESET_CARD, &dwActiveProtocol); PCSC_ERROR(worker, rc, "SCardReconnect");