From 31ebb6568fd8557ba184b38481887e540cbf5647 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Tue, 25 Aug 2015 00:25:25 -0500 Subject: Add preliminary cryptographic card support to TDEHWLib --- tdecore/tdehw/tdecryptographiccarddevice.cpp | 296 +++++++++++++++++++++++++++ 1 file changed, 296 insertions(+) create mode 100644 tdecore/tdehw/tdecryptographiccarddevice.cpp (limited to 'tdecore/tdehw/tdecryptographiccarddevice.cpp') diff --git a/tdecore/tdehw/tdecryptographiccarddevice.cpp b/tdecore/tdehw/tdecryptographiccarddevice.cpp new file mode 100644 index 000000000..9c827a1f6 --- /dev/null +++ b/tdecore/tdehw/tdecryptographiccarddevice.cpp @@ -0,0 +1,296 @@ +/* This file is part of the TDE libraries + Copyright (C) 2015 Timothy Pearson + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "tdecryptographiccarddevice_private.h" +#include "tdecryptographiccarddevice.h" + +#include +#include +#include +#include +#include + +#include "tdeglobal.h" +#include "tdelocale.h" + +#include "tdehardwaredevices.h" + +#include "config.h" + +// 1 second +#define PCSC_POLL_TIMEOUT_S 1000 + +/* FIXME + * This is incomplete + */ +static TQString pcsc_error_code_to_string(long errcode) { + if (errcode == SCARD_W_UNPOWERED_CARD) { + return i18n("card not powered on"); + } + else if (errcode == SCARD_E_PROTO_MISMATCH) { + return i18n("protocol mismatch"); + } + else { + return TQString::null; + } +} + +CryptoCardDeviceWatcher::CryptoCardDeviceWatcher() { + m_readerStates = NULL; +} + +CryptoCardDeviceWatcher::~CryptoCardDeviceWatcher() { + free(m_readerStates); +} + +void CryptoCardDeviceWatcher::run() { +#ifdef WITH_PCSC + bool first_loop; + unsigned int i; + long ret; + + DWORD dword_readers; + LPSTR lpstring_readers = NULL; + + TQStringList readers; + + first_loop = true; + m_terminationRequested = false; + + TQEventLoop* eventLoop = TQApplication::eventLoop(); + if (!eventLoop) return; + + ret = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &m_cardContext); + if (ret != SCARD_S_SUCCESS) { + printf("TDECryptographicCardDevice: PCSC SCardEstablishContext cannot connect to resource manager (%lX)", ret); + eventLoop->exit(0); + return; + } + + ret = SCardListReaders(m_cardContext, NULL, NULL, &dword_readers); + if (ret == SCARD_S_SUCCESS) { + lpstring_readers = (LPSTR)malloc(sizeof(char)*dword_readers); + if (lpstring_readers == NULL) { + printf("TDECryptographicCardDevice: insufficient memory, aborting"); + eventLoop->exit(0); + return; + } + + ret = SCardListReaders(m_cardContext, NULL, lpstring_readers, &dword_readers); + if (ret == SCARD_S_SUCCESS) { + /* Extract reader names from the null separated string */ + char *ptr = lpstring_readers; + while (*ptr != '\0') { + readers.append(ptr); + ptr += strlen(ptr)+1; + } + + free(lpstring_readers); + + m_readerStates = (SCARD_READERSTATE*)calloc(readers.count(), sizeof(*m_readerStates)); + if (m_readerStates == NULL) { + printf("TDECryptographicCardDevice: insufficient memory, aborting"); + free(lpstring_readers); + eventLoop->exit(0); + return; + } + + for (i=0; iexit(0); + return; + } + + for (i=0; ifriendlyName())) { + continue; + } + + if (first_loop) { + if (m_readerStates[i].dwEventState & SCARD_STATE_PRESENT) { + // sleep(1); // Allow the card to settle + statusChanged("PRESENT", getCardATR(readers[i])); + } + first_loop = false; + } + if (m_readerStates[i].dwEventState & SCARD_STATE_CHANGED) { + if ((m_readerStates[i].dwCurrentState & SCARD_STATE_PRESENT) + && (m_readerStates[i].dwEventState & SCARD_STATE_EMPTY)) { + statusChanged("REMOVED", TQString::null); + } + else if ((m_readerStates[i].dwCurrentState & SCARD_STATE_EMPTY) + && (m_readerStates[i].dwEventState & SCARD_STATE_PRESENT)) { + // sleep(1); // Allow the card to settle + statusChanged("INSERTED", getCardATR(readers[i])); + } + m_readerStates[i].dwCurrentState = m_readerStates[i].dwEventState; + } + else { + continue; + } + } + ret = SCardGetStatusChange(m_cardContext, PCSC_POLL_TIMEOUT_S, m_readerStates, readers.count()); + } + } + } + + eventLoop->exit(0); +#endif +} + +void CryptoCardDeviceWatcher::requestTermination() { + m_terminationRequested = true; +} + +TQString CryptoCardDeviceWatcher::getCardATR(TQString readerName) { + unsigned int i; + long ret; + TQString atr_formatted; + SCARDHANDLE hCard = 0; + DWORD dwActiveProtocol = 0; + DWORD cByte = 0; + + ret = SCardConnect(m_cardContext, readerName.ascii(), SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol); + if (ret == SCARD_S_SUCCESS) { + ret = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, NULL, &cByte); + if (ret == SCARD_S_SUCCESS) { + char* data = new char[cByte]; + ret = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, (LPBYTE)data, &cByte); + atr_formatted = TQString::null; + for (i=0; icardDevice = this; + m_watcherObject->moveToThread(m_watcherThread); + TQObject::connect(m_watcherObject, SIGNAL(statusChanged(TQString,TQString)), this, SLOT(cardStatusChanged(TQString,TQString))); + TQTimer::singleShot(0, m_watcherObject, SLOT(run())); + + m_watcherThread->start(); + } + else { + if (m_watcherObject) { + m_watcherObject->requestTermination(); + delete m_watcherObject; + m_watcherObject = NULL; + } + if (m_watcherThread) { + m_watcherThread->wait(); + delete m_watcherThread; + m_watcherThread = NULL; + } + } +#endif +} + +int TDECryptographicCardDevice::cardPresent() { + if (m_watcherObject && m_watcherThread) { + if (m_cardPresent) + return 1; + else + return 0; + } + else { + return -1; + } +} + +TQString TDECryptographicCardDevice::cardATR() { + if (m_watcherObject && m_watcherThread) { + if (m_cardPresent) + return m_cardATR; + else + return TQString::null; + } + else { + return TQString::null; + } +} + +void TDECryptographicCardDevice::cardStatusChanged(TQString status, TQString atr) { + if (status == "INSERTED") { + m_cardPresent = true; + m_cardATR = atr; + emit(cardInserted()); + } + else if (status == "REMOVED") { + m_cardPresent = false; + m_cardATR = atr; + emit(cardRemoved()); + } + else if (status == "PRESENT") { + m_cardATR = atr; + m_cardPresent = true; + } +} + +#include "tdecryptographiccarddevice.moc" +#include "tdecryptographiccarddevice_private.moc" -- cgit v1.2.1