diff options
| -rw-r--r-- | Swiften/Client/ClientOptions.h | 7 | ||||
| -rw-r--r-- | Swiften/Client/ClientSession.cpp | 41 | ||||
| -rw-r--r-- | Swiften/Client/ClientSession.h | 14 | ||||
| -rw-r--r-- | Swiften/Client/CoreClient.cpp | 2 | ||||
| -rw-r--r-- | Swiften/SASL/WindowsGSSAPIClientAuthenticator.cpp | 5 | ||||
| -rw-r--r-- | Swiften/SASL/WindowsGSSAPIClientAuthenticator.h | 2 |
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 | |||
| @@ -36,10 +36,11 @@ namespace Swift { | |||
| 36 | useTLS(UseTLSWhenAvailable), | 36 | useTLS(UseTLSWhenAvailable), |
| 37 | allowPLAINWithoutTLS(false), | 37 | allowPLAINWithoutTLS(false), |
| 38 | useStreamResumption(false), | 38 | useStreamResumption(false), |
| 39 | forgetPassword(false), | 39 | forgetPassword(false), |
| 40 | useAcks(true), | 40 | useAcks(true), |
| 41 | singleSignOn(false), | ||
| 41 | manualHostname(""), | 42 | manualHostname(""), |
| 42 | manualPort(-1), | 43 | manualPort(-1), |
| 43 | proxyType(SystemConfiguredProxy), | 44 | proxyType(SystemConfiguredProxy), |
| 44 | manualProxyHostname(""), | 45 | manualProxyHostname(""), |
| 45 | manualProxyPort(-1), | 46 | manualProxyPort(-1), |
| @@ -91,10 +92,16 @@ namespace Swift { | |||
| 91 | * Default: true | 92 | * Default: true |
| 92 | */ | 93 | */ |
| 93 | bool useAcks; | 94 | bool useAcks; |
| 94 | 95 | ||
| 95 | /** | 96 | /** |
| 97 | * Use Single Sign On. | ||
| 98 | * Default: false | ||
| 99 | */ | ||
| 100 | bool singleSignOn; | ||
| 101 | |||
| 102 | /** | ||
| 96 | * The hostname to connect to. | 103 | * The hostname to connect to. |
| 97 | * Leave this empty for standard XMPP connection, based on the JID domain. | 104 | * Leave this empty for standard XMPP connection, based on the JID domain. |
| 98 | */ | 105 | */ |
| 99 | std::string manualHostname; | 106 | std::string manualHostname; |
| 100 | 107 | ||
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())) { |
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 | |||
| @@ -124,10 +124,22 @@ namespace Swift { | |||
| 124 | 124 | ||
| 125 | void setCertificateTrustChecker(CertificateTrustChecker* checker) { | 125 | void setCertificateTrustChecker(CertificateTrustChecker* checker) { |
| 126 | certificateTrustChecker = checker; | 126 | certificateTrustChecker = checker; |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | void setSingleSignOn(bool b) { | ||
| 130 | singleSignOn = b; | ||
| 131 | } | ||
| 132 | |||
| 133 | /** | ||
| 134 | * Sets the port number used in Kerberos authentication | ||
| 135 | * Does not affect network connectivity. | ||
| 136 | */ | ||
| 137 | void setAuthenticationPort(int i) { | ||
| 138 | authenticationPort = i; | ||
| 139 | } | ||
| 140 | |||
| 129 | public: | 141 | public: |
| 130 | boost::signal<void ()> onNeedCredentials; | 142 | boost::signal<void ()> onNeedCredentials; |
| 131 | boost::signal<void ()> onInitialized; | 143 | boost::signal<void ()> onInitialized; |
| 132 | boost::signal<void (boost::shared_ptr<Swift::Error>)> onFinished; | 144 | boost::signal<void (boost::shared_ptr<Swift::Error>)> onFinished; |
| 133 | boost::signal<void (boost::shared_ptr<Stanza>)> onStanzaReceived; | 145 | boost::signal<void (boost::shared_ptr<Stanza>)> onStanzaReceived; |
| @@ -181,7 +193,9 @@ namespace Swift { | |||
| 181 | ClientAuthenticator* authenticator; | 193 | ClientAuthenticator* authenticator; |
| 182 | boost::shared_ptr<StanzaAckRequester> stanzaAckRequester_; | 194 | boost::shared_ptr<StanzaAckRequester> stanzaAckRequester_; |
| 183 | boost::shared_ptr<StanzaAckResponder> stanzaAckResponder_; | 195 | boost::shared_ptr<StanzaAckResponder> stanzaAckResponder_; |
| 184 | boost::shared_ptr<Swift::Error> error_; | 196 | boost::shared_ptr<Swift::Error> error_; |
| 185 | CertificateTrustChecker* certificateTrustChecker; | 197 | CertificateTrustChecker* certificateTrustChecker; |
| 198 | bool singleSignOn; | ||
| 199 | int authenticationPort; | ||
| 186 | }; | 200 | }; |
| 187 | } | 201 | } |
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 | |||
| @@ -150,10 +150,12 @@ void CoreClient::connect(const ClientOptions& o) { | |||
| 150 | void CoreClient::bindSessionToStream() { | 150 | void CoreClient::bindSessionToStream() { |
| 151 | session_ = ClientSession::create(jid_, sessionStream_, networkFactories->getIDNConverter(), networkFactories->getCryptoProvider()); | 151 | session_ = ClientSession::create(jid_, sessionStream_, networkFactories->getIDNConverter(), networkFactories->getCryptoProvider()); |
| 152 | session_->setCertificateTrustChecker(certificateTrustChecker); | 152 | session_->setCertificateTrustChecker(certificateTrustChecker); |
| 153 | session_->setUseStreamCompression(options.useStreamCompression); | 153 | session_->setUseStreamCompression(options.useStreamCompression); |
| 154 | session_->setAllowPLAINOverNonTLS(options.allowPLAINWithoutTLS); | 154 | session_->setAllowPLAINOverNonTLS(options.allowPLAINWithoutTLS); |
| 155 | session_->setSingleSignOn(options.singleSignOn); | ||
| 156 | session_->setAuthenticationPort(options.manualPort); | ||
| 155 | switch(options.useTLS) { | 157 | switch(options.useTLS) { |
| 156 | case ClientOptions::UseTLSWhenAvailable: | 158 | case ClientOptions::UseTLSWhenAvailable: |
| 157 | session_->setUseTLS(ClientSession::UseTLSWhenAvailable); | 159 | session_->setUseTLS(ClientSession::UseTLSWhenAvailable); |
| 158 | break; | 160 | break; |
| 159 | case ClientOptions::NeverUseTLS: | 161 | case ClientOptions::NeverUseTLS: |
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 | |||
| @@ -12,13 +12,16 @@ | |||
| 12 | 12 | ||
| 13 | #define SECURITY_LAYER_NONE 1 | 13 | #define SECURITY_LAYER_NONE 1 |
| 14 | 14 | ||
| 15 | namespace Swift { | 15 | namespace Swift { |
| 16 | 16 | ||
| 17 | WindowsGSSAPIClientAuthenticator::WindowsGSSAPIClientAuthenticator(const std::string& hostname, const std::string& domainname) : ClientAuthenticator("GSSAPI"), step_(BuildingSecurityContext), error_(false), haveCredentialsHandle_(false), haveContextHandle_(false), haveCompleteContext_(false) { | 17 | WindowsGSSAPIClientAuthenticator::WindowsGSSAPIClientAuthenticator(const std::string& hostname, const std::string& domainname, int port) : ClientAuthenticator("GSSAPI"), step_(BuildingSecurityContext), error_(false), haveCredentialsHandle_(false), haveContextHandle_(false), haveCompleteContext_(false) { |
| 18 | WindowsServicePrincipalName servicePrincipalName(domainname); | 18 | WindowsServicePrincipalName servicePrincipalName(domainname); |
| 19 | servicePrincipalName.setInstanceName(hostname); | 19 | servicePrincipalName.setInstanceName(hostname); |
| 20 | if ((port != -1) && (port != 5222)) { | ||
| 21 | servicePrincipalName.setInstancePort(port); | ||
| 22 | } | ||
| 20 | servicePrincipalNameString_ = servicePrincipalName.toString(); | 23 | servicePrincipalNameString_ = servicePrincipalName.toString(); |
| 21 | 24 | ||
| 22 | errorCode_ = acquireCredentialsHandle(&credentialsHandle_); | 25 | errorCode_ = acquireCredentialsHandle(&credentialsHandle_); |
| 23 | if (isError()) { | 26 | if (isError()) { |
| 24 | return; | 27 | return; |
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 | |||
| @@ -18,11 +18,11 @@ | |||
| 18 | #include <Swiften/SASL/ClientAuthenticator.h> | 18 | #include <Swiften/SASL/ClientAuthenticator.h> |
| 19 | 19 | ||
| 20 | namespace Swift { | 20 | namespace Swift { |
| 21 | class SWIFTEN_API WindowsGSSAPIClientAuthenticator : public ClientAuthenticator { | 21 | class SWIFTEN_API WindowsGSSAPIClientAuthenticator : public ClientAuthenticator { |
| 22 | public: | 22 | public: |
| 23 | WindowsGSSAPIClientAuthenticator(const std::string& hostname, const std::string& domainname); | 23 | WindowsGSSAPIClientAuthenticator(const std::string& hostname, const std::string& domainname, int port); |
| 24 | 24 | ||
| 25 | ~WindowsGSSAPIClientAuthenticator(); | 25 | ~WindowsGSSAPIClientAuthenticator(); |
| 26 | 26 | ||
| 27 | virtual boost::optional<SafeByteArray> getResponse() const; | 27 | virtual boost::optional<SafeByteArray> getResponse() const; |
| 28 | virtual bool setChallenge(const boost::optional<std::vector<unsigned char> >&); | 28 | virtual bool setChallenge(const boost::optional<std::vector<unsigned char> >&); |
Swift