OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Most of this code is copied from: | 5 // Most of this code is copied from: |
6 // src/chrome/browser/policy/asynchronous_policy_loader.{h,cc} | 6 // src/chrome/browser/policy/asynchronous_policy_loader.{h,cc} |
7 | 7 |
8 #include "remoting/host/policy_hack/policy_watcher.h" | 8 #include "remoting/host/policy_hack/policy_watcher.h" |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
12 #include "base/files/file_path.h" | |
12 #include "base/location.h" | 13 #include "base/location.h" |
13 #include "base/memory/weak_ptr.h" | |
14 #include "base/single_thread_task_runner.h" | 14 #include "base/single_thread_task_runner.h" |
15 #include "base/values.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" | |
16 #include "policy/policy_constants.h" | 22 #include "policy/policy_constants.h" |
17 #include "remoting/host/dns_blackhole_checker.h" | 23 #include "remoting/host/dns_blackhole_checker.h" |
18 | 24 |
19 #if !defined(NDEBUG) | 25 #if !defined(NDEBUG) |
20 #include "base/json/json_reader.h" | 26 #include "base/json/json_reader.h" |
21 #endif | 27 #endif |
22 | 28 |
29 #if defined(OS_CHROMEOS) | |
30 #include "content/public/browser/browser_thread.h" | |
31 #elif defined(OS_WIN) | |
32 #include "components/policy/core/common/policy_loader_win.h" | |
33 #elif defined(OS_MACOSX) | |
34 #include "components/policy/core/common/policy_loader_mac.h" | |
35 #include "components/policy/core/common/preferences_mac.h" | |
36 #elif defined(OS_POSIX) && !defined(OS_ANDROID) | |
37 #include "components/policy/core/common/config_dir_policy_loader.h" | |
38 #endif | |
39 | |
40 using namespace policy; | |
Sergey Ulanov
2015/01/26 18:20:01
style guide prohibits "using namespace": http://go
Łukasz Anforowicz
2015/01/26 19:24:20
Oops. Fixed. FWIW, I was just retaining it from
Sergey Ulanov
2015/01/28 07:07:53
If I remember correctly the style guide did allow
| |
41 | |
23 namespace remoting { | 42 namespace remoting { |
24 namespace policy_hack { | 43 namespace policy_hack { |
25 | 44 |
26 namespace { | 45 namespace { |
27 | 46 |
28 // Copies all policy values from one dictionary to another, using values from | 47 // Copies all policy values from one dictionary to another, using values from |
29 // |default| if they are not set in |from|, or values from |bad_type_values| if | 48 // |default| if they are not set in |from|, or values from |bad_type_values| if |
30 // the value in |from| has the wrong type. | 49 // the value in |from| has the wrong type. |
31 scoped_ptr<base::DictionaryValue> CopyGoodValuesAndAddDefaults( | 50 scoped_ptr<base::DictionaryValue> CopyGoodValuesAndAddDefaults( |
32 const base::DictionaryValue* from, | 51 const base::DictionaryValue* from, |
(...skipping 14 matching lines...) Expand all Loading... | |
47 if (!value->IsType(i.value().GetType())) { | 66 if (!value->IsType(i.value().GetType())) { |
48 CHECK(bad_type_values->Get(i.key(), &value)); | 67 CHECK(bad_type_values->Get(i.key(), &value)); |
49 } | 68 } |
50 | 69 |
51 to->Set(i.key(), value->DeepCopy()); | 70 to->Set(i.key(), value->DeepCopy()); |
52 } | 71 } |
53 | 72 |
54 #if !defined(NDEBUG) | 73 #if !defined(NDEBUG) |
55 // Replace values with those specified in DebugOverridePolicies, if present. | 74 // Replace values with those specified in DebugOverridePolicies, if present. |
56 std::string policy_overrides; | 75 std::string policy_overrides; |
57 if (from->GetString(policy::key::kRemoteAccessHostDebugOverridePolicies, | 76 if (from->GetString(key::kRemoteAccessHostDebugOverridePolicies, |
58 &policy_overrides)) { | 77 &policy_overrides)) { |
59 scoped_ptr<base::Value> value(base::JSONReader::Read(policy_overrides)); | 78 scoped_ptr<base::Value> value(base::JSONReader::Read(policy_overrides)); |
60 const base::DictionaryValue* override_values; | 79 const base::DictionaryValue* override_values; |
61 if (value && value->GetAsDictionary(&override_values)) { | 80 if (value && value->GetAsDictionary(&override_values)) { |
62 to->MergeDictionary(override_values); | 81 to->MergeDictionary(override_values); |
63 } | 82 } |
64 } | 83 } |
65 #endif // defined(NDEBUG) | 84 #endif // defined(NDEBUG) |
66 | 85 |
67 return to.Pass(); | 86 return to.Pass(); |
68 } | 87 } |
69 | 88 |
89 PolicyNamespace GetPolicyNamespace() { | |
90 return PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()); | |
91 } | |
92 | |
Łukasz Anforowicz
2015/01/26 17:45:11
GetPolicyNamespace is copy&pasted from policy_serv
| |
70 } // namespace | 93 } // namespace |
71 | 94 |
72 PolicyWatcher::PolicyWatcher( | 95 PolicyWatcher::PolicyWatcher(const scoped_refptr<base::SingleThreadTaskRunner>& |
Sergey Ulanov
2015/01/26 18:20:01
nit: Move this constructructor next to the other c
Łukasz Anforowicz
2015/01/26 19:24:20
Done.
| |
73 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) | 96 policy_service_task_runner) |
74 : task_runner_(task_runner), | 97 : policy_service_task_runner_(policy_service_task_runner), |
75 transient_policy_error_retry_counter_(0), | 98 transient_policy_error_retry_counter_(0), |
76 old_policies_(new base::DictionaryValue()), | 99 old_policies_(new base::DictionaryValue()), |
77 default_values_(new base::DictionaryValue()), | 100 default_values_(new base::DictionaryValue()) { |
78 weak_factory_(this) { | |
79 // Initialize the default values for each policy. | 101 // Initialize the default values for each policy. |
80 default_values_->SetBoolean(policy::key::kRemoteAccessHostFirewallTraversal, | 102 default_values_->SetBoolean(key::kRemoteAccessHostFirewallTraversal, true); |
81 true); | 103 default_values_->SetBoolean(key::kRemoteAccessHostRequireTwoFactor, false); |
82 default_values_->SetBoolean(policy::key::kRemoteAccessHostRequireTwoFactor, | 104 default_values_->SetBoolean(key::kRemoteAccessHostRequireCurtain, false); |
83 false); | 105 default_values_->SetBoolean(key::kRemoteAccessHostMatchUsername, false); |
84 default_values_->SetBoolean(policy::key::kRemoteAccessHostRequireCurtain, | 106 default_values_->SetString(key::kRemoteAccessHostDomain, std::string()); |
85 false); | 107 default_values_->SetString(key::kRemoteAccessHostTalkGadgetPrefix, |
86 default_values_->SetBoolean(policy::key::kRemoteAccessHostMatchUsername, | |
87 false); | |
88 default_values_->SetString(policy::key::kRemoteAccessHostDomain, | |
89 std::string()); | |
90 default_values_->SetString(policy::key::kRemoteAccessHostTalkGadgetPrefix, | |
91 kDefaultHostTalkGadgetPrefix); | 108 kDefaultHostTalkGadgetPrefix); |
92 default_values_->SetString(policy::key::kRemoteAccessHostTokenUrl, | 109 default_values_->SetString(key::kRemoteAccessHostTokenUrl, std::string()); |
93 std::string()); | 110 default_values_->SetString(key::kRemoteAccessHostTokenValidationUrl, |
94 default_values_->SetString(policy::key::kRemoteAccessHostTokenValidationUrl, | |
95 std::string()); | 111 std::string()); |
96 default_values_->SetString( | 112 default_values_->SetString( |
97 policy::key::kRemoteAccessHostTokenValidationCertificateIssuer, | 113 key::kRemoteAccessHostTokenValidationCertificateIssuer, std::string()); |
98 std::string()); | 114 default_values_->SetBoolean(key::kRemoteAccessHostAllowClientPairing, true); |
99 default_values_->SetBoolean(policy::key::kRemoteAccessHostAllowClientPairing, | 115 default_values_->SetBoolean(key::kRemoteAccessHostAllowGnubbyAuth, true); |
116 default_values_->SetBoolean(key::kRemoteAccessHostAllowRelayedConnection, | |
100 true); | 117 true); |
101 default_values_->SetBoolean(policy::key::kRemoteAccessHostAllowGnubbyAuth, | 118 default_values_->SetString(key::kRemoteAccessHostUdpPortRange, ""); |
102 true); | |
103 default_values_->SetBoolean( | |
104 policy::key::kRemoteAccessHostAllowRelayedConnection, true); | |
105 default_values_->SetString(policy::key::kRemoteAccessHostUdpPortRange, ""); | |
106 #if !defined(NDEBUG) | 119 #if !defined(NDEBUG) |
107 default_values_->SetString( | 120 default_values_->SetString(key::kRemoteAccessHostDebugOverridePolicies, |
108 policy::key::kRemoteAccessHostDebugOverridePolicies, std::string()); | 121 std::string()); |
109 #endif | 122 #endif |
110 | 123 |
111 // Initialize the fall-back values to use for unreadable policies. | 124 // Initialize the fall-back values to use for unreadable policies. |
112 // For most policies these match the defaults. | 125 // For most policies these match the defaults. |
113 bad_type_values_.reset(default_values_->DeepCopy()); | 126 bad_type_values_.reset(default_values_->DeepCopy()); |
114 bad_type_values_->SetBoolean(policy::key::kRemoteAccessHostFirewallTraversal, | 127 bad_type_values_->SetBoolean(key::kRemoteAccessHostFirewallTraversal, false); |
128 bad_type_values_->SetBoolean(key::kRemoteAccessHostAllowRelayedConnection, | |
115 false); | 129 false); |
116 bad_type_values_->SetBoolean( | |
117 policy::key::kRemoteAccessHostAllowRelayedConnection, false); | |
118 } | |
119 | |
120 PolicyWatcher::~PolicyWatcher() { | |
121 } | 130 } |
122 | 131 |
123 void PolicyWatcher::StartWatching( | 132 void PolicyWatcher::StartWatching( |
124 const PolicyUpdatedCallback& policy_updated_callback, | 133 const PolicyUpdatedCallback& policy_updated_callback, |
125 const PolicyErrorCallback& policy_error_callback) { | 134 const PolicyErrorCallback& policy_error_callback) { |
126 if (!OnPolicyWatcherThread()) { | 135 if (!OnPolicyWatcherThread()) { |
127 task_runner_->PostTask(FROM_HERE, | 136 policy_service_task_runner_->PostTask( |
128 base::Bind(&PolicyWatcher::StartWatching, | 137 FROM_HERE, |
129 base::Unretained(this), | 138 base::Bind(&PolicyWatcher::StartWatching, base::Unretained(this), |
130 policy_updated_callback, | 139 policy_updated_callback, policy_error_callback)); |
131 policy_error_callback)); | |
132 return; | 140 return; |
133 } | 141 } |
134 | 142 |
135 policy_updated_callback_ = policy_updated_callback; | 143 policy_updated_callback_ = policy_updated_callback; |
136 policy_error_callback_ = policy_error_callback; | 144 policy_error_callback_ = policy_error_callback; |
137 StartWatchingInternal(); | 145 StartWatchingInternal(); |
138 } | 146 } |
139 | 147 |
140 void PolicyWatcher::StopWatching(const base::Closure& stopped_callback) { | 148 void PolicyWatcher::StopWatching(const base::Closure& stopped_callback) { |
141 task_runner_->PostTaskAndReply( | 149 policy_service_task_runner_->PostTaskAndReply( |
142 FROM_HERE, base::Bind(&PolicyWatcher::StopWatchingOnPolicyWatcherThread, | 150 FROM_HERE, base::Bind(&PolicyWatcher::StopWatchingOnPolicyWatcherThread, |
143 base::Unretained(this)), | 151 base::Unretained(this)), |
144 stopped_callback); | 152 stopped_callback); |
145 } | 153 } |
146 | 154 |
147 void PolicyWatcher::StopWatchingOnPolicyWatcherThread() { | 155 void PolicyWatcher::StopWatchingOnPolicyWatcherThread() { |
148 StopWatchingInternal(); | 156 StopWatchingInternal(); |
149 weak_factory_.InvalidateWeakPtrs(); | |
150 policy_updated_callback_.Reset(); | 157 policy_updated_callback_.Reset(); |
151 policy_error_callback_.Reset(); | 158 policy_error_callback_.Reset(); |
152 } | 159 } |
153 | 160 |
154 const base::DictionaryValue& PolicyWatcher::Defaults() const { | |
155 return *default_values_; | |
156 } | |
157 | |
158 bool PolicyWatcher::OnPolicyWatcherThread() const { | 161 bool PolicyWatcher::OnPolicyWatcherThread() const { |
159 return task_runner_->BelongsToCurrentThread(); | 162 return policy_service_task_runner_->BelongsToCurrentThread(); |
160 } | 163 } |
161 | 164 |
162 void PolicyWatcher::UpdatePolicies( | 165 void PolicyWatcher::UpdatePolicies( |
163 const base::DictionaryValue* new_policies_raw) { | 166 const base::DictionaryValue* new_policies_raw) { |
164 DCHECK(OnPolicyWatcherThread()); | 167 DCHECK(OnPolicyWatcherThread()); |
165 | 168 |
166 transient_policy_error_retry_counter_ = 0; | 169 transient_policy_error_retry_counter_ = 0; |
167 | 170 |
168 // Use default values for any missing policies. | 171 // Use default values for any missing policies. |
169 scoped_ptr<base::DictionaryValue> new_policies = | 172 scoped_ptr<base::DictionaryValue> new_policies = |
(...skipping 28 matching lines...) Expand all Loading... | |
198 } | 201 } |
199 | 202 |
200 void PolicyWatcher::SignalTransientPolicyError() { | 203 void PolicyWatcher::SignalTransientPolicyError() { |
201 const int kMaxRetryCount = 5; | 204 const int kMaxRetryCount = 5; |
202 transient_policy_error_retry_counter_ += 1; | 205 transient_policy_error_retry_counter_ += 1; |
203 if (transient_policy_error_retry_counter_ >= kMaxRetryCount) { | 206 if (transient_policy_error_retry_counter_ >= kMaxRetryCount) { |
204 SignalPolicyError(); | 207 SignalPolicyError(); |
205 } | 208 } |
206 } | 209 } |
207 | 210 |
211 PolicyWatcher::PolicyWatcher(const scoped_refptr<base::SingleThreadTaskRunner>& | |
212 policy_service_task_runner, | |
213 PolicyService* policy_service) | |
214 : PolicyWatcher(policy_service_task_runner) { | |
215 policy_service_ = policy_service; | |
216 } | |
217 | |
218 PolicyWatcher::PolicyWatcher( | |
Sergey Ulanov
2015/01/26 18:20:01
This class has 3 private constructors. Consider re
Łukasz Anforowicz
2015/01/26 19:24:20
I merged into a single constructor.
| |
219 const scoped_refptr<base::SingleThreadTaskRunner>& | |
220 policy_service_task_runner, | |
221 scoped_ptr<PolicyService> owned_policy_service, | |
222 scoped_ptr<ConfigurationPolicyProvider> owned_policy_provider, | |
223 scoped_ptr<SchemaRegistry> owned_schema_registry) | |
224 : PolicyWatcher(policy_service_task_runner) { | |
225 owned_schema_registry_ = owned_schema_registry.Pass(); | |
226 owned_policy_provider_ = owned_policy_provider.Pass(); | |
227 owned_policy_service_ = owned_policy_service.Pass(); | |
228 policy_service_ = owned_policy_service_.get(); | |
229 } | |
Łukasz Anforowicz
2015/01/26 17:45:11
Everything below is copy&pasted from policy_servic
| |
230 | |
231 PolicyWatcher::~PolicyWatcher() { | |
232 if (owned_policy_provider_) { | |
233 owned_policy_provider_->Shutdown(); | |
234 } | |
235 } | |
236 | |
237 void PolicyWatcher::OnPolicyUpdated(const PolicyNamespace& ns, | |
238 const PolicyMap& previous, | |
239 const PolicyMap& current) { | |
240 scoped_ptr<base::DictionaryValue> policy_dict(new base::DictionaryValue()); | |
241 for (PolicyMap::const_iterator it = current.begin(); it != current.end(); | |
242 it++) { | |
Sergey Ulanov
2015/01/26 18:20:01
s/it++/++it/
http://google-styleguide.googlecode.c
Łukasz Anforowicz
2015/01/26 19:24:20
Done.
I also looked into whether I can use "auto"
Sergey Ulanov
2015/01/28 07:07:53
I don't think it's essential that the iterator is
| |
243 // TODO(lukasza): Use policy::Schema::Normalize() for schema verification. | |
244 policy_dict->Set(it->first, it->second.value->DeepCopy()); | |
245 } | |
246 UpdatePolicies(policy_dict.get()); | |
247 } | |
248 | |
249 void PolicyWatcher::OnPolicyServiceInitialized(PolicyDomain domain) { | |
250 PolicyNamespace ns = GetPolicyNamespace(); | |
251 const PolicyMap& current = policy_service_->GetPolicies(ns); | |
252 OnPolicyUpdated(ns, current, current); | |
253 } | |
254 | |
255 void PolicyWatcher::StartWatchingInternal() { | |
256 // Listen for future policy changes. | |
257 policy_service_->AddObserver(POLICY_DOMAIN_CHROME, this); | |
258 | |
259 // Process current policy state. | |
260 if (policy_service_->IsInitializationComplete(POLICY_DOMAIN_CHROME)) { | |
261 OnPolicyServiceInitialized(POLICY_DOMAIN_CHROME); | |
262 } | |
263 } | |
264 | |
265 void PolicyWatcher::StopWatchingInternal() { | |
266 policy_service_->RemoveObserver(POLICY_DOMAIN_CHROME, this); | |
267 } | |
268 | |
269 scoped_ptr<PolicyWatcher> PolicyWatcher::CreateFromPolicyLoader( | |
270 const scoped_refptr<base::SingleThreadTaskRunner>& | |
271 policy_service_task_runner, | |
272 scoped_ptr<AsyncPolicyLoader> async_policy_loader) { | |
273 // TODO(lukasza): Schema below should ideally only cover Chromoting-specific | |
274 // policies (expecting perf and maintanability improvement, but no functional | |
275 // impact). | |
276 Schema schema = Schema::Wrap(GetChromeSchemaData()); | |
277 | |
278 scoped_ptr<SchemaRegistry> schema_registry(new SchemaRegistry()); | |
279 schema_registry->RegisterComponent(GetPolicyNamespace(), schema); | |
280 | |
281 scoped_ptr<AsyncPolicyProvider> policy_provider(new AsyncPolicyProvider( | |
282 schema_registry.get(), async_policy_loader.Pass())); | |
283 policy_provider->Init(schema_registry.get()); | |
284 | |
285 PolicyServiceImpl::Providers providers; | |
286 providers.push_back(policy_provider.get()); | |
287 scoped_ptr<PolicyService> policy_service(new PolicyServiceImpl(providers)); | |
288 | |
289 return make_scoped_ptr( | |
290 new PolicyWatcher(policy_service_task_runner, policy_service.Pass(), | |
291 policy_provider.Pass(), schema_registry.Pass())); | |
292 } | |
293 | |
294 scoped_ptr<PolicyWatcher> PolicyWatcher::Create( | |
295 policy::PolicyService* policy_service, | |
296 const scoped_refptr<base::SingleThreadTaskRunner>& network_task_runner) { | |
297 #if defined(OS_CHROMEOS) | |
298 DCHECK(policy_service); | |
299 return make_scoped_ptr( | |
300 new PolicyWatcher(content::BrowserThread::GetMessageLoopProxyForThread( | |
301 content::BrowserThread::UI), | |
302 policy_service)); | |
303 #elif defined(OS_WIN) | |
304 DCHECK(!policy_service); | |
305 static const wchar_t kRegistryKey[] = L"SOFTWARE\\Policies\\Google\\Chrome"; | |
306 return PolicyWatcher::CreateFromPolicyLoader( | |
307 network_task_runner, | |
308 PolicyLoaderWin::Create(network_task_runner, kRegistryKey)); | |
309 #elif defined(OS_MACOSX) | |
310 CFStringRef bundle_id = CFSTR("com.google.Chrome"); | |
311 DCHECK(!policy_service); | |
312 return PolicyWatcher::CreateFromPolicyLoader( | |
313 network_task_runner, | |
314 make_scoped_ptr(new PolicyLoaderMac( | |
315 network_task_runner, | |
316 policy::PolicyLoaderMac::GetManagedPolicyPath(bundle_id), | |
317 new MacPreferences(), bundle_id))); | |
318 #elif defined(OS_POSIX) && !defined(OS_ANDROID) | |
319 DCHECK(!policy_service); | |
320 // Always read the Chrome policies (even on Chromium) so that policy | |
Sergey Ulanov
2015/01/26 18:20:01
This comment applies to Win and OSX too. Move it o
Łukasz Anforowicz
2015/01/26 19:24:20
I moved it slightly higher + added a note that the
| |
321 // enforcement can't be bypassed by running Chromium. | |
322 static const base::FilePath::CharType kPolicyDir[] = | |
323 FILE_PATH_LITERAL("/etc/opt/chrome/policies"); | |
324 return PolicyWatcher::CreateFromPolicyLoader( | |
325 network_task_runner, make_scoped_ptr(new ConfigDirPolicyLoader( | |
326 network_task_runner, base::FilePath(kPolicyDir), | |
327 POLICY_SCOPE_MACHINE))); | |
328 #else | |
329 #error OS that is not yet supported by PolicyWatcher code. | |
330 #endif | |
331 } | |
332 | |
208 } // namespace policy_hack | 333 } // namespace policy_hack |
209 } // namespace remoting | 334 } // namespace remoting |
OLD | NEW |