* [Qemu-devel] [PATCH v2 0/4] Add support for passthru cards to libcacard
@ 2015-01-20 15:38 Jeremy White
2015-01-20 15:38 ` [Qemu-devel] [PATCH v2 1/4] Add a configure check for libpcsclite, and an option to enable or disable it Jeremy White
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Jeremy White @ 2015-01-20 15:38 UTC (permalink / raw)
To: qemu-devel
This differs from v1 by:
* checkpatch review
* Patch series, instead of one patch
* Remove internal queue in favor of relying on thread safety of pcsclite
* Remove glib from configure
* Use glib thread and allocation functions
Jeremy White (4):
Add a configure check for libpcsclite, and an option to enable or
disable it.
Add a VCARD_DIRECT implemention to the libcacard smartcard support.
Enable support for passthru (e.g. direct to pcsc) smart cards in
the emul_options entry point in libcacard.
Remove the (broken) passthru option.
Makefile.objs | 5 +
configure | 38 ++++
libcacard/capcsc.c | 488 +++++++++++++++++++++++++++++++++++++++++++
libcacard/capcsc.h | 18 ++
libcacard/libcacard.syms | 1 +
libcacard/vcard.c | 2 +-
libcacard/vcard.h | 2 +-
libcacard/vcard_emul_nss.c | 29 ++-
libcacard/vcard_emul_type.c | 3 +-
libcacard/vscclient.c | 16 +-
10 files changed, 585 insertions(+), 17 deletions(-)
create mode 100644 libcacard/capcsc.c
create mode 100644 libcacard/capcsc.h
--
1.7.10.4
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH v2 1/4] Add a configure check for libpcsclite, and an option to enable or disable it.
2015-01-20 15:38 [Qemu-devel] [PATCH v2 0/4] Add support for passthru cards to libcacard Jeremy White
@ 2015-01-20 15:38 ` Jeremy White
2015-01-20 15:38 ` [Qemu-devel] [PATCH v2 2/4] Add a VCARD_DIRECT implemention to the libcacard smartcard support Jeremy White
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Jeremy White @ 2015-01-20 15:38 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Jeremy White <jwhite@codeweavers.com>
---
configure | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/configure b/configure
index 5ea1014..4529764 100755
--- a/configure
+++ b/configure
@@ -307,6 +307,7 @@ trace_file="trace"
spice=""
rbd=""
smartcard_nss=""
+smartcard_pcsc=""
libusb=""
usb_redir=""
glx=""
@@ -1042,6 +1043,10 @@ for opt do
;;
--enable-smartcard-nss) smartcard_nss="yes"
;;
+ --disable-smartcard-pcsc) smartcard_pcsc="no"
+ ;;
+ --enable-smartcard-pcsc) smartcard_pcsc="yes"
+ ;;
--disable-libusb) libusb="no"
;;
--enable-libusb) libusb="yes"
@@ -1368,6 +1373,8 @@ Advanced options (experts only):
--enable-libnfs enable nfs support
--disable-smartcard-nss disable smartcard nss support
--enable-smartcard-nss enable smartcard nss support
+ --disable-smartcard-pcsc disable smartcard pcsc passthru support
+ --enable-smartcard-pcsc enable smartcard pcsc passthru support
--disable-libusb disable libusb (for usb passthrough)
--enable-libusb enable libusb (for usb passthrough)
--disable-usb-redir disable usb network redirection support
@@ -3674,6 +3681,30 @@ EOF
fi
fi
+# check for pcsclite for smartcard passthru support
+# TODO - Add support for Winscard
+if test "$smartcard_pcsc" != "no"; then
+ cat > $TMPC << EOF
+#include <winscard.h>
+int main(void) { SCardEstablishContext(0, 0, 0, 0); return 0; }
+EOF
+ pcsc_libs="$($pkg_config --libs libpcsclite 2>/dev/null)"
+ pcsc_cflags="$($pkg_config --cflags libpcsclite 2>/dev/null)"
+ test_cflags="$pcsc_cflags"
+ if test "$werror" = "yes"; then
+ test_cflags="-Werror $test_cflags"
+ fi
+ if test -n "$libtool" &&
+ compile_prog "$test_cflags" "$pcsc_libs"; then
+ smartcard_pcsc="yes"
+ else
+ if test "$smartcard_pcsc" = "yes"; then
+ feature_not_found "pcsc" "Install libpcsclite"
+ fi
+ smartcard_pcsc="no"
+ fi
+fi
+
# check for libusb
if test "$libusb" != "no" ; then
if $pkg_config --atleast-version=1.0.13 libusb-1.0; then
@@ -4347,6 +4378,7 @@ fi
echo "rbd support $rbd"
echo "xfsctl support $xfs"
echo "nss used $smartcard_nss"
+echo "pcsc used $smartcard_pcsc"
echo "libusb $libusb"
echo "usb net redir $usb_redir"
echo "GLX support $glx"
@@ -4703,6 +4735,12 @@ if test "$smartcard_nss" = "yes" ; then
echo "NSS_CFLAGS=$nss_cflags" >> $config_host_mak
fi
+if test "$smartcard_pcsc" = "yes" ; then
+ echo "CONFIG_SMARTCARD_PCSC=y" >> $config_host_mak
+ echo "PCSC_LIBS=$pcsc_libs" >> $config_host_mak
+ echo "PCSC_CFLAGS=$pcsc_cflags" >> $config_host_mak
+fi
+
if test "$libusb" = "yes" ; then
echo "CONFIG_USB_LIBUSB=y" >> $config_host_mak
fi
--
1.7.10.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH v2 2/4] Add a VCARD_DIRECT implemention to the libcacard smartcard support.
2015-01-20 15:38 [Qemu-devel] [PATCH v2 0/4] Add support for passthru cards to libcacard Jeremy White
2015-01-20 15:38 ` [Qemu-devel] [PATCH v2 1/4] Add a configure check for libpcsclite, and an option to enable or disable it Jeremy White
@ 2015-01-20 15:38 ` Jeremy White
2015-01-20 15:38 ` [Qemu-devel] [PATCH v2 3/4] Enable support for passthru (e.g. direct to pcsc) smart cards in the emul_options entry point in libcacard Jeremy White
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Jeremy White @ 2015-01-20 15:38 UTC (permalink / raw)
To: qemu-devel
This uses libpcsclite to provide direct communication with a smartcard.
Signed-off-by: Jeremy White <jwhite@codeweavers.com>
---
Makefile.objs | 5 +
libcacard/capcsc.c | 488 ++++++++++++++++++++++++++++++++++++++++++++++
libcacard/capcsc.h | 18 ++
libcacard/libcacard.syms | 1 +
4 files changed, 512 insertions(+)
create mode 100644 libcacard/capcsc.c
create mode 100644 libcacard/capcsc.h
diff --git a/Makefile.objs b/Makefile.objs
index abeb902..bb9659e 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -32,6 +32,11 @@ libcacard-y += libcacard/card_7816.o
libcacard-y += libcacard/vcardt.o
libcacard/vcard_emul_nss.o-cflags := $(NSS_CFLAGS)
libcacard/vcard_emul_nss.o-libs := $(NSS_LIBS)
+ifeq ($(CONFIG_SMARTCARD_PCSC),y)
+libcacard-y += libcacard/capcsc.o
+libcacard/capcsc.o-cflags := $(PCSC_CFLAGS)
+libcacard/capcsc.o-libs := $(PCSC_LIBS)
+endif
######################################################################
# Target independent part of system emulation. The long term path is to
diff --git a/libcacard/capcsc.c b/libcacard/capcsc.c
new file mode 100644
index 0000000..05c06fb
--- /dev/null
+++ b/libcacard/capcsc.c
@@ -0,0 +1,488 @@
+/*
+ * Supply a vreader using the PC/SC interface.
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+/* avoid including prototypes.h that causes some qemu type conflicts */
+#define NO_NSPR_10_SUPPORT
+#include <prthread.h>
+
+#include "qemu-common.h"
+
+#include "vcard.h"
+#include "card_7816.h"
+#include "capcsc.h"
+#include "vreader.h"
+#include "vevent.h"
+
+#include <PCSC/wintypes.h>
+#include <PCSC/winscard.h>
+
+
+typedef struct _PCSCContext PCSCContext;
+
+typedef struct {
+ PCSCContext *context;
+ int index;
+ char *name;
+ DWORD protocol;
+ DWORD state;
+ SCARDHANDLE card;
+ BYTE atr[MAX_ATR_SIZE];
+ DWORD atrlen;
+ int card_connected;
+ unsigned long request_count;
+} SCardReader;
+
+typedef struct _PCSCContext {
+ SCARDCONTEXT context;
+ SCardReader readers[CAPCSC_MAX_READERS];
+ int reader_count;
+ int readers_changed;
+ GThread *thread;
+ CompatGMutex lock;
+} PCSCContext;
+
+
+static void delete_reader(PCSCContext *pc, int i)
+{
+ SCardReader *r = &pc->readers[i];
+ g_free(r->name);
+ r->name = NULL;
+
+ if (i < (pc->reader_count - 1)) {
+ int rem = pc->reader_count - i - 1;
+ memmove(&pc->readers[i], &pc->readers[i + 1],
+ sizeof(SCardReader) * rem);
+ }
+
+ pc->reader_count--;
+}
+
+static void delete_reader_cb(VReaderEmul *ve)
+{
+ SCardReader *r = (SCardReader *) ve;
+
+ g_mutex_lock(&r->context->lock);
+ delete_reader(r->context, r->index);
+ g_mutex_unlock(&r->context->lock);
+}
+
+static int new_reader(PCSCContext *pc, const char *name, DWORD state)
+{
+ SCardReader *r;
+ VReader *vreader;
+
+ if (pc->reader_count >= CAPCSC_MAX_READERS - 1) {
+ return 1;
+ }
+
+ r = &pc->readers[pc->reader_count];
+ memset(r, 0, sizeof(*r));
+ r->index = pc->reader_count++;
+ r->context = pc;
+ r->name = g_strdup(name);
+
+ vreader = vreader_new(name, (VReaderEmul *) r, delete_reader_cb);
+ vreader_add_reader(vreader);
+ vreader_free(vreader);
+
+ return 0;
+}
+
+static int find_reader(PCSCContext *pc, const char *name)
+{
+ int i;
+ for (i = 0; i < pc->reader_count; i++)
+ if (strcmp(pc->readers[i].name, name) == 0) {
+ return i;
+ }
+
+ return -1;
+}
+
+
+static int scan_for_readers(PCSCContext *pc)
+{
+ LONG rc;
+
+ int i;
+ char buf[8192];
+ DWORD buflen = sizeof(buf);
+
+ char *p;
+ int matches[CAPCSC_MAX_READERS];
+
+ g_mutex_lock(&pc->lock);
+
+ for (i = 0; i < CAPCSC_MAX_READERS; i++) {
+ matches[i] = 0;
+ }
+
+ pc->readers_changed = 1;
+ memset(buf, 0, sizeof(buf));
+ rc = SCardListReaders(pc->context, NULL, buf, &buflen);
+ if (rc == SCARD_E_NO_READERS_AVAILABLE) {
+ rc = 0;
+ goto exit;
+ }
+
+ if (rc != SCARD_S_SUCCESS) {
+ fprintf(stderr, "SCardListReaders failed: %s (0x%lX)\n",
+ pcsc_stringify_error(rc), rc);
+ goto exit;
+ }
+
+ for (p = buf; p && p < buf + sizeof(buf); p += (strlen(p) + 1)) {
+ if (strlen(p) > 0) {
+ i = find_reader(pc, p);
+ if (i >= 0) {
+ matches[i]++;
+ } else {
+ if (!new_reader(pc, p, SCARD_STATE_UNAWARE)) {
+ matches[pc->reader_count - 1]++;
+ }
+ }
+ }
+ }
+
+ rc = 0;
+
+exit:
+ i = pc->reader_count - 1;
+ g_mutex_unlock(&pc->lock);
+
+ for (; i >= 0; i--) {
+ if (!matches[i]) {
+ VReader *reader = vreader_get_reader_by_name(pc->readers[i].name);
+ if (reader) {
+ vreader_free(reader);
+ vreader_remove_reader(reader);
+ }
+ }
+ }
+
+
+ return rc;
+}
+
+static int init_pcsc(PCSCContext *pc)
+{
+ LONG rc;
+
+ memset(pc, 0, sizeof(*pc));
+
+ rc = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &pc->context);
+ if (rc != SCARD_S_SUCCESS) {
+ fprintf(stderr, "SCardEstablishContext: "
+ "Cannot Connect to Resource Manager %lX\n", rc);
+ return rc;
+ }
+
+ return 0;
+}
+
+
+static void prepare_reader_states(PCSCContext *pc, SCARD_READERSTATE **states,
+ DWORD *reader_count)
+{
+ SCARD_READERSTATE *state;
+ int i;
+
+ if (*states) {
+ g_free(*states);
+ }
+
+ *reader_count = pc->reader_count;
+
+ (*reader_count)++;
+ *states = g_malloc((*reader_count) * sizeof(**states));
+ memset(*states, 0, sizeof((*reader_count) * sizeof(**states)));
+
+ for (i = 0, state = *states; i < pc->reader_count; i++, state++) {
+ state->szReader = pc->readers[i].name;
+ state->dwCurrentState = pc->readers[i].state;
+ }
+
+ /* Leave a space to be notified of new readers */
+ state->szReader = "\\\\?PnP?\\Notification";
+ state->dwCurrentState = SCARD_STATE_UNAWARE;
+}
+
+static int connect_card(SCardReader *r)
+{
+ LONG rc;
+
+ r->protocol = -1;
+ rc = SCardConnect(r->context->context, r->name, SCARD_SHARE_SHARED,
+ SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
+ &r->card, &r->protocol);
+ if (rc != SCARD_S_SUCCESS) {
+ fprintf(stderr, "Failed to connect to a card reader: %s (0x%lX)\n",
+ pcsc_stringify_error(rc), rc);
+ return rc;
+ }
+
+ r->card_connected = 1;
+ r->request_count = 0;
+
+ return 0;
+}
+
+static LONG send_receive(SCardReader *r, BYTE *transmit, DWORD transmit_len,
+ BYTE *receive, DWORD *receive_len)
+{
+ const SCARD_IO_REQUEST *send_header;
+ SCARD_IO_REQUEST receive_header;
+ LONG rc;
+
+ if (!r->card_connected) {
+ rc = connect_card(r);
+ if (rc) {
+ return rc;
+ }
+ }
+
+ if (r->protocol == SCARD_PROTOCOL_T0) {
+ send_header = SCARD_PCI_T0;
+ } else if (r->protocol == SCARD_PROTOCOL_T1) {
+ send_header = SCARD_PCI_T1;
+ } else {
+ fprintf(stderr, "Unknown protocol %lX\n", r->protocol);
+ return 1;
+ }
+
+ rc = SCardTransmit(r->card, send_header, transmit, transmit_len,
+ &receive_header, receive, receive_len);
+ if (rc != SCARD_S_SUCCESS) {
+ fprintf(stderr, "Failed to transmit %ld bytes: %s (0x%lX)\n",
+ transmit_len, pcsc_stringify_error(rc), rc);
+ return rc;
+ }
+
+ return 0;
+}
+
+
+static VCardStatus apdu_cb(VCard *card, VCardAPDU *apdu,
+ VCardResponse **response)
+{
+ VCardStatus ret = VCARD_DONE;
+ SCardReader *r = (SCardReader *) vcard_get_private(card);
+ BYTE outbuf[4096];
+ DWORD outlen = sizeof(outbuf);
+ LONG rc;
+
+ rc = send_receive(r, apdu->a_data, apdu->a_len, outbuf, &outlen);
+ if (rc || outlen < 2) {
+ ret = VCARD_FAIL;
+ } else {
+ *response = vcard_response_new_bytes(card, outbuf, outlen, apdu->a_Le,
+ outbuf[outlen - 2],
+ outbuf[outlen - 1]);
+ }
+
+ return ret;
+}
+
+static VCardStatus reset_cb(VCard *card, int channel)
+{
+ SCardReader *r = (SCardReader *) vcard_get_private(card);
+ LONG rc;
+
+ /* vreader_power_on is a bit too free with it's resets.
+ And a reconnect is expensive; as much as 10-20 seconds.
+ Hence, we discard any initial reconnect request. */
+ if (r->request_count++ == 0) {
+ return VCARD_DONE;
+ }
+
+ rc = SCardReconnect(r->card, SCARD_SHARE_SHARED,
+ SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
+ SCARD_RESET_CARD, &r->protocol);
+ if (rc != SCARD_S_SUCCESS) {
+ fprintf(stderr, "Failed to reconnect to a card reader: %s (0x%lX)\n",
+ pcsc_stringify_error(rc), rc);
+ return VCARD_FAIL;
+ }
+ return VCARD_DONE;
+}
+
+static void get_atr_cb(VCard *card, unsigned char *atr, int *atr_len)
+{
+ SCardReader *r = (SCardReader *) vcard_get_private(card);
+ *atr_len = r->atrlen;
+ if (atr) {
+ memcpy(atr, r->atr, r->atrlen);
+ }
+}
+
+static void delete_card_cb(VCardEmul *ve)
+{
+ fprintf(stderr, "TODO, got a delete_card_cb\n");
+}
+
+static void insert_card(SCardReader *r, SCARD_READERSTATE *s)
+{
+ memcpy(r->atr, s->rgbAtr, MIN(sizeof(r->atr), sizeof(s->rgbAtr)));
+ r->atrlen = s->cbAtr;
+
+ VReader *reader = vreader_get_reader_by_name(r->name);
+ if (!reader) {
+ return;
+ }
+
+ if (connect_card(r)) {
+ return;
+ }
+
+ VCardApplet *applet =
+ vcard_new_applet(apdu_cb,
+ reset_cb,
+ (const unsigned char *) CAPCSC_APPLET,
+ strlen(CAPCSC_APPLET));
+ if (!applet) {
+ return;
+ }
+
+ VCard * card = vcard_new((VCardEmul *) r, delete_card_cb);
+ if (!card) {
+ vcard_delete_applet(applet);
+ vreader_free(reader);
+ return;
+ }
+
+ vcard_set_type(card, VCARD_DIRECT);
+ vcard_set_atr_func(card, get_atr_cb);
+ vcard_add_applet(card, applet);
+
+ vreader_insert_card(reader, card);
+ vreader_free(reader);
+}
+
+static void remove_card(SCardReader *r)
+{
+ LONG rc;
+ memset(r->atr, 0, sizeof(r->atr));
+ r->atrlen = 0;
+
+ rc = SCardDisconnect(r->card, SCARD_LEAVE_CARD);
+ if (rc != SCARD_S_SUCCESS) {
+ fprintf(stderr, "Non fatal info:"
+ "failed to disconnect card reader: %s (0x%lX)\n",
+ pcsc_stringify_error(rc), rc);
+ }
+ r->card_connected = 0;
+
+ VReader *reader = vreader_get_reader_by_name(r->name);
+ if (!reader) {
+ return;
+ }
+
+ vreader_insert_card(reader, NULL);
+ vreader_free(reader);
+}
+
+static void process_reader_change(SCardReader *r, SCARD_READERSTATE *s)
+{
+ if (s->dwEventState & SCARD_STATE_PRESENT) {
+ insert_card(r, s);
+ } else if (s->dwEventState & SCARD_STATE_EMPTY) {
+ remove_card(r);
+ } else {
+ fprintf(stderr, "Unexpected card state change from %lx to %lx:\n",
+ r->state, s->dwEventState);
+ }
+
+ r->state = s->dwEventState & ~SCARD_STATE_CHANGED;
+}
+
+/*
+ * This thread looks for card and reader insertions and puts events on the
+ * event queue.
+ */
+static gpointer event_thread(gpointer arg)
+{
+ PCSCContext *pc = (PCSCContext *) arg;
+ DWORD reader_count = 0;
+ SCARD_READERSTATE *reader_states = NULL;
+ LONG rc;
+
+ scan_for_readers(pc);
+
+ do {
+ int i;
+ DWORD timeout = INFINITE;
+
+ g_mutex_lock(&pc->lock);
+ if (pc->readers_changed) {
+ prepare_reader_states(pc, &reader_states, &reader_count);
+ timeout = 0;
+ } else if (reader_count > 1) {
+ timeout = CAPCSC_POLL_TIME;
+ }
+
+ pc->readers_changed = 0;
+ g_mutex_unlock(&pc->lock);
+
+ rc = SCardGetStatusChange(pc->context, timeout, reader_states,
+ reader_count);
+
+ /* If we have a new reader, or an unknown reader,
+ rescan and go back and do it again */
+ if ((rc == SCARD_S_SUCCESS && (reader_states[reader_count - 1].dwEventState & SCARD_STATE_CHANGED))
+ ||
+ rc == SCARD_E_UNKNOWN_READER) {
+ scan_for_readers(pc);
+ continue;
+ }
+
+ if (rc != SCARD_S_SUCCESS && rc != SCARD_E_TIMEOUT) {
+ fprintf(stderr, "Unexpected SCardGetStatusChange ret %lx(%s)\n",
+ rc, pcsc_stringify_error(rc));
+ continue;
+ }
+
+ g_mutex_lock(&pc->lock);
+ for (i = 0; i < reader_count; i++) {
+ if (reader_states[i].dwEventState & SCARD_STATE_CHANGED) {
+ process_reader_change(&pc->readers[i], &reader_states[i]);
+ pc->readers_changed++;
+ }
+
+ }
+ g_mutex_unlock(&pc->lock);
+
+ } while (1);
+
+ return NULL;
+}
+
+/*
+ * We poll the PC/SC interface, looking for device changes
+ */
+static int new_event_thread(PCSCContext *pc)
+{
+ pc->thread = g_thread_new("capcsc_event_thread", event_thread, pc);
+ return pc->thread == NULL;
+}
+
+
+static PCSCContext context;
+
+int capcsc_init(void)
+{
+ g_mutex_init(&context.lock);
+
+ if (init_pcsc(&context)) {
+ return -1;
+ }
+
+ if (new_event_thread(&context)) {
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/libcacard/capcsc.h b/libcacard/capcsc.h
new file mode 100644
index 0000000..bb59a4e
--- /dev/null
+++ b/libcacard/capcsc.h
@@ -0,0 +1,18 @@
+/*
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+#ifndef CAPCSC_H
+#define CAPCSC_H 1
+
+#define CAPCSC_POLL_TIME 50 /* ms - Time we will poll for */
+ /* card change when a */
+ /* reader is connected */
+#define CAPCSC_MAX_READERS 16
+
+#define CAPCSC_APPLET "CAPCSC APPLET"
+
+int capcsc_init(void);
+
+
+#endif
diff --git a/libcacard/libcacard.syms b/libcacard/libcacard.syms
index 1697515..0e44dc0 100644
--- a/libcacard/libcacard.syms
+++ b/libcacard/libcacard.syms
@@ -1,5 +1,6 @@
cac_card_init
cac_is_cac_card
+capcsc_init
vcard_add_applet
vcard_apdu_delete
vcard_apdu_new
--
1.7.10.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH v2 3/4] Enable support for passthru (e.g. direct to pcsc) smart cards in the emul_options entry point in libcacard.
2015-01-20 15:38 [Qemu-devel] [PATCH v2 0/4] Add support for passthru cards to libcacard Jeremy White
2015-01-20 15:38 ` [Qemu-devel] [PATCH v2 1/4] Add a configure check for libpcsclite, and an option to enable or disable it Jeremy White
2015-01-20 15:38 ` [Qemu-devel] [PATCH v2 2/4] Add a VCARD_DIRECT implemention to the libcacard smartcard support Jeremy White
@ 2015-01-20 15:38 ` Jeremy White
2015-01-20 15:38 ` [Qemu-devel] [PATCH v2 4/4] Remove the (broken) passthru option Jeremy White
2015-02-11 15:22 ` [Qemu-devel] [PATCH v2 0/4] Add support for passthru cards to libcacard Jeremy White
4 siblings, 0 replies; 6+ messages in thread
From: Jeremy White @ 2015-01-20 15:38 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Jeremy White <jwhite@codeweavers.com>
---
libcacard/vcard.c | 2 +-
libcacard/vcard.h | 2 +-
libcacard/vcard_emul_nss.c | 29 ++++++++++++++++++++++++++++-
libcacard/vcard_emul_type.c | 3 ++-
4 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/libcacard/vcard.c b/libcacard/vcard.c
index d140a8e..4a1d91e 100644
--- a/libcacard/vcard.c
+++ b/libcacard/vcard.c
@@ -95,7 +95,7 @@ vcard_reset(VCard *card, VCardPower power)
VCardApplet *
vcard_new_applet(VCardProcessAPDU applet_process_function,
VCardResetApplet applet_reset_function,
- unsigned char *aid, int aid_len)
+ const unsigned char *aid, int aid_len)
{
VCardApplet *applet;
diff --git a/libcacard/vcard.h b/libcacard/vcard.h
index 47dc703..c16b944 100644
--- a/libcacard/vcard.h
+++ b/libcacard/vcard.h
@@ -30,7 +30,7 @@ void vcard_reset(VCard *card, VCardPower power);
*/
VCardApplet *vcard_new_applet(VCardProcessAPDU applet_process_function,
VCardResetApplet applet_reset_function,
- unsigned char *aid, int aid_len);
+ const unsigned char *aid, int aid_len);
/*
* destructor for a VCardApplet
diff --git a/libcacard/vcard_emul_nss.c b/libcacard/vcard_emul_nss.c
index 950edee..5df0958 100644
--- a/libcacard/vcard_emul_nss.c
+++ b/libcacard/vcard_emul_nss.c
@@ -25,6 +25,7 @@
#include <prthread.h>
#include <secerr.h>
+#include "config-host.h"
#include "qemu-common.h"
#include "vcard.h"
@@ -34,6 +35,9 @@
#include "vevent.h"
#include "libcacard/vcardt_internal.h"
+#if defined(CONFIG_SMARTCARD_PCSC)
+#include "capcsc.h"
+#endif
typedef enum {
@@ -892,6 +896,23 @@ vcard_emul_init(const VCardEmulOptions *options)
options = &default_options;
}
+#if defined(CONFIG_SMARTCARD_PCSC)
+ if (options->use_hw && options->hw_card_type == VCARD_EMUL_PASSTHRU) {
+ if (options->vreader_count > 0) {
+ fprintf(stderr, "Error: you cannot use a soft card and "
+ "a passthru card simultaneously.\n");
+ return VCARD_EMUL_FAIL;
+ }
+
+ if (capcsc_init()) {
+ fprintf(stderr, "Error initializing PCSC interface.\n");
+ return VCARD_EMUL_FAIL;
+ }
+
+ return VCARD_EMUL_OK;
+ }
+#endif
+
/* first initialize NSS */
if (options->nss_db) {
rv = NSS_Init(options->nss_db);
@@ -1270,5 +1291,11 @@ vcard_emul_usage(void)
"hw_type, and parameters of hw_param.\n"
"\n"
"If more one or more soft= parameters are specified, these readers will be\n"
-"presented to the guest\n");
+"presented to the guest\n"
+#if defined(CONFIG_SMARTCARD_PCSC)
+"\n"
+"If a hw_type of PASSTHRU is given, a connection will be made to the hardware\n"
+"using libpcscslite. Note that in that case, no soft cards are permitted.\n"
+#endif
+);
}
diff --git a/libcacard/vcard_emul_type.c b/libcacard/vcard_emul_type.c
index 59a1458..e8f6a4c 100644
--- a/libcacard/vcard_emul_type.c
+++ b/libcacard/vcard_emul_type.c
@@ -9,6 +9,7 @@
*/
#include <strings.h>
+#include "config-host.h"
#include "vcardt.h"
#include "vcard_emul_type.h"
#include "cac.h"
@@ -48,7 +49,7 @@ VCardEmulType vcard_emul_type_from_string(const char *type_string)
if (strcasecmp(type_string, "CAC") == 0) {
return VCARD_EMUL_CAC;
}
-#ifdef USE_PASSTHRU
+#ifdef CONFIG_SMARTCARD_PCSC
if (strcasecmp(type_string, "PASSTHRU") == 0) {
return VCARD_EMUL_PASSTHRU;
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH v2 4/4] Remove the (broken) passthru option.
2015-01-20 15:38 [Qemu-devel] [PATCH v2 0/4] Add support for passthru cards to libcacard Jeremy White
` (2 preceding siblings ...)
2015-01-20 15:38 ` [Qemu-devel] [PATCH v2 3/4] Enable support for passthru (e.g. direct to pcsc) smart cards in the emul_options entry point in libcacard Jeremy White
@ 2015-01-20 15:38 ` Jeremy White
2015-02-11 15:22 ` [Qemu-devel] [PATCH v2 0/4] Add support for passthru cards to libcacard Jeremy White
4 siblings, 0 replies; 6+ messages in thread
From: Jeremy White @ 2015-01-20 15:38 UTC (permalink / raw)
To: qemu-devel
That option can be achieved using -e "use_hw=yes hw_type=passthru"
Signed-off-by: Jeremy White <jwhite@codeweavers.com>
---
libcacard/vscclient.c | 16 +++-------------
1 file changed, 3 insertions(+), 13 deletions(-)
diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c
index fa6041d..8573f50 100644
--- a/libcacard/vscclient.c
+++ b/libcacard/vscclient.c
@@ -41,14 +41,8 @@ print_byte_array(
static void
print_usage(void) {
- printf("vscclient [-c <certname> .. -e <emul_args> -d <level>%s] "
- "<host> <port>\n",
-#ifdef USE_PASSTHRU
- " -p");
- printf(" -p use passthrough mode\n");
-#else
- "");
-#endif
+ printf("vscclient [-c <certname> .. -e <emul_args> -d <level>] "
+ "<host> <port>\n");
vcard_emul_usage();
}
@@ -673,7 +667,7 @@ main(
}
#endif
- while ((c = getopt(argc, argv, "c:e:pd:")) != -1) {
+ while ((c = getopt(argc, argv, "c:e:d:")) != -1) {
switch (c) {
case 'c':
if (cert_count >= MAX_CERTS) {
@@ -685,10 +679,6 @@ main(
case 'e':
emul_args = optarg;
break;
- case 'p':
- print_usage();
- exit(4);
- break;
case 'd':
verbose = get_id_from_string(optarg, 1);
break;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH v2 0/4] Add support for passthru cards to libcacard
2015-01-20 15:38 [Qemu-devel] [PATCH v2 0/4] Add support for passthru cards to libcacard Jeremy White
` (3 preceding siblings ...)
2015-01-20 15:38 ` [Qemu-devel] [PATCH v2 4/4] Remove the (broken) passthru option Jeremy White
@ 2015-02-11 15:22 ` Jeremy White
4 siblings, 0 replies; 6+ messages in thread
From: Jeremy White @ 2015-02-11 15:22 UTC (permalink / raw)
To: qemu-devel
Ping? Anything I can do to get review/motion on these patches?
Cheers,
Jeremy
On 01/20/2015 09:38 AM, Jeremy White wrote:
> This differs from v1 by:
> * checkpatch review
> * Patch series, instead of one patch
> * Remove internal queue in favor of relying on thread safety of pcsclite
> * Remove glib from configure
> * Use glib thread and allocation functions
>
> Jeremy White (4):
> Add a configure check for libpcsclite, and an option to enable or
> disable it.
> Add a VCARD_DIRECT implemention to the libcacard smartcard support.
> Enable support for passthru (e.g. direct to pcsc) smart cards in
> the emul_options entry point in libcacard.
> Remove the (broken) passthru option.
>
> Makefile.objs | 5 +
> configure | 38 ++++
> libcacard/capcsc.c | 488 +++++++++++++++++++++++++++++++++++++++++++
> libcacard/capcsc.h | 18 ++
> libcacard/libcacard.syms | 1 +
> libcacard/vcard.c | 2 +-
> libcacard/vcard.h | 2 +-
> libcacard/vcard_emul_nss.c | 29 ++-
> libcacard/vcard_emul_type.c | 3 +-
> libcacard/vscclient.c | 16 +-
> 10 files changed, 585 insertions(+), 17 deletions(-)
> create mode 100644 libcacard/capcsc.c
> create mode 100644 libcacard/capcsc.h
>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2015-02-11 15:22 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-01-20 15:38 [Qemu-devel] [PATCH v2 0/4] Add support for passthru cards to libcacard Jeremy White
2015-01-20 15:38 ` [Qemu-devel] [PATCH v2 1/4] Add a configure check for libpcsclite, and an option to enable or disable it Jeremy White
2015-01-20 15:38 ` [Qemu-devel] [PATCH v2 2/4] Add a VCARD_DIRECT implemention to the libcacard smartcard support Jeremy White
2015-01-20 15:38 ` [Qemu-devel] [PATCH v2 3/4] Enable support for passthru (e.g. direct to pcsc) smart cards in the emul_options entry point in libcacard Jeremy White
2015-01-20 15:38 ` [Qemu-devel] [PATCH v2 4/4] Remove the (broken) passthru option Jeremy White
2015-02-11 15:22 ` [Qemu-devel] [PATCH v2 0/4] Add support for passthru cards to libcacard Jeremy White
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).