diff options
author | jkummerow@chromium.org <jkummerow@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-16 09:52:42 +0000 |
---|---|---|
committer | jkummerow@chromium.org <jkummerow@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-16 09:52:42 +0000 |
commit | 23ce43c353afdfe50571bfb57ceb384216170b84 (patch) | |
tree | 962acf3b1d63453648eda6e021ff124477107d66 /chrome/browser/policy | |
parent | 43aca00e01ed07ffbbe18f72e08d2cc0d9dfe8cd (diff) | |
download | chromium_src-23ce43c353afdfe50571bfb57ceb384216170b84.zip chromium_src-23ce43c353afdfe50571bfb57ceb384216170b84.tar.gz chromium_src-23ce43c353afdfe50571bfb57ceb384216170b84.tar.bz2 |
Revert 75082 - New policy protobuf protocol.
- cloud_policy.proto autogenerated from policy_templates.json
- C++ method decoding the protobuf autogenerated from policy_templates.json
- changed policy fetching mechanism to fetch new-style policy protobufs
BUG=68309, chromium-os:11253, chromium-os:11255
TEST=CloudPolicyCacheTest.*; also manual test against python testserver
Review URL: http://codereview.chromium.org/6409040
TBR=jkummerow@chromium.org
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@75084 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/policy')
23 files changed, 1160 insertions, 1596 deletions
diff --git a/chrome/browser/policy/asynchronous_policy_provider.cc b/chrome/browser/policy/asynchronous_policy_provider.cc index 9b050ad..e697b05 100644 --- a/chrome/browser/policy/asynchronous_policy_provider.cc +++ b/chrome/browser/policy/asynchronous_policy_provider.cc @@ -25,7 +25,7 @@ bool AsynchronousPolicyProvider::Provide( ConfigurationPolicyStoreInterface* store) { DCHECK(CalledOnValidThread()); DCHECK(loader_->policy()); - ApplyPolicyValueTree(loader_->policy(), store); + DecodePolicyValueTree(loader_->policy(), store); return true; } diff --git a/chrome/browser/policy/cloud_policy_cache.cc b/chrome/browser/policy/cloud_policy_cache.cc deleted file mode 100644 index 3bf69fb..0000000 --- a/chrome/browser/policy/cloud_policy_cache.cc +++ /dev/null @@ -1,429 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/policy/cloud_policy_cache.h" - -#include <limits> - -#include "base/file_util.h" -#include "base/logging.h" -#include "base/task.h" -#include "base/values.h" -#include "chrome/browser/browser_thread.h" -#include "chrome/browser/policy/proto/cloud_policy.pb.h" -#include "chrome/browser/policy/proto/device_management_backend.pb.h" -#include "chrome/browser/policy/proto/device_management_constants.h" -#include "chrome/browser/policy/proto/device_management_local.pb.h" - -using google::protobuf::RepeatedField; -using google::protobuf::RepeatedPtrField; - -// This CloudPolicyCache currently supports two protocols for the interaction -// with DMServer: the old "DevicePolicy" format, which is being used in the -// CrOS Pilot Program and will be deprecated afterwards, and the new -// "CloudPolicy" format, which will be used exclusively after the public launch -// of ChromeOS. - -namespace policy { - -// Decodes a CloudPolicySettings object into two maps with mandatory and -// recommended settings, respectively. The implementation is generated code -// in policy/cloud_policy_generated.cc. -void DecodePolicy(const em::CloudPolicySettings& policy, - ConfigurationPolicyProvider::PolicyMapType* mandatory, - ConfigurationPolicyProvider::PolicyMapType* recommended); - -// Saves policy information to a file. -class PersistPolicyTask : public Task { - public: - PersistPolicyTask(const FilePath& path, - const em::CloudPolicyResponse* cloud_policy_response, - const em::DevicePolicyResponse* device_policy_response, - const bool is_unmanaged) - : path_(path), - cloud_policy_response_(cloud_policy_response), - device_policy_response_(device_policy_response), - is_unmanaged_(is_unmanaged) {} - - private: - // Task override. - virtual void Run(); - - const FilePath path_; - scoped_ptr<const em::CloudPolicyResponse> cloud_policy_response_; - scoped_ptr<const em::DevicePolicyResponse> device_policy_response_; - const bool is_unmanaged_; -}; - -void PersistPolicyTask::Run() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); - std::string data; - em::CachedCloudPolicyResponse cached_policy; - if (cloud_policy_response_.get()) { - cached_policy.mutable_cloud_policy()->CopyFrom(*cloud_policy_response_); - } else if (device_policy_response_.get()) { - cached_policy.mutable_device_policy()->CopyFrom(*device_policy_response_); - cached_policy.set_timestamp(base::Time::NowFromSystemTime().ToTimeT()); - } - if (is_unmanaged_) { - cached_policy.set_unmanaged(true); - cached_policy.set_timestamp(base::Time::NowFromSystemTime().ToTimeT()); - } - if (!cached_policy.SerializeToString(&data)) { - LOG(WARNING) << "Failed to serialize policy data"; - return; - } - - int size = data.size(); - if (file_util::WriteFile(path_, data.c_str(), size) != size) { - LOG(WARNING) << "Failed to write " << path_.value(); - return; - } -} - -CloudPolicyCache::CloudPolicyCache( - const FilePath& backing_file_path) - : backing_file_path_(backing_file_path), - device_policy_(new DictionaryValue), - fresh_policy_(false), - is_unmanaged_(false), - has_device_policy_(false) { -} - -CloudPolicyCache::~CloudPolicyCache() {} - -void CloudPolicyCache::LoadPolicyFromFile() { - // TODO(jkummerow): This method is doing file IO during browser startup. In - // the long run it would be better to delay this until the FILE thread exists. - if (!file_util::PathExists(backing_file_path_) || fresh_policy_) { - return; - } - - // Read the protobuf from the file. - std::string data; - if (!file_util::ReadFileToString(backing_file_path_, &data)) { - LOG(WARNING) << "Failed to read policy data from " - << backing_file_path_.value(); - return; - } - - em::CachedCloudPolicyResponse cached_response; - if (!cached_response.ParseFromArray(data.c_str(), data.size())) { - LOG(WARNING) << "Failed to parse policy data read from " - << backing_file_path_.value(); - return; - } - base::Time timestamp; - PolicyMapType mandatory_policy; - PolicyMapType recommended_policy; - is_unmanaged_ = cached_response.unmanaged(); - if (is_unmanaged_ || cached_response.has_device_policy()) - timestamp = base::Time::FromTimeT(cached_response.timestamp()); - if (cached_response.has_cloud_policy()) { - DCHECK(!is_unmanaged_); - bool ok = DecodePolicyResponse(cached_response.cloud_policy(), - &mandatory_policy, - &recommended_policy, - ×tamp); - if (!ok) { - LOG(WARNING) << "Decoding policy data failed."; - return; - } - } - if (timestamp > base::Time::NowFromSystemTime()) { - LOG(WARNING) << "Rejected policy data from " << backing_file_path_.value() - << ", file is from the future."; - return; - } - // Swap in the new policy information. - if (is_unmanaged_) { - base::AutoLock lock(lock_); - last_policy_refresh_time_ = timestamp; - return; - } else if (cached_response.has_cloud_policy()) { - if (!fresh_policy_) { - base::AutoLock lock(lock_); - mandatory_policy_.swap(mandatory_policy); - recommended_policy_.swap(recommended_policy); - last_policy_refresh_time_ = timestamp; - has_device_policy_ = false; - } - } else if (cached_response.has_device_policy()) { - scoped_ptr<DictionaryValue> value( - DecodeDevicePolicy(cached_response.device_policy())); - if (!fresh_policy_) { - base::AutoLock lock(lock_); - device_policy_.reset(value.release()); - last_policy_refresh_time_ = timestamp; - has_device_policy_ = true; - } - } -} - -bool CloudPolicyCache::SetPolicy(const em::CloudPolicyResponse& policy) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - is_unmanaged_ = false; - base::Time timestamp; - PolicyMapType mandatory_policy; - PolicyMapType recommended_policy; - bool ok = DecodePolicyResponse(policy, &mandatory_policy, &recommended_policy, - ×tamp); - if (!ok) { - // TODO(jkummerow): Signal error to PolicyProvider. - return false; - } - const bool new_policy_differs = - !Equals(mandatory_policy, mandatory_policy_) || - !Equals(recommended_policy, recommended_policy_); - { - base::AutoLock lock(lock_); - mandatory_policy_.swap(mandatory_policy); - recommended_policy_.swap(recommended_policy); - fresh_policy_ = true; - last_policy_refresh_time_ = timestamp; - has_device_policy_ = false; - } - - if (timestamp > base::Time::NowFromSystemTime() + - base::TimeDelta::FromMinutes(1)) { - LOG(WARNING) << "Server returned policy with timestamp from the future, " - "not persisting to disk."; - } else { - em::CloudPolicyResponse* policy_copy = new em::CloudPolicyResponse; - policy_copy->CopyFrom(policy); - BrowserThread::PostTask( - BrowserThread::FILE, - FROM_HERE, - new PersistPolicyTask(backing_file_path_, policy_copy, NULL, false)); - } - return new_policy_differs; -} - -bool CloudPolicyCache::SetDevicePolicy(const em::DevicePolicyResponse& policy) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - is_unmanaged_ = false; - DictionaryValue* value = DecodeDevicePolicy(policy); - const bool new_policy_differs = !(value->Equals(device_policy_.get())); - base::Time now(base::Time::NowFromSystemTime()); - { - base::AutoLock lock(lock_); - device_policy_.reset(value); - fresh_policy_ = true; - last_policy_refresh_time_ = now; - has_device_policy_ = true; - } - - em::DevicePolicyResponse* policy_copy = new em::DevicePolicyResponse; - policy_copy->CopyFrom(policy); - BrowserThread::PostTask( - BrowserThread::FILE, - FROM_HERE, - new PersistPolicyTask(backing_file_path_, NULL, policy_copy, false)); - return new_policy_differs; -} - -DictionaryValue* CloudPolicyCache::GetDevicePolicy() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - base::AutoLock lock(lock_); - return device_policy_->DeepCopy(); -} - -const CloudPolicyCache::PolicyMapType* - CloudPolicyCache::GetMandatoryPolicy() const { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - return &mandatory_policy_; -} - -const CloudPolicyCache::PolicyMapType* - CloudPolicyCache::GetRecommendedPolicy() const { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - return &recommended_policy_; -} - -void CloudPolicyCache::SetUnmanaged() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - is_unmanaged_ = true; - { - base::AutoLock lock(lock_); - mandatory_policy_.clear(); - recommended_policy_.clear(); - device_policy_.reset(new DictionaryValue); - last_policy_refresh_time_ = base::Time::NowFromSystemTime(); - } - BrowserThread::PostTask( - BrowserThread::FILE, - FROM_HERE, - new PersistPolicyTask(backing_file_path_, NULL, NULL, true)); -} - -// static -bool CloudPolicyCache::DecodePolicyResponse( - const em::CloudPolicyResponse& policy_response, - PolicyMapType* mandatory, - PolicyMapType* recommended, - base::Time* timestamp) { - std::string data = policy_response.signed_response(); - - if (!VerifySignature(policy_response.signature(), data, - policy_response.certificate_chain())) { - LOG(WARNING) << "Failed to verify signature."; - return false; - } - - em::SignedCloudPolicyResponse response; - if (!response.ParseFromArray(data.c_str(), data.size())) { - LOG(WARNING) << "Failed to parse SignedCloudPolicyResponse protobuf."; - return false; - } - - // TODO(jkummerow): Verify response.device_token(). Needs final specification - // which token we're actually sending / expecting to get back. - - // TODO(jkummerow): Store response.device_name(), if we decide to transfer - // it from the server to the client. - - DCHECK(timestamp); - *timestamp = base::Time::FromTimeT(response.timestamp()); - DecodePolicy(response.settings(), mandatory, recommended); - return true; -} - -// static -bool CloudPolicyCache::VerifySignature( - const std::string& signature, - const std::string& data, - const RepeatedPtrField<std::string>& certificate_chain) { - // TODO(jkummerow): Implement this. Non-trivial because we want to do it - // for all platforms -> it's enough work to deserve its own CL. - // Don't forget to also verify the hostname of the server against the cert. - return true; -} - -// static -bool CloudPolicyCache::MapEntryEquals(const PolicyMapType::value_type& a, - const PolicyMapType::value_type& b) { - return a.first == b.first && Value::Equals(a.second, b.second); -} - -// static -bool CloudPolicyCache::Equals(const PolicyMapType& a, const PolicyMapType& b) { - return a.size() == b.size() && - std::equal(a.begin(), a.end(), b.begin(), MapEntryEquals); -} - -// static -Value* CloudPolicyCache::DecodeIntegerValue(google::protobuf::int64 value) { - if (value < std::numeric_limits<int>::min() || - value > std::numeric_limits<int>::max()) { - LOG(WARNING) << "Integer value " << value - << " out of numeric limits, ignoring."; - return NULL; - } - - return Value::CreateIntegerValue(static_cast<int>(value)); -} - -// static -Value* CloudPolicyCache::DecodeValue(const em::GenericValue& value) { - if (!value.has_value_type()) - return NULL; - - switch (value.value_type()) { - case em::GenericValue::VALUE_TYPE_BOOL: - if (value.has_bool_value()) - return Value::CreateBooleanValue(value.bool_value()); - return NULL; - case em::GenericValue::VALUE_TYPE_INT64: - if (value.has_int64_value()) - return DecodeIntegerValue(value.int64_value()); - return NULL; - case em::GenericValue::VALUE_TYPE_STRING: - if (value.has_string_value()) - return Value::CreateStringValue(value.string_value()); - return NULL; - case em::GenericValue::VALUE_TYPE_DOUBLE: - if (value.has_double_value()) - return Value::CreateDoubleValue(value.double_value()); - return NULL; - case em::GenericValue::VALUE_TYPE_BYTES: - if (value.has_bytes_value()) { - std::string bytes = value.bytes_value(); - return BinaryValue::CreateWithCopiedBuffer(bytes.c_str(), bytes.size()); - } - return NULL; - case em::GenericValue::VALUE_TYPE_BOOL_ARRAY: { - ListValue* list = new ListValue; - RepeatedField<bool>::const_iterator i; - for (i = value.bool_array().begin(); i != value.bool_array().end(); ++i) - list->Append(Value::CreateBooleanValue(*i)); - return list; - } - case em::GenericValue::VALUE_TYPE_INT64_ARRAY: { - ListValue* list = new ListValue; - RepeatedField<google::protobuf::int64>::const_iterator i; - for (i = value.int64_array().begin(); - i != value.int64_array().end(); ++i) { - Value* int_value = DecodeIntegerValue(*i); - if (int_value) - list->Append(int_value); - } - return list; - } - case em::GenericValue::VALUE_TYPE_STRING_ARRAY: { - ListValue* list = new ListValue; - RepeatedPtrField<std::string>::const_iterator i; - for (i = value.string_array().begin(); - i != value.string_array().end(); ++i) - list->Append(Value::CreateStringValue(*i)); - return list; - } - case em::GenericValue::VALUE_TYPE_DOUBLE_ARRAY: { - ListValue* list = new ListValue; - RepeatedField<double>::const_iterator i; - for (i = value.double_array().begin(); - i != value.double_array().end(); ++i) - list->Append(Value::CreateDoubleValue(*i)); - return list; - } - default: - NOTREACHED() << "Unhandled value type"; - } - - return NULL; -} - -// static -DictionaryValue* CloudPolicyCache::DecodeDevicePolicy( - const em::DevicePolicyResponse& policy) { - DictionaryValue* result = new DictionaryValue; - RepeatedPtrField<em::DevicePolicySetting>::const_iterator setting; - for (setting = policy.setting().begin(); - setting != policy.setting().end(); - ++setting) { - // Wrong policy key? Skip. - if (setting->policy_key().compare(kChromeDevicePolicySettingKey) != 0) - continue; - - // No policy value? Skip. - if (!setting->has_policy_value()) - continue; - - // Iterate through all the name-value pairs wrapped in |setting|. - const em::GenericSetting& policy_value(setting->policy_value()); - RepeatedPtrField<em::GenericNamedValue>::const_iterator named_value; - for (named_value = policy_value.named_value().begin(); - named_value != policy_value.named_value().end(); - ++named_value) { - if (named_value->has_value()) { - Value* decoded_value = - CloudPolicyCache::DecodeValue(named_value->value()); - if (decoded_value) - result->Set(named_value->name(), decoded_value); - } - } - } - return result; -} - -} // namespace policy diff --git a/chrome/browser/policy/cloud_policy_cache.h b/chrome/browser/policy/cloud_policy_cache.h deleted file mode 100644 index 20352ac..0000000 --- a/chrome/browser/policy/cloud_policy_cache.h +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_POLICY_CLOUD_POLICY_CACHE_H_ -#define CHROME_BROWSER_POLICY_CLOUD_POLICY_CACHE_H_ - -#include <string> - -#include "base/file_path.h" -#include "base/gtest_prod_util.h" -#include "base/ref_counted.h" -#include "base/scoped_ptr.h" -#include "base/synchronization/lock.h" -#include "base/time.h" -#include "chrome/browser/policy/configuration_policy_provider.h" -#include "chrome/browser/policy/proto/device_management_backend.pb.h" -#include "policy/configuration_policy_type.h" - -class DictionaryValue; -class ListValue; -class Value; - -using google::protobuf::RepeatedPtrField; - -namespace policy { - -namespace em = enterprise_management; - -// Keeps the authoritative copy of cloud policy information as read from the -// persistence file or determined by the policy backend. The cache doesn't talk -// to the service directly, but receives updated policy information through -// SetPolicy() calls, which is then persisted and decoded into the internal -// Value representation chrome uses. -class CloudPolicyCache { - public: - typedef ConfigurationPolicyProvider::PolicyMapType PolicyMapType; - - explicit CloudPolicyCache(const FilePath& backing_file_path); - ~CloudPolicyCache(); - - // Loads policy information from the backing file. Non-existing or erroneous - // cache files are ignored. - void LoadPolicyFromFile(); - - // Resets the policy information. Returns true if the new policy is different - // from the previously stored policy. - bool SetPolicy(const em::CloudPolicyResponse& policy); - bool SetDevicePolicy(const em::DevicePolicyResponse& policy); - - // Gets the policy information. Ownership of the return value is transferred - // to the caller. - DictionaryValue* GetDevicePolicy(); - const PolicyMapType* GetMandatoryPolicy() const; - const PolicyMapType* GetRecommendedPolicy() const; - - void SetUnmanaged(); - bool is_unmanaged() const { - return is_unmanaged_; - } - - // Returns the time at which the policy was last fetched. - base::Time last_policy_refresh_time() const { - return last_policy_refresh_time_; - } - - // Returns true if this cache holds (old-style) device policy that should be - // given preference over (new-style) mandatory/recommended policy. - bool has_device_policy() const { - return has_device_policy_; - } - - private: - friend class CloudPolicyCacheTest; - friend class DeviceManagementPolicyCacheDecodeTest; - - // Decodes a CloudPolicyResponse into two (ConfigurationPolicyType -> Value*) - // maps and a timestamp. Also performs verification, returns NULL if any - // check fails. - static bool DecodePolicyResponse( - const em::CloudPolicyResponse& policy_response, - PolicyMapType* mandatory, - PolicyMapType* recommended, - base::Time* timestamp); - - // Returns true if |certificate_chain| is trusted and a |signature| created - // from it matches |data|. - static bool VerifySignature( - const std::string& signature, - const std::string& data, - const RepeatedPtrField<std::string>& certificate_chain); - - // Returns true if |a| equals |b|. - static bool Equals(const PolicyMapType& a, const PolicyMapType& b); - // Helper function for the above. - static bool MapEntryEquals(const PolicyMapType::value_type& a, - const PolicyMapType::value_type& b); - - // Decodes an int64 value. Checks whether the passed value fits the numeric - // limits of the value representation. Returns a value (ownership is - // transferred to the caller) on success, NULL on failure. - static Value* DecodeIntegerValue(google::protobuf::int64 value); - - // Decode a GenericValue message to the Value representation used internally. - // Returns NULL if |value| is invalid (i.e. contains no actual value). - static Value* DecodeValue(const em::GenericValue& value); - - // Decodes a policy message and returns it in Value representation. Ownership - // of the returned dictionary is transferred to the caller. - static DictionaryValue* DecodeDevicePolicy( - const em::DevicePolicyResponse& response); - - // The file in which we store a cached version of the policy information. - const FilePath backing_file_path_; - - // Protects both |mandatory_policy_| and |recommended_policy_| as well as - // |device_policy_|. - base::Lock lock_; - - // Policy key-value information. - PolicyMapType mandatory_policy_; - PolicyMapType recommended_policy_; - scoped_ptr<DictionaryValue> device_policy_; - - // Tracks whether the store received a SetPolicy() call, which overrides any - // information loaded from the file. - bool fresh_policy_; - - bool is_unmanaged_; - - // Tracks whether the cache currently stores |device_policy_| that should be - // given preference over |mandatory_policy_| and |recommended_policy_|. - bool has_device_policy_; - - // The time at which the policy was last refreshed. - base::Time last_policy_refresh_time_; -}; - -} // namespace policy - -#endif // CHROME_BROWSER_POLICY_CLOUD_POLICY_CACHE_H_ diff --git a/chrome/browser/policy/cloud_policy_cache_unittest.cc b/chrome/browser/policy/cloud_policy_cache_unittest.cc deleted file mode 100644 index 554ff48..0000000 --- a/chrome/browser/policy/cloud_policy_cache_unittest.cc +++ /dev/null @@ -1,660 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/policy/cloud_policy_cache.h" - -#include <limits> -#include <string> - -#include "base/file_util.h" -#include "base/message_loop.h" -#include "base/scoped_temp_dir.h" -#include "base/values.h" -#include "chrome/browser/browser_thread.h" -#include "chrome/browser/policy/proto/cloud_policy.pb.h" -#include "chrome/browser/policy/proto/device_management_backend.pb.h" -// TODO(jkummerow): remove this import when removing old DMPC test cases. -#include "chrome/browser/policy/proto/device_management_constants.h" -#include "chrome/browser/policy/proto/device_management_local.pb.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace policy { - -// Decodes a CloudPolicySettings object into two maps with mandatory and -// recommended settings, respectively. The implementation is generated code -// in policy/cloud_policy_generated.cc. -void DecodePolicy(const em::CloudPolicySettings& policy, - ConfigurationPolicyProvider::PolicyMapType* mandatory, - ConfigurationPolicyProvider::PolicyMapType* recommended); - -// The implementations of these methods are in cloud_policy_generated.cc. -Value* DecodeIntegerValue(google::protobuf::int64 value); -ListValue* DecodeStringList(const em::StringList& string_list); - -// Tests the device management policy cache. -class CloudPolicyCacheTest : public testing::Test { - protected: - typedef ConfigurationPolicyProvider::PolicyMapType PolicyMapType; - - CloudPolicyCacheTest() - : loop_(MessageLoop::TYPE_UI), - ui_thread_(BrowserThread::UI, &loop_), - file_thread_(BrowserThread::FILE, &loop_) {} - - void SetUp() { - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - } - - void TearDown() { - loop_.RunAllPending(); - } - - // Creates a (signed) CloudPolicyResponse setting the given |homepage| and - // featuring the given |timestamp| (as issued by the server). - // Mildly hacky special feature: pass an empty string as |homepage| to get - // a completely empty policy. - em::CloudPolicyResponse* CreateHomepagePolicy( - const std::string& homepage, - const base::Time& timestamp, - const em::PolicyOptions::PolicyMode policy_mode) { - em::SignedCloudPolicyResponse signed_response; - if (homepage != "") { - em::CloudPolicySettings* settings = signed_response.mutable_settings(); - em::HomepageLocationProto* homepagelocation_proto = - settings->mutable_homepagelocation(); - homepagelocation_proto->set_homepagelocation(homepage); - homepagelocation_proto->mutable_policy_options()->set_mode(policy_mode); - } - signed_response.set_timestamp(timestamp.ToTimeT()); - std::string serialized_signed_response; - EXPECT_TRUE(signed_response.SerializeToString(&serialized_signed_response)); - - em::CloudPolicyResponse* response = new em::CloudPolicyResponse; - response->set_signed_response(serialized_signed_response); - // TODO(jkummerow): Set proper certificate_chain and signature (when - // implementing support for signature verification). - response->set_signature("TODO"); - response->add_certificate_chain("TODO"); - return response; - } - - void WritePolicy(const em::CloudPolicyResponse& policy) { - std::string data; - em::CachedCloudPolicyResponse cached_policy; - cached_policy.mutable_cloud_policy()->CopyFrom(policy); - EXPECT_TRUE(cached_policy.SerializeToString(&data)); - int size = static_cast<int>(data.size()); - EXPECT_EQ(size, file_util::WriteFile(test_file(), data.c_str(), size)); - } - - FilePath test_file() { - return temp_dir_.path().AppendASCII("CloudPolicyCacheTest"); - } - - bool Equals(const PolicyMapType& a, const PolicyMapType& b) const { - return CloudPolicyCache::Equals(a, b); - } - - MessageLoop loop_; - - private: - ScopedTempDir temp_dir_; - BrowserThread ui_thread_; - BrowserThread file_thread_; -}; - -TEST_F(CloudPolicyCacheTest, Equals) { - PolicyMapType a; - a.insert(std::make_pair(kPolicyHomepageLocation, - Value::CreateStringValue("aaa"))); - PolicyMapType a2; - a2.insert(std::make_pair(kPolicyHomepageLocation, - Value::CreateStringValue("aaa"))); - PolicyMapType b; - b.insert(std::make_pair(kPolicyHomepageLocation, - Value::CreateStringValue("bbb"))); - PolicyMapType c; - c.insert(std::make_pair(kPolicyHomepageLocation, - Value::CreateStringValue("aaa"))); - c.insert(std::make_pair(kPolicyHomepageIsNewTabPage, - Value::CreateBooleanValue(true))); - EXPECT_FALSE(Equals(a, b)); - EXPECT_FALSE(Equals(b, a)); - EXPECT_FALSE(Equals(a, c)); - EXPECT_FALSE(Equals(c, a)); - EXPECT_TRUE(Equals(a, a2)); - EXPECT_TRUE(Equals(a2, a)); - PolicyMapType empty1; - PolicyMapType empty2; - EXPECT_TRUE(Equals(empty1, empty2)); - EXPECT_TRUE(Equals(empty2, empty1)); - EXPECT_FALSE(Equals(empty1, a)); - EXPECT_FALSE(Equals(a, empty1)); -} - -TEST_F(CloudPolicyCacheTest, DecodePolicy) { - em::CloudPolicySettings settings; - settings.mutable_homepagelocation()->set_homepagelocation("chromium.org"); - settings.mutable_javascriptenabled()->set_javascriptenabled(true); - settings.mutable_javascriptenabled()->mutable_policy_options()->set_mode( - em::PolicyOptions::MANDATORY); - settings.mutable_policyrefreshrate()->set_policyrefreshrate(5); - settings.mutable_policyrefreshrate()->mutable_policy_options()->set_mode( - em::PolicyOptions::RECOMMENDED); - PolicyMapType mandatory_policy; - PolicyMapType recommended_policy; - DecodePolicy(settings, &mandatory_policy, &recommended_policy); - PolicyMapType mandatory; - mandatory.insert(std::make_pair(kPolicyHomepageLocation, - Value::CreateStringValue("chromium.org"))); - mandatory.insert(std::make_pair(kPolicyJavascriptEnabled, - Value::CreateBooleanValue(true))); - PolicyMapType recommended; - recommended.insert(std::make_pair(kPolicyPolicyRefreshRate, - Value::CreateIntegerValue(5))); - EXPECT_TRUE(Equals(mandatory, mandatory_policy)); - EXPECT_TRUE(Equals(recommended, recommended_policy)); -} - -TEST_F(CloudPolicyCacheTest, DecodeIntegerValue) { - const int min = std::numeric_limits<int>::min(); - const int max = std::numeric_limits<int>::max(); - scoped_ptr<Value> value( - DecodeIntegerValue(static_cast<google::protobuf::int64>(42))); - ASSERT_TRUE(value.get()); - EXPECT_TRUE(value->Equals(Value::CreateIntegerValue(42))); - value.reset( - DecodeIntegerValue(static_cast<google::protobuf::int64>(min - 1LL))); - EXPECT_EQ(NULL, value.get()); - value.reset(DecodeIntegerValue(static_cast<google::protobuf::int64>(min))); - ASSERT_TRUE(value.get()); - EXPECT_TRUE(value->Equals(Value::CreateIntegerValue(min))); - value.reset( - DecodeIntegerValue(static_cast<google::protobuf::int64>(max + 1LL))); - EXPECT_EQ(NULL, value.get()); - value.reset(DecodeIntegerValue(static_cast<google::protobuf::int64>(max))); - ASSERT_TRUE(value.get()); - EXPECT_TRUE(value->Equals(Value::CreateIntegerValue(max))); -} - -TEST_F(CloudPolicyCacheTest, DecodeStringList) { - em::StringList string_list; - string_list.add_entries("ponies"); - string_list.add_entries("more ponies"); - scoped_ptr<ListValue> decoded(DecodeStringList(string_list)); - ListValue expected; - expected.Append(Value::CreateStringValue("ponies")); - expected.Append(Value::CreateStringValue("more ponies")); - EXPECT_TRUE(decoded->Equals(&expected)); -} - -TEST_F(CloudPolicyCacheTest, Empty) { - CloudPolicyCache cache(test_file()); - PolicyMapType empty; - EXPECT_TRUE(Equals(empty, *cache.GetMandatoryPolicy())); - EXPECT_TRUE(Equals(empty, *cache.GetRecommendedPolicy())); - EXPECT_EQ(base::Time(), cache.last_policy_refresh_time()); -} - -TEST_F(CloudPolicyCacheTest, LoadNoFile) { - CloudPolicyCache cache(test_file()); - cache.LoadPolicyFromFile(); - PolicyMapType empty; - EXPECT_TRUE(Equals(empty, *cache.GetMandatoryPolicy())); - EXPECT_EQ(base::Time(), cache.last_policy_refresh_time()); -} - -TEST_F(CloudPolicyCacheTest, RejectFuture) { - scoped_ptr<em::CloudPolicyResponse> policy_response( - CreateHomepagePolicy("", base::Time::NowFromSystemTime() + - base::TimeDelta::FromMinutes(5), - em::PolicyOptions::MANDATORY)); - WritePolicy(*policy_response); - CloudPolicyCache cache(test_file()); - cache.LoadPolicyFromFile(); - PolicyMapType empty; - EXPECT_TRUE(Equals(empty, *cache.GetMandatoryPolicy())); - EXPECT_EQ(base::Time(), cache.last_policy_refresh_time()); -} - -TEST_F(CloudPolicyCacheTest, LoadWithFile) { - scoped_ptr<em::CloudPolicyResponse> policy_response( - CreateHomepagePolicy("", base::Time::NowFromSystemTime(), - em::PolicyOptions::MANDATORY)); - WritePolicy(*policy_response); - CloudPolicyCache cache(test_file()); - cache.LoadPolicyFromFile(); - PolicyMapType empty; - EXPECT_TRUE(Equals(empty, *cache.GetMandatoryPolicy())); - EXPECT_NE(base::Time(), cache.last_policy_refresh_time()); - EXPECT_GE(base::Time::Now(), cache.last_policy_refresh_time()); -} - -TEST_F(CloudPolicyCacheTest, LoadWithData) { - scoped_ptr<em::CloudPolicyResponse> policy( - CreateHomepagePolicy("http://www.example.com", - base::Time::NowFromSystemTime(), - em::PolicyOptions::MANDATORY)); - WritePolicy(*policy); - CloudPolicyCache cache(test_file()); - cache.LoadPolicyFromFile(); - PolicyMapType expected; - expected.insert( - std::make_pair(kPolicyHomepageLocation, - Value::CreateStringValue("http://www.example.com"))); - EXPECT_TRUE(Equals(expected, *cache.GetMandatoryPolicy())); -} - -TEST_F(CloudPolicyCacheTest, SetPolicy) { - CloudPolicyCache cache(test_file()); - scoped_ptr<em::CloudPolicyResponse> policy( - CreateHomepagePolicy("http://www.example.com", - base::Time::NowFromSystemTime(), - em::PolicyOptions::MANDATORY)); - EXPECT_TRUE(cache.SetPolicy(*policy)); - scoped_ptr<em::CloudPolicyResponse> policy2( - CreateHomepagePolicy("http://www.example.com", - base::Time::NowFromSystemTime(), - em::PolicyOptions::MANDATORY)); - EXPECT_FALSE(cache.SetPolicy(*policy2)); - PolicyMapType expected; - expected.insert( - std::make_pair(kPolicyHomepageLocation, - Value::CreateStringValue("http://www.example.com"))); - PolicyMapType empty; - EXPECT_TRUE(Equals(expected, *cache.GetMandatoryPolicy())); - EXPECT_TRUE(Equals(empty, *cache.GetRecommendedPolicy())); - policy.reset(CreateHomepagePolicy("http://www.example.com", - base::Time::NowFromSystemTime(), - em::PolicyOptions::RECOMMENDED)); - EXPECT_TRUE(cache.SetPolicy(*policy)); - EXPECT_TRUE(Equals(expected, *cache.GetRecommendedPolicy())); - EXPECT_TRUE(Equals(empty, *cache.GetMandatoryPolicy())); -} - -TEST_F(CloudPolicyCacheTest, ResetPolicy) { - CloudPolicyCache cache(test_file()); - - scoped_ptr<em::CloudPolicyResponse> policy( - CreateHomepagePolicy("http://www.example.com", - base::Time::NowFromSystemTime(), - em::PolicyOptions::MANDATORY)); - EXPECT_TRUE(cache.SetPolicy(*policy)); - PolicyMapType expected; - expected.insert( - std::make_pair(kPolicyHomepageLocation, - Value::CreateStringValue("http://www.example.com"))); - EXPECT_TRUE(Equals(expected, *cache.GetMandatoryPolicy())); - - scoped_ptr<em::CloudPolicyResponse> empty_policy( - CreateHomepagePolicy("", base::Time::NowFromSystemTime(), - em::PolicyOptions::MANDATORY)); - EXPECT_TRUE(cache.SetPolicy(*empty_policy)); - PolicyMapType empty; - EXPECT_TRUE(Equals(empty, *cache.GetMandatoryPolicy())); -} - -TEST_F(CloudPolicyCacheTest, PersistPolicy) { - { - CloudPolicyCache cache(test_file()); - scoped_ptr<em::CloudPolicyResponse> policy( - CreateHomepagePolicy("http://www.example.com", - base::Time::NowFromSystemTime(), - em::PolicyOptions::MANDATORY)); - cache.SetPolicy(*policy); - } - - loop_.RunAllPending(); - - EXPECT_TRUE(file_util::PathExists(test_file())); - CloudPolicyCache cache(test_file()); - cache.LoadPolicyFromFile(); - PolicyMapType expected; - expected.insert( - std::make_pair(kPolicyHomepageLocation, - Value::CreateStringValue("http://www.example.com"))); - EXPECT_TRUE(Equals(expected, *cache.GetMandatoryPolicy())); -} - -TEST_F(CloudPolicyCacheTest, FreshPolicyOverride) { - scoped_ptr<em::CloudPolicyResponse> policy( - CreateHomepagePolicy("http://www.example.com", - base::Time::NowFromSystemTime(), - em::PolicyOptions::MANDATORY)); - WritePolicy(*policy); - - CloudPolicyCache cache(test_file()); - scoped_ptr<em::CloudPolicyResponse> updated_policy( - CreateHomepagePolicy("http://www.chromium.org", - base::Time::NowFromSystemTime(), - em::PolicyOptions::MANDATORY)); - EXPECT_TRUE(cache.SetPolicy(*updated_policy)); - - cache.LoadPolicyFromFile(); - PolicyMapType expected; - expected.insert( - std::make_pair(kPolicyHomepageLocation, - Value::CreateStringValue("http://www.chromium.org"))); - EXPECT_TRUE(Equals(expected, *cache.GetMandatoryPolicy())); -} - -} // namespace policy - -// ================================================================== -// Everything below this line can go when we phase out support for -// the old (trusted testing/pilot program) policy format. - -// This is a (slightly updated) copy of the old -// device_management_policy_cache_unittest.cc. The new CloudPolicyCache -// supports the old DMPC's interface for now (until it is phased out), so for -// this transitional period, we keep these old test cases but apply them to the -// new implementation (CPC). - -namespace policy { - -// Wraps base functionaly for the test cases. -class DeviceManagementPolicyCacheTestBase : public testing::Test { - protected: - // Add a string policy setting to a policy response message. - void AddStringPolicy(em::DevicePolicyResponse* policy, - const std::string& name, - const std::string& value) { - em::DevicePolicySetting* setting = policy->add_setting(); - setting->set_policy_key(kChromeDevicePolicySettingKey); - em::GenericSetting* policy_value = setting->mutable_policy_value(); - em::GenericNamedValue* named_value = policy_value->add_named_value(); - named_value->set_name(name); - em::GenericValue* value_container = named_value->mutable_value(); - value_container->set_value_type(em::GenericValue::VALUE_TYPE_STRING); - value_container->set_string_value(value); - } -}; - -// Tests the device management policy cache. -class DeviceManagementPolicyCacheTest - : public DeviceManagementPolicyCacheTestBase { - protected: - DeviceManagementPolicyCacheTest() - : loop_(MessageLoop::TYPE_UI), - ui_thread_(BrowserThread::UI, &loop_), - file_thread_(BrowserThread::FILE, &loop_) {} - - void SetUp() { - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - } - - void TearDown() { - loop_.RunAllPending(); - } - - void WritePolicy(const em::DevicePolicyResponse& policy, - const base::Time& timestamp) { - std::string data; - em::CachedCloudPolicyResponse cached_policy; - cached_policy.mutable_device_policy()->CopyFrom(policy); - cached_policy.set_timestamp(timestamp.ToTimeT()); - EXPECT_TRUE(cached_policy.SerializeToString(&data)); - int size = static_cast<int>(data.size()); - EXPECT_EQ(size, file_util::WriteFile(test_file(), data.c_str(), size)); - } - - FilePath test_file() { - return temp_dir_.path().AppendASCII("DeviceManagementPolicyCacheTest"); - } - - protected: - MessageLoop loop_; - - private: - ScopedTempDir temp_dir_; - BrowserThread ui_thread_; - BrowserThread file_thread_; -}; - -TEST_F(DeviceManagementPolicyCacheTest, Empty) { - CloudPolicyCache cache(test_file()); - DictionaryValue empty; - scoped_ptr<Value> policy(cache.GetDevicePolicy()); - EXPECT_TRUE(empty.Equals(policy.get())); - EXPECT_EQ(base::Time(), cache.last_policy_refresh_time()); -} - -TEST_F(DeviceManagementPolicyCacheTest, LoadNoFile) { - CloudPolicyCache cache(test_file()); - cache.LoadPolicyFromFile(); - DictionaryValue empty; - scoped_ptr<Value> policy(cache.GetDevicePolicy()); - EXPECT_TRUE(empty.Equals(policy.get())); - EXPECT_EQ(base::Time(), cache.last_policy_refresh_time()); -} - -TEST_F(DeviceManagementPolicyCacheTest, RejectFuture) { - em::DevicePolicyResponse policy_response; - WritePolicy(policy_response, base::Time::NowFromSystemTime() + - base::TimeDelta::FromMinutes(5)); - CloudPolicyCache cache(test_file()); - cache.LoadPolicyFromFile(); - DictionaryValue empty; - scoped_ptr<Value> policy(cache.GetDevicePolicy()); - EXPECT_TRUE(empty.Equals(policy.get())); - EXPECT_EQ(base::Time(), cache.last_policy_refresh_time()); -} - -TEST_F(DeviceManagementPolicyCacheTest, LoadWithFile) { - em::DevicePolicyResponse policy_response; - WritePolicy(policy_response, base::Time::NowFromSystemTime()); - CloudPolicyCache cache(test_file()); - cache.LoadPolicyFromFile(); - DictionaryValue empty; - scoped_ptr<Value> policy(cache.GetDevicePolicy()); - EXPECT_TRUE(empty.Equals(policy.get())); - EXPECT_NE(base::Time(), cache.last_policy_refresh_time()); - EXPECT_GE(base::Time::Now(), cache.last_policy_refresh_time()); -} - -TEST_F(DeviceManagementPolicyCacheTest, LoadWithData) { - em::DevicePolicyResponse policy; - AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com"); - WritePolicy(policy, base::Time::NowFromSystemTime()); - CloudPolicyCache cache(test_file()); - cache.LoadPolicyFromFile(); - DictionaryValue expected; - expected.Set("HomepageLocation", - Value::CreateStringValue("http://www.example.com")); - scoped_ptr<Value> policy_value(cache.GetDevicePolicy()); - EXPECT_TRUE(expected.Equals(policy_value.get())); -} - -TEST_F(DeviceManagementPolicyCacheTest, SetDevicePolicy) { - CloudPolicyCache cache(test_file()); - em::DevicePolicyResponse policy; - AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com"); - EXPECT_TRUE(cache.SetDevicePolicy(policy)); - em::DevicePolicyResponse policy2; - AddStringPolicy(&policy2, "HomepageLocation", "http://www.example.com"); - EXPECT_FALSE(cache.SetDevicePolicy(policy2)); - DictionaryValue expected; - expected.Set("HomepageLocation", - Value::CreateStringValue("http://www.example.com")); - scoped_ptr<Value> policy_value(cache.GetDevicePolicy()); - EXPECT_TRUE(expected.Equals(policy_value.get())); -} - -TEST_F(DeviceManagementPolicyCacheTest, ResetPolicy) { - CloudPolicyCache cache(test_file()); - - em::DevicePolicyResponse policy; - AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com"); - EXPECT_TRUE(cache.SetDevicePolicy(policy)); - DictionaryValue expected; - expected.Set("HomepageLocation", - Value::CreateStringValue("http://www.example.com")); - scoped_ptr<Value> policy_value(cache.GetDevicePolicy()); - EXPECT_TRUE(expected.Equals(policy_value.get())); - - EXPECT_TRUE(cache.SetDevicePolicy(em::DevicePolicyResponse())); - policy_value.reset(cache.GetDevicePolicy()); - DictionaryValue empty; - EXPECT_TRUE(empty.Equals(policy_value.get())); -} - -TEST_F(DeviceManagementPolicyCacheTest, PersistPolicy) { - { - CloudPolicyCache cache(test_file()); - em::DevicePolicyResponse policy; - AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com"); - cache.SetDevicePolicy(policy); - } - - loop_.RunAllPending(); - - EXPECT_TRUE(file_util::PathExists(test_file())); - CloudPolicyCache cache(test_file()); - cache.LoadPolicyFromFile(); - DictionaryValue expected; - expected.Set("HomepageLocation", - Value::CreateStringValue("http://www.example.com")); - scoped_ptr<Value> policy_value(cache.GetDevicePolicy()); - EXPECT_TRUE(expected.Equals(policy_value.get())); -} - -TEST_F(DeviceManagementPolicyCacheTest, FreshPolicyOverride) { - em::DevicePolicyResponse policy; - AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com"); - WritePolicy(policy, base::Time::NowFromSystemTime()); - - CloudPolicyCache cache(test_file()); - em::DevicePolicyResponse updated_policy; - AddStringPolicy(&updated_policy, "HomepageLocation", - "http://www.chromium.org"); - EXPECT_TRUE(cache.SetDevicePolicy(updated_policy)); - - cache.LoadPolicyFromFile(); - DictionaryValue expected; - expected.Set("HomepageLocation", - Value::CreateStringValue("http://www.chromium.org")); - scoped_ptr<Value> policy_value(cache.GetDevicePolicy()); - EXPECT_TRUE(expected.Equals(policy_value.get())); -} - -// Tests proper decoding of policy values. -class DeviceManagementPolicyCacheDecodeTest - : public DeviceManagementPolicyCacheTestBase { - protected: - void DecodeAndCheck(Value* expected_value_ptr) { - scoped_ptr<Value> expected_value(expected_value_ptr); - scoped_ptr<Value> decoded_value( - CloudPolicyCache::DecodeValue(value_)); - if (expected_value_ptr) { - ASSERT_TRUE(decoded_value.get()); - EXPECT_TRUE(decoded_value->Equals(expected_value.get())); - } else { - ASSERT_FALSE(decoded_value.get()); - } - } - - DictionaryValue* DecodeDevicePolicy(const em::DevicePolicyResponse policy) { - return CloudPolicyCache::DecodeDevicePolicy(policy); - } - - em::GenericValue value_; -}; - -TEST_F(DeviceManagementPolicyCacheDecodeTest, Bool) { - value_.set_value_type(em::GenericValue::VALUE_TYPE_BOOL); - value_.set_bool_value(true); - DecodeAndCheck(Value::CreateBooleanValue(true)); -} - -TEST_F(DeviceManagementPolicyCacheDecodeTest, Int64) { - value_.set_value_type(em::GenericValue::VALUE_TYPE_INT64); - value_.set_int64_value(42); - DecodeAndCheck(Value::CreateIntegerValue(42)); -} - -TEST_F(DeviceManagementPolicyCacheDecodeTest, Int64Overflow) { - const int min = std::numeric_limits<int>::min(); - const int max = std::numeric_limits<int>::max(); - value_.set_value_type(em::GenericValue::VALUE_TYPE_INT64); - value_.set_int64_value(min - 1LL); - DecodeAndCheck(NULL); - value_.set_int64_value(max + 1LL); - DecodeAndCheck(NULL); - value_.set_int64_value(min); - DecodeAndCheck(Value::CreateIntegerValue(min)); - value_.set_int64_value(max); - DecodeAndCheck(Value::CreateIntegerValue(max)); -} - -TEST_F(DeviceManagementPolicyCacheDecodeTest, String) { - value_.set_value_type(em::GenericValue::VALUE_TYPE_STRING); - value_.set_string_value("ponies!"); - DecodeAndCheck(Value::CreateStringValue("ponies!")); -} - -TEST_F(DeviceManagementPolicyCacheDecodeTest, Double) { - value_.set_value_type(em::GenericValue::VALUE_TYPE_DOUBLE); - value_.set_double_value(0.42L); - DecodeAndCheck(Value::CreateDoubleValue(0.42L)); -} - -TEST_F(DeviceManagementPolicyCacheDecodeTest, Bytes) { - std::string data("binary ponies."); - value_.set_value_type(em::GenericValue::VALUE_TYPE_BYTES); - value_.set_bytes_value(data); - DecodeAndCheck( - BinaryValue::CreateWithCopiedBuffer(data.c_str(), data.size())); -} - -TEST_F(DeviceManagementPolicyCacheDecodeTest, BoolArray) { - value_.set_value_type(em::GenericValue::VALUE_TYPE_BOOL_ARRAY); - value_.add_bool_array(false); - value_.add_bool_array(true); - ListValue* list = new ListValue; - list->Append(Value::CreateBooleanValue(false)); - list->Append(Value::CreateBooleanValue(true)); - DecodeAndCheck(list); -} - -TEST_F(DeviceManagementPolicyCacheDecodeTest, Int64Array) { - value_.set_value_type(em::GenericValue::VALUE_TYPE_INT64_ARRAY); - value_.add_int64_array(42); - value_.add_int64_array(17); - ListValue* list = new ListValue; - list->Append(Value::CreateIntegerValue(42)); - list->Append(Value::CreateIntegerValue(17)); - DecodeAndCheck(list); -} - -TEST_F(DeviceManagementPolicyCacheDecodeTest, StringArray) { - value_.set_value_type(em::GenericValue::VALUE_TYPE_STRING_ARRAY); - value_.add_string_array("ponies"); - value_.add_string_array("more ponies"); - ListValue* list = new ListValue; - list->Append(Value::CreateStringValue("ponies")); - list->Append(Value::CreateStringValue("more ponies")); - DecodeAndCheck(list); -} - -TEST_F(DeviceManagementPolicyCacheDecodeTest, DoubleArray) { - value_.set_value_type(em::GenericValue::VALUE_TYPE_DOUBLE_ARRAY); - value_.add_double_array(0.42L); - value_.add_double_array(0.17L); - ListValue* list = new ListValue; - list->Append(Value::CreateDoubleValue(0.42L)); - list->Append(Value::CreateDoubleValue(0.17L)); - DecodeAndCheck(list); -} - -TEST_F(DeviceManagementPolicyCacheDecodeTest, DecodePolicy) { - em::DevicePolicyResponse policy; - AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com"); - scoped_ptr<Value> decoded(DecodeDevicePolicy(policy)); - DictionaryValue expected; - expected.Set("HomepageLocation", - Value::CreateStringValue("http://www.example.com")); - EXPECT_TRUE(expected.Equals(decoded.get())); -} - -} // namespace policy diff --git a/chrome/browser/policy/configuration_policy_provider.cc b/chrome/browser/policy/configuration_policy_provider.cc index 21190ee9..82ca864 100644 --- a/chrome/browser/policy/configuration_policy_provider.cc +++ b/chrome/browser/policy/configuration_policy_provider.cc @@ -21,7 +21,7 @@ bool ConfigurationPolicyProvider::IsInitializationComplete() const { return true; } -void ConfigurationPolicyProvider::ApplyPolicyValueTree( +void ConfigurationPolicyProvider::DecodePolicyValueTree( const DictionaryValue* policies, ConfigurationPolicyStoreInterface* store) { const PolicyDefinitionList* policy_list(policy_definition_list()); @@ -36,19 +36,6 @@ void ConfigurationPolicyProvider::ApplyPolicyValueTree( // supports it. } -void ConfigurationPolicyProvider::ApplyPolicyMap( - const PolicyMapType* policies, - ConfigurationPolicyStoreInterface* store) { - const PolicyDefinitionList* policy_list(policy_definition_list()); - for (const PolicyDefinitionList::Entry* i = policy_list->begin; - i != policy_list->end; ++i) { - PolicyMapType::const_iterator it = - policies->find(i->policy_type); - if (it != policies->end() && it->second->IsType(i->value_type)) - store->Apply(i->policy_type, it->second->DeepCopy()); - } -} - // Class ConfigurationPolicyObserverRegistrar. ConfigurationPolicyObserverRegistrar::ConfigurationPolicyObserverRegistrar() diff --git a/chrome/browser/policy/configuration_policy_provider.h b/chrome/browser/policy/configuration_policy_provider.h index 4eedab6..af2cddf 100644 --- a/chrome/browser/policy/configuration_policy_provider.h +++ b/chrome/browser/policy/configuration_policy_provider.h @@ -6,14 +6,12 @@ #define CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_PROVIDER_H_ #pragma once -#include <map> #include <string> #include "base/basictypes.h" #include "base/scoped_ptr.h" #include "base/values.h" #include "chrome/browser/policy/configuration_policy_store_interface.h" -#include "policy/configuration_policy_type.h" namespace policy { @@ -22,8 +20,6 @@ namespace policy { // etc.) should implement a subclass of this class. class ConfigurationPolicyProvider { public: - typedef std::map<ConfigurationPolicyType, Value*> PolicyMapType; - class Observer { public: virtual ~Observer() {} @@ -63,14 +59,9 @@ class ConfigurationPolicyProvider { protected: // Decodes the value tree and writes the configuration to the given |store|. - void ApplyPolicyValueTree(const DictionaryValue* policies, + void DecodePolicyValueTree(const DictionaryValue* policies, ConfigurationPolicyStoreInterface* store); - // Writes the configuration found in the already-decoded map |policies| to - // the given |store|. - void ApplyPolicyMap(const PolicyMapType* policies, - ConfigurationPolicyStoreInterface* store); - const PolicyDefinitionList* policy_definition_list() const { return policy_definition_list_; } diff --git a/chrome/browser/policy/configuration_policy_store_interface.h b/chrome/browser/policy/configuration_policy_store_interface.h index 1d3bf43..d3261a3 100644 --- a/chrome/browser/policy/configuration_policy_store_interface.h +++ b/chrome/browser/policy/configuration_policy_store_interface.h @@ -7,6 +7,8 @@ #pragma once #include "base/basictypes.h" +// configuration_policy_type.h is generated. See policy_template.json for +// policy definitions. #include "policy/configuration_policy_type.h" class Value; diff --git a/chrome/browser/policy/device_management_backend.h b/chrome/browser/policy/device_management_backend.h index f2fec0d..114c7b7 100644 --- a/chrome/browser/policy/device_management_backend.h +++ b/chrome/browser/policy/device_management_backend.h @@ -75,12 +75,8 @@ class DeviceManagementBackend : base::NonThreadSafe { public: virtual ~DevicePolicyResponseDelegate() {} - // Deprecated in favor of HandleCloudPolicyResponse. To be removed once - // DMServer supports the new protocol. virtual void HandlePolicyResponse( const em::DevicePolicyResponse& response) = 0; - virtual void HandleCloudPolicyResponse( - const em::CloudPolicyResponse& response) = 0; virtual void OnError(ErrorCode code) = 0; protected: @@ -110,12 +106,6 @@ class DeviceManagementBackend : base::NonThreadSafe { const em::DevicePolicyRequest& request, DevicePolicyResponseDelegate* delegate) = 0; - virtual void ProcessCloudPolicyRequest( - const std::string& device_management_token, - const std::string& device_id, - const em::CloudPolicyRequest& request, - DevicePolicyResponseDelegate* delegate) = 0; - protected: DeviceManagementBackend() {} diff --git a/chrome/browser/policy/device_management_backend_impl.cc b/chrome/browser/policy/device_management_backend_impl.cc index b01cbf8..ed75f3f 100644 --- a/chrome/browser/policy/device_management_backend_impl.cc +++ b/chrome/browser/policy/device_management_backend_impl.cc @@ -27,8 +27,6 @@ const char DeviceManagementBackendImpl::kValueRequestRegister[] = "register"; const char DeviceManagementBackendImpl::kValueRequestUnregister[] = "unregister"; const char DeviceManagementBackendImpl::kValueRequestPolicy[] = "policy"; -const char DeviceManagementBackendImpl::kValueRequestCloudPolicy[] = - "cloud_policy"; const char DeviceManagementBackendImpl::kValueDeviceType[] = "Chrome OS"; const char DeviceManagementBackendImpl::kValueAppType[] = "Chrome"; @@ -172,10 +170,7 @@ void DeviceManagementJobBase::HandleResponse( } if (response_code != 200) { - if (response_code == 400) - OnError(DeviceManagementBackend::kErrorRequestInvalid); - else - OnError(DeviceManagementBackend::kErrorHttpStatus); + OnError(DeviceManagementBackend::kErrorHttpStatus); return; } @@ -235,17 +230,7 @@ class DeviceManagementRegisterJob : public DeviceManagementJobBase { const std::string& auth_token, const std::string& device_id, const em::DeviceRegisterRequest& request, - DeviceManagementBackend::DeviceRegisterResponseDelegate* delegate) - : DeviceManagementJobBase( - backend_impl, - DeviceManagementBackendImpl::kValueRequestRegister, - device_id), - delegate_(delegate) { - SetAuthToken(auth_token); - em::DeviceManagementRequest request_wrapper; - request_wrapper.mutable_register_request()->CopyFrom(request); - SetPayload(request_wrapper); - } + DeviceManagementBackend::DeviceRegisterResponseDelegate* delegate); virtual ~DeviceManagementRegisterJob() {} private: @@ -262,25 +247,32 @@ class DeviceManagementRegisterJob : public DeviceManagementJobBase { DISALLOW_COPY_AND_ASSIGN(DeviceManagementRegisterJob); }; +DeviceManagementRegisterJob::DeviceManagementRegisterJob( + DeviceManagementBackendImpl* backend_impl, + const std::string& auth_token, + const std::string& device_id, + const em::DeviceRegisterRequest& request, + DeviceManagementBackend::DeviceRegisterResponseDelegate* delegate) + : DeviceManagementJobBase( + backend_impl, + DeviceManagementBackendImpl::kValueRequestRegister, + device_id), + delegate_(delegate) { + SetAuthToken(auth_token); + em::DeviceManagementRequest request_wrapper; + request_wrapper.mutable_register_request()->CopyFrom(request); + SetPayload(request_wrapper); +} + // Handles device unregistration jobs. class DeviceManagementUnregisterJob : public DeviceManagementJobBase { public: DeviceManagementUnregisterJob( DeviceManagementBackendImpl* backend_impl, - const std::string& device_management_token, const std::string& device_id, + const std::string& device_management_token, const em::DeviceUnregisterRequest& request, - DeviceManagementBackend::DeviceUnregisterResponseDelegate* delegate) - : DeviceManagementJobBase( - backend_impl, - DeviceManagementBackendImpl::kValueRequestUnregister, - device_id), - delegate_(delegate) { - SetDeviceManagementToken(device_management_token); - em::DeviceManagementRequest request_wrapper; - request_wrapper.mutable_unregister_request()->CopyFrom(request); - SetPayload(request_wrapper); - } + DeviceManagementBackend::DeviceUnregisterResponseDelegate* delegate); virtual ~DeviceManagementUnregisterJob() {} private: @@ -297,6 +289,23 @@ class DeviceManagementUnregisterJob : public DeviceManagementJobBase { DISALLOW_COPY_AND_ASSIGN(DeviceManagementUnregisterJob); }; +DeviceManagementUnregisterJob::DeviceManagementUnregisterJob( + DeviceManagementBackendImpl* backend_impl, + const std::string& device_management_token, + const std::string& device_id, + const em::DeviceUnregisterRequest& request, + DeviceManagementBackend::DeviceUnregisterResponseDelegate* delegate) + : DeviceManagementJobBase( + backend_impl, + DeviceManagementBackendImpl::kValueRequestUnregister, + device_id), + delegate_(delegate) { + SetDeviceManagementToken(device_management_token); + em::DeviceManagementRequest request_wrapper; + request_wrapper.mutable_unregister_request()->CopyFrom(request); + SetPayload(request_wrapper); +} + // Handles policy request jobs. class DeviceManagementPolicyJob : public DeviceManagementJobBase { public: @@ -305,17 +314,7 @@ class DeviceManagementPolicyJob : public DeviceManagementJobBase { const std::string& device_management_token, const std::string& device_id, const em::DevicePolicyRequest& request, - DeviceManagementBackend::DevicePolicyResponseDelegate* delegate) - : DeviceManagementJobBase( - backend_impl, - DeviceManagementBackendImpl::kValueRequestPolicy, - device_id), - delegate_(delegate) { - SetDeviceManagementToken(device_management_token); - em::DeviceManagementRequest request_wrapper; - request_wrapper.mutable_policy_request()->CopyFrom(request); - SetPayload(request_wrapper); - } + DeviceManagementBackend::DevicePolicyResponseDelegate* delegate); virtual ~DeviceManagementPolicyJob() {} private: @@ -332,40 +331,22 @@ class DeviceManagementPolicyJob : public DeviceManagementJobBase { DISALLOW_COPY_AND_ASSIGN(DeviceManagementPolicyJob); }; -// Handles cloud policy request jobs. -class CloudPolicyJob : public DeviceManagementJobBase { - public: - CloudPolicyJob( - DeviceManagementBackendImpl* backend_impl, - const std::string& device_management_token, - const std::string& device_id, - const em::CloudPolicyRequest& request, - DeviceManagementBackend::DevicePolicyResponseDelegate* delegate) - : DeviceManagementJobBase( +DeviceManagementPolicyJob::DeviceManagementPolicyJob( + DeviceManagementBackendImpl* backend_impl, + const std::string& device_management_token, + const std::string& device_id, + const em::DevicePolicyRequest& request, + DeviceManagementBackend::DevicePolicyResponseDelegate* delegate) + : DeviceManagementJobBase( backend_impl, - DeviceManagementBackendImpl::kValueRequestCloudPolicy, + DeviceManagementBackendImpl::kValueRequestPolicy, device_id), - delegate_(delegate) { - SetDeviceManagementToken(device_management_token); - em::DeviceManagementRequest request_wrapper; - request_wrapper.mutable_cloud_policy_request()->CopyFrom(request); - SetPayload(request_wrapper); - } - virtual ~CloudPolicyJob() {} - - private: - // DeviceManagementJobBase overrides. - virtual void OnError(DeviceManagementBackend::ErrorCode error) { - delegate_->OnError(error); - } - virtual void OnResponse(const em::DeviceManagementResponse& response) { - delegate_->HandleCloudPolicyResponse(response.cloud_policy_response()); - } - - DeviceManagementBackend::DevicePolicyResponseDelegate* delegate_; - - DISALLOW_COPY_AND_ASSIGN(CloudPolicyJob); -}; + delegate_(delegate) { + SetDeviceManagementToken(device_management_token); + em::DeviceManagementRequest request_wrapper; + request_wrapper.mutable_policy_request()->CopyFrom(request); + SetPayload(request_wrapper); +} DeviceManagementBackendImpl::DeviceManagementBackendImpl( DeviceManagementService* service) @@ -428,13 +409,4 @@ void DeviceManagementBackendImpl::ProcessPolicyRequest( request, delegate)); } -void DeviceManagementBackendImpl::ProcessCloudPolicyRequest( - const std::string& device_management_token, - const std::string& device_id, - const em::CloudPolicyRequest& request, - DevicePolicyResponseDelegate* delegate) { - AddJob(new CloudPolicyJob(this, device_management_token, device_id, - request, delegate)); -} - } // namespace policy diff --git a/chrome/browser/policy/device_management_backend_impl.h b/chrome/browser/policy/device_management_backend_impl.h index 40c7e11..d818b4d 100644 --- a/chrome/browser/policy/device_management_backend_impl.h +++ b/chrome/browser/policy/device_management_backend_impl.h @@ -36,10 +36,7 @@ class DeviceManagementBackendImpl : public DeviceManagementBackend { // String constants for the device and app type we report to the server. static const char kValueRequestRegister[]; static const char kValueRequestUnregister[]; - // Deprecated in favor of kValueRequestCloudPolicy. - // See DevicePolicyResponseDelegate::HandlePolicyResponse. static const char kValueRequestPolicy[]; - static const char kValueRequestCloudPolicy[]; static const char kValueDeviceType[]; static const char kValueAppType[]; @@ -66,18 +63,11 @@ class DeviceManagementBackendImpl : public DeviceManagementBackend { const std::string& device_id, const em::DeviceUnregisterRequest& request, DeviceUnregisterResponseDelegate* response_delegate); - // Deprecated in favor of ProcessCloudPolicyRequest. - // See DevicePolicyResponseDelegate::HandlePolicyResponse. virtual void ProcessPolicyRequest( const std::string& device_management_token, const std::string& device_id, const em::DevicePolicyRequest& request, DevicePolicyResponseDelegate* response_delegate); - virtual void ProcessCloudPolicyRequest( - const std::string& device_management_token, - const std::string& device_id, - const em::CloudPolicyRequest& request, - DevicePolicyResponseDelegate* delegate); // Keeps track of the jobs currently in flight. JobSet pending_jobs_; diff --git a/chrome/browser/policy/device_management_backend_mock.h b/chrome/browser/policy/device_management_backend_mock.h index 01ac14d..0533efc 100644 --- a/chrome/browser/policy/device_management_backend_mock.h +++ b/chrome/browser/policy/device_management_backend_mock.h @@ -40,7 +40,6 @@ class DevicePolicyResponseDelegateMock virtual ~DevicePolicyResponseDelegateMock(); MOCK_METHOD1(HandlePolicyResponse, void(const em::DevicePolicyResponse&)); - MOCK_METHOD1(HandleCloudPolicyResponse, void(const em::CloudPolicyResponse&)); MOCK_METHOD1(OnError, void(DeviceManagementBackend::ErrorCode error)); }; diff --git a/chrome/browser/policy/device_management_policy_cache.cc b/chrome/browser/policy/device_management_policy_cache.cc new file mode 100644 index 0000000..ef8e6e1 --- /dev/null +++ b/chrome/browser/policy/device_management_policy_cache.cc @@ -0,0 +1,270 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/policy/device_management_policy_cache.h" + +#include <limits> +#include <string> + +#include "base/file_util.h" +#include "base/logging.h" +#include "base/task.h" +#include "base/values.h" +#include "chrome/browser/browser_thread.h" +#include "chrome/browser/policy/proto/device_management_constants.h" +#include "chrome/browser/policy/proto/device_management_local.pb.h" + +using google::protobuf::RepeatedField; +using google::protobuf::RepeatedPtrField; + +namespace policy { + +// Saves policy information to a file. +class PersistPolicyTask : public Task { + public: + PersistPolicyTask(const FilePath& path, + const em::DevicePolicyResponse* policy, + const base::Time& timestamp, + const bool is_device_unmanaged) + : path_(path), + policy_(policy), + timestamp_(timestamp), + is_device_unmanaged_(is_device_unmanaged) {} + + private: + // Task override. + virtual void Run(); + + const FilePath path_; + scoped_ptr<const em::DevicePolicyResponse> policy_; + const base::Time timestamp_; + const bool is_device_unmanaged_; +}; + +void PersistPolicyTask::Run() { + std::string data; + em::CachedDevicePolicyResponse cached_policy; + if (policy_.get()) + cached_policy.mutable_policy()->CopyFrom(*policy_); + if (is_device_unmanaged_) + cached_policy.set_unmanaged(true); + cached_policy.set_timestamp(timestamp_.ToInternalValue()); + if (!cached_policy.SerializeToString(&data)) { + LOG(WARNING) << "Failed to serialize policy data"; + return; + } + + int size = data.size(); + if (file_util::WriteFile(path_, data.c_str(), size) != size) { + LOG(WARNING) << "Failed to write " << path_.value(); + return; + } +} + +DeviceManagementPolicyCache::DeviceManagementPolicyCache( + const FilePath& backing_file_path) + : backing_file_path_(backing_file_path), + policy_(new DictionaryValue), + fresh_policy_(false), + is_device_unmanaged_(false) { +} + +DeviceManagementPolicyCache::~DeviceManagementPolicyCache() {} + +void DeviceManagementPolicyCache::LoadPolicyFromFile() { + if (!file_util::PathExists(backing_file_path_) || fresh_policy_) + return; + + // Read the protobuf from the file. + std::string data; + if (!file_util::ReadFileToString(backing_file_path_, &data)) { + LOG(WARNING) << "Failed to read policy data from " + << backing_file_path_.value(); + return; + } + + em::CachedDevicePolicyResponse cached_policy; + if (!cached_policy.ParseFromArray(data.c_str(), data.size())) { + LOG(WARNING) << "Failed to parse policy data read from " + << backing_file_path_.value(); + return; + } + + // Reject files that claim to be from the future. + base::Time timestamp = base::Time::FromInternalValue( + cached_policy.timestamp()); + if (timestamp > base::Time::NowFromSystemTime()) { + LOG(WARNING) << "Rejected policy data from " << backing_file_path_.value() + << ", file is from the future."; + return; + } + is_device_unmanaged_ = cached_policy.unmanaged(); + + // Decode and swap in the new policy information. + scoped_ptr<DictionaryValue> value(DecodePolicy(cached_policy.policy())); + { + base::AutoLock lock(lock_); + if (!fresh_policy_) + policy_.reset(value.release()); + last_policy_refresh_time_ = timestamp; + } +} + +bool DeviceManagementPolicyCache::SetPolicy( + const em::DevicePolicyResponse& policy) { + is_device_unmanaged_ = false; + DictionaryValue* value = DeviceManagementPolicyCache::DecodePolicy(policy); + const bool new_policy_differs = !(value->Equals(policy_.get())); + base::Time now(base::Time::NowFromSystemTime()); + { + base::AutoLock lock(lock_); + policy_.reset(value); + fresh_policy_ = true; + last_policy_refresh_time_ = now; + } + + em::DevicePolicyResponse* policy_copy = new em::DevicePolicyResponse; + policy_copy->CopyFrom(policy); + BrowserThread::PostTask( + BrowserThread::FILE, + FROM_HERE, + new PersistPolicyTask(backing_file_path_, policy_copy, now, false)); + return new_policy_differs; +} + +DictionaryValue* DeviceManagementPolicyCache::GetPolicy() { + base::AutoLock lock(lock_); + return policy_->DeepCopy(); +} + +void DeviceManagementPolicyCache::SetDeviceUnmanaged() { + is_device_unmanaged_ = true; + base::Time now(base::Time::NowFromSystemTime()); + { + base::AutoLock lock(lock_); + policy_.reset(new DictionaryValue); + last_policy_refresh_time_ = now; + } + BrowserThread::PostTask( + BrowserThread::FILE, + FROM_HERE, + new PersistPolicyTask(backing_file_path_, NULL, now, true)); +} + +// static +Value* DeviceManagementPolicyCache::DecodeIntegerValue( + google::protobuf::int64 value) { + if (value < std::numeric_limits<int>::min() || + value > std::numeric_limits<int>::max()) { + LOG(WARNING) << "Integer value " << value + << " out of numeric limits, ignoring."; + return NULL; + } + + return Value::CreateIntegerValue(static_cast<int>(value)); +} + +// static +Value* DeviceManagementPolicyCache::DecodeValue(const em::GenericValue& value) { + if (!value.has_value_type()) + return NULL; + + switch (value.value_type()) { + case em::GenericValue::VALUE_TYPE_BOOL: + if (value.has_bool_value()) + return Value::CreateBooleanValue(value.bool_value()); + return NULL; + case em::GenericValue::VALUE_TYPE_INT64: + if (value.has_int64_value()) + return DecodeIntegerValue(value.int64_value()); + return NULL; + case em::GenericValue::VALUE_TYPE_STRING: + if (value.has_string_value()) + return Value::CreateStringValue(value.string_value()); + return NULL; + case em::GenericValue::VALUE_TYPE_DOUBLE: + if (value.has_double_value()) + return Value::CreateDoubleValue(value.double_value()); + return NULL; + case em::GenericValue::VALUE_TYPE_BYTES: + if (value.has_bytes_value()) { + std::string bytes = value.bytes_value(); + return BinaryValue::CreateWithCopiedBuffer(bytes.c_str(), bytes.size()); + } + return NULL; + case em::GenericValue::VALUE_TYPE_BOOL_ARRAY: { + ListValue* list = new ListValue; + RepeatedField<bool>::const_iterator i; + for (i = value.bool_array().begin(); i != value.bool_array().end(); ++i) + list->Append(Value::CreateBooleanValue(*i)); + return list; + } + case em::GenericValue::VALUE_TYPE_INT64_ARRAY: { + ListValue* list = new ListValue; + RepeatedField<google::protobuf::int64>::const_iterator i; + for (i = value.int64_array().begin(); + i != value.int64_array().end(); ++i) { + Value* int_value = DecodeIntegerValue(*i); + if (int_value) + list->Append(int_value); + } + return list; + } + case em::GenericValue::VALUE_TYPE_STRING_ARRAY: { + ListValue* list = new ListValue; + RepeatedPtrField<std::string>::const_iterator i; + for (i = value.string_array().begin(); + i != value.string_array().end(); ++i) + list->Append(Value::CreateStringValue(*i)); + return list; + } + case em::GenericValue::VALUE_TYPE_DOUBLE_ARRAY: { + ListValue* list = new ListValue; + RepeatedField<double>::const_iterator i; + for (i = value.double_array().begin(); + i != value.double_array().end(); ++i) + list->Append(Value::CreateDoubleValue(*i)); + return list; + } + default: + NOTREACHED() << "Unhandled value type"; + } + + return NULL; +} + +// static +DictionaryValue* DeviceManagementPolicyCache::DecodePolicy( + const em::DevicePolicyResponse& policy) { + DictionaryValue* result = new DictionaryValue; + RepeatedPtrField<em::DevicePolicySetting>::const_iterator setting; + for (setting = policy.setting().begin(); + setting != policy.setting().end(); + ++setting) { + // Wrong policy key? Skip. + if (setting->policy_key().compare(kChromeDevicePolicySettingKey) != 0) + continue; + + // No policy value? Skip. + if (!setting->has_policy_value()) + continue; + + // Iterate through all the name-value pairs wrapped in |setting|. + const em::GenericSetting& policy_value(setting->policy_value()); + RepeatedPtrField<em::GenericNamedValue>::const_iterator named_value; + for (named_value = policy_value.named_value().begin(); + named_value != policy_value.named_value().end(); + ++named_value) { + if (named_value->has_value()) { + Value* decoded_value = + DeviceManagementPolicyCache::DecodeValue(named_value->value()); + if (decoded_value) + result->Set(named_value->name(), decoded_value); + } + } + } + return result; +} + +} // namespace policy diff --git a/chrome/browser/policy/device_management_policy_cache.h b/chrome/browser/policy/device_management_policy_cache.h new file mode 100644 index 0000000..50441eb --- /dev/null +++ b/chrome/browser/policy/device_management_policy_cache.h @@ -0,0 +1,94 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_POLICY_DEVICE_MANAGEMENT_POLICY_CACHE_H_ +#define CHROME_BROWSER_POLICY_DEVICE_MANAGEMENT_POLICY_CACHE_H_ + +#include "base/file_path.h" +#include "base/gtest_prod_util.h" +#include "base/ref_counted.h" +#include "base/scoped_ptr.h" +#include "base/synchronization/lock.h" +#include "base/time.h" +#include "chrome/browser/policy/proto/device_management_backend.pb.h" + +class DictionaryValue; +class Value; + +namespace policy { + +namespace em = enterprise_management; + +// Keeps the authoritative copy of cloud policy information as read from the +// persistence file or determined by the policy backend. The cache doesn't talk +// to the service directly, but receives updated policy information through +// SetPolicy() calls, which is then persisted and decoded into the internal +// Value representation chrome uses. +class DeviceManagementPolicyCache { + public: + explicit DeviceManagementPolicyCache(const FilePath& backing_file_path); + ~DeviceManagementPolicyCache(); + + // Loads policy information from the backing file. Non-existing or erroneous + // cache files are ignored. + void LoadPolicyFromFile(); + + // Resets the policy information. Returns true if the new policy is different + // from the previously stored policy. + bool SetPolicy(const em::DevicePolicyResponse& policy); + + // Gets the policy information. Ownership of the return value is transferred + // to the caller. + DictionaryValue* GetPolicy(); + + void SetDeviceUnmanaged(); + bool is_device_unmanaged() const { + return is_device_unmanaged_; + } + + // Returns the time as which the policy was last fetched. + base::Time last_policy_refresh_time() const { + return last_policy_refresh_time_; + } + + private: + friend class DeviceManagementPolicyCacheDecodeTest; + FRIEND_TEST_ALL_PREFIXES(DeviceManagementPolicyCacheDecodeTest, DecodePolicy); + + // Decodes an int64 value. Checks whether the passed value fits the numeric + // limits of the value representation. Returns a value (ownership is + // transferred to the caller) on success, NULL on failure. + static Value* DecodeIntegerValue(google::protobuf::int64 value); + + // Decode a GenericValue message to the Value representation used internally. + // Returns NULL if |value| is invalid (i.e. contains no actual value). + static Value* DecodeValue(const em::GenericValue& value); + + // Decodes a policy message and returns it in Value representation. Ownership + // of the returned dictionary is transferred to the caller. + static DictionaryValue* DecodePolicy( + const em::DevicePolicyResponse& response); + + // The file in which we store a cached version of the policy information. + const FilePath backing_file_path_; + + // Protects |policy_|. + base::Lock lock_; + + // Policy key-value information. + scoped_ptr<DictionaryValue> policy_; + + // Tracks whether the store received a SetPolicy() call, which overrides any + // information loaded from the file. + bool fresh_policy_; + + bool is_device_unmanaged_; + + // The time at which the policy was last refreshed. + base::Time last_policy_refresh_time_; +}; + +} // namespace policy + +#endif // CHROME_BROWSER_POLICY_DEVICE_MANAGEMENT_POLICY_CACHE_H_ diff --git a/chrome/browser/policy/device_management_policy_cache_unittest.cc b/chrome/browser/policy/device_management_policy_cache_unittest.cc new file mode 100644 index 0000000..1fe98c8 --- /dev/null +++ b/chrome/browser/policy/device_management_policy_cache_unittest.cc @@ -0,0 +1,321 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/policy/device_management_policy_cache.h" + +#include <limits> +#include <string> + +#include "base/file_util.h" +#include "base/message_loop.h" +#include "base/scoped_temp_dir.h" +#include "base/values.h" +#include "chrome/browser/browser_thread.h" +#include "chrome/browser/policy/proto/device_management_constants.h" +#include "chrome/browser/policy/proto/device_management_local.pb.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace policy { + +// Wraps base functionaly for the test cases. +class DeviceManagementPolicyCacheTestBase : public testing::Test { + protected: + // Add a string policy setting to a policy response message. + void AddStringPolicy(em::DevicePolicyResponse* policy, + const std::string& name, + const std::string& value) { + em::DevicePolicySetting* setting = policy->add_setting(); + setting->set_policy_key(kChromeDevicePolicySettingKey); + em::GenericSetting* policy_value = setting->mutable_policy_value(); + em::GenericNamedValue* named_value = policy_value->add_named_value(); + named_value->set_name(name); + em::GenericValue* value_container = named_value->mutable_value(); + value_container->set_value_type(em::GenericValue::VALUE_TYPE_STRING); + value_container->set_string_value(value); + } +}; + +// Tests the device management policy cache. +class DeviceManagementPolicyCacheTest + : public DeviceManagementPolicyCacheTestBase { + protected: + DeviceManagementPolicyCacheTest() + : loop_(MessageLoop::TYPE_UI), + ui_thread_(BrowserThread::UI, &loop_), + file_thread_(BrowserThread::FILE, &loop_) {} + + void SetUp() { + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); + } + + void TearDown() { + loop_.RunAllPending(); + } + + void WritePolicy(const em::DevicePolicyResponse& policy, + const base::Time& timestamp) { + std::string data; + em::CachedDevicePolicyResponse cached_policy; + cached_policy.mutable_policy()->CopyFrom(policy); + cached_policy.set_timestamp(timestamp.ToInternalValue()); + EXPECT_TRUE(cached_policy.SerializeToString(&data)); + int size = static_cast<int>(data.size()); + EXPECT_EQ(size, file_util::WriteFile(test_file(), data.c_str(), size)); + } + + FilePath test_file() { + return temp_dir_.path().AppendASCII("DeviceManagementPolicyCacheTest"); + } + + protected: + MessageLoop loop_; + + private: + ScopedTempDir temp_dir_; + BrowserThread ui_thread_; + BrowserThread file_thread_; +}; + +TEST_F(DeviceManagementPolicyCacheTest, Empty) { + DeviceManagementPolicyCache cache(test_file()); + DictionaryValue empty; + scoped_ptr<Value> policy(cache.GetPolicy()); + EXPECT_TRUE(empty.Equals(policy.get())); + EXPECT_EQ(base::Time(), cache.last_policy_refresh_time()); +} + +TEST_F(DeviceManagementPolicyCacheTest, LoadNoFile) { + DeviceManagementPolicyCache cache(test_file()); + cache.LoadPolicyFromFile(); + DictionaryValue empty; + scoped_ptr<Value> policy(cache.GetPolicy()); + EXPECT_TRUE(empty.Equals(policy.get())); + EXPECT_EQ(base::Time(), cache.last_policy_refresh_time()); +} + +TEST_F(DeviceManagementPolicyCacheTest, RejectFuture) { + em::DevicePolicyResponse policy_response; + WritePolicy(policy_response, base::Time::NowFromSystemTime() + + base::TimeDelta::FromMinutes(5)); + DeviceManagementPolicyCache cache(test_file()); + cache.LoadPolicyFromFile(); + DictionaryValue empty; + scoped_ptr<Value> policy(cache.GetPolicy()); + EXPECT_TRUE(empty.Equals(policy.get())); + EXPECT_EQ(base::Time(), cache.last_policy_refresh_time()); +} + +TEST_F(DeviceManagementPolicyCacheTest, LoadWithFile) { + em::DevicePolicyResponse policy_response; + WritePolicy(policy_response, base::Time::NowFromSystemTime()); + DeviceManagementPolicyCache cache(test_file()); + cache.LoadPolicyFromFile(); + DictionaryValue empty; + scoped_ptr<Value> policy(cache.GetPolicy()); + EXPECT_TRUE(empty.Equals(policy.get())); + EXPECT_NE(base::Time(), cache.last_policy_refresh_time()); + EXPECT_GE(base::Time::Now(), cache.last_policy_refresh_time()); +} + +TEST_F(DeviceManagementPolicyCacheTest, LoadWithData) { + em::DevicePolicyResponse policy; + AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com"); + WritePolicy(policy, base::Time::NowFromSystemTime()); + DeviceManagementPolicyCache cache(test_file()); + cache.LoadPolicyFromFile(); + DictionaryValue expected; + expected.Set("HomepageLocation", + Value::CreateStringValue("http://www.example.com")); + scoped_ptr<Value> policy_value(cache.GetPolicy()); + EXPECT_TRUE(expected.Equals(policy_value.get())); +} + +TEST_F(DeviceManagementPolicyCacheTest, SetPolicy) { + DeviceManagementPolicyCache cache(test_file()); + em::DevicePolicyResponse policy; + AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com"); + EXPECT_TRUE(cache.SetPolicy(policy)); + em::DevicePolicyResponse policy2; + AddStringPolicy(&policy2, "HomepageLocation", "http://www.example.com"); + EXPECT_FALSE(cache.SetPolicy(policy2)); + DictionaryValue expected; + expected.Set("HomepageLocation", + Value::CreateStringValue("http://www.example.com")); + scoped_ptr<Value> policy_value(cache.GetPolicy()); + EXPECT_TRUE(expected.Equals(policy_value.get())); +} + +TEST_F(DeviceManagementPolicyCacheTest, ResetPolicy) { + DeviceManagementPolicyCache cache(test_file()); + + em::DevicePolicyResponse policy; + AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com"); + EXPECT_TRUE(cache.SetPolicy(policy)); + DictionaryValue expected; + expected.Set("HomepageLocation", + Value::CreateStringValue("http://www.example.com")); + scoped_ptr<Value> policy_value(cache.GetPolicy()); + EXPECT_TRUE(expected.Equals(policy_value.get())); + + EXPECT_TRUE(cache.SetPolicy(em::DevicePolicyResponse())); + policy_value.reset(cache.GetPolicy()); + DictionaryValue empty; + EXPECT_TRUE(empty.Equals(policy_value.get())); +} + +TEST_F(DeviceManagementPolicyCacheTest, PersistPolicy) { + { + DeviceManagementPolicyCache cache(test_file()); + em::DevicePolicyResponse policy; + AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com"); + cache.SetPolicy(policy); + } + + loop_.RunAllPending(); + + EXPECT_TRUE(file_util::PathExists(test_file())); + DeviceManagementPolicyCache cache(test_file()); + cache.LoadPolicyFromFile(); + DictionaryValue expected; + expected.Set("HomepageLocation", + Value::CreateStringValue("http://www.example.com")); + scoped_ptr<Value> policy_value(cache.GetPolicy()); + EXPECT_TRUE(expected.Equals(policy_value.get())); +} + +TEST_F(DeviceManagementPolicyCacheTest, FreshPolicyOverride) { + em::DevicePolicyResponse policy; + AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com"); + WritePolicy(policy, base::Time::NowFromSystemTime()); + + DeviceManagementPolicyCache cache(test_file()); + em::DevicePolicyResponse updated_policy; + AddStringPolicy(&updated_policy, "HomepageLocation", + "http://www.chromium.org"); + EXPECT_TRUE(cache.SetPolicy(updated_policy)); + + cache.LoadPolicyFromFile(); + DictionaryValue expected; + expected.Set("HomepageLocation", + Value::CreateStringValue("http://www.chromium.org")); + scoped_ptr<Value> policy_value(cache.GetPolicy()); + EXPECT_TRUE(expected.Equals(policy_value.get())); +} + +// Tests proper decoding of policy values. +class DeviceManagementPolicyCacheDecodeTest + : public DeviceManagementPolicyCacheTestBase { + protected: + void DecodeAndCheck(Value* expected_value_ptr) { + scoped_ptr<Value> expected_value(expected_value_ptr); + scoped_ptr<Value> decoded_value( + DeviceManagementPolicyCache::DecodeValue(value_)); + if (expected_value_ptr) { + ASSERT_TRUE(decoded_value.get()); + EXPECT_TRUE(decoded_value->Equals(expected_value.get())); + } else { + ASSERT_FALSE(decoded_value.get()); + } + } + + em::GenericValue value_; +}; + +TEST_F(DeviceManagementPolicyCacheDecodeTest, Bool) { + value_.set_value_type(em::GenericValue::VALUE_TYPE_BOOL); + value_.set_bool_value(true); + DecodeAndCheck(Value::CreateBooleanValue(true)); +} + +TEST_F(DeviceManagementPolicyCacheDecodeTest, Int64) { + value_.set_value_type(em::GenericValue::VALUE_TYPE_INT64); + value_.set_int64_value(42); + DecodeAndCheck(Value::CreateIntegerValue(42)); +} + +TEST_F(DeviceManagementPolicyCacheDecodeTest, Int64Overflow) { + const int min = std::numeric_limits<int>::min(); + const int max = std::numeric_limits<int>::max(); + value_.set_value_type(em::GenericValue::VALUE_TYPE_INT64); + value_.set_int64_value(min - 1LL); + DecodeAndCheck(NULL); + value_.set_int64_value(max + 1LL); + DecodeAndCheck(NULL); + value_.set_int64_value(min); + DecodeAndCheck(Value::CreateIntegerValue(min)); + value_.set_int64_value(max); + DecodeAndCheck(Value::CreateIntegerValue(max)); +} + +TEST_F(DeviceManagementPolicyCacheDecodeTest, String) { + value_.set_value_type(em::GenericValue::VALUE_TYPE_STRING); + value_.set_string_value("ponies!"); + DecodeAndCheck(Value::CreateStringValue("ponies!")); +} + +TEST_F(DeviceManagementPolicyCacheDecodeTest, Double) { + value_.set_value_type(em::GenericValue::VALUE_TYPE_DOUBLE); + value_.set_double_value(0.42L); + DecodeAndCheck(Value::CreateDoubleValue(0.42L)); +} + +TEST_F(DeviceManagementPolicyCacheDecodeTest, Bytes) { + std::string data("binary ponies."); + value_.set_value_type(em::GenericValue::VALUE_TYPE_BYTES); + value_.set_bytes_value(data); + DecodeAndCheck( + BinaryValue::CreateWithCopiedBuffer(data.c_str(), data.size())); +} + +TEST_F(DeviceManagementPolicyCacheDecodeTest, BoolArray) { + value_.set_value_type(em::GenericValue::VALUE_TYPE_BOOL_ARRAY); + value_.add_bool_array(false); + value_.add_bool_array(true); + ListValue* list = new ListValue; + list->Append(Value::CreateBooleanValue(false)); + list->Append(Value::CreateBooleanValue(true)); + DecodeAndCheck(list); +} + +TEST_F(DeviceManagementPolicyCacheDecodeTest, Int64Array) { + value_.set_value_type(em::GenericValue::VALUE_TYPE_INT64_ARRAY); + value_.add_int64_array(42); + value_.add_int64_array(17); + ListValue* list = new ListValue; + list->Append(Value::CreateIntegerValue(42)); + list->Append(Value::CreateIntegerValue(17)); + DecodeAndCheck(list); +} + +TEST_F(DeviceManagementPolicyCacheDecodeTest, StringArray) { + value_.set_value_type(em::GenericValue::VALUE_TYPE_STRING_ARRAY); + value_.add_string_array("ponies"); + value_.add_string_array("more ponies"); + ListValue* list = new ListValue; + list->Append(Value::CreateStringValue("ponies")); + list->Append(Value::CreateStringValue("more ponies")); + DecodeAndCheck(list); +} + +TEST_F(DeviceManagementPolicyCacheDecodeTest, DoubleArray) { + value_.set_value_type(em::GenericValue::VALUE_TYPE_DOUBLE_ARRAY); + value_.add_double_array(0.42L); + value_.add_double_array(0.17L); + ListValue* list = new ListValue; + list->Append(Value::CreateDoubleValue(0.42L)); + list->Append(Value::CreateDoubleValue(0.17L)); + DecodeAndCheck(list); +} + +TEST_F(DeviceManagementPolicyCacheDecodeTest, DecodePolicy) { + em::DevicePolicyResponse policy; + AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com"); + scoped_ptr<Value> decoded(DeviceManagementPolicyCache::DecodePolicy(policy)); + DictionaryValue expected; + expected.Set("HomepageLocation", + Value::CreateStringValue("http://www.example.com")); + EXPECT_TRUE(expected.Equals(decoded.get())); +} + +} // namespace policy diff --git a/chrome/browser/policy/device_management_policy_provider.cc b/chrome/browser/policy/device_management_policy_provider.cc index eaaf4d4..315a6d2 100644 --- a/chrome/browser/policy/device_management_policy_provider.cc +++ b/chrome/browser/policy/device_management_policy_provider.cc @@ -4,16 +4,14 @@ #include "chrome/browser/policy/device_management_policy_provider.h" -#include <algorithm> - #include "base/command_line.h" #include "base/file_util.h" #include "base/path_service.h" #include "base/rand_util.h" #include "base/task.h" #include "chrome/browser/browser_thread.h" -#include "chrome/browser/policy/cloud_policy_cache.h" #include "chrome/browser/policy/device_management_backend.h" +#include "chrome/browser/policy/device_management_policy_cache.h" #include "chrome/browser/policy/profile_policy_context.h" #include "chrome/browser/policy/proto/device_management_constants.h" #include "chrome/browser/profiles/profile.h" @@ -88,13 +86,8 @@ DeviceManagementPolicyProvider::~DeviceManagementPolicyProvider() { bool DeviceManagementPolicyProvider::Provide( ConfigurationPolicyStoreInterface* policy_store) { - if (cache_->has_device_policy()) { - scoped_ptr<DictionaryValue> policies(cache_->GetDevicePolicy()); - ApplyPolicyValueTree(policies.get(), policy_store); - } else { - ApplyPolicyMap(cache_->GetMandatoryPolicy(), policy_store); - // TODO(jkummerow, mnissler): provide recommended policy. - } + scoped_ptr<DictionaryValue> policies(cache_->GetPolicy()); + DecodePolicyValueTree(policies.get(), policy_store); return true; } @@ -105,23 +98,13 @@ bool DeviceManagementPolicyProvider::IsInitializationComplete() const { void DeviceManagementPolicyProvider::HandlePolicyResponse( const em::DevicePolicyResponse& response) { DCHECK(TokenAvailable()); - if (cache_->SetDevicePolicy(response)) { + if (cache_->SetPolicy(response)) { initial_fetch_done_ = true; NotifyCloudPolicyUpdate(); } SetState(STATE_POLICY_VALID); } -void DeviceManagementPolicyProvider::HandleCloudPolicyResponse( - const em::CloudPolicyResponse& response) { - DCHECK(TokenAvailable()); - if (cache_->SetPolicy(response)) { - initial_fetch_done_ = true; - NotifyCloudPolicyUpdate(); - } - SetState(STATE_POLICY_VALID); -} - void DeviceManagementPolicyProvider::OnError( DeviceManagementBackend::ErrorCode code) { DCHECK(TokenAvailable()); @@ -134,12 +117,6 @@ void DeviceManagementPolicyProvider::OnError( DeviceManagementBackend::kErrorServiceManagementNotSupported) { VLOG(1) << "The device is no longer managed, resetting device token."; SetState(STATE_TOKEN_RESET); - } else if (!fallback_to_old_protocol_ && - code == DeviceManagementBackend::kErrorRequestInvalid) { - LOG(WARNING) << "Device management server doesn't understand new protocol," - << " falling back to old request."; - fallback_to_old_protocol_ = true; - SetState(STATE_TOKEN_VALID); // Triggers SendPolicyRequest() immediately. } else { LOG(WARNING) << "Could not provide policy from the device manager (error = " << code << "), will retry in " @@ -163,7 +140,7 @@ void DeviceManagementPolicyProvider::OnTokenError() { void DeviceManagementPolicyProvider::OnNotManaged() { DCHECK(!TokenAvailable()); VLOG(1) << "This device is not managed."; - cache_->SetUnmanaged(); + cache_->SetDeviceUnmanaged(); SetState(STATE_UNMANAGED); } @@ -209,7 +186,6 @@ void DeviceManagementPolicyProvider::Initialize( DCHECK(profile); backend_.reset(backend); profile_ = profile; - fallback_to_old_protocol_ = false; storage_dir_ = GetOrCreateDeviceManagementDir(profile_->GetPath()); state_ = STATE_INITIALIZING; initial_fetch_done_ = false; @@ -225,13 +201,13 @@ void DeviceManagementPolicyProvider::Initialize( unmanaged_device_refresh_rate_ms_ = unmanaged_device_refresh_rate_ms; const FilePath policy_path = storage_dir_.Append(kPolicyFilename); - cache_.reset(new CloudPolicyCache(policy_path)); + cache_.reset(new DeviceManagementPolicyCache(policy_path)); cache_->LoadPolicyFromFile(); SetDeviceTokenFetcher(new DeviceTokenFetcher(backend_.get(), profile, GetTokenPath())); - if (cache_->is_unmanaged()) { + if (cache_->is_device_unmanaged()) { // This is a non-first login on an unmanaged device. SetState(STATE_UNMANAGED); } else { @@ -250,23 +226,15 @@ void DeviceManagementPolicyProvider::RemoveObserver( } void DeviceManagementPolicyProvider::SendPolicyRequest() { - if (!fallback_to_old_protocol_) { - em::CloudPolicyRequest policy_request; - policy_request.set_policy_scope(kChromePolicyScope); - backend_->ProcessCloudPolicyRequest(token_fetcher_->GetDeviceToken(), - token_fetcher_->GetDeviceID(), - policy_request, this); - } else { - em::DevicePolicyRequest policy_request; - policy_request.set_policy_scope(kChromePolicyScope); - em::DevicePolicySettingRequest* setting = - policy_request.add_setting_request(); - setting->set_key(kChromeDevicePolicySettingKey); - setting->set_watermark(""); - backend_->ProcessPolicyRequest(token_fetcher_->GetDeviceToken(), - token_fetcher_->GetDeviceID(), - policy_request, this); - } + em::DevicePolicyRequest policy_request; + policy_request.set_policy_scope(kChromePolicyScope); + em::DevicePolicySettingRequest* setting = + policy_request.add_setting_request(); + setting->set_key(kChromeDevicePolicySettingKey); + setting->set_watermark(""); + backend_->ProcessPolicyRequest(token_fetcher_->GetDeviceToken(), + token_fetcher_->GetDeviceID(), + policy_request, this); } void DeviceManagementPolicyProvider::RefreshTaskExecute() { diff --git a/chrome/browser/policy/device_management_policy_provider.h b/chrome/browser/policy/device_management_policy_provider.h index dd09628..592df9b 100644 --- a/chrome/browser/policy/device_management_policy_provider.h +++ b/chrome/browser/policy/device_management_policy_provider.h @@ -21,8 +21,8 @@ class TokenService; namespace policy { -class CloudPolicyCache; class DeviceManagementBackend; +class DeviceManagementPolicyCache; // Provides policy fetched from the device management server. With the exception // of the Provide method, which can be called on the FILE thread, all public @@ -44,9 +44,7 @@ class DeviceManagementPolicyProvider // DevicePolicyResponseDelegate implementation: virtual void HandlePolicyResponse( - const em::DevicePolicyResponse& response); // deprecated. - virtual void HandleCloudPolicyResponse( - const em::CloudPolicyResponse& response); + const em::DevicePolicyResponse& response); virtual void OnError(DeviceManagementBackend::ErrorCode code); // DeviceTokenFetcher::Observer implementation: @@ -148,8 +146,7 @@ class DeviceManagementPolicyProvider scoped_ptr<DeviceManagementBackend> backend_; Profile* profile_; // weak - scoped_ptr<CloudPolicyCache> cache_; - bool fallback_to_old_protocol_; + scoped_ptr<DeviceManagementPolicyCache> cache_; scoped_refptr<DeviceTokenFetcher> token_fetcher_; DeviceTokenFetcher::ObserverRegistrar registrar_; ObserverList<ConfigurationPolicyProvider::Observer, true> observer_list_; diff --git a/chrome/browser/policy/device_management_policy_provider_unittest.cc b/chrome/browser/policy/device_management_policy_provider_unittest.cc index 8dc3bf4..d0a0eaa 100644 --- a/chrome/browser/policy/device_management_policy_provider_unittest.cc +++ b/chrome/browser/policy/device_management_policy_provider_unittest.cc @@ -7,9 +7,9 @@ #include "base/scoped_temp_dir.h" #include "chrome/browser/browser_thread.h" #include "chrome/browser/net/gaia/token_service.h" -#include "chrome/browser/policy/cloud_policy_cache.h" #include "chrome/browser/policy/configuration_policy_pref_store.h" #include "chrome/browser/policy/configuration_policy_provider.h" +#include "chrome/browser/policy/device_management_policy_cache.h" #include "chrome/browser/policy/device_management_policy_provider.h" #include "chrome/browser/policy/mock_configuration_policy_store.h" #include "chrome/browser/policy/mock_device_management_backend.h" @@ -113,8 +113,9 @@ class DeviceManagementPolicyProviderTest : public testing::Test { MockConfigurationPolicyStore store; EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( MockDeviceManagementBackendSucceedRegister()); - EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( - MockDeviceManagementBackendSucceedSpdyCloudPolicy()); + EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( + MockDeviceManagementBackendSucceedBooleanPolicy( + key::kDisableSpdy, true)); SimulateSuccessfulLoginAndRunPending(); EXPECT_FALSE(waiting_for_initial_policies()); EXPECT_CALL(store, Apply(kPolicyDisableSpdy, _)).Times(1); @@ -137,7 +138,7 @@ class DeviceManagementPolicyProviderTest : public testing::Test { scoped_ptr<DeviceManagementPolicyProvider> provider_; protected: - CloudPolicyCache* cache(DeviceManagementPolicyProvider* provider) { + DeviceManagementPolicyCache* cache(DeviceManagementPolicyProvider* provider) { return provider->cache_.get(); } @@ -192,8 +193,9 @@ TEST_F(DeviceManagementPolicyProviderTest, SecondProvide) { // Simulate a app relaunch by constructing a new provider. Policy should be // refreshed (since that might be the purpose of the app relaunch). CreateNewProvider(); - EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( - MockDeviceManagementBackendSucceedSpdyCloudPolicy()); + EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( + MockDeviceManagementBackendSucceedBooleanPolicy( + key::kDisableSpdy, true)); loop_.RunAllPending(); Mock::VerifyAndClearExpectations(backend_); @@ -201,7 +203,7 @@ TEST_F(DeviceManagementPolicyProviderTest, SecondProvide) { // Cached policy should still be available. MockConfigurationPolicyStore store; CreateNewProvider(); - EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( + EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( MockDeviceManagementBackendFailPolicy( DeviceManagementBackend::kErrorRequestFailed)); SimulateSuccessfulLoginAndRunPending(); @@ -229,14 +231,15 @@ TEST_F(DeviceManagementPolicyProviderTest, ErrorCausesNewRequest) { DeviceManagementBackend::kErrorRequestFailed)); EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( MockDeviceManagementBackendSucceedRegister()); - EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( + EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( MockDeviceManagementBackendFailPolicy( DeviceManagementBackend::kErrorRequestFailed)); - EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( + EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( MockDeviceManagementBackendFailPolicy( DeviceManagementBackend::kErrorRequestFailed)); - EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( - MockDeviceManagementBackendSucceedSpdyCloudPolicy()); + EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( + MockDeviceManagementBackendSucceedBooleanPolicy(key::kDisableSpdy, + true)); } SimulateSuccessfulLoginAndRunPending(); } @@ -247,13 +250,16 @@ TEST_F(DeviceManagementPolicyProviderTest, RefreshPolicies) { CreateNewProvider(0, 0, 0, 1000 * 1000, 1000, 0); EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( MockDeviceManagementBackendSucceedRegister()); - EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( - MockDeviceManagementBackendSucceedSpdyCloudPolicy()); - EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( - MockDeviceManagementBackendSucceedSpdyCloudPolicy()); - EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( - MockDeviceManagementBackendSucceedSpdyCloudPolicy()); - EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( + EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( + MockDeviceManagementBackendSucceedBooleanPolicy(key::kDisableSpdy, + true)); + EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( + MockDeviceManagementBackendSucceedBooleanPolicy(key::kDisableSpdy, + true)); + EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( + MockDeviceManagementBackendSucceedBooleanPolicy(key::kDisableSpdy, + true)); + EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( MockDeviceManagementBackendFailPolicy( DeviceManagementBackend::kErrorRequestFailed)); } @@ -267,13 +273,14 @@ TEST_F(DeviceManagementPolicyProviderTest, DeviceNotFound) { InSequence s; EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( MockDeviceManagementBackendSucceedRegister()); - EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( + EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( MockDeviceManagementBackendFailPolicy( DeviceManagementBackend::kErrorServiceDeviceNotFound)); EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( MockDeviceManagementBackendSucceedRegister()); - EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( - MockDeviceManagementBackendSucceedSpdyCloudPolicy()); + EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( + MockDeviceManagementBackendSucceedBooleanPolicy(key::kDisableSpdy, + true)); } SimulateSuccessfulLoginAndRunPending(); } @@ -285,13 +292,14 @@ TEST_F(DeviceManagementPolicyProviderTest, InvalidTokenOnPolicyRequest) { InSequence s; EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( MockDeviceManagementBackendSucceedRegister()); - EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( + EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( MockDeviceManagementBackendFailPolicy( DeviceManagementBackend::kErrorServiceManagementTokenInvalid)); EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( MockDeviceManagementBackendSucceedRegister()); - EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( - MockDeviceManagementBackendSucceedSpdyCloudPolicy()); + EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( + MockDeviceManagementBackendSucceedBooleanPolicy(key::kDisableSpdy, + true)); } SimulateSuccessfulLoginAndRunPending(); } @@ -304,11 +312,13 @@ TEST_F(DeviceManagementPolicyProviderTest, DeviceNoLongerManaged) { CreateNewProvider(0, 0, 0, 0, 0, 1000 * 1000); EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( MockDeviceManagementBackendSucceedRegister()); - EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( - MockDeviceManagementBackendSucceedSpdyCloudPolicy()); - EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( - MockDeviceManagementBackendSucceedSpdyCloudPolicy()); - EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( + EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( + MockDeviceManagementBackendSucceedBooleanPolicy(key::kDisableSpdy, + true)); + EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( + MockDeviceManagementBackendSucceedBooleanPolicy(key::kDisableSpdy, + true)); + EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( MockDeviceManagementBackendFailPolicy( DeviceManagementBackend::kErrorServiceManagementNotSupported)); EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( @@ -331,7 +341,7 @@ TEST_F(DeviceManagementPolicyProviderTest, UnmanagedDevice) { SimulateSuccessfulLoginAndRunPending(); // (1) The provider's DMPolicyCache should know that the device is not // managed. - EXPECT_TRUE(cache(provider_.get())->is_unmanaged()); + EXPECT_TRUE(cache(provider_.get())->is_device_unmanaged()); // (2) On restart, the provider should detect that this is not the first // login. CreateNewProvider(1000 * 1000, 0, 0, 0, 0, 0); @@ -340,43 +350,14 @@ TEST_F(DeviceManagementPolicyProviderTest, UnmanagedDevice) { InSequence s; EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( MockDeviceManagementBackendSucceedRegister()); - EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( - MockDeviceManagementBackendSucceedSpdyCloudPolicy()); + EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( + MockDeviceManagementBackendSucceedBooleanPolicy(key::kDisableSpdy, + true)); } SimulateSuccessfulLoginAndRunPending(); // (3) Since the backend call this time returned a device id, the "unmanaged" // marker should have been deleted. - EXPECT_FALSE(cache(provider_.get())->is_unmanaged()); -} - -TEST_F(DeviceManagementPolicyProviderTest, FallbackToOldProtocol) { - { // Scoping so SimulateSuccessfulLoginAndRunPending doesn't see the sequence. - InSequence s; - CreateNewProvider(0, 0, 0, 0, 0, 1000 * 1000); - EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( - MockDeviceManagementBackendSucceedRegister()); - // If the CloudPolicyRequest fails with kErrorRequestInvalid... - EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( - MockDeviceManagementBackendFailPolicy( - DeviceManagementBackend::kErrorRequestInvalid)); - // ...the client should fall back to a classic PolicyRequest... - EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( - MockDeviceManagementBackendSucceedBooleanPolicy( - key::kDisableSpdy, true)); - // ...and remember this fallback for any future request, ... - EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( - MockDeviceManagementBackendFailPolicy( - DeviceManagementBackend::kErrorHttpStatus)); - // ...both after successful fetches and after errors. - EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( - MockDeviceManagementBackendFailPolicy( - DeviceManagementBackend::kErrorServiceManagementNotSupported)); - // Finally, we set the client to 'unmanaged' to stop its request stream. - EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( - MockDeviceManagementBackendFailRegister( - DeviceManagementBackend::kErrorServiceManagementNotSupported)); - } - SimulateSuccessfulLoginAndRunPending(); + EXPECT_FALSE(cache(provider_.get())->is_device_unmanaged()); } } // namespace policy diff --git a/chrome/browser/policy/mock_device_management_backend.h b/chrome/browser/policy/mock_device_management_backend.h index 54c8c8f..a684e4f 100644 --- a/chrome/browser/policy/mock_device_management_backend.h +++ b/chrome/browser/policy/mock_device_management_backend.h @@ -9,7 +9,6 @@ #include <map> #include <string> -#include "base/time.h" #include "base/values.h" #include "chrome/browser/policy/device_management_backend.h" #include "chrome/browser/policy/proto/device_management_constants.h" @@ -47,12 +46,6 @@ class MockDeviceManagementBackend : public DeviceManagementBackend { const em::DevicePolicyRequest& request, DevicePolicyResponseDelegate* delegate)); - MOCK_METHOD4(ProcessCloudPolicyRequest, void( - const std::string& device_management_token, - const std::string& device_id, - const em::CloudPolicyRequest& request, - DevicePolicyResponseDelegate* delegate)); - private: DISALLOW_COPY_AND_ASSIGN(MockDeviceManagementBackend); }; @@ -80,24 +73,6 @@ ACTION_P2(MockDeviceManagementBackendSucceedBooleanPolicy, name, value) { arg3->HandlePolicyResponse(response); } -ACTION(MockDeviceManagementBackendSucceedSpdyCloudPolicy) { - em::SignedCloudPolicyResponse signed_response; - em::CloudPolicySettings* settings = signed_response.mutable_settings(); - em::DisableSpdyProto* spdy_proto = settings->mutable_disablespdy(); - spdy_proto->set_disablespdy(true); - spdy_proto->mutable_policy_options()->set_mode(em::PolicyOptions::MANDATORY); - signed_response.set_timestamp(base::Time::NowFromSystemTime().ToTimeT()); - std::string serialized_signed_response; - EXPECT_TRUE(signed_response.SerializeToString(&serialized_signed_response)); - em::CloudPolicyResponse response; - response.set_signed_response(serialized_signed_response); - // TODO(jkummerow): Set proper certificate_chain and signature (when - // implementing support for signature verification). - response.set_signature("TODO"); - response.add_certificate_chain("TODO"); - arg3->HandleCloudPolicyResponse(response); -} - ACTION_P(MockDeviceManagementBackendFailRegister, error) { arg3->OnError(error); } diff --git a/chrome/browser/policy/profile_policy_context.cc b/chrome/browser/policy/profile_policy_context.cc index b8e3151a..7adffd3 100644 --- a/chrome/browser/policy/profile_policy_context.cc +++ b/chrome/browser/policy/profile_policy_context.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <algorithm> -#include <string> - #include "base/command_line.h" #include "chrome/browser/policy/configuration_policy_pref_store.h" #include "chrome/browser/policy/device_management_policy_provider.h" @@ -23,7 +20,7 @@ namespace { const int64 kPolicyRefreshRateMinMs = 30 * 60 * 1000; // 30 minutes const int64 kPolicyRefreshRateMaxMs = 24 * 60 * 60 * 1000; // 1 day -} // namespace +} namespace policy { diff --git a/chrome/browser/policy/proto/cloud_policy.proto b/chrome/browser/policy/proto/cloud_policy.proto new file mode 100644 index 0000000..82a1135 --- /dev/null +++ b/chrome/browser/policy/proto/cloud_policy.proto @@ -0,0 +1,221 @@ +// +// DO NOT MODIFY THIS FILE DIRECTLY! +// ITS IS GENERATED BY generate_policy_source.py +// FROM policy_templates.json +// + +syntax = "proto2"; + +option optimize_for = LITE_RUNTIME; + +package enterprise_management; + +// PBs for individual settings. + +message PolicyOptions { + enum PolicyMode { + // The user may choose to override the given settings. + RECOMMENDED = 1; + // The given settings are applied regardless of user choice. + MANDATORY = 2; + } + optional PolicyMode mode = 1; +} + +message HomepageProto { + optional PolicyOptions policy_options = 1; + optional string HomepageLocation = 2; + optional bool HomepageIsNewTabPage = 3; +} + +message ApplicationLocaleValueProto { + optional PolicyOptions policy_options = 1; + optional string ApplicationLocaleValue = 2; +} + +message AlternateErrorPagesEnabledProto { + optional PolicyOptions policy_options = 1; + optional bool AlternateErrorPagesEnabled = 2; +} + +message SearchSuggestEnabledProto { + optional PolicyOptions policy_options = 1; + optional bool SearchSuggestEnabled = 2; +} + +message DnsPrefetchingEnabledProto { + optional PolicyOptions policy_options = 1; + optional bool DnsPrefetchingEnabled = 2; +} + +message DisableSpdyProto { + optional PolicyOptions policy_options = 1; + optional bool DisableSpdy = 2; +} + +message JavascriptEnabledProto { + optional PolicyOptions policy_options = 1; + optional bool JavascriptEnabled = 2; +} + +message SavingBrowserHistoryDisabledProto { + optional PolicyOptions policy_options = 1; + optional bool SavingBrowserHistoryDisabled = 2; +} + +message PrintingEnabledProto { + optional PolicyOptions policy_options = 1; + optional bool PrintingEnabled = 2; +} + +message SafeBrowsingEnabledProto { + optional PolicyOptions policy_options = 1; + optional bool SafeBrowsingEnabled = 2; +} + +message MetricsReportingEnabledProto { + optional PolicyOptions policy_options = 1; + optional bool MetricsReportingEnabled = 2; +} + +message PasswordManagerProto { + optional PolicyOptions policy_options = 1; + optional bool PasswordManagerEnabled = 2; + optional bool PasswordManagerAllowShowPasswords = 3; +} + +message AutoFillEnabledProto { + optional PolicyOptions policy_options = 1; + optional bool AutoFillEnabled = 2; +} + +message DisabledPluginsProto { + optional PolicyOptions policy_options = 1; + repeated string DisabledPlugins = 2; +} + +message SyncDisabledProto { + optional PolicyOptions policy_options = 1; + optional bool SyncDisabled = 2; +} + +message ProxyProto { + optional PolicyOptions policy_options = 1; + optional string ProxyMode = 2; + optional int64 ProxyServerMode = 3; + optional string ProxyServer = 4; + optional string ProxyPacUrl = 5; + optional string ProxyBypassList = 6; +} + +message HTTPAuthenticationProto { + optional PolicyOptions policy_options = 1; + optional string AuthSchemes = 2; + optional bool DisableAuthNegotiateCnameLookup = 3; + optional bool EnableAuthNegotiatePort = 4; + optional string AuthServerWhitelist = 5; + optional string AuthNegotiateDelegateWhitelist = 6; + optional string GSSAPILibraryName = 7; +} + +message ExtensionsProto { + optional PolicyOptions policy_options = 1; + repeated string ExtensionInstallBlacklist = 2; + repeated string ExtensionInstallWhitelist = 3; + repeated string ExtensionInstallForcelist = 4; +} + +message ShowHomeButtonProto { + optional PolicyOptions policy_options = 1; + optional bool ShowHomeButton = 2; +} + +message DeveloperToolsDisabledProto { + optional PolicyOptions policy_options = 1; + optional bool DeveloperToolsDisabled = 2; +} + +message RestoreOnStartupGroupProto { + optional PolicyOptions policy_options = 1; + optional int64 RestoreOnStartup = 2; + repeated string RestoreOnStartupURLs = 3; +} + +message DefaultSearchProviderProto { + optional PolicyOptions policy_options = 1; + optional bool DefaultSearchProviderEnabled = 2; + optional string DefaultSearchProviderName = 3; + optional string DefaultSearchProviderKeyword = 4; + optional string DefaultSearchProviderSearchURL = 5; + optional string DefaultSearchProviderSuggestURL = 6; + optional string DefaultSearchProviderInstantURL = 7; + optional string DefaultSearchProviderIconURL = 8; + repeated string DefaultSearchProviderEncodings = 9; +} + +message ContentSettingsProto { + optional PolicyOptions policy_options = 1; + optional int64 DefaultCookiesSetting = 2; + optional int64 DefaultImagesSetting = 3; + optional int64 DefaultJavaScriptSetting = 4; + optional int64 DefaultPluginsSetting = 5; + optional int64 DefaultPopupsSetting = 6; + optional int64 DefaultNotificationSetting = 7; + optional int64 DefaultGeolocationSetting = 8; +} + +message Disable3DAPIsProto { + optional PolicyOptions policy_options = 1; + optional bool Disable3DAPIs = 2; +} + +message ChromeFrameRendererSettingsProto { + optional PolicyOptions policy_options = 1; + optional int64 ChromeFrameRendererSettings = 2; + repeated string RenderInChromeFrameList = 3; + repeated string RenderInHostList = 4; +} + +message ChromeFrameContentTypesProto { + optional PolicyOptions policy_options = 1; + repeated string ChromeFrameContentTypes = 2; +} + +message ChromeOsLockOnIdleSuspendProto { + optional PolicyOptions policy_options = 1; + optional bool ChromeOsLockOnIdleSuspend = 2; +} + + +// -------------------------------------------------- +// Wrapper PB for DMServer -> ChromeOS communication. + +message CloudPolicySettings { + optional HomepageProto Homepage = 1; + optional ApplicationLocaleValueProto ApplicationLocaleValue = 2; + optional AlternateErrorPagesEnabledProto AlternateErrorPagesEnabled = 3; + optional SearchSuggestEnabledProto SearchSuggestEnabled = 4; + optional DnsPrefetchingEnabledProto DnsPrefetchingEnabled = 5; + optional DisableSpdyProto DisableSpdy = 6; + optional JavascriptEnabledProto JavascriptEnabled = 7; + optional SavingBrowserHistoryDisabledProto SavingBrowserHistoryDisabled = 8; + optional PrintingEnabledProto PrintingEnabled = 9; + optional SafeBrowsingEnabledProto SafeBrowsingEnabled = 10; + optional MetricsReportingEnabledProto MetricsReportingEnabled = 11; + optional PasswordManagerProto PasswordManager = 12; + optional AutoFillEnabledProto AutoFillEnabled = 13; + optional DisabledPluginsProto DisabledPlugins = 14; + optional SyncDisabledProto SyncDisabled = 15; + optional ProxyProto Proxy = 16; + optional HTTPAuthenticationProto HTTPAuthentication = 17; + optional ExtensionsProto Extensions = 18; + optional ShowHomeButtonProto ShowHomeButton = 19; + optional DeveloperToolsDisabledProto DeveloperToolsDisabled = 20; + optional RestoreOnStartupGroupProto RestoreOnStartupGroup = 21; + optional DefaultSearchProviderProto DefaultSearchProvider = 22; + optional ContentSettingsProto ContentSettings = 23; + optional Disable3DAPIsProto Disable3DAPIs = 24; + optional ChromeFrameRendererSettingsProto ChromeFrameRendererSettings = 25; + optional ChromeFrameContentTypesProto ChromeFrameContentTypes = 26; + optional ChromeOsLockOnIdleSuspendProto ChromeOsLockOnIdleSuspend = 27; +} diff --git a/chrome/browser/policy/proto/device_management_backend.proto b/chrome/browser/policy/proto/device_management_backend.proto index 1a857b6..3187f6b 100644 --- a/chrome/browser/policy/proto/device_management_backend.proto +++ b/chrome/browser/policy/proto/device_management_backend.proto @@ -88,94 +88,62 @@ message DevicePolicyResponse { repeated DevicePolicySetting setting = 1; } -// Request from device to server to register device. The response will include -// a device token that can be used to query policies. -message DeviceRegisterRequest { - // reregister device without erasing server state. - // it can be used to refresh dmtoken etc. - optional bool reregister = 1; -} - -// Response from server to device register request. -message DeviceRegisterResponse { - // device mangement toke for this registration. - required string device_management_token = 1; -} - // Protocol buffers for the new protocol: // -------------------------------------- -// Request from device to server to get policies for an unregistered user. -// These are actually "meta-policies", that control the rules for the user -// about enrolling for real policies. -message InitialPolicyRequest { +// Request from device to server to query if the authenticated user is in a +// managed domain. +message ManagedCheckRequest { } -message InitialPolicySettings { - enum EnrollmentRule { - // The user must enroll its device for policies. +// Response from server to device indicating if the authenticated user is in a +// managed domain. +message ManagedCheckResponse { + enum Mode { + // The device must be enrolled for policies. MANAGED = 1; - // The users's device is not automatically enrolled for policies, but the - // user may choose to try to enroll it. + // The device is not automatically enrolled for policies, but the user + // may choose to try to enroll it. UNMANAGED = 2; } - optional EnrollmentRule enrollment_rule = 1; + optional Mode mode = 1; } -// Response from server to device containing the policies available before -// registration. -message InitialPolicyResponse { - optional InitialPolicySettings settings = 1; +// Request from device to server to register device. +message DeviceRegisterRequest { + // reregister device without erasing server state. + // it can be used to refresh dmtoken etc. + optional bool reregister = 1; } -// Request from device to server to unregister device management token. -message DeviceUnregisterRequest { -} +// Response from server to device register request. +message DeviceRegisterResponse { + // device mangement toke for this registration. + required string device_management_token = 1; -// Response from server to unregister request. -message DeviceUnregisterResponse { + // The name of the device, assigned by the server. + optional string device_name = 2; } -// Request from device to server to register device. The response will include -// a device token that can be used to query policies. -message CloudRegisterRequest { - enum Type { - // Requesting token for user policies. - USER = 1; - // Requesting token for device policies. - DEVICE = 2; - } - optional Type type = 1; - // Unique identifier of the machine. Only set if type == DEVICE. - // This won't be sent in later requests, the machine can be identified - // by its device token. - optional string machine_id = 2; +// Request from device to server to unregister device. +message DeviceUnregisterRequest { } -// Response from server to device register request. -message CloudRegisterResponse { - // Token for this registration. - required string device_management_token = 1; - - // The name of the requesting device, assigned by the server. - optional string machine_name = 2; +// Response from server to device unregister request. +message DeviceUnregisterResponse { } message CloudPolicyRequest { // Identify request scope: chromeos/device for device policies, chromeos/user - // for user policies. Only those policy scopes will be served, that are - // allowed by the type choice in CloudRegisterRequest. + // for user policies. optional string policy_scope = 1; - - // The token used to query device policies on the device sending the request. - // Note, that the token used for actual authentication is sent in an HTTP - // header. These two tokens are the same if this request is for querying - // device policies and they differ if this request is for querying user - // policies. In the second case, the server can use device_policy_token to - // identify the device and determine if the user is allowed to get policies - // on the given device. - optional string device_policy_token = 2; + // The device token of the owner of the device sending the request. In cases + // the request was sent by the device owner or device policies were + // requested, this is the same as the token used for authentication. + // Otherwise (if the user policy is requested for someone else than the device + // owner) this token is different from the token used for authentication. + optional string device_token = 2; } // Response from server to device for reading policies. @@ -208,20 +176,20 @@ message SignedCloudPolicyResponse { // // Http Query parameters: // Query parameters contain the following information in each request: -// request: register/unregister/policy/cloud_policy/cloud_register/ -// initial_policy +// request: register/unregister/policy/cloud_policy/managed_check etc. // devicetype: CrOS/Android/Iphone etc. // apptype: CrOS/AndroidDM etc. +// deviceid: unique id that identify the device. // agent: identify agent on device. // // Authorization: -// 1. If request is initial_policy, client must pass in GoogleLogin -// auth cookie in Authorization header: +// 1. If request is managed_check, client must pass in GoogleLogin auth +// cookie in Authorization header: // Authorization: GoogleLogin auth=<auth cookie> -// The response will contain settings that a user can get without -// registration. Currently the only such setting is a flag indicating if the -// user is in a managed domain or not. (We don't want to expose device ids of -// users not in managed domains.) +// This is the only case when the deviceid query parameter is set to empty. +// The response will contain a flag indicating if the user is in a managed +// domain or not. (We don't want to expose device ids of users not in +// managed domains.) // 2. If request is register_request, client must pass in GoogleLogin auth // cookie in Authorization header: // Authorization: GoogleLogin auth=<auth cookie> @@ -232,7 +200,7 @@ message SignedCloudPolicyResponse { // Authorization: GoogleDMToken token=<google dm token> // message DeviceManagementRequest { - // Register request (old protocol). + // Register request. optional DeviceRegisterRequest register_request = 1; // Unregister request. @@ -244,11 +212,8 @@ message DeviceManagementRequest { // Data request (new protocol). optional CloudPolicyRequest cloud_policy_request = 4; - // Request for initial (before registration) policies. - optional InitialPolicyRequest initial_policy_request = 5; - - // Register request (new protocol). - optional CloudRegisterRequest cloud_register_request = 6; + // Request to check if a user is managed or not. + optional ManagedCheckRequest managed_check_request = 5; } // Response from server to device. @@ -276,7 +241,7 @@ message DeviceManagementResponse { // Error message. optional string error_message = 2; - // Register response (old protocol). + // Register response optional DeviceRegisterResponse register_response = 3; // Unregister response @@ -288,9 +253,6 @@ message DeviceManagementResponse { // Policy response (new protocol). optional CloudPolicyResponse cloud_policy_response = 6; - // Response to initial (before registration) policy request. - optional InitialPolicyResponse initial_policy_response = 7; - - // Register response (new protocol). - optional CloudRegisterResponse cloud_register_response = 8; + // Response to managed check request. + optional ManagedCheckResponse managed_check_response = 7; }
\ No newline at end of file diff --git a/chrome/browser/policy/proto/device_management_local.proto b/chrome/browser/policy/proto/device_management_local.proto index 45c2994..a991551 100644 --- a/chrome/browser/policy/proto/device_management_local.proto +++ b/chrome/browser/policy/proto/device_management_local.proto @@ -10,18 +10,14 @@ package enterprise_management; import "device_management_backend.proto"; -// Wrapper around CloudPolicyResponse/DevicePolicyResponse for caching on disk. -message CachedCloudPolicyResponse { +// Wrapper around DevicePolicyResponse for caching on disk. +message CachedDevicePolicyResponse { // The DevicePolicyResponse wrapped by this message. - optional DevicePolicyResponse device_policy = 1; - // Timestamp noting when the |unmanaged| flag was set. The data format is - // a unix timestamp. When caching (deprecated) DevicePolicyResponses, this - // timestamp also notes when the response was cached. + optional DevicePolicyResponse policy = 1; + // Timestamp noting when this policy was cached. optional uint64 timestamp = 2; // Flag that is set to true if this device is not managed. optional bool unmanaged = 3; - // The CloudPolicyResponse wrapped by this message. - optional CloudPolicyResponse cloud_policy = 4; } // Encapsulates a device ID and the associated device token. diff --git a/chrome/browser/policy/proto/device_management_proto.gyp b/chrome/browser/policy/proto/device_management_proto.gyp new file mode 100644 index 0000000..ede0251 --- /dev/null +++ b/chrome/browser/policy/proto/device_management_proto.gyp @@ -0,0 +1,81 @@ +# Copyright (c) 2010 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'variables': { + 'chromium_code': 1, + 'protoc_out_dir': '<(SHARED_INTERMEDIATE_DIR)/protoc_out', + }, + 'targets': [ + { + # Protobuf compiler / generate rule for the device management protocol. + 'target_name': 'device_management_proto', + 'type': 'none', + 'sources': [ + 'cloud_policy.proto', + 'device_management_backend.proto', + 'device_management_local.proto', + ], + 'rules': [ + { + 'rule_name': 'genproto', + 'extension': 'proto', + 'inputs': [ + '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)', + ], + 'variables': { + # The protoc compiler requires a proto_path argument with the + # directory containing the .proto file. There's no generator + # variable that corresponds to this, so fake it. + 'rule_input_relpath': 'chrome/browser/policy/proto', + }, + 'outputs': [ + '<(PRODUCT_DIR)/pyproto/device_management_pb/<(RULE_INPUT_ROOT)_pb2.py', + '<(protoc_out_dir)/<(rule_input_relpath)/<(RULE_INPUT_ROOT).pb.h', + '<(protoc_out_dir)/<(rule_input_relpath)/<(RULE_INPUT_ROOT).pb.cc', + ], + 'action': [ + '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)', + '--proto_path=.', + './<(RULE_INPUT_ROOT)<(RULE_INPUT_EXT)', + '--cpp_out=<(protoc_out_dir)/<(rule_input_relpath)', + '--python_out=<(PRODUCT_DIR)/pyproto/device_management_pb', + ], + 'message': 'Generating C++ and Python code from <(RULE_INPUT_PATH)', + }, + ], + 'dependencies': [ + '../../../../third_party/protobuf/protobuf.gyp:protoc#host', + ], + 'direct_dependent_settings': { + 'include_dirs': [ + '<(protoc_out_dir)', + ] + }, + }, + { + 'target_name': 'device_management_proto_cpp', + 'type': 'none', + 'export_dependent_settings': [ + '../../../../third_party/protobuf/protobuf.gyp:protobuf_lite', + 'device_management_proto', + ], + 'dependencies': [ + '../../../../third_party/protobuf/protobuf.gyp:protobuf_lite', + 'device_management_proto', + ], + 'direct_dependent_settings': { + 'include_dirs': [ + '<(protoc_out_dir)', + ] + }, + }, + ], +} + +# Local Variables: +# tab-width:2 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=2 shiftwidth=2: |