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
@@ -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
78if (WindowsRegistry::isFIPSEnabled()) { 81if (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) {
150void CoreClient::bindSessionToStream() { 150void 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
15namespace Swift { 15namespace Swift {
16 16
17WindowsGSSAPIClientAuthenticator::WindowsGSSAPIClientAuthenticator(const std::string& hostname, const std::string& domainname) : ClientAuthenticator("GSSAPI"), step_(BuildingSecurityContext), error_(false), haveCredentialsHandle_(false), haveContextHandle_(false), haveCompleteContext_(false) { 17WindowsGSSAPIClientAuthenticator::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
20namespace Swift { 20namespace 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> >&);