summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Swiften/Client/ClientOptions.h7
-rw-r--r--Swiften/Client/ClientSession.cpp41
-rw-r--r--Swiften/Client/ClientSession.h14
-rw-r--r--Swiften/Client/CoreClient.cpp2
-rw-r--r--Swiften/SASL/WindowsGSSAPIClientAuthenticator.cpp5
-rw-r--r--Swiften/SASL/WindowsGSSAPIClientAuthenticator.h2
6 files changed, 67 insertions, 4 deletions
diff --git a/Swiften/Client/ClientOptions.h b/Swiften/Client/ClientOptions.h
index 25393e4..c09b987 100644
--- a/Swiften/Client/ClientOptions.h
+++ b/Swiften/Client/ClientOptions.h
@@ -38,6 +38,7 @@ namespace Swift {
useStreamResumption(false),
forgetPassword(false),
useAcks(true),
+ singleSignOn(false),
manualHostname(""),
manualPort(-1),
proxyType(SystemConfiguredProxy),
@@ -93,6 +94,12 @@ namespace Swift {
bool useAcks;
/**
+ * Use Single Sign On.
+ * Default: false
+ */
+ bool singleSignOn;
+
+ /**
* The hostname to connect to.
* Leave this empty for standard XMPP connection, based on the JID domain.
*/
diff --git a/Swiften/Client/ClientSession.cpp b/Swiften/Client/ClientSession.cpp
index 26b89c4..52b8cfb 100644
--- a/Swiften/Client/ClientSession.cpp
+++ b/Swiften/Client/ClientSession.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2015 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -47,6 +47,7 @@
#ifdef SWIFTEN_PLATFORM_WIN32
#include <Swiften/Base/WindowsRegistry.h>
+#include <Swiften/SASL/WindowsGSSAPIClientAuthenticator.h>
#endif
#define CHECK_STATE_OR_RETURN(a) \
@@ -73,7 +74,9 @@ ClientSession::ClientSession(
needAcking(false),
rosterVersioningSupported(false),
authenticator(NULL),
- certificateTrustChecker(NULL) {
+ certificateTrustChecker(NULL),
+ singleSignOn(false),
+ authenticationPort(-1) {
#ifdef SWIFTEN_PLATFORM_WIN32
if (WindowsRegistry::isFIPSEnabled()) {
SWIFT_LOG(info) << "Windows is running in FIPS-140 mode. Some authentication methods will be unavailable." << std::endl;
@@ -204,6 +207,32 @@ void ClientSession::handleElement(boost::shared_ptr<ToplevelElement> element) {
stream->writeElement(boost::make_shared<CompressRequest>("zlib"));
}
else if (streamFeatures->hasAuthenticationMechanisms()) {
+#ifdef SWIFTEN_PLATFORM_WIN32
+ if (singleSignOn) {
+ const boost::optional<std::string> authenticationHostname = streamFeatures->getAuthenticationHostname();
+ bool gssapiSupported = streamFeatures->hasAuthenticationMechanism("GSSAPI") && authenticationHostname && !authenticationHostname->empty();
+
+ if (!gssapiSupported) {
+ finishSession(Error::NoSupportedAuthMechanismsError);
+ }
+ else {
+ WindowsGSSAPIClientAuthenticator* gssapiAuthenticator = new WindowsGSSAPIClientAuthenticator(*authenticationHostname, localJID.getDomain(), authenticationPort);
+ boost::shared_ptr<Error> error = boost::make_shared<Error>(Error::AuthenticationFailedError);
+
+ authenticator = gssapiAuthenticator;
+
+ if (!gssapiAuthenticator->isError()) {
+ state = Authenticating;
+ stream->writeElement(boost::make_shared<AuthRequest>(authenticator->getName(), authenticator->getResponse()));
+ }
+ else {
+ error->errorCode = gssapiAuthenticator->getErrorCode();
+ finishSession(error);
+ }
+ }
+ }
+ else
+#endif
if (stream->hasTLSCertificate()) {
if (streamFeatures->hasAuthenticationMechanism("EXTERNAL")) {
authenticator = new EXTERNALClientAuthenticator();
@@ -298,6 +327,14 @@ void ClientSession::handleElement(boost::shared_ptr<ToplevelElement> element) {
if (authenticator->setChallenge(challenge->getValue())) {
stream->writeElement(boost::make_shared<AuthResponse>(authenticator->getResponse()));
}
+#ifdef SWIFTEN_PLATFORM_WIN32
+ else if (WindowsGSSAPIClientAuthenticator* gssapiAuthenticator = dynamic_cast<WindowsGSSAPIClientAuthenticator*>(authenticator)) {
+ boost::shared_ptr<Error> error = boost::make_shared<Error>(Error::AuthenticationFailedError);
+
+ error->errorCode = gssapiAuthenticator->getErrorCode();
+ finishSession(error);
+ }
+#endif
else {
finishSession(Error::AuthenticationFailedError);
}
diff --git a/Swiften/Client/ClientSession.h b/Swiften/Client/ClientSession.h
index 9bbc3f2..c4b6abe 100644
--- a/Swiften/Client/ClientSession.h
+++ b/Swiften/Client/ClientSession.h
@@ -126,6 +126,18 @@ namespace Swift {
certificateTrustChecker = checker;
}
+ void setSingleSignOn(bool b) {
+ singleSignOn = b;
+ }
+
+ /**
+ * Sets the port number used in Kerberos authentication
+ * Does not affect network connectivity.
+ */
+ void setAuthenticationPort(int i) {
+ authenticationPort = i;
+ }
+
public:
boost::signal<void ()> onNeedCredentials;
boost::signal<void ()> onInitialized;
@@ -183,5 +195,7 @@ namespace Swift {
boost::shared_ptr<StanzaAckResponder> stanzaAckResponder_;
boost::shared_ptr<Swift::Error> error_;
CertificateTrustChecker* certificateTrustChecker;
+ bool singleSignOn;
+ int authenticationPort;
};
}
diff --git a/Swiften/Client/CoreClient.cpp b/Swiften/Client/CoreClient.cpp
index baebd4a..b1a375b 100644
--- a/Swiften/Client/CoreClient.cpp
+++ b/Swiften/Client/CoreClient.cpp
@@ -152,6 +152,8 @@ void CoreClient::bindSessionToStream() {
session_->setCertificateTrustChecker(certificateTrustChecker);
session_->setUseStreamCompression(options.useStreamCompression);
session_->setAllowPLAINOverNonTLS(options.allowPLAINWithoutTLS);
+ session_->setSingleSignOn(options.singleSignOn);
+ session_->setAuthenticationPort(options.manualPort);
switch(options.useTLS) {
case ClientOptions::UseTLSWhenAvailable:
session_->setUseTLS(ClientSession::UseTLSWhenAvailable);
diff --git a/Swiften/SASL/WindowsGSSAPIClientAuthenticator.cpp b/Swiften/SASL/WindowsGSSAPIClientAuthenticator.cpp
index 7423243..f602bff 100644
--- a/Swiften/SASL/WindowsGSSAPIClientAuthenticator.cpp
+++ b/Swiften/SASL/WindowsGSSAPIClientAuthenticator.cpp
@@ -14,9 +14,12 @@
namespace Swift {
-WindowsGSSAPIClientAuthenticator::WindowsGSSAPIClientAuthenticator(const std::string& hostname, const std::string& domainname) : ClientAuthenticator("GSSAPI"), step_(BuildingSecurityContext), error_(false), haveCredentialsHandle_(false), haveContextHandle_(false), haveCompleteContext_(false) {
+WindowsGSSAPIClientAuthenticator::WindowsGSSAPIClientAuthenticator(const std::string& hostname, const std::string& domainname, int port) : ClientAuthenticator("GSSAPI"), step_(BuildingSecurityContext), error_(false), haveCredentialsHandle_(false), haveContextHandle_(false), haveCompleteContext_(false) {
WindowsServicePrincipalName servicePrincipalName(domainname);
servicePrincipalName.setInstanceName(hostname);
+ if ((port != -1) && (port != 5222)) {
+ servicePrincipalName.setInstancePort(port);
+ }
servicePrincipalNameString_ = servicePrincipalName.toString();
errorCode_ = acquireCredentialsHandle(&credentialsHandle_);
diff --git a/Swiften/SASL/WindowsGSSAPIClientAuthenticator.h b/Swiften/SASL/WindowsGSSAPIClientAuthenticator.h
index d046999..f772b71 100644
--- a/Swiften/SASL/WindowsGSSAPIClientAuthenticator.h
+++ b/Swiften/SASL/WindowsGSSAPIClientAuthenticator.h
@@ -20,7 +20,7 @@
namespace Swift {
class SWIFTEN_API WindowsGSSAPIClientAuthenticator : public ClientAuthenticator {
public:
- WindowsGSSAPIClientAuthenticator(const std::string& hostname, const std::string& domainname);
+ WindowsGSSAPIClientAuthenticator(const std::string& hostname, const std::string& domainname, int port);
~WindowsGSSAPIClientAuthenticator();