| 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/policy/user_cloud_policy_store_chromeos.h" | 5 #include "chrome/browser/policy/user_cloud_policy_store_chromeos.h" |
| 6 | 6 |
| 7 #include <string> | |
| 8 | |
| 9 #include "base/bind.h" | 7 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 11 #include "base/callback.h" | 9 #include "base/callback.h" |
| 12 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| 11 #include "base/logging.h" |
| 13 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
| 13 #include "base/stl_util.h" |
| 14 #include "base/stringprintf.h" |
| 14 #include "chrome/browser/policy/proto/cloud_policy.pb.h" | 15 #include "chrome/browser/policy/proto/cloud_policy.pb.h" |
| 15 #include "chrome/browser/policy/proto/device_management_local.pb.h" | 16 #include "chrome/browser/policy/proto/device_management_local.pb.h" |
| 16 #include "chrome/browser/policy/user_policy_disk_cache.h" | 17 #include "chrome/browser/policy/user_policy_disk_cache.h" |
| 17 #include "chrome/browser/policy/user_policy_token_loader.h" | 18 #include "chrome/browser/policy/user_policy_token_loader.h" |
| 19 #include "chromeos/dbus/cryptohome_client.h" |
| 18 #include "chromeos/dbus/session_manager_client.h" | 20 #include "chromeos/dbus/session_manager_client.h" |
| 19 #include "content/public/browser/browser_thread.h" | 21 #include "content/public/browser/browser_thread.h" |
| 20 #include "google_apis/gaia/gaia_auth_util.h" | 22 #include "google_apis/gaia/gaia_auth_util.h" |
| 21 | 23 |
| 22 namespace em = enterprise_management; | 24 namespace em = enterprise_management; |
| 23 | 25 |
| 24 namespace policy { | 26 namespace policy { |
| 25 | 27 |
| 26 namespace { | 28 namespace { |
| 27 // Subdirectory in the user's profile for storing user policies. | 29 |
| 28 const base::FilePath::CharType kPolicyDir[] = | 30 // Path within |user_policy_key_dir_| that contains the policy key. |
| 29 FILE_PATH_LITERAL("Device Management"); | 31 // "%s" must be substituted with the sanitized username. |
| 30 // File in the above directory for stroing user policy dmtokens. | 32 const base::FilePath::CharType kPolicyKeyFile[] = |
| 31 const base::FilePath::CharType kTokenCacheFile[] = FILE_PATH_LITERAL("Token"); | 33 FILE_PATH_LITERAL("%s/policy.pub"); |
| 32 // File in the above directory for storing user policy data. | 34 |
| 33 const base::FilePath::CharType kPolicyCacheFile[] = FILE_PATH_LITERAL("Policy"); | 35 // Maximum key size that will be loaded, in bytes. |
| 36 const int kKeySizeLimit = 16 * 1024; |
| 37 |
| 34 } // namespace | 38 } // namespace |
| 35 | 39 |
| 36 | |
| 37 // Helper class for loading legacy policy caches. | 40 // Helper class for loading legacy policy caches. |
| 38 class LegacyPolicyCacheLoader : public UserPolicyTokenLoader::Delegate, | 41 class LegacyPolicyCacheLoader : public UserPolicyTokenLoader::Delegate, |
| 39 public UserPolicyDiskCache::Delegate { | 42 public UserPolicyDiskCache::Delegate { |
| 40 public: | 43 public: |
| 41 typedef base::Callback<void(const std::string&, | 44 typedef base::Callback<void(const std::string&, |
| 42 const std::string&, | 45 const std::string&, |
| 43 CloudPolicyStore::Status, | 46 CloudPolicyStore::Status, |
| 44 scoped_ptr<em::PolicyFetchResponse>)> Callback; | 47 scoped_ptr<em::PolicyFetchResponse>)> Callback; |
| 45 | 48 |
| 46 LegacyPolicyCacheLoader(const base::FilePath& token_cache_file, | 49 LegacyPolicyCacheLoader(const base::FilePath& token_cache_file, |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 return CloudPolicyStore::STATUS_OK; | 143 return CloudPolicyStore::STATUS_OK; |
| 141 case UserPolicyDiskCache::LOAD_RESULT_PARSE_ERROR: | 144 case UserPolicyDiskCache::LOAD_RESULT_PARSE_ERROR: |
| 142 case UserPolicyDiskCache::LOAD_RESULT_READ_ERROR: | 145 case UserPolicyDiskCache::LOAD_RESULT_READ_ERROR: |
| 143 return CloudPolicyStore::STATUS_LOAD_ERROR; | 146 return CloudPolicyStore::STATUS_LOAD_ERROR; |
| 144 } | 147 } |
| 145 NOTREACHED(); | 148 NOTREACHED(); |
| 146 return CloudPolicyStore::STATUS_OK; | 149 return CloudPolicyStore::STATUS_OK; |
| 147 } | 150 } |
| 148 | 151 |
| 149 UserCloudPolicyStoreChromeOS::UserCloudPolicyStoreChromeOS( | 152 UserCloudPolicyStoreChromeOS::UserCloudPolicyStoreChromeOS( |
| 153 chromeos::CryptohomeClient* cryptohome_client, |
| 150 chromeos::SessionManagerClient* session_manager_client, | 154 chromeos::SessionManagerClient* session_manager_client, |
| 151 const std::string& username, | 155 const std::string& username, |
| 156 const base::FilePath& user_policy_key_dir, |
| 152 const base::FilePath& legacy_token_cache_file, | 157 const base::FilePath& legacy_token_cache_file, |
| 153 const base::FilePath& legacy_policy_cache_file) | 158 const base::FilePath& legacy_policy_cache_file) |
| 154 : session_manager_client_(session_manager_client), | 159 : cryptohome_client_(cryptohome_client), |
| 160 session_manager_client_(session_manager_client), |
| 155 username_(username), | 161 username_(username), |
| 162 user_policy_key_dir_(user_policy_key_dir), |
| 156 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | 163 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
| 157 legacy_cache_dir_(legacy_token_cache_file.DirName()), | 164 legacy_cache_dir_(legacy_token_cache_file.DirName()), |
| 158 legacy_loader_(new LegacyPolicyCacheLoader(legacy_token_cache_file, | 165 legacy_loader_(new LegacyPolicyCacheLoader(legacy_token_cache_file, |
| 159 legacy_policy_cache_file)), | 166 legacy_policy_cache_file)), |
| 160 legacy_caches_loaded_(false) {} | 167 legacy_caches_loaded_(false), |
| 168 policy_key_loaded_(false) {} |
| 161 | 169 |
| 162 UserCloudPolicyStoreChromeOS::~UserCloudPolicyStoreChromeOS() {} | 170 UserCloudPolicyStoreChromeOS::~UserCloudPolicyStoreChromeOS() {} |
| 163 | 171 |
| 164 void UserCloudPolicyStoreChromeOS::Store( | 172 void UserCloudPolicyStoreChromeOS::Store( |
| 165 const em::PolicyFetchResponse& policy) { | 173 const em::PolicyFetchResponse& policy) { |
| 166 // Cancel all pending requests. | 174 // Cancel all pending requests. |
| 167 weak_factory_.InvalidateWeakPtrs(); | 175 weak_factory_.InvalidateWeakPtrs(); |
| 168 Validate( | 176 scoped_ptr<em::PolicyFetchResponse> response( |
| 169 scoped_ptr<em::PolicyFetchResponse>(new em::PolicyFetchResponse(policy)), | 177 new em::PolicyFetchResponse(policy)); |
| 170 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyToStoreValidated, | 178 EnsurePolicyKeyLoaded( |
| 171 weak_factory_.GetWeakPtr())); | 179 base::Bind(&UserCloudPolicyStoreChromeOS::ValidatePolicyForStore, |
| 180 weak_factory_.GetWeakPtr(), |
| 181 base::Passed(&response))); |
| 172 } | 182 } |
| 173 | 183 |
| 174 void UserCloudPolicyStoreChromeOS::Load() { | 184 void UserCloudPolicyStoreChromeOS::Load() { |
| 175 // Cancel all pending requests. | 185 // Cancel all pending requests. |
| 176 weak_factory_.InvalidateWeakPtrs(); | 186 weak_factory_.InvalidateWeakPtrs(); |
| 177 session_manager_client_->RetrieveUserPolicy( | 187 session_manager_client_->RetrieveUserPolicy( |
| 178 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyRetrieved, | 188 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyRetrieved, |
| 179 weak_factory_.GetWeakPtr())); | 189 weak_factory_.GetWeakPtr())); |
| 180 } | 190 } |
| 181 | 191 |
| 192 void UserCloudPolicyStoreChromeOS::ValidatePolicyForStore( |
| 193 scoped_ptr<em::PolicyFetchResponse> policy) { |
| 194 // Create and configure a validator. |
| 195 scoped_ptr<UserCloudPolicyValidator> validator = |
| 196 CreateValidator(policy.Pass()); |
| 197 validator->ValidateUsername(username_); |
| 198 if (policy_key_.empty()) { |
| 199 validator->ValidateInitialKey(); |
| 200 } else { |
| 201 const bool allow_rotation = true; |
| 202 validator->ValidateSignature(policy_key_, allow_rotation); |
| 203 } |
| 204 |
| 205 // Start validation. The Validator will delete itself once validation is |
| 206 // complete. |
| 207 validator.release()->StartValidation( |
| 208 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyToStoreValidated, |
| 209 weak_factory_.GetWeakPtr())); |
| 210 } |
| 211 |
| 212 void UserCloudPolicyStoreChromeOS::OnPolicyToStoreValidated( |
| 213 UserCloudPolicyValidator* validator) { |
| 214 validation_status_ = validator->status(); |
| 215 if (!validator->success()) { |
| 216 status_ = STATUS_VALIDATION_ERROR; |
| 217 NotifyStoreError(); |
| 218 return; |
| 219 } |
| 220 |
| 221 std::string policy_blob; |
| 222 if (!validator->policy()->SerializeToString(&policy_blob)) { |
| 223 status_ = STATUS_SERIALIZE_ERROR; |
| 224 NotifyStoreError(); |
| 225 return; |
| 226 } |
| 227 |
| 228 session_manager_client_->StoreUserPolicy( |
| 229 policy_blob, |
| 230 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyStored, |
| 231 weak_factory_.GetWeakPtr())); |
| 232 } |
| 233 |
| 234 void UserCloudPolicyStoreChromeOS::OnPolicyStored(bool success) { |
| 235 if (!success) { |
| 236 status_ = STATUS_STORE_ERROR; |
| 237 NotifyStoreError(); |
| 238 } else { |
| 239 // Load the policy right after storing it, to make sure it was accepted by |
| 240 // the session manager. An additional validation is performed after the |
| 241 // load; reload the key for that validation too, in case it was rotated. |
| 242 ReloadPolicyKey(base::Bind(&UserCloudPolicyStoreChromeOS::Load, |
| 243 weak_factory_.GetWeakPtr())); |
| 244 } |
| 245 } |
| 246 |
| 182 void UserCloudPolicyStoreChromeOS::OnPolicyRetrieved( | 247 void UserCloudPolicyStoreChromeOS::OnPolicyRetrieved( |
| 183 const std::string& policy_blob) { | 248 const std::string& policy_blob) { |
| 184 if (policy_blob.empty()) { | 249 if (policy_blob.empty()) { |
| 185 // Policy fetch failed. Try legacy caches if we haven't done that already. | 250 // Policy fetch failed. Try legacy caches if we haven't done that already. |
| 186 if (!legacy_caches_loaded_ && legacy_loader_.get()) { | 251 if (!legacy_caches_loaded_ && legacy_loader_.get()) { |
| 187 legacy_caches_loaded_ = true; | 252 legacy_caches_loaded_ = true; |
| 188 legacy_loader_->Load( | 253 legacy_loader_->Load( |
| 189 base::Bind(&UserCloudPolicyStoreChromeOS::OnLegacyLoadFinished, | 254 base::Bind(&UserCloudPolicyStoreChromeOS::OnLegacyLoadFinished, |
| 190 weak_factory_.GetWeakPtr())); | 255 weak_factory_.GetWeakPtr())); |
| 191 } else { | 256 } else { |
| 192 // session_manager doesn't have policy. Adjust internal state and notify | 257 // session_manager doesn't have policy. Adjust internal state and notify |
| 193 // the world about the policy update. | 258 // the world about the policy update. |
| 194 policy_.reset(); | 259 policy_.reset(); |
| 195 NotifyStoreLoaded(); | 260 NotifyStoreLoaded(); |
| 196 } | 261 } |
| 197 return; | 262 return; |
| 198 } | 263 } |
| 199 | 264 |
| 200 // Policy is supplied by session_manager. Disregard legacy data from now on. | 265 // Policy is supplied by session_manager. Disregard legacy data from now on. |
| 201 legacy_loader_.reset(); | 266 legacy_loader_.reset(); |
| 202 | 267 |
| 203 scoped_ptr<em::PolicyFetchResponse> policy(new em::PolicyFetchResponse()); | 268 scoped_ptr<em::PolicyFetchResponse> policy(new em::PolicyFetchResponse()); |
| 204 if (!policy->ParseFromString(policy_blob)) { | 269 if (!policy->ParseFromString(policy_blob)) { |
| 205 status_ = STATUS_PARSE_ERROR; | 270 status_ = STATUS_PARSE_ERROR; |
| 206 NotifyStoreError(); | 271 NotifyStoreError(); |
| 207 return; | 272 return; |
| 208 } | 273 } |
| 209 | 274 |
| 210 Validate(policy.Pass(), | 275 // Load |policy_key_| to verify the loaded policy. |
| 211 base::Bind(&UserCloudPolicyStoreChromeOS::OnRetrievedPolicyValidated, | 276 EnsurePolicyKeyLoaded( |
| 212 weak_factory_.GetWeakPtr())); | 277 base::Bind(&UserCloudPolicyStoreChromeOS::ValidateRetrievedPolicy, |
| 278 weak_factory_.GetWeakPtr(), |
| 279 base::Passed(&policy))); |
| 280 } |
| 281 |
| 282 void UserCloudPolicyStoreChromeOS::ValidateRetrievedPolicy( |
| 283 scoped_ptr<em::PolicyFetchResponse> policy) { |
| 284 // Create and configure a validator for the loaded policy. |
| 285 scoped_ptr<UserCloudPolicyValidator> validator = |
| 286 CreateValidator(policy.Pass()); |
| 287 validator->ValidateUsername(username_); |
| 288 const bool allow_rotation = false; |
| 289 validator->ValidateSignature(policy_key_, allow_rotation); |
| 290 // Start validation. The Validator will delete itself once validation is |
| 291 // complete. |
| 292 validator.release()->StartValidation( |
| 293 base::Bind(&UserCloudPolicyStoreChromeOS::OnRetrievedPolicyValidated, |
| 294 weak_factory_.GetWeakPtr())); |
| 213 } | 295 } |
| 214 | 296 |
| 215 void UserCloudPolicyStoreChromeOS::OnRetrievedPolicyValidated( | 297 void UserCloudPolicyStoreChromeOS::OnRetrievedPolicyValidated( |
| 216 UserCloudPolicyValidator* validator) { | 298 UserCloudPolicyValidator* validator) { |
| 217 validation_status_ = validator->status(); | 299 validation_status_ = validator->status(); |
| 218 if (!validator->success()) { | 300 if (!validator->success()) { |
| 219 status_ = STATUS_VALIDATION_ERROR; | 301 status_ = STATUS_VALIDATION_ERROR; |
| 220 NotifyStoreError(); | 302 NotifyStoreError(); |
| 221 return; | 303 return; |
| 222 } | 304 } |
| 223 | 305 |
| 224 InstallPolicy(validator->policy_data().Pass(), validator->payload().Pass()); | 306 InstallPolicy(validator->policy_data().Pass(), validator->payload().Pass()); |
| 225 status_ = STATUS_OK; | 307 status_ = STATUS_OK; |
| 226 | 308 |
| 227 // Policy has been loaded successfully. This indicates that new-style policy | 309 // Policy has been loaded successfully. This indicates that new-style policy |
| 228 // is working, so the legacy cache directory can be removed. | 310 // is working, so the legacy cache directory can be removed. |
| 229 if (!legacy_cache_dir_.empty()) { | 311 if (!legacy_cache_dir_.empty()) { |
| 230 content::BrowserThread::PostBlockingPoolTask( | 312 content::BrowserThread::PostBlockingPoolTask( |
| 231 FROM_HERE, | 313 FROM_HERE, |
| 232 base::Bind(&UserCloudPolicyStoreChromeOS::RemoveLegacyCacheDir, | 314 base::Bind(&UserCloudPolicyStoreChromeOS::RemoveLegacyCacheDir, |
| 233 legacy_cache_dir_)); | 315 legacy_cache_dir_)); |
| 234 legacy_cache_dir_.clear(); | 316 legacy_cache_dir_.clear(); |
| 235 } | 317 } |
| 236 NotifyStoreLoaded(); | 318 NotifyStoreLoaded(); |
| 237 } | 319 } |
| 238 | 320 |
| 239 void UserCloudPolicyStoreChromeOS::OnPolicyToStoreValidated( | |
| 240 UserCloudPolicyValidator* validator) { | |
| 241 validation_status_ = validator->status(); | |
| 242 if (!validator->success()) { | |
| 243 status_ = STATUS_VALIDATION_ERROR; | |
| 244 NotifyStoreError(); | |
| 245 return; | |
| 246 } | |
| 247 | |
| 248 std::string policy_blob; | |
| 249 if (!validator->policy()->SerializeToString(&policy_blob)) { | |
| 250 status_ = STATUS_SERIALIZE_ERROR; | |
| 251 NotifyStoreError(); | |
| 252 return; | |
| 253 } | |
| 254 | |
| 255 session_manager_client_->StoreUserPolicy( | |
| 256 policy_blob, | |
| 257 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyStored, | |
| 258 weak_factory_.GetWeakPtr())); | |
| 259 } | |
| 260 | |
| 261 void UserCloudPolicyStoreChromeOS::OnPolicyStored(bool success) { | |
| 262 if (!success) { | |
| 263 status_ = STATUS_STORE_ERROR; | |
| 264 NotifyStoreError(); | |
| 265 } else { | |
| 266 // TODO(mnissler): Once we do signature verifications, we'll have to reload | |
| 267 // the key at this point to account for key rotations. | |
| 268 Load(); | |
| 269 } | |
| 270 } | |
| 271 | |
| 272 void UserCloudPolicyStoreChromeOS::Validate( | |
| 273 scoped_ptr<em::PolicyFetchResponse> policy, | |
| 274 const UserCloudPolicyValidator::CompletionCallback& callback) { | |
| 275 // Configure the validator. | |
| 276 scoped_ptr<UserCloudPolicyValidator> validator = | |
| 277 CreateValidator(policy.Pass()); | |
| 278 validator->ValidateUsername(username_); | |
| 279 | |
| 280 // TODO(mnissler): Do a signature check here as well. The key is stored by | |
| 281 // session_manager in the root-owned cryptohome area, which is currently | |
| 282 // inaccessible to Chrome though. | |
| 283 | |
| 284 // Start validation. The Validator will free itself once validation is | |
| 285 // complete. | |
| 286 validator.release()->StartValidation(callback); | |
| 287 } | |
| 288 | |
| 289 void UserCloudPolicyStoreChromeOS::OnLegacyLoadFinished( | 321 void UserCloudPolicyStoreChromeOS::OnLegacyLoadFinished( |
| 290 const std::string& dm_token, | 322 const std::string& dm_token, |
| 291 const std::string& device_id, | 323 const std::string& device_id, |
| 292 Status status, | 324 Status status, |
| 293 scoped_ptr<em::PolicyFetchResponse> policy) { | 325 scoped_ptr<em::PolicyFetchResponse> policy) { |
| 294 status_ = status; | 326 status_ = status; |
| 295 if (policy.get()) { | 327 if (policy.get()) { |
| 296 Validate(policy.Pass(), | 328 // Create and configure a validator for the loaded legacy policy. Note that |
| 297 base::Bind(&UserCloudPolicyStoreChromeOS::OnLegacyPolicyValidated, | 329 // the signature on this policy is not verified. |
| 298 weak_factory_.GetWeakPtr(), | 330 scoped_ptr<UserCloudPolicyValidator> validator = |
| 299 dm_token, device_id)); | 331 CreateValidator(policy.Pass()); |
| 332 validator->ValidateUsername(username_); |
| 333 validator.release()->StartValidation( |
| 334 base::Bind(&UserCloudPolicyStoreChromeOS::OnLegacyPolicyValidated, |
| 335 weak_factory_.GetWeakPtr(), |
| 336 dm_token, |
| 337 device_id)); |
| 300 } else { | 338 } else { |
| 301 InstallLegacyTokens(dm_token, device_id); | 339 InstallLegacyTokens(dm_token, device_id); |
| 302 } | 340 } |
| 303 } | 341 } |
| 304 | 342 |
| 305 void UserCloudPolicyStoreChromeOS::OnLegacyPolicyValidated( | 343 void UserCloudPolicyStoreChromeOS::OnLegacyPolicyValidated( |
| 306 const std::string& dm_token, | 344 const std::string& dm_token, |
| 307 const std::string& device_id, | 345 const std::string& device_id, |
| 308 UserCloudPolicyValidator* validator) { | 346 UserCloudPolicyValidator* validator) { |
| 309 validation_status_ = validator->status(); | 347 validation_status_ = validator->status(); |
| 310 if (validator->success()) { | 348 if (validator->success()) { |
| 311 status_ = STATUS_OK; | 349 status_ = STATUS_OK; |
| 312 InstallPolicy(validator->policy_data().Pass(), | 350 InstallPolicy(validator->policy_data().Pass(), validator->payload().Pass()); |
| 313 validator->payload().Pass()); | |
| 314 | 351 |
| 315 // Clear the public key version. The public key version field would | 352 // Clear the public key version. The public key version field would |
| 316 // otherwise indicate that we have key installed in the store when in fact | 353 // otherwise indicate that we have key installed in the store when in fact |
| 317 // we haven't. This may result in policy updates failing signature | 354 // we haven't. This may result in policy updates failing signature |
| 318 // verification. | 355 // verification. |
| 319 policy_->clear_public_key_version(); | 356 policy_->clear_public_key_version(); |
| 320 } else { | 357 } else { |
| 321 status_ = STATUS_VALIDATION_ERROR; | 358 status_ = STATUS_VALIDATION_ERROR; |
| 322 } | 359 } |
| 323 | 360 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 341 NotifyStoreLoaded(); | 378 NotifyStoreLoaded(); |
| 342 } | 379 } |
| 343 | 380 |
| 344 // static | 381 // static |
| 345 void UserCloudPolicyStoreChromeOS::RemoveLegacyCacheDir( | 382 void UserCloudPolicyStoreChromeOS::RemoveLegacyCacheDir( |
| 346 const base::FilePath& dir) { | 383 const base::FilePath& dir) { |
| 347 if (file_util::PathExists(dir) && !file_util::Delete(dir, true)) | 384 if (file_util::PathExists(dir) && !file_util::Delete(dir, true)) |
| 348 LOG(ERROR) << "Failed to remove cache dir " << dir.value(); | 385 LOG(ERROR) << "Failed to remove cache dir " << dir.value(); |
| 349 } | 386 } |
| 350 | 387 |
| 388 void UserCloudPolicyStoreChromeOS::ReloadPolicyKey( |
| 389 const base::Closure& callback) { |
| 390 std::vector<uint8>* key = new std::vector<uint8>(); |
| 391 content::BrowserThread::PostBlockingPoolTaskAndReply( |
| 392 FROM_HERE, |
| 393 base::Bind(&UserCloudPolicyStoreChromeOS::LoadPolicyKey, |
| 394 policy_key_path_, |
| 395 key), |
| 396 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyKeyReloaded, |
| 397 weak_factory_.GetWeakPtr(), |
| 398 base::Owned(key), |
| 399 callback)); |
| 400 } |
| 401 |
| 402 // static |
| 403 void UserCloudPolicyStoreChromeOS::LoadPolicyKey(const base::FilePath& path, |
| 404 std::vector<uint8>* key) { |
| 405 if (!file_util::PathExists(path)) { |
| 406 VLOG(1) << "No key at " << path.value(); |
| 407 return; |
| 408 } |
| 409 |
| 410 int64 size; |
| 411 if (!file_util::GetFileSize(path, &size)) { |
| 412 LOG(ERROR) << "Could not get size of " << path.value(); |
| 413 } else if (size == 0 || size > kKeySizeLimit) { |
| 414 LOG(ERROR) << "Key at " << path.value() << " has bad size " << size; |
| 415 } else { |
| 416 key->resize(size); |
| 417 int read_size = file_util::ReadFile( |
| 418 path, reinterpret_cast<char*>(vector_as_array(key)), size); |
| 419 if (read_size != size) { |
| 420 LOG(ERROR) << "Failed to read key at " << path.value(); |
| 421 key->clear(); |
| 422 } |
| 423 } |
| 424 } |
| 425 |
| 426 void UserCloudPolicyStoreChromeOS::OnPolicyKeyReloaded( |
| 427 std::vector<uint8>* key, |
| 428 const base::Closure& callback) { |
| 429 policy_key_.swap(*key); |
| 430 policy_key_loaded_ = true; |
| 431 callback.Run(); |
| 432 } |
| 433 |
| 434 void UserCloudPolicyStoreChromeOS::EnsurePolicyKeyLoaded( |
| 435 const base::Closure& callback) { |
| 436 if (policy_key_loaded_) { |
| 437 callback.Run(); |
| 438 } else { |
| 439 // Get the hashed username that's part of the key's path, to determine |
| 440 // |policy_key_path_|. |
| 441 cryptohome_client_->GetSanitizedUsername(username_, |
| 442 base::Bind(&UserCloudPolicyStoreChromeOS::OnGetSanitizedUsername, |
| 443 weak_factory_.GetWeakPtr(), |
| 444 callback)); |
| 445 } |
| 446 } |
| 447 |
| 448 void UserCloudPolicyStoreChromeOS::OnGetSanitizedUsername( |
| 449 const base::Closure& callback, |
| 450 chromeos::DBusMethodCallStatus call_status, |
| 451 const std::string& sanitized_username) { |
| 452 // The default empty path will always yield an empty key. |
| 453 if (call_status == chromeos::DBUS_METHOD_CALL_SUCCESS && |
| 454 !sanitized_username.empty()) { |
| 455 policy_key_path_ = user_policy_key_dir_.Append( |
| 456 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str())); |
| 457 } |
| 458 ReloadPolicyKey(callback); |
| 459 } |
| 460 |
| 351 } // namespace policy | 461 } // namespace policy |
| OLD | NEW |