don't throw exception in destructur when card has been removed

master
Marc Wäckerlin 9 years ago
parent 99c3b9e115
commit bfd747340a
  1. 111
      ax_check_qt.m4
  2. 97
      ax_init_standard_project.m4
  3. 2
      configure.ac
  4. 6
      src/cryptoki.cxx
  5. 11
      src/cryptoki.hxx
  6. 7
      src/pcsc.hxx

@ -1,10 +1,10 @@
# SYNOPSIS
#
# Check if a module exists:
# AX_CHECK_QT([qt_prefix], [list-of-qt-modules], [optional-modules])
# AX_CHECK_QT([qt_prefix], [list-of-qt-modules], [optional-modules] [flags])
#
# Abort if a module does not exist:
# AX_REQUIRE_QT([qt_prefix], [list-of-qt-modules], [optional-modules])
# AX_REQUIRE_QT([qt_prefix], [list-of-qt-modules], [optional-modules] [flags])
#
# DESCRIPTIONS
#
@ -35,6 +35,18 @@
# Optional list of more, optional modules, e.g. modules that
# exist only in Qt5, but not in Qt4, such as QtWidgets or
# QtWebKitWidgets
#
# flags
#
# Optional flages, space separated from this list:
#
# manualflags
#
# CXXFLAGS, CPPFLAGS and LIBS variables are not
# automatically expanded, but you need to add the
# qt_prefix_CXXFLAGS, qt_prefix_CPPFLAGS and qt_prefix_LIBS
# variables manually where you need them. This is useful,
# if some build targets need a feature and some don't.
AC_DEFUN([AX_CXX_QT_TOOL], [
@ -83,6 +95,7 @@ AC_DEFUN([AX_CXX_QT_TOOLS], [
AC_DEFUN([AX_CHECK_QT], [
qt_modules="$2"
qt_modules_optional="$3"
qt_flags="$4"
AX_CXX_QT_TOOLS
HAVE_$1=0
PKG_PROG_PKG_CONFIG
@ -91,17 +104,37 @@ AC_DEFUN([AX_CHECK_QT], [
AC_DEFINE([HAVE_$1])
QTDIR=$(${PKG_CONFIG} --variable=prefix Qt5Core)
QT_PLUGIN_PATH=${QTDIR}/share/qt5/plugins
CPPFLAGS+=" ${[$1]5_CFLAGS}"
MOC_FLAGS+=" -DHAVE_$1=1 ${[$1]5_CFLAGS}"
CXXFLAGS+=" ${[$1]5_CFLAGS}"
LIBS+=" ${[$1]5_LIBS}"
[$1]_CPPFLAGS="${[$1]5_CFLAGS}"
[$1]_CXXFLAGS="${[$1]5_CFLAGS}"
[$1]_LIBS="${[$1]5_LIBS}"
AC_SUBST([$1]_CPPFLAGS)
AC_SUBST([$1]_CXXFLAGS)
if test "${qt_flags/manualflags/}" = "${qt_flags}"; then
CPPFLAGS+=" ${[$1]_CPPFLAGS}"
CXXFLAGS+=" ${[$1]_CXXFLAGS}"
LIBS+=" ${[$1]_LIBS}"
AC_MSG_NOTICE([Adding flags for $1])
else
AC_MSG_NOTICE([To enable $1, add $1_CPPFLAGS, $1_CXXFLAGS and $1_LIBS])
fi
PKG_REQUIREMENTS+=" ${qt_modules//Qt/Qt5}"
if test -n "${qt_modules_optional}"; then
PKG_CHECK_MODULES([$1]5_OPTIONAL, [${qt_modules_optional//Qt/Qt5}], [
CPPFLAGS+=" ${[$1]5_OPTIONAL_CFLAGS}"
MOC_FLAGS+=" ${[$1]5_OPTIONAL_CFLAGS}"
[$1]_CPPFLAGS+=" ${[$1]5_OPTIONAL_CFLAGS}"
[$1]_CXXFLAGS+=" ${[$1]5_OPTIONAL_CFLAGS}"
[$1]_LIBS+=" ${[$1]5_OPTIONAL_LIBS}"
AC_SUBST([$1]_CPPFLAGS)
AC_SUBST([$1]_CXXFLAGS)
if test "${qt_flags/manualflags/}" = "${qt_flags}"; then
CPPFLAGS+=" ${[$1]5_OPTIONAL_CFLAGS}"
CXXFLAGS+=" ${[$1]5_OPTIONAL_CFLAGS}"
LIBS+=" ${[$1]5_OPTIONAL_LIBS}"
AC_MSG_NOTICE([Adding flags for $1])
else
AC_MSG_NOTICE([To enable $1, add $1_CPPFLAGS, $1_CXXFLAGS and $1_LIBS])
fi
PKG_REQUIREMENTS+=" ${qt_modules_optional//Qt/Qt5}"
], [
AC_MSG_NOTICE([Not found: ${qt_modules_optional//Qt/Qt5}])
@ -113,17 +146,36 @@ AC_DEFUN([AX_CHECK_QT], [
AC_DEFINE([HAVE_$1])
QTDIR=$(${PKG_CONFIG} --variable=prefix QtCore)
QT_PLUGIN_PATH=${QTDIR}/share/qt/plugins
CPPFLAGS+=" ${$1_CFLAGS}"
MOC_FLAGS+=" -DHAVE_$1=1 ${$1_CFLAGS}"
CXXFLAGS+=" ${$1_CFLAGS}"
LIBS+=" ${$1_LIBS}"
[$1]_CPPFLAGS="${[$1]_CFLAGS}"
[$1]_CXXFLAGS="${[$1]_CFLAGS}"
AC_SUBST([$1]_CPPFLAGS)
AC_SUBST([$1]_CXXFLAGS)
if test "${qt_flags/manualflags/}" = "${qt_flags}"; then
CPPFLAGS+=" ${[$1]_CPPFLAGS}"
CXXFLAGS+=" ${[$1]_CXXFLAGS}"
LIBS+=" ${[$1]_LIBS}"
AC_MSG_NOTICE([Adding flags for $1])
else
AC_MSG_NOTICE([To enable $1, add $1_CPPFLAGS, $1_CXXFLAGS and $1_LIBS])
fi
PKG_REQUIREMENTS+=" ${qt_modules}"
if test -n "$3"; then
PKG_CHECK_MODULES($1_OPTIONAL, [${qt_modules_optional}], [
CPPFLAGS+=" ${$1_OPTIONAL_CFLAGS}"
MOC_FLAGS+="${$1_OPTIONAL_CFLAGS}"
[$1]_CPPFLAGS+=" ${$1_OPTIONAL_CFLAGS}"
[$1]_CXXFLAGS+=" ${$1_OPTIONAL_CFLAGS}"
[$1]_LIBS+=" ${$1_OPTIONAL_LIBS}"
AC_SUBST([$1]_CPPFLAGS)
AC_SUBST([$1]_CXXFLAGS)
if test "${qt_flags/manualflags/}" = "${qt_flags}"; then
CPPFLAGS+=" ${$1_OPTIONAL_CFLAGS}"
CXXFLAGS+=" ${$1_OPTIONAL_CFLAGS}"
LIBS+=" ${$1_OPTIONAL_LIBS}"
AC_MSG_NOTICE([Adding flags for $1])
else
AC_MSG_NOTICE([To enable $1, add $1_CPPFLAGS, $1_CXXFLAGS and $1_LIBS])
fi
PKG_REQUIREMENTS+=" ${qt_modules_optional}"
], [
AC_MSG_NOTICE([Not found: ${qt_modules_optional}])
@ -133,7 +185,7 @@ AC_DEFUN([AX_CHECK_QT], [
])
AM_CONDITIONAL(HAVE_$1, test $HAVE_[$1] -eq 1)
AX_CHECK_VALID_CXX_FLAG([-fPIC -fPIE], [position independent code flag])
if test "${MINGW}" != "no"; then
if test -n "${MINGW}"; then
AX_CHECK_VALID_CXX_FLAG([-Wl,-subsystem,windows], [windows console flag])
fi
AC_SUBST(QTDIR)
@ -169,42 +221,8 @@ qrc_%.cxx: %.qrc
'])
# SYNOPSIS
#
# AX_CHECK_QT([qt_prefix], [list-of-qt-modules], [optional-modules])
#
# DESCRIPTIONS
#
# qt_prefix
#
# Each call to AX_CHECK_QT should have a different prefix
# value (with a few exceptions discussed later on). This value,
# usually provided in uppercase, is used as prefix to the
# variables holding the compiler flags and libraries reported by
# pkg-config.
#
# For instance, if your prefix was to be FOO you'll be provided
# two variables FOO_CFLAGS and FOO_LIBS.
#
# This will also be used as message during the configure checks:
# checking for FOO....
#
# list-of-modules
#
# A single call to the macro can check for the presence of one or
# more qt modules; you'll see later how to make good use of this
# feature. Each entry in the list can have a version comparison
# specifier, with the same syntax as the Requires keyword in the
# data files themselves.
#
# optional-modules
#
# Optional list of more, optional modules, e.g. modules that
# exist only in Qt5, but not in Qt4, such as QtWidgets or
# QtWebKitWidgets
AC_DEFUN([AX_REQUIRE_QT], [
AX_CHECK_QT([$1], [$2], [$3])
AX_CHECK_QT([$1], [$2], [$3], [$4])
if ! test "$HAVE_$1" -eq 1; then
AC_MSG_ERROR([Required Qt modules not found: $2])
fi
@ -213,7 +231,6 @@ AC_DEFUN([AX_REQUIRE_QT], [
# Omit Qt Keywords
# AX_QT_NO_KEYWORDS
AC_DEFUN([AX_QT_NO_KEYWORDS], [
CPPFLAGS+=" -DQT_NO_KEYWORDS"
])

@ -8,17 +8,26 @@ m4_define([mrw_esyscmd_s], [m4_normalize(m4_esyscmd([$1]))])
# define least version number from subversion's revision number:
# it is taken modulo 256 due to a bug on Apple's MacOSX
m4_define(x_least, mrw_esyscmd_s([
m4_define(x_least, m4_ifdef([x_least_diff], mrw_esyscmd_s([
SVN_REVISION="ERROR-UNDEFINED-REVISION-to-be-built-in-subdirectory-of-svn-checkout"
for path in . .. ../..; do
if svn info $path 2>&1 > /dev/null; then
SVN_REVISION=$(LANG= svn info $path | sed -n 's/Last Changed Rev: //p')
SVN_REVISION=$(LANG= svn info $path | sed -n 's/^Revision: //p')
break;
fi
done
echo $ECHO_N $(($SVN_REVISION))
]), mrw_esyscmd_s([
SVN_REVISION="ERROR-UNDEFINED-REVISION-to-be-built-in-subdirectory-of-svn-checkout"
for path in . .. ../..; do
if svn info $path 2>&1 > /dev/null; then
SVN_REVISION=$(LANG= svn info $path | sed -n 's/^Revision: //p')
break;
fi
done
# Mac does not support LEAST > 255
echo $ECHO_N $(($SVN_REVISION%256))
]))
])))
# define version number from subversion's revision number:
# it is taken modulo 256 due to a bug on Apple's MacOSX
# add to x_minor if revision number is > 256
@ -26,15 +35,15 @@ m4_define(x_minor_diff, mrw_esyscmd_s([
SVN_REVISION="ERROR-UNDEFINED-REVISION-to-be-built-in-subdirectory-of-svn-checkout"
for path in . .. ../..; do
if svn info $path 2>&1 > /dev/null; then
SVN_REVISION=$(LANG= svn info $path | sed -n 's/Last Changed Rev: //p')
SVN_REVISION=$(LANG= svn info $path | sed -n 's/^Revision: //p')
break;
fi;
done
# Mac does not support LEAST > 255
echo $ECHO_N $(($SVN_REVISION/256))
]))
])))
# setup version number
m4_define(x_version, [x_major.m4_eval(x_minor+x_minor_diff).x_least])
m4_define(x_version, [x_major.m4_ifdef([x_least_diff], x_minor, m4_eval(x_minor+x_minor_diff)).m4_eval(m4_ifdef([x_least_diff], [x_least-x_least_diff], [x_least]))])
## bugreport mail address is taken from <user@host> in first line of AUTHORS
m4_define(x_bugreport, mrw_esyscmd_s([
@ -107,14 +116,27 @@ AC_DEFUN([AX_SUBST], [
#
# configures the basic environment
AC_DEFUN([AX_INIT_STANDARD_PROJECT], [
MINGW=no
MAC=no
case $host in
*mingw*) MINGW=yes;;
*darwin* | *rhapsody* | *macosx*) MAC=yes;;
AC_MSG_CHECKING([target platfrom])
UNIX=1
MINGW=
MACOSX=
for h in ${target} ${target_os} ${host} ${host_os} \
${build} ${build_os} $(uname -s 2> /dev/null); do
p="$h is generic Unix"
case "$h" in
(*mingw*)
UNIX=; MINGW=1; p="MinGW"; break;;
(*Darwin*|*darwin*|*rhapsody*|*macosx*)
UNIX=; MACOSX=1; p="MacOSX"; break;;
esac
AM_CONDITIONAL(MINGW, test "$MINGW" = "yes")
AM_CONDITIONAL(MAC, test "$MAC" = "yes")
done
AC_MSG_RESULT($p)
AM_CONDITIONAL(UNIX, test "$UNIX" = "1")
AM_CONDITIONAL(MINGW, test "$MINGW" = "1")
AM_CONDITIONAL(MACOSX, test "$MACOSX" = "1")
AX_SUBST(UNIX)
AX_SUBST(MINGW)
AX_SUBST(MACOSX)
AM_CPPFLAGS+=" '-DMAKE_STRING(X)=\#X' '-DNAMESPACE=${PACKAGE_TARNAME//[^a-zA-Z0-9]/_}'"
AX_SUBST(NUMBERS)
AX_SUBST(HOME)
@ -127,7 +149,7 @@ AC_DEFUN([AX_INIT_STANDARD_PROJECT], [
AUTHOR=$(head -1 AUTHORS)
AX_SUBST(AUTHOR)
_AM_SUBST_NOTMAKE([AUTHOR])
DISTRO=$(lsb_release -sc)
DISTRO=$(lsb_release -sc 2>/dev/null || uname -s 2>/dev/null)
AX_SUBST(DISTRO)
BUILD_NUMBER=${BUILD_NUMBER:-1}
AX_SUBST(BUILD_NUMBER)
@ -156,11 +178,24 @@ AC_DEFUN([AX_INIT_STANDARD_PROJECT], [
- all warnings result in an error
- doxygen warnings are treated as error too]); fi
AC_ARG_ENABLE(debug,
[AS_HELP_STRING([--enable-debug],
[compile for debugger])],
[have_debug="$enableval"; test "$enableval" = "yes" && \
AM_CPPFLAGS="${AM_CPPFLAGS} -DDEBUG" && \
AM_CXXFLAGS="${AM_CXXFLAGS:-} -ggdb3 -O0" && \
AM_LDFLAGS="${AM_LDFLAGS} -ggdb3 -O0"])
AM_CONDITIONAL(DEBUG, test "$enableval" = "yes")
if test "$have_debug" == "yes"; then
AC_MSG_NOTICE([Debug compile mode enabled]);
fi
AC_CONFIG_FILES([makefile])
AX_ADD_MAKEFILE_TARGET_DEP([clean-am], [clean-standard-project-targets], [makefile.in])
AX_ADD_MAKEFILE_TARGET_DEP([distclean-am], [distclean-standard-project-targets], [makefile.in])
AX_ADD_MAKEFILE_TARGET_DEP([maintainer-clean-am], [maintainer-clean-standard-project-targets], [makefile.in])
test -f makefile.in && sed -i '1iEXTRA_DIST = ' makefile.in
test -f makefile.in && TMP_MAKEFILE="$(<makefile.in)" && \
(echo "EXTRA_DIST ="; echo "$TMP_MAKEFILE") > makefile.in
test -f makefile.in && cat >> makefile.in <<EOF
#### Begin: Appended by $0
EXTRA_DIST += bootstrap.sh
@ -387,6 +422,8 @@ EOF
# $2 = module name (optional, if different from id)
# $3 = a header file to find (optional)
# $4 = alternative module names (space separated, optional)
# $5 = optional flags:
# manualflags if CXXFLAGS, CPPFLAGS, LIBS should remain unchanged
#
# uses PKG_CHECK_MODULES to test for a module
# then, if given, looks for the header file
@ -395,6 +432,7 @@ EOF
# fails if not found
AC_DEFUN([AX_PKG_REQUIRE], [
PKG_PROG_PKG_CONFIG
optional_flags="$5"
$1_found=no
secondpar="m4_default([$2], [$1])"
PKG_CHECK_MODULES([$1], [m4_default([$2], [$1])], [
@ -474,26 +512,47 @@ AC_DEFUN([AX_PKG_REQUIRE], [
AC_MSG_ERROR([Feature $1 not found please install module $secondpar])
fi
fi
CPPFLAGS+=" ${$1_CFLAGS}"
CXXFLAGS+=" ${$1_CFLAGS}"
[$1]_CPPFLAGS="${$1_CFLAGS}"
[$1]_CXXFLAGS="${$1_CFLAGS}"
AC_SUBST([$1]_CPPFLAGS)
AC_SUBST([$1]_CXXFLAGS)
if test "${optional_flags/manualflags/}" = "${optional_flags}"; then
CPPFLAGS+=" ${$1_CPPFLAGS}"
CXXFLAGS+=" ${$1_CXXFLAGS}"
LIBS+=" ${$1_LIBS}"
AC_MSG_NOTICE([Adding flags for $1])
else
AC_MSG_NOTICE([To enable $1, add $1_CPPFLAGS, $1_CXXFLAGS and $1_LIBS])
fi
])
# check if a specific package exists
# - parameter:
# $1 = unique id (no special characters)
# $2 = module name (optional, if different from id)
# $3 = optional flags:
# manualflags if CXXFLAGS, CPPFLAGS, LIBS should remain unchanged
#
# uses PKG_CHECK_MODULES to test for a module
# sets automake conditional HAVE_$1 to 0 (not found) or 1 (found)
# sets all flags, so that the module can be used everywhere
AC_DEFUN([AX_PKG_CHECK], [
optional_flags="$3"
PKG_PROG_PKG_CONFIG
PKG_CHECK_MODULES([$1], [m4_default([$2], [$1])], [
HAVE_$1=1
CPPFLAGS+=" ${$1_CFLAGS}"
CXXFLAGS+=" ${$1_CFLAGS}"
[$1]_CPPFLAGS="${$1_CFLAGS}"
[$1]_CXXFLAGS="${$1_CFLAGS}"
AC_SUBST([$1]_CPPFLAGS)
AC_SUBST([$1]_CXXFLAGS)
if test "${optional_flags/manualflags/}" = "${optional_flags}"; then
CPPFLAGS+=" ${$1_CPPFLAGS}"
CXXFLAGS+=" ${$1_CXXFLAGS}"
LIBS+=" ${$1_LIBS}"
AC_MSG_NOTICE([Adding flags for $1])
else
AC_MSG_NOTICE([To enable $1, add $1_CPPFLAGS, $1_CXXFLAGS and $1_LIBS])
fi
if test -z "$PKG_REQUIREMENTS"; then
PKG_REQUIREMENTS="m4_default([$2], [$1])"
else

@ -39,7 +39,7 @@ AX_CHECK_QT([QTNETWORK], [Qt5Network >= 5.2])
CPPFLAGS="${CPPFLAGS} -DQT_NO_KEYWORDS"
# libraries used
if test "$MINGW" = "no"; then
if test -z "$MINGW"; then
AX_PKG_REQUIRE([pcsc], [libpcsclite], [pcsclite.h])
AX_PKG_REQUIRE([pkcs11], [p11-kit-1], [pkcs11.h], [p11-kit libpkcs11-helper-1])
AX_PKG_REQUIRE([ssl], [libssl], [openssl/crypto.h], [openssl])

@ -193,6 +193,8 @@ namespace cryptoki {
Library::Init::~Init() {
CRYPTOLOG("log");
/// ignore failure in disconnect, possibly smartcard has
/// been removed
try {
//! calls @c C_Finalize
check(_fn->C_Finalize(0), CRYPTOKI_FN_LOG("C_Finalize"));
@ -204,8 +206,10 @@ namespace cryptoki {
_lib = 0;
#endif
_fn = 0;
} catch (std::exception& e) {
CRYPTOLOG("unloading cryptoki library failed, reason: "+e.what());
} catch (...) {
if (!std::uncaught_exception()) throw;
CRYPTOLOG("unloading cryptoki library failed");
}
}

@ -1559,25 +1559,22 @@ namespace cryptoki {
}
~Session() try {
CRYPTOLOG("log "<<(std::uncaught_exception()?"IN EXCEPTION":""));
/// ignore failure in disconnect, possibly smartcard has
/// been removed
try {
logout();
} catch (const std::exception& x) {
CRYPTOLOG("caught: "<<x.what());
close();
if (!std::uncaught_exception()) throw;
} catch (...) {
CRYPTOLOG("caught");
close();
if (!std::uncaught_exception()) throw;
}
close();
} catch (const std::exception& x) {
CRYPTOLOG("caught: "<<x.what());
if (!std::uncaught_exception()) throw;
} catch (...) {
CRYPTOLOG("caught");
if (!std::uncaught_exception()) throw;
}
/*! @name Comfortable Access
@ -1879,16 +1876,16 @@ namespace cryptoki {
}
~Login() {
/// ignore failure in disconnect, possibly smartcard has
/// been removed
try {
//! calls @c C_Logout
_session.check(_session._slot.library()->C_Logout
(_session._session),
CRYPTOKI_FN_LOG("C_Logout"));
} catch (const std::exception& x) {
if (!std::uncaught_exception()) throw;
CRYPTOLOG("ERROR during error cleanup: "<<x.what());
} catch (...) {
if (!std::uncaught_exception()) throw;
CRYPTOLOG("ERROR during error cleanup.");
}
}

@ -219,8 +219,8 @@ namespace pcsc {
~Reader() {
CRYPTOLOG("Disconnect Reader");
_state = SCardDisconnect(_id, SCARD_RESET_CARD);
if (!std::uncaught_exception())
_connection->check(_state, "disconnect smartcard");
/// ignore failure in disconnect, possibly smartcard has
/// been removed
}
//! Get reader status.
@ -495,7 +495,8 @@ namespace pcsc {
~Connection() {
CRYPTOLOG("Close Connection id="<<_id);
_state = SCardReleaseContext(_id);
if (!std::uncaught_exception()) check("smartcard release context");
/// ignore failure in disconnect, possibly smartcard has
/// been removed
}
//! Scans for available readers from a specified list of groups.

Loading…
Cancel
Save