summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMili Verma <mili.verma@isode.com>2015-07-08 15:27:52 (GMT)
committerMili Verma <mili.verma@isode.com>2015-07-08 15:33:09 (GMT)
commit58bb58557368c520e8a9368fcacff8d22466e759 (patch)
treebfd8bb3b93ab771482fe46e1d558f4ad399bdaa1
parent0e6beadc1b4427e8ab5109e52872f99a5f85c3d8 (diff)
downloadswift-58bb58557368c520e8a9368fcacff8d22466e759.zip
swift-58bb58557368c520e8a9368fcacff8d22466e759.tar.bz2
Use GSSAPI when SSO is used
This patch uses the GSSAPI authenticator on Windows if the server advertises it and the client requests it. (The user is not able to request it in the UI yet) Also sends the manual port to the GSSAPI authenticator to construct the SPN if a non-default port is used. Test-information: Tested on Windows using WIP code. Tested both on TLS & without. Unit tests pass. Change-Id: I9a9ad9604fe084d5fb2003b7a91174a9512e2eec
-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 {
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),
@@ -93,6 +94,12 @@ namespace Swift {
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 */
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 @@
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 */
@@ -47,6 +47,7 @@
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) \
@@ -73,7 +74,9 @@ ClientSession::ClientSession(
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;
@@ -204,6 +207,32 @@ void ClientSession::handleElement(boost::shared_ptr<ToplevelElement> element) {
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();
@@ -298,6 +327,14 @@ void ClientSession::handleElement(boost::shared_ptr<ToplevelElement> element) {
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 }
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 {
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;
@@ -183,5 +195,7 @@ namespace Swift {
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
@@ -152,6 +152,8 @@ void CoreClient::bindSessionToStream() {
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);
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 @@
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_);
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 @@
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