blob: efbfea0613fae6bfa99703fe30c3c265a18f1209 [file] [log] [blame]
lukaszac285c9a2015-01-29 23:18:281// Copyright 2015 The Chromium Authors. All rights reserved.
[email protected]000d1f62012-07-24 01:56:542// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Most of this code is copied from:
6// src/chrome/browser/policy/asynchronous_policy_loader.{h,cc}
7
lukaszac285c9a2015-01-29 23:18:288#include "remoting/host/policy_watcher.h"
[email protected]000d1f62012-07-24 01:56:549
sergeyu1417e0132015-12-23 19:01:2210#include <utility>
11
[email protected]000d1f62012-07-24 01:56:5412#include "base/bind.h"
13#include "base/compiler_specific.h"
lukaszaa9376cd2015-01-28 20:29:0114#include "base/files/file_path.h"
[email protected]000d1f62012-07-24 01:56:5415#include "base/location.h"
dcheng0765c492016-04-06 22:41:5316#include "base/memory/ptr_util.h"
[email protected]000d1f62012-07-24 01:56:5417#include "base/single_thread_task_runner.h"
[email protected]000d1f62012-07-24 01:56:5418#include "base/values.h"
avic5960f32015-12-22 22:49:4819#include "build/build_config.h"
lukaszaa9376cd2015-01-28 20:29:0120#include "components/policy/core/common/async_policy_loader.h"
21#include "components/policy/core/common/async_policy_provider.h"
22#include "components/policy/core/common/policy_namespace.h"
23#include "components/policy/core/common/policy_service_impl.h"
24#include "components/policy/core/common/schema.h"
25#include "components/policy/core/common/schema_registry.h"
brettw39d6ba42016-08-24 16:56:3826#include "components/policy/policy_constants.h"
lukasza0d40d8a2015-03-03 18:36:2827#include "remoting/host/third_party_auth_config.h"
28#include "remoting/protocol/port_range.h"
[email protected]000d1f62012-07-24 01:56:5429
[email protected]158b2872012-11-13 10:08:3830#if !defined(NDEBUG)
31#include "base/json/json_reader.h"
32#endif
33
sergeyub2ae7e32015-01-30 23:33:2534#if defined(OS_WIN)
lukaszaa9376cd2015-01-28 20:29:0135#include "components/policy/core/common/policy_loader_win.h"
36#elif defined(OS_MACOSX)
37#include "components/policy/core/common/policy_loader_mac.h"
38#include "components/policy/core/common/preferences_mac.h"
39#elif defined(OS_POSIX) && !defined(OS_ANDROID)
40#include "components/policy/core/common/config_dir_policy_loader.h"
41#endif
42
[email protected]000d1f62012-07-24 01:56:5443namespace remoting {
[email protected]000d1f62012-07-24 01:56:5444
lukaszaa9376cd2015-01-28 20:29:0145namespace key = ::policy::key;
46
[email protected]000d1f62012-07-24 01:56:5447namespace {
[email protected]bf931a42012-11-10 19:07:0248
[email protected]bf931a42012-11-10 19:07:0249// Copies all policy values from one dictionary to another, using values from
lukaszae5d69ea2015-02-23 21:00:3150// |default_values| if they are not set in |from|.
dcheng0765c492016-04-06 22:41:5351std::unique_ptr<base::DictionaryValue> CopyValuesAndAddDefaults(
lukasza0d40d8a2015-03-03 18:36:2852 const base::DictionaryValue& from,
53 const base::DictionaryValue& default_values) {
dchengefaf1b112016-05-03 01:12:4954 std::unique_ptr<base::DictionaryValue> to(default_values.CreateDeepCopy());
lukasza0d40d8a2015-03-03 18:36:2855 for (base::DictionaryValue::Iterator i(default_values); !i.IsAtEnd();
lukaszac285c9a2015-01-29 23:18:2856 i.Advance()) {
sergeyuc5f104b2015-01-09 19:33:2457 const base::Value* value = nullptr;
[email protected]bf931a42012-11-10 19:07:0258
59 // If the policy isn't in |from|, use the default.
lukasza0d40d8a2015-03-03 18:36:2860 if (!from.Get(i.key(), &value)) {
[email protected]bf931a42012-11-10 19:07:0261 continue;
62 }
63
jdoerriee48b26a2017-12-09 14:19:0864 CHECK(value->type() == i.value().type());
dchengefaf1b112016-05-03 01:12:4965 to->Set(i.key(), value->CreateDeepCopy());
[email protected]b9612a52012-07-28 02:17:4866 }
[email protected]50409b32012-07-31 18:54:0267
sergeyu1417e0132015-12-23 19:01:2268 return to;
[email protected]000d1f62012-07-24 01:56:5469}
70
lukaszaa9376cd2015-01-28 20:29:0171policy::PolicyNamespace GetPolicyNamespace() {
72 return policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string());
73}
74
dcheng0765c492016-04-06 22:41:5375std::unique_ptr<policy::SchemaRegistry> CreateSchemaRegistry() {
lukaszae5d69ea2015-02-23 21:00:3176 // TODO(lukasza): Schema below should ideally only cover Chromoting-specific
77 // policies (expecting perf and maintanability improvement, but no functional
78 // impact).
79 policy::Schema schema = policy::Schema::Wrap(policy::GetChromeSchemaData());
80
dcheng0765c492016-04-06 22:41:5381 std::unique_ptr<policy::SchemaRegistry> schema_registry(
lukaszae5d69ea2015-02-23 21:00:3182 new policy::SchemaRegistry());
83 schema_registry->RegisterComponent(GetPolicyNamespace(), schema);
sergeyu1417e0132015-12-23 19:01:2284 return schema_registry;
lukaszae5d69ea2015-02-23 21:00:3185}
86
dcheng0765c492016-04-06 22:41:5387std::unique_ptr<base::DictionaryValue> CopyChromotingPoliciesIntoDictionary(
lukasza0d40d8a2015-03-03 18:36:2888 const policy::PolicyMap& current) {
89 const char kPolicyNameSubstring[] = "RemoteAccessHost";
dcheng0765c492016-04-06 22:41:5390 std::unique_ptr<base::DictionaryValue> policy_dict(
91 new base::DictionaryValue());
dcheng3b344bc22016-05-10 02:26:0992 for (const auto& entry : current) {
93 const std::string& key = entry.first;
94 const base::Value* value = entry.second.value.get();
lukasza0d40d8a2015-03-03 18:36:2895
96 // Copying only Chromoting-specific policies helps avoid false alarms
97 // raised by NormalizePolicies below (such alarms shutdown the host).
98 // TODO(lukasza): Removing this somewhat brittle filtering will be possible
99 // after having separate, Chromoting-specific schema.
100 if (key.find(kPolicyNameSubstring) != std::string::npos) {
dchengefaf1b112016-05-03 01:12:49101 policy_dict->Set(key, value->CreateDeepCopy());
lukasza0d40d8a2015-03-03 18:36:28102 }
103 }
104
sergeyu1417e0132015-12-23 19:01:22105 return policy_dict;
lukasza0d40d8a2015-03-03 18:36:28106}
107
108// Takes a dictionary containing only 1) recognized policy names and 2)
109// well-typed policy values and further verifies policy contents.
110bool VerifyWellformedness(const base::DictionaryValue& changed_policies) {
111 // Verify ThirdPartyAuthConfig policy.
112 ThirdPartyAuthConfig not_used;
113 switch (ThirdPartyAuthConfig::Parse(changed_policies, &not_used)) {
114 case ThirdPartyAuthConfig::NoPolicy:
115 case ThirdPartyAuthConfig::ParsingSuccess:
116 break; // Well-formed.
117 case ThirdPartyAuthConfig::InvalidPolicy:
118 return false; // Malformed.
119 default:
120 NOTREACHED();
121 return false;
122 }
123
124 // Verify UdpPortRange policy.
125 std::string udp_port_range_string;
126 PortRange udp_port_range;
127 if (changed_policies.GetString(policy::key::kRemoteAccessHostUdpPortRange,
128 &udp_port_range_string)) {
129 if (!PortRange::Parse(udp_port_range_string, &udp_port_range)) {
130 return false;
131 }
132 }
133
134 // Report that all the policies were well-formed.
135 return true;
136}
137
[email protected]000d1f62012-07-24 01:56:54138} // namespace
139
lukasza0fdd9512014-11-25 17:47:46140void PolicyWatcher::StartWatching(
141 const PolicyUpdatedCallback& policy_updated_callback,
142 const PolicyErrorCallback& policy_error_callback) {
gabbf77513a2017-06-01 14:35:34143 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
sergeyub2ae7e32015-01-30 23:33:25144 DCHECK(!policy_updated_callback.is_null());
145 DCHECK(!policy_error_callback.is_null());
146 DCHECK(policy_updated_callback_.is_null());
[email protected]000d1f62012-07-24 01:56:54147
lukasza0fdd9512014-11-25 17:47:46148 policy_updated_callback_ = policy_updated_callback;
149 policy_error_callback_ = policy_error_callback;
lukaszaa9376cd2015-01-28 20:29:01150
151 // Listen for future policy changes.
152 policy_service_->AddObserver(policy::POLICY_DOMAIN_CHROME, this);
153
154 // Process current policy state.
155 if (policy_service_->IsInitializationComplete(policy::POLICY_DOMAIN_CHROME)) {
156 OnPolicyServiceInitialized(policy::POLICY_DOMAIN_CHROME);
157 }
[email protected]000d1f62012-07-24 01:56:54158}
159
jamiewalchcf2cc682017-05-06 00:51:47160std::unique_ptr<base::DictionaryValue> PolicyWatcher::GetCurrentPolicies() {
jamiewalchc96bfee2017-05-11 17:10:59161 return old_policies_->CreateDeepCopy();
jamiewalchcf2cc682017-05-06 00:51:47162}
163
164std::unique_ptr<base::DictionaryValue> PolicyWatcher::GetDefaultPolicies() {
Jinho Bang138fde32018-01-18 23:13:42165 auto result = std::make_unique<base::DictionaryValue>();
jamiewalchcf2cc682017-05-06 00:51:47166 result->SetBoolean(key::kRemoteAccessHostFirewallTraversal, true);
167 result->SetBoolean(key::kRemoteAccessHostRequireCurtain, false);
168 result->SetBoolean(key::kRemoteAccessHostMatchUsername, false);
169 result->Set(key::kRemoteAccessHostClientDomainList,
Jinho Bang138fde32018-01-18 23:13:42170 std::make_unique<base::ListValue>());
jamiewalchcf2cc682017-05-06 00:51:47171 result->Set(key::kRemoteAccessHostDomainList,
Jinho Bang138fde32018-01-18 23:13:42172 std::make_unique<base::ListValue>());
Yuwei Huang6073c062019-07-15 21:15:40173 // TODO(yuweih): kRemoteAccessHostTalkGadgetPrefix is not used any more. Clean
174 // this up.
175 result->SetString(key::kRemoteAccessHostTalkGadgetPrefix, std::string());
jamiewalchcf2cc682017-05-06 00:51:47176 result->SetString(key::kRemoteAccessHostTokenUrl, std::string());
177 result->SetString(key::kRemoteAccessHostTokenValidationUrl, std::string());
178 result->SetString(key::kRemoteAccessHostTokenValidationCertificateIssuer,
179 std::string());
180 result->SetBoolean(key::kRemoteAccessHostAllowClientPairing, true);
181 result->SetBoolean(key::kRemoteAccessHostAllowGnubbyAuth, true);
182 result->SetBoolean(key::kRemoteAccessHostAllowRelayedConnection, true);
183 result->SetString(key::kRemoteAccessHostUdpPortRange, "");
184 result->SetBoolean(key::kRemoteAccessHostAllowUiAccessForRemoteAssistance,
185 false);
Erik Jensenc87cc702019-03-06 20:48:06186#if !defined(OS_CHROMEOS)
187 result->SetBoolean(key::kRemoteAccessHostAllowFileTransfer, true);
188#endif
jamiewalchcf2cc682017-05-06 00:51:47189 return result;
190}
191
lukasza0fdd9512014-11-25 17:47:46192void PolicyWatcher::SignalPolicyError() {
lukaszafecb18b2015-02-24 01:04:12193 old_policies_->Clear();
lukasza0fdd9512014-11-25 17:47:46194 policy_error_callback_.Run();
195}
196
lukaszaa9376cd2015-01-28 20:29:01197PolicyWatcher::PolicyWatcher(
lukaszaa9376cd2015-01-28 20:29:01198 policy::PolicyService* policy_service,
dcheng0765c492016-04-06 22:41:53199 std::unique_ptr<policy::PolicyService> owned_policy_service,
200 std::unique_ptr<policy::ConfigurationPolicyProvider> owned_policy_provider,
201 std::unique_ptr<policy::SchemaRegistry> owned_schema_registry)
lukaszae5d69ea2015-02-23 21:00:31202 : old_policies_(new base::DictionaryValue()),
jamiewalchcf2cc682017-05-06 00:51:47203 default_values_(GetDefaultPolicies()),
lukaszaa9376cd2015-01-28 20:29:01204 policy_service_(policy_service),
sergeyu1417e0132015-12-23 19:01:22205 owned_schema_registry_(std::move(owned_schema_registry)),
206 owned_policy_provider_(std::move(owned_policy_provider)),
207 owned_policy_service_(std::move(owned_policy_service)) {
lukaszae5d69ea2015-02-23 21:00:31208 DCHECK(policy_service_);
209 DCHECK(owned_schema_registry_);
lukaszaa9376cd2015-01-28 20:29:01210}
211
212PolicyWatcher::~PolicyWatcher() {
gabbf77513a2017-06-01 14:35:34213 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
sergeyub2ae7e32015-01-30 23:33:25214 // Stop observing |policy_service_| if StartWatching() has been called.
215 if (!policy_updated_callback_.is_null()) {
216 policy_service_->RemoveObserver(policy::POLICY_DOMAIN_CHROME, this);
217 }
218
lukaszaa9376cd2015-01-28 20:29:01219 if (owned_policy_provider_) {
220 owned_policy_provider_->Shutdown();
221 }
222}
223
lukaszae5d69ea2015-02-23 21:00:31224const policy::Schema* PolicyWatcher::GetPolicySchema() const {
225 return owned_schema_registry_->schema_map()->GetSchema(GetPolicyNamespace());
226}
227
lukasza0d40d8a2015-03-03 18:36:28228bool PolicyWatcher::NormalizePolicies(base::DictionaryValue* policy_dict) {
lukaszae5d69ea2015-02-23 21:00:31229 // Allowing unrecognized policy names allows presence of
230 // 1) comments (i.e. JSON of the form: { "_comment": "blah", ... }),
231 // 2) policies intended for future/newer versions of the host,
232 // 3) policies not supported on all OS-s (i.e. RemoteAccessHostMatchUsername
233 // is not supported on Windows and therefore policy_templates.json omits
234 // schema for this policy on this particular platform).
Sergey Poromov6aebfcf82019-10-07 19:55:21235 auto strategy = policy::SCHEMA_ALLOW_UNKNOWN;
lukaszae5d69ea2015-02-23 21:00:31236
237 std::string path;
238 std::string error;
lukasza1ffc24b2015-02-23 23:28:03239 bool changed = false;
lukaszae5d69ea2015-02-23 21:00:31240 const policy::Schema* schema = GetPolicySchema();
lukasza0d40d8a2015-03-03 18:36:28241 if (schema->Normalize(policy_dict, strategy, &path, &error, &changed)) {
lukaszae5d69ea2015-02-23 21:00:31242 if (changed) {
243 LOG(WARNING) << "Unknown (unrecognized or unsupported) policy: " << path
244 << ": " << error;
245 }
rkjnsn10cd2682017-04-28 22:04:01246 HandleDeprecatedPolicies(policy_dict);
lukasza0d40d8a2015-03-03 18:36:28247 return true;
lukaszae5d69ea2015-02-23 21:00:31248 } else {
249 LOG(ERROR) << "Invalid policy contents: " << path << ": " << error;
lukasza0d40d8a2015-03-03 18:36:28250 return false;
lukaszae5d69ea2015-02-23 21:00:31251 }
lukaszaa9376cd2015-01-28 20:29:01252}
253
rkjnsn10cd2682017-04-28 22:04:01254void PolicyWatcher::HandleDeprecatedPolicies(base::DictionaryValue* dict) {
255 // RemoteAccessHostDomain
256 if (dict->HasKey(policy::key::kRemoteAccessHostDomain)) {
257 if (!dict->HasKey(policy::key::kRemoteAccessHostDomainList)) {
258 std::string domain;
259 dict->GetString(policy::key::kRemoteAccessHostDomain, &domain);
260 if (!domain.empty()) {
Jinho Bang138fde32018-01-18 23:13:42261 auto list = std::make_unique<base::ListValue>();
rkjnsn10cd2682017-04-28 22:04:01262 list->AppendString(domain);
263 dict->Set(policy::key::kRemoteAccessHostDomainList, std::move(list));
264 }
265 }
266 dict->Remove(policy::key::kRemoteAccessHostDomain, nullptr);
267 }
268
269 // RemoteAccessHostClientDomain
270 if (dict->HasKey(policy::key::kRemoteAccessHostClientDomain)) {
271 if (!dict->HasKey(policy::key::kRemoteAccessHostClientDomainList)) {
272 std::string domain;
273 dict->GetString(policy::key::kRemoteAccessHostClientDomain, &domain);
274 if (!domain.empty()) {
Jinho Bang138fde32018-01-18 23:13:42275 auto list = std::make_unique<base::ListValue>();
rkjnsn10cd2682017-04-28 22:04:01276 list->AppendString(domain);
277 dict->Set(policy::key::kRemoteAccessHostClientDomainList,
278 std::move(list));
279 }
280 }
281 dict->Remove(policy::key::kRemoteAccessHostClientDomain, nullptr);
282 }
283}
284
lukasza0d40d8a2015-03-03 18:36:28285namespace {
286void CopyDictionaryValue(const base::DictionaryValue& from,
287 base::DictionaryValue& to,
288 std::string key) {
289 const base::Value* value;
290 if (from.Get(key, &value)) {
dchengefaf1b112016-05-03 01:12:49291 to.Set(key, value->CreateDeepCopy());
lukasza0d40d8a2015-03-03 18:36:28292 }
293}
294} // namespace
295
dcheng0765c492016-04-06 22:41:53296std::unique_ptr<base::DictionaryValue>
lukasza0d40d8a2015-03-03 18:36:28297PolicyWatcher::StoreNewAndReturnChangedPolicies(
dcheng0765c492016-04-06 22:41:53298 std::unique_ptr<base::DictionaryValue> new_policies) {
lukasza0d40d8a2015-03-03 18:36:28299 // Find the changed policies.
dcheng0765c492016-04-06 22:41:53300 std::unique_ptr<base::DictionaryValue> changed_policies(
lukasza0d40d8a2015-03-03 18:36:28301 new base::DictionaryValue());
302 base::DictionaryValue::Iterator iter(*new_policies);
303 while (!iter.IsAtEnd()) {
304 base::Value* old_policy;
305 if (!(old_policies_->Get(iter.key(), &old_policy) &&
306 old_policy->Equals(&iter.value()))) {
dchengefaf1b112016-05-03 01:12:49307 changed_policies->Set(iter.key(), iter.value().CreateDeepCopy());
lukasza0d40d8a2015-03-03 18:36:28308 }
309 iter.Advance();
310 }
311
312 // If one of ThirdPartyAuthConfig policies changed, we need to include all.
313 if (changed_policies->HasKey(key::kRemoteAccessHostTokenUrl) ||
314 changed_policies->HasKey(key::kRemoteAccessHostTokenValidationUrl) ||
315 changed_policies->HasKey(
316 key::kRemoteAccessHostTokenValidationCertificateIssuer)) {
317 CopyDictionaryValue(*new_policies, *changed_policies,
318 key::kRemoteAccessHostTokenUrl);
319 CopyDictionaryValue(*new_policies, *changed_policies,
320 key::kRemoteAccessHostTokenValidationUrl);
321 CopyDictionaryValue(*new_policies, *changed_policies,
322 key::kRemoteAccessHostTokenValidationCertificateIssuer);
323 }
324
325 // Save the new policies.
326 old_policies_.swap(new_policies);
327
sergeyu1417e0132015-12-23 19:01:22328 return changed_policies;
lukasza0d40d8a2015-03-03 18:36:28329}
330
331void PolicyWatcher::OnPolicyUpdated(const policy::PolicyNamespace& ns,
332 const policy::PolicyMap& previous,
333 const policy::PolicyMap& current) {
dcheng0765c492016-04-06 22:41:53334 std::unique_ptr<base::DictionaryValue> new_policies =
lukasza0d40d8a2015-03-03 18:36:28335 CopyChromotingPoliciesIntoDictionary(current);
336
337 // Check for mistyped values and get rid of unknown policies.
338 if (!NormalizePolicies(new_policies.get())) {
339 SignalPolicyError();
340 return;
341 }
342
343 // Use default values for any missing policies.
dcheng0765c492016-04-06 22:41:53344 std::unique_ptr<base::DictionaryValue> filled_policies =
lukasza0d40d8a2015-03-03 18:36:28345 CopyValuesAndAddDefaults(*new_policies, *default_values_);
346
347 // Limit reporting to only the policies that were changed.
dcheng0765c492016-04-06 22:41:53348 std::unique_ptr<base::DictionaryValue> changed_policies =
sergeyu1417e0132015-12-23 19:01:22349 StoreNewAndReturnChangedPolicies(std::move(filled_policies));
lukasza0d40d8a2015-03-03 18:36:28350 if (changed_policies->empty()) {
351 return;
352 }
353
354 // Verify that we are calling the callback with valid policies.
355 if (!VerifyWellformedness(*changed_policies)) {
356 SignalPolicyError();
357 return;
358 }
359
360 // Notify our client of the changed policies.
sergeyu1417e0132015-12-23 19:01:22361 policy_updated_callback_.Run(std::move(changed_policies));
lukasza0d40d8a2015-03-03 18:36:28362}
363
lukaszaa9376cd2015-01-28 20:29:01364void PolicyWatcher::OnPolicyServiceInitialized(policy::PolicyDomain domain) {
365 policy::PolicyNamespace ns = GetPolicyNamespace();
366 const policy::PolicyMap& current = policy_service_->GetPolicies(ns);
367 OnPolicyUpdated(ns, current, current);
368}
369
dcheng0765c492016-04-06 22:41:53370std::unique_ptr<PolicyWatcher> PolicyWatcher::CreateFromPolicyLoader(
371 std::unique_ptr<policy::AsyncPolicyLoader> async_policy_loader) {
372 std::unique_ptr<policy::SchemaRegistry> schema_registry =
373 CreateSchemaRegistry();
374 std::unique_ptr<policy::AsyncPolicyProvider> policy_provider(
lukaszaa9376cd2015-01-28 20:29:01375 new policy::AsyncPolicyProvider(schema_registry.get(),
sergeyu1417e0132015-12-23 19:01:22376 std::move(async_policy_loader)));
lukaszaa9376cd2015-01-28 20:29:01377 policy_provider->Init(schema_registry.get());
378
379 policy::PolicyServiceImpl::Providers providers;
380 providers.push_back(policy_provider.get());
Scott Violet61450302018-01-18 18:33:28381 std::unique_ptr<policy::PolicyServiceImpl> policy_service =
Scott Violet76da73a2018-01-31 00:58:18382 std::make_unique<policy::PolicyServiceImpl>(std::move(providers));
lukaszaa9376cd2015-01-28 20:29:01383
384 policy::PolicyService* borrowed_policy_service = policy_service.get();
dcheng0765c492016-04-06 22:41:53385 return base::WrapUnique(new PolicyWatcher(
sergeyu1417e0132015-12-23 19:01:22386 borrowed_policy_service, std::move(policy_service),
387 std::move(policy_provider), std::move(schema_registry)));
lukaszaa9376cd2015-01-28 20:29:01388}
389
Joe Downing734d0152017-07-18 02:56:16390std::unique_ptr<PolicyWatcher> PolicyWatcher::CreateWithPolicyService(
391 policy::PolicyService* policy_service) {
lukaszaa9376cd2015-01-28 20:29:01392 DCHECK(policy_service);
dcheng0765c492016-04-06 22:41:53393 return base::WrapUnique(new PolicyWatcher(policy_service, nullptr, nullptr,
394 CreateSchemaRegistry()));
Joe Downing734d0152017-07-18 02:56:16395}
sergeyub2ae7e32015-01-30 23:33:25396
Joe Downing734d0152017-07-18 02:56:16397std::unique_ptr<PolicyWatcher> PolicyWatcher::CreateWithTaskRunner(
398 const scoped_refptr<base::SingleThreadTaskRunner>& file_task_runner) {
sergeyub2ae7e32015-01-30 23:33:25399 // Create platform-specific PolicyLoader. Always read the Chrome policies
400 // (even on Chromium) so that policy enforcement can't be bypassed by running
401 // Chromium.
dcheng0765c492016-04-06 22:41:53402 std::unique_ptr<policy::AsyncPolicyLoader> policy_loader;
sergeyub2ae7e32015-01-30 23:33:25403#if defined(OS_WIN)
lukaszabccb49e2015-02-24 20:10:28404 policy_loader.reset(new policy::PolicyLoaderWin(
Julian Pastarmov0acd1622017-11-08 11:06:15405 file_task_runner, L"SOFTWARE\\Policies\\Google\\Chrome"));
lukaszaa9376cd2015-01-28 20:29:01406#elif defined(OS_MACOSX)
407 CFStringRef bundle_id = CFSTR("com.google.Chrome");
sergeyub2ae7e32015-01-30 23:33:25408 policy_loader.reset(new policy::PolicyLoaderMac(
409 file_task_runner,
410 policy::PolicyLoaderMac::GetManagedPolicyPath(bundle_id),
411 new MacPreferences(), bundle_id));
lukaszaa9376cd2015-01-28 20:29:01412#elif defined(OS_POSIX) && !defined(OS_ANDROID)
sergeyub2ae7e32015-01-30 23:33:25413 policy_loader.reset(new policy::ConfigDirPolicyLoader(
414 file_task_runner,
415 base::FilePath(FILE_PATH_LITERAL("/etc/opt/chrome/policies")),
416 policy::POLICY_SCOPE_MACHINE));
lambroslambrou51e19b92016-04-13 21:30:41417#elif defined(OS_ANDROID)
418 NOTIMPLEMENTED();
lambroslambrou709327e2016-04-26 19:07:34419 policy::PolicyServiceImpl::Providers providers;
420 std::unique_ptr<policy::PolicyService> owned_policy_service(
421 new policy::PolicyServiceImpl(providers));
422 return base::WrapUnique(new PolicyWatcher(
423 owned_policy_service.get(), std::move(owned_policy_service), nullptr,
424 CreateSchemaRegistry()));
Joe Downing734d0152017-07-18 02:56:16425#elif defined(OS_CHROMEOS)
426 NOTREACHED() << "CreateWithPolicyService() should be used on ChromeOS.";
427 return nullptr;
lukaszaa9376cd2015-01-28 20:29:01428#else
429#error OS that is not yet supported by PolicyWatcher code.
430#endif
sergeyub2ae7e32015-01-30 23:33:25431
sergeyu1417e0132015-12-23 19:01:22432 return PolicyWatcher::CreateFromPolicyLoader(std::move(policy_loader));
lukaszaa9376cd2015-01-28 20:29:01433}
434
rkjnsnd0aa1e52017-03-30 00:17:28435std::unique_ptr<PolicyWatcher> PolicyWatcher::CreateFromPolicyLoaderForTesting(
436 std::unique_ptr<policy::AsyncPolicyLoader> async_policy_loader) {
437 return CreateFromPolicyLoader(std::move(async_policy_loader));
438}
439
[email protected]000d1f62012-07-24 01:56:54440} // namespace remoting