1 // Copyright 2014 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.
5 #include "chrome/browser/managed_mode/chromeos/manager_password_service.h"
8 #include "base/metrics/histogram.h"
9 #include "base/values.h"
10 #include "chrome/browser/chromeos/login/managed/locally_managed_user_constants.h"
11 #include "chrome/browser/chromeos/login/managed/supervised_user_authentication.h"
12 #include "chrome/browser/chromeos/login/supervised_user_manager.h"
13 #include "chrome/browser/chromeos/login/user_manager.h"
14 #include "chrome/browser/managed_mode/managed_user_constants.h"
15 #include "chrome/browser/managed_mode/managed_user_sync_service.h"
19 ManagerPasswordService::ManagerPasswordService() : weak_ptr_factory_(this) {}
21 ManagerPasswordService::~ManagerPasswordService() {}
23 void ManagerPasswordService::Init(
24 const std::string& user_id,
25 ManagedUserSyncService* user_service,
26 ManagedUserSharedSettingsService* shared_settings_service) {
28 user_service_ = user_service;
29 settings_service_ = shared_settings_service;
30 settings_service_subscription_ = settings_service_->Subscribe(
31 base::Bind(&ManagerPasswordService::OnSharedSettingsChange,
32 weak_ptr_factory_.GetWeakPtr()));
34 authenticator_ = new ExtendedAuthenticator(this);
36 UserManager* user_manager = UserManager::Get();
38 SupervisedUserManager* supervised_user_manager =
39 user_manager->GetSupervisedUserManager();
41 const UserList& users = user_manager->GetUsers();
43 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
44 if ((*it)->GetType() != User::USER_TYPE_LOCALLY_MANAGED)
46 if (user_id != supervised_user_manager->GetManagerUserId((*it)->email()))
48 OnSharedSettingsChange(
49 supervised_user_manager->GetUserSyncId((*it)->email()),
50 managed_users::kChromeOSPasswordData);
54 void ManagerPasswordService::OnSharedSettingsChange(
55 const std::string& mu_id,
56 const std::string& key) {
57 if (key != managed_users::kChromeOSPasswordData)
60 SupervisedUserManager* supervised_user_manager =
61 UserManager::Get()->GetSupervisedUserManager();
62 const User* user = supervised_user_manager->FindBySyncId(mu_id);
67 const base::Value* value = settings_service_->GetValue(mu_id, key);
70 LOG(WARNING) << "Got empty value from sync.";
73 const base::DictionaryValue* dict;
74 if (!value->GetAsDictionary(&dict)) {
75 LOG(WARNING) << "Got non-dictionary value from sync.";
79 SupervisedUserAuthentication* auth =
80 supervised_user_manager->GetAuthentication();
82 if (!auth->NeedPasswordChange(user->email(), dict) &&
83 !auth->HasIncompleteKey(user->email())) {
86 scoped_ptr<base::DictionaryValue> wrapper(dict->DeepCopy());
87 user_service_->GetManagedUsersAsync(
88 base::Bind(&ManagerPasswordService::GetManagedUsersCallback,
89 weak_ptr_factory_.GetWeakPtr(),
95 void ManagerPasswordService::GetManagedUsersCallback(
96 const std::string& sync_mu_id,
97 const std::string& user_id,
98 scoped_ptr<base::DictionaryValue> password_data,
99 const base::DictionaryValue* managed_users) {
100 const base::DictionaryValue* managed_user = NULL;
101 if (!managed_users->GetDictionary(sync_mu_id, &managed_user))
103 std::string master_key;
104 std::string encryption_key;
105 std::string signature_key;
106 if (!managed_user->GetString(ManagedUserSyncService::kMasterKey,
108 LOG(WARNING) << "Can not apply password change to " << user_id
109 << ": no master key found";
110 UMA_HISTOGRAM_ENUMERATION(
111 "ManagedUsers.ChromeOS.PasswordChange",
112 SupervisedUserAuthentication::PASSWORD_CHANGE_FAILED_NO_MASTER_KEY,
113 SupervisedUserAuthentication::PASSWORD_CHANGE_RESULT_MAX_VALUE);
117 if (!managed_user->GetString(ManagedUserSyncService::kPasswordSignatureKey,
119 !managed_user->GetString(ManagedUserSyncService::kPasswordEncryptionKey,
121 LOG(WARNING) << "Can not apply password change to " << user_id
122 << ": no signature / encryption keys.";
123 UMA_HISTOGRAM_ENUMERATION(
124 "ManagedUsers.ChromeOS.PasswordChange",
125 SupervisedUserAuthentication::PASSWORD_CHANGE_FAILED_NO_SIGNATURE_KEY,
126 SupervisedUserAuthentication::PASSWORD_CHANGE_RESULT_MAX_VALUE);
130 UserContext manager_key(user_id, master_key, std::string());
131 manager_key.using_oauth = false;
133 // As master key can have old label, leave label field empty - it will work
139 bool has_data = password_data->GetStringWithoutPathExpansion(
140 kEncryptedPassword, &new_key);
141 has_data &= password_data->GetIntegerWithoutPathExpansion(kPasswordRevision,
144 LOG(WARNING) << "Can not apply password change to " << user_id
145 << ": incomplete password data.";
146 UMA_HISTOGRAM_ENUMERATION(
147 "ManagedUsers.ChromeOS.PasswordChange",
148 SupervisedUserAuthentication::PASSWORD_CHANGE_FAILED_NO_PASSWORD_DATA,
149 SupervisedUserAuthentication::PASSWORD_CHANGE_RESULT_MAX_VALUE);
153 cryptohome::KeyDefinition new_key_definition(
155 kCryptohomeManagedUserKeyLabel,
156 cryptohome::PRIV_AUTHORIZED_UPDATE || cryptohome::PRIV_MOUNT);
157 new_key_definition.revision = revision;
159 new_key_definition.encryption_key = encryption_key;
160 new_key_definition.signature_key = signature_key;
162 authenticator_->AddKey(manager_key,
164 true /* replace existing */,
165 base::Bind(&ManagerPasswordService::OnAddKeySuccess,
166 weak_ptr_factory_.GetWeakPtr(),
169 Passed(&password_data)));
172 void ManagerPasswordService::OnAuthenticationFailure(
173 ExtendedAuthenticator::AuthState state) {
174 UMA_HISTOGRAM_ENUMERATION(
175 "ManagedUsers.ChromeOS.PasswordChange",
176 SupervisedUserAuthentication::PASSWORD_CHANGE_FAILED_MASTER_KEY_FAILURE,
177 SupervisedUserAuthentication::PASSWORD_CHANGE_RESULT_MAX_VALUE);
178 LOG(ERROR) << "Can not apply password change, master key failure";
181 void ManagerPasswordService::OnAddKeySuccess(
182 const UserContext& master_key_context,
183 const std::string& user_id,
184 scoped_ptr<base::DictionaryValue> password_data) {
185 VLOG(0) << "Password changed for " << user_id;
186 UMA_HISTOGRAM_ENUMERATION(
187 "ManagedUsers.ChromeOS.PasswordChange",
188 SupervisedUserAuthentication::PASSWORD_CHANGED_IN_MANAGER_SESSION,
189 SupervisedUserAuthentication::PASSWORD_CHANGE_RESULT_MAX_VALUE);
191 SupervisedUserAuthentication* auth =
192 UserManager::Get()->GetSupervisedUserManager()->GetAuthentication();
193 int old_schema = auth->GetPasswordSchema(user_id);
194 auth->StorePasswordData(user_id, *password_data.get());
196 if (auth->HasIncompleteKey(user_id))
197 auth->MarkKeyIncomplete(user_id, false /* key is complete now */);
199 // Check if we have legacy labels for keys.
200 // TODO(antrim): Migrate it to GetLabels call once wad@ implement it.
201 if (old_schema == SupervisedUserAuthentication::SCHEMA_PLAIN) {
202 // 1) Add new manager key (using old key).
203 // 2) Remove old supervised user key.
204 // 3) Remove old manager key.
205 authenticator_->TransformContext(
207 base::Bind(&ManagerPasswordService::OnContextTransformed,
208 weak_ptr_factory_.GetWeakPtr()));
212 void ManagerPasswordService::OnContextTransformed(
213 const UserContext& master_key_context) {
214 DCHECK(!master_key_context.need_password_hashing);
215 cryptohome::KeyDefinition new_master_key(master_key_context.password,
216 kCryptohomeMasterKeyLabel,
217 cryptohome::PRIV_DEFAULT);
218 // Use new master key for further actions.
219 UserContext new_master_key_context;
220 new_master_key_context.CopyFrom(master_key_context);
221 new_master_key_context.key_label = kCryptohomeMasterKeyLabel;
222 authenticator_->AddKey(
225 true /* replace existing */,
226 base::Bind(&ManagerPasswordService::OnNewManagerKeySuccess,
227 weak_ptr_factory_.GetWeakPtr(),
228 new_master_key_context));
231 void ManagerPasswordService::OnNewManagerKeySuccess(
232 const UserContext& master_key_context) {
233 VLOG(1) << "Added new master key for " << master_key_context.username;
234 authenticator_->RemoveKey(
236 kLegacyCryptohomeManagedUserKeyLabel,
237 base::Bind(&ManagerPasswordService::OnOldManagedUserKeyDeleted,
238 weak_ptr_factory_.GetWeakPtr(),
239 master_key_context));
242 void ManagerPasswordService::OnOldManagedUserKeyDeleted(
243 const UserContext& master_key_context) {
244 VLOG(1) << "Removed old managed user key for " << master_key_context.username;
245 authenticator_->RemoveKey(
247 kLegacyCryptohomeMasterKeyLabel,
248 base::Bind(&ManagerPasswordService::OnOldManagerKeyDeleted,
249 weak_ptr_factory_.GetWeakPtr(),
250 master_key_context));
253 void ManagerPasswordService::OnOldManagerKeyDeleted(
254 const UserContext& master_key_context) {
255 VLOG(1) << "Removed old master key for " << master_key_context.username;
258 void ManagerPasswordService::Shutdown() {
259 settings_service_subscription_.reset();
262 } // namespace chromeos