[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:34:29 PDT 2015
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.
> 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?
> * 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?
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/c6b87bba/attachment.sig>
More information about the Spice-devel
mailing list