Merge branch 'master' of https://github.com/OpenSC/OpenSC into ecc-fixes

This commit is contained in:
alex-nitrokey 2020-04-09 10:25:00 +02:00
commit 27ea7cc6ac
No known key found for this signature in database
GPG Key ID: A8853020E8EE6FBA
17 changed files with 334 additions and 255 deletions

2
.gitignore vendored
View File

@ -4,6 +4,7 @@ core
archive
acinclude.m4
aclocal.m4
aminclude_static.am
autom4te.cache
compile
confdefs.h
@ -22,6 +23,7 @@ mkinstalldirs
so_locations
stamp-h*
tags
test-driver
.deps
.libs
.#*#

View File

@ -1,13 +1,5 @@
version: 0.20.0.{build}
image:
# not compatible with OpenSSL 1.1.1:
# - Visual Studio 2013
# not compatible with WiX 3.11.2:
# - Visual Studio 2019
- Visual Studio 2015
- Visual Studio 2017
platform:
- x86
- x64
@ -19,6 +11,21 @@ configuration:
environment:
GH_TOKEN:
secure: aLu3tFc7lRJbotnmnHLx/QruIHc5rLaGm1RttoEdy4QILlPXzVkCZ6loYMz0sfrY
PATH: C:\cygwin\bin;%PATH%
OPENPACE_VER: 1.1.0
ZLIB_VER_DOT: 1.2.11
matrix:
# not compatible with OpenSSL 1.1.1:
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
# VCVARSALL: "%VS120COMNTOOLS%/../../VC/vcvarsall.bat"
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
VCVARSALL: "%VS140COMNTOOLS%/../../VC/vcvarsall.bat"
DO_PUSH_ARTIFACT: yes
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
VCVARSALL: "%ProgramFiles(x86)%/Microsoft Visual Studio/2017/Community/VC/Auxiliary/Build/vcvarsall.bat"
# not compatible with WiX 3.11.2:
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
# VCVARSALL: "%ProgramFiles(x86)%/Microsoft Visual Studio/2019/Community/VC/Auxiliary/Build/vcvarsall.bat"
install:
- ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod `
@ -26,26 +33,21 @@ install:
Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { `
throw "There are newer queued builds for this pull request, failing early." }
- date /T & time /T
- set PATH=C:\cygwin\bin;%PATH%
- set OPENPACE_VER=1.1.0
- set ZLIB_VER_DOT=1.2.11
- ps: $env:PACKAGE_NAME=(git describe --tags --abbrev=0)
- ps: >-
If ($env:Platform -Match "x86") {
$env:VCVARS_PLATFORM="x86"
$env:OPENSSL_PF="Win32"
$env:ARTIFACT="OpenSC-${env:PACKAGE_NAME}_win32"
} Else {
$env:VCVARS_PLATFORM="amd64"
$env:OPENSSL_PF="Win64"
$env:ARTIFACT="OpenSC-${env:PACKAGE_NAME}_win64"
}
- ps: >-
If ($env:Configuration -Like "*Light*") {
$env:ARTIFACT="${env:ARTIFACT}-Light"
$env:ARTIFACT+="-Light"
} Else {
$env:NMAKE_EXTRA="OPENSSL_DEF=/DENABLE_OPENSSL OPENSSL_DIR=C:\OpenSSL-v111-${env:OPENSSL_PF} ${env:NMAKE_EXTRA}"
$env:NMAKE_EXTRA="OPENSSL_EXTRA_CFLAGS=/DOPENSSL_SECURE_MALLOC_SIZE=65536 ${env:NMAKE_EXTRA}"
$env:NMAKE_EXTRA+=" OPENSSL_DEF=/DENABLE_OPENSSL OPENSSL_DIR=C:\OpenSSL-v111-${env:OPENSSL_PF}"
$env:NMAKE_EXTRA+=" OPENSSL_EXTRA_CFLAGS=/DOPENSSL_SECURE_MALLOC_SIZE=65536"
If (!(Test-Path C:\zlib )) {
appveyor DownloadFile "https://github.com/madler/zlib/archive/v${env:ZLIB_VER_DOT}.zip" -FileName zlib.zip
7z x zlib.zip -oC:\
@ -60,19 +62,8 @@ install:
If (!(Test-Path cngsdk.msi )) {
appveyor DownloadFile "http://download.microsoft.com/download/2/C/9/2C93059C-0532-42DF-8C24-9AEAFF00768E/cngsdk.msi"
}
- ps: >-
If ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2019") {
$env:VCVARSALL="${env:ProgramFiles(x86)}\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat"
} ElseIf ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2017") {
$env:VCVARSALL="${env:ProgramFiles(x86)}\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat"
} ElseIf ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2015") {
$env:VCVARSALL="${env:VS140COMNTOOLS}\..\..\VC\vcvarsall.bat"
$env:DO_PUSH_ARTIFACT="yes"
} ElseIf ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2013") {
$env:VCVARSALL="${env:VS120COMNTOOLS}\..\..\VC\vcvarsall.bat"
}
- echo "Using %APPVEYOR_BUILD_WORKER_IMAGE% with %VCVARSALL%"
- call "%VCVARSALL%" %VCVARS_PLATFORM%
- call "%VCVARSALL%" %Platform%
- cngsdk.msi /quiet
- uname -a
- set
@ -85,23 +76,23 @@ build_script:
xcopy C:\zlib C:\zlib-${env:OPENSSL_PF} /e /i /y /s
cd C:\zlib-${env:OPENSSL_PF}
(Get-Content win32/Makefile.msc).replace('-MD', '-MT') | Set-Content win32/Makefile.msc
nmake -f win32/Makefile.msc zlib.lib
nmake /nologo -f win32/Makefile.msc zlib.lib
}
$env:NMAKE_EXTRA="ZLIBSTATIC_DEF=/DENABLE_ZLIB_STATIC ZLIB_INCL_DIR=/IC:\zlib-${env:OPENSSL_PF} ZLIB_LIB=C:\zlib-${env:OPENSSL_PF}\zlib.lib ${env:NMAKE_EXTRA}"
$env:NMAKE_EXTRA+=" ZLIBSTATIC_DEF=/DENABLE_ZLIB_STATIC ZLIB_INCL_DIR=/IC:\zlib-${env:OPENSSL_PF} ZLIB_LIB=C:\zlib-${env:OPENSSL_PF}\zlib.lib"
If (!(Test-Path -Path "C:\openpace-${env:OPENSSL_PF}" )) {
# build libeac.lib as a static library
xcopy C:\openpace C:\openpace-${env:OPENSSL_PF} /e /i /y /s
cd C:\openpace-${env:OPENSSL_PF}\src
# OpenSSL 1.1.0
#cl /IC:\OpenSSL-v111-${env:OPENSSL_PF}\include /I. /DX509DIR=\`"/\`" /DCVCDIR=\`"/\`" /W3 /D_CRT_SECURE_NO_DEPRECATE /DWIN32_LEAN_AND_MEAN /GS /MT /DHAVE_ASN1_STRING_GET0_DATA=1 /DHAVE_DECL_OPENSSL_ZALLOC=1 /DHAVE_DH_GET0_KEY=1 /DHAVE_DH_GET0_PQG=1 /DHAVE_DH_SET0_KEY=1 /DHAVE_DH_SET0_PQG=1 /DHAVE_ECDSA_SIG_GET0=1 /DHAVE_ECDSA_SIG_SET0=1 /DHAVE_EC_KEY_METHOD=1 /DHAVE_RSA_GET0_KEY=1 /DHAVE_RSA_SET0_KEY=1 /c ca_lib.c cv_cert.c cvc_lookup.c x509_lookup.c eac_asn1.c eac.c eac_ca.c eac_dh.c eac_ecdh.c eac_kdf.c eac_lib.c eac_print.c eac_util.c misc.c pace.c pace_lib.c pace_mappings.c ri.c ri_lib.c ta.c ta_lib.c objects.c ssl_compat.c
#cl /nologo /IC:\OpenSSL-v110-${env:OPENSSL_PF}\include /I. /DX509DIR=\`"/\`" /DCVCDIR=\`"/\`" /W3 /D_CRT_SECURE_NO_DEPRECATE /DWIN32_LEAN_AND_MEAN /GS /MT /DHAVE_ASN1_STRING_GET0_DATA=1 /DHAVE_DECL_OPENSSL_ZALLOC=1 /DHAVE_DH_GET0_KEY=1 /DHAVE_DH_GET0_PQG=1 /DHAVE_DH_SET0_KEY=1 /DHAVE_DH_SET0_PQG=1 /DHAVE_ECDSA_SIG_GET0=1 /DHAVE_ECDSA_SIG_SET0=1 /DHAVE_EC_KEY_METHOD=1 /DHAVE_RSA_GET0_KEY=1 /DHAVE_RSA_SET0_KEY=1 /c ca_lib.c cv_cert.c cvc_lookup.c x509_lookup.c eac_asn1.c eac.c eac_ca.c eac_dh.c eac_ecdh.c eac_kdf.c eac_lib.c eac_print.c eac_util.c misc.c pace.c pace_lib.c pace_mappings.c ri.c ri_lib.c ta.c ta_lib.c objects.c ssl_compat.c
# OpenSSL 1.1.1
cl /IC:\OpenSSL-v111-${env:OPENSSL_PF}\include /I. /DX509DIR=\`"/\`" /DCVCDIR=\`"/\`" /W3 /D_CRT_SECURE_NO_DEPRECATE /DWIN32_LEAN_AND_MEAN /GS /MT /DHAVE_ASN1_STRING_GET0_DATA=1 /DHAVE_DECL_OPENSSL_ZALLOC=1 /DHAVE_DH_GET0_KEY=1 /DHAVE_DH_GET0_PQG=1 /DHAVE_DH_SET0_KEY=1 /DHAVE_DH_SET0_PQG=1 /DHAVE_ECDSA_SIG_GET0=1 /DHAVE_ECDSA_SIG_SET0=1 /DHAVE_EC_KEY_METHOD=1 /DHAVE_RSA_GET0_KEY=1 /DHAVE_RSA_SET0_KEY=1 /DHAVE_EC_POINT_GET_AFFINE_COORDINATES=1 /DHAVE_EC_POINT_SET_AFFINE_COORDINATES=1 /c ca_lib.c cv_cert.c cvc_lookup.c x509_lookup.c eac_asn1.c eac.c eac_ca.c eac_dh.c eac_ecdh.c eac_kdf.c eac_lib.c eac_print.c eac_util.c misc.c pace.c pace_lib.c pace_mappings.c ri.c ri_lib.c ta.c ta_lib.c objects.c ssl_compat.c
cl /nologo /IC:\OpenSSL-v111-${env:OPENSSL_PF}\include /I. /DX509DIR=\`"/\`" /DCVCDIR=\`"/\`" /W3 /D_CRT_SECURE_NO_DEPRECATE /DWIN32_LEAN_AND_MEAN /GS /MT /DHAVE_ASN1_STRING_GET0_DATA=1 /DHAVE_DECL_OPENSSL_ZALLOC=1 /DHAVE_DH_GET0_KEY=1 /DHAVE_DH_GET0_PQG=1 /DHAVE_DH_SET0_KEY=1 /DHAVE_DH_SET0_PQG=1 /DHAVE_ECDSA_SIG_GET0=1 /DHAVE_ECDSA_SIG_SET0=1 /DHAVE_EC_KEY_METHOD=1 /DHAVE_RSA_GET0_KEY=1 /DHAVE_RSA_SET0_KEY=1 /DHAVE_EC_POINT_GET_AFFINE_COORDINATES=1 /DHAVE_EC_POINT_SET_AFFINE_COORDINATES=1 /c ca_lib.c cv_cert.c cvc_lookup.c x509_lookup.c eac_asn1.c eac.c eac_ca.c eac_dh.c eac_ecdh.c eac_kdf.c eac_lib.c eac_print.c eac_util.c misc.c pace.c pace_lib.c pace_mappings.c ri.c ri_lib.c ta.c ta_lib.c objects.c ssl_compat.c
# OpenSSL 1.0.2
#cl /IC:\OpenSSL-v111-${env:OPENSSL_PF}\include /I. /DX509DIR=\`"/\`" /DCVCDIR=\`"/\`" /W3 /D_CRT_SECURE_NO_DEPRECATE /DWIN32_LEAN_AND_MEAN /GS /MT /c ca_lib.c cv_cert.c cvc_lookup.c x509_lookup.c eac_asn1.c eac.c eac_ca.c eac_dh.c eac_ecdh.c eac_kdf.c eac_lib.c eac_print.c eac_util.c misc.c pace.c pace_lib.c pace_mappings.c ri.c ri_lib.c ta.c ta_lib.c objects.c ssl_compat.c
lib /out:libeac.lib ca_lib.obj cv_cert.obj cvc_lookup.obj x509_lookup.obj eac_asn1.obj eac.obj eac_ca.obj eac_dh.obj eac_ecdh.obj eac_kdf.obj eac_lib.obj eac_print.obj eac_util.obj misc.obj pace.obj pace_lib.obj pace_mappings.obj ri.obj ri_lib.obj ta.obj ta_lib.obj objects.obj ssl_compat.obj
#cl /nologo /IC:\OpenSSL-${env:OPENSSL_PF}\include /I. /DX509DIR=\`"/\`" /DCVCDIR=\`"/\`" /W3 /D_CRT_SECURE_NO_DEPRECATE /DWIN32_LEAN_AND_MEAN /GS /MT /c ca_lib.c cv_cert.c cvc_lookup.c x509_lookup.c eac_asn1.c eac.c eac_ca.c eac_dh.c eac_ecdh.c eac_kdf.c eac_lib.c eac_print.c eac_util.c misc.c pace.c pace_lib.c pace_mappings.c ri.c ri_lib.c ta.c ta_lib.c objects.c ssl_compat.c
lib /nologo /out:libeac.lib ca_lib.obj cv_cert.obj cvc_lookup.obj x509_lookup.obj eac_asn1.obj eac.obj eac_ca.obj eac_dh.obj eac_ecdh.obj eac_kdf.obj eac_lib.obj eac_print.obj eac_util.obj misc.obj pace.obj pace_lib.obj pace_mappings.obj ri.obj ri_lib.obj ta.obj ta_lib.obj objects.obj ssl_compat.obj
cd C:\projects\OpenSC
}
$env:NMAKE_EXTRA="OPENPACE_DEF=/DENABLE_OPENPACE OPENPACE_DIR=C:\openpace-${env:OPENSSL_PF} ${env:NMAKE_EXTRA}"
$env:NMAKE_EXTRA+=" OPENPACE_DEF=/DENABLE_OPENPACE OPENPACE_DIR=C:\openpace-${env:OPENSSL_PF}"
}
- bash -c "exec 0</dev/null && if [ \"$APPVEYOR_REPO_BRANCH\" == \"master\" -a -z \"$APPVEYOR_PULL_REQUEST_NUMBER\" ]; then ./bootstrap; fi"
- bash -c "exec 0</dev/null && if [ \"$APPVEYOR_REPO_BRANCH\" == \"master\" -a -n \"$APPVEYOR_PULL_REQUEST_NUMBER\" ]; then ./bootstrap.ci -s \"-pr$APPVEYOR_PULL_REQUEST_NUMBER\"; fi"
@ -111,7 +102,7 @@ build_script:
- bash -c "exec 0</dev/null && ./configure --with-cygwin-native --disable-openssl --disable-readline --disable-zlib || cat config.log"
- bash -c "exec 0</dev/null && rm src/getopt.h"
- nmake /f Makefile.mak %NMAKE_EXTRA%
- cd win32 && nmake /f Makefile.mak %NMAKE_EXTRA% OpenSC.msi && cd ..
- cd win32 && nmake /nologo /f Makefile.mak %NMAKE_EXTRA% OpenSC.msi && cd ..
- move win32\OpenSC.msi %ARTIFACT%.msi
# put all pdb files for dump analysis, but this consumes approx 100 MB per build
- md %ARTIFACT%-Debug

View File

@ -400,7 +400,8 @@ AC_HEADER_ASSERT
AC_CHECK_HEADERS([ \
errno.h fcntl.h stdlib.h \
inttypes.h string.h strings.h \
sys/time.h unistd.h sys/mman.h
sys/time.h unistd.h sys/mman.h \
sys/endian.h endian.h
])
dnl Checks for typedefs, structures, and compiler characteristics.

View File

@ -1036,6 +1036,7 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path,
rv = iasecc_process_fci(card, file, apdu.resp, apdu.resplen);
if (rv) {
sc_file_free(file);
if (file_out) {
sc_file_free(*file_out);
*file_out = NULL;

View File

@ -150,7 +150,7 @@ static int idprime_select_index(sc_card_t *card)
}
sc_file_free(file);
/* Ignore too large files */
if (r > MAX_FILE_SIZE) {
if (r <= 0 || r > MAX_FILE_SIZE) {
r = SC_ERROR_INVALID_DATA;
}
return r;

View File

@ -148,7 +148,7 @@ int sc_parse_ef_atr(struct sc_card *card)
sc_format_path("3F002F01", &path);
rv = sc_select_file(card, &path, &file);
LOG_TEST_RET(ctx, rv, "Cannot select EF(ATR) file");
LOG_TEST_GOTO_ERR(ctx, rv, "Cannot select EF(ATR) file");
if (file->size) {
size = file->size;
@ -156,8 +156,10 @@ int sc_parse_ef_atr(struct sc_card *card)
size = 1024;
}
buf = malloc(size);
if (!buf)
LOG_TEST_GOTO_ERR(ctx, SC_ERROR_OUT_OF_MEMORY, "Memory allocation error");
if (!buf) {
rv = SC_ERROR_OUT_OF_MEMORY;
LOG_TEST_GOTO_ERR(ctx, rv, "Memory allocation error");
}
rv = sc_read_binary(card, 0, buf, size, 0);
LOG_TEST_GOTO_ERR(ctx, rv, "Cannot read EF(ATR) file");

View File

@ -45,8 +45,8 @@ const char *sc_strerror(int error)
"Message too long (keypad)",
"Timeout while waiting for event from card reader",
"Unresponsive card (correctly inserted?)",
"Reader detached (hotplug device?)",
"Reader reattached (hotplug device?)",
"Reader detached",
"Reader reattached",
"Reader in use by another application"
};
const int rdr_base = -SC_ERROR_READER;

View File

@ -100,6 +100,7 @@ typedef unsigned __int8 uint8_t;
#define SCARD_E_NOT_TRANSACTED 0x80100016 /**< An attempt was made to end a non-existent transaction. */
#define SCARD_E_READER_UNAVAILABLE 0x80100017 /**< The specified reader is not currently available for use. */
#define SCARD_E_NO_SERVICE 0x8010001D /**< The Smart card resource manager is not running. */
#define SCARD_E_SERVICE_STOPPED 0x8010001E /**< The smart card resource manager has shut down. */
#define SCARD_E_NO_READERS_AVAILABLE 0x8010002E /**< Cannot find a smart card reader. */
#define SCARD_W_UNRESPONSIVE_CARD 0x80100066 /**< The smart card is not responding to a reset. */
#define SCARD_W_UNPOWERED_CARD 0x80100067 /**< Power has been removed from the smart card, so that further communication is not possible. */

View File

@ -213,10 +213,10 @@ extern "C" {
/* Event masks for sc_wait_for_event() */
#define SC_EVENT_CARD_INSERTED 0x0001
#define SC_EVENT_CARD_REMOVED 0x0002
#define SC_EVENT_CARD_EVENTS SC_EVENT_CARD_INSERTED|SC_EVENT_CARD_REMOVED
#define SC_EVENT_CARD_EVENTS (SC_EVENT_CARD_INSERTED|SC_EVENT_CARD_REMOVED)
#define SC_EVENT_READER_ATTACHED 0x0004
#define SC_EVENT_READER_DETACHED 0x0008
#define SC_EVENT_READER_EVENTS SC_EVENT_READER_ATTACHED|SC_EVENT_READER_DETACHED
#define SC_EVENT_READER_EVENTS (SC_EVENT_READER_ATTACHED|SC_EVENT_READER_DETACHED)
#define MAX_FILE_SIZE 65535
@ -1024,18 +1024,25 @@ int sc_disconnect_card(struct sc_card *card);
int sc_detect_card_presence(sc_reader_t *reader);
/**
* Waits for an event on readers. Note: only the event is detected,
* there is no update of any card or other info.
* NOTE: Only PC/SC backend implements this.
* @param ctx pointer to a Context structure
* @param event_mask The types of events to wait for; this should
* be ORed from one of the following
* SC_EVENT_CARD_REMOVED
* SC_EVENT_CARD_INSERTED
* SC_EVENT_READER_ATTACHED
* @param event_reader (OUT) the reader on which the event was detected, or NULL if new reader
* Waits for an event on readers.
*
* In case of a reader event (attached/detached), the list of reader is
* adjusted accordingly. This means that a subsequent call to
* `sc_ctx_detect_readers()` is not needed.
*
* @note Only PC/SC backend implements this. An infinite timeout on macOS does
* not detect reader events (use a limited timeout instead if needed).
*
* @param ctx (IN) pointer to a Context structure
* @param event_mask (IN) The types of events to wait for; this should
* be ORed from one of the following:
* - SC_EVENT_CARD_REMOVED
* - SC_EVENT_CARD_INSERTED
* - SC_EVENT_READER_ATTACHED
* - SC_EVENT_READER_DETACHED
* @param event_reader (OUT) the reader on which the event was detected
* @param event (OUT) the events that occurred. This is also ORed
* from the SC_EVENT_CARD_* constants listed above.
* from the constants listed above.
* @param timeout Amount of millisecs to wait; -1 means forever
* @retval < 0 if an error occurred
* @retval = 0 if a an event happened

View File

@ -127,6 +127,9 @@ struct pcsc_global_private_data {
SCardTransmit_t SCardTransmit;
SCardListReaders_t SCardListReaders;
SCardGetAttrib_t SCardGetAttrib;
sc_reader_t *attached_reader;
sc_reader_t *removed_reader;
};
struct pcsc_private_data {
@ -185,6 +188,7 @@ static int pcsc_to_opensc_error(LONG rv)
return SC_ERROR_READER_DETACHED;
case SCARD_E_NO_SERVICE:
case SCARD_E_SERVICE_STOPPED:
/* If the service is (auto)started, there could be readers later */
return SC_ERROR_NO_READERS_FOUND;
case SCARD_E_NO_SMARTCARD:
@ -358,7 +362,7 @@ static int refresh_attributes(sc_reader_t *reader)
if (reader->ctx->flags & SC_CTX_FLAG_TERMINATE)
return SC_ERROR_NOT_ALLOWED;
if (priv->reader_state.szReader == NULL) {
if (priv->reader_state.szReader == NULL || reader->ctx->flags & SC_READER_REMOVED) {
priv->reader_state.szReader = reader->name;
priv->reader_state.dwCurrentState = SCARD_STATE_UNAWARE;
priv->reader_state.dwEventState = SCARD_STATE_UNAWARE;
@ -382,12 +386,11 @@ static int refresh_attributes(sc_reader_t *reader)
}
/* the system could not detect the reader. It means, the prevoiusly attached reader is disconnected. */
if (
if (rv == (LONG)SCARD_E_UNKNOWN_READER
#ifdef SCARD_E_NO_READERS_AVAILABLE
(rv == (LONG)SCARD_E_NO_READERS_AVAILABLE) ||
|| rv == (LONG)SCARD_E_NO_READERS_AVAILABLE
#endif
(rv == (LONG)SCARD_E_UNKNOWN_READER) || (rv == (LONG)SCARD_E_SERVICE_STOPPED)) {
|| rv == (LONG)SCARD_E_SERVICE_STOPPED) {
if (old_flags & SC_READER_CARD_PRESENT) {
reader->flags |= SC_READER_CARD_CHANGED;
}
@ -1143,7 +1146,7 @@ static void detect_reader_features(sc_reader_t *reader, SCARDHANDLE card_handle)
return;
rv = gpriv->SCardControl(card_handle, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0, feature_buf, sizeof(feature_buf), &feature_len);
if (rv != (LONG)SCARD_S_SUCCESS) {
if (rv != SCARD_S_SUCCESS) {
PCSC_TRACE(reader, "SCardControl failed", rv);
return;
}
@ -1382,6 +1385,8 @@ static int pcsc_detect_readers(sc_context_t *ctx)
}
sc_log(ctx, "Probing PC/SC readers");
gpriv->attached_reader = NULL;
gpriv->removed_reader = NULL;
do {
if (gpriv->pcsc_ctx == (SCARDCONTEXT)-1) {
@ -1399,12 +1404,11 @@ static int pcsc_detect_readers(sc_context_t *ctx)
* All readers have disappeared, so mark them as
* such so we don't keep polling them over and over.
*/
if (
if (rv == (LONG)SCARD_E_NO_SERVICE
#ifdef SCARD_E_NO_READERS_AVAILABLE
(rv == (LONG)SCARD_E_NO_READERS_AVAILABLE) ||
|| rv == (LONG)SCARD_E_NO_READERS_AVAILABLE
#endif
(rv == (LONG)SCARD_E_NO_SERVICE) || (rv == (LONG)SCARD_E_SERVICE_STOPPED)) {
|| rv == (LONG)SCARD_E_SERVICE_STOPPED) {
for (i = 0; i < sc_ctx_get_reader_count(ctx); i++) {
sc_reader_t *reader = sc_ctx_get_reader(ctx, i);
@ -1414,6 +1418,7 @@ static int pcsc_detect_readers(sc_context_t *ctx)
}
reader->flags |= SC_READER_REMOVED;
gpriv->removed_reader = reader;
}
}
@ -1473,6 +1478,7 @@ static int pcsc_detect_readers(sc_context_t *ctx)
if (!strcmp(reader->name, reader_name)) {
if (reader->flags & SC_READER_REMOVED) {
reader->flags &= ~SC_READER_REMOVED;
gpriv->attached_reader = reader;
refresh_attributes(reader);
}
break;
@ -1487,8 +1493,11 @@ static int pcsc_detect_readers(sc_context_t *ctx)
(reader_buf + reader_buf_size) - next_reader_name);
reader_buf_size -= (next_reader_name - reader_name);
} else {
/* existing reader not found */
reader->flags |= SC_READER_REMOVED;
if (!(reader->flags & SC_READER_REMOVED)) {
/* existing reader not found */
reader->flags |= SC_READER_REMOVED;
gpriv->removed_reader = reader;
}
}
}
@ -1503,6 +1512,7 @@ static int pcsc_detect_readers(sc_context_t *ctx)
_sc_delete_reader(ctx, reader);
continue;
}
gpriv->attached_reader = reader;
/* check for pinpad support early, to allow opensc-tool -l display accurate information */
priv = reader->drv_data;
@ -1555,7 +1565,7 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re
SCARD_READERSTATE *rgReaderStates;
size_t i;
unsigned int num_watch, count;
int r = SC_ERROR_INTERNAL;
int r = SC_ERROR_INTERNAL, detect_readers = 0, detected_hotplug = 0;
DWORD dwtimeout;
LOG_FUNC_CALLED(ctx);
@ -1579,8 +1589,13 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re
sc_reader_t *reader = sc_ctx_get_reader(ctx, i);
if (reader->flags & SC_READER_REMOVED)
continue;
struct pcsc_private_data *priv = reader->drv_data;
rgReaderStates[num_watch].szReader = reader->name;
rgReaderStates[num_watch].dwCurrentState = SCARD_STATE_UNAWARE;
if (priv->reader_state.szReader == NULL) {
rgReaderStates[num_watch].dwCurrentState = SCARD_STATE_UNAWARE;
} else {
rgReaderStates[num_watch].dwCurrentState = priv->reader_state.dwEventState;
}
rgReaderStates[num_watch].dwEventState = SCARD_STATE_UNAWARE;
num_watch++;
}
@ -1589,6 +1604,12 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re
#ifdef __APPLE__
/* OS X 10.6.2 - 10.12.6 do not support PnP notification */
sc_log(ctx, "PnP notification not supported");
/* Always check on new readers as if a hotplug
* event was detected. This overwrites a
* SC_ERROR_EVENT_TIMEOUT if a new reader is
* detected with SC_SUCCESS. */
detect_readers = 1;
detected_hotplug = 1;
#else
rgReaderStates[num_watch].szReader = "\\\\?PnP?\\Notification";
rgReaderStates[num_watch].dwCurrentState = SCARD_STATE_UNAWARE;
@ -1622,9 +1643,11 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re
goto out;
}
*event_reader = NULL;
*event = 0;
if (num_watch == 0) {
sc_log(ctx, "No readers available to be watched");
*event_reader = NULL;
r = SC_ERROR_NO_READERS_FOUND;
goto out;
}
@ -1646,7 +1669,6 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re
/* Scan the current state of all readers to see if they
* match any of the events we're polling for */
*event = 0;
for (i = 0, rsp = rgReaderStates; i < num_watch; i++, rsp++) {
DWORD state, prev_state;
sc_log(ctx, "'%s' before=0x%08X now=0x%08X",
@ -1657,51 +1679,72 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re
state = rsp->dwEventState;
rsp->dwCurrentState = rsp->dwEventState;
if (state & SCARD_STATE_CHANGED) {
/* check for hotplug events */
if (!strcmp(rgReaderStates[i].szReader, "\\\\?PnP?\\Notification")) {
if (!strcmp(rsp->szReader, "\\\\?PnP?\\Notification")) {
sc_log(ctx, "detected hotplug event");
*event |= SC_EVENT_READER_ATTACHED;
*event_reader = NULL;
}
/* Windows sends hotplug event on both, attaching and
* detaching a reader. pcscd only sends it in case of
* attaching a reader. We'll detect later in which case we
* are. */
detect_readers = 1;
detected_hotplug = 1;
if ((state & SCARD_STATE_PRESENT) && !(prev_state & SCARD_STATE_PRESENT)) {
sc_log(ctx, "card inserted event");
*event |= SC_EVENT_CARD_INSERTED;
}
/* Windows wants us to manually reset the changed state */
rsp->dwEventState &= ~SCARD_STATE_CHANGED;
if ((prev_state & SCARD_STATE_PRESENT) && !(state & SCARD_STATE_PRESENT)) {
sc_log(ctx, "card removed event");
*event |= SC_EVENT_CARD_REMOVED;
}
/* By default, ignore a hotplug event as if a timout
* occurred, since it may be an unrequested removal or
* false alarm. Just continue to loop and check at the end
* of this function whether we need to return the attached
* reader or not. */
r = SC_ERROR_EVENT_TIMEOUT;
} else {
sc_reader_t *reader = sc_ctx_get_reader_by_name(ctx, rsp->szReader);
if (reader) {
/* copy the state so we know what to watch out for */
struct pcsc_private_data *priv = reader->drv_data;
priv->reader_state.dwEventState = state;
priv->reader_state.dwCurrentState = prev_state;
}
if ((state & SCARD_STATE_UNKNOWN) && !(prev_state & SCARD_STATE_UNKNOWN)) {
sc_log(ctx, "reader detached event");
*event |= SC_EVENT_READER_DETACHED;
}
if ((state & SCARD_STATE_PRESENT) && !(prev_state & SCARD_STATE_PRESENT)) {
sc_log(ctx, "card inserted event");
*event |= SC_EVENT_CARD_INSERTED;
}
if ((prev_state & SCARD_STATE_UNKNOWN) && !(state & SCARD_STATE_UNKNOWN)) {
sc_log(ctx, "reader re-attached event");
*event |= SC_EVENT_READER_ATTACHED;
}
if ((prev_state & SCARD_STATE_PRESENT) && !(state & SCARD_STATE_PRESENT)) {
sc_log(ctx, "card removed event");
*event |= SC_EVENT_CARD_REMOVED;
}
if (*event & event_mask) {
sc_log(ctx, "Matching event 0x%02X in reader %s", *event, rsp->szReader);
*event_reader = sc_ctx_get_reader_by_name(ctx, rsp->szReader);
r = SC_SUCCESS;
goto out;
}
if ((state & SCARD_STATE_UNKNOWN) && !(prev_state & SCARD_STATE_UNKNOWN)) {
sc_log(ctx, "reader detached event");
*event |= SC_EVENT_READER_DETACHED;
detect_readers = 1;
}
if ((state & SCARD_STATE_IGNORE) && !(prev_state & SCARD_STATE_IGNORE)) {
sc_log(ctx, "reader detached event");
*event |= SC_EVENT_READER_DETACHED;
detect_readers = 1;
}
if ((prev_state & SCARD_STATE_UNKNOWN) && !(state & SCARD_STATE_UNKNOWN)) {
sc_log(ctx, "reader re-attached event");
*event |= SC_EVENT_READER_ATTACHED;
detect_readers = 1;
}
if (*event & event_mask) {
sc_log(ctx, "Matching event 0x%02X in reader %s", *event, rsp->szReader);
*event_reader = reader;
r = SC_SUCCESS;
goto out;
} else {
*event = 0;
}
}
}
/* No match - copy the state so pcscd knows
* what to watch out for */
/* rsp->dwCurrentState = rsp->dwEventState; */
}
if (timeout == 0) {
r = SC_ERROR_EVENT_TIMEOUT;
goto out;
}
/* Set the timeout if caller wants to time out */
@ -1713,13 +1756,13 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re
rv = gpriv->SCardGetStatusChange(gpriv->pcsc_wait_ctx, dwtimeout, rgReaderStates, num_watch);
if (rv == (LONG) SCARD_E_CANCELLED) {
if (rv == (LONG)SCARD_E_CANCELLED) {
/* C_Finalize was called, events don't matter */
r = SC_ERROR_EVENT_TIMEOUT;
goto out;
}
if (rv == (LONG) SCARD_E_TIMEOUT) {
if (rv == (LONG)SCARD_E_TIMEOUT) {
r = SC_ERROR_EVENT_TIMEOUT;
goto out;
}
@ -1731,12 +1774,54 @@ static int pcsc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_re
}
}
out:
if (!reader_states) {
free(rgReaderStates);
/* in case of an error re-detect all readers */
if (r < 0 && r != SC_ERROR_EVENT_TIMEOUT)
detect_readers = 1;
if (detect_readers) {
pcsc_detect_readers(ctx);
}
else if (*reader_states == NULL) {
sc_log(ctx, "return allocated 'reader states'");
*reader_states = rgReaderStates;
if (detected_hotplug) {
if (gpriv->attached_reader) {
if (event_reader && event && !*event) {
/* no other event has been detected, yet */
*event_reader = gpriv->attached_reader;
*event = SC_EVENT_READER_ATTACHED;
r = SC_SUCCESS;
}
gpriv->attached_reader = NULL;
} else if (gpriv->removed_reader) {
/* Normally, we only check the hotplug event for attached readers.
* However, Windows also notifies on removal. Check, if the latter
* was requested by the caller. */
if (event_mask & SC_EVENT_READER_DETACHED
&& event_reader && event && !*event) {
/* no other event has been detected, yet */
*event_reader = gpriv->removed_reader;
*event = SC_EVENT_READER_DETACHED;
r = SC_SUCCESS;
}
gpriv->removed_reader = NULL;
} else {
/* false alarm, there was no reader attached or removed,
* avoid re-initialize the reader states by resetting detect_readers */
detect_readers = 0;
}
}
if (detect_readers) {
free(rgReaderStates);
if (reader_states && *reader_states)
*reader_states = NULL;
} else {
if (!reader_states) {
free(rgReaderStates);
}
else if (*reader_states == NULL) {
sc_log(ctx, "return allocated reader states");
*reader_states = rgReaderStates;
}
}
LOG_FUNC_RETURN(ctx, r);
@ -2449,6 +2534,7 @@ int pcsc_use_reader(sc_context_t *ctx, void * pcsc_context_handle, void * pcsc_c
}
sc_log(ctx, "Probing PC/SC reader");
gpriv->attached_reader = NULL;
gpriv->pcsc_ctx = *(SCARDCONTEXT *)pcsc_context_handle;
card_handle = *(SCARDHANDLE *)pcsc_card_handle;
@ -2467,6 +2553,7 @@ int pcsc_use_reader(sc_context_t *ctx, void * pcsc_context_handle, void * pcsc_c
} else {
_sc_delete_reader(ctx, reader);
}
gpriv->attached_reader = reader;
}
out:

View File

@ -40,8 +40,13 @@
#ifndef _BSD_SOURCE
#define _BSD_SOURCE /* See feature_test_macros(7) */
#endif
#ifdef HAVE_SYS_ENDIAN_H
#include <sys/endian.h>
#endif
#ifdef HAVE_ENDIAN_H
#include <endian.h>
#endif
#endif
int get_pace_capabilities(u8 *bitmap)
{

View File

@ -1668,22 +1668,6 @@ pkcs15_login(struct sc_pkcs11_slot *slot, CK_USER_TYPE userType,
if (!p11card)
return CKR_TOKEN_NOT_RECOGNIZED;
if (p11card->card->reader->capabilities & SC_READER_CAP_PIN_PAD
|| (p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)) {
/* pPin should be NULL in case of a pin pad reader, but
* some apps (e.g. older Netscapes) don't know about it.
* So we don't require that pPin == NULL, but set it to
* NULL ourselves. This way, you can supply an empty (if
* possible) or fake PIN if an application asks a PIN).
*/
/* But we want to be able to specify a PIN on the command
* line (e.g. for the test scripts). So we don't do anything
* here - this gives the user the choice of entering
* an empty pin (which makes us use the pin pad) or
* a valid pin (which is processed normally). --okir */
if (ulPinLen == 0)
pPin = NULL;
}
/* By default, we make the reader resource manager keep other
* processes from accessing the card while we're logged in.
@ -1843,26 +1827,11 @@ pkcs15_change_pin(struct sc_pkcs11_slot *slot,
return CKR_USER_PIN_NOT_INITIALIZED;
sc_log(context, "Change '%.*s' (ref:%i,type:%i)", (int) sizeof pin_obj->label, pin_obj->label, auth_info->attrs.pin.reference, login_user);
if ((p11card->card->reader->capabilities & SC_READER_CAP_PIN_PAD)
|| (p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)) {
/* pPin should be NULL in case of a pin pad reader, but
* some apps (e.g. older Netscapes) don't know about it.
* So we don't require that pPin == NULL, but set it to
* NULL ourselves. This way, you can supply an empty (if
* possible) or fake PIN if an application asks a PIN).
*/
pOldPin = pNewPin = NULL;
ulOldLen = ulNewLen = 0;
}
else if (ulNewLen < auth_info->attrs.pin.min_length || ulNewLen > auth_info->attrs.pin.max_length) {
if (pNewPin && (ulNewLen < auth_info->attrs.pin.min_length || ulNewLen > auth_info->attrs.pin.max_length)) {
return CKR_PIN_LEN_RANGE;
}
if (login_user < 0) {
if (sc_pkcs11_conf.pin_unblock_style != SC_PKCS11_PIN_UNBLOCK_UNLOGGED_SETPIN) {
sc_log(context, "PIN unlock is not allowed in unlogged session");
return CKR_FUNCTION_NOT_SUPPORTED;
}
if (login_user < 0 && sc_pkcs11_conf.pin_unblock_style == SC_PKCS11_PIN_UNBLOCK_UNLOGGED_SETPIN) {
rc = sc_pkcs15_unblock_pin(fw_data->p15_card, pin_obj, pOldPin, ulOldLen, pNewPin, ulNewLen);
}
else if (login_user == CKU_CONTEXT_SPECIFIC) {
@ -1872,7 +1841,7 @@ pkcs15_change_pin(struct sc_pkcs11_slot *slot,
}
rc = sc_pkcs15_unblock_pin(fw_data->p15_card, pin_obj, pOldPin, ulOldLen, pNewPin, ulNewLen);
}
else if ((login_user == CKU_USER) || (login_user == CKU_SO)) {
else if (login_user < 0 || login_user == CKU_USER || login_user == CKU_SO) {
rc = sc_pkcs15_change_pin(fw_data->p15_card, pin_obj, pOldPin, ulOldLen, pNewPin, ulNewLen);
}
else {

View File

@ -469,16 +469,17 @@ static int sm_encrypt(const struct iso_sm_ctx *ctx, sc_card_t *card,
sm_apdu->datalen = sm_data_len;
sm_apdu->lc = sm_data_len;
sm_apdu->le = 0;
/* for encrypted APDUs we usually get authenticated status bytes (4B), a
* MAC (2B without data) and a cryptogram with padding indicator (2B tag
* and indicator, max. 2B/3B ASN.1 length, without data). The cryptogram is
* always padded to the block size. */
if (apdu->cse & SC_APDU_EXT) {
sm_apdu->cse = SC_APDU_CASE_4_EXT;
sm_apdu->resplen = 4 + 2 + mac_len + 2 + 3 + ((apdu->resplen+1)/ctx->block_length+1)*ctx->block_length;
} else {
sm_apdu->cse = SC_APDU_CASE_4_SHORT;
sm_apdu->resplen = 4 + 2 + mac_len + 2 + 2 + ((apdu->resplen+1)/ctx->block_length+1)*ctx->block_length;
}
/* for encrypted APDUs we usually get authenticated status bytes
* (4B), a MAC (2B without data) and a cryptogram with padding
* indicator (3B without data). The cryptogram is always padded to
* the block size. */
sm_apdu->resplen = 4 + 2 + mac_len + 3 + ((apdu->resplen+1)/ctx->block_length+1)*ctx->block_length;
resp_data = calloc(sm_apdu->resplen, 1);
if (!resp_data) {
r = SC_ERROR_OUT_OF_MEMORY;

View File

@ -1486,7 +1486,7 @@ static int do_update_binary(int argc, char **argv)
r = parse_string_or_hexdata(argv[2], buf, &buflen);
if (r < 0) {
fprintf(stderr, "Unable to parse input data: %s\n", strerror(r));
fprintf(stderr, "Unable to parse input data: %s\n", sc_strerror(r));
return -1;
}
@ -1509,7 +1509,7 @@ static int do_update_binary(int argc, char **argv)
r = sc_update_binary(card, offs, buf, buflen, 0);
sc_unlock(card);
if (r < 0) {
fprintf(stderr, "Cannot update %04X: %s\n", file->id, strerror(r));
fprintf(stderr, "Cannot update %04X: %s\n", file->id, sc_strerror(r));
goto err;
}
@ -1561,7 +1561,7 @@ static int do_update_record(int argc, char **argv)
r = sc_read_record(card, rec, buf, sizeof(buf), SC_RECORD_BY_REC_NR);
if (r < 0) {
fprintf(stderr, "Cannot read record %"SC_FORMAT_LEN_SIZE_T"u of %04X: %s\n",
rec, file->id, strerror(r));
rec, file->id, sc_strerror(r));
goto err;
}
@ -1574,7 +1574,7 @@ static int do_update_record(int argc, char **argv)
buflen = sizeof(buf) - offs;
r = parse_string_or_hexdata(argv[3], buf + offs, &buflen);
if (r < 0) {
fprintf(stderr, "Unable to parse input data: %s.\n", strerror(r));
fprintf(stderr, "Unable to parse input data: %s.\n", sc_strerror(r));
goto err;
}
@ -1584,7 +1584,7 @@ static int do_update_record(int argc, char **argv)
sc_unlock(card);
if (r < 0) {
fprintf(stderr, "Cannot update record %"SC_FORMAT_LEN_SIZE_T"u of %04X: %s\n.",
rec, file->id, strerror(r));
rec, file->id, sc_strerror(r));
goto err;
}
@ -1698,7 +1698,7 @@ static int do_erase(int argc, char **argv)
r = sc_card_ctl(card, SC_CARDCTL_ERASE_CARD, NULL);
sc_unlock(card);
if (r) {
fprintf(stderr, "Failed to erase card: %s\n", sc_strerror (r));
fprintf(stderr, "Failed to erase card: %s\n", sc_strerror(r));
return -1;
}
return 0;

View File

@ -49,26 +49,21 @@ void Sleep(unsigned int Milliseconds)
}
#endif
void stop_daemon()
{
#ifdef PCSCLITE_GOOD
sc_cancel(ctx);
#endif
run_daemon = 0;
}
void notify_daemon()
{
int r;
const unsigned int event_mask = SC_EVENT_CARD_EVENTS;
const unsigned int event_mask = SC_EVENT_CARD_EVENTS|SC_EVENT_READER_EVENTS;
unsigned int event;
struct sc_reader *event_reader = NULL;
size_t error_count = 0;
void *reader_states = NULL;
#ifndef __APPLE__
/* timeout adjusted to the maximum response time for WM_CLOSE in case
* canceling doesn't work */
const int timeout = 20000;
struct sc_atr old_atr;
void *reader_states = NULL;
#else
/* lower timeout, because Apple doesn't support hotplug events */
const int timeout = 2000;
#endif
r = sc_establish_context(&ctx, "opensc-notify");
if (r < 0 || !ctx) {
@ -76,50 +71,51 @@ void notify_daemon()
return;
}
while (run_daemon && error_count < 1000) {
while (run_daemon) {
r = sc_wait_for_event(ctx, event_mask,
&event_reader, &event, timeout, &reader_states);
if (r < 0) {
if (r == SC_ERROR_NO_READERS_FOUND) {
/* No readers available, PnP notification not supported */
Sleep(200);
} else {
error_count++;
Sleep(timeout);
continue;
}
continue;
}
error_count = 0;
if (event & SC_EVENT_CARD_REMOVED) {
sc_notify_id(ctx, &old_atr, NULL, NOTIFY_CARD_REMOVED);
}
if (event & SC_EVENT_CARD_INSERTED) {
if (event_reader) {
/* FIXME `pcsc_wait_for_event` has all the information that's
* requested again with `pcsc_detect_card_presence`, but it
* doesn't use the ATR, for example, to refresh the reader's
* attributes. To get the ATR we need to call
* sc_detect_card_presence. Eventually this should be fixed. */
sc_detect_card_presence(event_reader);
memcpy(old_atr.value, event_reader->atr.value,
event_reader->atr.len);
old_atr.len = event_reader->atr.len;
} else {
old_atr.len = 0;
if (event_reader) {
if (event & SC_EVENT_CARD_REMOVED
|| (event & SC_EVENT_READER_DETACHED
&& event_reader->flags & SC_READER_CARD_PRESENT)) {
/* sc_notify_id uses only the reader's name for displaying on
* removal, so use a dummy card here to get that information
* into the notification */
struct sc_pkcs15_card p15card;
sc_card_t card;
memset(&card, 0, sizeof card);
card.reader = event_reader;
memset(&p15card, 0, sizeof p15card);
p15card.card = &card;
sc_notify_id(ctx, &event_reader->atr, &p15card, NOTIFY_CARD_REMOVED);
} else if (event & SC_EVENT_CARD_INSERTED
|| (event & SC_EVENT_READER_ATTACHED
&& event_reader->flags & SC_READER_CARD_PRESENT)) {
/* sc_notify_id prevers the reader's name for displaying on
* insertion, so use a dummy card here to get that information
* into the notification */
struct sc_pkcs15_card p15card;
sc_card_t card;
memset(&card, 0, sizeof card);
card.reader = event_reader;
memset(&p15card, 0, sizeof p15card);
p15card.card = &card;
sc_notify_id(ctx, &event_reader->atr, &p15card, NOTIFY_CARD_INSERTED);
}
sc_notify_id(ctx, old_atr.len ? &old_atr : NULL, NULL,
NOTIFY_CARD_INSERTED);
}
}
if (ctx) {
if (error_count >= 1000) {
sc_log(ctx, "Too many errors; aborting.");
}
/* free `reader_states` */
sc_wait_for_event(ctx, 0, NULL, NULL, 0, &reader_states);
reader_states = NULL;
sc_release_context(ctx);
ctx = NULL;
}
@ -132,7 +128,8 @@ void notify_daemon()
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_CLOSE || message == WM_QUIT) {
stop_daemon();
run_daemon = 0;
sc_cancel(ctx);
return TRUE;
}
@ -182,32 +179,54 @@ WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR lpCmdLine, int nShowC
#else
#ifdef HAVE_SIGACTION
#if defined(HAVE_SIGACTION) && defined(HAVE_PTHREAD)
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <unistd.h>
static int cancellation_fd[] = {-1, -1};
void sig_handler(int sig) {
stop_daemon();
run_daemon = 0;
write(cancellation_fd[1], &sig, sizeof sig);
}
void set_sa_handler(void)
static void *cancellation_proc(void *arg)
{
struct sigaction new_sig, old_sig;
(void)arg;
while (run_daemon) {
int sig;
if (sizeof sig == read(cancellation_fd[0], &sig, sizeof sig)) {
break;
}
}
sc_cancel(ctx);
return NULL;
}
/* Register signal handlers */
void setup_cancellation(void)
{
pthread_t cancellation_thread;
struct sigaction new_sig, old_sig;
new_sig.sa_handler = sig_handler;
sigemptyset(&new_sig.sa_mask);
new_sig.sa_flags = SA_RESTART;
if ((sigaction(SIGINT, &new_sig, &old_sig) < 0)
|| (sigaction(SIGTERM, &new_sig, &old_sig) < 0)) {
fprintf(stderr, "Failed to create signal handler: %s", strerror(errno));
if (pipe(cancellation_fd) != 0
|| (errno = pthread_create(&cancellation_thread, NULL, cancellation_proc, NULL)) != 0
|| sigaction(SIGINT, &new_sig, &old_sig) != 0
|| sigaction(SIGTERM, &new_sig, &old_sig) != 0) {
fprintf(stderr, "Failed to setup cancellation: %s", strerror(errno));
}
}
#else
void set_sa_handler(void)
void setup_cancellation(void)
{
}
#endif
#include "opensc-notify-cmdline.h"
@ -244,8 +263,8 @@ main (int argc, char **argv)
if ((!cmdline.customized_mode_counter && !cmdline.standard_mode_counter)
|| cmdline.daemon_mode_counter) {
set_sa_handler();
run_daemon = 1;
setup_cancellation();
notify_daemon();
} else {
/* give the notification process some time to spawn */

View File

@ -1597,53 +1597,42 @@ static void init_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess)
static int change_pin(CK_SLOT_ID slot, CK_SESSION_HANDLE sess)
{
char old_buf[21], *old_pin = NULL;
char new_buf[21], *new_pin = NULL;
char old_buf[21], *old_pin = opt_so_pin ? (char*)opt_so_pin : (char*)opt_pin;
char new_buf[21], *new_pin = (char *)opt_new_pin;
CK_TOKEN_INFO info;
CK_RV rv;
int r;
size_t len = 0;
get_token_info(slot, &info);
const CK_FLAGS hasReaderPinPad = info.flags & CKF_PROTECTED_AUTHENTICATION_PATH;
if (!(info.flags & CKF_PROTECTED_AUTHENTICATION_PATH)) {
if (!opt_pin && !opt_so_pin) {
printf("Please enter the current PIN: ");
r = util_getpass(&old_pin, &len, stdin);
if (r < 0)
return 1;
if (!old_pin || !*old_pin || strlen(old_pin) > 20)
return 1;
strcpy(old_buf, old_pin);
old_pin = old_buf;
}
else {
if (opt_so_pin)
old_pin = (char *) opt_so_pin;
else
old_pin = (char *) opt_pin;
}
if (!hasReaderPinPad && !old_pin) {
printf("Please enter the current PIN: ");
r = util_getpass(&old_pin, &len, stdin);
if (r < 0)
return 1;
if (!old_pin || !*old_pin || strlen(old_pin) > 20)
return 1;
strcpy(old_buf, old_pin);
old_pin = old_buf;
}
if (!hasReaderPinPad && !new_pin) {
printf("Please enter the new PIN: ");
r = util_getpass(&new_pin, &len, stdin);
if (r < 0)
return 1;
if (!new_pin || !*new_pin || strlen(new_pin) > 20)
return 1;
strcpy(new_buf, new_pin);
if (!opt_new_pin) {
printf("Please enter the new PIN: ");
r = util_getpass(&new_pin, &len, stdin);
if (r < 0)
return 1;
if (!new_pin || !*new_pin || strlen(new_pin) > 20)
return 1;
strcpy(new_buf, new_pin);
printf("Please enter the new PIN again: ");
r = util_getpass(&new_pin, &len, stdin);
if (r < 0)
return 1;
if (!new_pin || !*new_pin || strcmp(new_buf, new_pin) != 0) {
free(new_pin);
return 1;
}
}
else {
new_pin = (char *) opt_new_pin;
printf("Please enter the new PIN again: ");
r = util_getpass(&new_pin, &len, stdin);
if (r < 0)
return 1;
if (!new_pin || !*new_pin || strcmp(new_buf, new_pin) != 0) {
free(new_pin);
return 1;
}
}

View File

@ -34,8 +34,12 @@ static const char *get_inserted_text(struct sc_pkcs15_card *p15card, struct sc_a
static char text[3*SC_MAX_ATR_SIZE] = {0};
const char prefix[] = "ATR: ";
if (p15card && p15card->card && p15card->card->name) {
if (p15card && p15card->card
&& p15card->card->name) {
return p15card->card->name;
} else if (p15card && p15card->card
&& p15card->card->reader && p15card->card->reader->name) {
return p15card->card->reader->name;
}
if (!atr)
@ -192,7 +196,7 @@ const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr,
str = "Dieses Fenster wird automatisch geschlossen, wenn die PIN am PIN-Pad eingegeben wurde (Timeout typischerweise nach 30 Sekunden).";
break;
case NOTIFY_CARD_INSERTED:
if (p15card) {
if (p15card && p15card->card && p15card->card->name) {
str = "Smartcard kann jetzt verwendet werden";
} else {
str = "Smartcard erkannt";
@ -260,7 +264,7 @@ const char *ui_get_str(struct sc_context *ctx, struct sc_atr *atr,
str = "This window will be closed automatically after the PIN has been submitted on the PIN pad (timeout typically after 30 seconds).";
break;
case NOTIFY_CARD_INSERTED:
if (p15card) {
if (p15card && p15card->card && p15card->card->name) {
str = "Smart card is ready to use";
} else {
str = "Smart card detected";