Home | History | Annotate | Download | only in policy
      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.
     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 
     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 
     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 
    138 BrowserPolicyConnectorChromeOS::~BrowserPolicyConnectorChromeOS() {}
    139 
    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 
    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 
    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 
    251 bool BrowserPolicyConnectorChromeOS::IsEnterpriseManaged() {
    252   return install_attributes_ && install_attributes_->IsEnterpriseDevice();
    253 }
    254 
    255 std::string BrowserPolicyConnectorChromeOS::GetEnterpriseDomain() {
    256   return install_attributes_ ? install_attributes_->GetDomain() : std::string();
    257 }
    258 
    259 DeviceMode BrowserPolicyConnectorChromeOS::GetDeviceMode() {
    260   return install_attributes_ ? install_attributes_->GetMode()
    261                              : DEVICE_MODE_NOT_SET;
    262 }
    263 
    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 
    283 AppPackUpdater* BrowserPolicyConnectorChromeOS::GetAppPackUpdater() {
    284   return app_pack_updater_.get();
    285 }
    286 
    287 void BrowserPolicyConnectorChromeOS::SetUserPolicyDelegate(
    288     ConfigurationPolicyProvider* user_policy_provider) {
    289   global_user_cloud_policy_provider_->SetDelegate(user_policy_provider);
    290 }
    291 
    292 void BrowserPolicyConnectorChromeOS::SetDeviceCloudPolicyInitializerForTesting(
    293     scoped_ptr<DeviceCloudPolicyInitializer> initializer) {
    294   device_cloud_policy_initializer_ = initializer.Pass();
    295 }
    296 
    297 void BrowserPolicyConnectorChromeOS::SetInstallAttributesForTesting(
    298     EnterpriseInstallAttributes* attributes) {
    299   DCHECK(!g_testing_install_attributes);
    300   g_testing_install_attributes = attributes;
    301 }
    302 
    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
    311 void BrowserPolicyConnectorChromeOS::RegisterPrefs(
    312     PrefRegistrySimple* registry) {
    313   registry->RegisterIntegerPref(
    314       prefs::kDevicePolicyRefreshRate,
    315       CloudPolicyRefreshScheduler::kDefaultRefreshDelayMs);
    316 }
    317 
    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 
    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