[Spice-devel] [PATCH 04/12] Add a VCARD_DIRECT implemention to the libcacard smartcard support

Marc-André Lureau marcandre.lureau at gmail.com
Fri Oct 9 07:43:37 PDT 2015


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)

>
> Christophe
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
>



-- 
Marc-André Lureau


More information about the Spice-devel mailing list