New upstream version 1.9.9

This commit is contained in:
Ludovic Rousseau 2022-09-11 16:21:29 +02:00
parent fd719fbb94
commit 2cb5c621b8
18 changed files with 510 additions and 69 deletions

View File

@ -1,3 +1,13 @@
1.9.9: Ludovic Rousseau
11 September 2022
- SCardEstablishContext() may return SCARD_W_SECURITY_VIOLATION if refused by Polkit
- Fix SCardReleaseContext() failure on orphan handles
- Fix SCardDisconnect() on orphan handle
- pcsc-spy: log the pioSendPci & pioRecvPci SCardTransmit() parameters
- Improve the log from pcscd: log the return code in text instead of hex
- Some other minor improvements
1.9.8: Ludovic Rousseau 1.9.8: Ludovic Rousseau
11 June 2022 11 June 2022
- Install install_spy.sh & uninstall_spy.sh scripts in docdir - Install install_spy.sh & uninstall_spy.sh scripts in docdir

View File

@ -1,4 +1,290 @@
commit 41dc5a51321bc3198af36574f73dc007cab72a7d (HEAD -> master, tag: 1.9.8) commit 15c16c7796607b1c8a2ce253d3f536918ab26b4a (HEAD -> master, origin/master, origin/HEAD)
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
Date: Sun Sep 11 16:12:03 2022 +0200
Release 1.9.9
Signed-off-by: Ludovic Rousseau <ludovic.rousseau@free.fr>
ChangeLog | 10 ++++++++++
configure.ac | 2 +-
2 files changed, 11 insertions(+), 1 deletion(-)
commit d069c580b74273bfcf12523b73f71bb6be9378dd (zotac/master, github/master)
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
Date: Sun Sep 11 13:59:34 2022 +0200
c.sh: reformat
c.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
commit 241a993f954b00cbb5904ac5fc6e4425977fc319
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
Date: Thu Sep 8 19:43:39 2022 +0200
UT control_get_firmware: support multi-readers
Do not exit if the command fails with a reader but continue with the other
readers.
UnitaryTests/control_get_firmware.py | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
commit 1935b6997b281f0d836b829b4cfeeab6c81c3ded
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
Date: Sat Aug 20 15:29:28 2022 +0200
SCardEstablishContext() may return SCARD_W_SECURITY_VIOLATION
See the previous patch for details.
src/winscard_clnt.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
commit 68f629ffecaec3886c717021e70ac62c22b38bd8
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
Date: Sat Aug 20 15:13:00 2022 +0200
MessageReceive() may return SCARD_W_SECURITY_VIOLATION
If the daemon kills/resets the connection because the user is not
authorized by Polkit then the client side now returns
SCARD_W_SECURITY_VIOLATION instead of the too generic
SCARD_F_COMM_ERROR.
Polkit is used in RedHat/Fedora. Users connected by ssh do not have
access to PC/SC by default.
On the daemon side we have in the logs:
00000003 [139737213696960] pcscdaemon.c:133:SVCServiceRunLoop() A new
context thread creation is requested: 10
00019807 [139737012623104] auth.c:139:IsClientAuthorized() Process
41685 (user: 1000) is NOT authorized for action: access_pcsc
00000107 [139737012623104] winscard_svc.c:335:ContextThread() Rejected
unauthorized PC/SC client
But this information was not available in the client side.
pcsc_scan will now report:
$ pcsc_scan
SCardEstablishContext: Access denied.
This has been discussed on the pcsclite-muscle mailing list at:
"[Pcsclite-muscle] Change the error code when PC/SC access is refused by
polkit?"
http://lists.infradead.org/pipermail/pcsclite-muscle/2022-July/001279.html
src/winscard_msg.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
commit 34f27e766f413d8f37a95ad605dbe6f664c077bc
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
Date: Sat Aug 20 15:03:53 2022 +0200
pcsc_stringify_error(): add SCARD_W_SECURITY_VIOLATION
src/error.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
commit 8eca1a54b252a84f5498ac5e5b84e81a47c9d231
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
Date: Sat Aug 20 14:45:14 2022 +0200
Remove unsed #define
SCARD_PROTOCOL_ANY_OLD is no more used on the client side.
src/winscard_clnt.c | 3 ---
1 file changed, 3 deletions(-)
commit 6a6291eb8e7906d4f63c962360e5fdc5d6d745db
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
Date: Sat Aug 13 14:44:28 2022 +0200
Log the error in text and not just the hex code
We now have:
00000008 [139893430789696] winscard.c:1621:SCardTransmit() Card not transacted: rv=SCARD_E_NO_SMARTCARD
instead of:
00000008 [139893430789696] winscard.c:1621:SCardTransmit() Card not transacted: rv=0x8010000C
src/eventhandler.c | 2 +-
src/readerfactory.c | 2 +-
src/winscard.c | 14 +++++++-------
3 files changed, 9 insertions(+), 9 deletions(-)
commit fecbcac0e6a8cf43b691151fef2967600098b49b
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
Date: Sat Aug 13 14:52:42 2022 +0200
UnitaryTests: fix a deprecation warning
UnitaryTests/ThreadSafeConnect.py:87: DeprecationWarning: getName() is deprecated, get the name attribute instead
print("joined:", thread.getName())
UnitaryTests/ThreadSafeConnect.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
commit 13bd3dcc9fa1ae6894ac4f882c5a62b28a6adde5
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
Date: Sat Aug 13 14:41:59 2022 +0200
export rv2txt() function
convert from integer rv value to a string value
SCARD_S_SUCCESS -> "SCARD_S_SUCCESS"
src/PCSC/debuglog.h | 2 ++
src/debuglog.c | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
commit 002d1ffef359cfba1c45f24c78ac21e18925e670
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
Date: Fri Aug 12 17:51:37 2022 +0200
Improve the log from pcscd
- log the return code in text instead of hex
00000002 [139848448452160] winscard_svc.c:523:ContextThread() CONNECT for client 12, rv=SCARD_E_UNKNOWN_READER
insted of:
00000004 [140270933177920] winscard_svc.c:523:ContextThread() CONNECT rv=0x80100009 for client 12
- colorize the return value in red in case it is different from SCARD_S_SUCCESS
The idea is to more easily spot an error code in the values returned by
pcscd.
src/PCSC/debuglog.h | 5 +++
src/debuglog.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++----
src/winscard_svc.c | 2 +-
3 files changed, 107 insertions(+), 9 deletions(-)
commit e2de54e00f2ebeebf633adef32228d2af33a6483
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
Date: Sat Jul 30 14:02:49 2022 +0200
pcsc-spy: log the pioSendPci & pioRecvPci SCardTransmit() parameters
The pioSendPci contains the protocol to use and may be important to
diagnose a SCARD_E_PROTO_MISMATCH error.
src/spy/libpcscspy.c | 4 ++++
src/spy/pcsc-spy | 30 ++++++++++++++++++++++++++++++
2 files changed, 34 insertions(+)
commit af1f32ca3762374dc66aac972c0c3fc50e9ae566
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
Date: Sun Jul 17 17:57:26 2022 +0200
pcscd.8: remove reference to bundleTool
bundleTool is no more provided with pcsc-lite since
84448b0d2a7b5300837c40311f12d81a959a9f45 in 2006.
doc/pcscd.8.in | 1 -
1 file changed, 1 deletion(-)
commit ff8f77d445ebf7f863ed4cf4951b7ab6e1d08426
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
Date: Sun Jul 17 17:52:29 2022 +0200
pcscd.8: fix typo in manpage
doc/pcscd.8.in | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
commit c35130f2215b75c6d54c4f0162d68548a6de4bab
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
Date: Sun Jun 19 21:32:20 2022 +0200
Improve SCardDisconnect fix
Same justification as for the previous patch. RFReaderInfoById() may
return SCARD_E_READER_UNAVAILABLE.
src/winscard.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
commit d7a08877c3f1d423f8fcfcb5b60f2cf6fefeceda
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
Date: Sun Jun 19 21:27:46 2022 +0200
Improve SCardReleaseContext fix
From Maksim Ivanov:
SCARD_E_READER_UNAVAILABLE can be returned by RFReaderInfoById(): it's a
corner case when the reader context is still there, but has a zero
reference count.
See RFReaderInfoById() using the REF_READER macro, which calls
_RefReader() (and returns its error code on error), which in turn has
this code:
if (0 == sReader->reference)
return SCARD_E_READER_UNAVAILABLE;
src/winscard_svc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
commit d0e594789096c7b99ace1ec6ab2cecb7961747cb
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
Date: Sun Jun 19 18:53:36 2022 +0200
Test orphan handles
Check the return values of SCardDisconnect() and SCardReleaseContext()
after a reader removal.
UnitaryTests/SCard_RemovedReader.py | 80 +++++++++++++++++++++++++++++++++++++
1 file changed, 80 insertions(+)
commit a4e5bf41ae652fd3837cc446a5a8cce0f4249845
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
Date: Sun Jun 19 18:49:42 2022 +0200
Fix SCardDisconnect on orphan handle
If the reader is removed between SCardConnect() and SCardDisconnect()
then SCardDisconnect() should not fail with SCARD_E_INVALID_VALUE.
We now have the same behavior as on Windows 10.
This patch is quiet similar to the previous one from Maksim Ivanov.
Thanks for the idea.
src/winscard.c | 3 +++
1 file changed, 3 insertions(+)
commit 2735a6d1b7ffa5ca81e602417516a9c0702c0fcd
Author: Maksim Ivanov <emaxx@google.com>
Date: Sat Jun 18 13:46:38 2022 +0200
Fix SCardReleaseContext failure on orphan handles
Fix returning a spurious error from SCardReleaseContext() for a
correct SCARDCONTEXT, in case there was an orphan SCARDHANDLE left after
disconnecting a reader.
The error was caused by the fact that SCardReleaseContext attempts to do
SCardDisconnect for all active SCARDHANDLEs stored in SCARDCONTEXT,
which fails when the handle was already deleted by the hotplug code from
READER_CONTEXT or the reader got zero reference count.
src/winscard_svc.c | 59 ++++++++++++++++++++++++++++++------------------------
1 file changed, 33 insertions(+), 26 deletions(-)
commit 2c3e9156bea6d658f5f7af801f5b92cdb9c83882
Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
Date: Mon Jun 13 17:11:50 2022 +0200
pcscd.h: remove unused PCSCLITE_STATUS_WAIT
PCSCLITE_STATUS_WAIT is no more used since
c2a93242e445558ead8eea40223482ee8995954a in 2008.
src/pcscd.h.in | 2 --
1 file changed, 2 deletions(-)
commit 41dc5a51321bc3198af36574f73dc007cab72a7d (tag: 1.9.8)
Author: Ludovic Rousseau <ludovic.rousseau@free.fr> Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
Date: Sat Jun 11 10:49:34 2022 +0200 Date: Sat Jun 11 10:49:34 2022 +0200
@ -10,7 +296,7 @@ Date: Sat Jun 11 10:49:34 2022 +0200
configure.ac | 2 +- configure.ac | 2 +-
2 files changed, 11 insertions(+), 1 deletion(-) 2 files changed, 11 insertions(+), 1 deletion(-)
commit f7f80db5fae5f15c0d0ce2e6cd81a5c11c0a7510 (zotac/master, origin/master, origin/HEAD, github/master) commit f7f80db5fae5f15c0d0ce2e6cd81a5c11c0a7510
Author: Ludovic Rousseau <ludovic.rousseau@free.fr> Author: Ludovic Rousseau <ludovic.rousseau@free.fr>
Date: Fri Jun 10 09:58:46 2022 +0200 Date: Fri Jun 10 09:58:46 2022 +0200

