Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(24)

Side by Side Diff: chrome/browser/policy/cloud_policy_cache.cc

Issue 6537020: Update policy backend and testserver for the newest policy protocol (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix unit tests and chromeos crashes Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/policy/cloud_policy_cache.h" 5 #include "chrome/browser/policy/cloud_policy_cache.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/file_util.h" 9 #include "base/file_util.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 // Policy level this provider will handle. 75 // Policy level this provider will handle.
76 CloudPolicyCache::PolicyLevel level_; 76 CloudPolicyCache::PolicyLevel level_;
77 77
78 DISALLOW_COPY_AND_ASSIGN(CloudPolicyProvider); 78 DISALLOW_COPY_AND_ASSIGN(CloudPolicyProvider);
79 }; 79 };
80 80
81 // Saves policy information to a file. 81 // Saves policy information to a file.
82 class PersistPolicyTask : public Task { 82 class PersistPolicyTask : public Task {
83 public: 83 public:
84 PersistPolicyTask(const FilePath& path, 84 PersistPolicyTask(const FilePath& path,
85 const em::CloudPolicyResponse* cloud_policy_response, 85 const em::PolicyFetchResponse* cloud_policy_response,
86 const em::DevicePolicyResponse* device_policy_response, 86 const em::DevicePolicyResponse* device_policy_response,
87 const bool is_unmanaged) 87 const bool is_unmanaged)
88 : path_(path), 88 : path_(path),
89 cloud_policy_response_(cloud_policy_response), 89 cloud_policy_response_(cloud_policy_response),
90 device_policy_response_(device_policy_response), 90 device_policy_response_(device_policy_response),
91 is_unmanaged_(is_unmanaged) {} 91 is_unmanaged_(is_unmanaged) {}
92 92
93 private: 93 private:
94 // Task override. 94 // Task override.
95 virtual void Run(); 95 virtual void Run();
96 96
97 const FilePath path_; 97 const FilePath path_;
98 scoped_ptr<const em::CloudPolicyResponse> cloud_policy_response_; 98 scoped_ptr<const em::PolicyFetchResponse> cloud_policy_response_;
99 scoped_ptr<const em::DevicePolicyResponse> device_policy_response_; 99 scoped_ptr<const em::DevicePolicyResponse> device_policy_response_;
100 const bool is_unmanaged_; 100 const bool is_unmanaged_;
101 }; 101 };
102 102
103 void PersistPolicyTask::Run() { 103 void PersistPolicyTask::Run() {
104 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 104 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
105 std::string data; 105 std::string data;
106 em::CachedCloudPolicyResponse cached_policy; 106 em::CachedCloudPolicyResponse cached_policy;
107 if (cloud_policy_response_.get()) { 107 if (cloud_policy_response_.get()) {
108 cached_policy.mutable_cloud_policy()->CopyFrom(*cloud_policy_response_); 108 cached_policy.mutable_cloud_policy()->CopyFrom(*cloud_policy_response_);
(...skipping 16 matching lines...) Expand all
125 return; 125 return;
126 } 126 }
127 } 127 }
128 128
129 CloudPolicyCache::CloudPolicyCache( 129 CloudPolicyCache::CloudPolicyCache(
130 const FilePath& backing_file_path) 130 const FilePath& backing_file_path)
131 : backing_file_path_(backing_file_path), 131 : backing_file_path_(backing_file_path),
132 device_policy_(new DictionaryValue), 132 device_policy_(new DictionaryValue),
133 initialization_complete_(false), 133 initialization_complete_(false),
134 is_unmanaged_(false), 134 is_unmanaged_(false),
135 has_device_policy_(false) { 135 has_device_policy_(false),
136 last_policy_server_timestamp_(0) {
136 managed_policy_provider_.reset( 137 managed_policy_provider_.reset(
137 new CloudPolicyProvider( 138 new CloudPolicyProvider(
138 ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(), 139 ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(),
139 this, 140 this,
140 POLICY_LEVEL_MANDATORY)); 141 POLICY_LEVEL_MANDATORY));
141 recommended_policy_provider_.reset( 142 recommended_policy_provider_.reset(
142 new CloudPolicyProvider( 143 new CloudPolicyProvider(
143 ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(), 144 ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(),
144 this, 145 this,
145 POLICY_LEVEL_RECOMMENDED)); 146 POLICY_LEVEL_RECOMMENDED));
(...skipping 19 matching lines...) Expand all
165 return; 166 return;
166 } 167 }
167 168
168 em::CachedCloudPolicyResponse cached_response; 169 em::CachedCloudPolicyResponse cached_response;
169 if (!cached_response.ParseFromArray(data.c_str(), data.size())) { 170 if (!cached_response.ParseFromArray(data.c_str(), data.size())) {
170 LOG(WARNING) << "Failed to parse policy data read from " 171 LOG(WARNING) << "Failed to parse policy data read from "
171 << backing_file_path_.value(); 172 << backing_file_path_.value();
172 return; 173 return;
173 } 174 }
174 base::Time timestamp; 175 base::Time timestamp;
176 int64 raw_timestamp;
175 PolicyMap mandatory_policy; 177 PolicyMap mandatory_policy;
176 PolicyMap recommended_policy; 178 PolicyMap recommended_policy;
177 is_unmanaged_ = cached_response.unmanaged(); 179 is_unmanaged_ = cached_response.unmanaged();
178 if (is_unmanaged_ || cached_response.has_device_policy()) 180 if (is_unmanaged_ || cached_response.has_device_policy())
179 timestamp = base::Time::FromTimeT(cached_response.timestamp()); 181 timestamp = base::Time::FromTimeT(cached_response.timestamp());
180 if (cached_response.has_cloud_policy()) { 182 if (cached_response.has_cloud_policy()) {
181 DCHECK(!is_unmanaged_); 183 DCHECK(!is_unmanaged_);
182 bool ok = DecodePolicyResponse(cached_response.cloud_policy(), 184 bool ok = DecodePolicyResponse(cached_response.cloud_policy(),
183 &mandatory_policy, 185 &mandatory_policy,
184 &recommended_policy, 186 &recommended_policy,
185 &timestamp); 187 &timestamp,
188 &raw_timestamp);
186 if (!ok) { 189 if (!ok) {
187 LOG(WARNING) << "Decoding policy data failed."; 190 LOG(WARNING) << "Decoding policy data failed.";
188 return; 191 return;
189 } 192 }
190 } 193 }
191 if (timestamp > base::Time::NowFromSystemTime()) { 194 if (timestamp > base::Time::NowFromSystemTime()) {
192 LOG(WARNING) << "Rejected policy data from " << backing_file_path_.value() 195 LOG(WARNING) << "Rejected policy data from " << backing_file_path_.value()
193 << ", file is from the future."; 196 << ", file is from the future.";
194 return; 197 return;
195 } 198 }
196 // Swap in the new policy information. 199 // Swap in the new policy information.
197 if (cached_response.has_cloud_policy()) { 200 if (cached_response.has_cloud_policy()) {
198 mandatory_policy_.Swap(&mandatory_policy); 201 mandatory_policy_.Swap(&mandatory_policy);
199 recommended_policy_.Swap(&recommended_policy); 202 recommended_policy_.Swap(&recommended_policy);
203 last_policy_server_timestamp_ = raw_timestamp;
200 has_device_policy_ = false; 204 has_device_policy_ = false;
201 } else if (cached_response.has_device_policy()) { 205 } else if (cached_response.has_device_policy()) {
202 scoped_ptr<DictionaryValue> value( 206 scoped_ptr<DictionaryValue> value(
203 DecodeDevicePolicy(cached_response.device_policy())); 207 DecodeDevicePolicy(cached_response.device_policy()));
204 device_policy_.reset(value.release()); 208 device_policy_.reset(value.release());
205 has_device_policy_ = true; 209 has_device_policy_ = true;
206 } 210 }
207 last_policy_refresh_time_ = timestamp; 211 last_policy_refresh_time_ = timestamp;
208 initialization_complete_ = true; 212 initialization_complete_ = true;
209 213
210 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, 214 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
211 observer_list_, OnUpdatePolicy()); 215 observer_list_, OnUpdatePolicy());
212 } 216 }
213 217
214 void CloudPolicyCache::SetPolicy(const em::CloudPolicyResponse& policy) { 218 void CloudPolicyCache::SetPolicy(const em::PolicyFetchResponse& policy) {
215 DCHECK(CalledOnValidThread()); 219 DCHECK(CalledOnValidThread());
216 bool initialization_was_not_complete = !initialization_complete_; 220 bool initialization_was_not_complete = !initialization_complete_;
217 is_unmanaged_ = false; 221 is_unmanaged_ = false;
218 base::Time timestamp; 222 base::Time timestamp;
223 int64 raw_timestamp;
219 PolicyMap mandatory_policy; 224 PolicyMap mandatory_policy;
220 PolicyMap recommended_policy; 225 PolicyMap recommended_policy;
221 bool ok = DecodePolicyResponse(policy, &mandatory_policy, &recommended_policy, 226 bool ok = DecodePolicyResponse(policy, &mandatory_policy, &recommended_policy,
222 &timestamp); 227 &timestamp, &raw_timestamp);
223 if (!ok) 228 if (!ok)
224 return; 229 return;
225 230
226 const bool new_policy_differs = 231 const bool new_policy_differs =
227 !mandatory_policy_.Equals(mandatory_policy) || 232 !mandatory_policy_.Equals(mandatory_policy) ||
228 !recommended_policy_.Equals(recommended_policy); 233 !recommended_policy_.Equals(recommended_policy);
229 mandatory_policy_.Swap(&mandatory_policy); 234 mandatory_policy_.Swap(&mandatory_policy);
230 recommended_policy_.Swap(&recommended_policy); 235 recommended_policy_.Swap(&recommended_policy);
231 initialization_complete_ = true; 236 initialization_complete_ = true;
232 last_policy_refresh_time_ = timestamp; 237 last_policy_refresh_time_ = timestamp;
238 last_policy_server_timestamp_ = raw_timestamp;
233 has_device_policy_ = false; 239 has_device_policy_ = false;
234 240
235 if (new_policy_differs || initialization_was_not_complete) { 241 if (new_policy_differs || initialization_was_not_complete) {
236 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, 242 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
237 observer_list_, OnUpdatePolicy()); 243 observer_list_, OnUpdatePolicy());
238 } 244 }
239 245
240 if (timestamp > base::Time::NowFromSystemTime() + 246 if (timestamp > base::Time::NowFromSystemTime() +
241 base::TimeDelta::FromMinutes(1)) { 247 base::TimeDelta::FromMinutes(1)) {
242 LOG(WARNING) << "Server returned policy with timestamp from the future, " 248 LOG(WARNING) << "Server returned policy with timestamp from the future, "
243 "not persisting to disk."; 249 "not persisting to disk.";
244 } else { 250 } else {
245 em::CloudPolicyResponse* policy_copy = new em::CloudPolicyResponse; 251 em::PolicyFetchResponse* policy_copy = new em::PolicyFetchResponse;
246 policy_copy->CopyFrom(policy); 252 policy_copy->CopyFrom(policy);
247 BrowserThread::PostTask( 253 BrowserThread::PostTask(
248 BrowserThread::FILE, 254 BrowserThread::FILE,
249 FROM_HERE, 255 FROM_HERE,
250 new PersistPolicyTask(backing_file_path_, policy_copy, NULL, false)); 256 new PersistPolicyTask(backing_file_path_, policy_copy, NULL, false));
251 } 257 }
252 } 258 }
253 259
254 void CloudPolicyCache::SetDevicePolicy(const em::DevicePolicyResponse& policy) { 260 void CloudPolicyCache::SetDevicePolicy(const em::DevicePolicyResponse& policy) {
255 DCHECK(CalledOnValidThread()); 261 DCHECK(CalledOnValidThread());
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 observer_list_, OnUpdatePolicy()); 304 observer_list_, OnUpdatePolicy());
299 305
300 BrowserThread::PostTask( 306 BrowserThread::PostTask(
301 BrowserThread::FILE, 307 BrowserThread::FILE,
302 FROM_HERE, 308 FROM_HERE,
303 new PersistPolicyTask(backing_file_path_, NULL, NULL, true)); 309 new PersistPolicyTask(backing_file_path_, NULL, NULL, true));
304 } 310 }
305 311
306 // static 312 // static
307 bool CloudPolicyCache::DecodePolicyResponse( 313 bool CloudPolicyCache::DecodePolicyResponse(
308 const em::CloudPolicyResponse& policy_response, 314 const em::PolicyFetchResponse& policy_response,
309 PolicyMap* mandatory, 315 PolicyMap* mandatory,
310 PolicyMap* recommended, 316 PolicyMap* recommended,
311 base::Time* timestamp) { 317 base::Time* timestamp,
312 std::string data = policy_response.signed_response(); 318 int64* raw_timestamp) {
319 std::string data = policy_response.policy_data();
313 320
314 if (!VerifySignature(policy_response.signature(), data, 321 if (!VerifySignature(policy_response.policy_data_signature(), data,
315 policy_response.certificate_chain())) { 322 policy_response.certificate_chain())) {
316 LOG(WARNING) << "Failed to verify signature."; 323 LOG(WARNING) << "Failed to verify signature.";
317 return false; 324 return false;
318 } 325 }
319 326
320 em::SignedCloudPolicyResponse response; 327 em::PolicyData policy_data;
321 if (!response.ParseFromArray(data.c_str(), data.size())) { 328 if (!policy_data.ParseFromString(data)) {
322 LOG(WARNING) << "Failed to parse SignedCloudPolicyResponse protobuf."; 329 LOG(WARNING) << "Failed to parse PolicyData protobuf.";
323 return false; 330 return false;
324 } 331 }
325 332
326 // TODO(jkummerow): Verify response.device_token(). Needs final specification 333 // TODO(jkummerow): Verify policy_data.device_token(). Needs final
327 // which token we're actually sending / expecting to get back. 334 // specification which token we're actually sending / expecting to get back.
328 335
329 // TODO(jkummerow): Store response.device_name(), if we decide to transfer 336 // TODO(jkummerow): Store policy_data.device_name(), if we decide to transfer
330 // it from the server to the client. 337 // it from the server to the client.
331 338
332 DCHECK(timestamp); 339 DCHECK(timestamp);
333 *timestamp = base::Time::FromTimeT(response.timestamp()); 340 DCHECK(raw_timestamp);
334 DecodePolicy(response.settings(), mandatory, recommended); 341 *raw_timestamp = policy_data.timestamp();
342 *timestamp = base::Time::UnixEpoch() +
343 base::TimeDelta::FromMilliseconds(*raw_timestamp);
344 em::CloudPolicySettings policy;
345 if (!policy.ParseFromString(policy_data.policy_value())) {
346 LOG(WARNING) << "Failed to parse CloudPolicySettingsj protobuf.";
Jakob Kummerow 2011/02/28 11:06:31 nit: j?
gfeher 2011/02/28 12:21:32 Done.
347 return false;
348 }
349 DecodePolicy(policy, mandatory, recommended);
335 return true; 350 return true;
336 } 351 }
337 352
338 // static 353 // static
339 bool CloudPolicyCache::VerifySignature( 354 bool CloudPolicyCache::VerifySignature(
340 const std::string& signature, 355 const std::string& signature,
341 const std::string& data, 356 const std::string& data,
342 const RepeatedPtrField<std::string>& certificate_chain) { 357 const RepeatedPtrField<std::string>& certificate_chain) {
343 // TODO(jkummerow): Implement this. Non-trivial because we want to do it 358 // TODO(jkummerow): Implement this. Non-trivial because we want to do it
344 // for all platforms -> it's enough work to deserve its own CL. 359 // for all platforms -> it's enough work to deserve its own CL.
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 CloudPolicyCache::DecodeValue(named_value->value()); 469 CloudPolicyCache::DecodeValue(named_value->value());
455 if (decoded_value) 470 if (decoded_value)
456 result->Set(named_value->name(), decoded_value); 471 result->Set(named_value->name(), decoded_value);
457 } 472 }
458 } 473 }
459 } 474 }
460 return result; 475 return result;
461 } 476 }
462 477
463 } // namespace policy 478 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698