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/files/file_util.h" | 10 #include "base/files/file_util.h" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 VALIDATION_FAILURE_LOAD_KEY, | 42 VALIDATION_FAILURE_LOAD_KEY, |
43 VALIDATION_FAILURE_SIZE, | 43 VALIDATION_FAILURE_SIZE, |
44 }; | 44 }; |
45 | 45 |
46 void SampleValidationFailure(ValidationFailure sample) { | 46 void SampleValidationFailure(ValidationFailure sample) { |
47 UMA_HISTOGRAM_ENUMERATION("Enterprise.UserPolicyValidationFailure", | 47 UMA_HISTOGRAM_ENUMERATION("Enterprise.UserPolicyValidationFailure", |
48 sample, | 48 sample, |
49 VALIDATION_FAILURE_SIZE); | 49 VALIDATION_FAILURE_SIZE); |
50 } | 50 } |
51 | 51 |
52 // Extracts the domain name from the passed username. | 52 // Extracts the domain name from the passed user_email. |
53 std::string ExtractDomain(const std::string& username) { | 53 std::string ExtractDomain(const std::string& user_email) { |
54 return gaia::ExtractDomainName(gaia::CanonicalizeEmail(username)); | 54 return gaia::ExtractDomainName(gaia::CanonicalizeEmail(user_email)); |
55 } | 55 } |
56 | 56 |
57 } // namespace | 57 } // namespace |
58 | 58 |
59 // Helper class for loading legacy policy caches. | 59 // Helper class for loading legacy policy caches. |
60 class LegacyPolicyCacheLoader : public UserPolicyTokenLoader::Delegate, | 60 class LegacyPolicyCacheLoader : public UserPolicyTokenLoader::Delegate, |
61 public UserPolicyDiskCache::Delegate { | 61 public UserPolicyDiskCache::Delegate { |
62 public: | 62 public: |
63 typedef base::Callback<void(const std::string&, | 63 typedef base::Callback<void(const std::string&, |
64 const std::string&, | 64 const std::string&, |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 return CloudPolicyStore::STATUS_LOAD_ERROR; | 167 return CloudPolicyStore::STATUS_LOAD_ERROR; |
168 } | 168 } |
169 NOTREACHED(); | 169 NOTREACHED(); |
170 return CloudPolicyStore::STATUS_OK; | 170 return CloudPolicyStore::STATUS_OK; |
171 } | 171 } |
172 | 172 |
173 UserCloudPolicyStoreChromeOS::UserCloudPolicyStoreChromeOS( | 173 UserCloudPolicyStoreChromeOS::UserCloudPolicyStoreChromeOS( |
174 chromeos::CryptohomeClient* cryptohome_client, | 174 chromeos::CryptohomeClient* cryptohome_client, |
175 chromeos::SessionManagerClient* session_manager_client, | 175 chromeos::SessionManagerClient* session_manager_client, |
176 scoped_refptr<base::SequencedTaskRunner> background_task_runner, | 176 scoped_refptr<base::SequencedTaskRunner> background_task_runner, |
177 const std::string& username, | 177 const user_manager::UserID& user_id, |
178 const base::FilePath& user_policy_key_dir, | 178 const base::FilePath& user_policy_key_dir, |
179 const base::FilePath& legacy_token_cache_file, | 179 const base::FilePath& legacy_token_cache_file, |
180 const base::FilePath& legacy_policy_cache_file) | 180 const base::FilePath& legacy_policy_cache_file) |
181 : UserCloudPolicyStoreBase(background_task_runner), | 181 : UserCloudPolicyStoreBase(background_task_runner), |
182 cryptohome_client_(cryptohome_client), | 182 cryptohome_client_(cryptohome_client), |
183 session_manager_client_(session_manager_client), | 183 session_manager_client_(session_manager_client), |
184 username_(username), | 184 user_id_(user_id), |
185 user_policy_key_dir_(user_policy_key_dir), | 185 user_policy_key_dir_(user_policy_key_dir), |
186 legacy_cache_dir_(legacy_token_cache_file.DirName()), | 186 legacy_cache_dir_(legacy_token_cache_file.DirName()), |
187 legacy_loader_(new LegacyPolicyCacheLoader(legacy_token_cache_file, | 187 legacy_loader_(new LegacyPolicyCacheLoader(legacy_token_cache_file, |
188 legacy_policy_cache_file, | 188 legacy_policy_cache_file, |
189 background_task_runner)), | 189 background_task_runner)), |
190 legacy_caches_loaded_(false), | 190 legacy_caches_loaded_(false), |
191 policy_key_loaded_(false), | 191 policy_key_loaded_(false), |
192 weak_factory_(this) {} | 192 weak_factory_(this) {} |
193 | 193 |
194 UserCloudPolicyStoreChromeOS::~UserCloudPolicyStoreChromeOS() {} | 194 UserCloudPolicyStoreChromeOS::~UserCloudPolicyStoreChromeOS() {} |
195 | 195 |
196 void UserCloudPolicyStoreChromeOS::Store( | 196 void UserCloudPolicyStoreChromeOS::Store( |
197 const em::PolicyFetchResponse& policy) { | 197 const em::PolicyFetchResponse& policy) { |
198 // Cancel all pending requests. | 198 // Cancel all pending requests. |
199 weak_factory_.InvalidateWeakPtrs(); | 199 weak_factory_.InvalidateWeakPtrs(); |
200 scoped_ptr<em::PolicyFetchResponse> response( | 200 scoped_ptr<em::PolicyFetchResponse> response( |
201 new em::PolicyFetchResponse(policy)); | 201 new em::PolicyFetchResponse(policy)); |
202 EnsurePolicyKeyLoaded( | 202 EnsurePolicyKeyLoaded( |
203 base::Bind(&UserCloudPolicyStoreChromeOS::ValidatePolicyForStore, | 203 base::Bind(&UserCloudPolicyStoreChromeOS::ValidatePolicyForStore, |
204 weak_factory_.GetWeakPtr(), | 204 weak_factory_.GetWeakPtr(), |
205 base::Passed(&response))); | 205 base::Passed(&response))); |
206 } | 206 } |
207 | 207 |
208 void UserCloudPolicyStoreChromeOS::Load() { | 208 void UserCloudPolicyStoreChromeOS::Load() { |
209 // Cancel all pending requests. | 209 // Cancel all pending requests. |
210 weak_factory_.InvalidateWeakPtrs(); | 210 weak_factory_.InvalidateWeakPtrs(); |
211 session_manager_client_->RetrievePolicyForUser( | 211 session_manager_client_->RetrievePolicyForUser( |
212 username_, | 212 user_id_, |
213 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyRetrieved, | 213 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyRetrieved, |
214 weak_factory_.GetWeakPtr())); | 214 weak_factory_.GetWeakPtr())); |
215 } | 215 } |
216 | 216 |
217 void UserCloudPolicyStoreChromeOS::LoadImmediately() { | 217 void UserCloudPolicyStoreChromeOS::LoadImmediately() { |
218 // This blocking DBus call is in the startup path and will block the UI | 218 // This blocking DBus call is in the startup path and will block the UI |
219 // thread. This only happens when the Profile is created synchronously, which | 219 // thread. This only happens when the Profile is created synchronously, which |
220 // on ChromeOS happens whenever the browser is restarted into the same | 220 // on ChromeOS happens whenever the browser is restarted into the same |
221 // session. That happens when the browser crashes, or right after signin if | 221 // session. That happens when the browser crashes, or right after signin if |
222 // the user has flags configured in about:flags. | 222 // the user has flags configured in about:flags. |
223 // However, on those paths we must load policy synchronously so that the | 223 // However, on those paths we must load policy synchronously so that the |
224 // Profile initialization never sees unmanaged prefs, which would lead to | 224 // Profile initialization never sees unmanaged prefs, which would lead to |
225 // data loss. http://crbug.com/263061 | 225 // data loss. http://crbug.com/263061 |
226 std::string policy_blob = | 226 std::string policy_blob = |
227 session_manager_client_->BlockingRetrievePolicyForUser(username_); | 227 session_manager_client_->BlockingRetrievePolicyForUser(user_id_); |
228 if (policy_blob.empty()) { | 228 if (policy_blob.empty()) { |
229 // The session manager doesn't have policy, or the call failed. | 229 // The session manager doesn't have policy, or the call failed. |
230 // Just notify that the load is done, and don't bother with the legacy | 230 // Just notify that the load is done, and don't bother with the legacy |
231 // caches in this case. | 231 // caches in this case. |
232 NotifyStoreLoaded(); | 232 NotifyStoreLoaded(); |
233 return; | 233 return; |
234 } | 234 } |
235 | 235 |
236 scoped_ptr<em::PolicyFetchResponse> policy(new em::PolicyFetchResponse()); | 236 scoped_ptr<em::PolicyFetchResponse> policy(new em::PolicyFetchResponse()); |
237 if (!policy->ParseFromString(policy_blob)) { | 237 if (!policy->ParseFromString(policy_blob)) { |
238 status_ = STATUS_PARSE_ERROR; | 238 status_ = STATUS_PARSE_ERROR; |
239 NotifyStoreError(); | 239 NotifyStoreError(); |
240 return; | 240 return; |
241 } | 241 } |
242 | 242 |
243 std::string sanitized_username = | 243 std::string sanitized_username = |
244 cryptohome_client_->BlockingGetSanitizedUsername(username_); | 244 cryptohome_client_->BlockingGetSanitizedUsername(user_id_); |
245 if (sanitized_username.empty()) { | 245 if (sanitized_username.empty()) { |
246 status_ = STATUS_LOAD_ERROR; | 246 status_ = STATUS_LOAD_ERROR; |
247 NotifyStoreError(); | 247 NotifyStoreError(); |
248 return; | 248 return; |
249 } | 249 } |
250 | 250 |
251 policy_key_path_ = user_policy_key_dir_.Append( | 251 policy_key_path_ = user_policy_key_dir_.Append( |
252 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str())); | 252 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str())); |
253 LoadPolicyKey(policy_key_path_, &policy_key_); | 253 LoadPolicyKey(policy_key_path_, &policy_key_); |
254 policy_key_loaded_ = true; | 254 policy_key_loaded_ = true; |
255 | 255 |
256 scoped_ptr<UserCloudPolicyValidator> validator = | 256 scoped_ptr<UserCloudPolicyValidator> validator = |
257 CreateValidatorForLoad(policy.Pass()); | 257 CreateValidatorForLoad(policy.Pass()); |
258 validator->RunValidation(); | 258 validator->RunValidation(); |
259 OnRetrievedPolicyValidated(validator.get()); | 259 OnRetrievedPolicyValidated(validator.get()); |
260 } | 260 } |
261 | 261 |
262 void UserCloudPolicyStoreChromeOS::ValidatePolicyForStore( | 262 void UserCloudPolicyStoreChromeOS::ValidatePolicyForStore( |
263 scoped_ptr<em::PolicyFetchResponse> policy) { | 263 scoped_ptr<em::PolicyFetchResponse> policy) { |
264 // Create and configure a validator. | 264 // Create and configure a validator. |
265 scoped_ptr<UserCloudPolicyValidator> validator = | 265 scoped_ptr<UserCloudPolicyValidator> validator = |
266 CreateValidator(policy.Pass(), | 266 CreateValidator(policy.Pass(), |
267 CloudPolicyValidatorBase::TIMESTAMP_REQUIRED); | 267 CloudPolicyValidatorBase::TIMESTAMP_REQUIRED); |
268 validator->ValidateUsername(username_, true); | 268 validator->ValidateUsername(user_id_, true); |
269 if (policy_key_.empty()) { | 269 if (policy_key_.empty()) { |
270 validator->ValidateInitialKey(GetPolicyVerificationKey(), | 270 validator->ValidateInitialKey(GetPolicyVerificationKey(), |
271 ExtractDomain(username_)); | 271 ExtractDomain(user_id_.GetUserEmail())); |
272 } else { | 272 } else { |
273 const bool allow_rotation = true; | 273 const bool allow_rotation = true; |
274 validator->ValidateSignature(policy_key_, | 274 validator->ValidateSignature(policy_key_, |
275 GetPolicyVerificationKey(), | 275 GetPolicyVerificationKey(), |
276 ExtractDomain(username_), | 276 ExtractDomain(user_id_.GetUserEmail()), |
277 allow_rotation); | 277 allow_rotation); |
278 } | 278 } |
279 | 279 |
280 // Start validation. The Validator will delete itself once validation is | 280 // Start validation. The Validator will delete itself once validation is |
281 // complete. | 281 // complete. |
282 validator.release()->StartValidation( | 282 validator.release()->StartValidation( |
283 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyToStoreValidated, | 283 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyToStoreValidated, |
284 weak_factory_.GetWeakPtr())); | 284 weak_factory_.GetWeakPtr())); |
285 } | 285 } |
286 | 286 |
(...skipping 13 matching lines...) Expand all Loading... |
300 } | 300 } |
301 | 301 |
302 std::string policy_blob; | 302 std::string policy_blob; |
303 if (!validator->policy()->SerializeToString(&policy_blob)) { | 303 if (!validator->policy()->SerializeToString(&policy_blob)) { |
304 status_ = STATUS_SERIALIZE_ERROR; | 304 status_ = STATUS_SERIALIZE_ERROR; |
305 NotifyStoreError(); | 305 NotifyStoreError(); |
306 return; | 306 return; |
307 } | 307 } |
308 | 308 |
309 session_manager_client_->StorePolicyForUser( | 309 session_manager_client_->StorePolicyForUser( |
310 username_, | 310 user_id_, |
311 policy_blob, | 311 policy_blob, |
312 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyStored, | 312 base::Bind(&UserCloudPolicyStoreChromeOS::OnPolicyStored, |
313 weak_factory_.GetWeakPtr())); | 313 weak_factory_.GetWeakPtr())); |
314 } | 314 } |
315 | 315 |
316 void UserCloudPolicyStoreChromeOS::OnPolicyStored(bool success) { | 316 void UserCloudPolicyStoreChromeOS::OnPolicyStored(bool success) { |
317 if (!success) { | 317 if (!success) { |
318 status_ = STATUS_STORE_ERROR; | 318 status_ = STATUS_STORE_ERROR; |
319 NotifyStoreError(); | 319 NotifyStoreError(); |
320 } else { | 320 } else { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 const std::string& device_id, | 408 const std::string& device_id, |
409 Status status, | 409 Status status, |
410 scoped_ptr<em::PolicyFetchResponse> policy) { | 410 scoped_ptr<em::PolicyFetchResponse> policy) { |
411 status_ = status; | 411 status_ = status; |
412 if (policy.get()) { | 412 if (policy.get()) { |
413 // Create and configure a validator for the loaded legacy policy. Note that | 413 // Create and configure a validator for the loaded legacy policy. Note that |
414 // the signature on this policy is not verified. | 414 // the signature on this policy is not verified. |
415 scoped_ptr<UserCloudPolicyValidator> validator = | 415 scoped_ptr<UserCloudPolicyValidator> validator = |
416 CreateValidator(policy.Pass(), | 416 CreateValidator(policy.Pass(), |
417 CloudPolicyValidatorBase::TIMESTAMP_REQUIRED); | 417 CloudPolicyValidatorBase::TIMESTAMP_REQUIRED); |
418 validator->ValidateUsername(username_, true); | 418 validator->ValidateUsername(user_id_, true); |
419 validator.release()->StartValidation( | 419 validator.release()->StartValidation( |
420 base::Bind(&UserCloudPolicyStoreChromeOS::OnLegacyPolicyValidated, | 420 base::Bind(&UserCloudPolicyStoreChromeOS::OnLegacyPolicyValidated, |
421 weak_factory_.GetWeakPtr(), | 421 weak_factory_.GetWeakPtr(), |
422 dm_token, | 422 dm_token, |
423 device_id)); | 423 device_id)); |
424 } else { | 424 } else { |
425 InstallLegacyTokens(dm_token, device_id); | 425 InstallLegacyTokens(dm_token, device_id); |
426 } | 426 } |
427 } | 427 } |
428 | 428 |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 callback.Run(); | 520 callback.Run(); |
521 } | 521 } |
522 | 522 |
523 void UserCloudPolicyStoreChromeOS::EnsurePolicyKeyLoaded( | 523 void UserCloudPolicyStoreChromeOS::EnsurePolicyKeyLoaded( |
524 const base::Closure& callback) { | 524 const base::Closure& callback) { |
525 if (policy_key_loaded_) { | 525 if (policy_key_loaded_) { |
526 callback.Run(); | 526 callback.Run(); |
527 } else { | 527 } else { |
528 // Get the hashed username that's part of the key's path, to determine | 528 // Get the hashed username that's part of the key's path, to determine |
529 // |policy_key_path_|. | 529 // |policy_key_path_|. |
530 cryptohome_client_->GetSanitizedUsername(username_, | 530 cryptohome_client_->GetSanitizedUsername(user_id_, |
531 base::Bind(&UserCloudPolicyStoreChromeOS::OnGetSanitizedUsername, | 531 base::Bind(&UserCloudPolicyStoreChromeOS::OnGetSanitizedUsername, |
532 weak_factory_.GetWeakPtr(), | 532 weak_factory_.GetWeakPtr(), |
533 callback)); | 533 callback)); |
534 } | 534 } |
535 } | 535 } |
536 | 536 |
537 void UserCloudPolicyStoreChromeOS::OnGetSanitizedUsername( | 537 void UserCloudPolicyStoreChromeOS::OnGetSanitizedUsername( |
538 const base::Closure& callback, | 538 const base::Closure& callback, |
539 chromeos::DBusMethodCallStatus call_status, | 539 chromeos::DBusMethodCallStatus call_status, |
540 const std::string& sanitized_username) { | 540 const std::string& sanitized_username) { |
541 // The default empty path will always yield an empty key. | 541 // The default empty path will always yield an empty key. |
542 if (call_status == chromeos::DBUS_METHOD_CALL_SUCCESS && | 542 if (call_status == chromeos::DBUS_METHOD_CALL_SUCCESS && |
543 !sanitized_username.empty()) { | 543 !sanitized_username.empty()) { |
544 policy_key_path_ = user_policy_key_dir_.Append( | 544 policy_key_path_ = user_policy_key_dir_.Append( |
545 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str())); | 545 base::StringPrintf(kPolicyKeyFile, sanitized_username.c_str())); |
546 } else { | 546 } else { |
547 SampleValidationFailure(VALIDATION_FAILURE_DBUS); | 547 SampleValidationFailure(VALIDATION_FAILURE_DBUS); |
548 } | 548 } |
549 ReloadPolicyKey(callback); | 549 ReloadPolicyKey(callback); |
550 } | 550 } |
551 | 551 |
552 scoped_ptr<UserCloudPolicyValidator> | 552 scoped_ptr<UserCloudPolicyValidator> |
553 UserCloudPolicyStoreChromeOS::CreateValidatorForLoad( | 553 UserCloudPolicyStoreChromeOS::CreateValidatorForLoad( |
554 scoped_ptr<em::PolicyFetchResponse> policy) { | 554 scoped_ptr<em::PolicyFetchResponse> policy) { |
555 scoped_ptr<UserCloudPolicyValidator> validator = CreateValidator( | 555 scoped_ptr<UserCloudPolicyValidator> validator = CreateValidator( |
556 policy.Pass(), CloudPolicyValidatorBase::TIMESTAMP_NOT_BEFORE); | 556 policy.Pass(), CloudPolicyValidatorBase::TIMESTAMP_NOT_BEFORE); |
557 validator->ValidateUsername(username_, true); | 557 validator->ValidateUsername(user_id_, true); |
558 const bool allow_rotation = false; | 558 const bool allow_rotation = false; |
559 const std::string empty_key = std::string(); | 559 const std::string empty_key = std::string(); |
560 // The policy loaded from session manager need not be validated using the | 560 // The policy loaded from session manager need not be validated using the |
561 // verification key since it is secure, and since there may be legacy policy | 561 // verification key since it is secure, and since there may be legacy policy |
562 // data that was stored without a verification key. Hence passing an empty | 562 // data that was stored without a verification key. Hence passing an empty |
563 // value for the verification key. | 563 // value for the verification key. |
564 validator->ValidateSignature( | 564 validator->ValidateSignature( |
565 policy_key_, empty_key, ExtractDomain(username_), allow_rotation); | 565 policy_key_, empty_key, ExtractDomain(user_id_.GetUserEmail()), allow_rota
tion); |
566 return validator.Pass(); | 566 return validator.Pass(); |
567 } | 567 } |
568 } // namespace policy | 568 } // namespace policy |
OLD | NEW |