| 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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| 11 #include "base/location.h" | 11 #include "base/location.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
| 14 #include "base/sequenced_task_runner.h" | 14 #include "base/sequenced_task_runner.h" |
| 15 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
| 16 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
| 17 #include "chrome/browser/chromeos/policy/user_policy_disk_cache.h" | 17 #include "chrome/browser/chromeos/policy/user_policy_disk_cache.h" |
| 18 #include "chrome/browser/chromeos/policy/user_policy_token_loader.h" | 18 #include "chrome/browser/chromeos/policy/user_policy_token_loader.h" |
| 19 #include "chromeos/dbus/cryptohome_client.h" | 19 #include "chromeos/dbus/cryptohome_client.h" |
| 20 #include "chromeos/dbus/session_manager_client.h" | 20 #include "chromeos/dbus/session_manager_client.h" |
| 21 #include "components/policy/core/common/cloud/cloud_policy_constants.h" |
| 21 #include "google_apis/gaia/gaia_auth_util.h" | 22 #include "google_apis/gaia/gaia_auth_util.h" |
| 22 #include "policy/proto/cloud_policy.pb.h" | 23 #include "policy/proto/cloud_policy.pb.h" |
| 23 #include "policy/proto/device_management_local.pb.h" | 24 #include "policy/proto/device_management_local.pb.h" |
| 24 | 25 |
| 25 namespace em = enterprise_management; | 26 namespace em = enterprise_management; |
| 26 | 27 |
| 27 namespace policy { | 28 namespace policy { |
| 28 | 29 |
| 29 namespace { | 30 namespace { |
| 30 | 31 |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 policy_key_path_ = user_policy_key_dir_.Append( | 249 policy_key_path_ = user_policy_key_dir_.Append( |
| 249 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str())); | 250 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str())); |
| 250 LoadPolicyKey(policy_key_path_, &policy_key_); | 251 LoadPolicyKey(policy_key_path_, &policy_key_); |
| 251 policy_key_loaded_ = true; | 252 policy_key_loaded_ = true; |
| 252 | 253 |
| 253 scoped_ptr<UserCloudPolicyValidator> validator = | 254 scoped_ptr<UserCloudPolicyValidator> validator = |
| 254 CreateValidator(policy.Pass(), | 255 CreateValidator(policy.Pass(), |
| 255 CloudPolicyValidatorBase::TIMESTAMP_REQUIRED); | 256 CloudPolicyValidatorBase::TIMESTAMP_REQUIRED); |
| 256 validator->ValidateUsername(username_); | 257 validator->ValidateUsername(username_); |
| 257 const bool allow_rotation = false; | 258 const bool allow_rotation = false; |
| 258 validator->ValidateSignature(policy_key_, allow_rotation); | 259 validator->ValidateSignature( |
| 260 policy_key_, |
| 261 GetPolicyVerificationKey(), |
| 262 std::string(), // No signature verification needed. |
| 263 allow_rotation); |
| 259 validator->RunValidation(); | 264 validator->RunValidation(); |
| 260 OnRetrievedPolicyValidated(validator.get()); | 265 OnRetrievedPolicyValidated(validator.get()); |
| 261 } | 266 } |
| 262 | 267 |
| 263 void UserCloudPolicyStoreChromeOS::ValidatePolicyForStore( | 268 void UserCloudPolicyStoreChromeOS::ValidatePolicyForStore( |
| 264 scoped_ptr<em::PolicyFetchResponse> policy) { | 269 scoped_ptr<em::PolicyFetchResponse> policy) { |
| 265 // Create and configure a validator. | 270 // Create and configure a validator. |
| 266 scoped_ptr<UserCloudPolicyValidator> validator = | 271 scoped_ptr<UserCloudPolicyValidator> validator = |
| 267 CreateValidator(policy.Pass(), | 272 CreateValidator(policy.Pass(), |
| 268 CloudPolicyValidatorBase::TIMESTAMP_REQUIRED); | 273 CloudPolicyValidatorBase::TIMESTAMP_REQUIRED); |
| 269 validator->ValidateUsername(username_); | 274 validator->ValidateUsername(username_); |
| 270 if (policy_key_.empty()) { | 275 if (policy_key_.empty()) { |
| 271 validator->ValidateInitialKey(); | 276 validator->ValidateInitialKey(GetPolicyVerificationKey()); |
| 272 } else { | 277 } else { |
| 273 const bool allow_rotation = true; | 278 const bool allow_rotation = true; |
| 274 validator->ValidateSignature(policy_key_, allow_rotation); | 279 validator->ValidateSignature(policy_key_, |
| 280 GetPolicyVerificationKey(), |
| 281 std::string(), |
| 282 allow_rotation); |
| 275 } | 283 } |
| 276 | 284 |
| 277 // Start validation. The Validator will delete itself once validation is | 285 // Start validation. The Validator will delete itself once validation is |
| 278 // complete. | 286 // complete. |
| 279 validator.release()->StartValidation( | 287 validator.release()->StartValidation( |
| 280 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyToStoreValidated, | 288 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyToStoreValidated, |
| 281 weak_factory_.GetWeakPtr())); | 289 weak_factory_.GetWeakPtr())); |
| 282 } | 290 } |
| 283 | 291 |
| 284 void UserCloudPolicyStoreChromeOS::OnPolicyToStoreValidated( | 292 void UserCloudPolicyStoreChromeOS::OnPolicyToStoreValidated( |
| 285 UserCloudPolicyValidator* validator) { | 293 UserCloudPolicyValidator* validator) { |
| 286 validation_status_ = validator->status(); | 294 validation_status_ = validator->status(); |
| 287 | 295 |
| 288 UMA_HISTOGRAM_ENUMERATION( | 296 UMA_HISTOGRAM_ENUMERATION( |
| 289 "Enterprise.UserPolicyValidationStoreStatus", | 297 "Enterprise.UserPolicyValidationStoreStatus", |
| 290 validation_status_, | 298 validation_status_, |
| 291 UserCloudPolicyValidator::VALIDATION_POLICY_PARSE_ERROR + 1); | 299 UserCloudPolicyValidator::VALIDATION_STATUS_SIZE); |
| 292 | 300 |
| 293 if (!validator->success()) { | 301 if (!validator->success()) { |
| 294 status_ = STATUS_VALIDATION_ERROR; | 302 status_ = STATUS_VALIDATION_ERROR; |
| 295 NotifyStoreError(); | 303 NotifyStoreError(); |
| 296 return; | 304 return; |
| 297 } | 305 } |
| 298 | 306 |
| 299 std::string policy_blob; | 307 std::string policy_blob; |
| 300 if (!validator->policy()->SerializeToString(&policy_blob)) { | 308 if (!validator->policy()->SerializeToString(&policy_blob)) { |
| 301 status_ = STATUS_SERIALIZE_ERROR; | 309 status_ = STATUS_SERIALIZE_ERROR; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 } | 368 } |
| 361 | 369 |
| 362 void UserCloudPolicyStoreChromeOS::ValidateRetrievedPolicy( | 370 void UserCloudPolicyStoreChromeOS::ValidateRetrievedPolicy( |
| 363 scoped_ptr<em::PolicyFetchResponse> policy) { | 371 scoped_ptr<em::PolicyFetchResponse> policy) { |
| 364 // Create and configure a validator for the loaded policy. | 372 // Create and configure a validator for the loaded policy. |
| 365 scoped_ptr<UserCloudPolicyValidator> validator = | 373 scoped_ptr<UserCloudPolicyValidator> validator = |
| 366 CreateValidator(policy.Pass(), | 374 CreateValidator(policy.Pass(), |
| 367 CloudPolicyValidatorBase::TIMESTAMP_REQUIRED); | 375 CloudPolicyValidatorBase::TIMESTAMP_REQUIRED); |
| 368 validator->ValidateUsername(username_); | 376 validator->ValidateUsername(username_); |
| 369 const bool allow_rotation = false; | 377 const bool allow_rotation = false; |
| 370 validator->ValidateSignature(policy_key_, allow_rotation); | 378 validator->ValidateSignature(policy_key_, |
| 379 GetPolicyVerificationKey(), |
| 380 std::string(), |
| 381 allow_rotation); |
| 371 // Start validation. The Validator will delete itself once validation is | 382 // Start validation. The Validator will delete itself once validation is |
| 372 // complete. | 383 // complete. |
| 373 validator.release()->StartValidation( | 384 validator.release()->StartValidation( |
| 374 base::Bind(&UserCloudPolicyStoreChromeOS::OnRetrievedPolicyValidated, | 385 base::Bind(&UserCloudPolicyStoreChromeOS::OnRetrievedPolicyValidated, |
| 375 weak_factory_.GetWeakPtr())); | 386 weak_factory_.GetWeakPtr())); |
| 376 } | 387 } |
| 377 | 388 |
| 378 void UserCloudPolicyStoreChromeOS::OnRetrievedPolicyValidated( | 389 void UserCloudPolicyStoreChromeOS::OnRetrievedPolicyValidated( |
| 379 UserCloudPolicyValidator* validator) { | 390 UserCloudPolicyValidator* validator) { |
| 380 validation_status_ = validator->status(); | 391 validation_status_ = validator->status(); |
| 381 | 392 |
| 382 UMA_HISTOGRAM_ENUMERATION( | 393 UMA_HISTOGRAM_ENUMERATION( |
| 383 "Enterprise.UserPolicyValidationLoadStatus", | 394 "Enterprise.UserPolicyValidationLoadStatus", |
| 384 validation_status_, | 395 validation_status_, |
| 385 UserCloudPolicyValidator::VALIDATION_POLICY_PARSE_ERROR + 1); | 396 UserCloudPolicyValidator::VALIDATION_STATUS_SIZE); |
| 386 | 397 |
| 387 if (!validator->success()) { | 398 if (!validator->success()) { |
| 388 status_ = STATUS_VALIDATION_ERROR; | 399 status_ = STATUS_VALIDATION_ERROR; |
| 389 NotifyStoreError(); | 400 NotifyStoreError(); |
| 390 return; | 401 return; |
| 391 } | 402 } |
| 392 | 403 |
| 393 InstallPolicy(validator->policy_data().Pass(), validator->payload().Pass()); | 404 InstallPolicy(validator->policy_data().Pass(), validator->payload().Pass()); |
| 394 status_ = STATUS_OK; | 405 status_ = STATUS_OK; |
| 395 | 406 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 | 479 |
| 469 // static | 480 // static |
| 470 void UserCloudPolicyStoreChromeOS::RemoveLegacyCacheDir( | 481 void UserCloudPolicyStoreChromeOS::RemoveLegacyCacheDir( |
| 471 const base::FilePath& dir) { | 482 const base::FilePath& dir) { |
| 472 if (base::PathExists(dir) && !base::DeleteFile(dir, true)) | 483 if (base::PathExists(dir) && !base::DeleteFile(dir, true)) |
| 473 LOG(ERROR) << "Failed to remove cache dir " << dir.value(); | 484 LOG(ERROR) << "Failed to remove cache dir " << dir.value(); |
| 474 } | 485 } |
| 475 | 486 |
| 476 void UserCloudPolicyStoreChromeOS::ReloadPolicyKey( | 487 void UserCloudPolicyStoreChromeOS::ReloadPolicyKey( |
| 477 const base::Closure& callback) { | 488 const base::Closure& callback) { |
| 478 std::vector<uint8>* key = new std::vector<uint8>(); | 489 std::string* key = new std::string(); |
| 479 background_task_runner()->PostTaskAndReply( | 490 background_task_runner()->PostTaskAndReply( |
| 480 FROM_HERE, | 491 FROM_HERE, |
| 481 base::Bind(&UserCloudPolicyStoreChromeOS::LoadPolicyKey, | 492 base::Bind(&UserCloudPolicyStoreChromeOS::LoadPolicyKey, |
| 482 policy_key_path_, | 493 policy_key_path_, |
| 483 key), | 494 key), |
| 484 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyKeyReloaded, | 495 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyKeyReloaded, |
| 485 weak_factory_.GetWeakPtr(), | 496 weak_factory_.GetWeakPtr(), |
| 486 base::Owned(key), | 497 base::Owned(key), |
| 487 callback)); | 498 callback)); |
| 488 } | 499 } |
| 489 | 500 |
| 490 // static | 501 // static |
| 491 void UserCloudPolicyStoreChromeOS::LoadPolicyKey(const base::FilePath& path, | 502 void UserCloudPolicyStoreChromeOS::LoadPolicyKey(const base::FilePath& path, |
| 492 std::vector<uint8>* key) { | 503 std::string* key) { |
| 493 if (!base::PathExists(path)) { | 504 if (!base::PathExists(path)) { |
| 494 // There is no policy key the first time that a user fetches policy. If | 505 // There is no policy key the first time that a user fetches policy. If |
| 495 // |path| does not exist then that is the most likely scenario, so there's | 506 // |path| does not exist then that is the most likely scenario, so there's |
| 496 // no need to sample a failure. | 507 // no need to sample a failure. |
| 497 VLOG(1) << "No key at " << path.value(); | 508 VLOG(1) << "No key at " << path.value(); |
| 498 return; | 509 return; |
| 499 } | 510 } |
| 500 | 511 |
| 501 int64 size; | 512 int64 size; |
| 513 key->clear(); |
| 502 if (!base::GetFileSize(path, &size)) { | 514 if (!base::GetFileSize(path, &size)) { |
| 503 LOG(ERROR) << "Could not get size of " << path.value(); | 515 LOG(ERROR) << "Could not get size of " << path.value(); |
| 504 } else if (size == 0 || size > kKeySizeLimit) { | 516 } else if (size == 0 || size > kKeySizeLimit) { |
| 505 LOG(ERROR) << "Key at " << path.value() << " has bad size " << size; | 517 LOG(ERROR) << "Key at " << path.value() << " has bad size " << size; |
| 506 } else { | 518 } else { |
| 507 key->resize(size); | 519 char buf[size]; |
| 508 int read_size = base::ReadFile( | 520 int read_size = base::ReadFile(path, buf, size); |
| 509 path, reinterpret_cast<char*>(vector_as_array(key)), size); | |
| 510 if (read_size != size) { | 521 if (read_size != size) { |
| 511 LOG(ERROR) << "Failed to read key at " << path.value(); | 522 LOG(ERROR) << "Failed to read key at " << path.value(); |
| 512 key->clear(); | 523 } else { |
| 524 key->append(buf, size); |
| 513 } | 525 } |
| 514 } | 526 } |
| 515 | 527 |
| 516 if (key->empty()) | 528 if (key->empty()) |
| 517 SampleValidationFailure(VALIDATION_FAILURE_LOAD_KEY); | 529 SampleValidationFailure(VALIDATION_FAILURE_LOAD_KEY); |
| 518 } | 530 } |
| 519 | 531 |
| 520 void UserCloudPolicyStoreChromeOS::OnPolicyKeyReloaded( | 532 void UserCloudPolicyStoreChromeOS::OnPolicyKeyReloaded( |
| 521 std::vector<uint8>* key, | 533 std::string* key, |
| 522 const base::Closure& callback) { | 534 const base::Closure& callback) { |
| 523 policy_key_.swap(*key); | 535 policy_key_ = *key; |
| 524 policy_key_loaded_ = true; | 536 policy_key_loaded_ = true; |
| 525 callback.Run(); | 537 callback.Run(); |
| 526 } | 538 } |
| 527 | 539 |
| 528 void UserCloudPolicyStoreChromeOS::EnsurePolicyKeyLoaded( | 540 void UserCloudPolicyStoreChromeOS::EnsurePolicyKeyLoaded( |
| 529 const base::Closure& callback) { | 541 const base::Closure& callback) { |
| 530 if (policy_key_loaded_) { | 542 if (policy_key_loaded_) { |
| 531 callback.Run(); | 543 callback.Run(); |
| 532 } else { | 544 } else { |
| 533 // Get the hashed username that's part of the key's path, to determine | 545 // Get the hashed username that's part of the key's path, to determine |
| (...skipping 14 matching lines...) Expand all Loading... |
| 548 !sanitized_username.empty()) { | 560 !sanitized_username.empty()) { |
| 549 policy_key_path_ = user_policy_key_dir_.Append( | 561 policy_key_path_ = user_policy_key_dir_.Append( |
| 550 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str())); | 562 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str())); |
| 551 } else { | 563 } else { |
| 552 SampleValidationFailure(VALIDATION_FAILURE_DBUS); | 564 SampleValidationFailure(VALIDATION_FAILURE_DBUS); |
| 553 } | 565 } |
| 554 ReloadPolicyKey(callback); | 566 ReloadPolicyKey(callback); |
| 555 } | 567 } |
| 556 | 568 |
| 557 } // namespace policy | 569 } // namespace policy |
| OLD | NEW |