diff options
-rw-r--r-- | Swift/QtUI/QtLoginWindow.cpp | 4 | ||||
-rw-r--r-- | Swift/QtUI/QtLoginWindow.h | 5 | ||||
-rw-r--r-- | Swift/QtUI/QtSwift.cpp | 2 | ||||
-rw-r--r-- | Swift/QtUI/QtUIFactory.cpp | 4 | ||||
-rw-r--r-- | Swift/QtUI/QtUIFactory.h | 4 | ||||
-rw-r--r-- | Swift/QtUI/SConscript | 3 | ||||
-rw-r--r-- | Swiften/TLS/CAPICertificate.cpp | 184 | ||||
-rw-r--r-- | Swiften/TLS/CAPICertificate.h | 25 | ||||
-rw-r--r-- | Swiften/TLS/Schannel/SchannelContext.cpp | 18 | ||||
-rw-r--r-- | Swiften/TLS/Schannel/SchannelContext.h | 6 |
10 files changed, 241 insertions, 14 deletions
diff --git a/Swift/QtUI/QtLoginWindow.cpp b/Swift/QtUI/QtLoginWindow.cpp index dc6001b..7612720 100644 --- a/Swift/QtUI/QtLoginWindow.cpp +++ b/Swift/QtUI/QtLoginWindow.cpp @@ -43,19 +43,19 @@ #ifdef HAVE_SCHANNEL #include "CAPICertificateSelector.h" #include <Swiften/TLS/CAPICertificate.h> #endif #include <Swiften/TLS/PKCS12Certificate.h> namespace Swift{ -QtLoginWindow::QtLoginWindow(UIEventStream* uiEventStream, SettingsProvider* settings) : QMainWindow(), settings_(settings) { +QtLoginWindow::QtLoginWindow(UIEventStream* uiEventStream, SettingsProvider* settings, TimerFactory* timerFactory) : QMainWindow(), settings_(settings), timerFactory_(timerFactory) { uiEventStream_ = uiEventStream; setWindowTitle("Swift"); #ifndef Q_WS_MAC setWindowIcon(QIcon(":/logo-icon-16.png")); #endif QtUtilities::setX11Resource(this, "Main"); resize(200, 500); @@ -345,19 +345,19 @@ void QtLoginWindow::loginClicked() { msgBox.setDefaultButton(QMessageBox::No); if (msgBox.exec() != QMessageBox::Yes) { return; } } CertificateWithKey::ref certificate; std::string certificateString = Q2PSTRING(certificateFile_); #if defined(HAVE_SCHANNEL) if (isCAPIURI(certificateString)) { - certificate = boost::make_shared<CAPICertificate>(certificateString); + certificate = boost::make_shared<CAPICertificate>(certificateString, timerFactory_); } else { certificate = boost::make_shared<PKCS12Certificate>(certificateString, createSafeByteArray(Q2PSTRING(password_->text()))); } #else certificate = boost::make_shared<PKCS12Certificate>(certificateString, createSafeByteArray(Q2PSTRING(password_->text()))); #endif onLoginRequest(Q2PSTRING(username_->currentText()), Q2PSTRING(password_->text()), certificateString, certificate, remember_->isChecked(), loginAutomatically_->isChecked()); if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { /* Mustn't remember logins */ diff --git a/Swift/QtUI/QtLoginWindow.h b/Swift/QtUI/QtLoginWindow.h index dcd7c18..1add2f4 100644 --- a/Swift/QtUI/QtLoginWindow.h +++ b/Swift/QtUI/QtLoginWindow.h @@ -19,29 +19,31 @@ #include <Swift/Controllers/UIInterfaces/MainWindow.h> #include <QtAboutWidget.h> class QLabel; class QToolButton; class QComboBox; namespace Swift { class SettingsProvider; + class TimerFactory; + class QtLoginWindow : public QMainWindow, public LoginWindow { Q_OBJECT public: struct QtMenus { QtMenus(QMenu* swiftMenu, QMenu* generalMenu) : swiftMenu(swiftMenu), generalMenu(generalMenu) {} QMenu* swiftMenu; QMenu* generalMenu; }; public: - QtLoginWindow(UIEventStream* uiEventStream, SettingsProvider* settings); + QtLoginWindow(UIEventStream* uiEventStream, SettingsProvider* settings, TimerFactory* timerFactory); void morphInto(MainWindow *mainWindow); virtual void loggedOut(); virtual void setShowNotificationToggle(bool); virtual void setMessage(const std::string& message); virtual void addAvailableAccount(const std::string& defaultJID, const std::string& defaultPassword, const std::string& defaultCertificate); virtual void removeAvailableAccount(const std::string& jid); virtual void setLoginAutomatically(bool loginAutomatically); virtual void setIsLoggingIn(bool loggingIn); @@ -92,11 +94,12 @@ namespace Swift { QMenu* swiftMenu_; QMenu* generalMenu_; QAction* toggleSoundsAction_; QAction* toggleNotificationsAction_; UIEventStream* uiEventStream_; QPointer<QtAboutWidget> aboutDialog_; SettingsProvider* settings_; QAction* xmlConsoleAction_; QAction* fileTransferOverviewAction_; + TimerFactory* timerFactory_; }; } diff --git a/Swift/QtUI/QtSwift.cpp b/Swift/QtUI/QtSwift.cpp index 9dabf21..60f93cc 100644 --- a/Swift/QtUI/QtSwift.cpp +++ b/Swift/QtUI/QtSwift.cpp @@ -166,19 +166,19 @@ QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMa if (splitter_) { splitter_->show(); } for (int i = 0; i < numberOfAccounts; i++) { if (i > 0) { // Don't add the first tray (see note above) systemTrays_.push_back(new QtSystemTray()); } - QtUIFactory* uiFactory = new QtUIFactory(settingsHierachy_, qtSettings_, tabs_, splitter_, systemTrays_[i], chatWindowFactory_, startMinimized); + QtUIFactory* uiFactory = new QtUIFactory(settingsHierachy_, qtSettings_, tabs_, splitter_, systemTrays_[i], chatWindowFactory_, networkFactories_.getTimerFactory(), startMinimized); uiFactories_.push_back(uiFactory); MainController* mainController = new MainController( &clientMainThreadCaller_, &networkFactories_, uiFactory, settingsHierachy_, systemTrays_[i], soundPlayer_, storagesFactory_, diff --git a/Swift/QtUI/QtUIFactory.cpp b/Swift/QtUI/QtUIFactory.cpp index c686442..a8b693d 100644 --- a/Swift/QtUI/QtUIFactory.cpp +++ b/Swift/QtUI/QtUIFactory.cpp @@ -24,19 +24,19 @@ #include "QtProfileWindow.h" #include "QtContactEditWindow.h" #include "QtAdHocCommandWindow.h" #include "QtFileTransferListWidget.h" #include <Swift/Controllers/Settings/SettingsProviderHierachy.h> #include <Swift/QtUI/QtUISettingConstants.h> namespace Swift { -QtUIFactory::QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabs* tabs, QSplitter* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, bool startMinimized) : settings(settings), qtOnlySettings(qtOnlySettings), tabs(tabs), netbookSplitter(netbookSplitter), systemTray(systemTray), chatWindowFactory(chatWindowFactory), lastMainWindow(NULL), loginWindow(NULL), startMinimized(startMinimized) { +QtUIFactory::QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabs* tabs, QSplitter* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, bool startMinimized) : settings(settings), qtOnlySettings(qtOnlySettings), tabs(tabs), netbookSplitter(netbookSplitter), systemTray(systemTray), chatWindowFactory(chatWindowFactory), timerFactory_(timerFactory), lastMainWindow(NULL), loginWindow(NULL), startMinimized(startMinimized) { chatFontSize = settings->getSetting(QtUISettingConstants::CHATWINDOW_FONT_SIZE); } XMLConsoleWidget* QtUIFactory::createXMLConsoleWidget() { QtXMLConsoleWidget* widget = new QtXMLConsoleWidget(); tabs->addTab(widget); if (!tabs->isVisible()) { tabs->show(); } @@ -54,19 +54,19 @@ FileTransferListWidget* QtUIFactory::createFileTransferListWidget() { return widget; } MainWindow* QtUIFactory::createMainWindow(UIEventStream* eventStream) { lastMainWindow = new QtMainWindow(settings, eventStream, loginWindow->getMenus()); return lastMainWindow; } LoginWindow* QtUIFactory::createLoginWindow(UIEventStream* eventStream) { - loginWindow = new QtLoginWindow(eventStream, settings); + loginWindow = new QtLoginWindow(eventStream, settings, timerFactory_); if (netbookSplitter) { netbookSplitter->insertWidget(0, loginWindow); } connect(systemTray, SIGNAL(clicked()), loginWindow, SLOT(bringToFront())); #ifndef SWIFT_MOBILE QVariant loginWindowGeometryVariant = qtOnlySettings->getQSettings()->value("loginWindowGeometry"); if (loginWindowGeometryVariant.isValid()) { loginWindow->restoreGeometry(loginWindowGeometryVariant.toByteArray()); diff --git a/Swift/QtUI/QtUIFactory.h b/Swift/QtUI/QtUIFactory.h index c9e2f2e..8b8e3ce 100644 --- a/Swift/QtUI/QtUIFactory.h +++ b/Swift/QtUI/QtUIFactory.h @@ -17,23 +17,24 @@ namespace Swift { class QtSettingsProvider; class SettingsProviderHierachy; class QtChatTabs; class QtSystemTray; class QtLoginWindow; class QtMainWindow; class QtChatTheme; class QtChatWindowFactory; class QtChatWindow; + class TimerFactory; class QtUIFactory : public QObject, public UIFactory { Q_OBJECT public: - QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabs* tabs, QSplitter* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, bool startMinimized); + QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabs* tabs, QSplitter* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, bool startMinimized); virtual XMLConsoleWidget* createXMLConsoleWidget(); virtual MainWindow* createMainWindow(UIEventStream* eventStream); virtual LoginWindow* createLoginWindow(UIEventStream* eventStream); virtual EventWindow* createEventWindow(); virtual ChatListWindow* createChatListWindow(UIEventStream*); virtual MUCSearchWindow* createMUCSearchWindow(); virtual ChatWindow* createChatWindow(const JID &contact, UIEventStream* eventStream); virtual UserSearchWindow* createUserSearchWindow(UserSearchWindow::Type type, UIEventStream* eventStream, const std::set<std::string>& groups); @@ -51,13 +52,14 @@ namespace Swift { SettingsProviderHierachy* settings; QtSettingsProvider* qtOnlySettings; QtChatTabs* tabs; QSplitter* netbookSplitter; QtSystemTray* systemTray; QtChatWindowFactory* chatWindowFactory; QtMainWindow* lastMainWindow; QtLoginWindow* loginWindow; std::vector<QPointer<QtChatWindow> > chatWindows; + TimerFactory* timerFactory_; bool startMinimized; int chatFontSize; }; } diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript index 8d7697a..0622cc6 100644 --- a/Swift/QtUI/SConscript +++ b/Swift/QtUI/SConscript @@ -34,19 +34,20 @@ myenv.UseFlags(env["SWIFTEN_DEP_FLAGS"]) if myenv.get("HAVE_GROWL", False) : myenv.UseFlags(myenv["GROWL_FLAGS"]) myenv.Append(CPPDEFINES = ["HAVE_GROWL"]) if myenv["swift_mobile"] : myenv.Append(CPPDEFINES = ["SWIFT_MOBILE"]) if myenv.get("HAVE_SNARL", False) : myenv.UseFlags(myenv["SNARL_FLAGS"]) myenv.Append(CPPDEFINES = ["HAVE_SNARL"]) if env["PLATFORM"] == "win32" : - myenv.Append(LIBS = ["cryptui"]) + myenv.Append(LIBS = ["cryptui"]) + myenv.Append(LIBS = ["Winscard"]) myenv.UseFlags(myenv["PLATFORM_FLAGS"]) myenv.Tool("qt4", toolpath = ["#/BuildTools/SCons/Tools"]) myenv.Tool("nsis", toolpath = ["#/BuildTools/SCons/Tools"]) myenv.Tool("wix", toolpath = ["#/BuildTools/SCons/Tools"]) qt4modules = ['QtCore', 'QtGui', 'QtWebKit'] if env["PLATFORM"] == "posix" : qt4modules += ["QtDBus"] myenv.EnableQt4Modules(qt4modules, debug = False) diff --git a/Swiften/TLS/CAPICertificate.cpp b/Swiften/TLS/CAPICertificate.cpp index 0dc3009..b33ebcf 100644 --- a/Swiften/TLS/CAPICertificate.cpp +++ b/Swiften/TLS/CAPICertificate.cpp @@ -1,49 +1,79 @@ /* * Copyright (c) 2012 Isode Limited, London, England. * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ #pragma once +#include <Swiften/Network/TimerFactory.h> #include <Swiften/TLS/CAPICertificate.h> #include <Swiften/StringCodecs/Hexify.h> +#include <boost/bind.hpp> #include <boost/algorithm/string/predicate.hpp> // Size of the SHA1 hash #define SHA1_HASH_LEN 20 namespace Swift { -CAPICertificate::CAPICertificate(const std::string& capiUri) - : valid_(false), uri_(capiUri), certStoreHandle_(0), certStore_(), certName_() { + +CAPICertificate::CAPICertificate(const std::string& capiUri, TimerFactory* timerFactory) + : valid_(false), + uri_(capiUri), + certStoreHandle_(0), + scardContext_(0), + cardHandle_(0), + certStore_(), + certName_(), + smartCardReaderName_(), + timerFactory_(timerFactory) { + setUri(capiUri); } CAPICertificate::~CAPICertificate() { + if (smartCardTimer_) { + smartCardTimer_->stop(); + smartCardTimer_->onTick.disconnect(boost::bind(&CAPICertificate::handleSmartCardTimerTick, this)); + smartCardTimer_.reset(); + } + if (certStoreHandle_) { CertCloseStore(certStoreHandle_, 0); } + + if (cardHandle_) { + (void) SCardDisconnect(cardHandle_, SCARD_LEAVE_CARD); + } + + if (scardContext_) { + SCardReleaseContext(scardContext_); + } } bool CAPICertificate::isNull() const { return uri_.empty() || !valid_; } const std::string& CAPICertificate::getCertStoreName() const { return certStore_; } const std::string& CAPICertificate::getCertName() const { return certName_; } +const std::string& CAPICertificate::getSmartCardReaderName() const { + return smartCardReaderName_; +} + PCCERT_CONTEXT findCertificateInStore (HCERTSTORE certStoreHandle, const std::string &certName) { PCCERT_CONTEXT pCertContext = NULL; if (!boost::iequals(certName.substr(0, 5), "sha1:")) { // Find client certificate. Note that this sample just searches for a // certificate that contains the user name somewhere in the subject name. pCertContext = CertFindCertificateInStore(certStoreHandle, X509_ASN_ENCODING, @@ -164,23 +194,173 @@ void CAPICertificate::setUri (const std::string& capiUri) { if (!CryptAcquireContextW(&hprov, pinfo->pwszContainerName, pinfo->pwszProvName, pinfo->dwProvType, 0)) { free(pinfo); return; } + + char smartcard_reader[1024]; + DWORD buflen; + + buflen = sizeof(smartcard_reader); + if (!CryptGetProvParam(hprov, PP_SMARTCARD_READER, (BYTE *)&smartcard_reader, &buflen, 0)) { + DWORD error; + + error = GetLastError(); + smartCardReaderName_ = ""; + } else { + LONG lRet; + + smartCardReaderName_ = smartcard_reader; + + lRet = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &scardContext_); + if (SCARD_S_SUCCESS == lRet) { + // Initiate monitoring for smartcard ejection + smartCardTimer_ = timerFactory_->createTimer(SMARTCARD_EJECTION_CHECK_FREQ); + } else { + ///Need to handle an error here + } + } + if (!CryptGetUserKey(hprov, pinfo->dwKeySpec, &key)) { CryptReleaseContext(hprov, 0); free(pinfo); return; } CryptDestroyKey(key); CryptReleaseContext(hprov, 0); free(pinfo); + if (smartCardTimer_) { + smartCardTimer_->onTick.connect(boost::bind(&CAPICertificate::handleSmartCardTimerTick, this)); + smartCardTimer_->start(); + } + valid_ = true; } +static void smartcard_check_status (SCARDCONTEXT hContext, + const char * pReader, + SCARDHANDLE hCardHandle, // Can be 0 on the first call + SCARDHANDLE * newCardHandle, // The handle returned + DWORD * pdwState) { + LONG lReturn; + DWORD dwAP; + char szReader[200]; + DWORD cch = sizeof(szReader); + BYTE bAttr[32]; + DWORD cByte = 32; + + if (hCardHandle == 0) { + lReturn = SCardConnect(hContext, + pReader, + SCARD_SHARE_SHARED, + SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, + &hCardHandle, + &dwAP); + if ( SCARD_S_SUCCESS != lReturn ) { + hCardHandle = 0; + if (SCARD_E_NO_SMARTCARD == lReturn || SCARD_W_REMOVED_CARD == lReturn) { + *pdwState = SCARD_ABSENT; + } else { + *pdwState = SCARD_UNKNOWN; + } + goto done; + } + } + + lReturn = SCardStatus(hCardHandle, + szReader, // Unfortunately we can't use NULL here + &cch, + pdwState, + NULL, + (LPBYTE)&bAttr, + &cByte); + + if ( SCARD_S_SUCCESS != lReturn ) { + if (SCARD_E_NO_SMARTCARD == lReturn || SCARD_W_REMOVED_CARD == lReturn) { + *pdwState = SCARD_ABSENT; + } else { + *pdwState = SCARD_UNKNOWN; + } + } + +done: + if (newCardHandle == NULL) { + (void) SCardDisconnect(hCardHandle, SCARD_LEAVE_CARD); + hCardHandle = 0; + } else { + *newCardHandle = hCardHandle; + } +} + +bool CAPICertificate::checkIfSmartCardPresent () { + + DWORD dwState; + + if (!smartCardReaderName_.empty()) { + smartcard_check_status (scardContext_, + smartCardReaderName_.c_str(), + cardHandle_, + &cardHandle_, + &dwState); +////DEBUG + switch ( dwState ) { + case SCARD_ABSENT: + printf("Card absent.\n"); + break; + case SCARD_PRESENT: + printf("Card present.\n"); + break; + case SCARD_SWALLOWED: + printf("Card swallowed.\n"); + break; + case SCARD_POWERED: + printf("Card has power.\n"); + break; + case SCARD_NEGOTIABLE: + printf("Card reset and waiting PTS negotiation.\n"); + break; + case SCARD_SPECIFIC: + printf("Card has specific communication protocols set.\n"); + break; + default: + printf("Unknown or unexpected card state.\n"); + break; + } + + + + switch ( dwState ) { + case SCARD_ABSENT: + return false; + + case SCARD_PRESENT: + case SCARD_SWALLOWED: + case SCARD_POWERED: + case SCARD_NEGOTIABLE: + case SCARD_SPECIFIC: + return true; + + default: + return false; + } + } else { + return false; + } +} + +void CAPICertificate::handleSmartCardTimerTick() { + + if (checkIfSmartCardPresent() == false) { + smartCardTimer_->stop(); + onCertificateCardRemoved(); + } else { + smartCardTimer_->start(); + } +} + } diff --git a/Swiften/TLS/CAPICertificate.h b/Swiften/TLS/CAPICertificate.h index 4204a6b..c8c00fe 100644 --- a/Swiften/TLS/CAPICertificate.h +++ b/Swiften/TLS/CAPICertificate.h @@ -1,45 +1,68 @@ /* * Copyright (c) 2012 Isode Limited, London, England. * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ #pragma once +#include <Swiften/Base/boost_bsignals.h> #include <Swiften/Base/SafeByteArray.h> #include <Swiften/TLS/CertificateWithKey.h> +#include <Swiften/Network/Timer.h> #define SECURITY_WIN32 #include <Windows.h> #include <WinCrypt.h> +#include <Winscard.h> + +/* In ms */ +#define SMARTCARD_EJECTION_CHECK_FREQ 1000 namespace Swift { + class TimerFactory; + class CAPICertificate : public Swift::CertificateWithKey { public: - CAPICertificate(const std::string& capiUri); +////Allow timerFactory to be NULL? + CAPICertificate(const std::string& capiUri, TimerFactory* timerFactory); virtual ~CAPICertificate(); virtual bool isNull() const; const std::string& getCertStoreName() const; const std::string& getCertName() const; + const std::string& getSmartCardReaderName() const; + + public: + boost::signal<void ()> onCertificateCardRemoved; + private: void setUri (const std::string& capiUri); + void handleSmartCardTimerTick(); + + bool checkIfSmartCardPresent(); + private: bool valid_; std::string uri_; HCERTSTORE certStoreHandle_; + SCARDCONTEXT scardContext_; + SCARDHANDLE cardHandle_; /* Parsed components of the uri_ */ std::string certStore_; std::string certName_; + std::string smartCardReaderName_; + boost::shared_ptr<Timer> smartCardTimer_; + TimerFactory* timerFactory_; }; PCCERT_CONTEXT findCertificateInStore (HCERTSTORE certStoreHandle, const std::string &certName); } diff --git a/Swiften/TLS/Schannel/SchannelContext.cpp b/Swiften/TLS/Schannel/SchannelContext.cpp index 4f8f36f..8e952ea 100644 --- a/Swiften/TLS/Schannel/SchannelContext.cpp +++ b/Swiften/TLS/Schannel/SchannelContext.cpp @@ -1,30 +1,33 @@ /* * Copyright (c) 2011 Soren Dreijer * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ -#include "Swiften/TLS/Schannel/SchannelContext.h" -#include "Swiften/TLS/Schannel/SchannelCertificate.h" +#include <boost/bind.hpp> + +#include <Swiften/TLS/Schannel/SchannelContext.h> +#include <Swiften/TLS/Schannel/SchannelCertificate.h> #include <Swiften/TLS/CAPICertificate.h> #include <WinHTTP.h> // For SECURITY_FLAG_IGNORE_CERT_CN_INVALID namespace Swift { //------------------------------------------------------------------------ SchannelContext::SchannelContext() : m_state(Start) , m_secContext(0) , m_my_cert_store(NULL) , m_cert_store_name("MY") , m_cert_name() +, m_smartcard_reader() { m_ctxtFlags = ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_CONFIDENTIALITY | ISC_REQ_EXTENDED_ERROR | ISC_REQ_INTEGRITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_USE_SUPPLIED_CREDS | ISC_REQ_STREAM; @@ -633,22 +636,33 @@ bool SchannelContext::setClientCertificate(CertificateWithKey::ref certificate) boost::shared_ptr<CAPICertificate> capiCertificate = boost::dynamic_pointer_cast<CAPICertificate>(certificate); if (!capiCertificate || capiCertificate->isNull()) { return false; } // We assume that the Certificate Store Name/Certificate Name // are valid at this point m_cert_store_name = capiCertificate->getCertStoreName(); m_cert_name = capiCertificate->getCertName(); +////At the moment this is only useful for logging: + m_smartcard_reader = capiCertificate->getSmartCardReaderName(); + + capiCertificate->onCertificateCardRemoved.connect(boost::bind(&SchannelContext::handleCertificateCardRemoved, this)); + return true; } //------------------------------------------------------------------------ +void SchannelContext::handleCertificateCardRemoved() { + //ToDo: Might want to log the reason ("certificate card ejected") + indicateError(); +} + +//------------------------------------------------------------------------ Certificate::ref SchannelContext::getPeerCertificate() const { SchannelCertificate::ref pCertificate; ScopedCertContext pServerCert; SECURITY_STATUS status = QueryContextAttributes(m_ctxtHandle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, pServerCert.Reset()); if (status != SEC_E_OK) return pCertificate; diff --git a/Swiften/TLS/Schannel/SchannelContext.h b/Swiften/TLS/Schannel/SchannelContext.h index 70b0694..bce7415 100644 --- a/Swiften/TLS/Schannel/SchannelContext.h +++ b/Swiften/TLS/Schannel/SchannelContext.h @@ -4,19 +4,19 @@ * See Documentation/Licenses/BSD-simplified.txt for more information. */ #pragma once #include "Swiften/Base/boost_bsignals.h" #include "Swiften/TLS/TLSContext.h" #include "Swiften/TLS/Schannel/SchannelUtil.h" -#include <Swiften/TLS/CertificateWithKey.h> +#include "Swiften/TLS/CertificateWithKey.h" #include "Swiften/Base/ByteArray.h" #define SECURITY_WIN32 #include <Windows.h> #include <Schannel.h> #include <security.h> #include <schnlsp.h> #include <boost/noncopyable.hpp> @@ -56,18 +56,20 @@ namespace Swift void sendDataOnNetwork(const void* pData, size_t dataSize); void forwardDataToApplication(const void* pData, size_t dataSize); void decryptAndProcessData(const SafeByteArray& data); void encryptAndSendData(const SafeByteArray& data); void appendNewData(const SafeByteArray& data); SECURITY_STATUS validateServerCertificate(); + void handleCertificateCardRemoved(); + private: enum SchannelState { Start, Connecting, Connected, Error }; @@ -80,11 +82,13 @@ namespace Swift ScopedCtxtHandle m_ctxtHandle; DWORD m_ctxtFlags; SecPkgContext_StreamSizes m_streamSizes; std::vector<char> m_receivedData; HCERTSTORE m_my_cert_store; std::string m_cert_store_name; std::string m_cert_name; +////Not needed, most likely + std::string m_smartcard_reader; //Can be empty string for non SmartCard certificates }; } |