summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Swift/QtUI/QtLoginWindow.cpp4
-rw-r--r--Swift/QtUI/QtLoginWindow.h5
-rw-r--r--Swift/QtUI/QtSwift.cpp2
-rw-r--r--Swift/QtUI/QtUIFactory.cpp4
-rw-r--r--Swift/QtUI/QtUIFactory.h4
-rw-r--r--Swift/QtUI/SConscript3
-rw-r--r--Swiften/TLS/CAPICertificate.cpp184
-rw-r--r--Swiften/TLS/CAPICertificate.h25
-rw-r--r--Swiften/TLS/Schannel/SchannelContext.cpp18
-rw-r--r--Swiften/TLS/Schannel/SchannelContext.h6
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
};
}