Add support for passthru cards to libcacard
v3 cover Add support for passthru cards to libcacard
This is a resend of my outstanding patches, gathered together as one series. I'm hoping to agitate for this whole set to be considered.
Changes since v2:
* Include outstanding patches not strictly related to passthru mode
* Include a fix for read binary transactions
* Mitigate some performance issues arising from libpccslite's heavy handed thread safety code
Jeremy White (7):
Bug fix: delete the reader entry after queueing an event, not before. Retrieve the correct TD byte when checking an ATR.
Add a configure check for libpcsclite, and an option to enable or
disable it.
Add error checking to vcard_emul_options.
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 ++++ hw/usb/ccid-card-passthru.c | 2 +- libcacard/capcsc.c | 498 +++++++++++++++++++++++++++++++++++++++++++ libcacard/capcsc.h | 18 ++ libcacard/card_7816.c | 2 +- libcacard/card_7816.h | 3 + libcacard/libcacard.syms | 2 + libcacard/vcard.c | 2 +- libcacard/vcard.h | 2 +- libcacard/vcard_emul_nss.c | 78 +++++-- libcacard/vcard_emul_type.c | 3 +- libcacard/vreader.c | 2 +- libcacard/vscclient.c | 16 +- 14 files changed, 640 insertions(+), 31 deletions(-) create mode 100644 libcacard/capcsc.c create mode 100644 libcacard/capcsc.h
Signature · 1 line
1.7.10.4
PATCH v3 1/7 Bug fix: delete the reader entry after queueing an event, not before.
As far as I can tell, the vreader_remove_reader function is not presently in use anywhere; I have an upcoming patch set that uses it.
--- libcacard/vreader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
libcacard/vreader.c +1 -1
@@ -529,8 +529,8 @@ vreader_remove_reader(VReader *reader) }vreader_dequeue (vreader_list, current_entry);vreader_list_unlock (); -vreader_list_entry_delete (current_entry);vevent_queue_vevent (vevent_new (VEVENT_READER_REMOVE , reader,NULL )); +vreader_list_entry_delete (current_entry);return VREADER_OK ; }
Signature · 1 line
1.7.10.4
Re: [Qemu-devel] [PATCH v3 1/7] Bug fix: delete the reader entry after queueing an event, not before.
ACK.
Quoted 26 lines · Jeremy White
As far as I can tell, the
vreader_remove_readerfunction is not presently in use anywhere; I have an upcoming patch set that uses it.Signed-off-by Jeremy White <[email protected]>--- libcacard/vreader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)libcacard/vreader.c +1
-2@@ -529,8 +529,8 @@ vreader_remove_reader(VReader *reader) }vreader_dequeue (vreader_list, current_entry);vreader_list_unlock (); -vreader_list_entry_delete (current_entry);vevent_queue_vevent (vevent_new (VEVENT_READER_REMOVE , reader,NULL )); +vreader_list_entry_delete (current_entry);return VREADER_OK ; } --1.7.10.4
Signature · 1 line
Marc-André Lureau
PATCH v3 2/7 Retrieve the correct TD byte when checking an ATR.
In reply to Jeremy WhiteA physical smartcard with an ATR of
3B 95 95 40 FF AE 01 0E 00 00
was parsed incorrectly.
The '40' should have been the second TD; instead
the FF is used, incorrectly.
--- hw/usb/ccid-card-passthru.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
hw/usb/ccid-card-passthru.c +1 -1
@@ -168,8 +168,8 @@ static int check_atr(PassthruState *card, uint8_t *data, int len) opt_bytes++; }if (td &0x8 ) { - opt_bytes++; td = data[opt_bytes +2 ] >>4 ; + opt_bytes++; } }if (len <2 + historical_length + opt_bytes) {
Signature · 1 line
1.7.10.4
Re: [Qemu-devel] [PATCH v3 2/7] Retrieve the correct TD byte when checking an ATR.
ACK.
Quoted 30 lines · Jeremy White
A physical smartcard with an ATR of
3B 95 95 40 FF AE 01 0E 00 00
was parsed incorrectly.The '40' should have been the second TD; instead
the FF is used, incorrectly.Signed-off-by Jeremy White <[email protected]>--- hw/usb/ccid-card-passthru.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)hw/usb/ccid-card-passthru.c +1
-2@@ -168,8 +168,8 @@ static int check_atr(PassthruState *card, uint8_t *data, int len) opt_bytes++; }if (td &0x8 ) { - opt_bytes++; td = data[opt_bytes +2 ] >>4 ; + opt_bytes++; } }if (len <2 + historical_length + opt_bytes) { --1.7.10.4
Signature · 1 line
Marc-André Lureau
PATCH v3 3/7 Add a configure check for libpcsclite, and an option to enable or disable it.
In reply to Jeremy White--- configure | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+)
configure +38 -0
@@ -307,6 +307,7 @@ trace_file="trace" spice="" rbd="" smartcard_nss="" +smartcard_pcsc="" libusb="" usb_redir="" opengl=""
@@ -1043,6 +1044,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"
@@ -1373,6 +1378,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
@@ -3723,6 +3730,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
@@ -4396,6 +4427,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 "OpenGL support $opengl"
@@ -4756,6 +4788,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
Signature · 1 line
1.7.10.4
Re: [Qemu-devel] [PATCH v3 3/7] Add a configure check for libpcsclite, and an option to enable or disable it.
ACK.
Quoted 94 lines · Jeremy White
Signed-off-by Jeremy White <[email protected]>--- configure | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+)configure +38
-1@@ -307,6 +307,7 @@ trace_file="trace" spice="" rbd="" smartcard_nss="" +smartcard_pcsc="" libusb="" usb_redir="" opengl=""@@ -1043,6 +1044,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"@@ -1373,6 +1378,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@@ -3723,6 +3730,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@@ -4396,6 +4427,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 "OpenGL support $opengl"@@ -4756,6 +4788,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
Signature · 1 line
Marc-André Lureau
PATCH v3 4/7 Add error checking to vcard_emul_options.
In reply to Jeremy WhiteAlso add an alias of 'nssemul' for the default card of hw=yes hw_type=cac, and an alias of 'passthru' for the new card type of hw=yes hw_type=passthru.
This allows the spice-gtk client to take a more human friendly set of arguments and relay them through to this code.
--- libcacard/vcard_emul_nss.c | 49 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 11 deletions(-)
libcacard/vcard_emul_nss.c +38 -11
@@ -1113,17 +1113,13 @@ static VCardEmulOptions options;* and its length in "token_length". "token" will not be nul-terminated. * After calling the macro, "args" will be advanced to the beginning of * the next token. -* This macro may call continue or break. */ #define NEXT_TOKEN (token) \ (token) = args; \ args = strpbrk(args, ",)"); \ - if (*args == 0) { \ - break; \ - } \ - if (*args == ')') { \ - args++; \ - continue; \ + if (*args == 0 || *args == ')') { \ + fprintf(stderr, "Error: invalid soft specification.\n"); \ + return NULL; \ } \ (token##_length) = args - (token); \ args = strip(args+1);
@@ -1141,6 +1137,7 @@ vcard_emul_options(const char *args) do { args = strip(args); /* strip off the leading spaces */ if (*args == ',') { + args++; continue; } /* soft=(slot_name,virt_name,emul_type,emul_flags,cert_1, (no eol)
@@ -1159,7 +1156,8 @@ vcard_emul_options(const char *args) args =strip (args +5 );if (*args !='(' ) { -continue ; +fprintf (stderr,"Error: invalid soft specification.\n" ); +return NULL ; } args =strip (args+1 );
@@ -1170,11 +1168,17 @@ vcard_emul_options(const char *args)memcpy (type_str, type_params, type_params_length); type_str[type_params_length] ='\0' ; type =vcard_emul_type_from_string (type_str); +if (type ==VCARD_EMUL_NONE ) { +fprintf (stderr,"Error: invalid smartcard type '%s'.\n" , + type_str); +return NULL ; + }NEXT_TOKEN (type_params) if (*args == 0) { -break ; +fprintf (stderr,"Error: missing cert specification.\n" ); +return NULL ; }if (opts->vreader_count >= reader_count) {
@@ -1214,6 +1218,11 @@ vcard_emul_options(const char *args) }else if (strncmp (args,"hw_type=" ,8 ) ==0 ) { args =strip (args+8 ); opts->hw_card_type =vcard_emul_type_from_string (args); +if (opts->hw_card_type ==VCARD_EMUL_NONE ) { +fprintf (stderr,"Error: invalid smartcard type '%s'.\n" , + args); +return NULL ; + } args =find_blank (args);/* hw_params= */ }else if (strncmp (args,"hw_params=" ,10 ) ==0 ) {
@@ -1227,7 +1236,8 @@ vcard_emul_options(const char *args)const char *db; args =strip (args+3 );if (*args !='"' ) { -continue ; +fprintf (stderr,"Error: you must quote the file path.\n" ); +return NULL ; } args++; db = args;
@@ -1236,8 +1246,21 @@ vcard_emul_options(const char *args)if (*args !=0 ) { args++; } + }else if (strncmp (args,"nssemul" ,7 ) ==0 ) { + opts->hw_card_type =VCARD_EMUL_CAC ; + opts->use_hw =PR_TRUE ; + args =find_blank (args +7 ); +/* nssemul */ +#if defined(CONFIG_SMARTCARD_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 ); +/* passthru */ +#endif }else { - args =find_blank (args); +fprintf (stderr,"Error: Unknown smartcard specification.\n" ); +return NULL ; } }while (*args !=0 );
@@ -1253,6 +1276,10 @@ vcard_emul_usage(void)" use_hw=[yes|no] (default yes)\n" " 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(CONFIG_SMARTCARD_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"
Signature · 1 line
1.7.10.4
Re: [Qemu-devel] [PATCH v3 4/7] Add error checking to vcard_emul_options.
ACK.
Quoted 134 lines · Jeremy White
Also add an alias of 'nssemul' for the default card of hw=yes hw_type=cac, and an alias of 'passthru' for the new card type of hw=yes hw_type=passthru.
This allows the spice-gtk client to take a more human friendly set of arguments and relay them through to this code.
Signed-off-by Jeremy White <[email protected]>--- libcacard/vcard_emul_nss.c | 49 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 11 deletions(-)libcacard/vcard_emul_nss.c +38
-12@@ -1113,17 +1113,13 @@ static VCardEmulOptions options;* and its length in "token_length". "token" will not be nul-terminated. * After calling the macro, "args" will be advanced to the beginning of * the next token. -* This macro may call continue or break. */ #define NEXT_TOKEN (token) \ (token) = args; \ args = strpbrk(args, ",)"); \ - if (*args == 0) { \ - break; \ - } \ - if (*args == ')') { \ - args++; \ - continue; \ + if (*args == 0 || *args == ')') { \ + fprintf(stderr, "Error: invalid soft specification.\n"); \ + return NULL; \ } \ (token##_length) = args - (token); \ args = strip(args+1);@@ -1141,6 +1137,7 @@ vcard_emul_options(const char *args) do { args = strip(args); /* strip off the leading spaces */ if (*args == ',') { + args++; continue; } /* soft=(slot_name,virt_name,emul_type,emul_flags,cert_1, (no eol)@@ -1159,7 +1156,8 @@ vcard_emul_options(const char *args) args =strip (args +5 );if (*args !='(' ) { -continue ; +fprintf (stderr,"Error: invalid soft specification.\n" ); +return NULL ; } args =strip (args+1 );@@ -1170,11 +1168,17 @@ vcard_emul_options(const char *args)memcpy (type_str, type_params, type_params_length); type_str[type_params_length] ='\0' ; type =vcard_emul_type_from_string (type_str); +if (type ==VCARD_EMUL_NONE ) { +fprintf (stderr,"Error: invalid smartcard type '%s'.\n" , + type_str); +return NULL ; + }NEXT_TOKEN (type_params) if (*args == 0) { -break ; +fprintf (stderr,"Error: missing cert specification.\n" ); +return NULL ; }if (opts->vreader_count >= reader_count) {@@ -1214,6 +1218,11 @@ vcard_emul_options(const char *args) }else if (strncmp (args,"hw_type=" ,8 ) ==0 ) { args =strip (args+8 ); opts->hw_card_type =vcard_emul_type_from_string (args); +if (opts->hw_card_type ==VCARD_EMUL_NONE ) { +fprintf (stderr,"Error: invalid smartcard type '%s'.\n" , + args); +return NULL ; + } args =find_blank (args);/* hw_params= */ }else if (strncmp (args,"hw_params=" ,10 ) ==0 ) {@@ -1227,7 +1236,8 @@ vcard_emul_options(const char *args)const char *db; args =strip (args+3 );if (*args !='"' ) { -continue ; +fprintf (stderr,"Error: you must quote the file path.\n" ); +return NULL ; } args++; db = args;@@ -1236,8 +1246,21 @@ vcard_emul_options(const char *args)if (*args !=0 ) { args++; } + }else if (strncmp (args,"nssemul" ,7 ) ==0 ) { + opts->hw_card_type =VCARD_EMUL_CAC ; + opts->use_hw =PR_TRUE ; + args =find_blank (args +7 ); +/* nssemul */ +#if defined(CONFIG_SMARTCARD_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 ); +/* passthru */ +#endif }else { - args =find_blank (args); +fprintf (stderr,"Error: Unknown smartcard specification.\n" ); +return NULL ; } }while (*args !=0 );@@ -1253,6 +1276,10 @@ vcard_emul_usage(void)" use_hw=[yes|no] (default yes)\n" " 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(CONFIG_SMARTCARD_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" --1.7.10.4
Signature · 1 line
Marc-André Lureau
PATCH v3 5/7 Add a VCARD_DIRECT implemention to the libcacard smartcard support.
In reply to Jeremy WhiteThis uses libpcsclite to provide direct communication with a smartcard.
--- Makefile.objs | 5 + libcacard/capcsc.c | 498 ++++++++++++++++++++++++++++++++++++++++++++++ libcacard/capcsc.h | 18 ++ libcacard/card_7816.c | 2 +- libcacard/card_7816.h | 3 + libcacard/libcacard.syms | 2 + 6 files changed, 527 insertions(+), 1 deletion(-) create mode 100644 libcacard/capcsc.c create mode 100644 libcacard/capcsc.h
Makefile.objs +5 -0
@@ -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
libcacard/capcsc.c new file +498 -0
498 lines not on this page · raw message
libcacard/capcsc.h new file +18 -0
@@ -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
libcacard/card_7816.c +1 -1
@@ -31,7 +31,7 @@ vcard_response_set_status(VCardResponse *response, vcard_7816_status_t status)/* * set the status bytes in a response buffer */ -static void +void vcard_response_set_status_bytes (VCardResponse *response,unsigned char sw1,unsigned char sw2) {
libcacard/card_7816.h +3 -0
@@ -31,6 +31,9 @@ VCardResponse *vcard_make_response(vcard_7816_status_t status);/* create a raw response (status has already been encoded */ VCardResponse *vcard_response_new_data (unsigned char *buf,int len); +void +vcard_response_set_status_bytes (VCardResponse *response, +unsigned char sw1,unsigned char sw2);
libcacard/libcacard.syms +2 -0
@@ -1,5 +1,6 @@ cac_card_init cac_is_cac_card +capcsc_init vcard_add_applet vcard_apdu_delete vcard_apdu_new
@@ -41,6 +42,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
Signature · 1 line
1.7.10.4
Re: [Qemu-devel] [PATCH v3 5/7] Add a VCARD_DIRECT implemention to the libcacard smartcard support.
ACK.
(the extra symbols should be shaved in a future libcacard update)
Quoted 608 lines · Jeremy White
This uses libpcsclite to provide direct communication with a smartcard.
Signed-off-by Jeremy White <[email protected]>--- Makefile.objs | 5 + libcacard/capcsc.c | 498 ++++++++++++++++++++++++++++++++++++++++++++++ libcacard/capcsc.h | 18 ++ libcacard/card_7816.c | 2 +- libcacard/card_7816.h | 3 + libcacard/libcacard.syms | 2 + 6 files changed, 527 insertions(+), 1 deletion(-) create mode 100644 libcacard/capcsc.c create mode 100644 libcacard/capcsc.hMakefile.objs +5
-0@@ -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 tolibcacard/capcsc.c new file +498
-0@@ -0,0 +1,498 @@ +/* +* 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.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_data (outbuf, outlen -2 ); +if (*response ==NULL ) { +return VCARD_FAIL ; + } +vcard_response_set_status_bytes (*response, 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 =0 ; + } + + 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); + +/* libpcsclite is only thread safe at a high level. If we constantly +hold long calls into SCardGetStatusChange, we'll starve any running +clients. So, if we have an active session, and nothing has changed +on our front, we just idle. */ +if (!pc->readers_changed && reader_count >1 ) { +usleep (CAPCSC_POLL_TIME *1000 ); + } + + + }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 ; +}libcacard/capcsc.h new file +18
-0@@ -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 libcacard/card_7816.c +1
-1@@ -31,7 +31,7 @@ vcard_response_set_status(VCardResponse *response, vcard_7816_status_t status)/* * set the status bytes in a response buffer */ -static void +void vcard_response_set_status_bytes (VCardResponse *response,unsigned char sw1,unsigned char sw2) {libcacard/card_7816.h +3
-0@@ -31,6 +31,9 @@ VCardResponse *vcard_make_response(vcard_7816_status_t status);/* create a raw response (status has already been encoded */ VCardResponse *vcard_response_new_data (unsigned char *buf,int len); +void +vcard_response_set_status_bytes (VCardResponse *response, +unsigned char sw1,unsigned char sw2);libcacard/libcacard.syms +2
-1@@ -1,5 +1,6 @@ cac_card_init cac_is_cac_card +capcsc_init vcard_add_applet vcard_apdu_delete vcard_apdu_new@@ -41,6 +42,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 --1.7.10.4
Signature · 1 line
Marc-André Lureau
PATCH v3 6/7 Enable support for passthru (e.g. direct to pcsc) smart cards in the emul_options entry point in libcacard.
In reply to Jeremy White--- 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(-)
libcacard/vcard.c +1 -1
@@ -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;
libcacard/vcard.h +1 -1
@@ -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
libcacard/vcard_emul_nss.c +28 -1
@@ -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);
@@ -1297,5 +1318,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 +); }
libcacard/vcard_emul_type.c +2 -1
@@ -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 ; }
Signature · 1 line
1.7.10.4
Re: [Qemu-devel] [PATCH v3 6/7] Enable support for passthru (e.g. direct to pcsc) smart cards in the emul_options entry point in libcacard.
ACK.
Quoted 119 lines · Jeremy White
Signed-off-by Jeremy White <[email protected]>--- 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(-)libcacard/vcard.c +1
-1@@ -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;libcacard/vcard.h +1
-1@@ -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 libcacard/vcard_emul_nss.c +28
-1@@ -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);@@ -1297,5 +1318,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 +); }libcacard/vcard_emul_type.c +2
-2@@ -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
Signature · 1 line
Marc-André Lureau
PATCH v3 7/7 Remove the (broken) passthru option.
In reply to Jeremy WhiteThat option can be achieved using -e "use_hw=yes hw_type=passthru"
--- libcacard/vscclient.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-)
libcacard/vscclient.c +3 -13
@@ -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 ;
Signature · 1 line
1.7.10.4
Re: [Qemu-devel] [PATCH v3 7/7] Remove the (broken) passthru option.
ACK.
Quoted 52 lines · Jeremy White
That option can be achieved using -e "use_hw=yes hw_type=passthru"
Signed-off-by Jeremy White <[email protected]>--- libcacard/vscclient.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-)libcacard/vscclient.c +3
-14@@ -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
Signature · 1 line
Marc-André Lureau
This series passed Patchew automatic testing, but there are some warnings.
Find the log fragments below, or open the following URL to see the full log:
http://qemu.patchew.org/testing/log/<[email protected]>
----------8<---------
total: 0 errors, 0 warnings, 74 lines checked
0003-Add-a-configure-check-for-libpcsclite--and-an-option-to-enable-or-disable-it-.patch has no obvious style problems and is ready for submission.
Checking 0004-Add-error-checking-to-vcard_emul_options-.patch
total: 0 errors, 0 warnings, 106 lines checked
0004-Add-error-checking-to-vcard_emul_options-.patch has no obvious style problems and is ready for submission.
Checking 0005-Add-a-VCARD_DIRECT-implemention-to-the-libcacard-smartcard-support-.patch command failed with exit code 0
$@
WARNING: line over 80 characters
#472: FILE: libcacard/capcsc.c:436:
+ if ((rc == SCARD_S_SUCCESS && (reader_states[reader_count - 1].dwEventState & SCARD_STATE_CHANGED))
total: 0 errors, 1 warnings, 557 lines checked
0005-Add-a-VCARD_DIRECT-implemention-to-the-libcacard-smartcard-support-.patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking 0006-Enable-support-for-passthru--e-g--direct-to-pcsc--smart-cards-in-the-emul_options-entry-point-in-libcacard-.patch
total: 0 errors, 0 warnings, 82 lines checked
0006-Enable-support-for-passthru--e-g--direct-to-pcsc--smart-cards-in-the-emul_options-entry-point-in-libcacard-.patch has no obvious style problems and is ready for submission.
Checking 0007-Remove-the--broken--passthru-option-.patch
total: 0 errors, 0 warnings, 34 lines checked
0007-Remove-the--broken--passthru-option-.patch has no obvious style problems and is ready for submission.
Hi Jeremy
I have checked no regression for spice, but not the new pcsc backend. Do you have a spice-gtk branch or are you using vscclient only?
I would feel better note polluting more the exported symbols from libcacard. For ex, vcard_init() and cac_card_init() are already quite useless, since they are called from vcard_emul_init() Would you be able to init PCSC there too, when it's selected? (there are too many init or exported functions already)
Why did you export vcard_response_set_status_bytes()?
Hey Marc-André,
Thanks for the review.
Quoted 4 lines · Marc-André Lureau
Hi Jeremy
I have checked no regression for spice, but not the new pcsc backend. Do you have a spice-gtk branch or are you using vscclient only?
I'm using spice-gtk with this patch:
http://lists.freedesktop.org/archives/spice-devel/2015-January/018674.html
and then invoking it with --spice-smartcard[=passthru]
Quoted 9 lines
I would feel better note polluting more the exported symbols from libcacard. For ex,
vcard_init()andcac_card_init()are already quite useless, since they are called fromvcard_emul_init()Would you be able to init PCSC there too, when it's selected? (there are too many init or exported functions already)Why did you export
vcard_response_set_status_bytes()?
It seemed as though the convention was that all non static functions went into the .syms file; I may have misunderstood.
capcsc_init certainly does not need to be exported; it is only intended to be used from vcard_emul_init(). I thought I was simply following existing convention.
For vcard_response_set_status_bytes, I needed that function in capcsc.c.
Again, I followed what I saw as the convention. However, that one is
perhaps arguably more useful to export; certainly if you're going to export the other vcard_response_xxx functions, this would be a useful one to add to the mix.
Cheers,
Jeremy
Quoted 2 lines · Jeremy White
It seemed as though the convention was that all non static functions went into the .syms file; I may have misunderstood.
I suspect that the .syms file was introduced as a way to hide utility functions from libqemuutil.a. Now that libqemuutil is not used anymore in libcacard, we should either remove the .syms file or shave its contents. This is of course not falling on you.
Paolo
Quoted 3 lines
capcsc_initcertainly does not need to be exported; it is only intended to be used fromvcard_emul_init(). I thought I was simply following existing convention.
Hi
Quoted 8 lines · Paolo Bonzini
Quoted 2 lines · Jeremy White
It seemed as though the convention was that all non static functions went into the .syms file; I may have misunderstood.
I suspect that the .syms file was introduced as a way to hide utility functions from libqemuutil.a. Now that libqemuutil is not used anymore in libcacard, we should either remove the .syms file or shave its contents. This is of course not falling on you.
Ok, let's try to get this series first, and we can look at cleaning the library symbols after.
Signature · 1 line
Marc-André Lureau