| 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" |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 chromeos::CryptohomeClient* cryptohome_client, | 65 chromeos::CryptohomeClient* cryptohome_client, |
| 66 chromeos::SessionManagerClient* session_manager_client, | 66 chromeos::SessionManagerClient* session_manager_client, |
| 67 scoped_refptr<base::SequencedTaskRunner> background_task_runner, | 67 scoped_refptr<base::SequencedTaskRunner> background_task_runner, |
| 68 const AccountId& account_id, | 68 const AccountId& account_id, |
| 69 const base::FilePath& user_policy_key_dir) | 69 const base::FilePath& user_policy_key_dir) |
| 70 : UserCloudPolicyStoreBase(background_task_runner), | 70 : UserCloudPolicyStoreBase(background_task_runner), |
| 71 cryptohome_client_(cryptohome_client), | 71 cryptohome_client_(cryptohome_client), |
| 72 session_manager_client_(session_manager_client), | 72 session_manager_client_(session_manager_client), |
| 73 account_id_(account_id), | 73 account_id_(account_id), |
| 74 user_policy_key_dir_(user_policy_key_dir), | 74 user_policy_key_dir_(user_policy_key_dir), |
| 75 policy_key_loaded_(false), | |
| 76 weak_factory_(this) {} | 75 weak_factory_(this) {} |
| 77 | 76 |
| 78 UserCloudPolicyStoreChromeOS::~UserCloudPolicyStoreChromeOS() {} | 77 UserCloudPolicyStoreChromeOS::~UserCloudPolicyStoreChromeOS() {} |
| 79 | 78 |
| 80 void UserCloudPolicyStoreChromeOS::Store( | 79 void UserCloudPolicyStoreChromeOS::Store( |
| 81 const em::PolicyFetchResponse& policy) { | 80 const em::PolicyFetchResponse& policy) { |
| 82 // Cancel all pending requests. | 81 // Cancel all pending requests. |
| 83 weak_factory_.InvalidateWeakPtrs(); | 82 weak_factory_.InvalidateWeakPtrs(); |
| 84 std::unique_ptr<em::PolicyFetchResponse> response( | 83 std::unique_ptr<em::PolicyFetchResponse> response( |
| 85 new em::PolicyFetchResponse(policy)); | 84 new em::PolicyFetchResponse(policy)); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 | 125 |
| 127 std::string sanitized_username = | 126 std::string sanitized_username = |
| 128 cryptohome_client_->BlockingGetSanitizedUsername( | 127 cryptohome_client_->BlockingGetSanitizedUsername( |
| 129 cryptohome::Identification(account_id_)); | 128 cryptohome::Identification(account_id_)); |
| 130 if (sanitized_username.empty()) { | 129 if (sanitized_username.empty()) { |
| 131 status_ = STATUS_LOAD_ERROR; | 130 status_ = STATUS_LOAD_ERROR; |
| 132 NotifyStoreError(); | 131 NotifyStoreError(); |
| 133 return; | 132 return; |
| 134 } | 133 } |
| 135 | 134 |
| 136 policy_key_path_ = user_policy_key_dir_.Append( | 135 cached_policy_key_path_ = user_policy_key_dir_.Append( |
| 137 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str())); | 136 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str())); |
| 138 LoadPolicyKey(policy_key_path_, &policy_key_); | 137 LoadPolicyKey(cached_policy_key_path_, &cached_policy_key_); |
| 139 policy_key_loaded_ = true; | 138 cached_policy_key_loaded_ = true; |
| 140 | 139 |
| 141 std::unique_ptr<UserCloudPolicyValidator> validator = | 140 std::unique_ptr<UserCloudPolicyValidator> validator = |
| 142 CreateValidatorForLoad(std::move(policy)); | 141 CreateValidatorForLoad(std::move(policy)); |
| 143 validator->RunValidation(); | 142 validator->RunValidation(); |
| 144 OnRetrievedPolicyValidated(validator.get()); | 143 OnRetrievedPolicyValidated(validator.get()); |
| 145 } | 144 } |
| 146 | 145 |
| 147 void UserCloudPolicyStoreChromeOS::ValidatePolicyForStore( | 146 void UserCloudPolicyStoreChromeOS::ValidatePolicyForStore( |
| 148 std::unique_ptr<em::PolicyFetchResponse> policy) { | 147 std::unique_ptr<em::PolicyFetchResponse> policy) { |
| 149 // Create and configure a validator. | 148 // Create and configure a validator. |
| 150 std::unique_ptr<UserCloudPolicyValidator> validator = CreateValidator( | 149 std::unique_ptr<UserCloudPolicyValidator> validator = CreateValidator( |
| 151 std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_FULLY_VALIDATED); | 150 std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_FULLY_VALIDATED); |
| 152 validator->ValidateUsername(account_id_.GetUserEmail(), true); | 151 validator->ValidateUsername(account_id_.GetUserEmail(), true); |
| 153 if (policy_key_.empty()) { | 152 if (cached_policy_key_.empty()) { |
| 154 validator->ValidateInitialKey(GetPolicyVerificationKey(), | 153 validator->ValidateInitialKey(GetPolicyVerificationKey(), |
| 155 ExtractDomain(account_id_.GetUserEmail())); | 154 ExtractDomain(account_id_.GetUserEmail())); |
| 156 } else { | 155 } else { |
| 157 validator->ValidateSignatureAllowingRotation( | 156 validator->ValidateSignatureAllowingRotation( |
| 158 policy_key_, GetPolicyVerificationKey(), | 157 cached_policy_key_, GetPolicyVerificationKey(), |
| 159 ExtractDomain(account_id_.GetUserEmail())); | 158 ExtractDomain(account_id_.GetUserEmail())); |
| 160 } | 159 } |
| 161 | 160 |
| 162 // Start validation. The Validator will delete itself once validation is | 161 // Start validation. The Validator will delete itself once validation is |
| 163 // complete. | 162 // complete. |
| 164 validator.release()->StartValidation( | 163 validator.release()->StartValidation( |
| 165 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyToStoreValidated, | 164 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyToStoreValidated, |
| 166 weak_factory_.GetWeakPtr())); | 165 weak_factory_.GetWeakPtr())); |
| 167 } | 166 } |
| 168 | 167 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 ReloadPolicyKey(base::Bind(&UserCloudPolicyStoreChromeOS::Load, | 204 ReloadPolicyKey(base::Bind(&UserCloudPolicyStoreChromeOS::Load, |
| 206 weak_factory_.GetWeakPtr())); | 205 weak_factory_.GetWeakPtr())); |
| 207 } | 206 } |
| 208 } | 207 } |
| 209 | 208 |
| 210 void UserCloudPolicyStoreChromeOS::OnPolicyRetrieved( | 209 void UserCloudPolicyStoreChromeOS::OnPolicyRetrieved( |
| 211 const std::string& policy_blob) { | 210 const std::string& policy_blob) { |
| 212 if (policy_blob.empty()) { | 211 if (policy_blob.empty()) { |
| 213 // session_manager doesn't have policy. Adjust internal state and notify | 212 // session_manager doesn't have policy. Adjust internal state and notify |
| 214 // the world about the policy update. | 213 // the world about the policy update. |
| 214 policy_map_.Clear(); |
| 215 policy_.reset(); | 215 policy_.reset(); |
| 216 policy_signature_public_key_.clear(); |
| 216 NotifyStoreLoaded(); | 217 NotifyStoreLoaded(); |
| 217 return; | 218 return; |
| 218 } | 219 } |
| 219 | 220 |
| 220 std::unique_ptr<em::PolicyFetchResponse> policy( | 221 std::unique_ptr<em::PolicyFetchResponse> policy( |
| 221 new em::PolicyFetchResponse()); | 222 new em::PolicyFetchResponse()); |
| 222 if (!policy->ParseFromString(policy_blob)) { | 223 if (!policy->ParseFromString(policy_blob)) { |
| 223 status_ = STATUS_PARSE_ERROR; | 224 status_ = STATUS_PARSE_ERROR; |
| 224 NotifyStoreError(); | 225 NotifyStoreError(); |
| 225 return; | 226 return; |
| 226 } | 227 } |
| 227 | 228 |
| 228 // Load |policy_key_| to verify the loaded policy. | 229 // Load |cached_policy_key_| to verify the loaded policy. |
| 229 EnsurePolicyKeyLoaded( | 230 EnsurePolicyKeyLoaded( |
| 230 base::Bind(&UserCloudPolicyStoreChromeOS::ValidateRetrievedPolicy, | 231 base::Bind(&UserCloudPolicyStoreChromeOS::ValidateRetrievedPolicy, |
| 231 weak_factory_.GetWeakPtr(), | 232 weak_factory_.GetWeakPtr(), |
| 232 base::Passed(&policy))); | 233 base::Passed(&policy))); |
| 233 } | 234 } |
| 234 | 235 |
| 235 void UserCloudPolicyStoreChromeOS::ValidateRetrievedPolicy( | 236 void UserCloudPolicyStoreChromeOS::ValidateRetrievedPolicy( |
| 236 std::unique_ptr<em::PolicyFetchResponse> policy) { | 237 std::unique_ptr<em::PolicyFetchResponse> policy) { |
| 237 // Create and configure a validator for the loaded policy. | 238 // Create and configure a validator for the loaded policy. |
| 238 std::unique_ptr<UserCloudPolicyValidator> validator = | 239 std::unique_ptr<UserCloudPolicyValidator> validator = |
| (...skipping 14 matching lines...) Expand all Loading... |
| 253 validation_status_, | 254 validation_status_, |
| 254 UserCloudPolicyValidator::VALIDATION_STATUS_SIZE); | 255 UserCloudPolicyValidator::VALIDATION_STATUS_SIZE); |
| 255 | 256 |
| 256 if (!validator->success()) { | 257 if (!validator->success()) { |
| 257 status_ = STATUS_VALIDATION_ERROR; | 258 status_ = STATUS_VALIDATION_ERROR; |
| 258 NotifyStoreError(); | 259 NotifyStoreError(); |
| 259 return; | 260 return; |
| 260 } | 261 } |
| 261 | 262 |
| 262 InstallPolicy(std::move(validator->policy_data()), | 263 InstallPolicy(std::move(validator->policy_data()), |
| 263 std::move(validator->payload())); | 264 std::move(validator->payload()), cached_policy_key_); |
| 264 status_ = STATUS_OK; | 265 status_ = STATUS_OK; |
| 265 | 266 |
| 266 NotifyStoreLoaded(); | 267 NotifyStoreLoaded(); |
| 267 } | 268 } |
| 268 | 269 |
| 269 void UserCloudPolicyStoreChromeOS::ReloadPolicyKey( | 270 void UserCloudPolicyStoreChromeOS::ReloadPolicyKey( |
| 270 const base::Closure& callback) { | 271 const base::Closure& callback) { |
| 271 std::string* key = new std::string(); | 272 std::string* key = new std::string(); |
| 272 background_task_runner()->PostTaskAndReply( | 273 background_task_runner()->PostTaskAndReply( |
| 273 FROM_HERE, | 274 FROM_HERE, base::Bind(&UserCloudPolicyStoreChromeOS::LoadPolicyKey, |
| 274 base::Bind(&UserCloudPolicyStoreChromeOS::LoadPolicyKey, | 275 cached_policy_key_path_, key), |
| 275 policy_key_path_, | |
| 276 key), | |
| 277 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyKeyReloaded, | 276 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyKeyReloaded, |
| 278 weak_factory_.GetWeakPtr(), | 277 weak_factory_.GetWeakPtr(), base::Owned(key), callback)); |
| 279 base::Owned(key), | |
| 280 callback)); | |
| 281 } | 278 } |
| 282 | 279 |
| 283 // static | 280 // static |
| 284 void UserCloudPolicyStoreChromeOS::LoadPolicyKey(const base::FilePath& path, | 281 void UserCloudPolicyStoreChromeOS::LoadPolicyKey(const base::FilePath& path, |
| 285 std::string* key) { | 282 std::string* key) { |
| 286 if (!base::PathExists(path)) { | 283 if (!base::PathExists(path)) { |
| 287 // There is no policy key the first time that a user fetches policy. If | 284 // There is no policy key the first time that a user fetches policy. If |
| 288 // |path| does not exist then that is the most likely scenario, so there's | 285 // |path| does not exist then that is the most likely scenario, so there's |
| 289 // no need to sample a failure. | 286 // no need to sample a failure. |
| 290 VLOG(1) << "No key at " << path.value(); | 287 VLOG(1) << "No key at " << path.value(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 304 LOG(ERROR) << "Failed to read key at " << path.value(); | 301 LOG(ERROR) << "Failed to read key at " << path.value(); |
| 305 } | 302 } |
| 306 | 303 |
| 307 if (key->empty()) | 304 if (key->empty()) |
| 308 SampleValidationFailure(VALIDATION_FAILURE_LOAD_KEY); | 305 SampleValidationFailure(VALIDATION_FAILURE_LOAD_KEY); |
| 309 } | 306 } |
| 310 | 307 |
| 311 void UserCloudPolicyStoreChromeOS::OnPolicyKeyReloaded( | 308 void UserCloudPolicyStoreChromeOS::OnPolicyKeyReloaded( |
| 312 std::string* key, | 309 std::string* key, |
| 313 const base::Closure& callback) { | 310 const base::Closure& callback) { |
| 314 policy_key_ = *key; | 311 cached_policy_key_ = *key; |
| 315 policy_key_loaded_ = true; | 312 cached_policy_key_loaded_ = true; |
| 316 callback.Run(); | 313 callback.Run(); |
| 317 } | 314 } |
| 318 | 315 |
| 319 void UserCloudPolicyStoreChromeOS::EnsurePolicyKeyLoaded( | 316 void UserCloudPolicyStoreChromeOS::EnsurePolicyKeyLoaded( |
| 320 const base::Closure& callback) { | 317 const base::Closure& callback) { |
| 321 if (policy_key_loaded_) { | 318 if (cached_policy_key_loaded_) { |
| 322 callback.Run(); | 319 callback.Run(); |
| 323 } else { | 320 } else { |
| 324 // Get the hashed username that's part of the key's path, to determine | 321 // Get the hashed username that's part of the key's path, to determine |
| 325 // |policy_key_path_|. | 322 // |cached_policy_key_path_|. |
| 326 cryptohome_client_->GetSanitizedUsername( | 323 cryptohome_client_->GetSanitizedUsername( |
| 327 cryptohome::Identification(account_id_), | 324 cryptohome::Identification(account_id_), |
| 328 base::Bind(&UserCloudPolicyStoreChromeOS::OnGetSanitizedUsername, | 325 base::Bind(&UserCloudPolicyStoreChromeOS::OnGetSanitizedUsername, |
| 329 weak_factory_.GetWeakPtr(), callback)); | 326 weak_factory_.GetWeakPtr(), callback)); |
| 330 } | 327 } |
| 331 } | 328 } |
| 332 | 329 |
| 333 void UserCloudPolicyStoreChromeOS::OnGetSanitizedUsername( | 330 void UserCloudPolicyStoreChromeOS::OnGetSanitizedUsername( |
| 334 const base::Closure& callback, | 331 const base::Closure& callback, |
| 335 chromeos::DBusMethodCallStatus call_status, | 332 chromeos::DBusMethodCallStatus call_status, |
| 336 const std::string& sanitized_username) { | 333 const std::string& sanitized_username) { |
| 337 // The default empty path will always yield an empty key. | 334 // The default empty path will always yield an empty key. |
| 338 if (call_status == chromeos::DBUS_METHOD_CALL_SUCCESS && | 335 if (call_status == chromeos::DBUS_METHOD_CALL_SUCCESS && |
| 339 !sanitized_username.empty()) { | 336 !sanitized_username.empty()) { |
| 340 policy_key_path_ = user_policy_key_dir_.Append( | 337 cached_policy_key_path_ = user_policy_key_dir_.Append( |
| 341 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str())); | 338 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str())); |
| 342 } else { | 339 } else { |
| 343 SampleValidationFailure(VALIDATION_FAILURE_DBUS); | 340 SampleValidationFailure(VALIDATION_FAILURE_DBUS); |
| 344 } | 341 } |
| 345 ReloadPolicyKey(callback); | 342 ReloadPolicyKey(callback); |
| 346 } | 343 } |
| 347 | 344 |
| 348 std::unique_ptr<UserCloudPolicyValidator> | 345 std::unique_ptr<UserCloudPolicyValidator> |
| 349 UserCloudPolicyStoreChromeOS::CreateValidatorForLoad( | 346 UserCloudPolicyStoreChromeOS::CreateValidatorForLoad( |
| 350 std::unique_ptr<em::PolicyFetchResponse> policy) { | 347 std::unique_ptr<em::PolicyFetchResponse> policy) { |
| 351 std::unique_ptr<UserCloudPolicyValidator> validator = CreateValidator( | 348 std::unique_ptr<UserCloudPolicyValidator> validator = CreateValidator( |
| 352 std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_NOT_BEFORE); | 349 std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_NOT_BEFORE); |
| 353 validator->ValidateUsername(account_id_.GetUserEmail(), true); | 350 validator->ValidateUsername(account_id_.GetUserEmail(), true); |
| 354 // The policy loaded from session manager need not be validated using the | 351 // The policy loaded from session manager need not be validated using the |
| 355 // verification key since it is secure, and since there may be legacy policy | 352 // verification key since it is secure, and since there may be legacy policy |
| 356 // data that was stored without a verification key. | 353 // data that was stored without a verification key. |
| 357 validator->ValidateSignature(policy_key_); | 354 validator->ValidateSignature(cached_policy_key_); |
| 358 return validator; | 355 return validator; |
| 359 } | 356 } |
| 357 |
| 360 } // namespace policy | 358 } // namespace policy |
| OLD | NEW |