Chromium Code Reviews| 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))); |
| } |