| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/app_mode/kiosk_app_manager.h" | 5 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" | 28 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" |
| 29 #include "chrome/browser/chromeos/policy/device_local_account.h" | 29 #include "chrome/browser/chromeos/policy/device_local_account.h" |
| 30 #include "chrome/browser/chromeos/settings/cros_settings.h" | 30 #include "chrome/browser/chromeos/settings/cros_settings.h" |
| 31 #include "chrome/browser/extensions/external_loader.h" | 31 #include "chrome/browser/extensions/external_loader.h" |
| 32 #include "chrome/browser/extensions/external_provider_impl.h" | 32 #include "chrome/browser/extensions/external_provider_impl.h" |
| 33 #include "chrome/browser/lifetime/application_lifetime.h" | 33 #include "chrome/browser/lifetime/application_lifetime.h" |
| 34 #include "chrome/common/chrome_paths.h" | 34 #include "chrome/common/chrome_paths.h" |
| 35 #include "chrome/common/extensions/extension_constants.h" | 35 #include "chrome/common/extensions/extension_constants.h" |
| 36 #include "chromeos/chromeos_paths.h" | 36 #include "chromeos/chromeos_paths.h" |
| 37 #include "chromeos/cryptohome/async_method_caller.h" | 37 #include "chromeos/cryptohome/async_method_caller.h" |
| 38 #include "chromeos/cryptohome/cryptohome_parameters.h" |
| 38 #include "chromeos/dbus/dbus_thread_manager.h" | 39 #include "chromeos/dbus/dbus_thread_manager.h" |
| 40 #include "chromeos/login/user_names.h" |
| 39 #include "chromeos/settings/cros_settings_names.h" | 41 #include "chromeos/settings/cros_settings_names.h" |
| 40 #include "components/ownership/owner_key_util.h" | 42 #include "components/ownership/owner_key_util.h" |
| 41 #include "components/prefs/pref_registry_simple.h" | 43 #include "components/prefs/pref_registry_simple.h" |
| 42 #include "components/prefs/pref_service.h" | 44 #include "components/prefs/pref_service.h" |
| 43 #include "components/prefs/scoped_user_pref_update.h" | 45 #include "components/prefs/scoped_user_pref_update.h" |
| 44 #include "components/signin/core/account_id/account_id.h" | 46 #include "components/signin/core/account_id/account_id.h" |
| 47 #include "components/user_manager/known_user.h" |
| 45 #include "components/user_manager/user_manager.h" | 48 #include "components/user_manager/user_manager.h" |
| 46 #include "content/public/browser/browser_thread.h" | 49 #include "content/public/browser/browser_thread.h" |
| 47 #include "extensions/common/extension_urls.h" | 50 #include "extensions/common/extension_urls.h" |
| 48 | 51 |
| 49 namespace chromeos { | 52 namespace chromeos { |
| 50 | 53 |
| 51 namespace { | 54 namespace { |
| 52 | 55 |
| 53 // Domain that is used for kiosk-app account IDs. | 56 // Domain that is used for kiosk-app account IDs. |
| 54 const char kKioskAppAccountDomain[] = "kiosk-apps"; | 57 const char kKioskAppAccountDomain[] = "kiosk-apps"; |
| 55 | 58 |
| 56 // Preference for the dictionary of user ids for which cryptohomes have to be | 59 // Preference for the dictionary of user ids for which cryptohomes have to be |
| 57 // removed upon browser restart. | 60 // removed upon browser restart. |
| 58 const char kKioskUsersToRemove[] = "kiosk-users-to-remove"; | 61 const char kKioskUsersToRemove[] = "kiosk-users-to-remove"; |
| 59 | 62 |
| 60 std::string GenerateKioskAppAccountId(const std::string& app_id) { | 63 std::string GenerateKioskAppAccountId(const std::string& app_id) { |
| 61 return app_id + '@' + kKioskAppAccountDomain; | 64 return app_id + '@' + kKioskAppAccountDomain; |
| 62 } | 65 } |
| 63 | 66 |
| 64 void ScheduleDelayedCryptohomeRemoval(const std::string& user_id, | 67 void ScheduleDelayedCryptohomeRemoval(const cryptohome::Identification& id, |
| 65 const std::string& app_id) { | 68 const std::string& app_id) { |
| 66 PrefService* local_state = g_browser_process->local_state(); | 69 PrefService* local_state = g_browser_process->local_state(); |
| 67 DictionaryPrefUpdate dict_update(local_state, kKioskUsersToRemove); | 70 DictionaryPrefUpdate dict_update(local_state, kKioskUsersToRemove); |
| 68 dict_update->SetStringWithoutPathExpansion(user_id, app_id); | 71 |
| 72 // We are using cryptohome::Identification here because it cannot change |
| 73 // before actual removal will take place. (Possible cryptohome migration |
| 74 // happens only on session start, but deletion should happen before it.) |
| 75 dict_update->SetStringWithoutPathExpansion(id.id(), app_id); |
| 69 local_state->CommitPendingWrite(); | 76 local_state->CommitPendingWrite(); |
| 70 } | 77 } |
| 71 | 78 |
| 72 void CancelDelayedCryptohomeRemoval(const std::string& user_id) { | 79 void CancelDelayedCryptohomeRemoval(const cryptohome::Identification& id) { |
| 73 PrefService* local_state = g_browser_process->local_state(); | 80 PrefService* local_state = g_browser_process->local_state(); |
| 74 DictionaryPrefUpdate dict_update(local_state, kKioskUsersToRemove); | 81 DictionaryPrefUpdate dict_update(local_state, kKioskUsersToRemove); |
| 75 dict_update->RemoveWithoutPathExpansion(user_id, NULL); | 82 dict_update->RemoveWithoutPathExpansion(id.id(), NULL); |
| 76 local_state->CommitPendingWrite(); | 83 local_state->CommitPendingWrite(); |
| 77 } | 84 } |
| 78 | 85 |
| 79 void OnRemoveAppCryptohomeComplete(const std::string& user_id, | 86 void OnRemoveAppCryptohomeComplete(const cryptohome::Identification& id, |
| 80 const std::string& app, | 87 const std::string& app, |
| 81 const base::Closure& callback, | 88 const base::Closure& callback, |
| 82 bool success, | 89 bool success, |
| 83 cryptohome::MountError return_code) { | 90 cryptohome::MountError return_code) { |
| 84 if (success) { | 91 if (success) { |
| 85 CancelDelayedCryptohomeRemoval(user_id); | 92 CancelDelayedCryptohomeRemoval(id); |
| 86 } else { | 93 } else { |
| 87 ScheduleDelayedCryptohomeRemoval(user_id, app); | 94 ScheduleDelayedCryptohomeRemoval(id, app); |
| 88 LOG(ERROR) << "Remove cryptohome for " << app | 95 LOG(ERROR) << "Remove cryptohome for " << app |
| 89 << " failed, return code: " << return_code; | 96 << " failed, return code: " << return_code; |
| 90 } | 97 } |
| 91 if (!callback.is_null()) | 98 if (!callback.is_null()) |
| 92 callback.Run(); | 99 callback.Run(); |
| 93 } | 100 } |
| 94 | 101 |
| 95 void PerformDelayedCryptohomeRemovals(bool service_is_available) { | 102 void PerformDelayedCryptohomeRemovals(bool service_is_available) { |
| 96 if (!service_is_available) { | 103 if (!service_is_available) { |
| 97 LOG(ERROR) << "Crypthomed is not available."; | 104 LOG(ERROR) << "Crypthomed is not available."; |
| 98 return; | 105 return; |
| 99 } | 106 } |
| 100 | 107 |
| 101 PrefService* local_state = g_browser_process->local_state(); | 108 PrefService* local_state = g_browser_process->local_state(); |
| 102 const base::DictionaryValue* dict = | 109 const base::DictionaryValue* dict = |
| 103 local_state->GetDictionary(kKioskUsersToRemove); | 110 local_state->GetDictionary(kKioskUsersToRemove); |
| 104 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) { | 111 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) { |
| 105 std::string user_id = it.key(); | 112 const cryptohome::Identification cryptohome_id( |
| 113 cryptohome::Identification::FromString(it.key())); |
| 106 std::string app_id; | 114 std::string app_id; |
| 107 it.value().GetAsString(&app_id); | 115 it.value().GetAsString(&app_id); |
| 108 VLOG(1) << "Removing obsolete crypthome for " << app_id; | 116 VLOG(1) << "Removing obsolete crypthome for " << app_id; |
| 109 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( | 117 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( |
| 110 user_id, | 118 cryptohome_id, base::Bind(&OnRemoveAppCryptohomeComplete, cryptohome_id, |
| 111 base::Bind(&OnRemoveAppCryptohomeComplete, | 119 app_id, base::Closure())); |
| 112 user_id, | |
| 113 app_id, | |
| 114 base::Closure())); | |
| 115 } | 120 } |
| 116 } | 121 } |
| 117 | 122 |
| 118 // Check for presence of machine owner public key file. | 123 // Check for presence of machine owner public key file. |
| 119 void CheckOwnerFilePresence(bool *present) { | 124 void CheckOwnerFilePresence(bool *present) { |
| 120 scoped_refptr<ownership::OwnerKeyUtil> util = | 125 scoped_refptr<ownership::OwnerKeyUtil> util = |
| 121 OwnerSettingsServiceChromeOSFactory::GetInstance()->GetOwnerKeyUtil(); | 126 OwnerSettingsServiceChromeOSFactory::GetInstance()->GetOwnerKeyUtil(); |
| 122 *present = util.get() && util->IsPublicKeyPresent(); | 127 *present = util.get() && util->IsPublicKeyPresent(); |
| 123 } | 128 } |
| 124 | 129 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 } | 165 } |
| 161 | 166 |
| 162 // static | 167 // static |
| 163 void KioskAppManager::RemoveObsoleteCryptohomes() { | 168 void KioskAppManager::RemoveObsoleteCryptohomes() { |
| 164 chromeos::CryptohomeClient* client = | 169 chromeos::CryptohomeClient* client = |
| 165 chromeos::DBusThreadManager::Get()->GetCryptohomeClient(); | 170 chromeos::DBusThreadManager::Get()->GetCryptohomeClient(); |
| 166 client->WaitForServiceToBeAvailable( | 171 client->WaitForServiceToBeAvailable( |
| 167 base::Bind(&PerformDelayedCryptohomeRemovals)); | 172 base::Bind(&PerformDelayedCryptohomeRemovals)); |
| 168 } | 173 } |
| 169 | 174 |
| 170 KioskAppManager::App::App( | 175 KioskAppManager::App::App(const KioskAppData& data, |
| 171 const KioskAppData& data, | 176 bool is_extension_pending, |
| 172 bool is_extension_pending, | 177 bool auto_launched_with_zero_delay) |
| 173 bool auto_launched_with_zero_delay) | |
| 174 : app_id(data.app_id()), | 178 : app_id(data.app_id()), |
| 175 user_id(data.user_id()), | 179 account_id(data.account_id()), |
| 176 name(data.name()), | 180 name(data.name()), |
| 177 icon(data.icon()), | 181 icon(data.icon()), |
| 178 is_loading(data.IsLoading() || is_extension_pending), | 182 is_loading(data.IsLoading() || is_extension_pending), |
| 179 was_auto_launched_with_zero_delay(auto_launched_with_zero_delay) { | 183 was_auto_launched_with_zero_delay(auto_launched_with_zero_delay) {} |
| 180 } | |
| 181 | 184 |
| 182 KioskAppManager::App::App() : is_loading(false), | 185 KioskAppManager::App::App() |
| 183 was_auto_launched_with_zero_delay(false) {} | 186 : account_id(EmptyAccountId()), |
| 187 is_loading(false), |
| 188 was_auto_launched_with_zero_delay(false) {} |
| 184 | 189 |
| 185 KioskAppManager::App::~App() {} | 190 KioskAppManager::App::~App() {} |
| 186 | 191 |
| 187 std::string KioskAppManager::GetAutoLaunchApp() const { | 192 std::string KioskAppManager::GetAutoLaunchApp() const { |
| 188 return auto_launch_app_id_; | 193 return auto_launch_app_id_; |
| 189 } | 194 } |
| 190 | 195 |
| 191 void KioskAppManager::SetAutoLaunchApp(const std::string& app_id, | 196 void KioskAppManager::SetAutoLaunchApp(const std::string& app_id, |
| 192 OwnerSettingsServiceChromeOS* service) { | 197 OwnerSettingsServiceChromeOS* service) { |
| 193 SetAutoLoginState(AUTOLOGIN_REQUESTED); | 198 SetAutoLoginState(AUTOLOGIN_REQUESTED); |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 627 policy::GetDeviceLocalAccounts(CrosSettings::Get()); | 632 policy::GetDeviceLocalAccounts(CrosSettings::Get()); |
| 628 for (std::vector<policy::DeviceLocalAccount>::const_iterator | 633 for (std::vector<policy::DeviceLocalAccount>::const_iterator |
| 629 it = device_local_accounts.begin(); | 634 it = device_local_accounts.begin(); |
| 630 it != device_local_accounts.end(); ++it) { | 635 it != device_local_accounts.end(); ++it) { |
| 631 if (it->type != policy::DeviceLocalAccount::TYPE_KIOSK_APP) | 636 if (it->type != policy::DeviceLocalAccount::TYPE_KIOSK_APP) |
| 632 continue; | 637 continue; |
| 633 | 638 |
| 634 if (it->account_id == auto_login_account_id) | 639 if (it->account_id == auto_login_account_id) |
| 635 auto_launch_app_id_ = it->kiosk_app_id; | 640 auto_launch_app_id_ = it->kiosk_app_id; |
| 636 | 641 |
| 642 // Note that app ids are not canonical, i.e. they can contain upper |
| 643 // case letters. |
| 644 const AccountId account_id(AccountId::FromUserEmail(it->user_id)); |
| 637 std::map<std::string, KioskAppData*>::iterator old_it = | 645 std::map<std::string, KioskAppData*>::iterator old_it = |
| 638 old_apps.find(it->kiosk_app_id); | 646 old_apps.find(it->kiosk_app_id); |
| 639 if (old_it != old_apps.end()) { | 647 if (old_it != old_apps.end()) { |
| 640 apps_.push_back(old_it->second); | 648 apps_.push_back(old_it->second); |
| 641 old_apps.erase(old_it); | 649 old_apps.erase(old_it); |
| 642 } else { | 650 } else { |
| 643 KioskAppData* new_app = new KioskAppData( | 651 KioskAppData* new_app = new KioskAppData( |
| 644 this, it->kiosk_app_id, it->user_id, GURL(it->kiosk_app_update_url)); | 652 this, it->kiosk_app_id, account_id, GURL(it->kiosk_app_update_url)); |
| 645 apps_.push_back(new_app); // Takes ownership of |new_app|. | 653 apps_.push_back(new_app); // Takes ownership of |new_app|. |
| 646 new_app->Load(); | 654 new_app->Load(); |
| 647 } | 655 } |
| 648 CancelDelayedCryptohomeRemoval(it->user_id); | 656 CancelDelayedCryptohomeRemoval(cryptohome::Identification(account_id)); |
| 649 } | 657 } |
| 650 | 658 |
| 651 base::Closure cryptohomes_barrier_closure; | 659 base::Closure cryptohomes_barrier_closure; |
| 652 | 660 |
| 653 const user_manager::User* active_user = | 661 const user_manager::User* active_user = |
| 654 user_manager::UserManager::Get()->GetActiveUser(); | 662 user_manager::UserManager::Get()->GetActiveUser(); |
| 655 if (active_user) { | 663 if (active_user) { |
| 656 const AccountId active_account_id = active_user->GetAccountId(); | 664 const AccountId active_account_id = active_user->GetAccountId(); |
| 657 for (const auto& it : old_apps) { | 665 for (const auto& it : old_apps) { |
| 658 if (it.second->user_id() == active_account_id.GetUserEmail()) { | 666 if (it.second->account_id() == active_account_id) { |
| 659 VLOG(1) << "Currently running kiosk app removed from policy, exiting"; | 667 VLOG(1) << "Currently running kiosk app removed from policy, exiting"; |
| 660 cryptohomes_barrier_closure = BarrierClosure( | 668 cryptohomes_barrier_closure = BarrierClosure( |
| 661 old_apps.size(), base::Bind(&chrome::AttemptUserExit)); | 669 old_apps.size(), base::Bind(&chrome::AttemptUserExit)); |
| 662 break; | 670 break; |
| 663 } | 671 } |
| 664 } | 672 } |
| 665 } | 673 } |
| 666 | 674 |
| 667 // Clears cache and deletes the remaining old data. | 675 // Clears cache and deletes the remaining old data. |
| 668 std::vector<std::string> apps_to_remove; | 676 std::vector<std::string> apps_to_remove; |
| 669 for (std::map<std::string, KioskAppData*>::iterator it = old_apps.begin(); | 677 for (std::map<std::string, KioskAppData*>::iterator it = old_apps.begin(); |
| 670 it != old_apps.end(); ++it) { | 678 it != old_apps.end(); ++it) { |
| 671 it->second->ClearCache(); | 679 it->second->ClearCache(); |
| 680 const cryptohome::Identification cryptohome_id(it->second->account_id()); |
| 672 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( | 681 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( |
| 673 it->second->user_id(), | 682 cryptohome_id, base::Bind(&OnRemoveAppCryptohomeComplete, cryptohome_id, |
| 674 base::Bind(&OnRemoveAppCryptohomeComplete, | 683 it->first, cryptohomes_barrier_closure)); |
| 675 it->second->user_id(), | |
| 676 it->first, | |
| 677 cryptohomes_barrier_closure)); | |
| 678 apps_to_remove.push_back(it->second->app_id()); | 684 apps_to_remove.push_back(it->second->app_id()); |
| 679 } | 685 } |
| 680 STLDeleteValues(&old_apps); | 686 STLDeleteValues(&old_apps); |
| 681 external_cache_->RemoveExtensions(apps_to_remove); | 687 external_cache_->RemoveExtensions(apps_to_remove); |
| 682 | 688 |
| 683 // Request external_cache_ to download new apps and update the existing | 689 // Request external_cache_ to download new apps and update the existing |
| 684 // apps. | 690 // apps. |
| 685 scoped_ptr<base::DictionaryValue> prefs(new base::DictionaryValue); | 691 scoped_ptr<base::DictionaryValue> prefs(new base::DictionaryValue); |
| 686 for (size_t i = 0; i < apps_.size(); ++i) { | 692 for (size_t i = 0; i < apps_.size(); ++i) { |
| 687 scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue); | 693 scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 778 *cache_dir = user_data_dir.AppendASCII(kCrxCacheDir); | 784 *cache_dir = user_data_dir.AppendASCII(kCrxCacheDir); |
| 779 } | 785 } |
| 780 | 786 |
| 781 void KioskAppManager::GetCrxUnpackDir(base::FilePath* unpack_dir) { | 787 void KioskAppManager::GetCrxUnpackDir(base::FilePath* unpack_dir) { |
| 782 base::FilePath temp_dir; | 788 base::FilePath temp_dir; |
| 783 base::GetTempDir(&temp_dir); | 789 base::GetTempDir(&temp_dir); |
| 784 *unpack_dir = temp_dir.AppendASCII(kCrxUnpackDir); | 790 *unpack_dir = temp_dir.AppendASCII(kCrxUnpackDir); |
| 785 } | 791 } |
| 786 | 792 |
| 787 } // namespace chromeos | 793 } // namespace chromeos |
| OLD | NEW |