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. 4 5 #include "chrome/browser/chromeos/login/managed/managed_user_creation_controller_new.h" 6 7 #include "base/base64.h" 8 #include "base/bind.h" 9 #include "base/file_util.h" 10 #include "base/files/file_path.h" 11 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_util.h" 13 #include "base/sys_info.h" 14 #include "base/task_runner_util.h" 15 #include "base/threading/sequenced_worker_pool.h" 16 #include "base/values.h" 17 #include "chrome/browser/chromeos/login/auth/key.h" 18 #include "chrome/browser/chromeos/login/auth/mount_manager.h" 19 #include "chrome/browser/chromeos/login/auth/user_context.h" 20 #include "chrome/browser/chromeos/login/managed/locally_managed_user_constants.h" 21 #include "chrome/browser/chromeos/login/managed/supervised_user_authentication.h" 22 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h" 23 #include "chrome/browser/chromeos/login/users/user.h" 24 #include "chrome/browser/chromeos/login/users/user_manager.h" 25 #include "chrome/browser/lifetime/application_lifetime.h" 26 #include "chrome/browser/sync/profile_sync_service.h" 27 #include "chrome/browser/sync/profile_sync_service_factory.h" 28 #include "chromeos/cryptohome/cryptohome_parameters.h" 29 #include "chromeos/dbus/dbus_thread_manager.h" 30 #include "chromeos/dbus/session_manager_client.h" 31 #include "content/public/browser/browser_thread.h" 32 #include "content/public/browser/user_metrics.h" 33 #include "crypto/random.h" 34 #include "google_apis/gaia/google_service_auth_error.h" 35 36 namespace chromeos { 37 38 namespace { 39 40 const int kUserCreationTimeoutSeconds = 30; // 30 seconds. 41 42 bool StoreManagedUserFiles(const std::string& token, 43 const base::FilePath& base_path) { 44 if (!base::SysInfo::IsRunningOnChromeOS()) { 45 // If running on desktop, cryptohome stub does not create home directory. 46 base::CreateDirectory(base_path); 47 } 48 base::FilePath token_file = base_path.Append(kSupervisedUserTokenFilename); 49 int bytes = base::WriteFile(token_file, token.c_str(), token.length()); 50 return bytes >= 0; 51 } 52 53 } // namespace 54 55 ManagedUserCreationControllerNew::ManagedUserCreationControllerNew( 56 ManagedUserCreationControllerNew::StatusConsumer* consumer, 57 const std::string& manager_id) 58 : ManagedUserCreationController(consumer), 59 stage_(STAGE_INITIAL), 60 weak_factory_(this) { 61 creation_context_.reset( 62 new ManagedUserCreationControllerNew::UserCreationContext()); 63 creation_context_->manager_id = manager_id; 64 } 65 66 ManagedUserCreationControllerNew::~ManagedUserCreationControllerNew() {} 67 68 ManagedUserCreationControllerNew::UserCreationContext::UserCreationContext() {} 69 70 ManagedUserCreationControllerNew::UserCreationContext::~UserCreationContext() {} 71 72 void ManagedUserCreationControllerNew::SetManagerProfile( 73 Profile* manager_profile) { 74 creation_context_->manager_profile = manager_profile; 75 } 76 77 Profile* ManagedUserCreationControllerNew::GetManagerProfile() { 78 return creation_context_->manager_profile; 79 } 80 81 void ManagedUserCreationControllerNew::StartCreation( 82 const base::string16& display_name, 83 const std::string& password, 84 int avatar_index) { 85 DCHECK(creation_context_); 86 creation_context_->creation_type = NEW_USER; 87 creation_context_->display_name = display_name; 88 creation_context_->password = password; 89 creation_context_->avatar_index = avatar_index; 90 StartCreationImpl(); 91 } 92 93 void ManagedUserCreationControllerNew::StartImport( 94 const base::string16& display_name, 95 const std::string& password, 96 int avatar_index, 97 const std::string& sync_id, 98 const std::string& master_key) { 99 DCHECK(creation_context_); 100 creation_context_->creation_type = USER_IMPORT_OLD; 101 102 creation_context_->display_name = display_name; 103 creation_context_->password = password; 104 creation_context_->avatar_index = avatar_index; 105 106 creation_context_->sync_user_id = sync_id; 107 108 creation_context_->master_key = master_key; 109 StartCreationImpl(); 110 } 111 112 void ManagedUserCreationControllerNew::StartImport( 113 const base::string16& display_name, 114 int avatar_index, 115 const std::string& sync_id, 116 const std::string& master_key, 117 const base::DictionaryValue* password_data, 118 const std::string& encryption_key, 119 const std::string& signature_key) { 120 DCHECK(creation_context_); 121 creation_context_->creation_type = USER_IMPORT_NEW; 122 123 creation_context_->display_name = display_name; 124 125 creation_context_->avatar_index = avatar_index; 126 127 creation_context_->sync_user_id = sync_id; 128 129 creation_context_->master_key = master_key; 130 131 password_data->GetStringWithoutPathExpansion( 132 kEncryptedPassword, &creation_context_->salted_password); 133 134 creation_context_->signature_key = signature_key; 135 creation_context_->encryption_key = encryption_key; 136 137 creation_context_->password_data.MergeDictionary(password_data); 138 139 StartCreationImpl(); 140 } 141 142 void ManagedUserCreationControllerNew::StartCreationImpl() { 143 DCHECK(creation_context_); 144 DCHECK_EQ(STAGE_INITIAL, stage_); 145 VLOG(1) << "Starting supervised user creation"; 146 VLOG(1) << " Phase 1 : Prepare keys"; 147 148 SupervisedUserManager* manager = 149 UserManager::Get()->GetSupervisedUserManager(); 150 manager->StartCreationTransaction(creation_context_->display_name); 151 152 creation_context_->local_user_id = manager->GenerateUserId(); 153 if (creation_context_->creation_type == NEW_USER) { 154 creation_context_->sync_user_id = 155 SupervisedUserRegistrationUtility::GenerateNewSupervisedUserId(); 156 } 157 158 manager->SetCreationTransactionUserId(creation_context_->local_user_id); 159 160 stage_ = TRANSACTION_STARTED; 161 162 manager->CreateUserRecord(creation_context_->manager_id, 163 creation_context_->local_user_id, 164 creation_context_->sync_user_id, 165 creation_context_->display_name); 166 167 SupervisedUserAuthentication* authentication = 168 UserManager::Get()->GetSupervisedUserManager()->GetAuthentication(); 169 170 // When importing M35+ users we need only to store data, for all other cases 171 // we need to create some keys. 172 if (creation_context_->creation_type != USER_IMPORT_NEW) { 173 // Of all required keys old imported users have only master key. 174 // Otherwise they are the same as newly created users in terms of keys. 175 if (creation_context_->creation_type == NEW_USER) { 176 creation_context_->master_key = authentication->GenerateMasterKey(); 177 } 178 179 base::DictionaryValue extra; 180 authentication->FillDataForNewUser(creation_context_->local_user_id, 181 creation_context_->password, 182 &creation_context_->password_data, 183 &extra); 184 creation_context_->password_data.GetStringWithoutPathExpansion( 185 kEncryptedPassword, &creation_context_->salted_password); 186 extra.GetStringWithoutPathExpansion(kPasswordEncryptionKey, 187 &creation_context_->encryption_key); 188 extra.GetStringWithoutPathExpansion(kPasswordSignatureKey, 189 &creation_context_->signature_key); 190 } 191 192 authentication->StorePasswordData(creation_context_->local_user_id, 193 creation_context_->password_data); 194 stage_ = KEYS_GENERATED; 195 196 VLOG(1) << " Phase 2 : Create cryptohome"; 197 198 timeout_timer_.Start( 199 FROM_HERE, 200 base::TimeDelta::FromSeconds(kUserCreationTimeoutSeconds), 201 this, 202 &ManagedUserCreationControllerNew::CreationTimedOut); 203 authenticator_ = new ExtendedAuthenticator(this); 204 UserContext user_context; 205 user_context.SetKey(Key(creation_context_->master_key)); 206 authenticator_->TransformKeyIfNeeded( 207 user_context, 208 base::Bind(&ManagedUserCreationControllerNew::OnKeyTransformedIfNeeded, 209 weak_factory_.GetWeakPtr())); 210 } 211 212 void ManagedUserCreationControllerNew::OnKeyTransformedIfNeeded( 213 const UserContext& user_context) { 214 VLOG(1) << " Phase 2.1 : Got hashed master key"; 215 creation_context_->salted_master_key = user_context.GetKey()->GetSecret(); 216 217 // Create home dir with two keys. 218 std::vector<cryptohome::KeyDefinition> keys; 219 220 // Main key is the master key. Just as keys for plain GAIA users, it is salted 221 // with system salt. It has all usual privileges. 222 cryptohome::KeyDefinition master_key(creation_context_->salted_master_key, 223 kCryptohomeMasterKeyLabel, 224 cryptohome::PRIV_DEFAULT); 225 226 keys.push_back(master_key); 227 authenticator_->CreateMount( 228 creation_context_->local_user_id, 229 keys, 230 base::Bind(&ManagedUserCreationControllerNew::OnMountSuccess, 231 weak_factory_.GetWeakPtr())); 232 } 233 234 void ManagedUserCreationControllerNew::OnAuthenticationFailure( 235 ExtendedAuthenticator::AuthState error) { 236 timeout_timer_.Stop(); 237 ErrorCode code = NO_ERROR; 238 switch (error) { 239 case ManagedUserAuthenticator::NO_MOUNT: 240 code = CRYPTOHOME_NO_MOUNT; 241 break; 242 case ManagedUserAuthenticator::FAILED_MOUNT: 243 code = CRYPTOHOME_FAILED_MOUNT; 244 break; 245 case ManagedUserAuthenticator::FAILED_TPM: 246 code = CRYPTOHOME_FAILED_TPM; 247 break; 248 default: 249 NOTREACHED(); 250 } 251 stage_ = STAGE_ERROR; 252 if (consumer_) 253 consumer_->OnCreationError(code); 254 } 255 256 void ManagedUserCreationControllerNew::OnMountSuccess( 257 const std::string& mount_hash) { 258 DCHECK(creation_context_); 259 DCHECK_EQ(KEYS_GENERATED, stage_); 260 VLOG(1) << " Phase 2.2 : Created home dir with master key"; 261 262 creation_context_->mount_hash = mount_hash; 263 264 // Plain text password, hashed and salted with individual salt. 265 // It can be used for mounting homedir, and can be replaced only when signed. 266 cryptohome::KeyDefinition password_key( 267 creation_context_->salted_password, 268 kCryptohomeSupervisedUserKeyLabel, 269 kCryptohomeSupervisedUserKeyPrivileges); 270 base::Base64Decode(creation_context_->encryption_key, 271 &password_key.encryption_key); 272 base::Base64Decode(creation_context_->signature_key, 273 &password_key.signature_key); 274 275 Key key(Key::KEY_TYPE_SALTED_PBKDF2_AES256_1234, 276 std::string(), // The salt is stored elsewhere. 277 creation_context_->salted_master_key); 278 key.SetLabel(kCryptohomeMasterKeyLabel); 279 UserContext context(creation_context_->local_user_id); 280 context.SetKey(key); 281 context.SetIsUsingOAuth(false); 282 283 authenticator_->AddKey( 284 context, 285 password_key, 286 true, 287 base::Bind(&ManagedUserCreationControllerNew::OnAddKeySuccess, 288 weak_factory_.GetWeakPtr())); 289 } 290 291 void ManagedUserCreationControllerNew::OnAddKeySuccess() { 292 DCHECK(creation_context_); 293 DCHECK_EQ(KEYS_GENERATED, stage_); 294 stage_ = CRYPTOHOME_CREATED; 295 296 VLOG(1) << " Phase 3 : Create/update user on chrome.com/manage"; 297 298 ProfileSyncService* sync_service = 299 ProfileSyncServiceFactory::GetInstance()->GetForProfile( 300 creation_context_->manager_profile); 301 ProfileSyncService::SyncStatusSummary status = 302 sync_service->QuerySyncStatusSummary(); 303 304 if (status == ProfileSyncService::DATATYPES_NOT_INITIALIZED) 305 consumer_->OnLongCreationWarning(); 306 307 creation_context_->registration_utility = 308 SupervisedUserRegistrationUtility::Create( 309 creation_context_->manager_profile); 310 311 SupervisedUserRegistrationInfo info(creation_context_->display_name, 312 creation_context_->avatar_index); 313 info.master_key = creation_context_->master_key; 314 info.password_signature_key = creation_context_->signature_key; 315 info.password_encryption_key = creation_context_->encryption_key; 316 317 info.password_data.MergeDictionary(&creation_context_->password_data); 318 319 // Registration utility will update user data if user already exist. 320 creation_context_->registration_utility->Register( 321 creation_context_->sync_user_id, 322 info, 323 base::Bind(&ManagedUserCreationControllerNew::RegistrationCallback, 324 weak_factory_.GetWeakPtr())); 325 } 326 327 void ManagedUserCreationControllerNew::RegistrationCallback( 328 const GoogleServiceAuthError& error, 329 const std::string& token) { 330 DCHECK(creation_context_); 331 DCHECK_EQ(CRYPTOHOME_CREATED, stage_); 332 333 stage_ = DASHBOARD_CREATED; 334 335 if (error.state() == GoogleServiceAuthError::NONE) { 336 creation_context_->token = token; 337 338 PostTaskAndReplyWithResult( 339 content::BrowserThread::GetBlockingPool(), 340 FROM_HERE, 341 base::Bind(&StoreManagedUserFiles, 342 creation_context_->token, 343 MountManager::GetHomeDir(creation_context_->mount_hash)), 344 base::Bind(&ManagedUserCreationControllerNew::OnManagedUserFilesStored, 345 weak_factory_.GetWeakPtr())); 346 } else { 347 stage_ = STAGE_ERROR; 348 LOG(ERROR) << "Managed user creation failed. Error code " << error.state(); 349 if (consumer_) 350 consumer_->OnCreationError(CLOUD_SERVER_ERROR); 351 } 352 } 353 354 void ManagedUserCreationControllerNew::OnManagedUserFilesStored(bool success) { 355 DCHECK(creation_context_); 356 DCHECK_EQ(DASHBOARD_CREATED, stage_); 357 358 if (!success) { 359 stage_ = STAGE_ERROR; 360 if (consumer_) 361 consumer_->OnCreationError(TOKEN_WRITE_FAILED); 362 return; 363 } 364 // Assume that new token is valid. It will be automatically invalidated if 365 // sync service fails to use it. 366 UserManager::Get()->SaveUserOAuthStatus(creation_context_->local_user_id, 367 User::OAUTH2_TOKEN_STATUS_VALID); 368 369 stage_ = TOKEN_WRITTEN; 370 371 timeout_timer_.Stop(); 372 UserManager::Get()->GetSupervisedUserManager()->CommitCreationTransaction(); 373 content::RecordAction( 374 base::UserMetricsAction("ManagedMode_LocallyManagedUserCreated")); 375 376 stage_ = TRANSACTION_COMMITTED; 377 378 if (consumer_) 379 consumer_->OnCreationSuccess(); 380 } 381 382 void ManagedUserCreationControllerNew::CreationTimedOut() { 383 LOG(ERROR) << "Supervised user creation timed out. stage = " << stage_; 384 if (consumer_) 385 consumer_->OnCreationTimeout(); 386 } 387 388 void ManagedUserCreationControllerNew::FinishCreation() { 389 chrome::AttemptUserExit(); 390 } 391 392 void ManagedUserCreationControllerNew::CancelCreation() { 393 creation_context_->registration_utility.reset(); 394 chrome::AttemptUserExit(); 395 } 396 397 std::string ManagedUserCreationControllerNew::GetManagedUserId() { 398 DCHECK(creation_context_); 399 return creation_context_->local_user_id; 400 } 401 402 } // namespace chromeos 403