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