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
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 @@
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 @@
/* 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 @@
" 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 @@
{ "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 @@
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 @@
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 @@
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 @@
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");