diff options
author | pastarmovj@chromium.org <pastarmovj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-15 20:30:07 +0000 |
---|---|---|
committer | pastarmovj@chromium.org <pastarmovj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-15 20:30:07 +0000 |
commit | 2c5c2d07325f72e4c2d2a10c7ed6669683e6f86d (patch) | |
tree | 2564f1f712cf996c6335c508a5336c21af2bd97f | |
parent | 2104a213120259180d842d85dc85d8de013e8f0d (diff) | |
download | chromium_src-2c5c2d07325f72e4c2d2a10c7ed6669683e6f86d.zip chromium_src-2c5c2d07325f72e4c2d2a10c7ed6669683e6f86d.tar.gz chromium_src-2c5c2d07325f72e4c2d2a10c7ed6669683e6f86d.tar.bz2 |
Chrome to cryptohome::InstallAttrutes bindings.
BUG=chrome-os:14119
TEST=Manual.
Review URL: http://codereview.chromium.org/6821075
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81794 0039d316-1c4b-4281-b951-d872f2087c98
9 files changed, 269 insertions, 10 deletions
diff --git a/chrome/browser/chromeos/cros/cryptohome_library.cc b/chrome/browser/chromeos/cros/cryptohome_library.cc index ac2d701..6c20330 100644 --- a/chrome/browser/chromeos/cros/cryptohome_library.cc +++ b/chrome/browser/chromeos/cros/cryptohome_library.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -162,6 +162,46 @@ class CryptohomeLibraryImpl : public CryptohomeLibrary { chromeos::CryptohomeTpmClearStoredPassword(); } + bool InstallAttributesGet(const std::string& name, std::string* value) { + char* local_value; + bool done = + chromeos::CryptohomeInstallAttributesGet(name.c_str(), &local_value); + if (done) { + *value = local_value; + chromeos::CryptohomeFreeString(local_value); + } + return done; + } + + bool InstallAttributesSet(const std::string& name, const std::string& value) { + return chromeos::CryptohomeInstallAttributesSet(name.c_str(), + value.c_str()); + } + + int InstallAttributesCount() { + return chromeos::CryptohomeInstallAttributesCount(); + } + + bool InstallAttributesFinalize() { + return chromeos::CryptohomeInstallAttributesFinalize(); + } + + bool InstallAttributesIsReady() { + return chromeos::CryptohomeInstallAttributesIsReady(); + } + + bool InstallAttributesIsSecure() { + return chromeos::CryptohomeInstallAttributesIsSecure(); + } + + bool InstallAttributesIsInvalid() { + return chromeos::CryptohomeInstallAttributesIsInvalid(); + } + + bool InstallAttributesIsFirstInstall() { + return chromeos::CryptohomeInstallAttributesIsFirstInstall(); + } + private: static void Handler(const chromeos::CryptohomeAsyncCallStatus& event, void* cryptohome_library) { @@ -332,11 +372,52 @@ class CryptohomeLibraryStubImpl : public CryptohomeLibrary { void TpmClearStoredPassword() {} + bool InstallAttributesGet(const std::string& name, std::string* value) { + if (install_attrs_.find(name) != install_attrs_.end()) { + *value = install_attrs_[name]; + return true; + } + return false; + } + + bool InstallAttributesSet(const std::string& name, const std::string& value) { + install_attrs_[name] = value; + return true; + } + + int InstallAttributesCount() { + return install_attrs_.size(); + } + + bool InstallAttributesFinalize() { + locked_ = true; + return true; + } + + bool InstallAttributesIsReady() { + return true; + } + + bool InstallAttributesIsSecure() { + return locked_; + } + + bool InstallAttributesIsInvalid() { + return false; + } + + bool InstallAttributesIsFirstInstall() { + return false; + } + private: static void DoStubCallback(Delegate* callback) { if (callback) callback->OnComplete(true, kCryptohomeMountErrorNone); } + + std::map<std::string, std::string> install_attrs_; + bool locked_; DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryStubImpl); }; diff --git a/chrome/browser/chromeos/cros/cryptohome_library.h b/chrome/browser/chromeos/cros/cryptohome_library.h index 6019449..ed595a7 100644 --- a/chrome/browser/chromeos/cros/cryptohome_library.h +++ b/chrome/browser/chromeos/cros/cryptohome_library.h @@ -132,6 +132,17 @@ class CryptohomeLibrary { // shown to user. virtual void TpmClearStoredPassword() = 0; + virtual bool InstallAttributesGet(const std::string& name, + std::string* value) = 0; + virtual bool InstallAttributesSet(const std::string& name, + const std::string& value) = 0; + virtual int InstallAttributesCount() = 0; + virtual bool InstallAttributesFinalize() = 0; + virtual bool InstallAttributesIsReady() = 0; + virtual bool InstallAttributesIsSecure() = 0; + virtual bool InstallAttributesIsInvalid() = 0; + virtual bool InstallAttributesIsFirstInstall() = 0; + // Factory function, creates a new instance and returns ownership. // For normal usage, access the singleton via CrosLibrary::Get(). static CryptohomeLibrary* GetImpl(bool stub); diff --git a/chrome/browser/chromeos/cros/mock_cryptohome_library.h b/chrome/browser/chromeos/cros/mock_cryptohome_library.h index bf709df..772c1df 100644 --- a/chrome/browser/chromeos/cros/mock_cryptohome_library.h +++ b/chrome/browser/chromeos/cros/mock_cryptohome_library.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -80,6 +80,16 @@ class MockCryptohomeLibrary : public CryptohomeLibrary { MOCK_METHOD0(TpmCanAttemptOwnership, void(void)); MOCK_METHOD0(TpmClearStoredPassword, void(void)); + MOCK_METHOD2(InstallAttributesGet, bool(const std::string&, std::string*)); + MOCK_METHOD2(InstallAttributesSet, bool(const std::string&, + const std::string&)); + MOCK_METHOD0(InstallAttributesCount, int(void)); + MOCK_METHOD0(InstallAttributesFinalize, bool(void)); + MOCK_METHOD0(InstallAttributesIsReady, bool(void)); + MOCK_METHOD0(InstallAttributesIsSecure, bool(void)); + MOCK_METHOD0(InstallAttributesIsInvalid, bool(void)); + MOCK_METHOD0(InstallAttributesIsFirstInstall, bool(void)); + void SetAsyncBehavior(bool outcome, int code) { outcome_ = outcome; code_ = code; diff --git a/chrome/browser/chromeos/login/enterprise_enrollment_screen.cc b/chrome/browser/chromeos/login/enterprise_enrollment_screen.cc index ec775dc..4f6e477 100644 --- a/chrome/browser/chromeos/login/enterprise_enrollment_screen.cc +++ b/chrome/browser/chromeos/login/enterprise_enrollment_screen.cc @@ -6,15 +6,33 @@ #include "base/logging.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/cros/cros_library.h" +#include "chrome/browser/chromeos/cros/cryptohome_library.h" #include "chrome/browser/chromeos/login/screen_observer.h" #include "chrome/browser/policy/browser_policy_connector.h" #include "chrome/common/net/gaia/gaia_constants.h" namespace chromeos { +// Retry for InstallAttrs initialization every 500ms. +const int kLockboxRetryIntervalMs = 500; + EnterpriseEnrollmentScreen::EnterpriseEnrollmentScreen( WizardScreenDelegate* delegate) - : ViewScreen<EnterpriseEnrollmentView>(delegate) {} + : ViewScreen<EnterpriseEnrollmentView>(delegate), + ALLOW_THIS_IN_INITIALIZER_LIST(runnable_method_factory_(this)) { + // Init the TPM if it has not been done until now (in debug build we might + // have not done that yet). + chromeos::CryptohomeLibrary* cryptohome = + chromeos::CrosLibrary::Get()->GetCryptohomeLibrary(); + if (cryptohome) { + if (cryptohome->TpmIsEnabled() && + !cryptohome->TpmIsBeingOwned() && + !cryptohome->TpmIsOwned()) { + cryptohome->TpmCanAttemptOwnership(); + } + } +} EnterpriseEnrollmentScreen::~EnterpriseEnrollmentScreen() {} @@ -55,10 +73,34 @@ void EnterpriseEnrollmentScreen::CloseConfirmation() { observer->OnExit(ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED); } +bool EnterpriseEnrollmentScreen::GetInitialUser(std::string* user) { + chromeos::CryptohomeLibrary* cryptohome = + chromeos::CrosLibrary::Get()->GetCryptohomeLibrary(); + if (cryptohome && + cryptohome->InstallAttributesIsReady() && + !cryptohome->InstallAttributesIsFirstInstall()) { + std::string value; + if (cryptohome->InstallAttributesGet("enterprise.owned", &value) && + value == "true") { + if (cryptohome->InstallAttributesGet("enterprise.user", &value)) { + // If we landed in the enrollment dialogue with a locked InstallAttrs + // this means we might only want to reenroll with the DMServer so lock + // the username to what has been stored in the InstallAttrs already. + *user = value; + if (view()) + view()->set_editable_user(false); + return true; + } + } + LOG(ERROR) << "Enrollment will not finish because the InstallAttrs has " + << "been locked already but does not contain valid data."; + } + return false; +} + void EnterpriseEnrollmentScreen::OnClientLoginSuccess( const ClientLoginResult& result) { - auth_fetcher_->StartIssueAuthToken(result.sid, result.lsid, - GaiaConstants::kDeviceManagementService); + WriteInstallAttributesData(result); } void EnterpriseEnrollmentScreen::OnClientLoginFailure( @@ -177,4 +219,87 @@ void EnterpriseEnrollmentScreen::HandleAuthError( NOTREACHED() << error.state(); } +void EnterpriseEnrollmentScreen::WriteInstallAttributesData( + const ClientLoginResult& result) { + // Since this method is also called directly. + runnable_method_factory_.RevokeAll(); + + if (!view()) + return; + + chromeos::CryptohomeLibrary* cryptohome = + chromeos::CrosLibrary::Get()->GetCryptohomeLibrary(); + if (!cryptohome) { + LOG(ERROR) << "Enrollment can not proceed because the InstallAttrs can not " + << "be accessed."; + view()->ShowFatalEnrollmentError(); + return; + } + + if (!cryptohome->InstallAttributesIsReady()) { + // Lockbox is not ready yet, retry later. + LOG(WARNING) << "Lockbox is not ready yet will retry in " + << kLockboxRetryIntervalMs << "ms."; + MessageLoop::current()->PostDelayedTask( + FROM_HERE, + runnable_method_factory_.NewRunnableMethod( + &EnterpriseEnrollmentScreen::WriteInstallAttributesData, result), + kLockboxRetryIntervalMs); + return; + } + + // Clearing the TPM password seems to be always a good deal. + if (cryptohome->TpmIsEnabled() && + !cryptohome->TpmIsBeingOwned() && + cryptohome->TpmIsOwned()) { + cryptohome->TpmClearStoredPassword(); + } + + // Make sure we really have a working InstallAttrs. + if (cryptohome->InstallAttributesIsInvalid()) { + LOG(ERROR) << "Enrollment can not proceed because the InstallAttrs " + << "is corrupt or failed to initialize!"; + view()->ShowFatalEnrollmentError(); + return; + } + if (!cryptohome->InstallAttributesIsFirstInstall()) { + std::string value; + if (cryptohome->InstallAttributesGet("enterprise.owned", &value) && + value == "true") { + if (cryptohome->InstallAttributesGet("enterprise.user", &value)) { + if (value == user_) { + // If we landed here with a locked InstallAttrs this would mean we + // only want to reenroll with the DMServer so lock just continue. + auth_fetcher_->StartIssueAuthToken( + result.sid, result.lsid, + GaiaConstants::kDeviceManagementService); + return; + } + } + } + + LOG(ERROR) << "Enrollment can not proceed because the InstallAttrs " + << "has been locked already!"; + view()->ShowFatalEnrollmentError(); + return; + } + + // Set values in the InstallAttrs and lock it. + DCHECK(cryptohome->InstallAttributesIsFirstInstall()); + cryptohome->InstallAttributesSet("enterprise.owned", "true"); + cryptohome->InstallAttributesSet("enterprise.user", user_); + DCHECK(cryptohome->InstallAttributesCount() == 2); + cryptohome->InstallAttributesFinalize(); + if (cryptohome->InstallAttributesIsFirstInstall()) { + LOG(ERROR) << "Enrollment can not proceed because the InstallAttrs " + << "can not be sealed!"; + view()->ShowFatalEnrollmentError(); + return; + } + + // Proceed with register and policy fetch. + auth_fetcher_->StartIssueAuthToken( + result.sid, result.lsid, GaiaConstants::kDeviceManagementService); +} + } // namespace chromeos diff --git a/chrome/browser/chromeos/login/enterprise_enrollment_screen.h b/chrome/browser/chromeos/login/enterprise_enrollment_screen.h index c987d59..0734a3a 100644 --- a/chrome/browser/chromeos/login/enterprise_enrollment_screen.h +++ b/chrome/browser/chromeos/login/enterprise_enrollment_screen.h @@ -10,6 +10,9 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" +#include "base/message_loop.h" +#include "base/task.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/login/enterprise_enrollment_view.h" #include "chrome/browser/chromeos/login/view_screen.h" #include "chrome/browser/policy/cloud_policy_subsystem.h" @@ -31,6 +34,10 @@ class EnterpriseEnrollmentController { // Closes the confirmation window. virtual void CloseConfirmation() = 0; + + // Returns whether the GAIA login should be prepolutated with an user and if + // yes which one. + virtual bool GetInitialUser(std::string* user) = 0; }; // The screen implementation that links the enterprise enrollment UI into the @@ -51,6 +58,7 @@ class EnterpriseEnrollmentScreen const std::string& access_code) OVERRIDE; virtual void CancelEnrollment() OVERRIDE; virtual void CloseConfirmation() OVERRIDE; + virtual bool GetInitialUser(std::string* user) OVERRIDE; // GaiaAuthConsumer implementation: virtual void OnClientLoginSuccess(const ClientLoginResult& result) OVERRIDE; @@ -75,10 +83,15 @@ class EnterpriseEnrollmentScreen private: void HandleAuthError(const GoogleServiceAuthError& error); + // Starts the Lockbox storage process. + void WriteInstallAttributesData(const ClientLoginResult& result); + scoped_ptr<GaiaAuthFetcher> auth_fetcher_; std::string user_; std::string captcha_token_; scoped_ptr<policy::CloudPolicySubsystem::ObserverRegistrar> registrar_; + ScopedRunnableMethodFactory<EnterpriseEnrollmentScreen> + runnable_method_factory_; DISALLOW_COPY_AND_ASSIGN(EnterpriseEnrollmentScreen); }; diff --git a/chrome/browser/chromeos/login/enterprise_enrollment_view.cc b/chrome/browser/chromeos/login/enterprise_enrollment_view.cc index 44c7de5..ba2652d 100644 --- a/chrome/browser/chromeos/login/enterprise_enrollment_view.cc +++ b/chrome/browser/chromeos/login/enterprise_enrollment_view.cc @@ -82,7 +82,8 @@ class EnrollmentDomView : public WebPageDomView, EnterpriseEnrollmentView::EnterpriseEnrollmentView( EnterpriseEnrollmentController* controller) - : controller_(controller) {} + : controller_(controller), + editable_user_(true) {} EnterpriseEnrollmentView::~EnterpriseEnrollmentView() {} @@ -122,7 +123,7 @@ void EnterpriseEnrollmentView::ShowAuthError( const GoogleServiceAuthError& error) { DictionaryValue args; args.SetInteger("error", error.state()); - args.SetBoolean("editable_user", true); + args.SetBoolean("editable_user", editable_user_); args.SetString("captchaUrl", error.captcha().image_url.spec()); UpdateGaiaLogin(args); } @@ -158,6 +159,10 @@ void EnterpriseEnrollmentView::OnConfirmationClosed() { controller_->CloseConfirmation(); } +bool EnterpriseEnrollmentView::GetInitialUser(std::string* user) { + return controller_->GetInitialUser(user); +} + void EnterpriseEnrollmentView::UpdateGaiaLogin(const DictionaryValue& args) { std::string json; base::JSONWriter::Write(&args, false, &json); @@ -172,7 +177,7 @@ void EnterpriseEnrollmentView::UpdateGaiaLogin(const DictionaryValue& args) { void EnterpriseEnrollmentView::ShowError(int message_id) { DictionaryValue args; args.SetInteger("error", GoogleServiceAuthError::NONE); - args.SetBoolean("editable_user", true); + args.SetBoolean("editable_user", editable_user_); args.SetString("error_message", l10n_util::GetStringUTF16(message_id)); UpdateGaiaLogin(args); } @@ -181,4 +186,8 @@ void EnterpriseEnrollmentView::Layout() { enrollment_page_view_->SetBoundsRect(GetContentsBounds()); } +void EnterpriseEnrollmentView::set_editable_user(bool editable) { + editable_user_ = editable; +} + } // namespace chromeos diff --git a/chrome/browser/chromeos/login/enterprise_enrollment_view.h b/chrome/browser/chromeos/login/enterprise_enrollment_view.h index 23322f1..71f934a 100644 --- a/chrome/browser/chromeos/login/enterprise_enrollment_view.h +++ b/chrome/browser/chromeos/login/enterprise_enrollment_view.h @@ -34,6 +34,8 @@ class EnterpriseEnrollmentView : public views::View, explicit EnterpriseEnrollmentView(EnterpriseEnrollmentController* controller); virtual ~EnterpriseEnrollmentView(); + void set_editable_user(bool editable); + // Initialize view controls and layout. void Init(); @@ -54,6 +56,7 @@ class EnterpriseEnrollmentView : public views::View, const std::string& access_code) OVERRIDE; virtual void OnAuthCancelled() OVERRIDE; virtual void OnConfirmationClosed() OVERRIDE; + virtual bool GetInitialUser(std::string* user) OVERRIDE; private: // Updates the gaia login box. @@ -70,6 +73,8 @@ class EnterpriseEnrollmentView : public views::View, // Controls. WebPageDomView* enrollment_page_view_; + bool editable_user_; + DISALLOW_COPY_AND_ASSIGN(EnterpriseEnrollmentView); }; diff --git a/chrome/browser/ui/webui/chromeos/enterprise_enrollment_ui.cc b/chrome/browser/ui/webui/chromeos/enterprise_enrollment_ui.cc index 8de29a8..5b4cb24 100644 --- a/chrome/browser/ui/webui/chromeos/enterprise_enrollment_ui.cc +++ b/chrome/browser/ui/webui/chromeos/enterprise_enrollment_ui.cc @@ -288,11 +288,15 @@ void EnterpriseEnrollmentUI::RenderViewCreated( tab_contents()->profile()->GetChromeURLDataManager()->AddDataSource( new EnterpriseEnrollmentDataSource()); + std::string user; + bool has_init_user = GetController(this)->GetInitialUser(&user); + if (!has_init_user) + user = ""; // Set the arguments for showing the gaia login page. DictionaryValue args; - args.SetString("user", ""); + args.SetString("user", user); args.SetInteger("error", 0); - args.SetBoolean("editable_user", true); + args.SetBoolean("editable_user", !has_init_user); args.SetString("initialScreen", "login-screen"); std::string json_args; base::JSONWriter::Write(&args, false, &json_args); diff --git a/chrome/browser/ui/webui/chromeos/enterprise_enrollment_ui.h b/chrome/browser/ui/webui/chromeos/enterprise_enrollment_ui.h index d3b0df7..aa73438 100644 --- a/chrome/browser/ui/webui/chromeos/enterprise_enrollment_ui.h +++ b/chrome/browser/ui/webui/chromeos/enterprise_enrollment_ui.h @@ -27,6 +27,7 @@ class EnterpriseEnrollmentUI : public WebUI { const std::string& access_code) = 0; virtual void OnAuthCancelled() = 0; virtual void OnConfirmationClosed() = 0; + virtual bool GetInitialUser(std::string* user) = 0; }; explicit EnterpriseEnrollmentUI(TabContents* contents); |