| 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_), |
| 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_)); |
| 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_)); |
| 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_), 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 cryptohome::Identification(account_id_), |
| 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 |