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 |