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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/chromeos/policy/device_local_account_policy_store.h" 6 7 #include "base/bind.h" 8 #include "base/callback.h" 9 #include "chrome/browser/browser_process.h" 10 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" 11 #include "chrome/browser/chromeos/settings/owner_key_util.h" 12 #include "chromeos/dbus/session_manager_client.h" 13 #include "components/policy/core/common/cloud/device_management_service.h" 14 #include "components/policy/core/common/external_data_fetcher.h" 15 #include "components/policy/core/common/policy_map.h" 16 #include "components/policy/core/common/policy_types.h" 17 #include "policy/proto/cloud_policy.pb.h" 18 #include "policy/proto/device_management_backend.pb.h" 19 20 namespace em = enterprise_management; 21 22 namespace policy { 23 24 DeviceLocalAccountPolicyStore::DeviceLocalAccountPolicyStore( 25 const std::string& account_id, 26 chromeos::SessionManagerClient* session_manager_client, 27 chromeos::DeviceSettingsService* device_settings_service, 28 scoped_refptr<base::SequencedTaskRunner> background_task_runner) 29 : UserCloudPolicyStoreBase(background_task_runner), 30 account_id_(account_id), 31 session_manager_client_(session_manager_client), 32 device_settings_service_(device_settings_service), 33 weak_factory_(this) {} 34 35 DeviceLocalAccountPolicyStore::~DeviceLocalAccountPolicyStore() {} 36 37 void DeviceLocalAccountPolicyStore::Load() { 38 weak_factory_.InvalidateWeakPtrs(); 39 session_manager_client_->RetrieveDeviceLocalAccountPolicy( 40 account_id_, 41 base::Bind(&DeviceLocalAccountPolicyStore::ValidateLoadedPolicyBlob, 42 weak_factory_.GetWeakPtr())); 43 } 44 45 void DeviceLocalAccountPolicyStore::Store( 46 const em::PolicyFetchResponse& policy) { 47 weak_factory_.InvalidateWeakPtrs(); 48 CheckKeyAndValidate( 49 true, 50 make_scoped_ptr(new em::PolicyFetchResponse(policy)), 51 base::Bind(&DeviceLocalAccountPolicyStore::StoreValidatedPolicy, 52 weak_factory_.GetWeakPtr())); 53 } 54 55 void DeviceLocalAccountPolicyStore::ValidateLoadedPolicyBlob( 56 const std::string& policy_blob) { 57 if (policy_blob.empty()) { 58 status_ = CloudPolicyStore::STATUS_LOAD_ERROR; 59 NotifyStoreError(); 60 } else { 61 scoped_ptr<em::PolicyFetchResponse> policy(new em::PolicyFetchResponse()); 62 if (policy->ParseFromString(policy_blob)) { 63 CheckKeyAndValidate( 64 false, 65 policy.Pass(), 66 base::Bind(&DeviceLocalAccountPolicyStore::UpdatePolicy, 67 weak_factory_.GetWeakPtr())); 68 } else { 69 status_ = CloudPolicyStore::STATUS_PARSE_ERROR; 70 NotifyStoreError(); 71 } 72 } 73 } 74 75 void DeviceLocalAccountPolicyStore::UpdatePolicy( 76 UserCloudPolicyValidator* validator) { 77 validation_status_ = validator->status(); 78 if (!validator->success()) { 79 status_ = STATUS_VALIDATION_ERROR; 80 NotifyStoreError(); 81 return; 82 } 83 84 InstallPolicy(validator->policy_data().Pass(), validator->payload().Pass()); 85 status_ = STATUS_OK; 86 NotifyStoreLoaded(); 87 } 88 89 void DeviceLocalAccountPolicyStore::StoreValidatedPolicy( 90 UserCloudPolicyValidator* validator) { 91 if (!validator->success()) { 92 status_ = CloudPolicyStore::STATUS_VALIDATION_ERROR; 93 validation_status_ = validator->status(); 94 NotifyStoreError(); 95 return; 96 } 97 98 std::string policy_blob; 99 if (!validator->policy()->SerializeToString(&policy_blob)) { 100 status_ = CloudPolicyStore::STATUS_SERIALIZE_ERROR; 101 NotifyStoreError(); 102 return; 103 } 104 105 session_manager_client_->StoreDeviceLocalAccountPolicy( 106 account_id_, 107 policy_blob, 108 base::Bind(&DeviceLocalAccountPolicyStore::HandleStoreResult, 109 weak_factory_.GetWeakPtr())); 110 } 111 112 void DeviceLocalAccountPolicyStore::HandleStoreResult(bool success) { 113 if (!success) { 114 status_ = CloudPolicyStore::STATUS_STORE_ERROR; 115 NotifyStoreError(); 116 } else { 117 Load(); 118 } 119 } 120 121 void DeviceLocalAccountPolicyStore::CheckKeyAndValidate( 122 bool valid_timestamp_required, 123 scoped_ptr<em::PolicyFetchResponse> policy, 124 const UserCloudPolicyValidator::CompletionCallback& callback) { 125 device_settings_service_->GetOwnershipStatusAsync( 126 base::Bind(&DeviceLocalAccountPolicyStore::Validate, 127 weak_factory_.GetWeakPtr(), 128 valid_timestamp_required, 129 base::Passed(&policy), 130 callback)); 131 } 132 133 void DeviceLocalAccountPolicyStore::Validate( 134 bool valid_timestamp_required, 135 scoped_ptr<em::PolicyFetchResponse> policy_response, 136 const UserCloudPolicyValidator::CompletionCallback& callback, 137 chromeos::DeviceSettingsService::OwnershipStatus ownership_status) { 138 DCHECK_NE(chromeos::DeviceSettingsService::OWNERSHIP_UNKNOWN, 139 ownership_status); 140 const em::PolicyData* device_policy_data = 141 device_settings_service_->policy_data(); 142 scoped_refptr<chromeos::PublicKey> key = 143 device_settings_service_->GetPublicKey(); 144 if (!key || !key->is_loaded() || !device_policy_data) { 145 status_ = CloudPolicyStore::STATUS_BAD_STATE; 146 NotifyStoreLoaded(); 147 return; 148 } 149 150 scoped_ptr<UserCloudPolicyValidator> validator( 151 UserCloudPolicyValidator::Create(policy_response.Pass(), 152 background_task_runner())); 153 validator->ValidateUsername(account_id_, false); 154 validator->ValidatePolicyType(dm_protocol::kChromePublicAccountPolicyType); 155 // The timestamp is verified when storing a new policy downloaded from the 156 // server but not when loading a cached policy from disk. 157 // See SessionManagerOperation::ValidateDeviceSettings for the rationale. 158 validator->ValidateAgainstCurrentPolicy( 159 policy(), 160 valid_timestamp_required 161 ? CloudPolicyValidatorBase::TIMESTAMP_REQUIRED 162 : CloudPolicyValidatorBase::TIMESTAMP_NOT_REQUIRED, 163 CloudPolicyValidatorBase::DM_TOKEN_NOT_REQUIRED); 164 165 // Validate the DMToken to match what device policy has. 166 validator->ValidateDMToken(device_policy_data->request_token(), 167 CloudPolicyValidatorBase::DM_TOKEN_REQUIRED); 168 169 validator->ValidatePayload(); 170 policy::BrowserPolicyConnectorChromeOS* connector = 171 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 172 validator->ValidateSignature(key->as_string(), 173 GetPolicyVerificationKey(), 174 connector->GetEnterpriseDomain(), 175 false); 176 validator.release()->StartValidation(callback); 177 } 178 179 } // namespace policy 180