Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(142)

Side by Side Diff: net/http/http_auth_controller.cc

Issue 8340026: Use AuthCredentials throughout the network stack instead of username/password. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Reduce password zapping Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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_controller.h" 5 #include "net/http/http_auth_controller.h"
6 6
7 #include "base/metrics/histogram.h" 7 #include "base/metrics/histogram.h"
8 #include "base/string_util.h" 8 #include "base/string_util.h"
9 #include "base/threading/platform_thread.h" 9 #include "base/threading/platform_thread.h"
10 #include "base/utf_string_conversions.h" 10 #include "base/utf_string_conversions.h"
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 user_callback_ = NULL; 172 user_callback_ = NULL;
173 } 173 }
174 174
175 int HttpAuthController::MaybeGenerateAuthToken(const HttpRequestInfo* request, 175 int HttpAuthController::MaybeGenerateAuthToken(const HttpRequestInfo* request,
176 OldCompletionCallback* callback, 176 OldCompletionCallback* callback,
177 const BoundNetLog& net_log) { 177 const BoundNetLog& net_log) {
178 DCHECK(CalledOnValidThread()); 178 DCHECK(CalledOnValidThread());
179 bool needs_auth = HaveAuth() || SelectPreemptiveAuth(net_log); 179 bool needs_auth = HaveAuth() || SelectPreemptiveAuth(net_log);
180 if (!needs_auth) 180 if (!needs_auth)
181 return OK; 181 return OK;
182 const string16* username = NULL; 182 const AuthCredentials* credentials = NULL;
183 const string16* password = NULL; 183 if (identity_.source != HttpAuth::IDENT_SRC_DEFAULT_CREDENTIALS)
184 if (identity_.source != HttpAuth::IDENT_SRC_DEFAULT_CREDENTIALS) { 184 credentials = &identity_.credentials;
185 username = &identity_.username;
186 password = &identity_.password;
187 }
188 DCHECK(auth_token_.empty()); 185 DCHECK(auth_token_.empty());
189 DCHECK(NULL == user_callback_); 186 DCHECK(NULL == user_callback_);
190 int rv = handler_->GenerateAuthToken(username, 187 int rv = handler_->GenerateAuthToken(credentials,
191 password,
192 request, 188 request,
193 &io_callback_, 189 &io_callback_,
194 &auth_token_); 190 &auth_token_);
195 if (DisableOnAuthHandlerResult(rv)) 191 if (DisableOnAuthHandlerResult(rv))
196 rv = OK; 192 rv = OK;
197 if (rv == ERR_IO_PENDING) 193 if (rv == ERR_IO_PENDING)
198 user_callback_ = callback; 194 user_callback_ = callback;
199 else 195 else
200 OnIOComplete(rv); 196 OnIOComplete(rv);
201 return rv; 197 return rv;
(...skipping 24 matching lines...) Expand all
226 CreatePreemptiveAuthHandlerFromString(entry->auth_challenge(), target_, 222 CreatePreemptiveAuthHandlerFromString(entry->auth_challenge(), target_,
227 auth_origin_, 223 auth_origin_,
228 entry->IncrementNonceCount(), 224 entry->IncrementNonceCount(),
229 net_log, &handler_preemptive); 225 net_log, &handler_preemptive);
230 if (rv_create != OK) 226 if (rv_create != OK)
231 return false; 227 return false;
232 228
233 // Set the state 229 // Set the state
234 identity_.source = HttpAuth::IDENT_SRC_PATH_LOOKUP; 230 identity_.source = HttpAuth::IDENT_SRC_PATH_LOOKUP;
235 identity_.invalid = false; 231 identity_.invalid = false;
236 identity_.username = entry->username(); 232 identity_.credentials = entry->credentials();
237 identity_.password = entry->password();
238 handler_.swap(handler_preemptive); 233 handler_.swap(handler_preemptive);
239 return true; 234 return true;
240 } 235 }
241 236
242 void HttpAuthController::AddAuthorizationHeader( 237 void HttpAuthController::AddAuthorizationHeader(
243 HttpRequestHeaders* authorization_headers) { 238 HttpRequestHeaders* authorization_headers) {
244 DCHECK(CalledOnValidThread()); 239 DCHECK(CalledOnValidThread());
245 DCHECK(HaveAuth()); 240 DCHECK(HaveAuth());
246 // auth_token_ can be empty if we encountered a permanent error with 241 // auth_token_ can be empty if we encountered a permanent error with
247 // the auth scheme and want to retry. 242 // the auth scheme and want to retry.
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 369
375 // If we get here and we don't have a handler_, that's because we 370 // If we get here and we don't have a handler_, that's because we
376 // invalidated it due to not having any viable identities to use with it. Go 371 // invalidated it due to not having any viable identities to use with it. Go
377 // back and try again. 372 // back and try again.
378 // TODO(asanka): Instead we should create a priority list of 373 // TODO(asanka): Instead we should create a priority list of
379 // <handler,identity> and iterate through that. 374 // <handler,identity> and iterate through that.
380 } while(!handler_.get()); 375 } while(!handler_.get());
381 return OK; 376 return OK;
382 } 377 }
383 378
384 void HttpAuthController::ResetAuth(const string16& username, 379 void HttpAuthController::ResetAuth(const AuthCredentials& credentials) {
385 const string16& password) {
386 DCHECK(CalledOnValidThread()); 380 DCHECK(CalledOnValidThread());
387 DCHECK(identity_.invalid || (username.empty() && password.empty())); 381 DCHECK(identity_.invalid || credentials.Empty());
388 382
389 if (identity_.invalid) { 383 if (identity_.invalid) {
390 // Update the username/password. 384 // Update the username/password.
391 identity_.source = HttpAuth::IDENT_SRC_EXTERNAL; 385 identity_.source = HttpAuth::IDENT_SRC_EXTERNAL;
392 identity_.invalid = false; 386 identity_.invalid = false;
393 identity_.username = username; 387 identity_.credentials = credentials;
394 identity_.password = password;
395 } 388 }
396 389
397 DCHECK(identity_.source != HttpAuth::IDENT_SRC_PATH_LOOKUP); 390 DCHECK(identity_.source != HttpAuth::IDENT_SRC_PATH_LOOKUP);
398 391
399 // Add the auth entry to the cache before restarting. We don't know whether 392 // Add the auth entry to the cache before restarting. We don't know whether
400 // the identity is valid yet, but if it is valid we want other transactions 393 // the identity is valid yet, but if it is valid we want other transactions
401 // to know about it. If an entry for (origin, handler->realm()) already 394 // to know about it. If an entry for (origin, handler->realm()) already
402 // exists, we update it. 395 // exists, we update it.
403 // 396 //
404 // If identity_.source is HttpAuth::IDENT_SRC_NONE or 397 // If identity_.source is HttpAuth::IDENT_SRC_NONE or
405 // HttpAuth::IDENT_SRC_DEFAULT_CREDENTIALS, identity_ contains no 398 // HttpAuth::IDENT_SRC_DEFAULT_CREDENTIALS, identity_ contains no
406 // identity because identity is not required yet or we're using default 399 // identity because identity is not required yet or we're using default
407 // credentials. 400 // credentials.
408 // 401 //
409 // TODO(wtc): For NTLM_SSPI, we add the same auth entry to the cache in 402 // TODO(wtc): For NTLM_SSPI, we add the same auth entry to the cache in
410 // round 1 and round 2, which is redundant but correct. It would be nice 403 // round 1 and round 2, which is redundant but correct. It would be nice
411 // to add an auth entry to the cache only once, preferrably in round 1. 404 // to add an auth entry to the cache only once, preferrably in round 1.
412 // See http://crbug.com/21015. 405 // See http://crbug.com/21015.
413 switch (identity_.source) { 406 switch (identity_.source) {
414 case HttpAuth::IDENT_SRC_NONE: 407 case HttpAuth::IDENT_SRC_NONE:
415 case HttpAuth::IDENT_SRC_DEFAULT_CREDENTIALS: 408 case HttpAuth::IDENT_SRC_DEFAULT_CREDENTIALS:
416 break; 409 break;
417 default: 410 default:
418 http_auth_cache_->Add(auth_origin_, handler_->realm(), 411 http_auth_cache_->Add(auth_origin_, handler_->realm(),
419 handler_->auth_scheme(), handler_->challenge(), 412 handler_->auth_scheme(), handler_->challenge(),
420 identity_.username, identity_.password, 413 identity_.credentials, auth_path_);
421 auth_path_);
422 break; 414 break;
423 } 415 }
424 } 416 }
425 417
426 bool HttpAuthController::HaveAuthHandler() const { 418 bool HttpAuthController::HaveAuthHandler() const {
427 return handler_.get() != NULL; 419 return handler_.get() != NULL;
428 } 420 }
429 421
430 bool HttpAuthController::HaveAuth() const { 422 bool HttpAuthController::HaveAuth() const {
431 return handler_.get() && !identity_.invalid; 423 return handler_.get() && !identity_.invalid;
(...skipping 13 matching lines...) Expand all
445 } 437 }
446 438
447 void HttpAuthController::InvalidateRejectedAuthFromCache() { 439 void HttpAuthController::InvalidateRejectedAuthFromCache() {
448 DCHECK(CalledOnValidThread()); 440 DCHECK(CalledOnValidThread());
449 DCHECK(HaveAuth()); 441 DCHECK(HaveAuth());
450 442
451 // Clear the cache entry for the identity we just failed on. 443 // Clear the cache entry for the identity we just failed on.
452 // Note: we require the username/password to match before invalidating 444 // Note: we require the username/password to match before invalidating
453 // since the entry in the cache may be newer than what we used last time. 445 // since the entry in the cache may be newer than what we used last time.
454 http_auth_cache_->Remove(auth_origin_, handler_->realm(), 446 http_auth_cache_->Remove(auth_origin_, handler_->realm(),
455 handler_->auth_scheme(), identity_.username, 447 handler_->auth_scheme(), identity_.credentials);
456 identity_.password);
457 } 448 }
458 449
459 bool HttpAuthController::SelectNextAuthIdentityToTry() { 450 bool HttpAuthController::SelectNextAuthIdentityToTry() {
460 DCHECK(CalledOnValidThread()); 451 DCHECK(CalledOnValidThread());
461 DCHECK(handler_.get()); 452 DCHECK(handler_.get());
462 DCHECK(identity_.invalid); 453 DCHECK(identity_.invalid);
463 454
464 // Try to use the username/password encoded into the URL first. 455 // Try to use the username/password encoded into the URL first.
465 if (target_ == HttpAuth::AUTH_SERVER && auth_url_.has_username() && 456 if (target_ == HttpAuth::AUTH_SERVER && auth_url_.has_username() &&
466 !embedded_identity_used_) { 457 !embedded_identity_used_) {
467 identity_.source = HttpAuth::IDENT_SRC_URL; 458 identity_.source = HttpAuth::IDENT_SRC_URL;
468 identity_.invalid = false; 459 identity_.invalid = false;
469 // Extract the username:password from the URL. 460 // Extract the username:password from the URL.
470 GetIdentityFromURL(auth_url_, 461 string16 username;
471 &identity_.username, 462 string16 password;
472 &identity_.password); 463 GetIdentityFromURL(auth_url_, &username, &password);
464 identity_.credentials.Set(username, password);
473 embedded_identity_used_ = true; 465 embedded_identity_used_ = true;
474 // TODO(eroman): If the password is blank, should we also try combining 466 // TODO(eroman): If the password is blank, should we also try combining
475 // with a password from the cache? 467 // with a password from the cache?
476 return true; 468 return true;
477 } 469 }
478 470
479 // Check the auth cache for a realm entry. 471 // Check the auth cache for a realm entry.
480 HttpAuthCache::Entry* entry = 472 HttpAuthCache::Entry* entry =
481 http_auth_cache_->Lookup(auth_origin_, handler_->realm(), 473 http_auth_cache_->Lookup(auth_origin_, handler_->realm(),
482 handler_->auth_scheme()); 474 handler_->auth_scheme());
483 475
484 if (entry) { 476 if (entry) {
485 identity_.source = HttpAuth::IDENT_SRC_REALM_LOOKUP; 477 identity_.source = HttpAuth::IDENT_SRC_REALM_LOOKUP;
486 identity_.invalid = false; 478 identity_.invalid = false;
487 identity_.username = entry->username(); 479 identity_.credentials = entry->credentials();
488 identity_.password = entry->password();
489 return true; 480 return true;
490 } 481 }
491 482
492 // Use default credentials (single sign on) if this is the first attempt 483 // Use default credentials (single sign on) if this is the first attempt
493 // at identity. Do not allow multiple times as it will infinite loop. 484 // at identity. Do not allow multiple times as it will infinite loop.
494 // We use default credentials after checking the auth cache so that if 485 // We use default credentials after checking the auth cache so that if
495 // single sign-on doesn't work, we won't try default credentials for future 486 // single sign-on doesn't work, we won't try default credentials for future
496 // transactions. 487 // transactions.
497 if (!default_credentials_used_ && handler_->AllowsDefaultCredentials()) { 488 if (!default_credentials_used_ && handler_->AllowsDefaultCredentials()) {
498 identity_.source = HttpAuth::IDENT_SRC_DEFAULT_CREDENTIALS; 489 identity_.source = HttpAuth::IDENT_SRC_DEFAULT_CREDENTIALS;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 DCHECK(CalledOnValidThread()); 558 DCHECK(CalledOnValidThread());
568 return disabled_schemes_.find(scheme) != disabled_schemes_.end(); 559 return disabled_schemes_.find(scheme) != disabled_schemes_.end();
569 } 560 }
570 561
571 void HttpAuthController::DisableAuthScheme(HttpAuth::Scheme scheme) { 562 void HttpAuthController::DisableAuthScheme(HttpAuth::Scheme scheme) {
572 DCHECK(CalledOnValidThread()); 563 DCHECK(CalledOnValidThread());
573 disabled_schemes_.insert(scheme); 564 disabled_schemes_.insert(scheme);
574 } 565 }
575 566
576 } // namespace net 567 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698