Skip to content

Commit

Permalink
Revert of bootstrap: Use Smart Lock keys for existing users. (patchset
Browse files Browse the repository at this point in the history
…chromium#4 id:60001 of https://codereview.chromium.org/1007923003/)

Reason for revert:
Blink gardening. Speculative revert for Blink layout test failures in WebKit Mac10.8 (retina):
https://build.chromium.org/p/chromium.webkit/builders/WebKit%20Mac10.8%20%28retina%29/builds/27696
chromium range:  chromium revision 322799:322813
https://chromium.googlesource.com/chromium/src/+log/494aec68691f10626b226892396d442503dd9af7%5E..e240ab4e9c5841de8cb65226a80008600416c365?pretty=fuller

Original issue's description:
> bootstrap: Use Smart Lock keys for existing users.
>
> - Refactor EasyUnlockService and EasyUnlockAuthAttempt to have
>   a callback for finalized unlock/sign-in;
> - Change EasyBootstrapUserContextInitialize to try Smart lock keys
>   for existing users;
> - Only do auto pairing and trim "legacy-0" key when a random key is
>   used to create cryptohome;
>
> BUG=447006
>
> Committed: https://crrev.com/b073e1fc552ca21f07b9ee2dab9192086157e1f5
> Cr-Commit-Position: refs/heads/master@{#322800}

TBR=tengs@chromium.org,xiyuan@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=447006

Review URL: https://codereview.chromium.org/1040293002

Cr-Commit-Position: refs/heads/master@{#322979}
  • Loading branch information
hayatoito authored and Commit bot committed Mar 31, 2015
1 parent 7a4cf04 commit 85dcb72
Show file tree
Hide file tree
Showing 13 changed files with 47 additions and 249 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@

#include "base/strings/string_util.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h"
#include "chrome/browser/chromeos/login/session/user_session_manager.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/signin/easy_unlock_service_signin_chromeos.h"
#include "components/user_manager/user_manager.h"
#include "crypto/random.h"
#include "google_apis/gaia/gaia_constants.h"
#include "google_apis/gaia/gaia_urls.h"
Expand All @@ -35,9 +30,7 @@ void BootstrapUserContextInitializer::SetCompleteCallbackForTesting(
complete_callback_for_testing_ = callback;
}

BootstrapUserContextInitializer::BootstrapUserContextInitializer()
: random_key_used_(false),
weak_ptr_factory_(this) {
BootstrapUserContextInitializer::BootstrapUserContextInitializer() {
}

BootstrapUserContextInitializer::~BootstrapUserContextInitializer() {
Expand All @@ -48,7 +41,7 @@ void BootstrapUserContextInitializer::Start(const std::string& auth_code,
DCHECK(!callback.is_null());
callback_ = callback;

user_context_.SetAuthFlow(UserContext::AUTH_FLOW_EASY_BOOTSTRAP);
InitializeUserContext();
StartTokenFetch(auth_code);
}

Expand All @@ -67,67 +60,14 @@ void BootstrapUserContextInitializer::StartTokenFetch(
this);
}

void BootstrapUserContextInitializer::StartCheckExistingKeys() {
const std::string& user_id = user_context_.GetUserID();

// Use random key for the first time user.
if (!user_manager::UserManager::Get()->IsKnownUser(user_id)) {
CreateRandomKey();
return;
}

EasyUnlockKeyManager* key_manager =
UserSessionManager::GetInstance()->GetEasyUnlockKeyManager();
key_manager->GetDeviceDataList(
UserContext(user_id),
base::Bind(&BootstrapUserContextInitializer::OnGetEasyUnlockData,
weak_ptr_factory_.GetWeakPtr()));
}

void BootstrapUserContextInitializer::OnGetEasyUnlockData(
bool success,
const EasyUnlockDeviceKeyDataList& data_list) {
// Existing user must have Smart lock keys to use bootstrap flow.
if (!success || data_list.empty()) {
LOG(ERROR) << "Unable to get Easy unlock key data.";
Notify(false);
return;
}

EasyUnlockService* service =
EasyUnlockService::Get(ProfileHelper::GetSigninProfile());
service->AddObserver(this);

static_cast<EasyUnlockServiceSignin*>(service)
->SetCurrentUser(user_context_.GetUserID());
OnScreenlockStateChanged(service->GetScreenlockState());
}

void BootstrapUserContextInitializer::OnEasyUnlockAuthenticated(
EasyUnlockAuthAttempt::Type auth_attempt_type,
bool success,
const std::string& user_id,
const std::string& key_secret,
const std::string& key_label) {
DCHECK_EQ(EasyUnlockAuthAttempt::TYPE_SIGNIN, auth_attempt_type);
if (!success || key_secret.empty()) {
LOG(ERROR) << "Failed to sign-in using existing Smart lock key.";
Notify(false);
return;
}

user_context_.SetKey(Key(key_secret));
user_context_.GetKey()->SetLabel(key_label);
Notify(true);
}
void BootstrapUserContextInitializer::InitializeUserContext() {
user_context_.SetAuthFlow(UserContext::AUTH_FLOW_EASY_BOOTSTRAP);

void BootstrapUserContextInitializer::CreateRandomKey() {
std::string random_initial_key;
crypto::RandBytes(WriteInto(&random_initial_key, kUserKeyByteSize + 1),
kUserKeyByteSize);

user_context_.SetKey(Key(random_initial_key));
random_key_used_ = true;
Notify(true);
}

void BootstrapUserContextInitializer::Notify(bool success) {
Expand Down Expand Up @@ -177,8 +117,7 @@ void BootstrapUserContextInitializer::OnGetUserInfoResponse(
}

user_context_.SetUserID(email);
user_context_.SetGaiaID(gaia_id);
StartCheckExistingKeys();
Notify(true);
}

void BootstrapUserContextInitializer::OnOAuthError() {
Expand All @@ -191,21 +130,4 @@ void BootstrapUserContextInitializer::OnNetworkError(int response_code) {
Notify(false);
}

void BootstrapUserContextInitializer::OnScreenlockStateChanged(
EasyUnlockScreenlockStateHandler::State state) {
// TODO(xiyuan): Add timeout and hook up with error UI after
// http://crbug.com/471067.
if (state != EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED)
return;

EasyUnlockService* service =
EasyUnlockService::Get(ProfileHelper::GetSigninProfile());
service->RemoveObserver(this);

service->AttemptAuth(
user_context_.GetUserID(),
base::Bind(&BootstrapUserContextInitializer::OnEasyUnlockAuthenticated,
weak_ptr_factory_.GetWeakPtr()));
}

} // namespace chromeos
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_types.h"
#include "chrome/browser/signin/easy_unlock_auth_attempt.h"
#include "chrome/browser/signin/easy_unlock_service_observer.h"
#include "chromeos/login/auth/user_context.h"
#include "google_apis/gaia/gaia_oauth_client.h"

Expand All @@ -23,8 +19,7 @@ namespace chromeos {
// The class takes an authorization code then prepares a UserContext that
// could be used to create a new account.
class BootstrapUserContextInitializer final
: public gaia::GaiaOAuthClient::Delegate,
public EasyUnlockServiceObserver {
: public gaia::GaiaOAuthClient::Delegate {
public:
// Callback type to be invoked after initialization work is done.
typedef base::Callback<void(bool success, const UserContext& user_context)>
Expand All @@ -38,25 +33,13 @@ class BootstrapUserContextInitializer final
void Start(const std::string& auth_code, const CompleteCallback& callback);

const UserContext& user_context() const { return user_context_; }
bool random_key_used() const { return random_key_used_; }

static void SetCompleteCallbackForTesting(CompleteCallback* callback);

private:
void InitializeUserContext();
void Notify(bool success);

// Starts to check existing Smart lock keys to use.
void StartCheckExistingKeys();

void OnGetEasyUnlockData(bool success,
const EasyUnlockDeviceKeyDataList& data_list);
void OnEasyUnlockAuthenticated(EasyUnlockAuthAttempt::Type auth_attempt_type,
bool success,
const std::string& user_id,
const std::string& key_secret,
const std::string& key_label);
void CreateRandomKey();

// Start refresh token and user info fetching.
void StartTokenFetch(const std::string& auth_code);

Expand All @@ -71,17 +54,10 @@ class BootstrapUserContextInitializer final
void OnOAuthError() override;
void OnNetworkError(int response_code) override;

// EasyUnlockServiceObserver
void OnScreenlockStateChanged(
EasyUnlockScreenlockStateHandler::State state) override;

CompleteCallback callback_;
scoped_ptr<gaia::GaiaOAuthClient> token_fetcher_;

UserContext user_context_;
bool random_key_used_;

base::WeakPtrFactory<BootstrapUserContextInitializer> weak_ptr_factory_;

static CompleteCallback* complete_callback_for_testing_;

Expand Down
13 changes: 2 additions & 11 deletions chrome/browser/chromeos/login/easy_unlock/bootstrap_user_flow.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@

namespace chromeos {

BootstrapUserFlow::BootstrapUserFlow(const UserContext& user_context,
bool is_new_account)
BootstrapUserFlow::BootstrapUserFlow(const UserContext& user_context)
: ExtendedUserFlow(user_context.GetUserID()),
user_context_(user_context),
is_new_account_(is_new_account),
finished_(false),
user_profile_(nullptr),
weak_ptr_factory_(this) {
Expand Down Expand Up @@ -156,14 +154,7 @@ void BootstrapUserFlow::HandleOAuthTokenStatusChange(

void BootstrapUserFlow::LaunchExtraSteps(Profile* user_profile) {
user_profile_ = user_profile;

// Auto pairing only when a random key is used to boostrap cryptohome.
if (is_new_account_) {
StartAutoPairing();
return;
}

Finish();
StartAutoPairing();
}

bool BootstrapUserFlow::SupportsEarlyRestartToApplyFlags() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,7 @@ class BootstrapUserFlow final
: public ExtendedUserFlow,
public ExtendedAuthenticator::NewAuthStatusConsumer {
public:
// Constructs a BootstrapUserFlow. |user_context| is the user this flow
// represents and contains the user id and key needed for cryptohome
// operations. |is_new_account| is a boolean flag of whether the user
// is being added to the device.
BootstrapUserFlow(const UserContext& user_context, bool is_new_account);
explicit BootstrapUserFlow(const UserContext& user_context);
~BootstrapUserFlow() override;

private:
Expand Down Expand Up @@ -56,7 +52,6 @@ class BootstrapUserFlow final
void OnAuthenticationFailure(ExtendedAuthenticator::AuthState state) override;

UserContext user_context_;
const bool is_new_account_;

bool finished_;
Profile* user_profile_;
Expand Down
7 changes: 2 additions & 5 deletions chrome/browser/chromeos/login/existing_user_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1200,11 +1200,8 @@ void ExistingUserController::OnBootstrapUserContextInitialized(

// Setting a customized login user flow to perform additional initializations
// for bootstrap after the user session is started.
ChromeUserManager::Get()->SetUserFlow(
user_context.GetUserID(),
new BootstrapUserFlow(
user_context,
bootstrap_user_context_initializer_->random_key_used()));
ChromeUserManager::Get()->SetUserFlow(user_context.GetUserID(),
new BootstrapUserFlow(user_context));

PerformLogin(user_context, LoginPerformer::AUTH_MODE_EXTENSION);
}
Expand Down
75 changes: 25 additions & 50 deletions chrome/browser/signin/easy_unlock_auth_attempt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

#include "chrome/browser/signin/easy_unlock_auth_attempt.h"

#include "base/bind.h"
#include "base/logging.h"
#include "chrome/browser/signin/easy_unlock_app_manager.h"
#include "chrome/browser/signin/screenlock_bridge.h"
Expand Down Expand Up @@ -44,51 +43,15 @@ std::string UnwrapSecret(const std::string& wrapped_secret,
return secret;
}

void DefaultAuthAttemptFinalizedHandler(
EasyUnlockAuthAttempt::Type auth_attempt_type,
bool success,
const std::string& user_id,
const std::string& key_secret,
const std::string& key_label) {
if (!ScreenlockBridge::Get()->IsLocked())
return;

switch (auth_attempt_type) {
case EasyUnlockAuthAttempt::TYPE_UNLOCK:
if (success) {
ScreenlockBridge::Get()->lock_handler()->Unlock(user_id);
} else {
ScreenlockBridge::Get()->lock_handler()->EnableInput();
}
return;
case EasyUnlockAuthAttempt::TYPE_SIGNIN:
if (success) {
ScreenlockBridge::Get()->lock_handler()->AttemptEasySignin(
user_id, key_secret, key_label);
} else {
// Attempting signin with an empty secret is equivalent to canceling the
// attempt.
ScreenlockBridge::Get()->lock_handler()->AttemptEasySignin(
user_id, std::string(), std::string());
}
return;
}
}

} // namespace

EasyUnlockAuthAttempt::EasyUnlockAuthAttempt(
EasyUnlockAppManager* app_manager,
const std::string& user_id,
Type type,
const FinalizedCallback& finalized_callback)
EasyUnlockAuthAttempt::EasyUnlockAuthAttempt(EasyUnlockAppManager* app_manager,
const std::string& user_id,
Type type)
: app_manager_(app_manager),
state_(STATE_IDLE),
user_id_(user_id),
type_(type),
finalized_callback_(finalized_callback) {
if (finalized_callback_.is_null())
finalized_callback_ = base::Bind(&DefaultAuthAttemptFinalizedHandler);
type_(type) {
}

EasyUnlockAuthAttempt::~EasyUnlockAuthAttempt() {
Expand All @@ -97,7 +60,7 @@ EasyUnlockAuthAttempt::~EasyUnlockAuthAttempt() {
}

bool EasyUnlockAuthAttempt::Start() {
DCHECK_EQ(STATE_IDLE, state_);
DCHECK(state_ == STATE_IDLE);

if (!ScreenlockBridge::Get()->IsLocked())
return false;
Expand Down Expand Up @@ -133,8 +96,12 @@ void EasyUnlockAuthAttempt::FinalizeUnlock(const std::string& user_id,
return;
}

finalized_callback_.Run(type_, success, user_id, std::string(),
std::string());
if (success) {
ScreenlockBridge::Get()->lock_handler()->Unlock(user_id_);
} else {
ScreenlockBridge::Get()->lock_handler()->EnableInput();
}

state_ = STATE_DONE;
}

Expand Down Expand Up @@ -164,16 +131,24 @@ void EasyUnlockAuthAttempt::FinalizeSignin(const std::string& user_id,
key_label = chromeos::EasyUnlockKeyManager::GetKeyLabel(0u);
#endif // defined(OS_CHROMEOS)

const bool kSuccess = true;
finalized_callback_.Run(type_, kSuccess, user_id, unwrapped_secret,
key_label);
ScreenlockBridge::Get()->lock_handler()->AttemptEasySignin(
user_id,
unwrapped_secret,
key_label);
state_ = STATE_DONE;
}

void EasyUnlockAuthAttempt::Cancel(const std::string& user_id) {
state_ = STATE_DONE;

const bool kFailure = false;
finalized_callback_.Run(type_, kFailure, user_id, std::string(),
std::string());
if (!ScreenlockBridge::Get()->IsLocked())
return;

if (type_ == TYPE_UNLOCK) {
ScreenlockBridge::Get()->lock_handler()->EnableInput();
} else {
// Attempting signin with an empty secret is equivalent to canceling the
// attempt.
ScreenlockBridge::Get()->lock_handler()->AttemptEasySignin(user_id, "", "");
}
}
Loading

0 comments on commit 85dcb72

Please sign in to comment.