Index: net/http/http_auth_handler_negotiate.cc |
diff --git a/net/http/http_auth_handler_negotiate.cc b/net/http/http_auth_handler_negotiate.cc |
index 864a703e12e24c7369125b3a470bc80019a9de65..00d8ba84cec1247a3d8cc8a2dbc2ef7b655b4605 100644 |
--- a/net/http/http_auth_handler_negotiate.cc |
+++ b/net/http/http_auth_handler_negotiate.cc |
@@ -7,16 +7,50 @@ |
#include "base/bind.h" |
#include "base/bind_helpers.h" |
#include "base/logging.h" |
+#include "base/strings/string_number_conversions.h" |
+#include "base/strings/string_util.h" |
#include "base/strings/stringprintf.h" |
+#include "base/values.h" |
#include "net/base/address_family.h" |
#include "net/base/net_errors.h" |
+#include "net/cert/x509_util.h" |
#include "net/dns/host_resolver.h" |
#include "net/dns/single_request_host_resolver.h" |
#include "net/http/http_auth_filter.h" |
#include "net/http/http_auth_preferences.h" |
+#include "net/http/http_response_info.h" |
+#include "net/log/net_log.h" |
namespace net { |
+namespace { |
+ |
+scoped_ptr<base::Value> NetLogParameterChannelBindings( |
+ const std::string& channel_binding_token, |
+ NetLogCaptureMode capture_mode) { |
+ scoped_ptr<base::DictionaryValue> dict; |
+ if (!capture_mode.include_socket_bytes()) |
+ return std::move(dict); |
+ |
+ dict.reset(new base::DictionaryValue()); |
+ auto colon = channel_binding_token.find(':'); |
Ryan Sleevi
2016/03/18 21:27:40
Is it necessary to split this? I'm not sure why yo
asanka
2016/03/23 04:51:30
Done. Yeah, went with logging the token in hex wit
|
+ if (colon == channel_binding_token.npos || colon < 1 || |
Ryan Sleevi
2016/03/18 21:27:40
Shouldn't this be std::string::npos? It's a static
asanka
2016/03/23 04:51:30
Either is valid for a static member of a class, bu
|
+ !base::IsStringASCII(channel_binding_token.substr(0, colon))) { |
+ dict->SetString("type", "(unknown)"); |
+ dict->SetString("token", base::HexEncode(channel_binding_token.data(), |
+ channel_binding_token.size())); |
+ } else { |
+ dict->SetString("type", channel_binding_token.substr(0, colon)); |
+ ++colon; |
+ dict->SetString("token", |
+ base::HexEncode(channel_binding_token.data() + colon, |
+ channel_binding_token.size() - colon)); |
+ } |
+ return std::move(dict); |
+} |
+ |
+} // namespace |
+ |
HttpAuthHandlerNegotiate::Factory::Factory() |
: resolver_(NULL), |
#if defined(OS_WIN) |
@@ -36,6 +70,7 @@ void HttpAuthHandlerNegotiate::Factory::set_host_resolver( |
int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler( |
HttpAuthChallengeTokenizer* challenge, |
HttpAuth::Target target, |
+ const HttpResponseInfo& response_info, |
const GURL& origin, |
CreateReason reason, |
int digest_nonce_count, |
@@ -78,7 +113,8 @@ int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler( |
scoped_ptr<HttpAuthHandler> tmp_handler(new HttpAuthHandlerNegotiate( |
auth_library_.get(), http_auth_preferences(), resolver_)); |
#endif |
- if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) |
+ if (!tmp_handler->InitFromChallenge(challenge, target, response_info, origin, |
+ net_log)) |
return ERR_INVALID_RESPONSE; |
handler->swap(tmp_handler); |
return OK; |
@@ -185,7 +221,8 @@ bool HttpAuthHandlerNegotiate::AllowsExplicitCredentials() { |
// The Negotiate challenge header looks like: |
// WWW-Authenticate: NEGOTIATE auth-data |
-bool HttpAuthHandlerNegotiate::Init(HttpAuthChallengeTokenizer* challenge) { |
+bool HttpAuthHandlerNegotiate::Init(HttpAuthChallengeTokenizer* challenge, |
+ const HttpResponseInfo& response_info) { |
#if defined(OS_POSIX) |
if (!auth_system_.Init()) { |
VLOG(1) << "can't initialize GSSAPI library"; |
@@ -203,9 +240,21 @@ bool HttpAuthHandlerNegotiate::Init(HttpAuthChallengeTokenizer* challenge) { |
auth_scheme_ = HttpAuth::AUTH_SCHEME_NEGOTIATE; |
score_ = 4; |
properties_ = ENCRYPTS_IDENTITY | IS_CONNECTION_BASED; |
+ |
HttpAuth::AuthorizationResult auth_result = |
auth_system_.ParseChallenge(challenge); |
- return (auth_result == HttpAuth::AUTHORIZATION_RESULT_ACCEPT); |
+ if (auth_result != HttpAuth::AUTHORIZATION_RESULT_ACCEPT) |
+ return false; |
+ |
+ // Try to extract channel bindings. |
+ if (response_info.ssl_info.is_valid()) |
+ x509_util::GetTLSServerEndPointChannelBinding(*response_info.ssl_info.cert, |
+ &channel_bindings_); |
+ if (!channel_bindings_.empty()) |
+ net_log_.AddEvent( |
+ NetLog::TYPE_AUTH_CHANNEL_BINDINGS, |
+ base::Bind(&NetLogParameterChannelBindings, channel_bindings_)); |
+ return true; |
} |
int HttpAuthHandlerNegotiate::GenerateAuthTokenImpl( |
@@ -319,7 +368,7 @@ int HttpAuthHandlerNegotiate::DoGenerateAuthToken() { |
next_state_ = STATE_GENERATE_AUTH_TOKEN_COMPLETE; |
AuthCredentials* credentials = has_credentials_ ? &credentials_ : NULL; |
return auth_system_.GenerateAuthToken( |
- credentials, spn_, auth_token_, |
+ credentials, spn_, channel_bindings_, auth_token_, |
base::Bind(&HttpAuthHandlerNegotiate::OnIOComplete, |
base::Unretained(this))); |
} |