diff options
Diffstat (limited to 'Swiften/Client/ClientSession.cpp')
-rw-r--r-- | Swiften/Client/ClientSession.cpp | 41 |
1 files changed, 39 insertions, 2 deletions
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,8 +1,8 @@ /* - * Copyright (c) 2010-2014 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swiften/Client/ClientSession.h> @@ -44,12 +44,13 @@ #include <Swiften/Session/SessionStream.h> #include <Swiften/TLS/CertificateTrustChecker.h> #include <Swiften/TLS/ServerIdentityVerifier.h> #ifdef SWIFTEN_PLATFORM_WIN32 #include <Swiften/Base/WindowsRegistry.h> +#include <Swiften/SASL/WindowsGSSAPIClientAuthenticator.h> #endif #define CHECK_STATE_OR_RETURN(a) \ if (!checkState(a)) { return; } namespace Swift { @@ -70,13 +71,15 @@ ClientSession::ClientSession( useAcks(true), needSessionStart(false), needResourceBind(false), 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; } #endif } @@ -201,12 +204,38 @@ void ClientSession::handleElement(boost::shared_ptr<ToplevelElement> element) { } else if (useStreamCompression && stream->supportsZLibCompression() && streamFeatures->hasCompressionMethod("zlib")) { state = Compressing; 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(); state = Authenticating; stream->writeElement(boost::make_shared<AuthRequest>("EXTERNAL", createSafeByteArray(""))); } @@ -295,12 +324,20 @@ void ClientSession::handleElement(boost::shared_ptr<ToplevelElement> element) { else if (AuthChallenge* challenge = dynamic_cast<AuthChallenge*>(element.get())) { CHECK_STATE_OR_RETURN(Authenticating); assert(authenticator); 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); } } else if (AuthSuccess* authSuccess = dynamic_cast<AuthSuccess*>(element.get())) { CHECK_STATE_OR_RETURN(Authenticating); |