summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Client/CoreClient.cpp')
-rw-r--r--Swiften/Client/CoreClient.cpp27
1 files changed, 26 insertions, 1 deletions
diff --git a/Swiften/Client/CoreClient.cpp b/Swiften/Client/CoreClient.cpp
index de12fb7..36bfe35 100644
--- a/Swiften/Client/CoreClient.cpp
+++ b/Swiften/Client/CoreClient.cpp
@@ -94,89 +94,114 @@ void CoreClient::connect(const std::string& host) {
networkFactories->getDomainNameResolver(),
host,
options.boshHTTPConnectProxyURL,
options.boshHTTPConnectProxyAuthID,
options.boshHTTPConnectProxyAuthPassword));
sessionStream_->onDataRead.connect(boost::bind(&CoreClient::handleDataRead, this, _1));
sessionStream_->onDataWritten.connect(boost::bind(&CoreClient::handleDataWritten, this, _1));
bindSessionToStream();
}
}
void CoreClient::bindSessionToStream() {
session_ = ClientSession::create(jid_, sessionStream_);
session_->setCertificateTrustChecker(certificateTrustChecker);
session_->setUseStreamCompression(options.useStreamCompression);
session_->setAllowPLAINOverNonTLS(options.allowPLAINWithoutTLS);
switch(options.useTLS) {
case ClientOptions::UseTLSWhenAvailable:
session_->setUseTLS(ClientSession::UseTLSWhenAvailable);
break;
case ClientOptions::NeverUseTLS:
session_->setUseTLS(ClientSession::NeverUseTLS);
break;
case ClientOptions::RequireTLS:
session_->setUseTLS(ClientSession::RequireTLS);
break;
}
session_->setUseAcks(options.useAcks);
stanzaChannel_->setSession(session_);
session_->onFinished.connect(boost::bind(&CoreClient::handleSessionFinished, this, _1));
session_->onNeedCredentials.connect(boost::bind(&CoreClient::handleNeedCredentials, this));
session_->start();
}
+bool CoreClient::isCAPIURI() {
+#ifdef HAVE_SCHANNEL
+ if (!boost::iequals(certificate_.substr(0, 10), "certstore:")) {
+ return false;
+ }
+
+ return true;
+
+#else
+ return false;
+#endif
+}
+
/**
* Only called for TCP sessions. BOSH is handled inside the BOSHSessionStream.
*/
void CoreClient::handleConnectorFinished(boost::shared_ptr<Connection> connection) {
resetConnector();
if (!connection) {
if (options.forgetPassword) {
purgePassword();
}
onDisconnected(disconnectRequested_ ? boost::optional<ClientError>() : boost::optional<ClientError>(ClientError::ConnectionError));
}
else {
assert(!connection_);
connection_ = connection;
assert(!sessionStream_);
sessionStream_ = boost::make_shared<BasicSessionStream>(ClientStreamType, connection_, getPayloadParserFactories(), getPayloadSerializers(), networkFactories->getTLSContextFactory(), networkFactories->getTimerFactory(), networkFactories->getXMLParserFactory());
if (!certificate_.empty()) {
- sessionStream_->setTLSCertificate(PKCS12Certificate(certificate_, password_));
+ CertificateWithKey* cert;
+
+#if defined(SWIFTEN_PLATFORM_WIN32)
+ if (isCAPIURI()) {
+ cert = new CAPICertificate(certificate_);
+ } else {
+ cert = new PKCS12Certificate(certificate_, password_);
+ }
+#else
+ cert = new PKCS12Certificate(certificate_, password_);
+#endif
+
+ sessionStream_->setTLSCertificate(cert);
}
sessionStream_->onDataRead.connect(boost::bind(&CoreClient::handleDataRead, this, _1));
sessionStream_->onDataWritten.connect(boost::bind(&CoreClient::handleDataWritten, this, _1));
bindSessionToStream();
}
}
void CoreClient::disconnect() {
// FIXME: We should be able to do without this boolean. We just have to make sure we can tell the difference between
// connector finishing without a connection due to an error or because of a disconnect.
disconnectRequested_ = true;
if (session_ && !session_->isFinished()) {
session_->finish();
}
else if (connector_) {
connector_->stop();
}
}
void CoreClient::setCertificate(const std::string& certificate) {
certificate_ = certificate;
}
void CoreClient::handleSessionFinished(boost::shared_ptr<Error> error) {
if (options.forgetPassword) {
purgePassword();
}
resetSession();
boost::optional<ClientError> actualError;
if (error) {
ClientError clientError;
if (boost::shared_ptr<ClientSession::Error> actualError = boost::dynamic_pointer_cast<ClientSession::Error>(error)) {
switch(actualError->type) {