All of lore.kernel.org
 help / color / mirror / Atom feed
* [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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.