| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/http/http_auth_handler_negotiate.h" | 5 #include "net/http/http_auth_handler_negotiate.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 | 31 |
| 32 HttpAuthHandlerNegotiate::Factory::~Factory() { | 32 HttpAuthHandlerNegotiate::Factory::~Factory() { |
| 33 } | 33 } |
| 34 | 34 |
| 35 void HttpAuthHandlerNegotiate::Factory::set_host_resolver( | 35 void HttpAuthHandlerNegotiate::Factory::set_host_resolver( |
| 36 HostResolver* resolver) { | 36 HostResolver* resolver) { |
| 37 resolver_ = resolver; | 37 resolver_ = resolver; |
| 38 } | 38 } |
| 39 | 39 |
| 40 int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler( | 40 int HttpAuthHandlerNegotiate::Factory::CreateAuthHandler( |
| 41 HttpAuthChallengeTokenizer* challenge, | 41 const HttpAuthChallengeTokenizer& challenge, |
| 42 HttpAuth::Target target, | 42 HttpAuth::Target target, |
| 43 const GURL& origin, | 43 const GURL& origin, |
| 44 CreateReason reason, | 44 CreateReason reason, |
| 45 int digest_nonce_count, | 45 int digest_nonce_count, |
| 46 const BoundNetLog& net_log, | 46 const BoundNetLog& net_log, |
| 47 scoped_ptr<HttpAuthHandler>* handler) { | 47 scoped_ptr<HttpAuthHandler>* handler) { |
| 48 #if defined(OS_WIN) | 48 #if defined(OS_WIN) |
| 49 if (is_unsupported_ || reason == CREATE_PREEMPTIVE) | 49 if (is_unsupported_ || reason == CREATE_PREEMPTIVE) |
| 50 return ERR_UNSUPPORTED_AUTH_SCHEME; | 50 return ERR_UNSUPPORTED_AUTH_SCHEME; |
| 51 if (max_token_length_ == 0) { | 51 if (max_token_length_ == 0) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 77 is_unsupported_ = true; | 77 is_unsupported_ = true; |
| 78 return ERR_UNSUPPORTED_AUTH_SCHEME; | 78 return ERR_UNSUPPORTED_AUTH_SCHEME; |
| 79 } | 79 } |
| 80 // TODO(ahendrickson): Move towards model of parsing in the factory | 80 // TODO(ahendrickson): Move towards model of parsing in the factory |
| 81 // method and only constructing when valid. | 81 // method and only constructing when valid. |
| 82 scoped_ptr<HttpAuthHandler> tmp_handler( | 82 scoped_ptr<HttpAuthHandler> tmp_handler( |
| 83 new HttpAuthHandlerNegotiate(auth_library_.get(), url_security_manager(), | 83 new HttpAuthHandlerNegotiate(auth_library_.get(), url_security_manager(), |
| 84 resolver_, disable_cname_lookup_, | 84 resolver_, disable_cname_lookup_, |
| 85 use_port_)); | 85 use_port_)); |
| 86 #endif | 86 #endif |
| 87 if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) | 87 int result = |
| 88 return ERR_INVALID_RESPONSE; | 88 tmp_handler->HandleInitialChallenge(challenge, target, origin, net_log); |
| 89 handler->swap(tmp_handler); | 89 if (result == OK) |
| 90 return OK; | 90 handler->swap(tmp_handler); |
| 91 return result; |
| 91 } | 92 } |
| 92 | 93 |
| 93 HttpAuthHandlerNegotiate::HttpAuthHandlerNegotiate( | 94 HttpAuthHandlerNegotiate::HttpAuthHandlerNegotiate( |
| 94 AuthLibrary* auth_library, | 95 AuthLibrary* auth_library, |
| 95 #if defined(OS_WIN) | 96 #if defined(OS_WIN) |
| 96 ULONG max_token_length, | 97 ULONG max_token_length, |
| 97 #endif | 98 #endif |
| 98 URLSecurityManager* url_security_manager, | 99 URLSecurityManager* url_security_manager, |
| 99 HostResolver* resolver, | 100 HostResolver* resolver, |
| 100 bool disable_cname_lookup, | 101 bool disable_cname_lookup, |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 #endif | 162 #endif |
| 162 if (port != 80 && port != 443 && use_port_) { | 163 if (port != 80 && port != 443 && use_port_) { |
| 163 return base::StringPrintf("HTTP%c%s:%d", kSpnSeparator, server.c_str(), | 164 return base::StringPrintf("HTTP%c%s:%d", kSpnSeparator, server.c_str(), |
| 164 port); | 165 port); |
| 165 } else { | 166 } else { |
| 166 return base::StringPrintf("HTTP%c%s", kSpnSeparator, server.c_str()); | 167 return base::StringPrintf("HTTP%c%s", kSpnSeparator, server.c_str()); |
| 167 } | 168 } |
| 168 } | 169 } |
| 169 | 170 |
| 170 HttpAuth::AuthorizationResult HttpAuthHandlerNegotiate::HandleAnotherChallenge( | 171 HttpAuth::AuthorizationResult HttpAuthHandlerNegotiate::HandleAnotherChallenge( |
| 171 HttpAuthChallengeTokenizer* challenge) { | 172 const HttpAuthChallengeTokenizer& challenge) { |
| 172 return auth_system_.ParseChallenge(challenge); | 173 return auth_system_.ParseChallenge(challenge); |
| 173 } | 174 } |
| 174 | 175 |
| 175 // Require identity on first pass instead of second. | 176 // Require identity on first pass instead of second. |
| 176 bool HttpAuthHandlerNegotiate::NeedsIdentity() { | 177 bool HttpAuthHandlerNegotiate::NeedsIdentity() { |
| 177 return auth_system_.NeedsIdentity(); | 178 return auth_system_.NeedsIdentity(); |
| 178 } | 179 } |
| 179 | 180 |
| 180 bool HttpAuthHandlerNegotiate::AllowsDefaultCredentials() { | 181 bool HttpAuthHandlerNegotiate::AllowsDefaultCredentials() { |
| 181 if (target_ == HttpAuth::AUTH_PROXY) | 182 if (target_ == HttpAuth::AUTH_PROXY) |
| 182 return true; | 183 return true; |
| 183 if (!url_security_manager_) | 184 if (!url_security_manager_) |
| 184 return false; | 185 return false; |
| 185 return url_security_manager_->CanUseDefaultCredentials(origin_); | 186 return url_security_manager_->CanUseDefaultCredentials(origin_); |
| 186 } | 187 } |
| 187 | 188 |
| 188 bool HttpAuthHandlerNegotiate::AllowsExplicitCredentials() { | 189 bool HttpAuthHandlerNegotiate::AllowsExplicitCredentials() { |
| 189 return auth_system_.AllowsExplicitCredentials(); | 190 return auth_system_.AllowsExplicitCredentials(); |
| 190 } | 191 } |
| 191 | 192 |
| 192 // The Negotiate challenge header looks like: | 193 // The Negotiate challenge header looks like: |
| 193 // WWW-Authenticate: NEGOTIATE auth-data | 194 // WWW-Authenticate: NEGOTIATE auth-data |
| 194 bool HttpAuthHandlerNegotiate::Init(HttpAuthChallengeTokenizer* challenge) { | 195 int HttpAuthHandlerNegotiate::Init( |
| 196 const HttpAuthChallengeTokenizer& challenge) { |
| 195 #if defined(OS_POSIX) | 197 #if defined(OS_POSIX) |
| 196 if (!auth_system_.Init()) { | 198 if (!auth_system_.Init()) { |
| 197 VLOG(1) << "can't initialize GSSAPI library"; | 199 VLOG(1) << "can't initialize GSSAPI library"; |
| 198 return false; | 200 return ERR_UNSUPPORTED_AUTH_SCHEME; |
| 199 } | 201 } |
| 200 // GSSAPI does not provide a way to enter username/password to | 202 // GSSAPI does not provide a way to enter username/password to |
| 201 // obtain a TGT. If the default credentials are not allowed for | 203 // obtain a TGT. If the default credentials are not allowed for |
| 202 // a particular site (based on whitelist), fall back to a | 204 // a particular site (based on whitelist), fall back to a |
| 203 // different scheme. | 205 // different scheme. |
| 204 if (!AllowsDefaultCredentials()) | 206 if (!AllowsDefaultCredentials()) |
| 205 return false; | 207 return ERR_UNSUPPORTED_AUTH_SCHEME; |
| 206 #endif | 208 #endif |
| 207 if (CanDelegate()) | 209 if (CanDelegate()) |
| 208 auth_system_.Delegate(); | 210 auth_system_.Delegate(); |
| 209 auth_scheme_ = "negotiate"; | 211 auth_scheme_ = "negotiate"; |
| 210 HttpAuth::AuthorizationResult auth_result = | 212 HttpAuth::AuthorizationResult auth_result = |
| 211 auth_system_.ParseChallenge(challenge); | 213 auth_system_.ParseChallenge(challenge); |
| 212 return (auth_result == HttpAuth::AUTHORIZATION_RESULT_ACCEPT); | 214 return auth_result == HttpAuth::AUTHORIZATION_RESULT_ACCEPT |
| 215 ? OK |
| 216 : ERR_INVALID_RESPONSE; |
| 213 } | 217 } |
| 214 | 218 |
| 215 int HttpAuthHandlerNegotiate::GenerateAuthTokenImpl( | 219 int HttpAuthHandlerNegotiate::GenerateAuthTokenImpl( |
| 216 const AuthCredentials* credentials, const HttpRequestInfo* request, | 220 const AuthCredentials* credentials, |
| 217 const CompletionCallback& callback, std::string* auth_token) { | 221 const HttpRequestInfo& request, |
| 222 const CompletionCallback& callback, |
| 223 std::string* auth_token) { |
| 218 DCHECK(callback_.is_null()); | 224 DCHECK(callback_.is_null()); |
| 219 DCHECK(auth_token_ == NULL); | 225 DCHECK(auth_token_ == NULL); |
| 220 auth_token_ = auth_token; | 226 auth_token_ = auth_token; |
| 221 if (already_called_) { | 227 if (already_called_) { |
| 222 DCHECK((!has_credentials_ && credentials == NULL) || | 228 DCHECK((!has_credentials_ && credentials == NULL) || |
| 223 (has_credentials_ && credentials->Equals(credentials_))); | 229 (has_credentials_ && credentials->Equals(credentials_))); |
| 224 next_state_ = STATE_GENERATE_AUTH_TOKEN; | 230 next_state_ = STATE_GENERATE_AUTH_TOKEN; |
| 225 } else { | 231 } else { |
| 226 already_called_ = true; | 232 already_called_ = true; |
| 227 if (credentials) { | 233 if (credentials) { |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 bool HttpAuthHandlerNegotiate::CanDelegate() const { | 341 bool HttpAuthHandlerNegotiate::CanDelegate() const { |
| 336 // TODO(cbentzel): Should delegation be allowed on proxies? | 342 // TODO(cbentzel): Should delegation be allowed on proxies? |
| 337 if (target_ == HttpAuth::AUTH_PROXY) | 343 if (target_ == HttpAuth::AUTH_PROXY) |
| 338 return false; | 344 return false; |
| 339 if (!url_security_manager_) | 345 if (!url_security_manager_) |
| 340 return false; | 346 return false; |
| 341 return url_security_manager_->CanDelegate(origin_); | 347 return url_security_manager_->CanDelegate(origin_); |
| 342 } | 348 } |
| 343 | 349 |
| 344 } // namespace net | 350 } // namespace net |
| OLD | NEW |