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

Side by Side Diff: chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc

Issue 2487703002: Remove legacy policy cache support on chromeos (Closed)
Patch Set: Created 4 years, 1 month 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/chromeos/policy/user_cloud_policy_store_chromeos.h" 5 #include "chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 VALIDATION_FAILURE_SIZE); 54 VALIDATION_FAILURE_SIZE);
55 } 55 }
56 56
57 // Extracts the domain name from the passed username. 57 // Extracts the domain name from the passed username.
58 std::string ExtractDomain(const std::string& username) { 58 std::string ExtractDomain(const std::string& username) {
59 return gaia::ExtractDomainName(gaia::CanonicalizeEmail(username)); 59 return gaia::ExtractDomainName(gaia::CanonicalizeEmail(username));
60 } 60 }
61 61
62 } // namespace 62 } // namespace
63 63
64 // Helper class for loading legacy policy caches.
65 class LegacyPolicyCacheLoader : public UserPolicyTokenLoader::Delegate,
66 public UserPolicyDiskCache::Delegate {
67 public:
68 typedef base::Callback<void(const std::string&,
69 const std::string&,
70 CloudPolicyStore::Status,
71 std::unique_ptr<em::PolicyFetchResponse>)>
72 Callback;
73
74 LegacyPolicyCacheLoader(
75 const base::FilePath& token_cache_file,
76 const base::FilePath& policy_cache_file,
77 scoped_refptr<base::SequencedTaskRunner> background_task_runner);
78 ~LegacyPolicyCacheLoader() override;
79
80 // Starts loading, and reports the result to |callback| when done.
81 void Load(const Callback& callback);
82
83 // UserPolicyTokenLoader::Delegate:
84 void OnTokenLoaded(const std::string& token,
85 const std::string& device_id) override;
86
87 // UserPolicyDiskCache::Delegate:
88 void OnDiskCacheLoaded(UserPolicyDiskCache::LoadResult result,
89 const em::CachedCloudPolicyResponse& policy) override;
90
91 private:
92 // Checks whether the load operations from the legacy caches completed. If so,
93 // fires the appropriate notification.
94 void CheckLoadFinished();
95
96 // Maps a disk cache LoadResult to a CloudPolicyStore::Status.
97 static CloudPolicyStore::Status TranslateLoadResult(
98 UserPolicyDiskCache::LoadResult result);
99
100 scoped_refptr<UserPolicyTokenLoader> token_loader_;
101 scoped_refptr<UserPolicyDiskCache> policy_cache_;
102
103 std::string dm_token_;
104 std::string device_id_;
105 std::unique_ptr<em::PolicyFetchResponse> policy_;
106 CloudPolicyStore::Status status_;
107
108 Callback callback_;
109
110 base::WeakPtrFactory<LegacyPolicyCacheLoader> weak_factory_;
111
112 DISALLOW_COPY_AND_ASSIGN(LegacyPolicyCacheLoader);
113 };
114
115 LegacyPolicyCacheLoader::LegacyPolicyCacheLoader(
116 const base::FilePath& token_cache_file,
117 const base::FilePath& policy_cache_file,
118 scoped_refptr<base::SequencedTaskRunner> background_task_runner)
119 : status_(CloudPolicyStore::STATUS_OK),
120 weak_factory_(this) {
121 token_loader_ = new UserPolicyTokenLoader(weak_factory_.GetWeakPtr(),
122 token_cache_file,
123 background_task_runner);
124 policy_cache_ = new UserPolicyDiskCache(weak_factory_.GetWeakPtr(),
125 policy_cache_file,
126 background_task_runner);
127 }
128
129 LegacyPolicyCacheLoader::~LegacyPolicyCacheLoader() {}
130
131 void LegacyPolicyCacheLoader::Load(const Callback& callback) {
132 callback_ = callback;
133 token_loader_->Load();
134 policy_cache_->Load();
135 }
136
137 void LegacyPolicyCacheLoader::OnTokenLoaded(const std::string& token,
138 const std::string& device_id) {
139 dm_token_ = token;
140 device_id_ = device_id;
141 token_loader_ = NULL;
142 CheckLoadFinished();
143 }
144
145 void LegacyPolicyCacheLoader::OnDiskCacheLoaded(
146 UserPolicyDiskCache::LoadResult result,
147 const em::CachedCloudPolicyResponse& policy) {
148 status_ = TranslateLoadResult(result);
149 if (result == UserPolicyDiskCache::LOAD_RESULT_SUCCESS) {
150 if (policy.has_cloud_policy())
151 policy_.reset(new em::PolicyFetchResponse(policy.cloud_policy()));
152 } else {
153 LOG(WARNING) << "Failed to load legacy policy cache: " << result;
154 }
155 policy_cache_ = NULL;
156 CheckLoadFinished();
157 }
158
159 void LegacyPolicyCacheLoader::CheckLoadFinished() {
160 if (!token_loader_.get() && !policy_cache_.get())
161 callback_.Run(dm_token_, device_id_, status_, std::move(policy_));
162 }
163
164 // static
165 CloudPolicyStore::Status LegacyPolicyCacheLoader::TranslateLoadResult(
166 UserPolicyDiskCache::LoadResult result) {
167 switch (result) {
168 case UserPolicyDiskCache::LOAD_RESULT_SUCCESS:
169 case UserPolicyDiskCache::LOAD_RESULT_NOT_FOUND:
170 return CloudPolicyStore::STATUS_OK;
171 case UserPolicyDiskCache::LOAD_RESULT_PARSE_ERROR:
172 case UserPolicyDiskCache::LOAD_RESULT_READ_ERROR:
173 return CloudPolicyStore::STATUS_LOAD_ERROR;
174 }
175 NOTREACHED();
176 return CloudPolicyStore::STATUS_OK;
177 }
178
179 UserCloudPolicyStoreChromeOS::UserCloudPolicyStoreChromeOS( 64 UserCloudPolicyStoreChromeOS::UserCloudPolicyStoreChromeOS(
180 chromeos::CryptohomeClient* cryptohome_client, 65 chromeos::CryptohomeClient* cryptohome_client,
181 chromeos::SessionManagerClient* session_manager_client, 66 chromeos::SessionManagerClient* session_manager_client,
182 scoped_refptr<base::SequencedTaskRunner> background_task_runner, 67 scoped_refptr<base::SequencedTaskRunner> background_task_runner,
183 const AccountId& account_id, 68 const AccountId& account_id,
184 const base::FilePath& user_policy_key_dir, 69 const base::FilePath& user_policy_key_dir)
185 const base::FilePath& legacy_token_cache_file,
186 const base::FilePath& legacy_policy_cache_file)
187 : UserCloudPolicyStoreBase(background_task_runner), 70 : UserCloudPolicyStoreBase(background_task_runner),
188 cryptohome_client_(cryptohome_client), 71 cryptohome_client_(cryptohome_client),
189 session_manager_client_(session_manager_client), 72 session_manager_client_(session_manager_client),
190 account_id_(account_id), 73 account_id_(account_id),
191 user_policy_key_dir_(user_policy_key_dir), 74 user_policy_key_dir_(user_policy_key_dir),
192 legacy_cache_dir_(legacy_token_cache_file.DirName()),
193 legacy_loader_(new LegacyPolicyCacheLoader(legacy_token_cache_file,
194 legacy_policy_cache_file,
195 background_task_runner)),
196 legacy_caches_loaded_(false),
197 policy_key_loaded_(false), 75 policy_key_loaded_(false),
198 weak_factory_(this) {} 76 weak_factory_(this) {}
199 77
200 UserCloudPolicyStoreChromeOS::~UserCloudPolicyStoreChromeOS() {} 78 UserCloudPolicyStoreChromeOS::~UserCloudPolicyStoreChromeOS() {}
201 79
202 void UserCloudPolicyStoreChromeOS::Store( 80 void UserCloudPolicyStoreChromeOS::Store(
203 const em::PolicyFetchResponse& policy) { 81 const em::PolicyFetchResponse& policy) {
204 // Cancel all pending requests. 82 // Cancel all pending requests.
205 weak_factory_.InvalidateWeakPtrs(); 83 weak_factory_.InvalidateWeakPtrs();
206 std::unique_ptr<em::PolicyFetchResponse> response( 84 std::unique_ptr<em::PolicyFetchResponse> response(
(...skipping 20 matching lines...) Expand all
227 // session. That happens when the browser crashes, or right after signin if 105 // session. That happens when the browser crashes, or right after signin if
228 // the user has flags configured in about:flags. 106 // the user has flags configured in about:flags.
229 // However, on those paths we must load policy synchronously so that the 107 // However, on those paths we must load policy synchronously so that the
230 // Profile initialization never sees unmanaged prefs, which would lead to 108 // Profile initialization never sees unmanaged prefs, which would lead to
231 // data loss. http://crbug.com/263061 109 // data loss. http://crbug.com/263061
232 std::string policy_blob = 110 std::string policy_blob =
233 session_manager_client_->BlockingRetrievePolicyForUser( 111 session_manager_client_->BlockingRetrievePolicyForUser(
234 cryptohome::Identification(account_id_)); 112 cryptohome::Identification(account_id_));
235 if (policy_blob.empty()) { 113 if (policy_blob.empty()) {
236 // The session manager doesn't have policy, or the call failed. 114 // The session manager doesn't have policy, or the call failed.
237 // Just notify that the load is done, and don't bother with the legacy
238 // caches in this case.
239 NotifyStoreLoaded(); 115 NotifyStoreLoaded();
240 return; 116 return;
241 } 117 }
242 118
243 std::unique_ptr<em::PolicyFetchResponse> policy( 119 std::unique_ptr<em::PolicyFetchResponse> policy(
244 new em::PolicyFetchResponse()); 120 new em::PolicyFetchResponse());
245 if (!policy->ParseFromString(policy_blob)) { 121 if (!policy->ParseFromString(policy_blob)) {
246 status_ = STATUS_PARSE_ERROR; 122 status_ = STATUS_PARSE_ERROR;
247 NotifyStoreError(); 123 NotifyStoreError();
248 return; 124 return;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 // the session manager. An additional validation is performed after the 204 // the session manager. An additional validation is performed after the
329 // load; reload the key for that validation too, in case it was rotated. 205 // load; reload the key for that validation too, in case it was rotated.
330 ReloadPolicyKey(base::Bind(&UserCloudPolicyStoreChromeOS::Load, 206 ReloadPolicyKey(base::Bind(&UserCloudPolicyStoreChromeOS::Load,
331 weak_factory_.GetWeakPtr())); 207 weak_factory_.GetWeakPtr()));
332 } 208 }
333 } 209 }
334 210
335 void UserCloudPolicyStoreChromeOS::OnPolicyRetrieved( 211 void UserCloudPolicyStoreChromeOS::OnPolicyRetrieved(
336 const std::string& policy_blob) { 212 const std::string& policy_blob) {
337 if (policy_blob.empty()) { 213 if (policy_blob.empty()) {
338 // Policy fetch failed. Try legacy caches if we haven't done that already. 214 // session_manager doesn't have policy. Adjust internal state and notify
339 if (!legacy_caches_loaded_ && legacy_loader_.get()) { 215 // the world about the policy update.
340 legacy_caches_loaded_ = true; 216 policy_.reset();
341 legacy_loader_->Load( 217 NotifyStoreLoaded();
342 base::Bind(&UserCloudPolicyStoreChromeOS::OnLegacyLoadFinished,
343 weak_factory_.GetWeakPtr()));
344 } else {
345 // session_manager doesn't have policy. Adjust internal state and notify
346 // the world about the policy update.
347 policy_.reset();
348 NotifyStoreLoaded();
349 }
350 return; 218 return;
351 } 219 }
352 220
353 // Policy is supplied by session_manager. Disregard legacy data from now on.
354 legacy_loader_.reset();
355
356 std::unique_ptr<em::PolicyFetchResponse> policy( 221 std::unique_ptr<em::PolicyFetchResponse> policy(
357 new em::PolicyFetchResponse()); 222 new em::PolicyFetchResponse());
358 if (!policy->ParseFromString(policy_blob)) { 223 if (!policy->ParseFromString(policy_blob)) {
359 status_ = STATUS_PARSE_ERROR; 224 status_ = STATUS_PARSE_ERROR;
360 NotifyStoreError(); 225 NotifyStoreError();
361 return; 226 return;
362 } 227 }
363 228
364 // Load |policy_key_| to verify the loaded policy. 229 // Load |policy_key_| to verify the loaded policy.
365 EnsurePolicyKeyLoaded( 230 EnsurePolicyKeyLoaded(
(...skipping 26 matching lines...) Expand all
392 if (!validator->success()) { 257 if (!validator->success()) {
393 status_ = STATUS_VALIDATION_ERROR; 258 status_ = STATUS_VALIDATION_ERROR;
394 NotifyStoreError(); 259 NotifyStoreError();
395 return; 260 return;
396 } 261 }
397 262
398 InstallPolicy(std::move(validator->policy_data()), 263 InstallPolicy(std::move(validator->policy_data()),
399 std::move(validator->payload())); 264 std::move(validator->payload()));
400 status_ = STATUS_OK; 265 status_ = STATUS_OK;
401 266
402 // Policy has been loaded successfully. This indicates that new-style policy
403 // is working, so the legacy cache directory can be removed.
404 if (!legacy_cache_dir_.empty()) {
405 background_task_runner()->PostTask(
406 FROM_HERE,
407 base::Bind(&UserCloudPolicyStoreChromeOS::RemoveLegacyCacheDir,
408 legacy_cache_dir_));
409 legacy_cache_dir_.clear();
410 }
411 NotifyStoreLoaded(); 267 NotifyStoreLoaded();
412 } 268 }
413 269
414 void UserCloudPolicyStoreChromeOS::OnLegacyLoadFinished(
415 const std::string& dm_token,
416 const std::string& device_id,
417 Status status,
418 std::unique_ptr<em::PolicyFetchResponse> policy) {
419 status_ = status;
420 if (policy.get()) {
421 // Create and configure a validator for the loaded legacy policy. Note that
422 // the signature on this policy is not verified.
423 std::unique_ptr<UserCloudPolicyValidator> validator = CreateValidator(
424 std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_FULLY_VALIDATED);
425 validator->ValidateUsername(account_id_.GetUserEmail(), true);
426 validator.release()->StartValidation(
427 base::Bind(&UserCloudPolicyStoreChromeOS::OnLegacyPolicyValidated,
428 weak_factory_.GetWeakPtr(),
429 dm_token,
430 device_id));
431 } else {
432 InstallLegacyTokens(dm_token, device_id);
433 }
434 }
435
436 void UserCloudPolicyStoreChromeOS::OnLegacyPolicyValidated(
437 const std::string& dm_token,
438 const std::string& device_id,
439 UserCloudPolicyValidator* validator) {
440 validation_status_ = validator->status();
441 if (validator->success()) {
442 status_ = STATUS_OK;
443 InstallPolicy(std::move(validator->policy_data()),
444 std::move(validator->payload()));
445
446 // Clear the public key version. The public key version field would
447 // otherwise indicate that we have key installed in the store when in fact
448 // we haven't. This may result in policy updates failing signature
449 // verification.
450 policy_->clear_public_key_version();
451 } else {
452 status_ = STATUS_VALIDATION_ERROR;
453 }
454
455 InstallLegacyTokens(dm_token, device_id);
456 }
457
458 void UserCloudPolicyStoreChromeOS::InstallLegacyTokens(
459 const std::string& dm_token,
460 const std::string& device_id) {
461 // Write token and device ID to |policy_|, giving them precedence over the
462 // policy blob. This is to match the legacy behavior, which used token and
463 // device id exclusively from the token cache file.
464 if (!dm_token.empty() && !device_id.empty()) {
465 if (!policy_.get())
466 policy_.reset(new em::PolicyData());
467 policy_->set_request_token(dm_token);
468 policy_->set_device_id(device_id);
469 }
470
471 // Tell the rest of the world that the policy load completed.
472 NotifyStoreLoaded();
473 }
474
475 // static
476 void UserCloudPolicyStoreChromeOS::RemoveLegacyCacheDir(
477 const base::FilePath& dir) {
478 if (base::PathExists(dir) && !base::DeleteFile(dir, true))
479 LOG(ERROR) << "Failed to remove cache dir " << dir.value();
480 }
481
482 void UserCloudPolicyStoreChromeOS::ReloadPolicyKey( 270 void UserCloudPolicyStoreChromeOS::ReloadPolicyKey(
483 const base::Closure& callback) { 271 const base::Closure& callback) {
484 std::string* key = new std::string(); 272 std::string* key = new std::string();
485 background_task_runner()->PostTaskAndReply( 273 background_task_runner()->PostTaskAndReply(
486 FROM_HERE, 274 FROM_HERE,
487 base::Bind(&UserCloudPolicyStoreChromeOS::LoadPolicyKey, 275 base::Bind(&UserCloudPolicyStoreChromeOS::LoadPolicyKey,
488 policy_key_path_, 276 policy_key_path_,
489 key), 277 key),
490 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyKeyReloaded, 278 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyKeyReloaded,
491 weak_factory_.GetWeakPtr(), 279 weak_factory_.GetWeakPtr(),
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 348
561 std::unique_ptr<UserCloudPolicyValidator> 349 std::unique_ptr<UserCloudPolicyValidator>
562 UserCloudPolicyStoreChromeOS::CreateValidatorForLoad( 350 UserCloudPolicyStoreChromeOS::CreateValidatorForLoad(
563 std::unique_ptr<em::PolicyFetchResponse> policy) { 351 std::unique_ptr<em::PolicyFetchResponse> policy) {
564 std::unique_ptr<UserCloudPolicyValidator> validator = CreateValidator( 352 std::unique_ptr<UserCloudPolicyValidator> validator = CreateValidator(
565 std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_NOT_BEFORE); 353 std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_NOT_BEFORE);
566 validator->ValidateUsername(account_id_.GetUserEmail(), true); 354 validator->ValidateUsername(account_id_.GetUserEmail(), true);
567 const bool allow_rotation = false; 355 const bool allow_rotation = false;
568 const std::string empty_key = std::string(); 356 const std::string empty_key = std::string();
569 // The policy loaded from session manager need not be validated using the 357 // The policy loaded from session manager need not be validated using the
570 // verification key since it is secure, and since there may be legacy policy 358 // verification key since it is secure. Hence passing an empty value for the
571 // data that was stored without a verification key. Hence passing an empty 359 // verification key.
Andrew T Wilson (Slow) 2016/11/08 15:50:40 Actually, the "legacy policy" described in this co
572 // value for the verification key.
573 validator->ValidateSignature(policy_key_, empty_key, 360 validator->ValidateSignature(policy_key_, empty_key,
574 ExtractDomain(account_id_.GetUserEmail()), 361 ExtractDomain(account_id_.GetUserEmail()),
575 allow_rotation); 362 allow_rotation);
576 return validator; 363 return validator;
577 } 364 }
578 } // namespace policy 365 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698