summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/base/net_error_list.h9
-rw-r--r--net/http/http_auth_cache_unittest.cc29
-rw-r--r--net/http/http_auth_handler.cc6
-rw-r--r--net/http/http_auth_handler.h33
-rw-r--r--net/http/http_auth_handler_basic.cc27
-rw-r--r--net/http/http_auth_handler_basic.h17
-rw-r--r--net/http/http_auth_handler_basic_unittest.cc15
-rw-r--r--net/http/http_auth_handler_digest.cc28
-rw-r--r--net/http/http_auth_handler_digest.h15
-rw-r--r--net/http/http_auth_handler_negotiate.h14
-rw-r--r--[-rwxr-xr-x]net/http/http_auth_handler_negotiate_posix.cc26
-rw-r--r--net/http/http_auth_handler_negotiate_win.cc44
-rw-r--r--[-rwxr-xr-x]net/http/http_auth_handler_ntlm.cc41
-rw-r--r--net/http/http_auth_handler_ntlm.h17
-rw-r--r--net/http/http_auth_handler_ntlm_portable.cc17
-rw-r--r--net/http/http_auth_handler_ntlm_win.cc25
-rw-r--r--net/http/http_auth_sspi_win.cc215
-rw-r--r--[-rwxr-xr-x]net/http/http_auth_sspi_win.h30
-rw-r--r--[-rwxr-xr-x]net/http/http_auth_unittest.cc0
-rw-r--r--net/http/http_network_transaction.cc19
-rw-r--r--net/socket_stream/socket_stream.cc15
21 files changed, 457 insertions, 185 deletions
diff --git a/net/base/net_error_list.h b/net/base/net_error_list.h
index 7c0c3de..6ea5457 100644
--- a/net/base/net_error_list.h
+++ b/net/base/net_error_list.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// 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.
@@ -305,6 +305,13 @@ NET_ERROR(NO_SUPPORTED_PROXIES, -336)
// There is a FLIP protocol framing error.
NET_ERROR(FLIP_PROTOCOL_ERROR, -337)
+// Credentials could not be estalished during HTTP Authentication.
+NET_ERROR(INVALID_AUTH_CREDENTIALS, -338)
+
+// An HTTP Authentication scheme was tried which is not supported on this
+// machine.
+NET_ERROR(UNSUPPORTED_AUTH_SCHEME, -339)
+
// The cache does not have the requested entry.
NET_ERROR(CACHE_MISS, -400)
diff --git a/net/http/http_auth_cache_unittest.cc b/net/http/http_auth_cache_unittest.cc
index 52fa5cd..b00e8d0 100644
--- a/net/http/http_auth_cache_unittest.cc
+++ b/net/http/http_auth_cache_unittest.cc
@@ -1,8 +1,9 @@
-// Copyright (c) 2008 The Chromium Authors. All rights reserved.
+// 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 "base/string_util.h"
+#include "net/base/net_errors.h"
#include "net/http/http_auth_cache.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -23,11 +24,20 @@ class MockAuthHandler : public HttpAuthHandler {
properties_ = 0;
}
- virtual std::string GenerateCredentials(const std::wstring&,
- const std::wstring&,
- const HttpRequestInfo*,
- const ProxyInfo*) {
- return "mock-credentials"; // Unused.
+ virtual int GenerateAuthToken(const std::wstring&,
+ const std::wstring&,
+ const HttpRequestInfo*,
+ const ProxyInfo*,
+ std::string* auth_token) {
+ *auth_token = "mock-credentials";
+ return OK;
+ }
+
+ virtual int GenerateDefaultAuthToken(const HttpRequestInfo*,
+ const ProxyInfo*,
+ std::string* auth_token) {
+ *auth_token = "mock-credentials";
+ return OK;
}
protected:
@@ -52,12 +62,12 @@ TEST(HttpAuthCacheTest, Basic) {
scoped_refptr<HttpAuthHandler> realm1_handler =
new MockAuthHandler("basic", "Realm1", HttpAuth::AUTH_SERVER);
cache.Add(origin, realm1_handler, L"realm1-user", L"realm1-password",
- "/foo/bar/index.html");
+ "/foo/bar/index.html");
scoped_refptr<HttpAuthHandler> realm2_handler =
new MockAuthHandler("basic", "Realm2", HttpAuth::AUTH_SERVER);
cache.Add(origin, realm2_handler, L"realm2-user", L"realm2-password",
- "/foo2/index.html");
+ "/foo2/index.html");
scoped_refptr<HttpAuthHandler> realm3_handler =
new MockAuthHandler("basic", "Realm3", HttpAuth::AUTH_PROXY);
@@ -227,7 +237,8 @@ class HttpAuthCacheEvictionTest : public testing::Test {
}
void AddPathToRealm(int realm_i, int path_i) {
- scoped_refptr<HttpAuthHandler> handler = new MockAuthHandler("basic",
+ scoped_refptr<HttpAuthHandler> handler = new MockAuthHandler(
+ "basic",
GenerateRealm(realm_i), HttpAuth::AUTH_SERVER);
std::string path = GeneratePath(realm_i, path_i);
cache_.Add(origin_, handler, L"username", L"password", path);
diff --git a/net/http/http_auth_handler.cc b/net/http/http_auth_handler.cc
index 9abdd9a..9d70ca0 100644
--- a/net/http/http_auth_handler.cc
+++ b/net/http/http_auth_handler.cc
@@ -1,10 +1,12 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// 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 "base/logging.h"
#include "net/http/http_auth_handler.h"
+#include "base/logging.h"
+#include "net/base/net_errors.h"
+
namespace net {
bool HttpAuthHandler::InitFromChallenge(std::string::const_iterator begin,
diff --git a/net/http/http_auth_handler.h b/net/http/http_auth_handler.h
index 02a410e..4b8f5261 100644
--- a/net/http/http_auth_handler.h
+++ b/net/http/http_auth_handler.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// 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.
@@ -72,11 +72,32 @@ class HttpAuthHandler : public base::RefCounted<HttpAuthHandler> {
// single-round schemes.
virtual bool IsFinalRound() { return true; }
- // Generate the Authorization header value.
- virtual std::string GenerateCredentials(const std::wstring& username,
- const std::wstring& password,
- const HttpRequestInfo* request,
- const ProxyInfo* proxy) = 0;
+ // Returns whether the default credentials may be used for the |origin| passed
+ // into |InitFromChallenge|. If true, the user does not need to be prompted
+ // for username and password to establish credentials.
+ virtual bool AllowDefaultCredentials() { return false; }
+
+ // TODO(cbentzel): Separate providing credentials from generating the
+ // authentication token in the API.
+
+ // Generates an authentication token.
+ // The return value is an error code. If the code is not |OK|, the value of
+ // |*auth_token| is unspecified.
+ // |auth_token| is a return value and must be non-NULL.
+ virtual int GenerateAuthToken(const std::wstring& username,
+ const std::wstring& password,
+ const HttpRequestInfo* request,
+ const ProxyInfo* proxy,
+ std::string* auth_token) = 0;
+
+ // Generates an authentication token using default credentials.
+ // The return value is an error code. If the code is not |OK|, the value of
+ // |*auth_token| is unspecified.
+ // |auth_token| is a return value and must be non-NULL.
+ // This should only be called after |AllowDefaultCredentials| returns true.
+ virtual int GenerateDefaultAuthToken(const HttpRequestInfo* request,
+ const ProxyInfo* proxy,
+ std::string* auth_token) = 0;
protected:
enum Property {
diff --git a/net/http/http_auth_handler_basic.cc b/net/http/http_auth_handler_basic.cc
index 71c310c..2c70577 100644
--- a/net/http/http_auth_handler_basic.cc
+++ b/net/http/http_auth_handler_basic.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// 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.
@@ -8,6 +8,7 @@
#include "base/base64.h"
#include "base/string_util.h"
+#include "net/base/net_errors.h"
#include "net/http/http_auth.h"
namespace net {
@@ -41,17 +42,31 @@ bool HttpAuthHandlerBasic::Init(std::string::const_iterator challenge_begin,
return challenge_tok.valid();
}
-std::string HttpAuthHandlerBasic::GenerateCredentials(
+int HttpAuthHandlerBasic::GenerateAuthToken(
const std::wstring& username,
const std::wstring& password,
const HttpRequestInfo*,
- const ProxyInfo*) {
+ const ProxyInfo*,
+ std::string* auth_token) {
// TODO(eroman): is this the right encoding of username/password?
std::string base64_username_password;
if (!base::Base64Encode(WideToUTF8(username) + ":" + WideToUTF8(password),
- &base64_username_password))
- return std::string(); // FAIL
- return std::string("Basic ") + base64_username_password;
+ &base64_username_password)) {
+ LOG(ERROR) << "Unexpected problem Base64 encoding.";
+ return ERR_UNEXPECTED;
+ }
+ *auth_token = "Basic " + base64_username_password;
+ return OK;
+}
+
+int HttpAuthHandlerBasic::GenerateDefaultAuthToken(
+ const HttpRequestInfo* request,
+ const ProxyInfo* proxy,
+ std::string* auth_token) {
+ NOTREACHED();
+ LOG(ERROR) << ErrorToString(ERR_NOT_IMPLEMENTED);
+ return ERR_NOT_IMPLEMENTED;
}
+
} // namespace net
diff --git a/net/http/http_auth_handler_basic.h b/net/http/http_auth_handler_basic.h
index 679c91a..e4d2f25 100644
--- a/net/http/http_auth_handler_basic.h
+++ b/net/http/http_auth_handler_basic.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// 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.
@@ -12,10 +12,17 @@ namespace net {
// Code for handling http basic authentication.
class HttpAuthHandlerBasic : public HttpAuthHandler {
public:
- virtual std::string GenerateCredentials(const std::wstring& username,
- const std::wstring& password,
- const HttpRequestInfo*,
- const ProxyInfo*);
+ virtual int GenerateAuthToken(const std::wstring& username,
+ const std::wstring& password,
+ const HttpRequestInfo*,
+ const ProxyInfo*,
+ std::string* auth_token);
+
+ virtual int GenerateDefaultAuthToken(const HttpRequestInfo* request,
+ const ProxyInfo* proxy,
+ std::string* auth_token);
+
+
protected:
virtual bool Init(std::string::const_iterator challenge_begin,
std::string::const_iterator challenge_end);
diff --git a/net/http/http_auth_handler_basic_unittest.cc b/net/http/http_auth_handler_basic_unittest.cc
index d7a1437..59d9a56 100644
--- a/net/http/http_auth_handler_basic_unittest.cc
+++ b/net/http/http_auth_handler_basic_unittest.cc
@@ -1,15 +1,16 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// 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 "testing/gtest/include/gtest/gtest.h"
#include "base/basictypes.h"
+#include "net/base/net_errors.h"
#include "net/http/http_auth_handler_basic.h"
namespace net {
-TEST(HttpAuthHandlerBasicTest, GenerateCredentials) {
+TEST(HttpAuthHandlerBasicTest, GenerateAuthToken) {
static const struct {
const wchar_t* username;
const wchar_t* password;
@@ -30,9 +31,13 @@ TEST(HttpAuthHandlerBasicTest, GenerateCredentials) {
bool ok = basic->InitFromChallenge(challenge.begin(), challenge.end(),
HttpAuth::AUTH_SERVER, origin);
EXPECT_TRUE(ok);
- std::string credentials = basic->GenerateCredentials(tests[i].username,
- tests[i].password,
- NULL, NULL);
+ std::string credentials;
+ int rv = basic->GenerateAuthToken(tests[i].username,
+ tests[i].password,
+ NULL,
+ NULL,
+ &credentials);
+ EXPECT_EQ(OK, rv);
EXPECT_STREQ(tests[i].expected_credentials, credentials.c_str());
}
}
diff --git a/net/http/http_auth_handler_digest.cc b/net/http/http_auth_handler_digest.cc
index a0c443c..10af291 100644
--- a/net/http/http_auth_handler_digest.cc
+++ b/net/http/http_auth_handler_digest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// 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.
@@ -7,6 +7,7 @@
#include "base/md5.h"
#include "base/rand_util.h"
#include "base/string_util.h"
+#include "net/base/net_errors.h"
#include "net/base/net_util.h"
#include "net/http/http_auth.h"
#include "net/http/http_request_info.h"
@@ -77,11 +78,12 @@ std::string HttpAuthHandlerDigest::AlgorithmToString(int algorithm) {
}
}
-std::string HttpAuthHandlerDigest::GenerateCredentials(
+int HttpAuthHandlerDigest::GenerateAuthToken(
const std::wstring& username,
const std::wstring& password,
const HttpRequestInfo* request,
- const ProxyInfo* proxy) {
+ const ProxyInfo* proxy,
+ std::string* auth_token) {
// Generate a random client nonce.
std::string cnonce = GenerateNonce();
@@ -97,11 +99,21 @@ std::string HttpAuthHandlerDigest::GenerateCredentials(
std::string path;
GetRequestMethodAndPath(request, proxy, &method, &path);
- return AssembleCredentials(method, path,
- // TODO(eroman): is this the right encoding?
- WideToUTF8(username),
- WideToUTF8(password),
- cnonce, nonce_count);
+ *auth_token = AssembleCredentials(method, path,
+ // TODO(eroman): is this the right encoding?
+ WideToUTF8(username),
+ WideToUTF8(password),
+ cnonce, nonce_count);
+ return OK;
+}
+
+int HttpAuthHandlerDigest::GenerateDefaultAuthToken(
+ const HttpRequestInfo* request,
+ const ProxyInfo* proxy,
+ std::string* auth_token) {
+ NOTREACHED();
+ LOG(ERROR) << ErrorToString(ERR_NOT_IMPLEMENTED);
+ return ERR_NOT_IMPLEMENTED;
}
void HttpAuthHandlerDigest::GetRequestMethodAndPath(
diff --git a/net/http/http_auth_handler_digest.h b/net/http/http_auth_handler_digest.h
index b4c8687..686f354 100644
--- a/net/http/http_auth_handler_digest.h
+++ b/net/http/http_auth_handler_digest.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// 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.
@@ -15,10 +15,15 @@ namespace net {
// Code for handling http digest authentication.
class HttpAuthHandlerDigest : public HttpAuthHandler {
public:
- virtual std::string GenerateCredentials(const std::wstring& username,
- const std::wstring& password,
- const HttpRequestInfo* request,
- const ProxyInfo* proxy);
+ virtual int GenerateAuthToken(const std::wstring& username,
+ const std::wstring& password,
+ const HttpRequestInfo* request,
+ const ProxyInfo* proxy,
+ std::string* auth_token);
+
+ virtual int GenerateDefaultAuthToken(const HttpRequestInfo* request,
+ const ProxyInfo* proxy,
+ std::string* auth_token);
protected:
virtual bool Init(std::string::const_iterator challenge_begin,
diff --git a/net/http/http_auth_handler_negotiate.h b/net/http/http_auth_handler_negotiate.h
index eb4d11f..b057f5c 100644
--- a/net/http/http_auth_handler_negotiate.h
+++ b/net/http/http_auth_handler_negotiate.h
@@ -30,11 +30,17 @@ class HttpAuthHandlerNegotiate : public HttpAuthHandler {
virtual bool IsFinalRound();
- virtual std::string GenerateCredentials(const std::wstring& username,
- const std::wstring& password,
- const HttpRequestInfo* request,
- const ProxyInfo* proxy);
+ virtual bool AllowDefaultCredentials();
+ virtual int GenerateAuthToken(const std::wstring& username,
+ const std::wstring& password,
+ const HttpRequestInfo* request,
+ const ProxyInfo* proxy,
+ std::string* auth_token);
+
+ virtual int GenerateDefaultAuthToken(const HttpRequestInfo* request,
+ const ProxyInfo* proxy,
+ std::string* auth_token);
protected:
virtual bool Init(std::string::const_iterator challenge_begin,
diff --git a/net/http/http_auth_handler_negotiate_posix.cc b/net/http/http_auth_handler_negotiate_posix.cc
index 581b489..f70b58b 100755..100644
--- a/net/http/http_auth_handler_negotiate_posix.cc
+++ b/net/http/http_auth_handler_negotiate_posix.cc
@@ -5,6 +5,7 @@
#include "net/http/http_auth_handler_negotiate.h"
#include "base/logging.h"
+#include "net/base/net_errors.h"
namespace net {
@@ -20,11 +21,19 @@ HttpAuthHandlerNegotiate::~HttpAuthHandlerNegotiate() {
bool HttpAuthHandlerNegotiate::NeedsIdentity() {
NOTREACHED();
+ LOG(ERROR) << ErrorToString(ERR_NOT_IMPLEMENTED);
return false;
}
bool HttpAuthHandlerNegotiate::IsFinalRound() {
NOTREACHED();
+ LOG(ERROR) << ErrorToString(ERR_NOT_IMPLEMENTED);
+ return false;
+}
+
+bool HttpAuthHandlerNegotiate::AllowDefaultCredentials() {
+ NOTREACHED();
+ LOG(ERROR) << ErrorToString(ERR_NOT_IMPLEMENTED);
return false;
}
@@ -33,13 +42,24 @@ bool HttpAuthHandlerNegotiate::Init(std::string::const_iterator challenge_begin,
return false;
}
-std::string HttpAuthHandlerNegotiate::GenerateCredentials(
+int HttpAuthHandlerNegotiate::GenerateAuthToken(
const std::wstring& username,
const std::wstring& password,
const HttpRequestInfo* request,
- const ProxyInfo* proxy) {
+ const ProxyInfo* proxy,
+ std::string* auth_token) {
+ NOTREACHED();
+ LOG(ERROR) << ErrorToString(ERR_NOT_IMPLEMENTED);
+ return ERR_NOT_IMPLEMENTED;
+}
+
+int HttpAuthHandlerNegotiate::GenerateDefaultAuthToken(
+ const HttpRequestInfo* request,
+ const ProxyInfo* proxy,
+ std::string* auth_token) {
NOTREACHED();
- return std::string();
+ LOG(ERROR) << ErrorToString(ERR_NOT_IMPLEMENTED);
+ return ERR_NOT_IMPLEMENTED;
}
} // namespace net
diff --git a/net/http/http_auth_handler_negotiate_win.cc b/net/http/http_auth_handler_negotiate_win.cc
index 782cb5c..c005590 100644
--- a/net/http/http_auth_handler_negotiate_win.cc
+++ b/net/http/http_auth_handler_negotiate_win.cc
@@ -15,23 +15,19 @@ HttpAuthHandlerNegotiate::HttpAuthHandlerNegotiate() :
HttpAuthHandlerNegotiate::~HttpAuthHandlerNegotiate() {
}
-std::string HttpAuthHandlerNegotiate::GenerateCredentials(
+int HttpAuthHandlerNegotiate::GenerateAuthToken(
const std::wstring& username,
const std::wstring& password,
const HttpRequestInfo* request,
- const ProxyInfo* proxy) {
- std::string auth_credentials;
-
- int rv = auth_sspi_.GenerateCredentials(
- username,
- password,
+ const ProxyInfo* proxy,
+ std::string* auth_token) {
+ return auth_sspi_.GenerateAuthToken(
+ &username,
+ &password,
origin_,
request,
proxy,
- &auth_credentials);
- if (rv == OK)
- return auth_credentials;
- return std::string();
+ auth_token);
}
// The Negotiate challenge header looks like:
@@ -54,4 +50,30 @@ bool HttpAuthHandlerNegotiate::IsFinalRound() {
return auth_sspi_.IsFinalRound();
}
+bool HttpAuthHandlerNegotiate::AllowDefaultCredentials() {
+ // NOTE: Temporarily disabled. SSO is a potential security risk.
+ // TODO(cbentzel): Add a pointer to Firefox documentation about risk.
+
+ // TODO(cbentzel): Add a blanket command line flag to enable/disable?
+ // TODO(cbentzel): Add a whitelist regexp command line flag?
+ // TODO(cbentzel): Resolve the origin_ (helpful if doing already) and see if
+ // it is in private IP space?
+ // TODO(cbentzel): Compare origin_ to this machine's hostname and allow if
+ // it matches at least two or three layers deep?
+ return false;
+}
+
+int HttpAuthHandlerNegotiate::GenerateDefaultAuthToken(
+ const HttpRequestInfo* request,
+ const ProxyInfo* proxy,
+ std::string* auth_token) {
+ return auth_sspi_.GenerateAuthToken(
+ NULL, // username
+ NULL, // password
+ origin_,
+ request,
+ proxy,
+ auth_token);
+}
+
} // namespace net
diff --git a/net/http/http_auth_handler_ntlm.cc b/net/http/http_auth_handler_ntlm.cc
index 6e10e79..e191ce4 100755..100644
--- a/net/http/http_auth_handler_ntlm.cc
+++ b/net/http/http_auth_handler_ntlm.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// 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.
@@ -10,24 +10,20 @@
namespace net {
-std::string HttpAuthHandlerNTLM::GenerateCredentials(
+int HttpAuthHandlerNTLM::GenerateAuthToken(
const std::wstring& username,
const std::wstring& password,
const HttpRequestInfo* request,
- const ProxyInfo* proxy) {
+ const ProxyInfo* proxy,
+ std::string* auth_token) {
#if defined(NTLM_SSPI)
- std::string auth_credentials;
-
- int rv = auth_sspi_.GenerateCredentials(
- username,
- password,
+ return auth_sspi_.GenerateAuthToken(
+ &username,
+ &password,
origin_,
request,
proxy,
- &auth_credentials);
- if (rv == OK)
- return auth_credentials;
- return std::string();
+ auth_token);
#else // !defined(NTLM_SSPI)
// TODO(wtc): See if we can use char* instead of void* for in_buf and
// out_buf. This change will need to propagate to GetNextToken,
@@ -58,7 +54,7 @@ std::string HttpAuthHandlerNTLM::GenerateCredentials(
in_buf = NULL;
int rv = InitializeBeforeFirstChallenge();
if (rv != OK)
- return std::string();
+ return rv;
} else {
// Decode |auth_data_| into the input buffer.
int len = auth_data_.length();
@@ -71,25 +67,30 @@ std::string HttpAuthHandlerNTLM::GenerateCredentials(
len--;
auth_data_.erase(len);
- if (!base::Base64Decode(auth_data_, &decoded_auth_data))
- return std::string(); // Improper base64 encoding
+ if (!base::Base64Decode(auth_data_, &decoded_auth_data)) {
+ LOG(ERROR) << "Unexpected problem Base64 decoding.";
+ return ERR_UNEXPECTED;
+ }
in_buf_len = decoded_auth_data.length();
in_buf = decoded_auth_data.data();
}
int rv = GetNextToken(in_buf, in_buf_len, &out_buf, &out_buf_len);
if (rv != OK)
- return std::string();
+ return rv;
// Base64 encode data in output buffer and prepend "NTLM ".
std::string encode_input(static_cast<char*>(out_buf), out_buf_len);
std::string encode_output;
- bool ok = base::Base64Encode(encode_input, &encode_output);
+ bool base64_rv = base::Base64Encode(encode_input, &encode_output);
// OK, we are done with |out_buf|
free(out_buf);
- if (!ok)
- return std::string();
- return std::string("NTLM ") + encode_output;
+ if (!base64_rv) {
+ LOG(ERROR) << "Unexpected problem Base64 encoding.";
+ return ERR_UNEXPECTED;
+ }
+ *auth_token = std::string("NTLM ") + encode_output;
+ return OK;
#endif
}
diff --git a/net/http/http_auth_handler_ntlm.h b/net/http/http_auth_handler_ntlm.h
index c3bda62..c4b9dab 100644
--- a/net/http/http_auth_handler_ntlm.h
+++ b/net/http/http_auth_handler_ntlm.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// 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.
@@ -68,10 +68,17 @@ class HttpAuthHandlerNTLM : public HttpAuthHandler {
virtual bool IsFinalRound();
- virtual std::string GenerateCredentials(const std::wstring& username,
- const std::wstring& password,
- const HttpRequestInfo* request,
- const ProxyInfo* proxy);
+ virtual bool AllowDefaultCredentials();
+
+ virtual int GenerateAuthToken(const std::wstring& username,
+ const std::wstring& password,
+ const HttpRequestInfo* request,
+ const ProxyInfo* proxy,
+ std::string* auth_token);
+
+ virtual int GenerateDefaultAuthToken(const HttpRequestInfo* request,
+ const ProxyInfo* proxy,
+ std::string* auth_token);
protected:
virtual bool Init(std::string::const_iterator challenge_begin,
diff --git a/net/http/http_auth_handler_ntlm_portable.cc b/net/http/http_auth_handler_ntlm_portable.cc
index 7976878..7fccfce 100644
--- a/net/http/http_auth_handler_ntlm_portable.cc
+++ b/net/http/http_auth_handler_ntlm_portable.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// 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.
@@ -657,6 +657,12 @@ bool HttpAuthHandlerNTLM::IsFinalRound() {
return !auth_data_.empty();
}
+bool HttpAuthHandlerNTLM::AllowDefaultCredentials() {
+ // Default credentials are not supported in the portable implementation of
+ // NTLM, but are supported in the SSPI implementation.
+ return false;
+}
+
// static
HttpAuthHandlerNTLM::GenerateRandomProc
HttpAuthHandlerNTLM::SetGenerateRandomProc(
@@ -704,4 +710,13 @@ int HttpAuthHandlerNTLM::InitializeBeforeFirstChallenge() {
return OK;
}
+int HttpAuthHandlerNTLM::GenerateDefaultAuthToken(
+ const HttpRequestInfo* request,
+ const ProxyInfo* proxy,
+ std::string* auth_token) {
+ NOTREACHED();
+ LOG(ERROR) << ErrorToString(ERR_NOT_IMPLEMENTED);
+ return ERR_NOT_IMPLEMENTED;
+}
+
} // namespace net
diff --git a/net/http/http_auth_handler_ntlm_win.cc b/net/http/http_auth_handler_ntlm_win.cc
index fba9c1b..c096aaf 100644
--- a/net/http/http_auth_handler_ntlm_win.cc
+++ b/net/http/http_auth_handler_ntlm_win.cc
@@ -34,6 +34,31 @@ bool HttpAuthHandlerNTLM::IsFinalRound() {
return auth_sspi_.IsFinalRound();
}
+bool HttpAuthHandlerNTLM::AllowDefaultCredentials() {
+ // NOTE: Temporarily disabled. SSO is a potential security risk with NTLM.
+ // TODO(cbentzel): Add a pointer to Firefox documentation about risk.
+
+ // TODO(cbentzel): Add a blanket command line flag to enable/disable?
+ // TODO(cbentzel): Add a whitelist regexp command line flag?
+ // TODO(cbentzel): Resolve the origin_ (helpful if doing already) and see if
+ // it is in private IP space?
+ // TODO(cbentzel): Compare origin_ to this machine's hostname and allow if
+ // it matches at least two or three layers deep?
+ return false;
+}
+
+int HttpAuthHandlerNTLM::GenerateDefaultAuthToken(
+ const HttpRequestInfo* request,
+ const ProxyInfo* proxy,
+ std::string* auth_token) {
+ return auth_sspi_.GenerateAuthToken(
+ NULL, // username
+ NULL, // password
+ origin_,
+ request,
+ proxy,
+ auth_token);
+}
} // namespace net
diff --git a/net/http/http_auth_sspi_win.cc b/net/http/http_auth_sspi_win.cc
index 00861e5..c858d36 100644
--- a/net/http/http_auth_sspi_win.cc
+++ b/net/http/http_auth_sspi_win.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// 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.
@@ -15,6 +15,87 @@
#include "net/http/http_auth.h"
namespace net {
+namespace {
+
+int MapAcquireCredentialsStatusToError(SECURITY_STATUS status,
+ const SEC_WCHAR* package) {
+ switch (status) {
+ case SEC_E_OK:
+ return OK;
+ case SEC_E_INSUFFICIENT_MEMORY:
+ return ERR_OUT_OF_MEMORY;
+ case SEC_E_INTERNAL_ERROR:
+ return ERR_UNEXPECTED;
+ case SEC_E_NO_CREDENTIALS:
+ case SEC_E_NOT_OWNER:
+ case SEC_E_UNKNOWN_CREDENTIALS:
+ return ERR_INVALID_AUTH_CREDENTIALS;
+ case SEC_E_SECPKG_NOT_FOUND:
+ // This indicates that the SSPI configuration does not match expectations
+ LOG(ERROR) << "Received SEC_E_SECPKG_NOT_FOUND for " << package;
+ return ERR_UNSUPPORTED_AUTH_SCHEME;
+ default:
+ LOG(ERROR) << "Unexpected SECURITY_STATUS " << status;
+ return ERR_UNEXPECTED;
+ }
+}
+
+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.
+ 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
+
+ return MapAcquireCredentialsStatusToError(status, package);
+}
+
+int AcquireDefaultCredentials(const SEC_WCHAR* package, CredHandle* cred) {
+ TimeStamp expiry;
+
+ // Pass the username/password to get the credentials handle.
+ // Note: Since the 5th argument is NULL, it uses the default
+ // cached credentials for the logged in user, which can be used
+ // for a single sign-on.
+ SECURITY_STATUS status = AcquireCredentialsHandle(
+ NULL, // pszPrincipal
+ const_cast<SEC_WCHAR*>(package), // pszPackage
+ SECPKG_CRED_OUTBOUND, // fCredentialUse
+ NULL, // pvLogonID
+ NULL, // pAuthData
+ NULL, // pGetKeyFn (not used)
+ NULL, // pvGetKeyArgument (not used)
+ cred, // phCredential
+ &expiry); // ptsExpiry
+
+ return MapAcquireCredentialsStatusToError(status, package);
+}
+
+} // anonymous namespace
HttpAuthSSPI::HttpAuthSSPI(const std::string& scheme,
SEC_WCHAR* security_package)
@@ -73,28 +154,26 @@ bool HttpAuthSSPI::ParseChallenge(std::string::const_iterator challenge_begin,
encoded_auth_token.erase(encoded_length);
std::string decoded_auth_token;
- bool rv = base::Base64Decode(encoded_auth_token, &decoded_auth_token);
- if (rv) {
- decoded_server_auth_token_ = decoded_auth_token;
+ bool base64_rv = base::Base64Decode(encoded_auth_token, &decoded_auth_token);
+ if (!base64_rv) {
+ LOG(ERROR) << "Base64 decoding of auth token failed.";
+ return false;
}
- return rv;
+ decoded_server_auth_token_ = decoded_auth_token;
+ return true;
}
-int HttpAuthSSPI::GenerateCredentials(const std::wstring& username,
- const std::wstring& password,
- const GURL& origin,
- const HttpRequestInfo* request,
- const ProxyInfo* proxy,
- std::string* out_credentials) {
- // |username| may be in the form "DOMAIN\user". Parse it into the two
- // components.
- std::wstring domain;
- std::wstring user;
- SplitDomainAndUser(username, &domain, &user);
+int HttpAuthSSPI::GenerateAuthToken(const std::wstring* username,
+ const std::wstring* password,
+ const GURL& origin,
+ const HttpRequestInfo* request,
+ const ProxyInfo* proxy,
+ std::string* auth_token) {
+ DCHECK((username == NULL) == (password == NULL));
// Initial challenge.
if (!IsFinalRound()) {
- int rv = OnFirstRound(domain, user, password);
+ int rv = OnFirstRound(username, password);
if (rv != OK)
return rv;
}
@@ -114,23 +193,38 @@ int HttpAuthSSPI::GenerateCredentials(const std::wstring& username,
// Base64 encode data in output buffer and prepend the scheme.
std::string encode_input(static_cast<char*>(out_buf), out_buf_len);
std::string encode_output;
- bool ok = base::Base64Encode(encode_input, &encode_output);
+ bool base64_rv = base::Base64Encode(encode_input, &encode_output);
// OK, we are done with |out_buf|
free(out_buf);
- if (!ok)
- return rv;
- *out_credentials = scheme_ + " " + encode_output;
+ if (!base64_rv) {
+ LOG(ERROR) << "Base64 encoding of auth token failed.";
+ return ERR_UNEXPECTED;
+ }
+ *auth_token = scheme_ + " " + encode_output;
return OK;
}
-int HttpAuthSSPI::OnFirstRound(const std::wstring& domain,
- const std::wstring& user,
- const std::wstring& password) {
+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) {
+ if (rv != OK)
return rv;
+
+ if (username) {
+ std::wstring domain;
+ std::wstring user;
+ SplitDomainAndUser(*username, &domain, &user);
+ rv = AcquireCredentials(security_package_, domain, user, *password, &cred_);
+ if (rv != OK)
+ return rv;
+ } else {
+ rv = AcquireDefaultCredentials(security_package_, &cred_);
+ if (rv != OK)
+ return rv;
}
- rv = AcquireCredentials(security_package_, domain, user, password, &cred_);
+
return rv;
}
@@ -204,7 +298,7 @@ int HttpAuthSSPI::GetNextSecurityToken(
// and SEC_E_OK on the second call. On failure, the function returns an
// error code.
if (status != SEC_I_CONTINUE_NEEDED && status != SEC_E_OK) {
- LOG(ERROR) << "InitializeSecurityContext failed: " << status;
+ LOG(ERROR) << "InitializeSecurityContext failed " << status;
ResetSecurityContext();
free(out_buffer.pvBuffer);
return ERR_UNEXPECTED; // TODO(wtc): map error code.
@@ -221,6 +315,9 @@ int HttpAuthSSPI::GetNextSecurityToken(
void SplitDomainAndUser(const std::wstring& combined,
std::wstring* domain,
std::wstring* user) {
+ // |combined| may be in the form "user" or "DOMAIN\user".
+ // Separatethe two parts if they exist.
+ // TODO(cbentzel): I believe user@domain is also a valid form.
size_t backslash_idx = combined.find(L'\\');
if (backslash_idx == std::wstring::npos) {
domain->clear();
@@ -233,54 +330,36 @@ void SplitDomainAndUser(const std::wstring& combined,
int DetermineMaxTokenLength(const std::wstring& package,
ULONG* max_token_length) {
- PSecPkgInfo pkg_info;
+ PSecPkgInfo pkg_info = NULL;
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;
+ // The documentation at
+ // http://msdn.microsoft.com/en-us/library/aa379359(VS.85).aspx
+ // only mentions that a non-zero (or non-SEC_E_OK) value is returned
+ // if the function fails. In practice, it appears to return
+ // SEC_E_SECPKG_NOT_FOUND for invalid/unknown packages.
+ LOG(ERROR) << "Security package " << package << " not found."
+ << " Status code: " << status;
+ if (status == SEC_E_SECPKG_NOT_FOUND)
+ return ERR_UNSUPPORTED_AUTH_SCHEME;
+ else
+ 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)
+ status = FreeContextBuffer(pkg_info);
+ if (status != SEC_E_OK) {
+ // The documentation at
+ // http://msdn.microsoft.com/en-us/library/aa375416(VS.85).aspx
+ // only mentions that a non-zero (or non-SEC_E_OK) value is returned
+ // if the function fails, and does not indicate what the failure conditions
+ // are.
+ LOG(ERROR) << "Unexpected problem freeing context buffer. Status code: "
+ << status;
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
index 4d340aa..b94ffbc 100755..100644
--- a/net/http/http_auth_sspi_win.h
+++ b/net/http/http_auth_sspi_win.h
@@ -35,17 +35,22 @@ class HttpAuthSSPI {
bool ParseChallenge(std::string::const_iterator challenge_begin,
std::string::const_iterator challenge_end);
- int GenerateCredentials(const std::wstring& username,
- const std::wstring& password,
- const GURL& origin,
- const HttpRequestInfo* request,
- const ProxyInfo* proxy,
- std::string* out_credentials);
+ // Generates an authentication token.
+ // The return value is an error code. If it's not |OK|, the value of
+ // |*auth_token| is unspecified.
+ // If this is the first round of a multiple round scheme, credentials are
+ // obtained using |*username| and |*password|. If |username| and |password|
+ // are NULL, the default credentials are used instead.
+ int GenerateAuthToken(const std::wstring* username,
+ const std::wstring* password,
+ const GURL& origin,
+ const HttpRequestInfo* request,
+ const ProxyInfo* proxy,
+ std::string* auth_token);
private:
- int OnFirstRound(const std::wstring& domain,
- const std::wstring& user,
- const std::wstring& password);
+ int OnFirstRound(const std::wstring* username,
+ const std::wstring* password);
int GetNextSecurityToken(
const GURL& origin,
@@ -80,13 +85,6 @@ void SplitDomainAndUser(const std::wstring& combined,
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_unittest.cc b/net/http/http_auth_unittest.cc
index a960d70..a960d70 100755..100644
--- a/net/http/http_auth_unittest.cc
+++ b/net/http/http_auth_unittest.cc
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index 300482f..d89a84a 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// 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.
@@ -1609,14 +1609,21 @@ std::string HttpNetworkTransaction::BuildAuthorizationHeader(
DCHECK(HaveAuth(target));
// Add a Authorization/Proxy-Authorization header line.
- std::string credentials = auth_handler_[target]->GenerateCredentials(
+ std::string auth_token;
+ int rv = auth_handler_[target]->GenerateAuthToken(
auth_identity_[target].username,
auth_identity_[target].password,
request_,
- &proxy_info_);
-
- return HttpAuth::GetAuthorizationHeaderName(target) +
- ": " + credentials + "\r\n";
+ &proxy_info_,
+ &auth_token);
+ if (rv == OK)
+ return HttpAuth::GetAuthorizationHeaderName(target) +
+ ": " + auth_token + "\r\n";
+
+ // TODO(cbentzel): Evict username and password from cache on non-OK return?
+ // TODO(cbentzel): Never use this scheme again if
+ // ERR_UNSUPPORTED_AUTH_SCHEME is returned.
+ return std::string();
}
GURL HttpNetworkTransaction::AuthOrigin(HttpAuth::Target target) const {
diff --git a/net/socket_stream/socket_stream.cc b/net/socket_stream/socket_stream.cc
index 2a01f17..aae234e 100644
--- a/net/socket_stream/socket_stream.cc
+++ b/net/socket_stream/socket_stream.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// 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.
//
@@ -556,14 +556,21 @@ int SocketStream::DoWriteTunnelHeaders() {
// HttpRequestInfo.
// TODO(ukai): Add support other authentication scheme.
if (auth_handler_.get() && auth_handler_->scheme() == "basic") {
- std::string credentials = auth_handler_->GenerateCredentials(
+ std::string auth_token;
+ int rv = auth_handler_->GenerateAuthToken(
auth_identity_.username,
auth_identity_.password,
NULL,
- &proxy_info_);
+ &proxy_info_,
+ &auth_token);
+ // TODO(cbentzel): Should do something different if credentials
+ // can't be generated. In this case, only Basic is allowed which
+ // should only fail if Base64 encoding fails.
+ if (rv != OK)
+ auth_token = std::string();
authorization_headers.append(
HttpAuth::GetAuthorizationHeaderName(HttpAuth::AUTH_PROXY) +
- ": " + credentials + "\r\n");
+ ": " + auth_token + "\r\n");
}
tunnel_request_headers_->headers_ = StringPrintf(