// 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/observer_list.h" #include "base/ref_counted.h" #include "base/scoped_ptr.h" #include "base/threading/non_thread_safe.h" #include "base/time.h" #include "chrome/browser/policy/configuration_policy_provider.h" #include "chrome/browser/policy/policy_map.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 base::NonThreadSafe { public: // Used to distinguish mandatory from recommended policies. enum PolicyLevel { // Policy is forced upon the user and should always take effect. POLICY_LEVEL_MANDATORY, // The value is just a recommendation that the user may override. POLICY_LEVEL_RECOMMENDED, }; explicit CloudPolicyCache(const FilePath& backing_file_path); ~CloudPolicyCache(); // Loads policy information from the backing file. Non-existing or erroneous // cache files are ignored. void LoadFromFile(); // Resets the policy information. void SetPolicy(const em::PolicyFetchResponse& policy); void SetDevicePolicy(const em::DevicePolicyResponse& policy); ConfigurationPolicyProvider* GetManagedPolicyProvider(); ConfigurationPolicyProvider* GetRecommendedPolicyProvider(); 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: class CloudPolicyProvider; friend class CloudPolicyCacheTest; friend class DeviceManagementPolicyCacheTest; 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::PolicyFetchResponse& policy_response, PolicyMap* mandatory, PolicyMap* 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); // 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_; // Policy key-value information. PolicyMap mandatory_policy_; PolicyMap recommended_policy_; scoped_ptr<DictionaryValue> device_policy_; // Whether initialization has been completed. This is the case when we have // valid policy, learned that the device is unmanaged or ran into // unrecoverable errors. bool initialization_complete_; // Whether the the server has indicated this device is unmanaged. 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_; // Policy providers. scoped_ptr<ConfigurationPolicyProvider> managed_policy_provider_; scoped_ptr<ConfigurationPolicyProvider> recommended_policy_provider_; // Provider observers that are registered with this cache's providers. ObserverList<ConfigurationPolicyProvider::Observer, true> observer_list_; DISALLOW_COPY_AND_ASSIGN(CloudPolicyCache); }; } // namespace policy #endif // CHROME_BROWSER_POLICY_CLOUD_POLICY_CACHE_H_