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