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, nullptr); | 82 dict_update->RemoveWithoutPathExpansion(id.id(), nullptr); |
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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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(const KioskAppData& data, | 175 KioskAppManager::App::App(const KioskAppData& data, |
171 bool is_extension_pending, | 176 bool is_extension_pending, |
172 bool auto_launched_with_zero_delay) | 177 bool auto_launched_with_zero_delay) |
173 : app_id(data.app_id()), | 178 : app_id(data.app_id()), |
174 user_id(data.user_id()), | 179 account_id(data.account_id()), |
175 name(data.name()), | 180 name(data.name()), |
176 icon(data.icon()), | 181 icon(data.icon()), |
177 required_platform_version(data.required_platform_version()), | 182 required_platform_version(data.required_platform_version()), |
178 is_loading(data.IsLoading() || is_extension_pending), | 183 is_loading(data.IsLoading() || is_extension_pending), |
179 was_auto_launched_with_zero_delay(auto_launched_with_zero_delay) {} | 184 was_auto_launched_with_zero_delay(auto_launched_with_zero_delay) {} |
180 | 185 |
181 KioskAppManager::App::App() : is_loading(false), | 186 KioskAppManager::App::App() |
182 was_auto_launched_with_zero_delay(false) {} | 187 : account_id(EmptyAccountId()), |
| 188 is_loading(false), |
| 189 was_auto_launched_with_zero_delay(false) {} |
183 | 190 |
184 KioskAppManager::App::~App() {} | 191 KioskAppManager::App::~App() {} |
185 | 192 |
186 std::string KioskAppManager::GetAutoLaunchApp() const { | 193 std::string KioskAppManager::GetAutoLaunchApp() const { |
187 return auto_launch_app_id_; | 194 return auto_launch_app_id_; |
188 } | 195 } |
189 | 196 |
190 void KioskAppManager::SetAutoLaunchApp(const std::string& app_id, | 197 void KioskAppManager::SetAutoLaunchApp(const std::string& app_id, |
191 OwnerSettingsServiceChromeOS* service) { | 198 OwnerSettingsServiceChromeOS* service) { |
192 SetAutoLoginState(AUTOLOGIN_REQUESTED); | 199 SetAutoLoginState(AUTOLOGIN_REQUESTED); |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
635 policy::GetDeviceLocalAccounts(CrosSettings::Get()); | 642 policy::GetDeviceLocalAccounts(CrosSettings::Get()); |
636 for (std::vector<policy::DeviceLocalAccount>::const_iterator | 643 for (std::vector<policy::DeviceLocalAccount>::const_iterator |
637 it = device_local_accounts.begin(); | 644 it = device_local_accounts.begin(); |
638 it != device_local_accounts.end(); ++it) { | 645 it != device_local_accounts.end(); ++it) { |
639 if (it->type != policy::DeviceLocalAccount::TYPE_KIOSK_APP) | 646 if (it->type != policy::DeviceLocalAccount::TYPE_KIOSK_APP) |
640 continue; | 647 continue; |
641 | 648 |
642 if (it->account_id == auto_login_account_id) | 649 if (it->account_id == auto_login_account_id) |
643 auto_launch_app_id_ = it->kiosk_app_id; | 650 auto_launch_app_id_ = it->kiosk_app_id; |
644 | 651 |
| 652 // Note that app ids are not canonical, i.e. they can contain upper |
| 653 // case letters. |
| 654 const AccountId account_id(AccountId::FromUserEmail(it->user_id)); |
645 std::map<std::string, KioskAppData*>::iterator old_it = | 655 std::map<std::string, KioskAppData*>::iterator old_it = |
646 old_apps.find(it->kiosk_app_id); | 656 old_apps.find(it->kiosk_app_id); |
647 if (old_it != old_apps.end()) { | 657 if (old_it != old_apps.end()) { |
648 apps_.push_back(old_it->second); | 658 apps_.push_back(old_it->second); |
649 old_apps.erase(old_it); | 659 old_apps.erase(old_it); |
650 } else { | 660 } else { |
651 KioskAppData* new_app = new KioskAppData( | 661 KioskAppData* new_app = new KioskAppData( |
652 this, it->kiosk_app_id, it->user_id, GURL(it->kiosk_app_update_url)); | 662 this, it->kiosk_app_id, account_id, GURL(it->kiosk_app_update_url)); |
653 apps_.push_back(new_app); // Takes ownership of |new_app|. | 663 apps_.push_back(new_app); // Takes ownership of |new_app|. |
654 new_app->Load(); | 664 new_app->Load(); |
655 } | 665 } |
656 CancelDelayedCryptohomeRemoval(it->user_id); | 666 CancelDelayedCryptohomeRemoval(cryptohome::Identification(account_id)); |
657 } | 667 } |
658 | 668 |
659 base::Closure cryptohomes_barrier_closure; | 669 base::Closure cryptohomes_barrier_closure; |
660 | 670 |
661 const user_manager::User* active_user = | 671 const user_manager::User* active_user = |
662 user_manager::UserManager::Get()->GetActiveUser(); | 672 user_manager::UserManager::Get()->GetActiveUser(); |
663 if (active_user) { | 673 if (active_user) { |
664 const AccountId active_account_id = active_user->GetAccountId(); | 674 const AccountId active_account_id = active_user->GetAccountId(); |
665 for (const auto& it : old_apps) { | 675 for (const auto& it : old_apps) { |
666 if (it.second->user_id() == active_account_id.GetUserEmail()) { | 676 if (it.second->account_id() == active_account_id) { |
667 VLOG(1) << "Currently running kiosk app removed from policy, exiting"; | 677 VLOG(1) << "Currently running kiosk app removed from policy, exiting"; |
668 cryptohomes_barrier_closure = BarrierClosure( | 678 cryptohomes_barrier_closure = BarrierClosure( |
669 old_apps.size(), base::Bind(&chrome::AttemptUserExit)); | 679 old_apps.size(), base::Bind(&chrome::AttemptUserExit)); |
670 break; | 680 break; |
671 } | 681 } |
672 } | 682 } |
673 } | 683 } |
674 | 684 |
675 // Clears cache and deletes the remaining old data. | 685 // Clears cache and deletes the remaining old data. |
676 std::vector<std::string> apps_to_remove; | 686 std::vector<std::string> apps_to_remove; |
677 for (std::map<std::string, KioskAppData*>::iterator it = old_apps.begin(); | 687 for (std::map<std::string, KioskAppData*>::iterator it = old_apps.begin(); |
678 it != old_apps.end(); ++it) { | 688 it != old_apps.end(); ++it) { |
679 it->second->ClearCache(); | 689 it->second->ClearCache(); |
| 690 const cryptohome::Identification cryptohome_id(it->second->account_id()); |
680 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( | 691 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( |
681 it->second->user_id(), | 692 cryptohome_id, base::Bind(&OnRemoveAppCryptohomeComplete, cryptohome_id, |
682 base::Bind(&OnRemoveAppCryptohomeComplete, | 693 it->first, cryptohomes_barrier_closure)); |
683 it->second->user_id(), | |
684 it->first, | |
685 cryptohomes_barrier_closure)); | |
686 apps_to_remove.push_back(it->second->app_id()); | 694 apps_to_remove.push_back(it->second->app_id()); |
687 } | 695 } |
688 STLDeleteValues(&old_apps); | 696 STLDeleteValues(&old_apps); |
689 external_cache_->RemoveExtensions(apps_to_remove); | 697 external_cache_->RemoveExtensions(apps_to_remove); |
690 | 698 |
691 // Request external_cache_ to download new apps and update the existing | 699 // Request external_cache_ to download new apps and update the existing |
692 // apps. | 700 // apps. |
693 scoped_ptr<base::DictionaryValue> prefs(new base::DictionaryValue); | 701 scoped_ptr<base::DictionaryValue> prefs(new base::DictionaryValue); |
694 for (size_t i = 0; i < apps_.size(); ++i) { | 702 for (size_t i = 0; i < apps_.size(); ++i) { |
695 scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue); | 703 scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
795 base::TimeDelta KioskAppManager::GetAutoLaunchDelay() const { | 803 base::TimeDelta KioskAppManager::GetAutoLaunchDelay() const { |
796 int delay; | 804 int delay; |
797 if (!CrosSettings::Get()->GetInteger( | 805 if (!CrosSettings::Get()->GetInteger( |
798 kAccountsPrefDeviceLocalAccountAutoLoginDelay, &delay)) { | 806 kAccountsPrefDeviceLocalAccountAutoLoginDelay, &delay)) { |
799 return base::TimeDelta(); // Default delay is 0ms. | 807 return base::TimeDelta(); // Default delay is 0ms. |
800 } | 808 } |
801 return base::TimeDelta::FromMilliseconds(delay); | 809 return base::TimeDelta::FromMilliseconds(delay); |
802 } | 810 } |
803 | 811 |
804 } // namespace chromeos | 812 } // namespace chromeos |
OLD | NEW |