browser_policy_connector_chromeos.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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
53using content::BrowserThread;
54
55namespace policy {
56
57namespace {
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.
63const char kDefaultConsumerDeviceManagementServerUrl[] =
64    "https://m.google.com/devicemanagement/data/api";
65
66// Install attributes for tests.
67EnterpriseInstallAttributes* 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.
71scoped_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
78std::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
90BrowserPolicyConnectorChromeOS::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
138BrowserPolicyConnectorChromeOS::~BrowserPolicyConnectorChromeOS() {}
139
140void 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
218void 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
231void 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
251bool BrowserPolicyConnectorChromeOS::IsEnterpriseManaged() {
252  return install_attributes_ && install_attributes_->IsEnterpriseDevice();
253}
254
255std::string BrowserPolicyConnectorChromeOS::GetEnterpriseDomain() {
256  return install_attributes_ ? install_attributes_->GetDomain() : std::string();
257}
258
259DeviceMode BrowserPolicyConnectorChromeOS::GetDeviceMode() {
260  return install_attributes_ ? install_attributes_->GetMode()
261                             : DEVICE_MODE_NOT_SET;
262}
263
264UserAffiliation 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
283AppPackUpdater* BrowserPolicyConnectorChromeOS::GetAppPackUpdater() {
284  return app_pack_updater_.get();
285}
286
287void BrowserPolicyConnectorChromeOS::SetUserPolicyDelegate(
288    ConfigurationPolicyProvider* user_policy_provider) {
289  global_user_cloud_policy_provider_->SetDelegate(user_policy_provider);
290}
291
292void BrowserPolicyConnectorChromeOS::SetDeviceCloudPolicyInitializerForTesting(
293    scoped_ptr<DeviceCloudPolicyInitializer> initializer) {
294  device_cloud_policy_initializer_ = initializer.Pass();
295}
296
297void BrowserPolicyConnectorChromeOS::SetInstallAttributesForTesting(
298    EnterpriseInstallAttributes* attributes) {
299  DCHECK(!g_testing_install_attributes);
300  g_testing_install_attributes = attributes;
301}
302
303void 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
311void BrowserPolicyConnectorChromeOS::RegisterPrefs(
312    PrefRegistrySimple* registry) {
313  registry->RegisterIntegerPref(
314      prefs::kDevicePolicyRefreshRate,
315      CloudPolicyRefreshScheduler::kDefaultRefreshDelayMs);
316}
317
318void 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
337void 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