15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/supervised_user/chromeos/manager_password_service.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/bind.h" 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/logging.h" 923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/metrics/histogram.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/values.h" 115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/login/supervised/supervised_user_authentication.h" 125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/login/supervised/supervised_user_constants.h" 136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/chrome_user_manager.h" 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/supervised_user_manager.h" 15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/supervised_user/supervised_user_constants.h" 16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/supervised_user/supervised_user_sync_service.h" 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chromeos/login/auth/key.h" 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chromeos/login/auth/user_context.h" 195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/user_manager/user.h" 206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/user_manager/user_manager.h" 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/user_manager/user_type.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)namespace chromeos { 2423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ManagerPasswordService::ManagerPasswordService() : weak_ptr_factory_(this) {} 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ManagerPasswordService::~ManagerPasswordService() {} 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ManagerPasswordService::Init( 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& user_id, 31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SupervisedUserSyncService* user_service, 32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SupervisedUserSharedSettingsService* shared_settings_service) { 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) user_id_ = user_id; 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) user_service_ = user_service; 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) settings_service_ = shared_settings_service; 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) settings_service_subscription_ = settings_service_->Subscribe( 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&ManagerPasswordService::OnSharedSettingsChange, 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4029b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch authenticator_ = ExtendedAuthenticator::Create(this); 4123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 4223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) SupervisedUserManager* supervised_user_manager = 436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ChromeUserManager::Get()->GetSupervisedUserManager(); 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const user_manager::UserList& users = 466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) user_manager::UserManager::Get()->GetUsers(); 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (user_manager::UserList::const_iterator it = users.begin(); 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) it != users.end(); 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ++it) { 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if ((*it)->GetType() != user_manager::USER_TYPE_SUPERVISED) 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (user_id != supervised_user_manager->GetManagerUserId((*it)->email())) 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnSharedSettingsChange( 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) supervised_user_manager->GetUserSyncId((*it)->email()), 57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) supervised_users::kChromeOSPasswordData); 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ManagerPasswordService::OnSharedSettingsChange( 62f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& su_id, 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& key) { 64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (key != supervised_users::kChromeOSPasswordData) 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) SupervisedUserManager* supervised_user_manager = 686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ChromeUserManager::Get()->GetSupervisedUserManager(); 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const user_manager::User* user = supervised_user_manager->FindBySyncId(su_id); 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // No user on device. 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (user == NULL) 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const base::Value* value = settings_service_->GetValue(su_id, key); 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (value == NULL) { 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(WARNING) << "Got empty value from sync."; 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::DictionaryValue* dict; 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!value->GetAsDictionary(&dict)) { 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(WARNING) << "Got non-dictionary value from sync."; 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) SupervisedUserAuthentication* auth = 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) supervised_user_manager->GetAuthentication(); 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!auth->NeedPasswordChange(user->email(), dict) && 90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch !auth->HasIncompleteKey(user->email())) { 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_ptr<base::DictionaryValue> wrapper(dict->DeepCopy()); 94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) user_service_->GetSupervisedUsersAsync( 95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Bind(&ManagerPasswordService::GetSupervisedUsersCallback, 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) su_id, 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) user->email(), 99effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch Passed(&wrapper))); 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ManagerPasswordService::GetSupervisedUsersCallback( 103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& sync_su_id, 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& user_id, 105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_ptr<base::DictionaryValue> password_data, 106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const base::DictionaryValue* supervised_users) { 107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const base::DictionaryValue* supervised_user = NULL; 108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!supervised_users->GetDictionary(sync_su_id, &supervised_user)) 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string master_key; 11123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) std::string encryption_key; 11223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) std::string signature_key; 113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!supervised_user->GetString(SupervisedUserSyncService::kMasterKey, 114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &master_key)) { 11523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) LOG(WARNING) << "Can not apply password change to " << user_id 11623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) << ": no master key found"; 11723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION( 11823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) "ManagedUsers.ChromeOS.PasswordChange", 11923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) SupervisedUserAuthentication::PASSWORD_CHANGE_FAILED_NO_MASTER_KEY, 12023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) SupervisedUserAuthentication::PASSWORD_CHANGE_RESULT_MAX_VALUE); 12123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 12223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 12323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!supervised_user->GetString( 125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SupervisedUserSyncService::kPasswordSignatureKey, &signature_key) || 126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) !supervised_user->GetString( 127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SupervisedUserSyncService::kPasswordEncryptionKey, 128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &encryption_key)) { 12923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) LOG(WARNING) << "Can not apply password change to " << user_id 13023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) << ": no signature / encryption keys."; 13123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION( 13223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) "ManagedUsers.ChromeOS.PasswordChange", 13323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) SupervisedUserAuthentication::PASSWORD_CHANGE_FAILED_NO_SIGNATURE_KEY, 13423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) SupervisedUserAuthentication::PASSWORD_CHANGE_RESULT_MAX_VALUE); 13523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 13623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 13723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) UserContext manager_key(user_id); 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) manager_key.SetKey(Key(master_key)); 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) manager_key.SetIsUsingOAuth(false); 14123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 14223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // As master key can have old label, leave label field empty - it will work 14323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // as wildcard. 14423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 14523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) std::string new_key; 14623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int revision; 14723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 14823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bool has_data = password_data->GetStringWithoutPathExpansion( 14923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) kEncryptedPassword, &new_key); 15023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) has_data &= password_data->GetIntegerWithoutPathExpansion(kPasswordRevision, 15123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &revision); 15223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!has_data) { 15323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) LOG(WARNING) << "Can not apply password change to " << user_id 15423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) << ": incomplete password data."; 15523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION( 15623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) "ManagedUsers.ChromeOS.PasswordChange", 15723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) SupervisedUserAuthentication::PASSWORD_CHANGE_FAILED_NO_PASSWORD_DATA, 15823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) SupervisedUserAuthentication::PASSWORD_CHANGE_RESULT_MAX_VALUE); 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 16023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 16123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 16223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) cryptohome::KeyDefinition new_key_definition( 16323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) new_key, 164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) kCryptohomeSupervisedUserKeyLabel, 16523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) cryptohome::PRIV_AUTHORIZED_UPDATE || cryptohome::PRIV_MOUNT); 16623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) new_key_definition.revision = revision; 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_key_definition.authorization_data.push_back( 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cryptohome::KeyDefinition::AuthorizationData(true /* encrypt */, 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci false /* sign */, 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci encryption_key)); 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_key_definition.authorization_data.push_back( 1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cryptohome::KeyDefinition::AuthorizationData(false /* encrypt */, 1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci true /* sign */, 1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci signature_key)); 17523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 17623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) authenticator_->AddKey(manager_key, 17723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) new_key_definition, 17823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) true /* replace existing */, 17923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&ManagerPasswordService::OnAddKeySuccess, 18023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 181effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch manager_key, 18223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) user_id, 183effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch Passed(&password_data))); 18423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 18523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 18623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void ManagerPasswordService::OnAuthenticationFailure( 18723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ExtendedAuthenticator::AuthState state) { 18823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION( 18923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) "ManagedUsers.ChromeOS.PasswordChange", 19023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) SupervisedUserAuthentication::PASSWORD_CHANGE_FAILED_MASTER_KEY_FAILURE, 19123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) SupervisedUserAuthentication::PASSWORD_CHANGE_RESULT_MAX_VALUE); 19223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) LOG(ERROR) << "Can not apply password change, master key failure"; 19323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 19423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 19523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void ManagerPasswordService::OnAddKeySuccess( 196effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const UserContext& master_key_context, 19723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const std::string& user_id, 198effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_ptr<base::DictionaryValue> password_data) { 19923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) VLOG(0) << "Password changed for " << user_id; 20023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION( 20123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) "ManagedUsers.ChromeOS.PasswordChange", 20223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) SupervisedUserAuthentication::PASSWORD_CHANGED_IN_MANAGER_SESSION, 20323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) SupervisedUserAuthentication::PASSWORD_CHANGE_RESULT_MAX_VALUE); 20423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 20523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) SupervisedUserAuthentication* auth = 2066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ChromeUserManager::Get()->GetSupervisedUserManager()->GetAuthentication(); 207effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch int old_schema = auth->GetPasswordSchema(user_id); 208effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch auth->StorePasswordData(user_id, *password_data.get()); 209c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 210c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (auth->HasIncompleteKey(user_id)) 211c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch auth->MarkKeyIncomplete(user_id, false /* key is complete now */); 212c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 213c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Check if we have legacy labels for keys. 214c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // TODO(antrim): Migrate it to GetLabels call once wad@ implement it. 215effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (old_schema == SupervisedUserAuthentication::SCHEMA_PLAIN) { 216effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // 1) Add new manager key (using old key). 217effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // 2) Remove old supervised user key. 218effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // 3) Remove old manager key. 219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) authenticator_->TransformKeyIfNeeded( 220effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch master_key_context, 221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&ManagerPasswordService::OnKeyTransformedIfNeeded, 222effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch weak_ptr_factory_.GetWeakPtr())); 223effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 224effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 225effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ManagerPasswordService::OnKeyTransformedIfNeeded( 227effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const UserContext& master_key_context) { 228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const Key* const key = master_key_context.GetKey(); 229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK_NE(Key::KEY_TYPE_PASSWORD_PLAIN, key->GetKeyType()); 230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cryptohome::KeyDefinition new_master_key(key->GetSecret(), 231effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch kCryptohomeMasterKeyLabel, 232effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch cryptohome::PRIV_DEFAULT); 233c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Use new master key for further actions. 234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) UserContext new_master_key_context = master_key_context; 235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new_master_key_context.GetKey()->SetLabel(kCryptohomeMasterKeyLabel); 236effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch authenticator_->AddKey( 237effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch master_key_context, 238effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch new_master_key, 239effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch true /* replace existing */, 240effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Bind(&ManagerPasswordService::OnNewManagerKeySuccess, 241effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch weak_ptr_factory_.GetWeakPtr(), 242c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch new_master_key_context)); 243effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 244effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 245effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ManagerPasswordService::OnNewManagerKeySuccess( 246effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const UserContext& master_key_context) { 247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) VLOG(1) << "Added new master key for " << master_key_context.GetUserID(); 248effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch authenticator_->RemoveKey( 249effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch master_key_context, 250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) kLegacyCryptohomeSupervisedUserKeyLabel, 251f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Bind(&ManagerPasswordService::OnOldSupervisedUserKeyDeleted, 252effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch weak_ptr_factory_.GetWeakPtr(), 253effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch master_key_context)); 254effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 255effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ManagerPasswordService::OnOldSupervisedUserKeyDeleted( 257effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const UserContext& master_key_context) { 258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) VLOG(1) << "Removed old supervised user key for " 259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << master_key_context.GetUserID(); 260effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch authenticator_->RemoveKey( 261effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch master_key_context, 262effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch kLegacyCryptohomeMasterKeyLabel, 263effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Bind(&ManagerPasswordService::OnOldManagerKeyDeleted, 264effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch weak_ptr_factory_.GetWeakPtr(), 265effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch master_key_context)); 266effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 267effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 268effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ManagerPasswordService::OnOldManagerKeyDeleted( 269effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const UserContext& master_key_context) { 270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) VLOG(1) << "Removed old master key for " << master_key_context.GetUserID(); 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ManagerPasswordService::Shutdown() { 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) settings_service_subscription_.reset(); 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 27623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 27723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} // namespace chromeos 278