Chromium Code Reviews| 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 "chrome/browser/chromeos/login/parallel_authenticator.h" | 5 #include "chrome/browser/chromeos/login/parallel_authenticator.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/file_path.h" | 12 #include "base/file_path.h" |
| 13 #include "base/file_util.h" | 13 #include "base/file_util.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/path_service.h" | 15 #include "base/path_service.h" |
| 16 #include "base/string_util.h" | 16 #include "base/string_util.h" |
| 17 #include "base/synchronization/lock.h" | 17 #include "base/synchronization/lock.h" |
| 18 #include "chrome/browser/chromeos/cros/cert_library.h" | 18 #include "chrome/browser/chromeos/cros/cert_library.h" |
| 19 #include "chrome/browser/chromeos/cros/cryptohome_library.h" | 19 #include "chrome/browser/chromeos/cros/cryptohome_library.h" |
| 20 #include "chrome/browser/chromeos/cros_settings.h" | |
| 20 #include "chrome/browser/chromeos/login/auth_response_handler.h" | 21 #include "chrome/browser/chromeos/login/auth_response_handler.h" |
| 21 #include "chrome/browser/chromeos/login/authentication_notification_details.h" | 22 #include "chrome/browser/chromeos/login/authentication_notification_details.h" |
| 22 #include "chrome/browser/chromeos/login/login_status_consumer.h" | 23 #include "chrome/browser/chromeos/login/login_status_consumer.h" |
| 23 #include "chrome/browser/chromeos/login/ownership_service.h" | 24 #include "chrome/browser/chromeos/login/ownership_service.h" |
| 24 #include "chrome/browser/chromeos/login/user_manager.h" | 25 #include "chrome/browser/chromeos/login/user_manager.h" |
| 25 #include "chrome/browser/profiles/profile.h" | 26 #include "chrome/browser/profiles/profile.h" |
| 26 #include "chrome/browser/profiles/profile_manager.h" | 27 #include "chrome/browser/profiles/profile_manager.h" |
| 27 #include "chrome/common/chrome_notification_types.h" | 28 #include "chrome/common/chrome_notification_types.h" |
| 28 #include "chrome/common/chrome_paths.h" | 29 #include "chrome/common/chrome_paths.h" |
| 29 #include "chrome/common/chrome_switches.h" | 30 #include "chrome/common/chrome_switches.h" |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 46 using file_util::ReadFileToString; | 47 using file_util::ReadFileToString; |
| 47 | 48 |
| 48 namespace chromeos { | 49 namespace chromeos { |
| 49 | 50 |
| 50 // static | 51 // static |
| 51 const int ParallelAuthenticator::kClientLoginTimeoutMs = 10000; | 52 const int ParallelAuthenticator::kClientLoginTimeoutMs = 10000; |
| 52 | 53 |
| 53 ParallelAuthenticator::ParallelAuthenticator(LoginStatusConsumer* consumer) | 54 ParallelAuthenticator::ParallelAuthenticator(LoginStatusConsumer* consumer) |
| 54 : Authenticator(consumer), | 55 : Authenticator(consumer), |
| 55 already_reported_success_(false), | 56 already_reported_success_(false), |
| 57 owner_is_verified_(false), | |
| 58 user_can_login_(false), | |
| 56 using_oauth_( | 59 using_oauth_( |
| 57 CommandLine::ForCurrentProcess()->HasSwitch( | 60 CommandLine::ForCurrentProcess()->HasSwitch( |
| 58 switches::kWebUILogin) && | 61 switches::kWebUILogin) && |
| 59 !CommandLine::ForCurrentProcess()->HasSwitch( | 62 !CommandLine::ForCurrentProcess()->HasSwitch( |
| 60 switches::kSkipOAuthLogin)) { | 63 switches::kSkipOAuthLogin)) { |
| 61 // If not already owned, this is a no-op. If it is, this loads the owner's | 64 // If not already owned, this is a no-op. If it is, this loads the owner's |
| 62 // public key off of disk. | 65 // public key off of disk. |
| 63 OwnershipService::GetSharedInstance()->StartLoadOwnerKeyAttempt(); | 66 OwnershipService::GetSharedInstance()->StartLoadOwnerKeyAttempt(); |
| 64 } | 67 } |
| 65 | 68 |
| 66 ParallelAuthenticator::~ParallelAuthenticator() {} | 69 ParallelAuthenticator::~ParallelAuthenticator() {} |
| 67 | 70 |
| 68 void ParallelAuthenticator::AuthenticateToLogin( | 71 void ParallelAuthenticator::AuthenticateToLogin( |
| 69 Profile* profile, | 72 Profile* profile, |
| 70 const std::string& username, | 73 const std::string& username, |
| 71 const std::string& password, | 74 const std::string& password, |
| 72 const std::string& login_token, | 75 const std::string& login_token, |
| 73 const std::string& login_captcha) { | 76 const std::string& login_captcha) { |
| 74 std::string canonicalized = Authenticator::Canonicalize(username); | 77 std::string canonicalized = Authenticator::Canonicalize(username); |
| 75 authentication_profile_ = profile; | 78 authentication_profile_ = profile; |
| 76 current_state_.reset( | 79 current_state_.reset( |
| 77 new AuthAttemptState( | 80 new AuthAttemptState( |
| 78 canonicalized, | 81 canonicalized, |
| 79 password, | 82 password, |
| 80 CrosLibrary::Get()->GetCryptohomeLibrary()->HashPassword(password), | 83 CrosLibrary::Get()->GetCryptohomeLibrary()->HashPassword(password), |
| 81 login_token, | 84 login_token, |
| 82 login_captcha, | 85 login_captcha, |
| 83 !UserManager::Get()->IsKnownUser(canonicalized))); | 86 !UserManager::Get()->IsKnownUser(canonicalized))); |
| 87 { | |
| 88 LOG(ERROR) << "@@@ Resetting for " << username; | |
| 89 // Reset the verified flag. | |
| 90 base::AutoLock for_this_block(owner_verified_lock_); | |
| 91 owner_is_verified_ = false; | |
| 92 } | |
| 84 mounter_ = CryptohomeOp::CreateMountAttempt(current_state_.get(), | 93 mounter_ = CryptohomeOp::CreateMountAttempt(current_state_.get(), |
| 85 this, | 94 this, |
| 86 false /* don't create */); | 95 false /* don't create */); |
| 87 // Sadly, this MUST be on the UI thread due to sending DBus traffic :-/ | 96 // Sadly, this MUST be on the UI thread due to sending DBus traffic :-/ |
| 88 BrowserThread::PostTask( | 97 BrowserThread::PostTask( |
| 89 BrowserThread::UI, FROM_HERE, | 98 BrowserThread::UI, FROM_HERE, |
| 90 | |
| 91 base::Bind(&CryptohomeOp::Initiate, mounter_.get())); | 99 base::Bind(&CryptohomeOp::Initiate, mounter_.get())); |
| 92 // ClientLogin authentication check should happen immediately here. | 100 // ClientLogin authentication check should happen immediately here. |
| 93 // We should not try OAuthLogin check until the profile loads. | 101 // We should not try OAuthLogin check until the profile loads. |
| 94 if (!using_oauth_) { | 102 if (!using_oauth_) { |
| 95 // Initiate ClientLogin-based post authentication. | 103 // Initiate ClientLogin-based post authentication. |
| 96 current_online_ = new OnlineAttempt(using_oauth_, | 104 current_online_ = new OnlineAttempt(using_oauth_, |
| 97 current_state_.get(), | 105 current_state_.get(), |
| 98 this); | 106 this); |
| 99 current_online_->Initiate(profile); | 107 current_online_->Initiate(profile); |
| 100 } | 108 } |
| 101 } | 109 } |
| 102 | 110 |
| 103 void ParallelAuthenticator::CompleteLogin(Profile* profile, | 111 void ParallelAuthenticator::CompleteLogin(Profile* profile, |
| 104 const std::string& username, | 112 const std::string& username, |
| 105 const std::string& password) { | 113 const std::string& password) { |
| 106 std::string canonicalized = Authenticator::Canonicalize(username); | 114 std::string canonicalized = Authenticator::Canonicalize(username); |
| 107 authentication_profile_ = profile; | 115 authentication_profile_ = profile; |
| 108 current_state_.reset( | 116 current_state_.reset( |
| 109 new AuthAttemptState( | 117 new AuthAttemptState( |
| 110 canonicalized, | 118 canonicalized, |
| 111 password, | 119 password, |
| 112 CrosLibrary::Get()->GetCryptohomeLibrary()->HashPassword(password), | 120 CrosLibrary::Get()->GetCryptohomeLibrary()->HashPassword(password), |
| 113 !UserManager::Get()->IsKnownUser(canonicalized))); | 121 !UserManager::Get()->IsKnownUser(canonicalized))); |
| 122 { | |
| 123 LOG(ERROR) << "@@@ Resetting for " << username; | |
| 124 // Reset the verified flag. | |
| 125 base::AutoLock for_this_block(owner_verified_lock_); | |
| 126 owner_is_verified_ = false; | |
| 127 } | |
| 114 mounter_ = CryptohomeOp::CreateMountAttempt(current_state_.get(), | 128 mounter_ = CryptohomeOp::CreateMountAttempt(current_state_.get(), |
| 115 this, | 129 this, |
| 116 false /* don't create */); | 130 false /* don't create */); |
| 117 // Sadly, this MUST be on the UI thread due to sending DBus traffic :-/ | 131 // Sadly, this MUST be on the UI thread due to sending DBus traffic :-/ |
| 118 BrowserThread::PostTask( | 132 BrowserThread::PostTask( |
| 119 BrowserThread::UI, FROM_HERE, | 133 BrowserThread::UI, FROM_HERE, |
| 120 base::Bind(&CryptohomeOp::Initiate, mounter_.get())); | 134 base::Bind(&CryptohomeOp::Initiate, mounter_.get())); |
| 121 | 135 |
| 122 if (!using_oauth_) { | 136 if (!using_oauth_) { |
| 123 // Test automation needs to disable oauth, but that leads to other | 137 // Test automation needs to disable oauth, but that leads to other |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 246 } | 260 } |
| 247 | 261 |
| 248 void ParallelAuthenticator::ResyncRecoverHelper(CryptohomeOp* to_initiate) { | 262 void ParallelAuthenticator::ResyncRecoverHelper(CryptohomeOp* to_initiate) { |
| 249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 263 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 250 current_state_->ResetCryptohomeStatus(); | 264 current_state_->ResetCryptohomeStatus(); |
| 251 BrowserThread::PostTask( | 265 BrowserThread::PostTask( |
| 252 BrowserThread::UI, FROM_HERE, | 266 BrowserThread::UI, FROM_HERE, |
| 253 base::Bind(&CryptohomeOp::Initiate, to_initiate)); | 267 base::Bind(&CryptohomeOp::Initiate, to_initiate)); |
| 254 } | 268 } |
| 255 | 269 |
| 270 void ParallelAuthenticator::VerifyOwnerOnUIThread() { | |
| 271 // Check if policy data is fine and continue in safe mode if needed. | |
| 272 bool is_safe_mode = false; | |
| 273 CrosSettings::Get()->GetBoolean(kPolicyMissingMitigationMode, &is_safe_mode); | |
| 274 if (!is_safe_mode) { | |
| 275 base::AutoLock for_this_block(owner_verified_lock_); | |
| 276 // Now we can continue reading the private key. | |
| 277 user_can_login_ = true; | |
| 278 owner_is_verified_ = true; | |
| 279 BrowserThread::PostTask( | |
| 280 BrowserThread::IO, FROM_HERE, | |
| 281 base::Bind(&ParallelAuthenticator::Resolve, this)); | |
| 282 return; | |
| 283 } | |
| 284 // First we have to make sure the current user's cert store is available. | |
| 285 UserManager::Get()->LoadKeyStore(); | |
| 286 // Now we can continue reading the private key. | |
| 287 BrowserThread::PostTask( | |
| 288 BrowserThread::FILE, FROM_HERE, | |
| 289 base::Bind(&ParallelAuthenticator::FinishVerifyOwnerOnFileThread, this)); | |
| 290 } | |
| 291 | |
| 292 void ParallelAuthenticator::FinishVerifyOwnerOnFileThread() { | |
| 293 base::AutoLock for_this_block(owner_verified_lock_); | |
| 294 // Now we can continue reading the private key. | |
| 295 user_can_login_ = | |
| 296 OwnershipService::GetSharedInstance()->CurrentUserIsOwner(); | |
| 297 owner_is_verified_ = true; | |
| 298 BrowserThread::PostTask( | |
| 299 BrowserThread::IO, FROM_HERE, | |
| 300 base::Bind(&ParallelAuthenticator::Resolve, this)); | |
| 301 LOG(ERROR) << "@@@ Check finished: " << user_can_login_; | |
| 302 } | |
| 303 | |
| 256 void ParallelAuthenticator::RetryAuth(Profile* profile, | 304 void ParallelAuthenticator::RetryAuth(Profile* profile, |
| 257 const std::string& username, | 305 const std::string& username, |
| 258 const std::string& password, | 306 const std::string& password, |
| 259 const std::string& login_token, | 307 const std::string& login_token, |
| 260 const std::string& login_captcha) { | 308 const std::string& login_captcha) { |
| 261 reauth_state_.reset( | 309 reauth_state_.reset( |
| 262 new AuthAttemptState( | 310 new AuthAttemptState( |
| 263 Authenticator::Canonicalize(username), | 311 Authenticator::Canonicalize(username), |
| 264 password, | 312 password, |
| 265 CrosLibrary::Get()->GetCryptohomeLibrary()->HashPassword(password), | 313 CrosLibrary::Get()->GetCryptohomeLibrary()->HashPassword(password), |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 410 break; | 458 break; |
| 411 case LOGIN_FAILED: | 459 case LOGIN_FAILED: |
| 412 current_state_->ResetCryptohomeStatus(); | 460 current_state_->ResetCryptohomeStatus(); |
| 413 BrowserThread::PostTask(BrowserThread::UI, | 461 BrowserThread::PostTask(BrowserThread::UI, |
| 414 FROM_HERE, | 462 FROM_HERE, |
| 415 base::Bind( | 463 base::Bind( |
| 416 &ParallelAuthenticator::OnLoginFailure, | 464 &ParallelAuthenticator::OnLoginFailure, |
| 417 this, | 465 this, |
| 418 current_state_->online_outcome())); | 466 current_state_->online_outcome())); |
| 419 break; | 467 break; |
| 468 case OWNER_REQUIRED: | |
| 469 current_state_->ResetCryptohomeStatus(); | |
|
Chris Masone
2012/02/24 18:49:45
Hm. This doesn't actually unmount the user's cryp
pastarmovj
2012/03/13 15:21:55
Done.
| |
| 470 BrowserThread::PostTask(BrowserThread::UI, | |
| 471 FROM_HERE, | |
| 472 base::Bind( | |
| 473 &ParallelAuthenticator::OnLoginFailure, | |
| 474 this, | |
| 475 LoginFailure(LoginFailure::OWNER_REQUIRED))); | |
| 476 break; | |
| 420 default: | 477 default: |
| 421 NOTREACHED(); | 478 NOTREACHED(); |
| 422 break; | 479 break; |
| 423 } | 480 } |
| 424 } | 481 } |
| 425 | 482 |
| 426 ParallelAuthenticator::AuthState ParallelAuthenticator::ResolveState() { | 483 ParallelAuthenticator::AuthState ParallelAuthenticator::ResolveState() { |
| 427 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 484 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 428 // If we haven't mounted the user's home dir yet, we can't be done. | 485 // If we haven't mounted the user's home dir yet, we can't be done. |
| 429 // We never get past here if a cryptohome op is still pending. | 486 // We never get past here if a cryptohome op is still pending. |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 525 ParallelAuthenticator::ResolveCryptohomeSuccessState() { | 582 ParallelAuthenticator::ResolveCryptohomeSuccessState() { |
| 526 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 583 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 527 if (data_remover_.get()) | 584 if (data_remover_.get()) |
| 528 return CREATE_NEW; | 585 return CREATE_NEW; |
| 529 if (guest_mounter_.get()) | 586 if (guest_mounter_.get()) |
| 530 return GUEST_LOGIN; | 587 return GUEST_LOGIN; |
| 531 if (key_migrator_.get()) | 588 if (key_migrator_.get()) |
| 532 return RECOVER_MOUNT; | 589 return RECOVER_MOUNT; |
| 533 if (key_checker_.get()) | 590 if (key_checker_.get()) |
| 534 return UNLOCK; | 591 return UNLOCK; |
| 535 return OFFLINE_LOGIN; | 592 |
| 593 base::AutoLock for_this_block(owner_verified_lock_); | |
| 594 LOG(ERROR) << "@@@ cryptohome state " << owner_is_verified_; | |
| 595 if (!owner_is_verified_) { | |
| 596 BrowserThread::PostTask( | |
| 597 BrowserThread::UI, FROM_HERE, | |
| 598 base::Bind(&ParallelAuthenticator::VerifyOwnerOnUIThread, this)); | |
| 599 return CONTINUE; | |
| 600 } | |
| 601 return user_can_login_ ? OFFLINE_LOGIN : OWNER_REQUIRED; | |
| 536 } | 602 } |
| 537 | 603 |
| 538 namespace { | 604 namespace { |
| 539 bool WasConnectionIssue(const LoginFailure& online_outcome) { | 605 bool WasConnectionIssue(const LoginFailure& online_outcome) { |
| 540 return ((online_outcome.reason() == LoginFailure::LOGIN_TIMED_OUT) || | 606 return ((online_outcome.reason() == LoginFailure::LOGIN_TIMED_OUT) || |
| 541 (online_outcome.error().state() == | 607 (online_outcome.error().state() == |
| 542 GoogleServiceAuthError::CONNECTION_FAILED) || | 608 GoogleServiceAuthError::CONNECTION_FAILED) || |
| 543 (online_outcome.error().state() == | 609 (online_outcome.error().state() == |
| 544 GoogleServiceAuthError::REQUEST_CANCELED)); | 610 GoogleServiceAuthError::REQUEST_CANCELED)); |
| 545 } | 611 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 582 } | 648 } |
| 583 | 649 |
| 584 void ParallelAuthenticator::ResolveLoginCompletionStatus() { | 650 void ParallelAuthenticator::ResolveLoginCompletionStatus() { |
| 585 // Shortcut online state resolution process. | 651 // Shortcut online state resolution process. |
| 586 current_state_->RecordOnlineLoginStatus(GaiaAuthConsumer::ClientLoginResult(), | 652 current_state_->RecordOnlineLoginStatus(GaiaAuthConsumer::ClientLoginResult(), |
| 587 LoginFailure::None()); | 653 LoginFailure::None()); |
| 588 Resolve(); | 654 Resolve(); |
| 589 } | 655 } |
| 590 | 656 |
| 591 } // namespace chromeos | 657 } // namespace chromeos |
| OLD | NEW |