This source file includes following definitions.
- CopyGoodValuesAndAddDefaults
- weak_factory_
- StartWatching
- StopWatching
- ScheduleFallbackReloadTask
- ScheduleReloadTask
- Defaults
- OnPolicyWatcherThread
- UpdatePolicies
#include "remoting/host/policy_hack/policy_watcher.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/location.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
#include "base/time/time.h"
#include "base/values.h"
#include "remoting/host/dns_blackhole_checker.h"
#if !defined(NDEBUG)
#include "base/json/json_reader.h"
#endif
namespace remoting {
namespace policy_hack {
namespace {
const int kFallbackReloadDelayMinutes = 15;
scoped_ptr<base::DictionaryValue> CopyGoodValuesAndAddDefaults(
const base::DictionaryValue* from,
const base::DictionaryValue* default_values,
const base::DictionaryValue* bad_type_values) {
scoped_ptr<base::DictionaryValue> to(default_values->DeepCopy());
for (base::DictionaryValue::Iterator i(*default_values);
!i.IsAtEnd(); i.Advance()) {
const base::Value* value = NULL;
if (!from->Get(i.key(), &value)) {
continue;
}
if (!value->IsType(i.value().GetType())) {
CHECK(bad_type_values->Get(i.key(), &value));
}
to->Set(i.key(), value->DeepCopy());
}
#if !defined(NDEBUG)
std::string policy_overrides;
if (from->GetString(PolicyWatcher::kHostDebugOverridePoliciesName,
&policy_overrides)) {
scoped_ptr<base::Value> value(base::JSONReader::Read(policy_overrides));
const base::DictionaryValue* override_values;
if (value && value->GetAsDictionary(&override_values)) {
to->MergeDictionary(override_values);
}
}
#endif
return to.Pass();
}
}
const char PolicyWatcher::kNatPolicyName[] =
"RemoteAccessHostFirewallTraversal";
const char PolicyWatcher::kHostRequireTwoFactorPolicyName[] =
"RemoteAccessHostRequireTwoFactor";
const char PolicyWatcher::kHostDomainPolicyName[] =
"RemoteAccessHostDomain";
const char PolicyWatcher::kHostMatchUsernamePolicyName[] =
"RemoteAccessHostMatchUsername";
const char PolicyWatcher::kHostTalkGadgetPrefixPolicyName[] =
"RemoteAccessHostTalkGadgetPrefix";
const char PolicyWatcher::kHostRequireCurtainPolicyName[] =
"RemoteAccessHostRequireCurtain";
const char PolicyWatcher::kHostTokenUrlPolicyName[] =
"RemoteAccessHostTokenUrl";
const char PolicyWatcher::kHostTokenValidationUrlPolicyName[] =
"RemoteAccessHostTokenValidationUrl";
const char PolicyWatcher::kHostTokenValidationCertIssuerPolicyName[] =
"RemoteAccessHostTokenValidationCertificateIssuer";
const char PolicyWatcher::kHostAllowClientPairing[] =
"RemoteAccessHostAllowClientPairing";
const char PolicyWatcher::kHostAllowGnubbyAuthPolicyName[] =
"RemoteAccessHostAllowGnubbyAuth";
const char PolicyWatcher::kHostDebugOverridePoliciesName[] =
"RemoteAccessHostDebugOverridePolicies";
PolicyWatcher::PolicyWatcher(
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
: task_runner_(task_runner),
old_policies_(new base::DictionaryValue()),
default_values_(new base::DictionaryValue()),
weak_factory_(this) {
default_values_->SetBoolean(kNatPolicyName, true);
default_values_->SetBoolean(kHostRequireTwoFactorPolicyName, false);
default_values_->SetBoolean(kHostRequireCurtainPolicyName, false);
default_values_->SetBoolean(kHostMatchUsernamePolicyName, false);
default_values_->SetString(kHostDomainPolicyName, std::string());
default_values_->SetString(kHostTalkGadgetPrefixPolicyName,
kDefaultHostTalkGadgetPrefix);
default_values_->SetString(kHostTokenUrlPolicyName, std::string());
default_values_->SetString(kHostTokenValidationUrlPolicyName, std::string());
default_values_->SetString(kHostTokenValidationCertIssuerPolicyName,
std::string());
default_values_->SetBoolean(kHostAllowClientPairing, true);
default_values_->SetBoolean(kHostAllowGnubbyAuthPolicyName, true);
#if !defined(NDEBUG)
default_values_->SetString(kHostDebugOverridePoliciesName, std::string());
#endif
bad_type_values_.reset(default_values_->DeepCopy());
bad_type_values_->SetBoolean(kNatPolicyName, false);
}
PolicyWatcher::~PolicyWatcher() {
}
void PolicyWatcher::StartWatching(const PolicyCallback& policy_callback) {
if (!OnPolicyWatcherThread()) {
task_runner_->PostTask(FROM_HERE,
base::Bind(&PolicyWatcher::StartWatching,
base::Unretained(this),
policy_callback));
return;
}
policy_callback_ = policy_callback;
StartWatchingInternal();
}
void PolicyWatcher::StopWatching(base::WaitableEvent* done) {
if (!OnPolicyWatcherThread()) {
task_runner_->PostTask(FROM_HERE,
base::Bind(&PolicyWatcher::StopWatching,
base::Unretained(this), done));
return;
}
StopWatchingInternal();
weak_factory_.InvalidateWeakPtrs();
policy_callback_.Reset();
done->Signal();
}
void PolicyWatcher::ScheduleFallbackReloadTask() {
DCHECK(OnPolicyWatcherThread());
ScheduleReloadTask(
base::TimeDelta::FromMinutes(kFallbackReloadDelayMinutes));
}
void PolicyWatcher::ScheduleReloadTask(const base::TimeDelta& delay) {
DCHECK(OnPolicyWatcherThread());
task_runner_->PostDelayedTask(
FROM_HERE,
base::Bind(&PolicyWatcher::Reload, weak_factory_.GetWeakPtr()),
delay);
}
const base::DictionaryValue& PolicyWatcher::Defaults() const {
return *default_values_;
}
bool PolicyWatcher::OnPolicyWatcherThread() const {
return task_runner_->BelongsToCurrentThread();
}
void PolicyWatcher::UpdatePolicies(
const base::DictionaryValue* new_policies_raw) {
DCHECK(OnPolicyWatcherThread());
scoped_ptr<base::DictionaryValue> new_policies =
CopyGoodValuesAndAddDefaults(
new_policies_raw, default_values_.get(), bad_type_values_.get());
scoped_ptr<base::DictionaryValue> changed_policies(
new base::DictionaryValue());
base::DictionaryValue::Iterator iter(*new_policies);
while (!iter.IsAtEnd()) {
base::Value* old_policy;
if (!(old_policies_->Get(iter.key(), &old_policy) &&
old_policy->Equals(&iter.value()))) {
changed_policies->Set(iter.key(), iter.value().DeepCopy());
}
iter.Advance();
}
old_policies_.swap(new_policies);
if (!changed_policies->empty()) {
policy_callback_.Run(changed_policies.Pass());
}
}
}
}