summaryrefslogtreecommitdiffstats
path: root/net/http
diff options
context:
space:
mode:
authorcbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-08 14:56:56 +0000
committercbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-08 14:56:56 +0000
commit7da0b3399c137070e5e5b9403428c98f52b9e2c5 (patch)
tree44045ed03614d156f9cc49f9404a3f0820d67d8b /net/http
parent50ada2e97cc6f1c1e0f1bf7ee33ff64a0d28d79a (diff)
downloadchromium_src-7da0b3399c137070e5e5b9403428c98f52b9e2c5.zip
chromium_src-7da0b3399c137070e5e5b9403428c98f52b9e2c5.tar.gz
chromium_src-7da0b3399c137070e5e5b9403428c98f52b9e2c5.tar.bz2
Abstracted and moved common SSPI functionality.
The NTLM and Negotiate authentication schemes follow very similar code paths when using the SSPI API on Windows. BUG=29862 TEST=New unittest, plus manual NTLM Authentication testing. Review URL: http://codereview.chromium.org/505048 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35791 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/http')
-rw-r--r--net/http/http_auth_handler_ntlm_win.cc51
-rwxr-xr-xnet/http/http_auth_sspi_win.cc77
-rwxr-xr-xnet/http/http_auth_sspi_win.h47
-rwxr-xr-xnet/http/http_auth_sspi_win_unittest.cc26
4 files changed, 156 insertions, 45 deletions
diff --git a/net/http/http_auth_handler_ntlm_win.cc b/net/http/http_auth_handler_ntlm_win.cc
index 7970740..0f40236 100644
--- a/net/http/http_auth_handler_ntlm_win.cc
+++ b/net/http/http_auth_handler_ntlm_win.cc
@@ -13,6 +13,7 @@
#include "base/string_util.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
+#include "net/http/http_auth_sspi_win.h"
#pragma comment(lib, "secur32.lib")
@@ -43,52 +44,12 @@ HttpAuthHandlerNTLM::~HttpAuthHandlerNTLM() {
int HttpAuthHandlerNTLM::InitializeBeforeFirstChallenge() {
DCHECK_EQ("ntlm", scheme_) << "This is not ntlm scheme";
- SEC_WCHAR* package = NTLMSP_NAME;
- PSecPkgInfo pkg_info;
- SECURITY_STATUS status;
-
- // The following API call is required to get the maximum token length
- // for the scheme.
- // TODO(arindam): Move this (PSecPkgInfo) to a static function.
- status = QuerySecurityPackageInfo(package, &pkg_info);
- if (status != SEC_E_OK) {
- LOG(ERROR) << "Security package " << package << " not found";
- return ERR_UNEXPECTED;
+ int rv = DetermineMaxTokenLength(NTLMSP_NAME, &max_token_len_);
+ if (rv != OK) {
+ return rv;
}
- max_token_len_ = pkg_info->cbMaxToken;
- FreeContextBuffer(pkg_info);
-
- SEC_WINNT_AUTH_IDENTITY identity;
- identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
- identity.User =
- reinterpret_cast<USHORT*>(const_cast<wchar_t*>(username_.c_str()));
- identity.UserLength = username_.size();
- identity.Domain =
- reinterpret_cast<USHORT*>(const_cast<wchar_t*>(domain_.c_str()));
- identity.DomainLength = domain_.size();
- identity.Password =
- reinterpret_cast<USHORT*>(const_cast<wchar_t*>(password_.c_str()));
- identity.PasswordLength = password_.size();
-
- TimeStamp expiry; // Since the credentials handle doesn't expire, ignore
- // the expiration time.
-
- // Pass the username/password to get the credentials handle.
- // Note: If the 5th argument is NULL, it uses the default cached credentials
- // for the logged in user, which can be used for single sign-on.
- status = AcquireCredentialsHandle(NULL, // pszPrincipal
- package, // pszPackage
- SECPKG_CRED_OUTBOUND, // fCredentialUse
- NULL, // pvLogonID
- &identity, // pAuthData
- NULL, // pGetKeyFn (not used)
- NULL, // pvGetKeyArgument (not used)
- &cred_, // phCredential
- &expiry); // ptsExpiry
- if (status != SEC_E_OK)
- return ERR_UNEXPECTED;
-
- return OK;
+ rv = AcquireCredentials(NTLMSP_NAME, domain_, username_, password_, &cred_);
+ return rv;
}
int HttpAuthHandlerNTLM::GetNextToken(const void* in_token,
diff --git a/net/http/http_auth_sspi_win.cc b/net/http/http_auth_sspi_win.cc
new file mode 100755
index 0000000..ff3ec82
--- /dev/null
+++ b/net/http/http_auth_sspi_win.cc
@@ -0,0 +1,77 @@
+// Copyright (c) 2009 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_sspi_win.h"
+
+#include "base/logging.h"
+#include "net/base/net_errors.h"
+
+namespace net {
+
+void SplitDomainAndUser(const std::wstring& combined,
+ std::wstring* domain,
+ std::wstring* user) {
+ size_t backslash_idx = combined.find(L'\\');
+ if (backslash_idx == std::wstring::npos) {
+ domain->clear();
+ *user = combined;
+ } else {
+ *domain = combined.substr(0, backslash_idx);
+ *user = combined.substr(backslash_idx + 1);
+ }
+}
+
+int DetermineMaxTokenLength(const std::wstring& package,
+ ULONG* max_token_length) {
+ PSecPkgInfo pkg_info;
+ SECURITY_STATUS status = QuerySecurityPackageInfo(
+ const_cast<wchar_t *>(package.c_str()), &pkg_info);
+ if (status != SEC_E_OK) {
+ LOG(ERROR) << "Security package " << package << " not found";
+ return ERR_UNEXPECTED;
+ }
+ *max_token_length = pkg_info->cbMaxToken;
+ FreeContextBuffer(pkg_info);
+ return OK;
+}
+
+int AcquireCredentials(const SEC_WCHAR* package,
+ const std::wstring& domain,
+ const std::wstring& user,
+ const std::wstring& password,
+ CredHandle* cred) {
+ SEC_WINNT_AUTH_IDENTITY identity;
+ identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
+ identity.User =
+ reinterpret_cast<unsigned short*>(const_cast<wchar_t*>(user.c_str()));
+ identity.UserLength = user.size();
+ identity.Domain =
+ reinterpret_cast<unsigned short*>(const_cast<wchar_t*>(domain.c_str()));
+ identity.DomainLength = domain.size();
+ identity.Password =
+ reinterpret_cast<unsigned short*>(const_cast<wchar_t*>(password.c_str()));
+ identity.PasswordLength = password.size();
+
+ TimeStamp expiry;
+
+ // Pass the username/password to get the credentials handle.
+ // Note: If the 5th argument is NULL, it uses the default cached credentials
+ // for the logged in user, which can be used for single sign-on.
+ SECURITY_STATUS status = AcquireCredentialsHandle(
+ NULL, // pszPrincipal
+ const_cast<SEC_WCHAR*>(package), // pszPackage
+ SECPKG_CRED_OUTBOUND, // fCredentialUse
+ NULL, // pvLogonID
+ &identity, // pAuthData
+ NULL, // pGetKeyFn (not used)
+ NULL, // pvGetKeyArgument (not used)
+ cred, // phCredential
+ &expiry); // ptsExpiry
+
+ if (status != SEC_E_OK)
+ return ERR_UNEXPECTED;
+ return OK;
+}
+
+} // namespace net
diff --git a/net/http/http_auth_sspi_win.h b/net/http/http_auth_sspi_win.h
new file mode 100755
index 0000000..d58678b
--- /dev/null
+++ b/net/http/http_auth_sspi_win.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2009 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.
+
+// This file contains common routines used by NTLM and Negotiate authentication
+// using the SSPI API on Windows.
+
+#ifndef NET_HTTP_HTTP_AUTH_SSPI_WIN_H_
+#define NET_HTTP_HTTP_AUTH_SSPI_WIN_H_
+
+// security.h needs to be included for CredHandle. Unfortunately CredHandle
+// is a typedef and can't be forward declared.
+#define SECURITY_WIN32 1
+#include <windows.h>
+#include <security.h>
+
+#include <string>
+
+namespace net {
+
+// Splits |combined| into domain and username.
+// If |combined| is of form "FOO\bar", |domain| will contain "FOO" and |user|
+// will contain "bar".
+// If |combined| is of form "bar", |domain| will be empty and |user| will
+// contain "bar".
+// |domain| and |user| must be non-NULL.
+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.
+int DetermineMaxTokenLength(const std::wstring& package,
+ ULONG* max_token_length);
+
+// Acquire credentials for a user.
+int AcquireCredentials(const SEC_WCHAR* package,
+ const std::wstring& domain,
+ const std::wstring& user,
+ const std::wstring& password,
+ CredHandle* cred);
+} // namespace net
+
+#endif // NET_HTTP_HTTP_AUTH_SSPI_WIN_H_
+
diff --git a/net/http/http_auth_sspi_win_unittest.cc b/net/http/http_auth_sspi_win_unittest.cc
new file mode 100755
index 0000000..b421ca9
--- /dev/null
+++ b/net/http/http_auth_sspi_win_unittest.cc
@@ -0,0 +1,26 @@
+// Copyright (c) 2009 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 "base/basictypes.h"
+#include "net/http/http_auth_sspi_win.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+void MatchDomainUserAfterSplit(const std::wstring& combined,
+ const std::wstring& expected_domain,
+ const std::wstring& expected_user) {
+ std::wstring actual_domain;
+ std::wstring actual_user;
+ SplitDomainAndUser(combined, &actual_domain, &actual_user);
+ EXPECT_EQ(expected_domain, actual_domain);
+ EXPECT_EQ(expected_user, actual_user);
+}
+
+TEST(HttpAuthHandlerSspiWinTest, SplitUserAndDomain) {
+ MatchDomainUserAfterSplit(L"foobar", L"", L"foobar");
+ MatchDomainUserAfterSplit(L"FOO\\bar", L"FOO", L"bar");
+}
+
+} // namespace net