1 // Copyright (c) 2012 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/policy/browser_policy_connector.h" 6 7 #include <algorithm> 8 #include <iterator> 9 10 #include "base/bind.h" 11 #include "base/bind_helpers.h" 12 #include "base/command_line.h" 13 #include "base/files/file_path.h" 14 #include "base/logging.h" 15 #include "base/message_loop/message_loop.h" 16 #include "base/path_service.h" 17 #include "base/prefs/pref_registry_simple.h" 18 #include "base/prefs/pref_service.h" 19 #include "base/strings/string_util.h" 20 #include "base/strings/utf_string_conversions.h" 21 #include "chrome/browser/browser_process.h" 22 #include "chrome/browser/policy/async_policy_provider.h" 23 #include "chrome/browser/policy/cloud/cloud_policy_client.h" 24 #include "chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.h" 25 #include "chrome/browser/policy/cloud/cloud_policy_service.h" 26 #include "chrome/browser/policy/cloud/device_management_service.h" 27 #include "chrome/browser/policy/configuration_policy_provider.h" 28 #include "chrome/browser/policy/managed_mode_policy_provider.h" 29 #include "chrome/browser/policy/policy_domain_descriptor.h" 30 #include "chrome/browser/policy/policy_service_impl.h" 31 #include "chrome/browser/policy/policy_statistics_collector.h" 32 #include "chrome/common/chrome_paths.h" 33 #include "chrome/common/chrome_switches.h" 34 #include "chrome/common/pref_names.h" 35 #include "content/public/browser/browser_thread.h" 36 #include "google_apis/gaia/gaia_auth_util.h" 37 #include "google_apis/gaia/gaia_constants.h" 38 #include "grit/generated_resources.h" 39 #include "net/url_request/url_request_context_getter.h" 40 #include "policy/policy_constants.h" 41 #include "third_party/icu/source/i18n/unicode/regex.h" 42 43 #if defined(OS_WIN) 44 #include "chrome/browser/policy/policy_loader_win.h" 45 #elif defined(OS_MACOSX) 46 #include "chrome/browser/policy/policy_loader_mac.h" 47 #include "chrome/browser/policy/preferences_mac.h" 48 #elif defined(OS_POSIX) && !defined(OS_ANDROID) 49 #include "chrome/browser/policy/config_dir_policy_loader.h" 50 #endif 51 52 #if defined(OS_CHROMEOS) 53 #include "chrome/browser/chromeos/cros/network_library.h" 54 #include "chrome/browser/chromeos/login/user_manager.h" 55 #include "chrome/browser/chromeos/policy/app_pack_updater.h" 56 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h" 57 #include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h" 58 #include "chrome/browser/chromeos/policy/device_local_account.h" 59 #include "chrome/browser/chromeos/policy/device_local_account_policy_service.h" 60 #include "chrome/browser/chromeos/policy/device_status_collector.h" 61 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h" 62 #include "chrome/browser/chromeos/policy/network_configuration_updater.h" 63 #include "chrome/browser/chromeos/policy/network_configuration_updater_impl.h" 64 #include "chrome/browser/chromeos/policy/network_configuration_updater_impl_cros.h" 65 #include "chrome/browser/chromeos/settings/cros_settings.h" 66 #include "chrome/browser/chromeos/settings/cros_settings_provider.h" 67 #include "chrome/browser/chromeos/settings/device_settings_service.h" 68 #include "chrome/browser/chromeos/system/statistics_provider.h" 69 #include "chrome/browser/chromeos/system/timezone_settings.h" 70 #include "chromeos/chromeos_paths.h" 71 #include "chromeos/chromeos_switches.h" 72 #include "chromeos/cryptohome/cryptohome_library.h" 73 #include "chromeos/dbus/cryptohome_client.h" 74 #include "chromeos/dbus/dbus_thread_manager.h" 75 #include "chromeos/network/managed_network_configuration_handler.h" 76 #include "chromeos/network/onc/onc_certificate_importer_impl.h" 77 #endif 78 79 using content::BrowserThread; 80 81 namespace policy { 82 83 namespace { 84 85 // The following constants define delays applied before the initial policy fetch 86 // on startup. (So that displaying Chrome's GUI does not get delayed.) 87 // Delay in milliseconds from startup. 88 const int64 kServiceInitializationStartupDelay = 5000; 89 90 // The URL for the device management server. 91 const char kDefaultDeviceManagementServerUrl[] = 92 "https://m.google.com/devicemanagement/data/api"; 93 94 // Used in BrowserPolicyConnector::SetPolicyProviderForTesting. 95 ConfigurationPolicyProvider* g_testing_provider = NULL; 96 97 } // namespace 98 99 BrowserPolicyConnector::BrowserPolicyConnector() 100 : is_initialized_(false), 101 local_state_(NULL), 102 weak_ptr_factory_(this) { 103 // GetPolicyService() must be ready after the constructor is done. 104 // The connector is created very early during startup, when the browser 105 // threads aren't running yet; initialize components that need local_state, 106 // the system request context or other threads (e.g. FILE) at Init(). 107 108 platform_provider_.reset(CreatePlatformProvider()); 109 110 device_management_service_.reset( 111 new DeviceManagementService(GetDeviceManagementUrl())); 112 113 #if defined(OS_CHROMEOS) 114 // CryptohomeLibrary or DBusThreadManager may be uninitialized on unit tests. 115 if (chromeos::CryptohomeLibrary::IsInitialized() && 116 chromeos::DBusThreadManager::IsInitialized()) { 117 chromeos::CryptohomeLibrary* cryptohome = 118 chromeos::CryptohomeLibrary::Get(); 119 chromeos::CryptohomeClient* cryptohome_client = 120 chromeos::DBusThreadManager::Get()->GetCryptohomeClient(); 121 install_attributes_.reset( 122 new EnterpriseInstallAttributes(cryptohome, cryptohome_client)); 123 base::FilePath install_attrs_file; 124 CHECK(PathService::Get(chromeos::FILE_INSTALL_ATTRIBUTES, 125 &install_attrs_file)); 126 install_attributes_->ReadCacheFile(install_attrs_file); 127 128 scoped_ptr<DeviceCloudPolicyStoreChromeOS> device_cloud_policy_store( 129 new DeviceCloudPolicyStoreChromeOS( 130 chromeos::DeviceSettingsService::Get(), 131 install_attributes_.get())); 132 device_cloud_policy_manager_.reset( 133 new DeviceCloudPolicyManagerChromeOS( 134 device_cloud_policy_store.Pass(), 135 install_attributes_.get())); 136 } 137 #endif 138 } 139 140 BrowserPolicyConnector::~BrowserPolicyConnector() { 141 if (is_initialized()) { 142 // Shutdown() wasn't invoked by our owner after having called Init(). 143 // This usually means it's an early shutdown and 144 // BrowserProcessImpl::StartTearDown() wasn't invoked. 145 // Cleanup properly in those cases and avoid crashing the ToastCrasher test. 146 Shutdown(); 147 } 148 } 149 150 void BrowserPolicyConnector::Init( 151 PrefService* local_state, 152 scoped_refptr<net::URLRequestContextGetter> request_context) { 153 // Initialization of some of the providers requires the FILE thread; make 154 // sure that threading is ready at this point. 155 DCHECK(BrowserThread::IsThreadInitialized(BrowserThread::FILE)); 156 DCHECK(!is_initialized()) << "BrowserPolicyConnector::Init() called twice."; 157 158 local_state_ = local_state; 159 request_context_ = request_context; 160 161 device_management_service_->ScheduleInitialization( 162 kServiceInitializationStartupDelay); 163 164 if (g_testing_provider) 165 g_testing_provider->Init(); 166 if (platform_provider_) 167 platform_provider_->Init(); 168 169 #if defined(OS_CHROMEOS) 170 global_user_cloud_policy_provider_.Init(); 171 172 if (device_cloud_policy_manager_) { 173 device_cloud_policy_manager_->Init(); 174 scoped_ptr<CloudPolicyClient::StatusProvider> status_provider( 175 new DeviceStatusCollector( 176 local_state_, 177 chromeos::system::StatisticsProvider::GetInstance(), 178 NULL)); 179 device_cloud_policy_manager_->Connect( 180 local_state_, 181 device_management_service_.get(), 182 status_provider.Pass()); 183 } 184 185 CommandLine* command_line = CommandLine::ForCurrentProcess(); 186 if (!command_line->HasSwitch(chromeos::switches::kDisableLocalAccounts)) { 187 device_local_account_policy_service_.reset( 188 new DeviceLocalAccountPolicyService( 189 chromeos::DBusThreadManager::Get()->GetSessionManagerClient(), 190 chromeos::DeviceSettingsService::Get(), 191 chromeos::CrosSettings::Get())); 192 device_local_account_policy_service_->Connect( 193 device_management_service_.get()); 194 } 195 196 GetAppPackUpdater(); 197 198 SetTimezoneIfPolicyAvailable(); 199 #endif 200 201 policy_statistics_collector_.reset( 202 new policy::PolicyStatisticsCollector( 203 GetPolicyService(), 204 local_state_, 205 base::MessageLoop::current()->message_loop_proxy())); 206 policy_statistics_collector_->Initialize(); 207 208 #if defined(OS_CHROMEOS) 209 210 network_configuration_updater_.reset(new NetworkConfigurationUpdaterImpl( 211 GetPolicyService(), 212 scoped_ptr<chromeos::onc::CertificateImporter>( 213 new chromeos::onc::CertificateImporterImpl))); 214 #endif 215 216 is_initialized_ = true; 217 } 218 219 void BrowserPolicyConnector::Shutdown() { 220 is_initialized_ = false; 221 222 if (g_testing_provider) 223 g_testing_provider->Shutdown(); 224 // Drop g_testing_provider so that tests executed with --single_process can 225 // call SetPolicyProviderForTesting() again. It is still owned by the test. 226 g_testing_provider = NULL; 227 if (platform_provider_) 228 platform_provider_->Shutdown(); 229 230 #if defined(OS_CHROMEOS) 231 // The AppPackUpdater may be observing the |device_cloud_policy_subsystem_|. 232 // Delete it first. 233 app_pack_updater_.reset(); 234 235 network_configuration_updater_.reset(); 236 237 if (device_cloud_policy_manager_) 238 device_cloud_policy_manager_->Shutdown(); 239 if (device_local_account_policy_service_) 240 device_local_account_policy_service_->Disconnect(); 241 global_user_cloud_policy_provider_.Shutdown(); 242 #endif 243 244 device_management_service_.reset(); 245 246 request_context_ = NULL; 247 } 248 249 PolicyService* BrowserPolicyConnector::GetPolicyService() { 250 if (!policy_service_) { 251 std::vector<ConfigurationPolicyProvider*> providers; 252 #if defined(OS_CHROMEOS) 253 providers.push_back(&global_user_cloud_policy_provider_); 254 #endif 255 policy_service_ = CreatePolicyService(providers); 256 } 257 return policy_service_.get(); 258 } 259 260 #if defined(OS_CHROMEOS) 261 bool BrowserPolicyConnector::IsEnterpriseManaged() { 262 return install_attributes_ && install_attributes_->IsEnterpriseDevice(); 263 } 264 265 std::string BrowserPolicyConnector::GetEnterpriseDomain() { 266 return install_attributes_ ? install_attributes_->GetDomain() : std::string(); 267 } 268 269 DeviceMode BrowserPolicyConnector::GetDeviceMode() { 270 return install_attributes_ ? install_attributes_->GetMode() 271 : DEVICE_MODE_NOT_SET; 272 } 273 #endif 274 275 void BrowserPolicyConnector::ScheduleServiceInitialization( 276 int64 delay_milliseconds) { 277 // Skip device initialization if the BrowserPolicyConnector was never 278 // initialized (unit tests). 279 if (device_management_service_) 280 device_management_service_->ScheduleInitialization(delay_milliseconds); 281 } 282 283 scoped_ptr<PolicyService> BrowserPolicyConnector::CreatePolicyService( 284 const std::vector<ConfigurationPolicyProvider*>& additional_providers) { 285 std::vector<ConfigurationPolicyProvider*> providers; 286 if (g_testing_provider) { 287 providers.push_back(g_testing_provider); 288 } else { 289 // |providers| in decreasing order of priority. 290 if (platform_provider_) 291 providers.push_back(platform_provider_.get()); 292 #if defined(OS_CHROMEOS) 293 if (device_cloud_policy_manager_) 294 providers.push_back(device_cloud_policy_manager_.get()); 295 #endif 296 std::copy(additional_providers.begin(), additional_providers.end(), 297 std::back_inserter(providers)); 298 } 299 scoped_ptr<PolicyService> service(new PolicyServiceImpl(providers)); 300 scoped_refptr<PolicyDomainDescriptor> descriptor = new PolicyDomainDescriptor( 301 POLICY_DOMAIN_CHROME); 302 service->RegisterPolicyDomain(descriptor); 303 return service.Pass(); 304 } 305 306 const ConfigurationPolicyHandlerList* 307 BrowserPolicyConnector::GetHandlerList() const { 308 return &handler_list_; 309 } 310 311 UserAffiliation BrowserPolicyConnector::GetUserAffiliation( 312 const std::string& user_name) { 313 #if defined(OS_CHROMEOS) 314 // An empty username means incognito user in case of ChromiumOS and 315 // no logged-in user in case of Chromium (SigninService). Many tests use 316 // nonsense email addresses (e.g. 'test') so treat those as non-enterprise 317 // users. 318 if (user_name.empty() || user_name.find('@') == std::string::npos) 319 return USER_AFFILIATION_NONE; 320 if (install_attributes_ && 321 (gaia::ExtractDomainName(gaia::CanonicalizeEmail(user_name)) == 322 install_attributes_->GetDomain() || 323 policy::IsDeviceLocalAccountUser(user_name))) { 324 return USER_AFFILIATION_MANAGED; 325 } 326 #endif 327 328 return USER_AFFILIATION_NONE; 329 } 330 331 #if defined(OS_CHROMEOS) 332 AppPackUpdater* BrowserPolicyConnector::GetAppPackUpdater() { 333 // request_context_ is NULL in unit tests. 334 if (!app_pack_updater_ && request_context_.get()) { 335 app_pack_updater_.reset( 336 new AppPackUpdater(request_context_.get(), install_attributes_.get())); 337 } 338 return app_pack_updater_.get(); 339 } 340 341 net::CertTrustAnchorProvider* 342 BrowserPolicyConnector::GetCertTrustAnchorProvider() { 343 return network_configuration_updater()->GetCertTrustAnchorProvider(); 344 } 345 346 void BrowserPolicyConnector::SetUserPolicyDelegate( 347 ConfigurationPolicyProvider* user_policy_provider) { 348 global_user_cloud_policy_provider_.SetDelegate(user_policy_provider); 349 } 350 #endif 351 352 void BrowserPolicyConnector::SetDeviceManagementServiceForTesting( 353 scoped_ptr<DeviceManagementService> service) { 354 device_management_service_ = service.Pass(); 355 } 356 357 // static 358 void BrowserPolicyConnector::SetPolicyProviderForTesting( 359 ConfigurationPolicyProvider* provider) { 360 CHECK(!g_browser_process) << "Must be invoked before the browser is created"; 361 DCHECK(!g_testing_provider); 362 g_testing_provider = provider; 363 } 364 365 // static 366 std::string BrowserPolicyConnector::GetDeviceManagementUrl() { 367 CommandLine* command_line = CommandLine::ForCurrentProcess(); 368 if (command_line->HasSwitch(switches::kDeviceManagementUrl)) 369 return command_line->GetSwitchValueASCII(switches::kDeviceManagementUrl); 370 else 371 return kDefaultDeviceManagementServerUrl; 372 } 373 374 namespace { 375 376 // Returns true if |domain| matches the regex |pattern|. 377 bool MatchDomain(const string16& domain, const string16& pattern) { 378 UErrorCode status = U_ZERO_ERROR; 379 const icu::UnicodeString icu_pattern(pattern.data(), pattern.length()); 380 icu::RegexMatcher matcher(icu_pattern, UREGEX_CASE_INSENSITIVE, status); 381 DCHECK(U_SUCCESS(status)) << "Invalid domain pattern: " << pattern; 382 icu::UnicodeString icu_input(domain.data(), domain.length()); 383 matcher.reset(icu_input); 384 status = U_ZERO_ERROR; 385 UBool match = matcher.matches(status); 386 DCHECK(U_SUCCESS(status)); 387 return !!match; // !! == convert from UBool to bool 388 } 389 390 } // namespace 391 392 // static 393 bool BrowserPolicyConnector::IsNonEnterpriseUser(const std::string& username) { 394 if (username.empty() || username.find('@') == std::string::npos) { 395 // An empty username means incognito user in case of ChromiumOS and 396 // no logged-in user in case of Chromium (SigninService). Many tests use 397 // nonsense email addresses (e.g. 'test') so treat those as non-enterprise 398 // users. 399 return true; 400 } 401 402 // Exclude many of the larger public email providers as we know these users 403 // are not from hosted enterprise domains. 404 static const wchar_t* kNonManagedDomainPatterns[] = { 405 L"aol\\.com", 406 L"googlemail\\.com", 407 L"gmail\\.com", 408 L"hotmail(\\.co|\\.com|)\\.[^.]+", // hotmail.com, hotmail.it, hotmail.co.uk 409 L"live\\.com", 410 L"mail\\.ru", 411 L"msn\\.com", 412 L"qq\\.com", 413 L"yahoo(\\.co|\\.com|)\\.[^.]+", // yahoo.com, yahoo.co.uk, yahoo.com.tw 414 L"yandex\\.ru", 415 }; 416 const string16 domain = 417 UTF8ToUTF16(gaia::ExtractDomainName(gaia::CanonicalizeEmail(username))); 418 for (size_t i = 0; i < arraysize(kNonManagedDomainPatterns); i++) { 419 string16 pattern = WideToUTF16(kNonManagedDomainPatterns[i]); 420 if (MatchDomain(domain, pattern)) 421 return true; 422 } 423 return false; 424 } 425 426 // static 427 void BrowserPolicyConnector::RegisterPrefs(PrefRegistrySimple* registry) { 428 registry->RegisterIntegerPref( 429 prefs::kUserPolicyRefreshRate, 430 CloudPolicyRefreshScheduler::kDefaultRefreshDelayMs); 431 #if defined(OS_CHROMEOS) 432 registry->RegisterIntegerPref( 433 prefs::kDevicePolicyRefreshRate, 434 CloudPolicyRefreshScheduler::kDefaultRefreshDelayMs); 435 #endif 436 } 437 438 void BrowserPolicyConnector::SetTimezoneIfPolicyAvailable() { 439 #if defined(OS_CHROMEOS) 440 typedef chromeos::CrosSettingsProvider Provider; 441 Provider::TrustedStatus result = 442 chromeos::CrosSettings::Get()->PrepareTrustedValues( 443 base::Bind(&BrowserPolicyConnector::SetTimezoneIfPolicyAvailable, 444 weak_ptr_factory_.GetWeakPtr())); 445 446 if (result != Provider::TRUSTED) 447 return; 448 449 std::string timezone; 450 if (chromeos::CrosSettings::Get()->GetString(chromeos::kSystemTimezonePolicy, 451 &timezone) && 452 !timezone.empty()) { 453 chromeos::system::TimezoneSettings::GetInstance()->SetTimezoneFromID( 454 UTF8ToUTF16(timezone)); 455 } 456 #endif 457 } 458 459 // static 460 ConfigurationPolicyProvider* BrowserPolicyConnector::CreatePlatformProvider() { 461 #if defined(OS_WIN) 462 const PolicyDefinitionList* policy_list = GetChromePolicyDefinitionList(); 463 scoped_ptr<AsyncPolicyLoader> loader(PolicyLoaderWin::Create(policy_list)); 464 return new AsyncPolicyProvider(loader.Pass()); 465 #elif defined(OS_MACOSX) 466 const PolicyDefinitionList* policy_list = GetChromePolicyDefinitionList(); 467 scoped_ptr<AsyncPolicyLoader> loader( 468 new PolicyLoaderMac(policy_list, new MacPreferences())); 469 return new AsyncPolicyProvider(loader.Pass()); 470 #elif defined(OS_POSIX) && !defined(OS_ANDROID) 471 base::FilePath config_dir_path; 472 if (PathService::Get(chrome::DIR_POLICY_FILES, &config_dir_path)) { 473 scoped_ptr<AsyncPolicyLoader> loader( 474 new ConfigDirPolicyLoader(config_dir_path, POLICY_SCOPE_MACHINE)); 475 return new AsyncPolicyProvider(loader.Pass()); 476 } else { 477 return NULL; 478 } 479 #else 480 return NULL; 481 #endif 482 } 483 484 } // namespace policy 485