[Spice-devel] [PATCH 04/12] Add a VCARD_DIRECT implemention to the libcacard smartcard support
Christophe Fergeau
cfergeau at redhat.com
Fri Oct 9 07:59:10 PDT 2015
On Fri, Oct 09, 2015 at 04:43:37PM +0200, Marc-André Lureau wrote:
> Keeping the author of the patch in CC
>
> On Fri, Oct 9, 2015 at 4:34 PM, Christophe Fergeau <cfergeau at redhat.com> wrote:
> > On Thu, Oct 08, 2015 at 05:40:33PM +0200, marcandre.lureau at redhat.com wrote:
> >> From: Jeremy White <jwhite at codeweavers.com>
> >>
> >> This uses libpcsclite to provide direct communication with a smartcard.
> >>
> >> Signed-off-by: Jeremy White <jwhite at codeweavers.com>
> >> Reviewed-by: Marc-André Lureau <marcandre.lureau at redhat.com>
> >> ---
> >> Makefile.am | 9 +-
> >> configure.ac | 1 +
> >> src/capcsc.c | 505 ++++++++++++++++++++++++++++++++++++++++++++++++++
> >> src/capcsc.h | 18 ++
> >> src/card_7816.c | 2 +-
> >> src/card_7816.h | 4 +-
> >> src/libcacard.syms | 2 +
> >> src/vcard.c | 2 +-
> >> src/vcard.h | 2 +-
> >> src/vcard_emul_nss.c | 11 +-
> >> src/vcard_emul_type.c | 1 +
> >> 11 files changed, 549 insertions(+), 8 deletions(-)
> >> create mode 100644 src/capcsc.c
> >> create mode 100644 src/capcsc.h
> >>
> >> diff --git a/Makefile.am b/Makefile.am
> >> index 7939079..b1e257f 100644
> >> --- a/Makefile.am
> >> +++ b/Makefile.am
> >> @@ -15,9 +15,14 @@ libcacard_la_SOURCES = \
> >> src/vreader.c \
> >> $(NULL)
> >>
> >> +if ENABLE_PCSC
> >> +libcacard_la_SOURCES += src/capcsc.c
> >> +endif
> >> +
> >> libcacard_includedir = $(includedir)/cacard
> >> libcacard_include_HEADERS = \
> >> src/cac.h \
> >> + src/capcsc.h \
> >> src/card_7816.h \
> >> src/card_7816t.h \
> >> src/eventt.h \
> >> @@ -32,7 +37,7 @@ libcacard_include_HEADERS = \
> >> src/vscard_common.h \
> >> $(NULL)
> >>
> >> -libcacard_la_LIBADD = $(CACARD_LIBS)
> >> +libcacard_la_LIBADD = $(CACARD_LIBS) $(PCSC_LIBS)
> >> libcacard_la_LDFLAGS = \
> >> -export-symbols $(srcdir)/src/libcacard.syms \
> >> -no-undefined \
> >> @@ -56,7 +61,7 @@ if OS_WIN32
> >> vscclient_CFLAGS += -D__USE_MINGW_ANSI_STDIO=1
> >> endif
> >>
> >> -AM_CPPFLAGS = $(CACARD_CFLAGS) $(WARN_CFLAGS)
> >> +AM_CPPFLAGS = $(CACARD_CFLAGS) $(PCSC_CFLAGS) $(WARN_CFLAGS)
> >> EXTRA_DIST = \
> >> NEWS \
> >> README.md \
> >> diff --git a/configure.ac b/configure.ac
> >> index b878526..6a0a73d 100644
> >> --- a/configure.ac
> >> +++ b/configure.ac
> >> @@ -49,6 +49,7 @@ if test "x$enable_pcsc" != "xno"; then
> >> fi
> >> if test "x$have_pcsc" = "xyes"; then
> >> enable_pcsc=yes
> >> + AC_DEFINE([ENABLE_PCSC], 1, [pcsc support])
> >> fi
> >> fi
> >
> > This could go in the patch adding the configure check.
>
> ok
>
> >
> >> AM_CONDITIONAL(ENABLE_PCSC, test "x$enable_pcsc" = "xyes")
> >> diff --git a/src/capcsc.c b/src/capcsc.c
> >> new file mode 100644
> >> index 0000000..3b68ee3
> >> --- /dev/null
> >> +++ b/src/capcsc.c
> >> @@ -0,0 +1,505 @@
> >> +/*
> >> + * 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.
> >> + */
> >> +
> >> +#include "glib-compat.h"
> >> +#include <string.h>
> >> +#include <stdio.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);
> >> + }
> >
> > Since libcacard is using glib, I think GArray/GPtrArray might be usable
> > to avoid manual memory juggling. There are few places where memory is
> > moved around though, so I'm fine if this stays this way.
> >
> >
> >> +
> >> + 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;
> >> + }
> >
> > Why not int matches[..] = { 0, }; or a memset?
>
> make sense
>
> >
> >> * destructor for VCardResponse.
> >> diff --git a/src/libcacard.syms b/src/libcacard.syms
> >> index 2f9d423..1b78f8d 100644
> >> --- a/src/libcacard.syms
> >> +++ b/src/libcacard.syms
> >> @@ -1,4 +1,5 @@
> >> cac_card_init
> >> +capcsc_init
> >> vcard_add_applet
> >> vcard_apdu_delete
> >> vcard_apdu_new
> >
> > I don't think you need to export capcsc_init as it's called by
> > vcard_emul_init() when needed?
> >
> >> @@ -40,6 +41,7 @@ vcard_response_new
> >> vcard_response_new_bytes
> >> vcard_response_new_data
> >> vcard_response_new_status_bytes
> >> +vcard_response_set_status_bytes
> >> vcard_select_applet
> >> vcard_set_applet_private
> >> vcard_set_atr_func
> >> diff --git a/src/vcard.c b/src/vcard.c
> >> index 667f30a..2edf1d0 100644
> >> --- a/src/vcard.c
> >> +++ b/src/vcard.c
> >> @@ -97,7 +97,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/src/vcard.h b/src/vcard.h
> >> index 16a23b5..1364dfb 100644
> >> --- a/src/vcard.h
> >> +++ b/src/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/src/vcard_emul_nss.c b/src/vcard_emul_nss.c
> >> index 7ffa0b4..d046ea9 100644
> >> --- a/src/vcard_emul_nss.c
> >> +++ b/src/vcard_emul_nss.c
> >> @@ -9,6 +9,7 @@
> >> * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
> >> * See the COPYING file in the top-level directory.
> >> */
> >> +#include "config.h"
> >>
> >> /*
> >> * NSS headers
> >> @@ -1253,7 +1254,12 @@ vcard_emul_options(const char *args)
> >> opts->hw_card_type = VCARD_EMUL_CAC;
> >> opts->use_hw = PR_TRUE;
> >> args = find_blank(args + 7);
> >> - /* nssemul */
> >> +#if defined(ENABLE_PCSC)
> >> + } else if (strncmp(args, "passthru", 8) == 0) {
> >> + opts->hw_card_type = VCARD_EMUL_PASSTHRU;
> >> + opts->use_hw = PR_TRUE;
> >> + args = find_blank(args + 8);
> >> +#endif
> >> } else {
> >> fprintf(stderr, "Error: Unknown smartcard specification.\n");
> >> return NULL;
> >> @@ -1273,6 +1279,9 @@ vcard_emul_usage(void)
> >> " hw_type={card_type_to_emulate} (default CAC)\n"
> >> " hw_param={param_for_card} (default \"\")\n"
> >> " nssemul (alias for use_hw=yes, hw_type=CAC)\n"
> >> +#if defined(ENABLE_PCSC)
> >> +" passthru (alias for use_hw=yes, hw_type=PASSTHRU)\n"
> >> +#endif
> >> " soft=({slot_name},{vreader_name},{card_type_to_emulate},{params_for_card},\n"
> >> " {cert1},{cert2},{cert3} (default none)\n"
> >> "\n"
> >
> > This is the passthru alias mentioned in another commit log.
> >
> >> diff --git a/src/vcard_emul_type.c b/src/vcard_emul_type.c
> >> index 04e8d99..385e121 100644
> >> --- a/src/vcard_emul_type.c
> >> +++ b/src/vcard_emul_type.c
> >> @@ -7,6 +7,7 @@
> >> * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
> >> * See the COPYING file in the top-level directory.
> >> */
> >> +#include "config.h"
> >>
> >> #include <strings.h>
> >> #include "vcardt.h"
> >
> > Is this hunk required as part of this commit?
>
> for #if defined(ENABLE_PCSC)
Ah, but this is only added in the "Enable support for passthru" commit,
not here.
Christophe
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/spice-devel/attachments/20151009/13d02a76/attachment.sig>
More information about the Spice-devel
mailing list