View File

@ -160,7 +160,7 @@ DIST_SUBDIRS = $(SUBDIRS)
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
$(top_srcdir)/src/PCSC/pcsclite.h.in AUTHORS COPYING ChangeLog \ $(top_srcdir)/src/PCSC/pcsclite.h.in AUTHORS COPYING ChangeLog \
INSTALL NEWS README TODO ar-lib compile config.guess \ INSTALL NEWS README TODO ar-lib compile config.guess \
config.sub install-sh ltmain.sh missing ylwrap config.sub depcomp install-sh ltmain.sh missing ylwrap
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION) distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir) top_distdir = $(distdir)

20
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.71 for pcsc-lite 1.9.8. # Generated by GNU Autoconf 2.71 for pcsc-lite 1.9.9.
# #
# #
# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
@ -618,8 +618,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='pcsc-lite' PACKAGE_NAME='pcsc-lite'
PACKAGE_TARNAME='pcsc-lite' PACKAGE_TARNAME='pcsc-lite'
PACKAGE_VERSION='1.9.8' PACKAGE_VERSION='1.9.9'
PACKAGE_STRING='pcsc-lite 1.9.8' PACKAGE_STRING='pcsc-lite 1.9.9'
PACKAGE_BUGREPORT='' PACKAGE_BUGREPORT=''
PACKAGE_URL='' PACKAGE_URL=''
@ -1424,7 +1424,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures pcsc-lite 1.9.8 to adapt to many kinds of systems. \`configure' configures pcsc-lite 1.9.9 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1495,7 +1495,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of pcsc-lite 1.9.8:";; short | recursive ) echo "Configuration of pcsc-lite 1.9.9:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1649,7 +1649,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
pcsc-lite configure 1.9.8 pcsc-lite configure 1.9.9
generated by GNU Autoconf 2.71 generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc. Copyright (C) 2021 Free Software Foundation, Inc.
@ -2065,7 +2065,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by pcsc-lite $as_me 1.9.8, which was It was created by pcsc-lite $as_me 1.9.9, which was
generated by GNU Autoconf 2.71. Invocation command line was generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw $ $0$ac_configure_args_raw
@ -3336,7 +3336,7 @@ fi
# Define the identity of the package. # Define the identity of the package.
PACKAGE='pcsc-lite' PACKAGE='pcsc-lite'
VERSION='1.9.8' VERSION='1.9.9'
printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
@ -17242,7 +17242,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by pcsc-lite $as_me 1.9.8, which was This file was extended by pcsc-lite $as_me 1.9.9, which was
generated by GNU Autoconf 2.71. Invocation command line was generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -17310,7 +17310,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped' ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\ ac_cs_version="\\
pcsc-lite config.status 1.9.8 pcsc-lite config.status 1.9.9
configured by $0, generated by GNU Autoconf 2.71, configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"

View File

@ -3,7 +3,7 @@
AC_PREREQ([2.69]) AC_PREREQ([2.69])
AC_INIT([pcsc-lite],[1.9.8]) AC_INIT([pcsc-lite],[1.9.9])
AC_CONFIG_SRCDIR(src/pcscdaemon.c) AC_CONFIG_SRCDIR(src/pcscdaemon.c)
AM_INIT_AUTOMAKE(1.8 dist-bzip2 no-dist-gzip) AM_INIT_AUTOMAKE(1.8 dist-bzip2 no-dist-gzip)
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])

View File

@ -77,7 +77,7 @@ files to detect added or removed non-USB readers (serial or PCMCIA).
.BR \-x ", " \-\-auto\-exit .BR \-x ", " \-\-auto\-exit
pcscd will quit after 60 seconds of inactivity after the release of pcscd will quit after 60 seconds of inactivity after the release of
the last PC/SC context. This is used when pcscd the last PC/SC context. This is used when pcscd
os started on demand by systemd. is started on demand by systemd.
.TP .TP
.BR \-S ", " \-\-reader\-name\-no\-serial .BR \-S ", " \-\-reader\-name\-no\-serial
Do not include the USB serial number in the reader name. Do not include the USB serial number in the reader name.
@ -90,7 +90,7 @@ coordinates communications with smart card readers and smart cards and
cryptographic tokens that are connected to the system. cryptographic tokens that are connected to the system.
.PP .PP
It allows applications to access smart cards and readers using the It allows applications to access smart cards and readers using the
winscard API but without knowing details of the card or reader. WinSCard API but without knowing details of the card or reader.
.PP .PP
pcscd coordinates the loading of drivers for card readers. pcscd coordinates the loading of drivers for card readers.
. .
@ -125,7 +125,6 @@ file.
: directory containing bundles for USB drivers : directory containing bundles for USB drivers
. .
.SH "SEE ALSO" .SH "SEE ALSO"
.BR bundleTool (8),
.BR reader.conf (5), .BR reader.conf (5),
.BR syslog (3) .BR syslog (3)
. .

View File

@ -92,9 +92,11 @@ enum {
#define Log2(priority, fmt, data) do {(void)priority; } while(0) #define Log2(priority, fmt, data) do {(void)priority; } while(0)
#define Log3(priority, fmt, data1, data2) do {int p = priority; (void)p; } while(0) #define Log3(priority, fmt, data1, data2) do {int p = priority; (void)p; } while(0)
#define Log4(priority, fmt, data1, data2, data3) do { } while(0) #define Log4(priority, fmt, data1, data2, data3) do { } while(0)
#define LogRv4(priority, rv, fmt, data1, data2) do { } while(0)
#define Log5(priority, fmt, data1, data2, data3, data4) do { } while(0) #define Log5(priority, fmt, data1, data2, data3, data4) do { } while(0)
#define Log9(priority, fmt, data1, data2, data3, data4, data5, data6, data7, data8) do { } while(0) #define Log9(priority, fmt, data1, data2, data3, data4, data5, data6, data7, data8) do { } while(0)
#define LogXxd(priority, msg, buffer, size) do { } while(0) #define LogXxd(priority, msg, buffer, size) do { } while(0)
#define rv2text(rv) ""
#define DebugLogA(a) #define DebugLogA(a)
#define DebugLogB(a, b) #define DebugLogB(a, b)
@ -107,9 +109,11 @@ enum {
#define Log2(priority, fmt, data) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data) #define Log2(priority, fmt, data) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data)
#define Log3(priority, fmt, data1, data2) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data1, data2) #define Log3(priority, fmt, data1, data2) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data1, data2)
#define Log4(priority, fmt, data1, data2, data3) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data1, data2, data3) #define Log4(priority, fmt, data1, data2, data3) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data1, data2, data3)
#define LogRv4(priority, rv, fmt, data1, data2) log_msg_rv(priority, rv, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data1, data2)
#define Log5(priority, fmt, data1, data2, data3, data4) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data1, data2, data3, data4) #define Log5(priority, fmt, data1, data2, data3, data4) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data1, data2, data3, data4)
#define Log9(priority, fmt, data1, data2, data3, data4, data5, data6, data7, data8) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data1, data2, data3, data4, data5, data6, data7, data8) #define Log9(priority, fmt, data1, data2, data3, data4, data5, data6, data7, data8) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data1, data2, data3, data4, data5, data6, data7, data8)
#define LogXxd(priority, msg, buffer, size) log_xxd(priority, msg, buffer, size) #define LogXxd(priority, msg, buffer, size) log_xxd(priority, msg, buffer, size)
const char * rv2text(unsigned int rv);
#define DebugLogA(a) Log1(PCSC_LOG_INFO, a) #define DebugLogA(a) Log1(PCSC_LOG_INFO, a)
#define DebugLogB(a, b) Log2(PCSC_LOG_INFO, a, b) #define DebugLogB(a, b) Log2(PCSC_LOG_INFO, a, b)
@ -117,6 +121,9 @@ enum {
#endif /* NO_LOG */ #endif /* NO_LOG */
PCSC_API void log_msg_rv(const int priority, unsigned int rv, const char *fmt, ...)
__attribute__((format(printf, 3, 4)));
PCSC_API void log_msg(const int priority, const char *fmt, ...) PCSC_API void log_msg(const int priority, const char *fmt, ...)
__attribute__((format(printf, 2, 3))); __attribute__((format(printf, 2, 3)));

View File

@ -110,7 +110,27 @@ static char LogLevel = PCSC_LOG_ERROR;
static signed char LogDoColor = 0; /**< no color by default */ static signed char LogDoColor = 0; /**< no color by default */
static void log_line(const int priority, const char *DebugBuffer); static void log_line(const int priority, const char *DebugBuffer,
unsigned int rv);
/*
* log a message with the RV value returned by the daemon
*/
void log_msg_rv(const int priority, unsigned int rv, const char *fmt, ...)
{
char DebugBuffer[DEBUG_BUF_SIZE];
va_list argptr;
if ((priority < LogLevel) /* log priority lower than threshold? */
|| (DEBUGLOG_NO_DEBUG == LogMsgType))
return;
va_start(argptr, fmt);
vsnprintf(DebugBuffer, sizeof DebugBuffer, fmt, argptr);
va_end(argptr);
log_line(priority, DebugBuffer, rv);
}
void log_msg(const int priority, const char *fmt, ...) void log_msg(const int priority, const char *fmt, ...)
{ {
@ -125,10 +145,62 @@ void log_msg(const int priority, const char *fmt, ...)
vsnprintf(DebugBuffer, sizeof DebugBuffer, fmt, argptr); vsnprintf(DebugBuffer, sizeof DebugBuffer, fmt, argptr);
va_end(argptr); va_end(argptr);
log_line(priority, DebugBuffer); log_line(priority, DebugBuffer, -1);
} /* log_msg */ } /* log_msg */
static void log_line(const int priority, const char *DebugBuffer) /* convert from integer rv value to a string value
* SCARD_S_SUCCESS -> "SCARD_S_SUCCESS"
*/
const char * rv2text(unsigned int rv)
{
const char *rv_text = NULL;
static __thread char strError[30];
#define CASE(x) \
case x: \
rv_text = "rv=" #x; \
break
if (rv != (unsigned int)-1)
{
switch (rv)
{
CASE(SCARD_S_SUCCESS);
CASE(SCARD_E_CANCELLED);
CASE(SCARD_E_INSUFFICIENT_BUFFER);
CASE(SCARD_E_INVALID_HANDLE);
CASE(SCARD_E_INVALID_PARAMETER);
CASE(SCARD_E_INVALID_VALUE);
CASE(SCARD_E_NO_MEMORY);
CASE(SCARD_E_NO_SERVICE);
CASE(SCARD_E_NO_SMARTCARD);
CASE(SCARD_E_NOT_TRANSACTED);
CASE(SCARD_E_PROTO_MISMATCH);
CASE(SCARD_E_READER_UNAVAILABLE);
CASE(SCARD_E_SHARING_VIOLATION);
CASE(SCARD_E_TIMEOUT);
CASE(SCARD_E_UNKNOWN_READER);
CASE(SCARD_E_UNSUPPORTED_FEATURE);
CASE(SCARD_F_COMM_ERROR);
CASE(SCARD_F_INTERNAL_ERROR);
CASE(SCARD_W_REMOVED_CARD);
CASE(SCARD_W_RESET_CARD);
CASE(SCARD_W_UNPOWERED_CARD);
CASE(SCARD_W_UNRESPONSIVE_CARD);
CASE(SCARD_E_NO_READERS_AVAILABLE);
default:
(void)snprintf(strError, sizeof(strError)-1,
"Unknown error: 0x%08X", rv);
rv_text = strError;
}
}
return rv_text;
}
static void log_line(const int priority, const char *DebugBuffer,
unsigned int rv)
{ {
if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType) if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType)
syslog(LOG_INFO, "%s", DebugBuffer); syslog(LOG_INFO, "%s", DebugBuffer);
@ -139,6 +211,7 @@ static void log_line(const int priority, const char *DebugBuffer)
struct timeval tmp; struct timeval tmp;
int delta; int delta;
pthread_t thread_id; pthread_t thread_id;
const char *rv_text = NULL;
gettimeofday(&new_time, NULL); gettimeofday(&new_time, NULL);
if (0 == last_time.tv_sec) if (0 == last_time.tv_sec)
@ -160,6 +233,8 @@ static void log_line(const int priority, const char *DebugBuffer)
thread_id = pthread_self(); thread_id = pthread_self();
rv_text = rv2text(rv);
if (LogDoColor) if (LogDoColor)
{ {
const char *color_pfx = "", *color_sfx = "\33[0m"; const char *color_pfx = "", *color_sfx = "\33[0m";
@ -190,13 +265,31 @@ static void log_line(const int priority, const char *DebugBuffer)
#else #else
#define THREAD_FORMAT "%lu" #define THREAD_FORMAT "%lu"
#endif #endif
printf("%s%.8d%s [" THREAD_FORMAT "] %s%s%s\n", if (rv_text)
time_pfx, delta, time_sfx, thread_id, {
color_pfx, DebugBuffer, color_sfx); const char * rv_pfx = "", * rv_sfx = "";
if (rv != SCARD_S_SUCCESS)
{
rv_pfx = "\33[31m"; /* Red */
rv_sfx = "\33[0m";
}
printf("%s%.8d%s [" THREAD_FORMAT "] %s%s%s, %s%s%s\n",
time_pfx, delta, time_sfx, thread_id,
color_pfx, DebugBuffer, color_sfx,
rv_pfx, rv_text, rv_sfx);
}
else
printf("%s%.8d%s [" THREAD_FORMAT "] %s%s%s\n",
time_pfx, delta, time_sfx, thread_id,
color_pfx, DebugBuffer, color_sfx);
} }
else else
{ {
printf("%.8d %s\n", delta, DebugBuffer); if (rv_text)
printf("%.8d %s, %s\n", delta, DebugBuffer, rv_text);
else
printf("%.8d %s\n", delta, DebugBuffer);
} }
fflush(stdout); fflush(stdout);
} }
@ -220,7 +313,7 @@ static void log_xxd_always(const int priority, const char *msg,
c += 3; c += 3;
} }
log_line(priority, DebugBuffer); log_line(priority, DebugBuffer, -1);
} /* log_xxd_always */ } /* log_xxd_always */
void log_xxd(const int priority, const char *msg, const unsigned char *buffer, void log_xxd(const int priority, const char *msg, const unsigned char *buffer,

View File

@ -213,7 +213,9 @@ PCSC_API const char* pcsc_stringify_error(const LONG pcscError)
case SCARD_W_REMOVED_CARD: case SCARD_W_REMOVED_CARD:
msg = "Card was removed."; msg = "Card was removed.";
break; break;
/* case SCARD_W_SECURITY_VIOLATION: */ case SCARD_W_SECURITY_VIOLATION:
msg = "Access denied.";
break;
/* case SCARD_W_WRONG_CHV: */ /* case SCARD_W_WRONG_CHV: */
/* case SCARD_W_CHV_BLOCKED: */ /* case SCARD_W_CHV_BLOCKED: */
/* case SCARD_W_EOF: */ /* case SCARD_W_EOF: */

View File

@ -302,7 +302,7 @@ static void * EHStatusHandlerThread(READER_CONTEXT * rContext)
readerState = SCARD_PRESENT | SCARD_SWALLOWED; readerState = SCARD_PRESENT | SCARD_SWALLOWED;
RFSetPowerState(rContext, POWER_STATE_UNPOWERED); RFSetPowerState(rContext, POWER_STATE_UNPOWERED);
Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_UNPOWERED"); Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_UNPOWERED");
Log3(PCSC_LOG_ERROR, "Error powering up card: %ld 0x%04lX", rv, rv); Log2(PCSC_LOG_ERROR, "Error powering up card: %s", rv2text(rv));
} }
#endif #endif

View File

@ -57,8 +57,6 @@
#define PCSC_MAX_CONTEXT_CARD_HANDLES 200 #define PCSC_MAX_CONTEXT_CARD_HANDLES 200
#define PCSC_MAX_READER_HANDLES 200 #define PCSC_MAX_READER_HANDLES 200
#define PCSCLITE_STATUS_WAIT 200000 /**< Status Change Sleep */
/** Different values for struct ReaderContext powerState field */ /** Different values for struct ReaderContext powerState field */
enum enum
{ {

View File

@ -1395,7 +1395,7 @@ void RFCleanupReaders(void)
REMOVE_READER_NO_FLAG); REMOVE_READER_NO_FLAG);
if (rv != SCARD_S_SUCCESS) if (rv != SCARD_S_SUCCESS)
Log2(PCSC_LOG_ERROR, "RFRemoveReader error: 0x%08lX", rv); Log2(PCSC_LOG_ERROR, "RFRemoveReader error: %s", rv2text(rv));
} }
free(sReadersContexts[i]); free(sReadersContexts[i]);

View File

@ -590,9 +590,13 @@ PCSC_API p_SCardTransmit(SCardTransmit)
Enter(); Enter();
spy_long(hCard); spy_long(hCard);
spy_long(pioSendPci->dwProtocol);
spy_long(pioSendPci->cbPciLength);
spy_buffer(pbSendBuffer, cbSendLength); spy_buffer(pbSendBuffer, cbSendLength);
rv = spy.SCardTransmit(hCard, pioSendPci, pbSendBuffer, cbSendLength, rv = spy.SCardTransmit(hCard, pioSendPci, pbSendBuffer, cbSendLength,
pioRecvPci, pbRecvBuffer, pcbRecvLength); pioRecvPci, pbRecvBuffer, pcbRecvLength);
spy_long(pioRecvPci->dwProtocol);
spy_long(pioRecvPci->cbPciLength);
if (pcbRecvLength) if (pcbRecvLength)
spy_buffer(pbRecvBuffer, *pcbRecvLength); spy_buffer(pbRecvBuffer, *pcbRecvLength);
else else

View File

@ -219,6 +219,20 @@ class PCSCspy(object):
else: else:
self.log_in("hCard: %s" % hCard) self.log_in("hCard: %s" % hCard)
def log_in_scard_io_request(self):
""" log SCARD_IO_REQUEST IN parameter """
dwProtocol = self.get_line()
if self.diffable:
self.log_in("pioSendPci.dwProtocol: 0x????")
else:
self.log_in("pioSendPci.dwProtocol: %s" % dwProtocol)
cbPciLength = self.get_line()
if self.diffable:
self.log_in("pioSendPci.cbPciLength: 0x????")
else:
self.log_in("pioSendPci.cbPciLength: %s" % cbPciLength)
def log_in_hContext(self): def log_in_hContext(self):
""" log hContext IN parameter """ """ log hContext IN parameter """
hContext = self.get_line() hContext = self.get_line()
@ -289,6 +303,20 @@ class PCSCspy(object):
self.log_in("dwPreferredProtocols: %s (%s)" % (dwPreferredProtocols, self.log_in("dwPreferredProtocols: %s (%s)" % (dwPreferredProtocols,
", ".join(PreferredProtocols))) ", ".join(PreferredProtocols)))
def log_out_scard_io_request(self):
""" log SCARD_IO_REQUEST OUT parameter """
dwProtocol = self.get_line()
if self.diffable:
self.log_out("pioRecvPci.dwProtocol: 0x????")
else:
self.log_out("pioRecvPci.dwProtocol: %s" % dwProtocol)
cbPciLength = self.get_line()
if self.diffable:
self.log_out("pioRecvPci.cbPciLength: 0x????")
else:
self.log_out("pioRecvPci.cbPciLength: %s" % cbPciLength)
def log_out_dwActiveProtocol(self): def log_out_dwActiveProtocol(self):
""" log dwActiveProtocol OUT parameter """ """ log dwActiveProtocol OUT parameter """
dwActiveProtocol = self.get_line() dwActiveProtocol = self.get_line()
@ -510,8 +538,10 @@ class PCSCspy(object):
""" SCardTransmit """ """ SCardTransmit """
self.log_name("SCardTransmit") self.log_name("SCardTransmit")
self.log_in_hCard() self.log_in_hCard()
self.log_in_scard_io_request()
self.log_in2("bSendLength") self.log_in2("bSendLength")
self.log_buffer("bSendBuffer", "in") self.log_buffer("bSendBuffer", "in")
self.log_out_scard_io_request()
self.log_out2("bRecvLength") self.log_out2("bRecvLength")
self.log_buffer("bRecvBuffer", "out") self.log_buffer("bRecvBuffer", "out")
self._log_rv() self._log_rv()

View File

@ -335,8 +335,8 @@ LONG SCardConnect(/*@unused@*/ SCARDCONTEXT hContext, LPCSTR szReader,
rContext->readerState->cardAtrLength); rContext->readerState->cardAtrLength);
} }
else else
Log3(PCSC_LOG_ERROR, "Error powering up card: %ld 0x%04lX", Log2(PCSC_LOG_ERROR, "Error powering up card: %s",
rv, rv); rv2text(rv));
} }
if (! (rContext->readerState->readerState & SCARD_POWERED)) if (! (rContext->readerState->readerState & SCARD_POWERED))
@ -840,6 +840,9 @@ LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
/* get rContext corresponding to hCard */ /* get rContext corresponding to hCard */
rv = RFReaderInfoById(hCard, &rContext); rv = RFReaderInfoById(hCard, &rContext);
/* ignore reader removal */
if (SCARD_E_INVALID_VALUE == rv || SCARD_E_READER_UNAVAILABLE == rv)
return SCARD_S_SUCCESS;
if (rv != SCARD_S_SUCCESS) if (rv != SCARD_S_SUCCESS)
return rv; return rv;
@ -924,8 +927,8 @@ LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
else else
{ {
if (SCARD_UNPOWER_CARD == dwDisposition) if (SCARD_UNPOWER_CARD == dwDisposition)
Log3(PCSC_LOG_ERROR, "Error powering down card: %ld 0x%04lX", Log2(PCSC_LOG_ERROR, "Error powering down card: %s",
rv, rv); rv2text(rv));
else else
{ {
rContext->readerState->cardAtrLength = 0; rContext->readerState->cardAtrLength = 0;
@ -1077,7 +1080,7 @@ LONG SCardBeginTransaction(SCARDHANDLE hCard)
if (SCARD_E_SHARING_VIOLATION == rv) if (SCARD_E_SHARING_VIOLATION == rv)
(void)SYS_USleep(PCSCLITE_LOCK_POLL_RATE); (void)SYS_USleep(PCSCLITE_LOCK_POLL_RATE);
Log2(PCSC_LOG_DEBUG, "Status: 0x%08lX", rv); Log2(PCSC_LOG_DEBUG, "Status: %s", rv2text(rv));
exit: exit:
UNREF_READER(rContext) UNREF_READER(rContext)
@ -1229,7 +1232,7 @@ LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
if (rv == SCARD_S_SUCCESS) if (rv == SCARD_S_SUCCESS)
rv = rv2; rv = rv2;
Log2(PCSC_LOG_DEBUG, "Status: 0x%08lX", rv); Log2(PCSC_LOG_DEBUG, "Status: %s", rv2text(rv));
exit: exit:
UNREF_READER(rContext) UNREF_READER(rContext)
@ -1615,7 +1618,7 @@ LONG SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
if (rv != SCARD_S_SUCCESS) if (rv != SCARD_S_SUCCESS)
{ {
*pcbRecvLength = 0; *pcbRecvLength = 0;
Log2(PCSC_LOG_ERROR, "Card not transacted: 0x%08lX", rv); Log2(PCSC_LOG_ERROR, "Card not transacted: %s", rv2text(rv));
if (SCARD_E_NO_SMARTCARD == rv) if (SCARD_E_NO_SMARTCARD == rv)
{ {

View File

@ -134,9 +134,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//#define DO_PROFILE //#define DO_PROFILE
/** used for backward compatibility */
#define SCARD_PROTOCOL_ANY_OLD 0x1000
#ifndef TRUE #ifndef TRUE
#define TRUE 1 #define TRUE 1
#define FALSE 0 #define FALSE 0
@ -530,6 +527,7 @@ DESTRUCTOR static void destructor(void)
* @retval SCARD_E_NO_SERVICE The server is not running (\ref SCARD_E_NO_SERVICE) * @retval SCARD_E_NO_SERVICE The server is not running (\ref SCARD_E_NO_SERVICE)
* @retval SCARD_F_COMM_ERROR An internal communications error has been detected (\ref SCARD_F_COMM_ERROR) * @retval SCARD_F_COMM_ERROR An internal communications error has been detected (\ref SCARD_F_COMM_ERROR)
* @retval SCARD_F_INTERNAL_ERROR An internal consistency check failed (\ref SCARD_F_INTERNAL_ERROR) * @retval SCARD_F_INTERNAL_ERROR An internal consistency check failed (\ref SCARD_F_INTERNAL_ERROR)
* @retval SCARD_W_SECURITY_VIOLATION Access was denied by the daemon (Polkit issue?). (\ref SCARD_W_SECURITY_VIOLATION)
*/ */
static LONG SCardEstablishContextTH(DWORD dwScope, static LONG SCardEstablishContextTH(DWORD dwScope,
/*@unused@*/ LPCVOID pvReserved1, /*@unused@*/ LPCVOID pvReserved1,
@ -609,7 +607,6 @@ static LONG SCardEstablishContextTH(DWORD dwScope,
{ {
Log1(PCSC_LOG_CRITICAL, Log1(PCSC_LOG_CRITICAL,
"Your pcscd is too old and does not support CMD_VERSION"); "Your pcscd is too old and does not support CMD_VERSION");
rv = SCARD_F_COMM_ERROR;
goto cleanup; goto cleanup;
} }

View File

@ -506,7 +506,11 @@ INTERNAL LONG MessageReceive(void *buffer_void, uint64_t buffer_size,
* other errors are fatal */ * other errors are fatal */
if (errno != EINTR && errno != EAGAIN) if (errno != EINTR && errno != EAGAIN)
{ {
retval = SCARD_F_COMM_ERROR; /* connection reseted by pcscd? */
if (ECONNRESET == errno)
retval = SCARD_W_SECURITY_VIOLATION;
else
retval = SCARD_F_COMM_ERROR;
break; break;
} }
} }

View File

@ -321,7 +321,7 @@ static const char *CommandsText[] = {
WRITE_BODY_WITH_COMMAND(CommandsText[header.command], v) WRITE_BODY_WITH_COMMAND(CommandsText[header.command], v)
#define WRITE_BODY_WITH_COMMAND(command, v) \ #define WRITE_BODY_WITH_COMMAND(command, v) \
do { \ do { \
Log4(PCSC_LOG_DEBUG, "%s rv=0x%X for client %d", command, v.rv, filedes); \ LogRv4(PCSC_LOG_DEBUG, v.rv, "%s for client %d", command, filedes); \
ret = MessageSend(&v, sizeof(v), filedes); \ ret = MessageSend(&v, sizeof(v), filedes); \
} while (0) } while (0)
@ -886,47 +886,53 @@ static LONG MSGRemoveContext(SCARDCONTEXT hContext, SCONTEXT * threadContext)
hCard = *(int32_t *)ptr; hCard = *(int32_t *)ptr;
/* /*
* Unlock the sharing * Unlock the sharing. If the reader or handle already
* disappeared, skip the disconnection part and just delete the
* orphan handle.
*/ */
rv = RFReaderInfoById(hCard, &rContext); rv = RFReaderInfoById(hCard, &rContext);
if (rv != SCARD_S_SUCCESS) if (rv != SCARD_S_SUCCESS && rv != SCARD_E_INVALID_VALUE
&& rv != SCARD_E_READER_UNAVAILABLE)
{ {
(void)pthread_mutex_unlock(&threadContext->cardsList_lock); (void)pthread_mutex_unlock(&threadContext->cardsList_lock);
return rv; return rv;
} }
if (0 == rContext->hLockId) if (rContext)
{ {
/* no lock. Just leave the card */ if (0 == rContext->hLockId)
(void)SCardDisconnect(hCard, SCARD_LEAVE_CARD);
}
else
{
if (hCard != rContext->hLockId)
{ {
/* /* no lock. Just leave the card */
* if the card is locked by someone else we do not reset it
*/
/* decrement card use */
(void)SCardDisconnect(hCard, SCARD_LEAVE_CARD); (void)SCardDisconnect(hCard, SCARD_LEAVE_CARD);
} }
else else
{ {
/* release the lock */ if (hCard != rContext->hLockId)
rContext->hLockId = 0; {
/*
* if the card is locked by someone else we do not reset it
*/
/* /* decrement card use */
* We will use SCardStatus to see if the card has been
* reset there is no need to reset each time
* Disconnect is called
*/
rv = SCardStatus(hCard, NULL, NULL, NULL, NULL, NULL, NULL);
if (rv == SCARD_W_RESET_CARD || rv == SCARD_W_REMOVED_CARD)
(void)SCardDisconnect(hCard, SCARD_LEAVE_CARD); (void)SCardDisconnect(hCard, SCARD_LEAVE_CARD);
}
else else
(void)SCardDisconnect(hCard, SCARD_RESET_CARD); {
/* release the lock */
rContext->hLockId = 0;
/*
* We will use SCardStatus to see if the card has been
* reset there is no need to reset each time
* Disconnect is called
*/
rv = SCardStatus(hCard, NULL, NULL, NULL, NULL, NULL, NULL);
if (rv == SCARD_W_RESET_CARD || rv == SCARD_W_REMOVED_CARD)
(void)SCardDisconnect(hCard, SCARD_LEAVE_CARD);
else
(void)SCardDisconnect(hCard, SCARD_RESET_CARD);
}
} }
} }
@ -936,7 +942,9 @@ static LONG MSGRemoveContext(SCARDCONTEXT hContext, SCONTEXT * threadContext)
Log2(PCSC_LOG_CRITICAL, Log2(PCSC_LOG_CRITICAL,
"list_delete_at failed with return value: %d", lrv); "list_delete_at failed with return value: %d", lrv);
UNREF_READER(rContext) if (rContext) {
UNREF_READER(rContext)
}
} }
(void)pthread_mutex_unlock(&threadContext->cardsList_lock); (void)pthread_mutex_unlock(&threadContext->cardsList_lock);