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,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2010-2014 Isode Limited. | 2 | * Copyright (c) 2010-2015 Isode Limited. |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * See the COPYING file for more information. | 4 | * See the COPYING file for more information. |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #include <Swiften/Client/ClientSession.h> | 7 | #include <Swiften/Client/ClientSession.h> |
| @@ -45,10 +45,11 @@ | |||
| 45 | #include <Swiften/TLS/CertificateTrustChecker.h> | 45 | #include <Swiften/TLS/CertificateTrustChecker.h> |
| 46 | #include <Swiften/TLS/ServerIdentityVerifier.h> | 46 | #include <Swiften/TLS/ServerIdentityVerifier.h> |
| 47 | 47 | ||
| 48 | #ifdef SWIFTEN_PLATFORM_WIN32 | 48 | #ifdef SWIFTEN_PLATFORM_WIN32 |
| 49 | #include <Swiften/Base/WindowsRegistry.h> | 49 | #include <Swiften/Base/WindowsRegistry.h> |
| 50 | #include <Swiften/SASL/WindowsGSSAPIClientAuthenticator.h> | ||
| 50 | #endif | 51 | #endif |
| 51 | 52 | ||
| 52 | #define CHECK_STATE_OR_RETURN(a) \ | 53 | #define CHECK_STATE_OR_RETURN(a) \ |
| 53 | if (!checkState(a)) { return; } | 54 | if (!checkState(a)) { return; } |
| 54 | 55 | ||
| @@ -71,11 +72,13 @@ ClientSession::ClientSession( | |||
| 71 | needSessionStart(false), | 72 | needSessionStart(false), |
| 72 | needResourceBind(false), | 73 | needResourceBind(false), |
| 73 | needAcking(false), | 74 | needAcking(false), |
| 74 | rosterVersioningSupported(false), | 75 | rosterVersioningSupported(false), |
| 75 | authenticator(NULL), | 76 | authenticator(NULL), |
| 76 | certificateTrustChecker(NULL) { | 77 | certificateTrustChecker(NULL), |
| 78 | singleSignOn(false), | ||
| 79 | authenticationPort(-1) { | ||
| 77 | #ifdef SWIFTEN_PLATFORM_WIN32 | 80 | #ifdef SWIFTEN_PLATFORM_WIN32 |
| 78 | if (WindowsRegistry::isFIPSEnabled()) { | 81 | if (WindowsRegistry::isFIPSEnabled()) { |
| 79 | SWIFT_LOG(info) << "Windows is running in FIPS-140 mode. Some authentication methods will be unavailable." << std::endl; | 82 | SWIFT_LOG(info) << "Windows is running in FIPS-140 mode. Some authentication methods will be unavailable." << std::endl; |
| 80 | } | 83 | } |
| 81 | #endif | 84 | #endif |
| @@ -202,10 +205,36 @@ void ClientSession::handleElement(boost::shared_ptr<ToplevelElement> element) { | |||
| 202 | else if (useStreamCompression && stream->supportsZLibCompression() && streamFeatures->hasCompressionMethod("zlib")) { | 205 | else if (useStreamCompression && stream->supportsZLibCompression() && streamFeatures->hasCompressionMethod("zlib")) { |
| 203 | state = Compressing; | 206 | state = Compressing; |
| 204 | stream->writeElement(boost::make_shared<CompressRequest>("zlib")); | 207 | stream->writeElement(boost::make_shared<CompressRequest>("zlib")); |
| 205 | } | 208 | } |
| 206 | else if (streamFeatures->hasAuthenticationMechanisms()) { | 209 | else if (streamFeatures->hasAuthenticationMechanisms()) { |
| 210 | #ifdef SWIFTEN_PLATFORM_WIN32 | ||
| 211 | if (singleSignOn) { | ||
| 212 | const boost::optional<std::string> authenticationHostname = streamFeatures->getAuthenticationHostname(); | ||
| 213 | bool gssapiSupported = streamFeatures->hasAuthenticationMechanism("GSSAPI") && authenticationHostname && !authenticationHostname->empty(); | ||
| 214 | |||
| 215 | if (!gssapiSupported) { | ||
| 216 | finishSession(Error::NoSupportedAuthMechanismsError); | ||
| 217 | } | ||
| 218 | else { | ||
| 219 | WindowsGSSAPIClientAuthenticator* gssapiAuthenticator = new WindowsGSSAPIClientAuthenticator(*authenticationHostname, localJID.getDomain(), authenticationPort); | ||
| 220 | boost::shared_ptr<Error> error = boost::make_shared<Error>(Error::AuthenticationFailedError); | ||
| 221 | |||
| 222 | authenticator = gssapiAuthenticator; | ||
| 223 | |||
| 224 | if (!gssapiAuthenticator->isError()) { | ||
| 225 | state = Authenticating; | ||
| 226 | stream->writeElement(boost::make_shared<AuthRequest>(authenticator->getName(), authenticator->getResponse())); | ||
| 227 | } | ||
| 228 | else { | ||
| 229 | error->errorCode = gssapiAuthenticator->getErrorCode(); | ||
| 230 | finishSession(error); | ||
| 231 | } | ||
| 232 | } | ||
| 233 | } | ||
| 234 | else | ||
| 235 | #endif | ||
| 207 | if (stream->hasTLSCertificate()) { | 236 | if (stream->hasTLSCertificate()) { |
| 208 | if (streamFeatures->hasAuthenticationMechanism("EXTERNAL")) { | 237 | if (streamFeatures->hasAuthenticationMechanism("EXTERNAL")) { |
| 209 | authenticator = new EXTERNALClientAuthenticator(); | 238 | authenticator = new EXTERNALClientAuthenticator(); |
| 210 | state = Authenticating; | 239 | state = Authenticating; |
| 211 | stream->writeElement(boost::make_shared<AuthRequest>("EXTERNAL", createSafeByteArray(""))); | 240 | stream->writeElement(boost::make_shared<AuthRequest>("EXTERNAL", createSafeByteArray(""))); |
| @@ -296,10 +325,18 @@ void ClientSession::handleElement(boost::shared_ptr<ToplevelElement> element) { | |||
| 296 | CHECK_STATE_OR_RETURN(Authenticating); | 325 | CHECK_STATE_OR_RETURN(Authenticating); |
| 297 | assert(authenticator); | 326 | assert(authenticator); |
| 298 | if (authenticator->setChallenge(challenge->getValue())) { | 327 | if (authenticator->setChallenge(challenge->getValue())) { |
| 299 | stream->writeElement(boost::make_shared<AuthResponse>(authenticator->getResponse())); | 328 | stream->writeElement(boost::make_shared<AuthResponse>(authenticator->getResponse())); |
| 300 | } | 329 | } |
| 330 | #ifdef SWIFTEN_PLATFORM_WIN32 | ||
| 331 | else if (WindowsGSSAPIClientAuthenticator* gssapiAuthenticator = dynamic_cast<WindowsGSSAPIClientAuthenticator*>(authenticator)) { | ||
| 332 | boost::shared_ptr<Error> error = boost::make_shared<Error>(Error::AuthenticationFailedError); | ||
| 333 | |||
| 334 | error->errorCode = gssapiAuthenticator->getErrorCode(); | ||
| 335 | finishSession(error); | ||
| 336 | } | ||
| 337 | #endif | ||
| 301 | else { | 338 | else { |
| 302 | finishSession(Error::AuthenticationFailedError); | 339 | finishSession(Error::AuthenticationFailedError); |
| 303 | } | 340 | } |
| 304 | } | 341 | } |
| 305 | else if (AuthSuccess* authSuccess = dynamic_cast<AuthSuccess*>(element.get())) { | 342 | else if (AuthSuccess* authSuccess = dynamic_cast<AuthSuccess*>(element.get())) { |
Swift