1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
6
7 #include <string>
8 #include "base/bind.h"
9 #include "base/bind_helpers.h"
10 #include "base/command_line.h"
11 #include "base/files/file_path.h"
12 #include "base/location.h"
13 #include "base/logging.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/message_loop/message_loop_proxy.h"
16 #include "base/path_service.h"
17 #include "base/prefs/pref_registry_simple.h"
18 #include "base/sequenced_task_runner.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "base/threading/sequenced_worker_pool.h"
21 #include "chrome/browser/chromeos/policy/app_pack_updater.h"
22 #include "chrome/browser/chromeos/policy/consumer_management_service.h"
23 #include "chrome/browser/chromeos/policy/device_cloud_policy_initializer.h"
24 #include "chrome/browser/chromeos/policy/device_cloud_policy_invalidator.h"
25 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
26 #include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h"
27 #include "chrome/browser/chromeos/policy/device_local_account.h"
28 #include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
29 #include "chrome/browser/chromeos/policy/device_network_configuration_updater.h"
30 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h"
31 #include "chrome/browser/chromeos/policy/server_backed_state_keys_broker.h"
32 #include "chrome/browser/chromeos/settings/cros_settings.h"
33 #include "chrome/browser/chromeos/settings/device_settings_service.h"
34 #include "chrome/browser/policy/device_management_service_configuration.h"
35 #include "chrome/common/pref_names.h"
36 #include "chromeos/chromeos_paths.h"
37 #include "chromeos/chromeos_switches.h"
38 #include "chromeos/cryptohome/system_salt_getter.h"
39 #include "chromeos/dbus/cryptohome_client.h"
40 #include "chromeos/dbus/dbus_thread_manager.h"
41 #include "chromeos/network/network_handler.h"
42 #include "chromeos/network/onc/onc_certificate_importer_impl.h"
43 #include "chromeos/settings/cros_settings_names.h"
44 #include "chromeos/settings/cros_settings_provider.h"
45 #include "chromeos/settings/timezone_settings.h"
46 #include "components/policy/core/common/cloud/cloud_policy_client.h"
47 #include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h"
48 #include "components/policy/core/common/proxy_policy_provider.h"
49 #include "content/public/browser/browser_thread.h"
50 #include "google_apis/gaia/gaia_auth_util.h"
51 #include "net/url_request/url_request_context_getter.h"
52
53 using content::BrowserThread;
54
55 namespace policy {
56
57 namespace {
58
59 // TODO(davidyu): Update the URL to the real one once it is ready.
60 // http://crbug.com/366491.
61 //
62 // The URL for the consumer device management server.
63 const char kDefaultConsumerDeviceManagementServerUrl[] =
64 "https://m.google.com/devicemanagement/data/api";
65
66 // Install attributes for tests.
67 EnterpriseInstallAttributes* g_testing_install_attributes = NULL;
68
69 // Helper that returns a new SequencedTaskRunner backed by the blocking pool.
70 // Each SequencedTaskRunner returned is independent from the others.
GetBackgroundTaskRunner()71 scoped_refptr<base::SequencedTaskRunner> GetBackgroundTaskRunner() {
72 base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool();
73 CHECK(pool);
74 return pool->GetSequencedTaskRunnerWithShutdownBehavior(
75 pool->GetSequenceToken(), base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
76 }
77
GetDeviceManagementServerUrlForConsumer()78 std::string GetDeviceManagementServerUrlForConsumer() {
79 const CommandLine* command_line = CommandLine::ForCurrentProcess();
80 if (command_line->HasSwitch(
81 chromeos::switches::kConsumerDeviceManagementUrl)) {
82 return command_line->GetSwitchValueASCII(
83 chromeos::switches::kConsumerDeviceManagementUrl);
84 }
85 return kDefaultConsumerDeviceManagementServerUrl;
86 }
87
88 } // namespace
89
BrowserPolicyConnectorChromeOS()90 BrowserPolicyConnectorChromeOS::BrowserPolicyConnectorChromeOS()
91 : device_cloud_policy_manager_(NULL),
92 global_user_cloud_policy_provider_(NULL),
93 weak_ptr_factory_(this) {
94 if (g_testing_install_attributes) {
95 install_attributes_.reset(g_testing_install_attributes);
96 g_testing_install_attributes = NULL;
97 }
98
99 // SystemSaltGetter or DBusThreadManager may be uninitialized on unit tests.
100
101 // TODO(satorux): Remove SystemSaltGetter::IsInitialized() when it's ready
102 // (removing it now breaks tests). crbug.com/141016.
103 if (chromeos::SystemSaltGetter::IsInitialized() &&
104 chromeos::DBusThreadManager::IsInitialized()) {
105 state_keys_broker_.reset(new ServerBackedStateKeysBroker(
106 chromeos::DBusThreadManager::Get()->GetSessionManagerClient(),
107 base::MessageLoopProxy::current()));
108
109 chromeos::CryptohomeClient* cryptohome_client =
110 chromeos::DBusThreadManager::Get()->GetCryptohomeClient();
111 if (!install_attributes_) {
112 install_attributes_.reset(
113 new EnterpriseInstallAttributes(cryptohome_client));
114 }
115 base::FilePath install_attrs_file;
116 CHECK(PathService::Get(chromeos::FILE_INSTALL_ATTRIBUTES,
117 &install_attrs_file));
118 install_attributes_->ReadCacheFile(install_attrs_file);
119
120 scoped_ptr<DeviceCloudPolicyStoreChromeOS> device_cloud_policy_store(
121 new DeviceCloudPolicyStoreChromeOS(
122 chromeos::DeviceSettingsService::Get(),
123 install_attributes_.get(),
124 GetBackgroundTaskRunner()));
125 device_cloud_policy_manager_ =
126 new DeviceCloudPolicyManagerChromeOS(device_cloud_policy_store.Pass(),
127 base::MessageLoopProxy::current(),
128 state_keys_broker_.get());
129 AddPolicyProvider(
130 scoped_ptr<ConfigurationPolicyProvider>(device_cloud_policy_manager_));
131 }
132
133 global_user_cloud_policy_provider_ = new ProxyPolicyProvider();
134 AddPolicyProvider(scoped_ptr<ConfigurationPolicyProvider>(
135 global_user_cloud_policy_provider_));
136 }
137
~BrowserPolicyConnectorChromeOS()138 BrowserPolicyConnectorChromeOS::~BrowserPolicyConnectorChromeOS() {}
139
Init(PrefService * local_state,scoped_refptr<net::URLRequestContextGetter> request_context)140 void BrowserPolicyConnectorChromeOS::Init(
141 PrefService* local_state,
142 scoped_refptr<net::URLRequestContextGetter> request_context) {
143 ChromeBrowserPolicyConnector::Init(local_state, request_context);
144
145 scoped_ptr<DeviceManagementService::Configuration> configuration(
146 new DeviceManagementServiceConfiguration(
147 GetDeviceManagementServerUrlForConsumer()));
148 consumer_device_management_service_.reset(
149 new DeviceManagementService(configuration.Pass()));
150 consumer_device_management_service_->ScheduleInitialization(
151 kServiceInitializationStartupDelay);
152
153 const CommandLine* command_line = CommandLine::ForCurrentProcess();
154 if (command_line->HasSwitch(chromeos::switches::kEnableConsumerManagement)) {
155 chromeos::CryptohomeClient* cryptohome_client =
156 chromeos::DBusThreadManager::Get()->GetCryptohomeClient();
157 consumer_management_service_.reset(
158 new ConsumerManagementService(cryptohome_client,
159 chromeos::DeviceSettingsService::Get()));
160 }
161
162 if (device_cloud_policy_manager_) {
163 // Note: for now the |device_cloud_policy_manager_| is using the global
164 // schema registry. Eventually it will have its own registry, once device
165 // cloud policy for extensions is introduced. That means it'd have to be
166 // initialized from here instead of BrowserPolicyConnector::Init().
167
168 device_cloud_policy_manager_->Initialize(local_state);
169
170 device_cloud_policy_initializer_.reset(
171 new DeviceCloudPolicyInitializer(
172 local_state,
173 device_management_service(),
174 GetDeviceManagementServiceForConsumer(),
175 GetBackgroundTaskRunner(),
176 install_attributes_.get(),
177 state_keys_broker_.get(),
178 device_cloud_policy_manager_->device_store(),
179 device_cloud_policy_manager_,
180 chromeos::DeviceSettingsService::Get(),
181 base::Bind(&BrowserPolicyConnectorChromeOS::
182 OnDeviceCloudPolicyManagerConnected,
183 base::Unretained(this))));
184 device_cloud_policy_initializer_->Init();
185 }
186
187 device_local_account_policy_service_.reset(
188 new DeviceLocalAccountPolicyService(
189 chromeos::DBusThreadManager::Get()->GetSessionManagerClient(),
190 chromeos::DeviceSettingsService::Get(),
191 chromeos::CrosSettings::Get(),
192 GetBackgroundTaskRunner(),
193 GetBackgroundTaskRunner(),
194 GetBackgroundTaskRunner(),
195 content::BrowserThread::GetMessageLoopProxyForThread(
196 content::BrowserThread::IO),
197 request_context));
198 device_local_account_policy_service_->Connect(device_management_service());
199 device_cloud_policy_invalidator_.reset(new DeviceCloudPolicyInvalidator);
200
201 // request_context is NULL in unit tests.
202 if (request_context.get() && install_attributes_) {
203 app_pack_updater_.reset(
204 new AppPackUpdater(request_context.get(), install_attributes_.get()));
205 }
206
207 SetTimezoneIfPolicyAvailable();
208
209 network_configuration_updater_ =
210 DeviceNetworkConfigurationUpdater::CreateForDevicePolicy(
211 GetPolicyService(),
212 chromeos::NetworkHandler::Get()
213 ->managed_network_configuration_handler(),
214 chromeos::NetworkHandler::Get()->network_device_handler(),
215 chromeos::CrosSettings::Get());
216 }
217
PreShutdown()218 void BrowserPolicyConnectorChromeOS::PreShutdown() {
219 // Let the |device_cloud_policy_invalidator_| unregister itself as an
220 // observer of per-Profile InvalidationServices and the device-global
221 // invalidation::TiclInvalidationService it may have created as an observer of
222 // the DeviceOAuth2TokenService that is destroyed before Shutdown() is called.
223 device_cloud_policy_invalidator_.reset();
224
225 // The |consumer_management_service_| may be observing a
226 // ProfileOAuth2TokenService and needs to be destroyed before the token
227 // service.
228 consumer_management_service_.reset();
229 }
230
Shutdown()231 void BrowserPolicyConnectorChromeOS::Shutdown() {
232 // Verify that PreShutdown() has been called first.
233 DCHECK(!device_cloud_policy_invalidator_);
234 DCHECK(!consumer_management_service_);
235
236 // The AppPackUpdater may be observing the |device_cloud_policy_manager_|.
237 // Delete it first.
238 app_pack_updater_.reset();
239
240 network_configuration_updater_.reset();
241
242 if (device_local_account_policy_service_)
243 device_local_account_policy_service_->Shutdown();
244
245 if (device_cloud_policy_initializer_)
246 device_cloud_policy_initializer_->Shutdown();
247
248 ChromeBrowserPolicyConnector::Shutdown();
249 }
250
IsEnterpriseManaged()251 bool BrowserPolicyConnectorChromeOS::IsEnterpriseManaged() {
252 return install_attributes_ && install_attributes_->IsEnterpriseDevice();
253 }
254
GetEnterpriseDomain()255 std::string BrowserPolicyConnectorChromeOS::GetEnterpriseDomain() {
256 return install_attributes_ ? install_attributes_->GetDomain() : std::string();
257 }
258
GetDeviceMode()259 DeviceMode BrowserPolicyConnectorChromeOS::GetDeviceMode() {
260 return install_attributes_ ? install_attributes_->GetMode()
261 : DEVICE_MODE_NOT_SET;
262 }
263
GetUserAffiliation(const std::string & user_name)264 UserAffiliation BrowserPolicyConnectorChromeOS::GetUserAffiliation(
265 const std::string& user_name) {
266 // An empty username means incognito user in case of ChromiumOS and
267 // no logged-in user in case of Chromium (SigninService). Many tests use
268 // nonsense email addresses (e.g. 'test') so treat those as non-enterprise
269 // users.
270 if (user_name.empty() || user_name.find('@') == std::string::npos)
271 return USER_AFFILIATION_NONE;
272
273 if (install_attributes_ &&
274 (gaia::ExtractDomainName(gaia::CanonicalizeEmail(user_name)) ==
275 install_attributes_->GetDomain() ||
276 policy::IsDeviceLocalAccountUser(user_name, NULL))) {
277 return USER_AFFILIATION_MANAGED;
278 }
279
280 return USER_AFFILIATION_NONE;
281 }
282
GetAppPackUpdater()283 AppPackUpdater* BrowserPolicyConnectorChromeOS::GetAppPackUpdater() {
284 return app_pack_updater_.get();
285 }
286
SetUserPolicyDelegate(ConfigurationPolicyProvider * user_policy_provider)287 void BrowserPolicyConnectorChromeOS::SetUserPolicyDelegate(
288 ConfigurationPolicyProvider* user_policy_provider) {
289 global_user_cloud_policy_provider_->SetDelegate(user_policy_provider);
290 }
291
SetDeviceCloudPolicyInitializerForTesting(scoped_ptr<DeviceCloudPolicyInitializer> initializer)292 void BrowserPolicyConnectorChromeOS::SetDeviceCloudPolicyInitializerForTesting(
293 scoped_ptr<DeviceCloudPolicyInitializer> initializer) {
294 device_cloud_policy_initializer_ = initializer.Pass();
295 }
296
SetInstallAttributesForTesting(EnterpriseInstallAttributes * attributes)297 void BrowserPolicyConnectorChromeOS::SetInstallAttributesForTesting(
298 EnterpriseInstallAttributes* attributes) {
299 DCHECK(!g_testing_install_attributes);
300 g_testing_install_attributes = attributes;
301 }
302
RemoveInstallAttributesForTesting()303 void BrowserPolicyConnectorChromeOS::RemoveInstallAttributesForTesting() {
304 if (g_testing_install_attributes) {
305 delete g_testing_install_attributes;
306 g_testing_install_attributes = NULL;
307 }
308 }
309
310 // static
RegisterPrefs(PrefRegistrySimple * registry)311 void BrowserPolicyConnectorChromeOS::RegisterPrefs(
312 PrefRegistrySimple* registry) {
313 registry->RegisterIntegerPref(
314 prefs::kDevicePolicyRefreshRate,
315 CloudPolicyRefreshScheduler::kDefaultRefreshDelayMs);
316 }
317
SetTimezoneIfPolicyAvailable()318 void BrowserPolicyConnectorChromeOS::SetTimezoneIfPolicyAvailable() {
319 typedef chromeos::CrosSettingsProvider Provider;
320 Provider::TrustedStatus result =
321 chromeos::CrosSettings::Get()->PrepareTrustedValues(base::Bind(
322 &BrowserPolicyConnectorChromeOS::SetTimezoneIfPolicyAvailable,
323 weak_ptr_factory_.GetWeakPtr()));
324
325 if (result != Provider::TRUSTED)
326 return;
327
328 std::string timezone;
329 if (chromeos::CrosSettings::Get()->GetString(chromeos::kSystemTimezonePolicy,
330 &timezone) &&
331 !timezone.empty()) {
332 chromeos::system::TimezoneSettings::GetInstance()->SetTimezoneFromID(
333 base::UTF8ToUTF16(timezone));
334 }
335 }
336
OnDeviceCloudPolicyManagerConnected()337 void BrowserPolicyConnectorChromeOS::OnDeviceCloudPolicyManagerConnected() {
338 // This function is invoked by DCPInitializer, so we should release the
339 // initializer after this function returns.
340 if (device_cloud_policy_initializer_) {
341 device_cloud_policy_initializer_->Shutdown();
342 base::MessageLoop::current()->DeleteSoon(
343 FROM_HERE, device_cloud_policy_initializer_.release());
344 }
345 }
346
347 } // namespace policy
348