Update content setting for app banners to store more information.
[chromium-blink-merge.git] / remoting / host / policy_watcher.cc
blob8ef59a7558e47b638e77ecf2587a663a15b5a6e3
1 // Copyright 2015 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.
5 // Most of this code is copied from:
6 // src/chrome/browser/policy/asynchronous_policy_loader.{h,cc}
8 #include "remoting/host/policy_watcher.h"
10 #include "base/bind.h"
11 #include "base/compiler_specific.h"
12 #include "base/files/file_path.h"
13 #include "base/location.h"
14 #include "base/single_thread_task_runner.h"
15 #include "base/values.h"
16 #include "components/policy/core/common/async_policy_loader.h"
17 #include "components/policy/core/common/async_policy_provider.h"
18 #include "components/policy/core/common/policy_namespace.h"
19 #include "components/policy/core/common/policy_service_impl.h"
20 #include "components/policy/core/common/schema.h"
21 #include "components/policy/core/common/schema_registry.h"
22 #include "policy/policy_constants.h"
23 #include "remoting/host/dns_blackhole_checker.h"
25 #if !defined(NDEBUG)
26 #include "base/json/json_reader.h"
27 #endif
29 #if defined(OS_WIN)
30 #include "components/policy/core/common/policy_loader_win.h"
31 #elif defined(OS_MACOSX)
32 #include "components/policy/core/common/policy_loader_mac.h"
33 #include "components/policy/core/common/preferences_mac.h"
34 #elif defined(OS_POSIX) && !defined(OS_ANDROID)
35 #include "components/policy/core/common/config_dir_policy_loader.h"
36 #endif
38 namespace remoting {
40 namespace key = ::policy::key;
42 namespace {
44 // Copies all policy values from one dictionary to another, using values from
45 // |default| if they are not set in |from|, or values from |bad_type_values| if
46 // the value in |from| has the wrong type.
47 scoped_ptr<base::DictionaryValue> CopyGoodValuesAndAddDefaults(
48 const base::DictionaryValue* from,
49 const base::DictionaryValue* default_values,
50 const base::DictionaryValue* bad_type_values) {
51 scoped_ptr<base::DictionaryValue> to(default_values->DeepCopy());
52 for (base::DictionaryValue::Iterator i(*default_values); !i.IsAtEnd();
53 i.Advance()) {
54 const base::Value* value = nullptr;
56 // If the policy isn't in |from|, use the default.
57 if (!from->Get(i.key(), &value)) {
58 continue;
61 // If the policy is the wrong type, use the value from |bad_type_values|.
62 if (!value->IsType(i.value().GetType())) {
63 CHECK(bad_type_values->Get(i.key(), &value));
66 to->Set(i.key(), value->DeepCopy());
69 #if !defined(NDEBUG)
70 // Replace values with those specified in DebugOverridePolicies, if present.
71 std::string policy_overrides;
72 if (from->GetString(key::kRemoteAccessHostDebugOverridePolicies,
73 &policy_overrides)) {
74 scoped_ptr<base::Value> value(base::JSONReader::Read(policy_overrides));
75 const base::DictionaryValue* override_values;
76 if (value && value->GetAsDictionary(&override_values)) {
77 to->MergeDictionary(override_values);
80 #endif // defined(NDEBUG)
82 return to.Pass();
85 policy::PolicyNamespace GetPolicyNamespace() {
86 return policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string());
89 } // namespace
91 void PolicyWatcher::StartWatching(
92 const PolicyUpdatedCallback& policy_updated_callback,
93 const PolicyErrorCallback& policy_error_callback) {
94 DCHECK(CalledOnValidThread());
95 DCHECK(!policy_updated_callback.is_null());
96 DCHECK(!policy_error_callback.is_null());
97 DCHECK(policy_updated_callback_.is_null());
99 policy_updated_callback_ = policy_updated_callback;
100 policy_error_callback_ = policy_error_callback;
102 // Listen for future policy changes.
103 policy_service_->AddObserver(policy::POLICY_DOMAIN_CHROME, this);
105 // Process current policy state.
106 if (policy_service_->IsInitializationComplete(policy::POLICY_DOMAIN_CHROME)) {
107 OnPolicyServiceInitialized(policy::POLICY_DOMAIN_CHROME);
111 void PolicyWatcher::UpdatePolicies(
112 const base::DictionaryValue* new_policies_raw) {
113 DCHECK(CalledOnValidThread());
115 transient_policy_error_retry_counter_ = 0;
117 // Use default values for any missing policies.
118 scoped_ptr<base::DictionaryValue> new_policies = CopyGoodValuesAndAddDefaults(
119 new_policies_raw, default_values_.get(), bad_type_values_.get());
121 // Find the changed policies.
122 scoped_ptr<base::DictionaryValue> changed_policies(
123 new base::DictionaryValue());
124 base::DictionaryValue::Iterator iter(*new_policies);
125 while (!iter.IsAtEnd()) {
126 base::Value* old_policy;
127 if (!(old_policies_->Get(iter.key(), &old_policy) &&
128 old_policy->Equals(&iter.value()))) {
129 changed_policies->Set(iter.key(), iter.value().DeepCopy());
131 iter.Advance();
134 // Save the new policies.
135 old_policies_.swap(new_policies);
137 // Notify our client of the changed policies.
138 if (!changed_policies->empty()) {
139 policy_updated_callback_.Run(changed_policies.Pass());
143 void PolicyWatcher::SignalPolicyError() {
144 transient_policy_error_retry_counter_ = 0;
145 policy_error_callback_.Run();
148 void PolicyWatcher::SignalTransientPolicyError() {
149 const int kMaxRetryCount = 5;
150 transient_policy_error_retry_counter_ += 1;
151 if (transient_policy_error_retry_counter_ >= kMaxRetryCount) {
152 SignalPolicyError();
156 PolicyWatcher::PolicyWatcher(
157 policy::PolicyService* policy_service,
158 scoped_ptr<policy::PolicyService> owned_policy_service,
159 scoped_ptr<policy::ConfigurationPolicyProvider> owned_policy_provider,
160 scoped_ptr<policy::SchemaRegistry> owned_schema_registry)
161 : transient_policy_error_retry_counter_(0),
162 old_policies_(new base::DictionaryValue()),
163 default_values_(new base::DictionaryValue()),
164 policy_service_(policy_service),
165 owned_schema_registry_(owned_schema_registry.Pass()),
166 owned_policy_provider_(owned_policy_provider.Pass()),
167 owned_policy_service_(owned_policy_service.Pass()) {
168 // Initialize the default values for each policy.
169 default_values_->SetBoolean(key::kRemoteAccessHostFirewallTraversal, true);
170 default_values_->SetBoolean(key::kRemoteAccessHostRequireTwoFactor, false);
171 default_values_->SetBoolean(key::kRemoteAccessHostRequireCurtain, false);
172 default_values_->SetBoolean(key::kRemoteAccessHostMatchUsername, false);
173 default_values_->SetString(key::kRemoteAccessHostDomain, std::string());
174 default_values_->SetString(key::kRemoteAccessHostTalkGadgetPrefix,
175 kDefaultHostTalkGadgetPrefix);
176 default_values_->SetString(key::kRemoteAccessHostTokenUrl, std::string());
177 default_values_->SetString(key::kRemoteAccessHostTokenValidationUrl,
178 std::string());
179 default_values_->SetString(
180 key::kRemoteAccessHostTokenValidationCertificateIssuer, std::string());
181 default_values_->SetBoolean(key::kRemoteAccessHostAllowClientPairing, true);
182 default_values_->SetBoolean(key::kRemoteAccessHostAllowGnubbyAuth, true);
183 default_values_->SetBoolean(key::kRemoteAccessHostAllowRelayedConnection,
184 true);
185 default_values_->SetString(key::kRemoteAccessHostUdpPortRange, "");
186 #if !defined(NDEBUG)
187 default_values_->SetString(key::kRemoteAccessHostDebugOverridePolicies,
188 std::string());
189 #endif
191 // Initialize the fall-back values to use for unreadable policies.
192 // For most policies these match the defaults.
193 bad_type_values_.reset(default_values_->DeepCopy());
194 bad_type_values_->SetBoolean(key::kRemoteAccessHostFirewallTraversal, false);
195 bad_type_values_->SetBoolean(key::kRemoteAccessHostAllowRelayedConnection,
196 false);
199 PolicyWatcher::~PolicyWatcher() {
200 // Stop observing |policy_service_| if StartWatching() has been called.
201 if (!policy_updated_callback_.is_null()) {
202 policy_service_->RemoveObserver(policy::POLICY_DOMAIN_CHROME, this);
205 if (owned_policy_provider_) {
206 owned_policy_provider_->Shutdown();
210 void PolicyWatcher::OnPolicyUpdated(const policy::PolicyNamespace& ns,
211 const policy::PolicyMap& previous,
212 const policy::PolicyMap& current) {
213 scoped_ptr<base::DictionaryValue> policy_dict(new base::DictionaryValue());
214 for (auto it = current.begin(); it != current.end(); ++it) {
215 // TODO(lukasza): Use policy::Schema::Normalize() for schema verification.
216 policy_dict->Set(it->first, it->second.value->DeepCopy());
218 UpdatePolicies(policy_dict.get());
221 void PolicyWatcher::OnPolicyServiceInitialized(policy::PolicyDomain domain) {
222 policy::PolicyNamespace ns = GetPolicyNamespace();
223 const policy::PolicyMap& current = policy_service_->GetPolicies(ns);
224 OnPolicyUpdated(ns, current, current);
227 scoped_ptr<PolicyWatcher> PolicyWatcher::CreateFromPolicyLoader(
228 scoped_ptr<policy::AsyncPolicyLoader> async_policy_loader) {
229 // TODO(lukasza): Schema below should ideally only cover Chromoting-specific
230 // policies (expecting perf and maintanability improvement, but no functional
231 // impact).
232 policy::Schema schema = policy::Schema::Wrap(policy::GetChromeSchemaData());
234 scoped_ptr<policy::SchemaRegistry> schema_registry(
235 new policy::SchemaRegistry());
236 schema_registry->RegisterComponent(GetPolicyNamespace(), schema);
238 scoped_ptr<policy::AsyncPolicyProvider> policy_provider(
239 new policy::AsyncPolicyProvider(schema_registry.get(),
240 async_policy_loader.Pass()));
241 policy_provider->Init(schema_registry.get());
243 policy::PolicyServiceImpl::Providers providers;
244 providers.push_back(policy_provider.get());
245 scoped_ptr<policy::PolicyService> policy_service(
246 new policy::PolicyServiceImpl(providers));
248 policy::PolicyService* borrowed_policy_service = policy_service.get();
249 return make_scoped_ptr(
250 new PolicyWatcher(borrowed_policy_service, policy_service.Pass(),
251 policy_provider.Pass(), schema_registry.Pass()));
254 scoped_ptr<PolicyWatcher> PolicyWatcher::Create(
255 policy::PolicyService* policy_service,
256 const scoped_refptr<base::SingleThreadTaskRunner>& file_task_runner) {
257 #if defined(OS_CHROMEOS)
258 // On Chrome OS the PolicyService is owned by the browser.
259 DCHECK(policy_service);
260 return make_scoped_ptr(
261 new PolicyWatcher(policy_service, nullptr, nullptr, nullptr));
262 #else // !defined(OS_CHROMEOS)
263 DCHECK(!policy_service);
265 // Create platform-specific PolicyLoader. Always read the Chrome policies
266 // (even on Chromium) so that policy enforcement can't be bypassed by running
267 // Chromium.
268 scoped_ptr<policy::AsyncPolicyLoader> policy_loader;
269 #if defined(OS_WIN)
270 policy_loader = policy::PolicyLoaderWin::Create(
271 file_task_runner, L"SOFTWARE\\Policies\\Google\\Chrome");
272 #elif defined(OS_MACOSX)
273 CFStringRef bundle_id = CFSTR("com.google.Chrome");
274 policy_loader.reset(new policy::PolicyLoaderMac(
275 file_task_runner,
276 policy::PolicyLoaderMac::GetManagedPolicyPath(bundle_id),
277 new MacPreferences(), bundle_id));
278 #elif defined(OS_POSIX) && !defined(OS_ANDROID)
279 policy_loader.reset(new policy::ConfigDirPolicyLoader(
280 file_task_runner,
281 base::FilePath(FILE_PATH_LITERAL("/etc/opt/chrome/policies")),
282 policy::POLICY_SCOPE_MACHINE));
283 #else
284 #error OS that is not yet supported by PolicyWatcher code.
285 #endif
287 return PolicyWatcher::CreateFromPolicyLoader(policy_loader.Pass());
288 #endif // !(OS_CHROMEOS)
291 } // namespace remoting