This source file includes following definitions.
- TriggerResolve
- TriggerResolveResult
- TriggerResolveWithLoginTimeMarker
- Mount
- AddKey
- AuthenticateToMount
- AuthenticateToCreate
- AddMasterKey
- OnAuthenticationSuccess
- OnAuthenticationFailure
- Resolve
- ResolveState
- ResolveCryptohomeFailureState
- ResolveCryptohomeSuccessState
- cryptohome_code_
- RecordCryptohomeStatus
- RecordHash
- cryptohome_complete
- cryptohome_outcome
- cryptohome_code
- hash_obtained
- hash
#include "chrome/browser/chromeos/login/managed/managed_user_authenticator.h"
#include "base/bind.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "chrome/browser/chromeos/boot_times_loader.h"
#include "chrome/browser/chromeos/login/parallel_authenticator.h"
#include "chromeos/cryptohome/async_method_caller.h"
#include "chromeos/cryptohome/cryptohome_parameters.h"
#include "chromeos/cryptohome/system_salt_getter.h"
#include "chromeos/dbus/cryptohome_client.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "content/public/browser/browser_thread.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 {
void TriggerResolve(ManagedUserAuthenticator::AuthAttempt* attempt,
scoped_refptr<ManagedUserAuthenticator> resolver,
bool success,
cryptohome::MountError return_code) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
attempt->RecordCryptohomeStatus(success, return_code);
resolver->Resolve();
}
void TriggerResolveResult(ManagedUserAuthenticator::AuthAttempt* attempt,
scoped_refptr<ManagedUserAuthenticator> resolver,
bool success,
const std::string& result) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
attempt->RecordHash(result);
resolver->Resolve();
}
void TriggerResolveWithLoginTimeMarker(
const std::string& marker_name,
ManagedUserAuthenticator::AuthAttempt* attempt,
scoped_refptr<ManagedUserAuthenticator> resolver,
bool success,
cryptohome::MountError return_code) {
chromeos::BootTimesLoader::Get()->AddLoginTimeMarker(marker_name, false);
TriggerResolve(attempt, resolver, success, return_code);
}
void Mount(ManagedUserAuthenticator::AuthAttempt* attempt,
scoped_refptr<ManagedUserAuthenticator> resolver,
int flags,
const std::string& system_salt) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
chromeos::BootTimesLoader::Get()->AddLoginTimeMarker(
"CryptohomeMount-LMU-Start", false);
cryptohome::AsyncMethodCaller::GetInstance()->AsyncMount(
attempt->username,
ParallelAuthenticator::HashPassword(attempt->password, system_salt),
flags,
base::Bind(&TriggerResolveWithLoginTimeMarker,
"CryptohomeMount-LMU-End",
attempt,
resolver));
cryptohome::AsyncMethodCaller::GetInstance()->AsyncGetSanitizedUsername(
attempt->username,
base::Bind(&TriggerResolveResult, attempt, resolver));
}
void AddKey(ManagedUserAuthenticator::AuthAttempt* attempt,
scoped_refptr<ManagedUserAuthenticator> resolver,
const std::string& master_key,
const std::string& system_salt) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
chromeos::BootTimesLoader::Get()->AddLoginTimeMarker(
"CryptohomeAddKey-LMU-Start", false);
cryptohome::AsyncMethodCaller::GetInstance()->AsyncAddKey(
attempt->username,
ParallelAuthenticator::HashPassword(attempt->password, system_salt),
ParallelAuthenticator::HashPassword(master_key, system_salt),
base::Bind(&TriggerResolveWithLoginTimeMarker,
"CryptohomeAddKey-LMU-End",
attempt,
resolver));
}
}
ManagedUserAuthenticator::ManagedUserAuthenticator(AuthStatusConsumer* consumer)
: consumer_(consumer) {}
void ManagedUserAuthenticator::AuthenticateToMount(
const std::string& username,
const std::string& password) {
std::string canonicalized = gaia::CanonicalizeEmail(username);
current_state_.reset(new ManagedUserAuthenticator::AuthAttempt(
canonicalized, password, false));
SystemSaltGetter::Get()->GetSystemSalt(
base::Bind(&Mount,
current_state_.get(),
scoped_refptr<ManagedUserAuthenticator>(this),
cryptohome::MOUNT_FLAGS_NONE));
}
void ManagedUserAuthenticator::AuthenticateToCreate(
const std::string& username,
const std::string& password) {
std::string canonicalized = gaia::CanonicalizeEmail(username);
current_state_.reset(new ManagedUserAuthenticator::AuthAttempt(
canonicalized, password, false));
SystemSaltGetter::Get()->GetSystemSalt(
base::Bind(&Mount,
current_state_.get(),
scoped_refptr<ManagedUserAuthenticator>(this),
cryptohome::CREATE_IF_MISSING));
}
void ManagedUserAuthenticator::AddMasterKey(
const std::string& username,
const std::string& password,
const std::string& master_key) {
std::string canonicalized = gaia::CanonicalizeEmail(username);
current_state_.reset(new ManagedUserAuthenticator::AuthAttempt(
canonicalized, password, true));
SystemSaltGetter::Get()->GetSystemSalt(
base::Bind(&AddKey,
current_state_.get(),
scoped_refptr<ManagedUserAuthenticator>(this),
master_key));
}
void ManagedUserAuthenticator::OnAuthenticationSuccess(
const std::string& mount_hash,
bool add_key) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
VLOG(1) << "Locally managed user authentication success";
if (consumer_) {
if (add_key)
consumer_->OnAddKeySuccess();
else
consumer_->OnMountSuccess(mount_hash);
}
}
void ManagedUserAuthenticator::OnAuthenticationFailure(
ManagedUserAuthenticator::AuthState state) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
LOG(WARNING) << "Locally managed user authentication failure";
if (consumer_)
consumer_->OnAuthenticationFailure(state);
}
void ManagedUserAuthenticator::Resolve() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
ManagedUserAuthenticator::AuthState state = ResolveState();
VLOG(1) << "Resolved state to: " << state;
switch (state) {
case CONTINUE:
break;
case FAILED_MOUNT:
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
base::Bind(
&ManagedUserAuthenticator::OnAuthenticationFailure, this, state));
break;
case NO_MOUNT:
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
base::Bind(
&ManagedUserAuthenticator::OnAuthenticationFailure, this, state));
break;
case FAILED_TPM:
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
base::Bind(
&ManagedUserAuthenticator::OnAuthenticationFailure, this, state));
break;
case SUCCESS:
VLOG(2) << "Locally managed user login";
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
base::Bind(&ManagedUserAuthenticator::OnAuthenticationSuccess,
this,
current_state_->hash(),
current_state_->add_key));
break;
default:
NOTREACHED();
break;
}
}
ManagedUserAuthenticator::~ManagedUserAuthenticator() {}
ManagedUserAuthenticator::AuthState ManagedUserAuthenticator::ResolveState() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (!current_state_->cryptohome_complete())
return CONTINUE;
if (!current_state_->add_key && !current_state_->hash_obtained())
return CONTINUE;
AuthState state;
if (current_state_->cryptohome_outcome())
state = ResolveCryptohomeSuccessState();
else
state = ResolveCryptohomeFailureState();
DCHECK(current_state_->cryptohome_complete());
DCHECK(current_state_->hash_obtained() || current_state_->add_key);
return state;
}
ManagedUserAuthenticator::AuthState
ManagedUserAuthenticator::ResolveCryptohomeFailureState() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (current_state_->cryptohome_code() ==
cryptohome::MOUNT_ERROR_TPM_NEEDS_REBOOT) {
return FAILED_TPM;
}
if (current_state_->cryptohome_code() ==
cryptohome::MOUNT_ERROR_USER_DOES_NOT_EXIST) {
return NO_MOUNT;
}
return FAILED_MOUNT;
}
ManagedUserAuthenticator::AuthState
ManagedUserAuthenticator::ResolveCryptohomeSuccessState() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return SUCCESS;
}
ManagedUserAuthenticator::AuthAttempt::AuthAttempt(const std::string& username,
const std::string& password,
bool add_key_attempt)
: username(username),
password(password),
add_key(add_key_attempt),
cryptohome_complete_(false),
cryptohome_outcome_(false),
hash_obtained_(false),
cryptohome_code_(cryptohome::MOUNT_ERROR_NONE) {}
ManagedUserAuthenticator::AuthAttempt::~AuthAttempt() {}
void ManagedUserAuthenticator::AuthAttempt::RecordCryptohomeStatus(
bool cryptohome_outcome,
cryptohome::MountError cryptohome_code) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
cryptohome_complete_ = true;
cryptohome_outcome_ = cryptohome_outcome;
cryptohome_code_ = cryptohome_code;
}
void ManagedUserAuthenticator::AuthAttempt::RecordHash(
const std::string& hash) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
hash_obtained_ = true;
hash_ = hash;
}
bool ManagedUserAuthenticator::AuthAttempt::cryptohome_complete() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return cryptohome_complete_;
}
bool ManagedUserAuthenticator::AuthAttempt::cryptohome_outcome() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return cryptohome_outcome_;
}
cryptohome::MountError
ManagedUserAuthenticator::AuthAttempt::cryptohome_code() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return cryptohome_code_;
}
bool ManagedUserAuthenticator::AuthAttempt::hash_obtained() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return hash_obtained_;
}
std::string ManagedUserAuthenticator::AuthAttempt::hash() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return hash_;
}
}