1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
// 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_
|