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 |
23 namespace remoting { | 40 namespace remoting { |
24 namespace policy_hack { | 41 namespace policy_hack { |
25 | 42 |
| 43 namespace key = ::policy::key; |
| 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, |
33 const base::DictionaryValue* default_values, | 52 const base::DictionaryValue* default_values, |
34 const base::DictionaryValue* bad_type_values) { | 53 const base::DictionaryValue* bad_type_values) { |
35 scoped_ptr<base::DictionaryValue> to(default_values->DeepCopy()); | 54 scoped_ptr<base::DictionaryValue> to(default_values->DeepCopy()); |
(...skipping 11 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 policy::PolicyNamespace GetPolicyNamespace() { |
| 90 return policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string()); |
| 91 } |
| 92 |
70 } // namespace | 93 } // namespace |
71 | 94 |
72 PolicyWatcher::PolicyWatcher( | |
73 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) | |
74 : task_runner_(task_runner), | |
75 transient_policy_error_retry_counter_(0), | |
76 old_policies_(new base::DictionaryValue()), | |
77 default_values_(new base::DictionaryValue()), | |
78 weak_factory_(this) { | |
79 // Initialize the default values for each policy. | |
80 default_values_->SetBoolean(policy::key::kRemoteAccessHostFirewallTraversal, | |
81 true); | |
82 default_values_->SetBoolean(policy::key::kRemoteAccessHostRequireTwoFactor, | |
83 false); | |
84 default_values_->SetBoolean(policy::key::kRemoteAccessHostRequireCurtain, | |
85 false); | |
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); | |
92 default_values_->SetString(policy::key::kRemoteAccessHostTokenUrl, | |
93 std::string()); | |
94 default_values_->SetString(policy::key::kRemoteAccessHostTokenValidationUrl, | |
95 std::string()); | |
96 default_values_->SetString( | |
97 policy::key::kRemoteAccessHostTokenValidationCertificateIssuer, | |
98 std::string()); | |
99 default_values_->SetBoolean(policy::key::kRemoteAccessHostAllowClientPairing, | |
100 true); | |
101 default_values_->SetBoolean(policy::key::kRemoteAccessHostAllowGnubbyAuth, | |
102 true); | |
103 default_values_->SetBoolean( | |
104 policy::key::kRemoteAccessHostAllowRelayedConnection, true); | |
105 default_values_->SetString(policy::key::kRemoteAccessHostUdpPortRange, ""); | |
106 #if !defined(NDEBUG) | |
107 default_values_->SetString( | |
108 policy::key::kRemoteAccessHostDebugOverridePolicies, std::string()); | |
109 #endif | |
110 | |
111 // Initialize the fall-back values to use for unreadable policies. | |
112 // For most policies these match the defaults. | |
113 bad_type_values_.reset(default_values_->DeepCopy()); | |
114 bad_type_values_->SetBoolean(policy::key::kRemoteAccessHostFirewallTraversal, | |
115 false); | |
116 bad_type_values_->SetBoolean( | |
117 policy::key::kRemoteAccessHostAllowRelayedConnection, false); | |
118 } | |
119 | |
120 PolicyWatcher::~PolicyWatcher() { | |
121 } | |
122 | |
123 void PolicyWatcher::StartWatching( | 95 void PolicyWatcher::StartWatching( |
124 const PolicyUpdatedCallback& policy_updated_callback, | 96 const PolicyUpdatedCallback& policy_updated_callback, |
125 const PolicyErrorCallback& policy_error_callback) { | 97 const PolicyErrorCallback& policy_error_callback) { |
126 if (!OnPolicyWatcherThread()) { | 98 if (!OnPolicyServiceThread()) { |
127 task_runner_->PostTask(FROM_HERE, | 99 policy_service_task_runner_->PostTask( |
128 base::Bind(&PolicyWatcher::StartWatching, | 100 FROM_HERE, |
129 base::Unretained(this), | 101 base::Bind(&PolicyWatcher::StartWatching, base::Unretained(this), |
130 policy_updated_callback, | 102 policy_updated_callback, policy_error_callback)); |
131 policy_error_callback)); | |
132 return; | 103 return; |
133 } | 104 } |
134 | 105 |
135 policy_updated_callback_ = policy_updated_callback; | 106 policy_updated_callback_ = policy_updated_callback; |
136 policy_error_callback_ = policy_error_callback; | 107 policy_error_callback_ = policy_error_callback; |
137 StartWatchingInternal(); | 108 |
| 109 // Listen for future policy changes. |
| 110 policy_service_->AddObserver(policy::POLICY_DOMAIN_CHROME, this); |
| 111 |
| 112 // Process current policy state. |
| 113 if (policy_service_->IsInitializationComplete(policy::POLICY_DOMAIN_CHROME)) { |
| 114 OnPolicyServiceInitialized(policy::POLICY_DOMAIN_CHROME); |
| 115 } |
138 } | 116 } |
139 | 117 |
140 void PolicyWatcher::StopWatching(const base::Closure& stopped_callback) { | 118 void PolicyWatcher::StopWatching(const base::Closure& stopped_callback) { |
141 task_runner_->PostTaskAndReply( | 119 policy_service_task_runner_->PostTaskAndReply( |
142 FROM_HERE, base::Bind(&PolicyWatcher::StopWatchingOnPolicyWatcherThread, | 120 FROM_HERE, base::Bind(&PolicyWatcher::StopWatchingOnPolicyServiceThread, |
143 base::Unretained(this)), | 121 base::Unretained(this)), |
144 stopped_callback); | 122 stopped_callback); |
145 } | 123 } |
146 | 124 |
147 void PolicyWatcher::StopWatchingOnPolicyWatcherThread() { | 125 void PolicyWatcher::StopWatchingOnPolicyServiceThread() { |
148 StopWatchingInternal(); | 126 policy_service_->RemoveObserver(policy::POLICY_DOMAIN_CHROME, this); |
149 weak_factory_.InvalidateWeakPtrs(); | |
150 policy_updated_callback_.Reset(); | 127 policy_updated_callback_.Reset(); |
151 policy_error_callback_.Reset(); | 128 policy_error_callback_.Reset(); |
152 } | 129 } |
153 | 130 |
154 const base::DictionaryValue& PolicyWatcher::Defaults() const { | 131 bool PolicyWatcher::OnPolicyServiceThread() const { |
155 return *default_values_; | 132 return policy_service_task_runner_->BelongsToCurrentThread(); |
156 } | |
157 | |
158 bool PolicyWatcher::OnPolicyWatcherThread() const { | |
159 return task_runner_->BelongsToCurrentThread(); | |
160 } | 133 } |
161 | 134 |
162 void PolicyWatcher::UpdatePolicies( | 135 void PolicyWatcher::UpdatePolicies( |
163 const base::DictionaryValue* new_policies_raw) { | 136 const base::DictionaryValue* new_policies_raw) { |
164 DCHECK(OnPolicyWatcherThread()); | 137 DCHECK(OnPolicyServiceThread()); |
165 | 138 |
166 transient_policy_error_retry_counter_ = 0; | 139 transient_policy_error_retry_counter_ = 0; |
167 | 140 |
168 // Use default values for any missing policies. | 141 // Use default values for any missing policies. |
169 scoped_ptr<base::DictionaryValue> new_policies = | 142 scoped_ptr<base::DictionaryValue> new_policies = |
170 CopyGoodValuesAndAddDefaults( | 143 CopyGoodValuesAndAddDefaults( |
171 new_policies_raw, default_values_.get(), bad_type_values_.get()); | 144 new_policies_raw, default_values_.get(), bad_type_values_.get()); |
172 | 145 |
173 // Find the changed policies. | 146 // Find the changed policies. |
174 scoped_ptr<base::DictionaryValue> changed_policies( | 147 scoped_ptr<base::DictionaryValue> changed_policies( |
(...skipping 23 matching lines...) Expand all Loading... |
198 } | 171 } |
199 | 172 |
200 void PolicyWatcher::SignalTransientPolicyError() { | 173 void PolicyWatcher::SignalTransientPolicyError() { |
201 const int kMaxRetryCount = 5; | 174 const int kMaxRetryCount = 5; |
202 transient_policy_error_retry_counter_ += 1; | 175 transient_policy_error_retry_counter_ += 1; |
203 if (transient_policy_error_retry_counter_ >= kMaxRetryCount) { | 176 if (transient_policy_error_retry_counter_ >= kMaxRetryCount) { |
204 SignalPolicyError(); | 177 SignalPolicyError(); |
205 } | 178 } |
206 } | 179 } |
207 | 180 |
| 181 PolicyWatcher::PolicyWatcher( |
| 182 const scoped_refptr<base::SingleThreadTaskRunner>& |
| 183 policy_service_task_runner, |
| 184 policy::PolicyService* policy_service, |
| 185 scoped_ptr<policy::PolicyService> owned_policy_service, |
| 186 scoped_ptr<policy::ConfigurationPolicyProvider> owned_policy_provider, |
| 187 scoped_ptr<policy::SchemaRegistry> owned_schema_registry) |
| 188 : policy_service_task_runner_(policy_service_task_runner), |
| 189 transient_policy_error_retry_counter_(0), |
| 190 old_policies_(new base::DictionaryValue()), |
| 191 default_values_(new base::DictionaryValue()), |
| 192 policy_service_(policy_service), |
| 193 owned_schema_registry_(owned_schema_registry.Pass()), |
| 194 owned_policy_provider_(owned_policy_provider.Pass()), |
| 195 owned_policy_service_(owned_policy_service.Pass()) { |
| 196 // Initialize the default values for each policy. |
| 197 default_values_->SetBoolean(key::kRemoteAccessHostFirewallTraversal, true); |
| 198 default_values_->SetBoolean(key::kRemoteAccessHostRequireTwoFactor, false); |
| 199 default_values_->SetBoolean(key::kRemoteAccessHostRequireCurtain, false); |
| 200 default_values_->SetBoolean(key::kRemoteAccessHostMatchUsername, false); |
| 201 default_values_->SetString(key::kRemoteAccessHostDomain, std::string()); |
| 202 default_values_->SetString(key::kRemoteAccessHostTalkGadgetPrefix, |
| 203 kDefaultHostTalkGadgetPrefix); |
| 204 default_values_->SetString(key::kRemoteAccessHostTokenUrl, std::string()); |
| 205 default_values_->SetString(key::kRemoteAccessHostTokenValidationUrl, |
| 206 std::string()); |
| 207 default_values_->SetString( |
| 208 key::kRemoteAccessHostTokenValidationCertificateIssuer, std::string()); |
| 209 default_values_->SetBoolean(key::kRemoteAccessHostAllowClientPairing, true); |
| 210 default_values_->SetBoolean(key::kRemoteAccessHostAllowGnubbyAuth, true); |
| 211 default_values_->SetBoolean(key::kRemoteAccessHostAllowRelayedConnection, |
| 212 true); |
| 213 default_values_->SetString(key::kRemoteAccessHostUdpPortRange, ""); |
| 214 #if !defined(NDEBUG) |
| 215 default_values_->SetString(key::kRemoteAccessHostDebugOverridePolicies, |
| 216 std::string()); |
| 217 #endif |
| 218 |
| 219 // Initialize the fall-back values to use for unreadable policies. |
| 220 // For most policies these match the defaults. |
| 221 bad_type_values_.reset(default_values_->DeepCopy()); |
| 222 bad_type_values_->SetBoolean(key::kRemoteAccessHostFirewallTraversal, false); |
| 223 bad_type_values_->SetBoolean(key::kRemoteAccessHostAllowRelayedConnection, |
| 224 false); |
| 225 } |
| 226 |
| 227 PolicyWatcher::~PolicyWatcher() { |
| 228 if (owned_policy_provider_) { |
| 229 owned_policy_provider_->Shutdown(); |
| 230 } |
| 231 } |
| 232 |
| 233 void PolicyWatcher::OnPolicyUpdated(const policy::PolicyNamespace& ns, |
| 234 const policy::PolicyMap& previous, |
| 235 const policy::PolicyMap& current) { |
| 236 scoped_ptr<base::DictionaryValue> policy_dict(new base::DictionaryValue()); |
| 237 for (auto it = current.begin(); it != current.end(); ++it) { |
| 238 // TODO(lukasza): Use policy::Schema::Normalize() for schema verification. |
| 239 policy_dict->Set(it->first, it->second.value->DeepCopy()); |
| 240 } |
| 241 UpdatePolicies(policy_dict.get()); |
| 242 } |
| 243 |
| 244 void PolicyWatcher::OnPolicyServiceInitialized(policy::PolicyDomain domain) { |
| 245 policy::PolicyNamespace ns = GetPolicyNamespace(); |
| 246 const policy::PolicyMap& current = policy_service_->GetPolicies(ns); |
| 247 OnPolicyUpdated(ns, current, current); |
| 248 } |
| 249 |
| 250 scoped_ptr<PolicyWatcher> PolicyWatcher::CreateFromPolicyLoader( |
| 251 const scoped_refptr<base::SingleThreadTaskRunner>& |
| 252 policy_service_task_runner, |
| 253 scoped_ptr<policy::AsyncPolicyLoader> async_policy_loader) { |
| 254 // TODO(lukasza): Schema below should ideally only cover Chromoting-specific |
| 255 // policies (expecting perf and maintanability improvement, but no functional |
| 256 // impact). |
| 257 policy::Schema schema = policy::Schema::Wrap(policy::GetChromeSchemaData()); |
| 258 |
| 259 scoped_ptr<policy::SchemaRegistry> schema_registry( |
| 260 new policy::SchemaRegistry()); |
| 261 schema_registry->RegisterComponent(GetPolicyNamespace(), schema); |
| 262 |
| 263 scoped_ptr<policy::AsyncPolicyProvider> policy_provider( |
| 264 new policy::AsyncPolicyProvider(schema_registry.get(), |
| 265 async_policy_loader.Pass())); |
| 266 policy_provider->Init(schema_registry.get()); |
| 267 |
| 268 policy::PolicyServiceImpl::Providers providers; |
| 269 providers.push_back(policy_provider.get()); |
| 270 scoped_ptr<policy::PolicyService> policy_service( |
| 271 new policy::PolicyServiceImpl(providers)); |
| 272 |
| 273 policy::PolicyService* borrowed_policy_service = policy_service.get(); |
| 274 return make_scoped_ptr(new PolicyWatcher( |
| 275 policy_service_task_runner, borrowed_policy_service, |
| 276 policy_service.Pass(), policy_provider.Pass(), schema_registry.Pass())); |
| 277 } |
| 278 |
| 279 scoped_ptr<PolicyWatcher> PolicyWatcher::Create( |
| 280 policy::PolicyService* policy_service, |
| 281 const scoped_refptr<base::SingleThreadTaskRunner>& network_task_runner) { |
| 282 #if defined(OS_CHROMEOS) |
| 283 DCHECK(policy_service); |
| 284 return make_scoped_ptr( |
| 285 new PolicyWatcher(content::BrowserThread::GetMessageLoopProxyForThread( |
| 286 content::BrowserThread::UI), |
| 287 policy_service, nullptr, nullptr, nullptr)); |
| 288 #elif defined(OS_WIN) |
| 289 DCHECK(!policy_service); |
| 290 // Always read the Chrome policies (even on Chromium) so that policy |
| 291 // enforcement can't be bypassed by running Chromium. |
| 292 // Note that this comment applies to all of Win/Mac/Posix branches below. |
| 293 static const wchar_t kRegistryKey[] = L"SOFTWARE\\Policies\\Google\\Chrome"; |
| 294 return PolicyWatcher::CreateFromPolicyLoader( |
| 295 network_task_runner, |
| 296 policy::PolicyLoaderWin::Create(network_task_runner, kRegistryKey)); |
| 297 #elif defined(OS_MACOSX) |
| 298 CFStringRef bundle_id = CFSTR("com.google.Chrome"); |
| 299 DCHECK(!policy_service); |
| 300 return PolicyWatcher::CreateFromPolicyLoader( |
| 301 network_task_runner, |
| 302 make_scoped_ptr(new policy::PolicyLoaderMac( |
| 303 network_task_runner, |
| 304 policy::PolicyLoaderMac::GetManagedPolicyPath(bundle_id), |
| 305 new MacPreferences(), bundle_id))); |
| 306 #elif defined(OS_POSIX) && !defined(OS_ANDROID) |
| 307 DCHECK(!policy_service); |
| 308 static const base::FilePath::CharType kPolicyDir[] = |
| 309 FILE_PATH_LITERAL("/etc/opt/chrome/policies"); |
| 310 return PolicyWatcher::CreateFromPolicyLoader( |
| 311 network_task_runner, make_scoped_ptr(new policy::ConfigDirPolicyLoader( |
| 312 network_task_runner, base::FilePath(kPolicyDir), |
| 313 policy::POLICY_SCOPE_MACHINE))); |
| 314 #else |
| 315 #error OS that is not yet supported by PolicyWatcher code. |
| 316 #endif |
| 317 } |
| 318 |
208 } // namespace policy_hack | 319 } // namespace policy_hack |
209 } // namespace remoting | 320 } // namespace remoting |
OLD | NEW |