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

Unified Diff: chrome/browser/chromeos/login/parallel_authenticator.cc

Issue 286933002: [cros login] Split login related classes into subfolders. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix includes in new tests Created 6 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/login/parallel_authenticator.cc
diff --git a/chrome/browser/chromeos/login/parallel_authenticator.cc b/chrome/browser/chromeos/login/parallel_authenticator.cc
deleted file mode 100644
index 1352859de47e32426deb168a6ea6459880cbdc24..0000000000000000000000000000000000000000
--- a/chrome/browser/chromeos/login/parallel_authenticator.cc
+++ /dev/null
@@ -1,844 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/chromeos/login/parallel_authenticator.h"
-
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/chromeos/boot_times_loader.h"
-#include "chrome/browser/chromeos/login/authentication_notification_details.h"
-#include "chrome/browser/chromeos/login/login_status_consumer.h"
-#include "chrome/browser/chromeos/login/user.h"
-#include "chrome/browser/chromeos/login/user_manager.h"
-#include "chrome/browser/chromeos/settings/cros_settings.h"
-#include "chrome/common/chrome_switches.h"
-#include "chromeos/cryptohome/async_method_caller.h"
-#include "chromeos/cryptohome/system_salt_getter.h"
-#include "chromeos/dbus/cryptohome_client.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/login/login_state.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/notification_service.h"
-#include "crypto/sha2.h"
-#include "google_apis/gaia/gaia_auth_util.h"
-#include "third_party/cros_system_api/dbus/service_constants.h"
-
-using content::BrowserThread;
-
-namespace chromeos {
-
-namespace {
-
-// Length of password hashed with SHA-256.
-const int kPasswordHashLength = 32;
-
-// Records status and calls resolver->Resolve().
-void TriggerResolve(AuthAttemptState* attempt,
- scoped_refptr<ParallelAuthenticator> resolver,
- bool success,
- cryptohome::MountError return_code) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- attempt->RecordCryptohomeStatus(success, return_code);
- resolver->Resolve();
-}
-
-// Records get hash status and calls resolver->Resolve().
-void TriggerResolveHash(AuthAttemptState* attempt,
- scoped_refptr<ParallelAuthenticator> resolver,
- bool success,
- const std::string& username_hash) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (success)
- attempt->RecordUsernameHash(username_hash);
- else
- attempt->RecordUsernameHashFailed();
- resolver->Resolve();
-}
-
-// Calls TriggerResolve while adding login time marker.
-void TriggerResolveWithLoginTimeMarker(
- const std::string& marker_name,
- AuthAttemptState* attempt,
- scoped_refptr<ParallelAuthenticator> resolver,
- bool success,
- cryptohome::MountError return_code) {
- chromeos::BootTimesLoader::Get()->AddLoginTimeMarker(marker_name, false);
- TriggerResolve(attempt, resolver, success, return_code);
-}
-
-// Calls cryptohome's mount method.
-void Mount(AuthAttemptState* attempt,
- scoped_refptr<ParallelAuthenticator> resolver,
- int flags,
- const std::string& system_salt) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- chromeos::BootTimesLoader::Get()->AddLoginTimeMarker(
- "CryptohomeMount-Start", false);
- // Set state that username_hash is requested here so that test implementation
- // that returns directly would not generate 2 OnLoginSucces() calls.
- attempt->UsernameHashRequested();
- cryptohome::AsyncMethodCaller::GetInstance()->AsyncMount(
- attempt->user_context.GetUserID(),
- ParallelAuthenticator::HashPassword(attempt->user_context.GetPassword(),
- system_salt),
- flags,
- base::Bind(&TriggerResolveWithLoginTimeMarker,
- "CryptohomeMount-End",
- attempt,
- resolver));
- cryptohome::AsyncMethodCaller::GetInstance()->AsyncGetSanitizedUsername(
- attempt->user_context.GetUserID(),
- base::Bind(&TriggerResolveHash,
- attempt,
- resolver));
-}
-
-// Calls cryptohome's mount method for guest.
-void MountGuest(AuthAttemptState* attempt,
- scoped_refptr<ParallelAuthenticator> resolver) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- cryptohome::AsyncMethodCaller::GetInstance()->AsyncMountGuest(
- base::Bind(&TriggerResolveWithLoginTimeMarker,
- "CryptohomeMount-End",
- attempt,
- resolver));
-}
-
-// Calls cryptohome's mount method for guest and also get the user hash from
-// cryptohome.
-void MountGuestAndGetHash(AuthAttemptState* attempt,
- scoped_refptr<ParallelAuthenticator> resolver) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- attempt->UsernameHashRequested();
- cryptohome::AsyncMethodCaller::GetInstance()->AsyncMountGuest(
- base::Bind(&TriggerResolveWithLoginTimeMarker,
- "CryptohomeMount-End",
- attempt,
- resolver));
- cryptohome::AsyncMethodCaller::GetInstance()->AsyncGetSanitizedUsername(
- attempt->user_context.GetUserID(),
- base::Bind(&TriggerResolveHash,
- attempt,
- resolver));
-}
-
-// Calls cryptohome's MountPublic method
-void MountPublic(AuthAttemptState* attempt,
- scoped_refptr<ParallelAuthenticator> resolver,
- int flags) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- cryptohome::AsyncMethodCaller::GetInstance()->AsyncMountPublic(
- attempt->user_context.GetUserID(),
- flags,
- base::Bind(&TriggerResolveWithLoginTimeMarker,
- "CryptohomeMountPublic-End",
- attempt,
- resolver));
- cryptohome::AsyncMethodCaller::GetInstance()->AsyncGetSanitizedUsername(
- attempt->user_context.GetUserID(),
- base::Bind(&TriggerResolveHash,
- attempt,
- resolver));
-}
-
-// Calls cryptohome's key migration method.
-void Migrate(AuthAttemptState* attempt,
- scoped_refptr<ParallelAuthenticator> resolver,
- bool passing_old_hash,
- const std::string& old_password,
- const std::string& system_salt) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- chromeos::BootTimesLoader::Get()->AddLoginTimeMarker(
- "CryptohomeMigrate-Start", false);
- cryptohome::AsyncMethodCaller* caller =
- cryptohome::AsyncMethodCaller::GetInstance();
- if (passing_old_hash) {
- caller->AsyncMigrateKey(
- attempt->user_context.GetUserID(),
- ParallelAuthenticator::HashPassword(old_password, system_salt),
- ParallelAuthenticator::HashPassword(attempt->user_context.GetPassword(),
- system_salt),
- base::Bind(&TriggerResolveWithLoginTimeMarker,
- "CryptohomeMount-End",
- attempt,
- resolver));
- } else {
- caller->AsyncMigrateKey(
- attempt->user_context.GetUserID(),
- ParallelAuthenticator::HashPassword(attempt->user_context.GetPassword(),
- system_salt),
- ParallelAuthenticator::HashPassword(old_password, system_salt),
- base::Bind(&TriggerResolveWithLoginTimeMarker,
- "CryptohomeMount-End",
- attempt,
- resolver));
- }
-}
-
-// Calls cryptohome's remove method.
-void Remove(AuthAttemptState* attempt,
- scoped_refptr<ParallelAuthenticator> resolver) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- chromeos::BootTimesLoader::Get()->AddLoginTimeMarker(
- "CryptohomeRemove-Start", false);
- cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
- attempt->user_context.GetUserID(),
- base::Bind(&TriggerResolveWithLoginTimeMarker,
- "CryptohomeRemove-End",
- attempt,
- resolver));
-}
-
-// Calls cryptohome's key check method.
-void CheckKey(AuthAttemptState* attempt,
- scoped_refptr<ParallelAuthenticator> resolver,
- const std::string& system_salt) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- cryptohome::AsyncMethodCaller::GetInstance()->AsyncCheckKey(
- attempt->user_context.GetUserID(),
- ParallelAuthenticator::HashPassword(attempt->user_context.GetPassword(),
- system_salt),
- base::Bind(&TriggerResolve, attempt, resolver));
-}
-
-} // namespace
-
-ParallelAuthenticator::ParallelAuthenticator(LoginStatusConsumer* consumer)
- : Authenticator(consumer),
- migrate_attempted_(false),
- remove_attempted_(false),
- resync_attempted_(false),
- ephemeral_mount_attempted_(false),
- check_key_attempted_(false),
- already_reported_success_(false),
- owner_is_verified_(false),
- user_can_login_(false),
- remove_user_data_on_failure_(false),
- delayed_login_failure_(NULL) {
-}
-
-void ParallelAuthenticator::AuthenticateToLogin(
- Profile* profile,
- const UserContext& user_context) {
- std::string canonicalized = gaia::CanonicalizeEmail(user_context.GetUserID());
- authentication_profile_ = profile;
- current_state_.reset(
- new AuthAttemptState(
- UserContext(canonicalized,
- user_context.GetPassword(),
- user_context.GetAuthCode()),
- std::string(), // login_token, not used.
- std::string(), // login_captcha, not used.
- User::USER_TYPE_REGULAR,
- !UserManager::Get()->IsKnownUser(canonicalized)));
- // Reset the verified flag.
- owner_is_verified_ = false;
-
- SystemSaltGetter::Get()->GetSystemSalt(
- base::Bind(&Mount,
- current_state_.get(),
- scoped_refptr<ParallelAuthenticator>(this),
- cryptohome::MOUNT_FLAGS_NONE));
-}
-
-void ParallelAuthenticator::CompleteLogin(Profile* profile,
- const UserContext& user_context) {
- std::string canonicalized = gaia::CanonicalizeEmail(user_context.GetUserID());
- authentication_profile_ = profile;
- current_state_.reset(
- new AuthAttemptState(
- UserContext(canonicalized,
- user_context.GetPassword(),
- user_context.GetAuthCode(),
- user_context.GetUserIDHash(),
- user_context.IsUsingOAuth(),
- user_context.GetAuthFlow()),
- !UserManager::Get()->IsKnownUser(canonicalized)));
-
- // Reset the verified flag.
- owner_is_verified_ = false;
-
- SystemSaltGetter::Get()->GetSystemSalt(
- base::Bind(&Mount,
- current_state_.get(),
- scoped_refptr<ParallelAuthenticator>(this),
- cryptohome::MOUNT_FLAGS_NONE));
-
- // For login completion from extension, we just need to resolve the current
- // auth attempt state, the rest of OAuth related tasks will be done in
- // parallel.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&ParallelAuthenticator::ResolveLoginCompletionStatus, this));
-}
-
-void ParallelAuthenticator::AuthenticateToUnlock(
- const UserContext& user_context) {
- current_state_.reset(
- new AuthAttemptState(
- gaia::CanonicalizeEmail(user_context.GetUserID()),
- user_context.GetPassword()));
- remove_user_data_on_failure_ = false;
- check_key_attempted_ = true;
- SystemSaltGetter::Get()->GetSystemSalt(
- base::Bind(&CheckKey,
- current_state_.get(),
- scoped_refptr<ParallelAuthenticator>(this)));
-}
-
-void ParallelAuthenticator::LoginAsLocallyManagedUser(
- const UserContext& user_context) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- // TODO(nkostylev): Pass proper value for |user_is_new| or remove (not used).
- current_state_.reset(
- new AuthAttemptState(user_context,
- "", // login_token
- "", // login_captcha
- User::USER_TYPE_LOCALLY_MANAGED,
- false));
- remove_user_data_on_failure_ = false;
- SystemSaltGetter::Get()->GetSystemSalt(
- base::Bind(&Mount,
- current_state_.get(),
- scoped_refptr<ParallelAuthenticator>(this),
- cryptohome::MOUNT_FLAGS_NONE));
-}
-
-void ParallelAuthenticator::LoginRetailMode() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- // Note: |kRetailModeUserEMail| is used in other places to identify a retail
- // mode session.
- current_state_.reset(new AuthAttemptState(
- UserContext(UserManager::kRetailModeUserName,
- std::string(), // password
- std::string()), // auth_code
- std::string(), // login_token
- std::string(), // login_captcha
- User::USER_TYPE_RETAIL_MODE,
- false));
- remove_user_data_on_failure_ = false;
- ephemeral_mount_attempted_ = true;
- MountGuest(current_state_.get(),
- scoped_refptr<ParallelAuthenticator>(this));
-}
-
-void ParallelAuthenticator::LoginOffTheRecord() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- current_state_.reset(new AuthAttemptState(
- UserContext(UserManager::kGuestUserName, // username
- std::string(), // password
- std::string()), // auth_code
- std::string(), // login_token
- std::string(), // login_captcha
- User::USER_TYPE_GUEST,
- false));
- remove_user_data_on_failure_ = false;
- ephemeral_mount_attempted_ = true;
- MountGuest(current_state_.get(),
- scoped_refptr<ParallelAuthenticator>(this));
-}
-
-void ParallelAuthenticator::LoginAsPublicAccount(const std::string& username) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- current_state_.reset(new AuthAttemptState(
- UserContext(username,
- std::string(), // password
- std::string()), // auth_code
- std::string(), // login_token
- std::string(), // login_captcha
- User::USER_TYPE_PUBLIC_ACCOUNT,
- false));
- remove_user_data_on_failure_ = false;
- ephemeral_mount_attempted_ = true;
- SystemSaltGetter::Get()->GetSystemSalt(
- base::Bind(&Mount,
- current_state_.get(),
- scoped_refptr<ParallelAuthenticator>(this),
- cryptohome::CREATE_IF_MISSING | cryptohome::ENSURE_EPHEMERAL));
-}
-
-void ParallelAuthenticator::LoginAsKioskAccount(
- const std::string& app_user_id,
- bool use_guest_mount) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- const std::string user_id =
- use_guest_mount ? UserManager::kGuestUserName : app_user_id;
- current_state_.reset(new AuthAttemptState(
- UserContext(user_id,
- std::string(), // password
- std::string()), // auth_code
- std::string(), // login_token
- std::string(), // login_captcha
- User::USER_TYPE_KIOSK_APP,
- false));
-
- remove_user_data_on_failure_ = true;
- if (!use_guest_mount) {
- MountPublic(current_state_.get(),
- scoped_refptr<ParallelAuthenticator>(this),
- cryptohome::CREATE_IF_MISSING);
- } else {
- ephemeral_mount_attempted_ = true;
- MountGuestAndGetHash(current_state_.get(),
- scoped_refptr<ParallelAuthenticator>(this));
- }
-}
-
-void ParallelAuthenticator::OnRetailModeLoginSuccess() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- VLOG(1) << "Retail mode login success";
- // Send notification of success
- AuthenticationNotificationDetails details(true);
- content::NotificationService::current()->Notify(
- chrome::NOTIFICATION_LOGIN_AUTHENTICATION,
- content::NotificationService::AllSources(),
- content::Details<AuthenticationNotificationDetails>(&details));
- if (consumer_)
- consumer_->OnRetailModeLoginSuccess(current_state_->user_context);
-}
-
-void ParallelAuthenticator::OnLoginSuccess() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- VLOG(1) << "Login success";
- // Send notification of success
- AuthenticationNotificationDetails details(true);
- content::NotificationService::current()->Notify(
- chrome::NOTIFICATION_LOGIN_AUTHENTICATION,
- content::NotificationService::AllSources(),
- content::Details<AuthenticationNotificationDetails>(&details));
- {
- base::AutoLock for_this_block(success_lock_);
- already_reported_success_ = true;
- }
- if (consumer_)
- consumer_->OnLoginSuccess(current_state_->user_context);
-}
-
-void ParallelAuthenticator::OnOffTheRecordLoginSuccess() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- // Send notification of success
- AuthenticationNotificationDetails details(true);
- content::NotificationService::current()->Notify(
- chrome::NOTIFICATION_LOGIN_AUTHENTICATION,
- content::NotificationService::AllSources(),
- content::Details<AuthenticationNotificationDetails>(&details));
- if (consumer_)
- consumer_->OnOffTheRecordLoginSuccess();
-}
-
-void ParallelAuthenticator::OnPasswordChangeDetected() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (consumer_)
- consumer_->OnPasswordChangeDetected();
-}
-
-void ParallelAuthenticator::OnLoginFailure(const LoginFailure& error) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- // OnLoginFailure will be called again with the same |error|
- // after the cryptohome has been removed.
- if (remove_user_data_on_failure_) {
- delayed_login_failure_ = &error;
- RemoveEncryptedData();
- return;
- }
-
- // Send notification of failure
- AuthenticationNotificationDetails details(false);
- content::NotificationService::current()->Notify(
- chrome::NOTIFICATION_LOGIN_AUTHENTICATION,
- content::NotificationService::AllSources(),
- content::Details<AuthenticationNotificationDetails>(&details));
- LOG(WARNING) << "Login failed: " << error.GetErrorString();
- if (consumer_)
- consumer_->OnLoginFailure(error);
-}
-
-void ParallelAuthenticator::RecoverEncryptedData(
- const std::string& old_password) {
- migrate_attempted_ = true;
- current_state_->ResetCryptohomeStatus();
- SystemSaltGetter::Get()->GetSystemSalt(
- base::Bind(&Migrate,
- current_state_.get(),
- scoped_refptr<ParallelAuthenticator>(this),
- true,
- old_password));
-}
-
-void ParallelAuthenticator::RemoveEncryptedData() {
- remove_attempted_ = true;
- current_state_->ResetCryptohomeStatus();
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&Remove,
- current_state_.get(),
- scoped_refptr<ParallelAuthenticator>(this)));
-}
-
-void ParallelAuthenticator::ResyncEncryptedData() {
- resync_attempted_ = true;
- current_state_->ResetCryptohomeStatus();
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&Remove,
- current_state_.get(),
- scoped_refptr<ParallelAuthenticator>(this)));
-}
-
-bool ParallelAuthenticator::VerifyOwner() {
- if (owner_is_verified_)
- return true;
- // Check if policy data is fine and continue in safe mode if needed.
- bool is_safe_mode = false;
- CrosSettings::Get()->GetBoolean(kPolicyMissingMitigationMode, &is_safe_mode);
- if (!is_safe_mode) {
- // Now we can continue with the login and report mount success.
- user_can_login_ = true;
- owner_is_verified_ = true;
- return true;
- }
- // Now we can continue reading the private key.
- DeviceSettingsService::Get()->SetUsername(
- current_state_->user_context.GetUserID());
- // This should trigger certificate loading, which is needed in order to
- // correctly determine if the current user is the owner.
- if (LoginState::IsInitialized()) {
- LoginState::Get()->SetLoggedInState(LoginState::LOGGED_IN_SAFE_MODE,
- LoginState::LOGGED_IN_USER_NONE);
- }
- DeviceSettingsService::Get()->IsCurrentUserOwnerAsync(
- base::Bind(&ParallelAuthenticator::OnOwnershipChecked, this));
- return false;
-}
-
-void ParallelAuthenticator::OnOwnershipChecked(bool is_owner) {
- // Now we can check if this user is the owner.
- user_can_login_ = is_owner;
- owner_is_verified_ = true;
- Resolve();
-}
-
-void ParallelAuthenticator::Resolve() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- int mount_flags = cryptohome::MOUNT_FLAGS_NONE;
- ParallelAuthenticator::AuthState state = ResolveState();
- VLOG(1) << "Resolved state to: " << state;
- switch (state) {
- case CONTINUE:
- case POSSIBLE_PW_CHANGE:
- case NO_MOUNT:
- // These are intermediate states; we need more info from a request that
- // is still pending.
- break;
- case FAILED_MOUNT:
- // In this case, whether login succeeded or not, we can't log
- // the user in because their data is horked. So, override with
- // the appropriate failure.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&ParallelAuthenticator::OnLoginFailure, this,
- LoginFailure(LoginFailure::COULD_NOT_MOUNT_CRYPTOHOME)));
- break;
- case FAILED_REMOVE:
- // In this case, we tried to remove the user's old cryptohome at her
- // request, and the remove failed.
- remove_user_data_on_failure_ = false;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&ParallelAuthenticator::OnLoginFailure, this,
- LoginFailure(LoginFailure::DATA_REMOVAL_FAILED)));
- break;
- case FAILED_TMPFS:
- // In this case, we tried to mount a tmpfs for guest and failed.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&ParallelAuthenticator::OnLoginFailure, this,
- LoginFailure(LoginFailure::COULD_NOT_MOUNT_TMPFS)));
- break;
- case FAILED_TPM:
- // In this case, we tried to create/mount cryptohome and failed
- // because of the critical TPM error.
- // Chrome will notify user and request reboot.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&ParallelAuthenticator::OnLoginFailure, this,
- LoginFailure(LoginFailure::TPM_ERROR)));
- break;
- case FAILED_USERNAME_HASH:
- // In this case, we failed the GetSanitizedUsername request to
- // cryptohomed. This can happen for any login attempt.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&ParallelAuthenticator::OnLoginFailure, this,
- LoginFailure(LoginFailure::USERNAME_HASH_FAILED)));
- break;
- case REMOVED_DATA_AFTER_FAILURE:
- remove_user_data_on_failure_ = false;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&ParallelAuthenticator::OnLoginFailure, this,
- *delayed_login_failure_));
- break;
- case CREATE_NEW:
- mount_flags |= cryptohome::CREATE_IF_MISSING;
- case RECOVER_MOUNT:
- current_state_->ResetCryptohomeStatus();
- SystemSaltGetter::Get()->GetSystemSalt(
- base::Bind(&Mount,
- current_state_.get(),
- scoped_refptr<ParallelAuthenticator>(this),
- mount_flags));
- break;
- case NEED_OLD_PW:
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&ParallelAuthenticator::OnPasswordChangeDetected, this));
- break;
- case ONLINE_FAILED:
- case NEED_NEW_PW:
- case HAVE_NEW_PW:
- NOTREACHED() << "Using obsolete ClientLogin code path.";
- break;
- case OFFLINE_LOGIN:
- VLOG(2) << "Offline login";
- // Fall through.
- case UNLOCK:
- VLOG(2) << "Unlock";
- // Fall through.
- case ONLINE_LOGIN:
- VLOG(2) << "Online login";
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&ParallelAuthenticator::OnLoginSuccess, this));
- break;
- case DEMO_LOGIN:
- VLOG(2) << "Retail mode login";
- current_state_->user_context.SetIsUsingOAuth(false);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&ParallelAuthenticator::OnRetailModeLoginSuccess, this));
- break;
- case GUEST_LOGIN:
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&ParallelAuthenticator::OnOffTheRecordLoginSuccess, this));
- break;
- case KIOSK_ACCOUNT_LOGIN:
- case PUBLIC_ACCOUNT_LOGIN:
- current_state_->user_context.SetIsUsingOAuth(false);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&ParallelAuthenticator::OnLoginSuccess, this));
- break;
- case LOCALLY_MANAGED_USER_LOGIN:
- current_state_->user_context.SetIsUsingOAuth(false);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&ParallelAuthenticator::OnLoginSuccess, this));
- break;
- case LOGIN_FAILED:
- current_state_->ResetCryptohomeStatus();
- BrowserThread::PostTask(BrowserThread::UI,
- FROM_HERE,
- base::Bind(
- &ParallelAuthenticator::OnLoginFailure,
- this,
- current_state_->online_outcome()));
- break;
- case OWNER_REQUIRED: {
- current_state_->ResetCryptohomeStatus();
- bool success = false;
- DBusThreadManager::Get()->GetCryptohomeClient()->Unmount(&success);
- if (!success) {
- // Maybe we should reboot immediately here?
- LOG(ERROR) << "Couldn't unmount users home!";
- }
- BrowserThread::PostTask(BrowserThread::UI,
- FROM_HERE,
- base::Bind(
- &ParallelAuthenticator::OnLoginFailure,
- this,
- LoginFailure(LoginFailure::OWNER_REQUIRED)));
- break;
- }
- default:
- NOTREACHED();
- break;
- }
-}
-
-// static.
-std::string ParallelAuthenticator::HashPassword(const std::string& password,
- const std::string& ascii_salt) {
- // Update sha with ascii encoded salt, then update with ascii of password,
- // then end.
- // TODO(stevenjb/nkostylev): Handle empty system salt gracefully.
- CHECK(!ascii_salt.empty());
- char passhash_buf[kPasswordHashLength];
-
- // Hash salt and password
- crypto::SHA256HashString(ascii_salt + password,
- &passhash_buf, sizeof(passhash_buf));
-
- // Only want the top half for 'weak' hashing so that the passphrase is not
- // immediately exposed even if the output is reversed.
- const int encoded_length = sizeof(passhash_buf) / 2;
-
- return StringToLowerASCII(base::HexEncode(
- reinterpret_cast<const void*>(passhash_buf), encoded_length));
-}
-
-ParallelAuthenticator::~ParallelAuthenticator() {}
-
-ParallelAuthenticator::AuthState ParallelAuthenticator::ResolveState() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- // If we haven't mounted the user's home dir yet or
- // haven't got sanitized username value, we can't be done.
- // We never get past here if any of these two cryptohome ops is still pending.
- // This is an important invariant.
- if (!current_state_->cryptohome_complete() ||
- !current_state_->username_hash_obtained()) {
- return CONTINUE;
- }
-
- AuthState state = CONTINUE;
-
- if (current_state_->cryptohome_outcome() &&
- current_state_->username_hash_valid()) {
- state = ResolveCryptohomeSuccessState();
- } else {
- state = ResolveCryptohomeFailureState();
- }
-
- DCHECK(current_state_->cryptohome_complete()); // Ensure invariant holds.
- migrate_attempted_ = false;
- remove_attempted_ = false;
- resync_attempted_ = false;
- ephemeral_mount_attempted_ = false;
- check_key_attempted_ = false;
-
- if (state != POSSIBLE_PW_CHANGE &&
- state != NO_MOUNT &&
- state != OFFLINE_LOGIN)
- return state;
-
- if (current_state_->online_complete()) {
- if (current_state_->online_outcome().reason() == LoginFailure::NONE) {
- // Online attempt succeeded as well, so combine the results.
- return ResolveOnlineSuccessState(state);
- }
- NOTREACHED() << "Using obsolete ClientLogin code path.";
- }
- // if online isn't complete yet, just return the offline result.
- return state;
-}
-
-ParallelAuthenticator::AuthState
-ParallelAuthenticator::ResolveCryptohomeFailureState() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (remove_attempted_ || resync_attempted_)
- return FAILED_REMOVE;
- if (ephemeral_mount_attempted_)
- return FAILED_TMPFS;
- if (migrate_attempted_)
- return NEED_OLD_PW;
- if (check_key_attempted_)
- return LOGIN_FAILED;
-
- if (current_state_->cryptohome_code() ==
- cryptohome::MOUNT_ERROR_TPM_NEEDS_REBOOT) {
- // Critical TPM error detected, reboot needed.
- return FAILED_TPM;
- }
-
- // Return intermediate states in the following case:
- // when there is an online result to use;
- // This is the case after user finishes Gaia login;
- if (current_state_->online_complete()) {
- if (current_state_->cryptohome_code() ==
- cryptohome::MOUNT_ERROR_KEY_FAILURE) {
- // If we tried a mount but they used the wrong key, we may need to
- // ask the user for her old password. We'll only know once we've
- // done the online check.
- return POSSIBLE_PW_CHANGE;
- }
- if (current_state_->cryptohome_code() ==
- cryptohome::MOUNT_ERROR_USER_DOES_NOT_EXIST) {
- // If we tried a mount but the user did not exist, then we should wait
- // for online login to succeed and try again with the "create" flag set.
- return NO_MOUNT;
- }
- }
-
- if (!current_state_->username_hash_valid())
- return FAILED_USERNAME_HASH;
-
- return FAILED_MOUNT;
-}
-
-ParallelAuthenticator::AuthState
-ParallelAuthenticator::ResolveCryptohomeSuccessState() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (resync_attempted_)
- return CREATE_NEW;
- if (remove_attempted_)
- return REMOVED_DATA_AFTER_FAILURE;
- if (migrate_attempted_)
- return RECOVER_MOUNT;
- if (check_key_attempted_)
- return UNLOCK;
-
- if (current_state_->user_type == User::USER_TYPE_GUEST)
- return GUEST_LOGIN;
- if (current_state_->user_type == User::USER_TYPE_RETAIL_MODE)
- return DEMO_LOGIN;
- if (current_state_->user_type == User::USER_TYPE_PUBLIC_ACCOUNT)
- return PUBLIC_ACCOUNT_LOGIN;
- if (current_state_->user_type == User::USER_TYPE_KIOSK_APP)
- return KIOSK_ACCOUNT_LOGIN;
- if (current_state_->user_type == User::USER_TYPE_LOCALLY_MANAGED)
- return LOCALLY_MANAGED_USER_LOGIN;
-
- if (!VerifyOwner())
- return CONTINUE;
- return user_can_login_ ? OFFLINE_LOGIN : OWNER_REQUIRED;
-}
-
-ParallelAuthenticator::AuthState
-ParallelAuthenticator::ResolveOnlineSuccessState(
- ParallelAuthenticator::AuthState offline_state) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- switch (offline_state) {
- case POSSIBLE_PW_CHANGE:
- return NEED_OLD_PW;
- case NO_MOUNT:
- return CREATE_NEW;
- case OFFLINE_LOGIN:
- return ONLINE_LOGIN;
- default:
- NOTREACHED();
- return offline_state;
- }
-}
-
-void ParallelAuthenticator::ResolveLoginCompletionStatus() {
- // Shortcut online state resolution process.
- current_state_->RecordOnlineLoginStatus(LoginFailure::LoginFailureNone());
- Resolve();
-}
-
-void ParallelAuthenticator::SetOwnerState(bool owner_check_finished,
- bool check_result) {
- owner_is_verified_ = owner_check_finished;
- user_can_login_ = check_result;
-}
-
-} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698