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

Side by Side Diff: chrome/browser/chromeos/login/parallel_authenticator.cc

Issue 9466005: Make sure the device recovers from policy loss in the consumer case. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased to ToT and cleaned up the unit tests. Created 8 years, 9 months 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 | Annotate | Revision Log
OLDNEW
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 "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/file_path.h" 9 #include "base/file_path.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/path_service.h" 12 #include "base/path_service.h"
13 #include "base/string_util.h" 13 #include "base/string_util.h"
14 #include "chrome/browser/chromeos/boot_times_loader.h" 14 #include "chrome/browser/chromeos/boot_times_loader.h"
15 #include "chrome/browser/chromeos/cros/cros_library.h" 15 #include "chrome/browser/chromeos/cros/cros_library.h"
16 #include "chrome/browser/chromeos/cros/cryptohome_library.h" 16 #include "chrome/browser/chromeos/cros/cryptohome_library.h"
17 #include "chrome/browser/chromeos/cros_settings.h"
17 #include "chrome/browser/chromeos/cryptohome/async_method_caller.h" 18 #include "chrome/browser/chromeos/cryptohome/async_method_caller.h"
19 #include "chrome/browser/chromeos/dbus/cryptohome_client.h"
20 #include "chrome/browser/chromeos/dbus/dbus_thread_manager.h"
18 #include "chrome/browser/chromeos/login/authentication_notification_details.h" 21 #include "chrome/browser/chromeos/login/authentication_notification_details.h"
19 #include "chrome/browser/chromeos/login/login_status_consumer.h" 22 #include "chrome/browser/chromeos/login/login_status_consumer.h"
20 #include "chrome/browser/chromeos/login/ownership_service.h" 23 #include "chrome/browser/chromeos/login/ownership_service.h"
21 #include "chrome/browser/chromeos/login/user_manager.h" 24 #include "chrome/browser/chromeos/login/user_manager.h"
22 #include "chrome/common/chrome_notification_types.h" 25 #include "chrome/common/chrome_notification_types.h"
23 #include "chrome/common/chrome_paths.h" 26 #include "chrome/common/chrome_paths.h"
24 #include "chrome/common/chrome_switches.h" 27 #include "chrome/common/chrome_switches.h"
25 #include "content/public/browser/browser_thread.h" 28 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/notification_service.h" 29 #include "content/public/browser/notification_service.h"
27 #include "third_party/cros_system_api/dbus/service_constants.h" 30 #include "third_party/cros_system_api/dbus/service_constants.h"
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 165
163 } // namespace 166 } // namespace
164 167
165 ParallelAuthenticator::ParallelAuthenticator(LoginStatusConsumer* consumer) 168 ParallelAuthenticator::ParallelAuthenticator(LoginStatusConsumer* consumer)
166 : Authenticator(consumer), 169 : Authenticator(consumer),
167 migrate_attempted_(false), 170 migrate_attempted_(false),
168 remove_attempted_(false), 171 remove_attempted_(false),
169 mount_guest_attempted_(false), 172 mount_guest_attempted_(false),
170 check_key_attempted_(false), 173 check_key_attempted_(false),
171 already_reported_success_(false), 174 already_reported_success_(false),
175 owner_is_verified_(false),
176 user_can_login_(false),
172 using_oauth_( 177 using_oauth_(
173 !CommandLine::ForCurrentProcess()->HasSwitch( 178 !CommandLine::ForCurrentProcess()->HasSwitch(
174 switches::kSkipOAuthLogin)) { 179 switches::kSkipOAuthLogin)) {
175 // If not already owned, this is a no-op. If it is, this loads the owner's 180 // If not already owned, this is a no-op. If it is, this loads the owner's
176 // public key off of disk. 181 // public key off of disk.
177 OwnershipService::GetSharedInstance()->StartLoadOwnerKeyAttempt(); 182 OwnershipService::GetSharedInstance()->StartLoadOwnerKeyAttempt();
178 } 183 }
179 184
180 ParallelAuthenticator::~ParallelAuthenticator() {} 185 ParallelAuthenticator::~ParallelAuthenticator() {}
181 186
182 void ParallelAuthenticator::AuthenticateToLogin( 187 void ParallelAuthenticator::AuthenticateToLogin(
183 Profile* profile, 188 Profile* profile,
184 const std::string& username, 189 const std::string& username,
185 const std::string& password, 190 const std::string& password,
186 const std::string& login_token, 191 const std::string& login_token,
187 const std::string& login_captcha) { 192 const std::string& login_captcha) {
188 std::string canonicalized = Authenticator::Canonicalize(username); 193 std::string canonicalized = Authenticator::Canonicalize(username);
189 authentication_profile_ = profile; 194 authentication_profile_ = profile;
190 current_state_.reset( 195 current_state_.reset(
191 new AuthAttemptState( 196 new AuthAttemptState(
192 canonicalized, 197 canonicalized,
193 password, 198 password,
194 CrosLibrary::Get()->GetCryptohomeLibrary()->HashPassword(password), 199 CrosLibrary::Get()->GetCryptohomeLibrary()->HashPassword(password),
195 login_token, 200 login_token,
196 login_captcha, 201 login_captcha,
197 !UserManager::Get()->IsKnownUser(canonicalized))); 202 !UserManager::Get()->IsKnownUser(canonicalized)));
203 {
204 // Reset the verified flag.
205 base::AutoLock for_this_block(owner_verified_lock_);
206 owner_is_verified_ = false;
207 }
208
198 const bool create_if_missing = false; 209 const bool create_if_missing = false;
199 BrowserThread::PostTask( 210 BrowserThread::PostTask(
200 BrowserThread::UI, FROM_HERE, 211 BrowserThread::UI, FROM_HERE,
201 base::Bind(&Mount, 212 base::Bind(&Mount,
202 current_state_.get(), 213 current_state_.get(),
203 static_cast<AuthAttemptStateResolver*>(this), 214 static_cast<AuthAttemptStateResolver*>(this),
204 create_if_missing)); 215 create_if_missing));
205
206 // ClientLogin authentication check should happen immediately here. 216 // ClientLogin authentication check should happen immediately here.
207 // We should not try OAuthLogin check until the profile loads. 217 // We should not try OAuthLogin check until the profile loads.
208 if (!using_oauth_) { 218 if (!using_oauth_) {
209 // Initiate ClientLogin-based post authentication. 219 // Initiate ClientLogin-based post authentication.
210 current_online_.reset(new OnlineAttempt(using_oauth_, 220 current_online_.reset(new OnlineAttempt(using_oauth_,
211 current_state_.get(), 221 current_state_.get(),
212 this)); 222 this));
213 current_online_->Initiate(profile); 223 current_online_->Initiate(profile);
214 } 224 }
215 } 225 }
216 226
217 void ParallelAuthenticator::CompleteLogin(Profile* profile, 227 void ParallelAuthenticator::CompleteLogin(Profile* profile,
218 const std::string& username, 228 const std::string& username,
219 const std::string& password) { 229 const std::string& password) {
220 std::string canonicalized = Authenticator::Canonicalize(username); 230 std::string canonicalized = Authenticator::Canonicalize(username);
221 authentication_profile_ = profile; 231 authentication_profile_ = profile;
222 current_state_.reset( 232 current_state_.reset(
223 new AuthAttemptState( 233 new AuthAttemptState(
224 canonicalized, 234 canonicalized,
225 password, 235 password,
226 CrosLibrary::Get()->GetCryptohomeLibrary()->HashPassword(password), 236 CrosLibrary::Get()->GetCryptohomeLibrary()->HashPassword(password),
227 !UserManager::Get()->IsKnownUser(canonicalized))); 237 !UserManager::Get()->IsKnownUser(canonicalized)));
238 {
239 // Reset the verified flag.
240 base::AutoLock for_this_block(owner_verified_lock_);
241 owner_is_verified_ = false;
242 }
243
228 const bool create_if_missing = false; 244 const bool create_if_missing = false;
229 BrowserThread::PostTask( 245 BrowserThread::PostTask(
230 BrowserThread::UI, FROM_HERE, 246 BrowserThread::UI, FROM_HERE,
231 base::Bind(&Mount, 247 base::Bind(&Mount,
232 current_state_.get(), 248 current_state_.get(),
233 static_cast<AuthAttemptStateResolver*>(this), 249 static_cast<AuthAttemptStateResolver*>(this),
234 create_if_missing)); 250 create_if_missing));
235 251
236 if (!using_oauth_) { 252 if (!using_oauth_) {
237 // Test automation needs to disable oauth, but that leads to other 253 // Test automation needs to disable oauth, but that leads to other
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 void ParallelAuthenticator::ResyncEncryptedData() { 386 void ParallelAuthenticator::ResyncEncryptedData() {
371 remove_attempted_ = true; 387 remove_attempted_ = true;
372 current_state_->ResetCryptohomeStatus(); 388 current_state_->ResetCryptohomeStatus();
373 BrowserThread::PostTask( 389 BrowserThread::PostTask(
374 BrowserThread::UI, FROM_HERE, 390 BrowserThread::UI, FROM_HERE,
375 base::Bind(&Remove, 391 base::Bind(&Remove,
376 current_state_.get(), 392 current_state_.get(),
377 static_cast<AuthAttemptStateResolver*>(this))); 393 static_cast<AuthAttemptStateResolver*>(this)));
378 } 394 }
379 395
396 bool ParallelAuthenticator::VerifyOwner() {
397 base::AutoLock for_this_block(owner_verified_lock_);
398 if (owner_is_verified_)
399 return true;
400 // Check if policy data is fine and continue in safe mode if needed.
401 bool is_safe_mode = false;
402 CrosSettings::Get()->GetBoolean(kPolicyMissingMitigationMode, &is_safe_mode);
403 if (!is_safe_mode) {
404 // Now we can continue with the login and report mount success.
405 user_can_login_ = true;
406 owner_is_verified_ = true;
407 return true;
408 }
409 // First we have to make sure the current user's cert store is available.
410 UserManager::Get()->LoadKeyStore();
411 // Now we can continue reading the private key.
412 BrowserThread::PostTask(
413 BrowserThread::FILE, FROM_HERE,
414 base::Bind(&ParallelAuthenticator::FinishVerifyOwnerOnFileThread, this));
415 return false;
416 }
417
418 void ParallelAuthenticator::FinishVerifyOwnerOnFileThread() {
419 base::AutoLock for_this_block(owner_verified_lock_);
420 // Now we can check if this user is the owner.
421 user_can_login_ =
422 OwnershipService::GetSharedInstance()->IsCurrentUserOwner();
423 owner_is_verified_ = true;
424 BrowserThread::PostTask(
425 BrowserThread::UI, FROM_HERE,
426 base::Bind(&ParallelAuthenticator::Resolve, this));
427 }
428
380 void ParallelAuthenticator::RetryAuth(Profile* profile, 429 void ParallelAuthenticator::RetryAuth(Profile* profile,
381 const std::string& username, 430 const std::string& username,
382 const std::string& password, 431 const std::string& password,
383 const std::string& login_token, 432 const std::string& login_token,
384 const std::string& login_captcha) { 433 const std::string& login_captcha) {
385 reauth_state_.reset( 434 reauth_state_.reset(
386 new AuthAttemptState( 435 new AuthAttemptState(
387 Authenticator::Canonicalize(username), 436 Authenticator::Canonicalize(username),
388 password, 437 password,
389 CrosLibrary::Get()->GetCryptohomeLibrary()->HashPassword(password), 438 CrosLibrary::Get()->GetCryptohomeLibrary()->HashPassword(password),
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 break; 588 break;
540 case LOGIN_FAILED: 589 case LOGIN_FAILED:
541 current_state_->ResetCryptohomeStatus(); 590 current_state_->ResetCryptohomeStatus();
542 BrowserThread::PostTask(BrowserThread::UI, 591 BrowserThread::PostTask(BrowserThread::UI,
543 FROM_HERE, 592 FROM_HERE,
544 base::Bind( 593 base::Bind(
545 &ParallelAuthenticator::OnLoginFailure, 594 &ParallelAuthenticator::OnLoginFailure,
546 this, 595 this,
547 current_state_->online_outcome())); 596 current_state_->online_outcome()));
548 break; 597 break;
598 case OWNER_REQUIRED: {
599 current_state_->ResetCryptohomeStatus();
600 bool success = false;
601 DBusThreadManager::Get()->GetCryptohomeClient()->Unmount(&success);
602 if (!success) {
603 // Maybe we should reboot immediately here?
604 LOG(ERROR) << "Couldn't unmount users home!";
605 }
606 BrowserThread::PostTask(BrowserThread::UI,
607 FROM_HERE,
608 base::Bind(
609 &ParallelAuthenticator::OnLoginFailure,
610 this,
611 LoginFailure(LoginFailure::OWNER_REQUIRED)));
612 break;
613 }
549 default: 614 default:
550 NOTREACHED(); 615 NOTREACHED();
551 break; 616 break;
552 } 617 }
553 } 618 }
554 619
555 ParallelAuthenticator::AuthState ParallelAuthenticator::ResolveState() { 620 ParallelAuthenticator::AuthState ParallelAuthenticator::ResolveState() {
556 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 621 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
557 // If we haven't mounted the user's home dir yet, we can't be done. 622 // If we haven't mounted the user's home dir yet, we can't be done.
558 // We never get past here if a cryptohome op is still pending. 623 // We never get past here if a cryptohome op is still pending.
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 if (mount_guest_attempted_) { 723 if (mount_guest_attempted_) {
659 if (current_state_->username == kDemoUser) 724 if (current_state_->username == kDemoUser)
660 return DEMO_LOGIN; 725 return DEMO_LOGIN;
661 else 726 else
662 return GUEST_LOGIN; 727 return GUEST_LOGIN;
663 } 728 }
664 if (migrate_attempted_) 729 if (migrate_attempted_)
665 return RECOVER_MOUNT; 730 return RECOVER_MOUNT;
666 if (check_key_attempted_) 731 if (check_key_attempted_)
667 return UNLOCK; 732 return UNLOCK;
668 return OFFLINE_LOGIN; 733
734 if (!VerifyOwner())
735 return CONTINUE;
736 return user_can_login_ ? OFFLINE_LOGIN : OWNER_REQUIRED;
669 } 737 }
670 738
671 ParallelAuthenticator::AuthState 739 ParallelAuthenticator::AuthState
672 ParallelAuthenticator::ResolveOnlineFailureState( 740 ParallelAuthenticator::ResolveOnlineFailureState(
673 ParallelAuthenticator::AuthState offline_state) { 741 ParallelAuthenticator::AuthState offline_state) {
674 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 742 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
675 if (offline_state == OFFLINE_LOGIN) { 743 if (offline_state == OFFLINE_LOGIN) {
676 if (WasConnectionIssue(current_state_->online_outcome())) { 744 if (WasConnectionIssue(current_state_->online_outcome())) {
677 // Couldn't do an online check, so just go with the offline result. 745 // Couldn't do an online check, so just go with the offline result.
678 return OFFLINE_LOGIN; 746 return OFFLINE_LOGIN;
(...skipping 24 matching lines...) Expand all
703 return offline_state; 771 return offline_state;
704 } 772 }
705 } 773 }
706 774
707 void ParallelAuthenticator::ResolveLoginCompletionStatus() { 775 void ParallelAuthenticator::ResolveLoginCompletionStatus() {
708 // Shortcut online state resolution process. 776 // Shortcut online state resolution process.
709 current_state_->RecordOnlineLoginStatus(LoginFailure::None()); 777 current_state_->RecordOnlineLoginStatus(LoginFailure::None());
710 Resolve(); 778 Resolve();
711 } 779 }
712 780
781 void ParallelAuthenticator::SetOwnerState(bool owner_check_finished,
782 bool check_result) {
783 base::AutoLock for_this_block(owner_verified_lock_);
784 owner_is_verified_ = owner_check_finished;
785 user_can_login_ = check_result;
786 }
787
713 } // namespace chromeos 788 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698