OLD | NEW |
---|---|
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" |
11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
12 #include "base/callback.h" | 12 #include "base/callback.h" |
13 #include "base/files/file_util.h" | 13 #include "base/files/file_util.h" |
14 #include "base/location.h" | 14 #include "base/location.h" |
15 #include "base/logging.h" | 15 #include "base/logging.h" |
16 #include "base/macros.h" | 16 #include "base/macros.h" |
17 #include "base/metrics/histogram.h" | 17 #include "base/metrics/histogram.h" |
18 #include "base/sequenced_task_runner.h" | 18 #include "base/sequenced_task_runner.h" |
19 #include "base/stl_util.h" | 19 #include "base/stl_util.h" |
20 #include "base/strings/stringprintf.h" | 20 #include "base/strings/stringprintf.h" |
21 #include "chrome/browser/chromeos/policy/user_policy_disk_cache.h" | 21 #include "chrome/browser/chromeos/policy/user_policy_disk_cache.h" |
22 #include "chrome/browser/chromeos/policy/user_policy_token_loader.h" | 22 #include "chrome/browser/chromeos/policy/user_policy_token_loader.h" |
23 #include "chromeos/cryptohome/cryptohome_parameters.h" | |
23 #include "chromeos/dbus/cryptohome_client.h" | 24 #include "chromeos/dbus/cryptohome_client.h" |
24 #include "chromeos/dbus/session_manager_client.h" | 25 #include "chromeos/dbus/session_manager_client.h" |
25 #include "components/policy/core/common/cloud/cloud_policy_constants.h" | 26 #include "components/policy/core/common/cloud/cloud_policy_constants.h" |
26 #include "google_apis/gaia/gaia_auth_util.h" | 27 #include "google_apis/gaia/gaia_auth_util.h" |
27 #include "policy/proto/cloud_policy.pb.h" | 28 #include "policy/proto/cloud_policy.pb.h" |
28 #include "policy/proto/device_management_local.pb.h" | 29 #include "policy/proto/device_management_local.pb.h" |
29 | 30 |
30 namespace em = enterprise_management; | 31 namespace em = enterprise_management; |
31 | 32 |
32 namespace policy { | 33 namespace policy { |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
171 return CloudPolicyStore::STATUS_LOAD_ERROR; | 172 return CloudPolicyStore::STATUS_LOAD_ERROR; |
172 } | 173 } |
173 NOTREACHED(); | 174 NOTREACHED(); |
174 return CloudPolicyStore::STATUS_OK; | 175 return CloudPolicyStore::STATUS_OK; |
175 } | 176 } |
176 | 177 |
177 UserCloudPolicyStoreChromeOS::UserCloudPolicyStoreChromeOS( | 178 UserCloudPolicyStoreChromeOS::UserCloudPolicyStoreChromeOS( |
178 chromeos::CryptohomeClient* cryptohome_client, | 179 chromeos::CryptohomeClient* cryptohome_client, |
179 chromeos::SessionManagerClient* session_manager_client, | 180 chromeos::SessionManagerClient* session_manager_client, |
180 scoped_refptr<base::SequencedTaskRunner> background_task_runner, | 181 scoped_refptr<base::SequencedTaskRunner> background_task_runner, |
181 const std::string& username, | 182 const AccountId& account_id, |
182 const base::FilePath& user_policy_key_dir, | 183 const base::FilePath& user_policy_key_dir, |
183 const base::FilePath& legacy_token_cache_file, | 184 const base::FilePath& legacy_token_cache_file, |
184 const base::FilePath& legacy_policy_cache_file) | 185 const base::FilePath& legacy_policy_cache_file) |
185 : UserCloudPolicyStoreBase(background_task_runner), | 186 : UserCloudPolicyStoreBase(background_task_runner), |
186 cryptohome_client_(cryptohome_client), | 187 cryptohome_client_(cryptohome_client), |
187 session_manager_client_(session_manager_client), | 188 session_manager_client_(session_manager_client), |
188 username_(username), | 189 account_id_(account_id), |
189 user_policy_key_dir_(user_policy_key_dir), | 190 user_policy_key_dir_(user_policy_key_dir), |
190 legacy_cache_dir_(legacy_token_cache_file.DirName()), | 191 legacy_cache_dir_(legacy_token_cache_file.DirName()), |
191 legacy_loader_(new LegacyPolicyCacheLoader(legacy_token_cache_file, | 192 legacy_loader_(new LegacyPolicyCacheLoader(legacy_token_cache_file, |
192 legacy_policy_cache_file, | 193 legacy_policy_cache_file, |
193 background_task_runner)), | 194 background_task_runner)), |
194 legacy_caches_loaded_(false), | 195 legacy_caches_loaded_(false), |
195 policy_key_loaded_(false), | 196 policy_key_loaded_(false), |
196 weak_factory_(this) {} | 197 weak_factory_(this) {} |
197 | 198 |
198 UserCloudPolicyStoreChromeOS::~UserCloudPolicyStoreChromeOS() {} | 199 UserCloudPolicyStoreChromeOS::~UserCloudPolicyStoreChromeOS() {} |
199 | 200 |
200 void UserCloudPolicyStoreChromeOS::Store( | 201 void UserCloudPolicyStoreChromeOS::Store( |
201 const em::PolicyFetchResponse& policy) { | 202 const em::PolicyFetchResponse& policy) { |
202 // Cancel all pending requests. | 203 // Cancel all pending requests. |
203 weak_factory_.InvalidateWeakPtrs(); | 204 weak_factory_.InvalidateWeakPtrs(); |
204 scoped_ptr<em::PolicyFetchResponse> response( | 205 scoped_ptr<em::PolicyFetchResponse> response( |
205 new em::PolicyFetchResponse(policy)); | 206 new em::PolicyFetchResponse(policy)); |
206 EnsurePolicyKeyLoaded( | 207 EnsurePolicyKeyLoaded( |
207 base::Bind(&UserCloudPolicyStoreChromeOS::ValidatePolicyForStore, | 208 base::Bind(&UserCloudPolicyStoreChromeOS::ValidatePolicyForStore, |
208 weak_factory_.GetWeakPtr(), | 209 weak_factory_.GetWeakPtr(), |
209 base::Passed(&response))); | 210 base::Passed(&response))); |
210 } | 211 } |
211 | 212 |
212 void UserCloudPolicyStoreChromeOS::Load() { | 213 void UserCloudPolicyStoreChromeOS::Load() { |
213 // Cancel all pending requests. | 214 // Cancel all pending requests. |
214 weak_factory_.InvalidateWeakPtrs(); | 215 weak_factory_.InvalidateWeakPtrs(); |
215 session_manager_client_->RetrievePolicyForUser( | 216 session_manager_client_->RetrievePolicyForUser( |
216 username_, | 217 cryptohome::Identification(account_id_).id(), |
217 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyRetrieved, | 218 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyRetrieved, |
218 weak_factory_.GetWeakPtr())); | 219 weak_factory_.GetWeakPtr())); |
219 } | 220 } |
220 | 221 |
221 void UserCloudPolicyStoreChromeOS::LoadImmediately() { | 222 void UserCloudPolicyStoreChromeOS::LoadImmediately() { |
222 // This blocking DBus call is in the startup path and will block the UI | 223 // This blocking DBus call is in the startup path and will block the UI |
223 // thread. This only happens when the Profile is created synchronously, which | 224 // thread. This only happens when the Profile is created synchronously, which |
224 // on ChromeOS happens whenever the browser is restarted into the same | 225 // on ChromeOS happens whenever the browser is restarted into the same |
225 // session. That happens when the browser crashes, or right after signin if | 226 // session. That happens when the browser crashes, or right after signin if |
226 // the user has flags configured in about:flags. | 227 // the user has flags configured in about:flags. |
227 // However, on those paths we must load policy synchronously so that the | 228 // However, on those paths we must load policy synchronously so that the |
228 // Profile initialization never sees unmanaged prefs, which would lead to | 229 // Profile initialization never sees unmanaged prefs, which would lead to |
229 // data loss. http://crbug.com/263061 | 230 // data loss. http://crbug.com/263061 |
230 std::string policy_blob = | 231 std::string policy_blob = |
231 session_manager_client_->BlockingRetrievePolicyForUser(username_); | 232 session_manager_client_->BlockingRetrievePolicyForUser( |
233 cryptohome::Identification(account_id_).id()); | |
232 if (policy_blob.empty()) { | 234 if (policy_blob.empty()) { |
233 // The session manager doesn't have policy, or the call failed. | 235 // The session manager doesn't have policy, or the call failed. |
234 // Just notify that the load is done, and don't bother with the legacy | 236 // Just notify that the load is done, and don't bother with the legacy |
235 // caches in this case. | 237 // caches in this case. |
236 NotifyStoreLoaded(); | 238 NotifyStoreLoaded(); |
237 return; | 239 return; |
238 } | 240 } |
239 | 241 |
240 scoped_ptr<em::PolicyFetchResponse> policy(new em::PolicyFetchResponse()); | 242 scoped_ptr<em::PolicyFetchResponse> policy(new em::PolicyFetchResponse()); |
241 if (!policy->ParseFromString(policy_blob)) { | 243 if (!policy->ParseFromString(policy_blob)) { |
242 status_ = STATUS_PARSE_ERROR; | 244 status_ = STATUS_PARSE_ERROR; |
243 NotifyStoreError(); | 245 NotifyStoreError(); |
244 return; | 246 return; |
245 } | 247 } |
246 | 248 |
247 std::string sanitized_username = | 249 std::string sanitized_username = |
248 cryptohome_client_->BlockingGetSanitizedUsername(username_); | 250 cryptohome_client_->BlockingGetSanitizedUsername( |
251 cryptohome::Identification(account_id_).id()); | |
249 if (sanitized_username.empty()) { | 252 if (sanitized_username.empty()) { |
250 status_ = STATUS_LOAD_ERROR; | 253 status_ = STATUS_LOAD_ERROR; |
251 NotifyStoreError(); | 254 NotifyStoreError(); |
252 return; | 255 return; |
253 } | 256 } |
254 | 257 |
255 policy_key_path_ = user_policy_key_dir_.Append( | 258 policy_key_path_ = user_policy_key_dir_.Append( |
256 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str())); | 259 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str())); |
257 LoadPolicyKey(policy_key_path_, &policy_key_); | 260 LoadPolicyKey(policy_key_path_, &policy_key_); |
258 policy_key_loaded_ = true; | 261 policy_key_loaded_ = true; |
259 | 262 |
260 scoped_ptr<UserCloudPolicyValidator> validator = | 263 scoped_ptr<UserCloudPolicyValidator> validator = |
261 CreateValidatorForLoad(std::move(policy)); | 264 CreateValidatorForLoad(std::move(policy)); |
262 validator->RunValidation(); | 265 validator->RunValidation(); |
263 OnRetrievedPolicyValidated(validator.get()); | 266 OnRetrievedPolicyValidated(validator.get()); |
264 } | 267 } |
265 | 268 |
266 void UserCloudPolicyStoreChromeOS::ValidatePolicyForStore( | 269 void UserCloudPolicyStoreChromeOS::ValidatePolicyForStore( |
267 scoped_ptr<em::PolicyFetchResponse> policy) { | 270 scoped_ptr<em::PolicyFetchResponse> policy) { |
268 // Create and configure a validator. | 271 // Create and configure a validator. |
269 scoped_ptr<UserCloudPolicyValidator> validator = CreateValidator( | 272 scoped_ptr<UserCloudPolicyValidator> validator = CreateValidator( |
270 std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_REQUIRED); | 273 std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_REQUIRED); |
271 validator->ValidateUsername(username_, true); | 274 validator->ValidateUsername(account_id_.GetUserEmail(), true); |
272 if (policy_key_.empty()) { | 275 if (policy_key_.empty()) { |
273 validator->ValidateInitialKey(GetPolicyVerificationKey(), | 276 validator->ValidateInitialKey(GetPolicyVerificationKey(), |
274 ExtractDomain(username_)); | 277 ExtractDomain(account_id_.GetUserEmail())); |
275 } else { | 278 } else { |
276 const bool allow_rotation = true; | 279 const bool allow_rotation = true; |
277 validator->ValidateSignature(policy_key_, | 280 validator->ValidateSignature(policy_key_, GetPolicyVerificationKey(), |
278 GetPolicyVerificationKey(), | 281 ExtractDomain(account_id_.GetUserEmail()), |
279 ExtractDomain(username_), | |
280 allow_rotation); | 282 allow_rotation); |
281 } | 283 } |
282 | 284 |
283 // Start validation. The Validator will delete itself once validation is | 285 // Start validation. The Validator will delete itself once validation is |
284 // complete. | 286 // complete. |
285 validator.release()->StartValidation( | 287 validator.release()->StartValidation( |
286 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyToStoreValidated, | 288 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyToStoreValidated, |
287 weak_factory_.GetWeakPtr())); | 289 weak_factory_.GetWeakPtr())); |
288 } | 290 } |
289 | 291 |
(...skipping 13 matching lines...) Expand all Loading... | |
303 } | 305 } |
304 | 306 |
305 std::string policy_blob; | 307 std::string policy_blob; |
306 if (!validator->policy()->SerializeToString(&policy_blob)) { | 308 if (!validator->policy()->SerializeToString(&policy_blob)) { |
307 status_ = STATUS_SERIALIZE_ERROR; | 309 status_ = STATUS_SERIALIZE_ERROR; |
308 NotifyStoreError(); | 310 NotifyStoreError(); |
309 return; | 311 return; |
310 } | 312 } |
311 | 313 |
312 session_manager_client_->StorePolicyForUser( | 314 session_manager_client_->StorePolicyForUser( |
313 username_, | 315 cryptohome::Identification(account_id_).id(), policy_blob, |
314 policy_blob, | |
315 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyStored, | 316 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyStored, |
316 weak_factory_.GetWeakPtr())); | 317 weak_factory_.GetWeakPtr())); |
317 } | 318 } |
318 | 319 |
319 void UserCloudPolicyStoreChromeOS::OnPolicyStored(bool success) { | 320 void UserCloudPolicyStoreChromeOS::OnPolicyStored(bool success) { |
320 if (!success) { | 321 if (!success) { |
321 status_ = STATUS_STORE_ERROR; | 322 status_ = STATUS_STORE_ERROR; |
322 NotifyStoreError(); | 323 NotifyStoreError(); |
323 } else { | 324 } else { |
324 // Load the policy right after storing it, to make sure it was accepted by | 325 // Load the policy right after storing it, to make sure it was accepted by |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
411 const std::string& dm_token, | 412 const std::string& dm_token, |
412 const std::string& device_id, | 413 const std::string& device_id, |
413 Status status, | 414 Status status, |
414 scoped_ptr<em::PolicyFetchResponse> policy) { | 415 scoped_ptr<em::PolicyFetchResponse> policy) { |
415 status_ = status; | 416 status_ = status; |
416 if (policy.get()) { | 417 if (policy.get()) { |
417 // Create and configure a validator for the loaded legacy policy. Note that | 418 // Create and configure a validator for the loaded legacy policy. Note that |
418 // the signature on this policy is not verified. | 419 // the signature on this policy is not verified. |
419 scoped_ptr<UserCloudPolicyValidator> validator = CreateValidator( | 420 scoped_ptr<UserCloudPolicyValidator> validator = CreateValidator( |
420 std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_REQUIRED); | 421 std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_REQUIRED); |
421 validator->ValidateUsername(username_, true); | 422 validator->ValidateUsername(account_id_.GetUserEmail(), true); |
422 validator.release()->StartValidation( | 423 validator.release()->StartValidation( |
423 base::Bind(&UserCloudPolicyStoreChromeOS::OnLegacyPolicyValidated, | 424 base::Bind(&UserCloudPolicyStoreChromeOS::OnLegacyPolicyValidated, |
424 weak_factory_.GetWeakPtr(), | 425 weak_factory_.GetWeakPtr(), |
425 dm_token, | 426 dm_token, |
426 device_id)); | 427 device_id)); |
427 } else { | 428 } else { |
428 InstallLegacyTokens(dm_token, device_id); | 429 InstallLegacyTokens(dm_token, device_id); |
429 } | 430 } |
430 } | 431 } |
431 | 432 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
524 callback.Run(); | 525 callback.Run(); |
525 } | 526 } |
526 | 527 |
527 void UserCloudPolicyStoreChromeOS::EnsurePolicyKeyLoaded( | 528 void UserCloudPolicyStoreChromeOS::EnsurePolicyKeyLoaded( |
528 const base::Closure& callback) { | 529 const base::Closure& callback) { |
529 if (policy_key_loaded_) { | 530 if (policy_key_loaded_) { |
530 callback.Run(); | 531 callback.Run(); |
531 } else { | 532 } else { |
532 // Get the hashed username that's part of the key's path, to determine | 533 // Get the hashed username that's part of the key's path, to determine |
533 // |policy_key_path_|. | 534 // |policy_key_path_|. |
534 cryptohome_client_->GetSanitizedUsername(username_, | 535 cryptohome_client_->GetSanitizedUsername( |
536 account_id_.GetUserEmail(), | |
xiyuan
2016/02/17 23:14:25
Should we use cryptohome::Identification(account_i
Alexander Alekseev
2016/02/18 13:45:14
you are right.
This is why I was talking about usi
| |
535 base::Bind(&UserCloudPolicyStoreChromeOS::OnGetSanitizedUsername, | 537 base::Bind(&UserCloudPolicyStoreChromeOS::OnGetSanitizedUsername, |
536 weak_factory_.GetWeakPtr(), | 538 weak_factory_.GetWeakPtr(), callback)); |
537 callback)); | |
538 } | 539 } |
539 } | 540 } |
540 | 541 |
541 void UserCloudPolicyStoreChromeOS::OnGetSanitizedUsername( | 542 void UserCloudPolicyStoreChromeOS::OnGetSanitizedUsername( |
542 const base::Closure& callback, | 543 const base::Closure& callback, |
543 chromeos::DBusMethodCallStatus call_status, | 544 chromeos::DBusMethodCallStatus call_status, |
544 const std::string& sanitized_username) { | 545 const std::string& sanitized_username) { |
545 // The default empty path will always yield an empty key. | 546 // The default empty path will always yield an empty key. |
546 if (call_status == chromeos::DBUS_METHOD_CALL_SUCCESS && | 547 if (call_status == chromeos::DBUS_METHOD_CALL_SUCCESS && |
547 !sanitized_username.empty()) { | 548 !sanitized_username.empty()) { |
548 policy_key_path_ = user_policy_key_dir_.Append( | 549 policy_key_path_ = user_policy_key_dir_.Append( |
549 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str())); | 550 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str())); |
550 } else { | 551 } else { |
551 SampleValidationFailure(VALIDATION_FAILURE_DBUS); | 552 SampleValidationFailure(VALIDATION_FAILURE_DBUS); |
552 } | 553 } |
553 ReloadPolicyKey(callback); | 554 ReloadPolicyKey(callback); |
554 } | 555 } |
555 | 556 |
556 scoped_ptr<UserCloudPolicyValidator> | 557 scoped_ptr<UserCloudPolicyValidator> |
557 UserCloudPolicyStoreChromeOS::CreateValidatorForLoad( | 558 UserCloudPolicyStoreChromeOS::CreateValidatorForLoad( |
558 scoped_ptr<em::PolicyFetchResponse> policy) { | 559 scoped_ptr<em::PolicyFetchResponse> policy) { |
559 scoped_ptr<UserCloudPolicyValidator> validator = CreateValidator( | 560 scoped_ptr<UserCloudPolicyValidator> validator = CreateValidator( |
560 std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_NOT_BEFORE); | 561 std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_NOT_BEFORE); |
561 validator->ValidateUsername(username_, true); | 562 validator->ValidateUsername(account_id_.GetUserEmail(), true); |
562 const bool allow_rotation = false; | 563 const bool allow_rotation = false; |
563 const std::string empty_key = std::string(); | 564 const std::string empty_key = std::string(); |
564 // The policy loaded from session manager need not be validated using the | 565 // The policy loaded from session manager need not be validated using the |
565 // verification key since it is secure, and since there may be legacy policy | 566 // verification key since it is secure, and since there may be legacy policy |
566 // data that was stored without a verification key. Hence passing an empty | 567 // data that was stored without a verification key. Hence passing an empty |
567 // value for the verification key. | 568 // value for the verification key. |
568 validator->ValidateSignature( | 569 validator->ValidateSignature(policy_key_, empty_key, |
569 policy_key_, empty_key, ExtractDomain(username_), allow_rotation); | 570 ExtractDomain(account_id_.GetUserEmail()), |
571 allow_rotation); | |
570 return validator; | 572 return validator; |
571 } | 573 } |
572 } // namespace policy | 574 } // namespace policy |
OLD | NEW |