summaryrefslogtreecommitdiffstats
path: root/net/http
diff options
context:
space:
mode:
authorcbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-22 16:41:01 +0000
committercbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-22 16:41:01 +0000
commit5b9eb6cd8f4428c4647e1546aa2461d0062e0301 (patch)
treed2ecf90ec66cfb7d1b6d3503f46973e9e4c381fe /net/http
parent74d1423427b9665b5506e8fdc285597358ed3cf6 (diff)
downloadchromium_src-5b9eb6cd8f4428c4647e1546aa2461d0062e0301.zip
chromium_src-5b9eb6cd8f4428c4647e1546aa2461d0062e0301.tar.gz
chromium_src-5b9eb6cd8f4428c4647e1546aa2461d0062e0301.tar.bz2
Validate that an SSPI scheme is supported before generating a handler.
When SSPI is used (for Windows builds), the NTLM and Negotiate handler factories determine the maximum token length the first time it is used. The SSPI call to determinine the maximum length also returns an error code if the scheme is unsupported. The factories remember if the scheme is unsupported and will not attempt to create any handlers. If the token length is found, it is remembered. If a different error occurs, don't create a handler this round, but try again in the future. BUG=None TEST=Manually used an incorrect auth scheme and validated that it worked. Working on a mock SSPI Library I can use for unit testing. Review URL: http://codereview.chromium.org/600129 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39600 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/http')
-rw-r--r--net/http/http_auth_handler_negotiate.cc15
-rw-r--r--net/http/http_auth_handler_negotiate.h10
-rw-r--r--net/http/http_auth_handler_negotiate_posix.cc6
-rw-r--r--net/http/http_auth_handler_negotiate_win.cc27
-rw-r--r--net/http/http_auth_handler_ntlm.cc20
-rw-r--r--net/http/http_auth_handler_ntlm.h11
-rw-r--r--net/http/http_auth_handler_ntlm_portable.cc20
-rw-r--r--net/http/http_auth_handler_ntlm_win.cc38
-rw-r--r--net/http/http_auth_sspi_win.cc15
-rw-r--r--net/http/http_auth_sspi_win.h21
10 files changed, 130 insertions, 53 deletions
diff --git a/net/http/http_auth_handler_negotiate.cc b/net/http/http_auth_handler_negotiate.cc
deleted file mode 100644
index 1e99c71..0000000
--- a/net/http/http_auth_handler_negotiate.cc
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/http/http_auth_handler_negotiate.h"
-
-namespace net {
-
-HttpAuthHandlerNegotiate::Factory::Factory() {
-}
-
-HttpAuthHandlerNegotiate::Factory::~Factory() {
-}
-
-} // namespace net
diff --git a/net/http/http_auth_handler_negotiate.h b/net/http/http_auth_handler_negotiate.h
index c8e5585..73b1240 100644
--- a/net/http/http_auth_handler_negotiate.h
+++ b/net/http/http_auth_handler_negotiate.h
@@ -34,9 +34,19 @@ class HttpAuthHandlerNegotiate : public HttpAuthHandler {
HttpAuth::Target target,
const GURL& origin,
scoped_refptr<HttpAuthHandler>* handler);
+ private:
+#if defined(OS_WIN)
+ ULONG max_token_length_;
+ bool first_creation_;
+ bool is_unsupported_;
+#endif // defined(OS_WIN)
};
+#if defined(OS_WIN)
+ explicit HttpAuthHandlerNegotiate(ULONG max_token_length);
+#else
HttpAuthHandlerNegotiate();
+#endif
virtual bool NeedsIdentity();
diff --git a/net/http/http_auth_handler_negotiate_posix.cc b/net/http/http_auth_handler_negotiate_posix.cc
index 40ab439..ab69267 100644
--- a/net/http/http_auth_handler_negotiate_posix.cc
+++ b/net/http/http_auth_handler_negotiate_posix.cc
@@ -61,6 +61,12 @@ int HttpAuthHandlerNegotiate::GenerateDefaultAuthToken(
return ERR_NOT_IMPLEMENTED;
}
+HttpAuthHandlerNegotiate::Factory::Factory() {
+}
+
+HttpAuthHandlerNegotiate::Factory::~Factory() {
+}
+
int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler(
HttpAuth::ChallengeTokenizer* challenge,
HttpAuth::Target target,
diff --git a/net/http/http_auth_handler_negotiate_win.cc b/net/http/http_auth_handler_negotiate_win.cc
index 917fc1d..bbd62a4 100644
--- a/net/http/http_auth_handler_negotiate_win.cc
+++ b/net/http/http_auth_handler_negotiate_win.cc
@@ -8,8 +8,8 @@
namespace net {
-HttpAuthHandlerNegotiate::HttpAuthHandlerNegotiate() :
- auth_sspi_("Negotiate", NEGOSSP_NAME) {
+HttpAuthHandlerNegotiate::HttpAuthHandlerNegotiate(ULONG max_token_length)
+ : auth_sspi_("Negotiate", NEGOSSP_NAME, max_token_length) {
}
HttpAuthHandlerNegotiate::~HttpAuthHandlerNegotiate() {
@@ -74,14 +74,35 @@ int HttpAuthHandlerNegotiate::GenerateDefaultAuthToken(
auth_token);
}
+HttpAuthHandlerNegotiate::Factory::Factory()
+ : max_token_length_(0),
+ first_creation_(true),
+ is_unsupported_(false) {
+}
+
+HttpAuthHandlerNegotiate::Factory::~Factory() {
+}
+
int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler(
HttpAuth::ChallengeTokenizer* challenge,
HttpAuth::Target target,
const GURL& origin,
scoped_refptr<HttpAuthHandler>* handler) {
+ if (is_unsupported_)
+ return ERR_UNSUPPORTED_AUTH_SCHEME;
+
+ if (max_token_length_ == 0) {
+ int rv = DetermineMaxTokenLength(NEGOSSP_NAME, &max_token_length_);
+ if (rv == ERR_UNSUPPORTED_AUTH_SCHEME)
+ is_unsupported_ = true;
+ if (rv != OK)
+ return rv;
+ }
+
// TODO(cbentzel): Move towards model of parsing in the factory
// method and only constructing when valid.
- scoped_refptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerNegotiate());
+ scoped_refptr<HttpAuthHandler> tmp_handler(
+ new HttpAuthHandlerNegotiate(max_token_length_));
if (!tmp_handler->InitFromChallenge(challenge, target, origin))
return ERR_INVALID_RESPONSE;
handler->swap(tmp_handler);
diff --git a/net/http/http_auth_handler_ntlm.cc b/net/http/http_auth_handler_ntlm.cc
index 1e0c3f0..c026b98 100644
--- a/net/http/http_auth_handler_ntlm.cc
+++ b/net/http/http_auth_handler_ntlm.cc
@@ -107,24 +107,4 @@ bool HttpAuthHandlerNTLM::ParseChallenge(
#endif // defined(NTLM_SSPI)
}
-HttpAuthHandlerNTLM::Factory::Factory() {
-}
-
-HttpAuthHandlerNTLM::Factory::~Factory() {
-}
-
-int HttpAuthHandlerNTLM::Factory::CreateAuthHandler(
- HttpAuth::ChallengeTokenizer* challenge,
- HttpAuth::Target target,
- const GURL& origin,
- scoped_refptr<HttpAuthHandler>* handler) {
- // TODO(cbentzel): Move towards model of parsing in the factory
- // method and only constructing when valid.
- scoped_refptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerNTLM());
- if (!tmp_handler->InitFromChallenge(challenge, target, origin))
- return ERR_INVALID_RESPONSE;
- handler->swap(tmp_handler);
- return OK;
-}
-
} // namespace net
diff --git a/net/http/http_auth_handler_ntlm.h b/net/http/http_auth_handler_ntlm.h
index 759d3a2..9e86e1e 100644
--- a/net/http/http_auth_handler_ntlm.h
+++ b/net/http/http_auth_handler_ntlm.h
@@ -43,6 +43,12 @@ class HttpAuthHandlerNTLM : public HttpAuthHandler {
HttpAuth::Target target,
const GURL& origin,
scoped_refptr<HttpAuthHandler>* handler);
+ private:
+#if defined(NTLM_SSPI)
+ ULONG max_token_length_;
+ bool first_creation_;
+ bool is_unsupported_;
+#endif // defined(NTLM_SSPI)
};
#if defined(NTLM_PORTABLE)
@@ -74,7 +80,12 @@ class HttpAuthHandlerNTLM : public HttpAuthHandler {
};
#endif
+#if defined(NTLM_PORTABLE)
HttpAuthHandlerNTLM();
+#endif
+#if defined(NTLM_SSPI)
+ HttpAuthHandlerNTLM(ULONG max_token_length);
+#endif
virtual bool NeedsIdentity();
diff --git a/net/http/http_auth_handler_ntlm_portable.cc b/net/http/http_auth_handler_ntlm_portable.cc
index 7fccfce..b6c7d32 100644
--- a/net/http/http_auth_handler_ntlm_portable.cc
+++ b/net/http/http_auth_handler_ntlm_portable.cc
@@ -719,4 +719,24 @@ int HttpAuthHandlerNTLM::GenerateDefaultAuthToken(
return ERR_NOT_IMPLEMENTED;
}
+HttpAuthHandlerNTLM::Factory::Factory() {
+}
+
+HttpAuthHandlerNTLM::Factory::~Factory() {
+}
+
+int HttpAuthHandlerNTLM::Factory::CreateAuthHandler(
+ HttpAuth::ChallengeTokenizer* challenge,
+ HttpAuth::Target target,
+ const GURL& origin,
+ scoped_refptr<HttpAuthHandler>* handler) {
+ // TODO(cbentzel): Move towards model of parsing in the factory
+ // method and only constructing when valid.
+ scoped_refptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerNTLM());
+ if (!tmp_handler->InitFromChallenge(challenge, target, origin))
+ return ERR_INVALID_RESPONSE;
+ handler->swap(tmp_handler);
+ return OK;
+}
+
} // namespace net
diff --git a/net/http/http_auth_handler_ntlm_win.cc b/net/http/http_auth_handler_ntlm_win.cc
index c096aaf..cf3b448 100644
--- a/net/http/http_auth_handler_ntlm_win.cc
+++ b/net/http/http_auth_handler_ntlm_win.cc
@@ -19,7 +19,8 @@
namespace net {
-HttpAuthHandlerNTLM::HttpAuthHandlerNTLM() : auth_sspi_("NTLM", NTLMSP_NAME) {
+HttpAuthHandlerNTLM::HttpAuthHandlerNTLM(ULONG max_token_length) :
+ auth_sspi_("NTLM", NTLMSP_NAME, max_token_length) {
}
HttpAuthHandlerNTLM::~HttpAuthHandlerNTLM() {
@@ -60,5 +61,40 @@ int HttpAuthHandlerNTLM::GenerateDefaultAuthToken(
auth_token);
}
+HttpAuthHandlerNTLM::Factory::Factory() :
+ max_token_length_(0),
+ first_creation_(true),
+ is_unsupported_(false) {
+}
+
+HttpAuthHandlerNTLM::Factory::~Factory() {
+}
+
+int HttpAuthHandlerNTLM::Factory::CreateAuthHandler(
+ HttpAuth::ChallengeTokenizer* challenge,
+ HttpAuth::Target target,
+ const GURL& origin,
+ scoped_refptr<HttpAuthHandler>* handler) {
+ if (is_unsupported_)
+ return ERR_UNSUPPORTED_AUTH_SCHEME;
+
+ if (max_token_length_ == 0) {
+ int rv = DetermineMaxTokenLength(NTLMSP_NAME, &max_token_length_);
+ if (rv == ERR_UNSUPPORTED_AUTH_SCHEME)
+ is_unsupported_ = true;
+ if (rv != OK)
+ return rv;
+ }
+
+ // TODO(cbentzel): Move towards model of parsing in the factory
+ // method and only constructing when valid.
+ scoped_refptr<HttpAuthHandler> tmp_handler(
+ new HttpAuthHandlerNTLM(max_token_length_));
+ if (!tmp_handler->InitFromChallenge(challenge, target, origin))
+ return ERR_INVALID_RESPONSE;
+ handler->swap(tmp_handler);
+ return OK;
+}
+
} // namespace net
diff --git a/net/http/http_auth_sspi_win.cc b/net/http/http_auth_sspi_win.cc
index d8a22c2..39d87af 100644
--- a/net/http/http_auth_sspi_win.cc
+++ b/net/http/http_auth_sspi_win.cc
@@ -98,10 +98,11 @@ int AcquireDefaultCredentials(const SEC_WCHAR* package, CredHandle* cred) {
} // anonymous namespace
HttpAuthSSPI::HttpAuthSSPI(const std::string& scheme,
- SEC_WCHAR* security_package)
+ SEC_WCHAR* security_package,
+ ULONG max_token_length)
: scheme_(scheme),
security_package_(security_package),
- max_token_length_(0) {
+ max_token_length_(max_token_length) {
SecInvalidateHandle(&cred_);
SecInvalidateHandle(&ctxt_);
}
@@ -196,11 +197,7 @@ int HttpAuthSSPI::GenerateAuthToken(const std::wstring* username,
int HttpAuthSSPI::OnFirstRound(const std::wstring* username,
const std::wstring* password) {
DCHECK((username == NULL) == (password == NULL));
-
- int rv = DetermineMaxTokenLength(security_package_, &max_token_length_);
- if (rv != OK)
- return rv;
-
+ int rv = OK;
if (username) {
std::wstring domain;
std::wstring user;
@@ -335,7 +332,7 @@ int DetermineMaxTokenLength(const std::wstring& package,
else
return ERR_UNEXPECTED;
}
- *max_token_length = pkg_info->cbMaxToken;
+ int token_length = pkg_info->cbMaxToken;
status = FreeContextBuffer(pkg_info);
if (status != SEC_E_OK) {
// The documentation at
@@ -347,8 +344,8 @@ int DetermineMaxTokenLength(const std::wstring& package,
<< status;
return ERR_UNEXPECTED;
}
+ *max_token_length = token_length;
return OK;
}
-
} // namespace net
diff --git a/net/http/http_auth_sspi_win.h b/net/http/http_auth_sspi_win.h
index 526e25b..186c65f 100644
--- a/net/http/http_auth_sspi_win.h
+++ b/net/http/http_auth_sspi_win.h
@@ -28,7 +28,8 @@ class ProxyInfo;
class HttpAuthSSPI {
public:
HttpAuthSSPI(const std::string& scheme,
- SEC_WCHAR* security_package);
+ SEC_WCHAR* security_package,
+ ULONG max_token_length);
~HttpAuthSSPI();
bool NeedsIdentity() const;
@@ -79,10 +80,20 @@ void SplitDomainAndUser(const std::wstring& combined,
std::wstring* domain,
std::wstring* user);
-// Determines the max token length for a particular SSPI package.
-// If the return value is not OK, than the value of max_token_length
-// is undefined.
-// |max_token_length| must be non-NULL.
+// Determines the maximum token length in bytes for a particular SSPI package.
+//
+// If the return value is OK, |*max_token_length| contains the maximum token
+// length in bytes.
+//
+// If the return value is ERR_INVALID_ARGUMENT, |max_token_length| is NULL.
+//
+// If the return value is ERR_UNSUPPORTED_AUTH_SCHEME, |package| is not an
+// known SSPI authentication scheme on this system. |*max_token_length| is not
+// changed.
+//
+// If the return value is ERR_UNEXPECTED, there was an unanticipated problem
+// in the underlying SSPI call. The details are logged, and |*max_token_length|
+// is not changed.
int DetermineMaxTokenLength(const std::wstring& package,
ULONG* max_token_length);