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_old.h" 6 7 #include "base/bind.h" 8 #include "base/file_util.h" 9 #include "base/files/file_path.h" 10 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_util.h" 12 #include "base/sys_info.h" 13 #include "base/task_runner_util.h" 14 #include "base/threading/sequenced_worker_pool.h" 15 #include "base/values.h" 16 #include "chrome/browser/chromeos/login/auth/key.h" 17 #include "chrome/browser/chromeos/login/auth/mount_manager.h" 18 #include "chrome/browser/chromeos/login/auth/user_context.h" 19 #include "chrome/browser/chromeos/login/managed/locally_managed_user_constants.h" 20 #include "chrome/browser/chromeos/login/managed/supervised_user_authentication.h" 21 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h" 22 #include "chrome/browser/chromeos/login/users/user.h" 23 #include "chrome/browser/chromeos/login/users/user_manager.h" 24 #include "chrome/browser/lifetime/application_lifetime.h" 25 #include "chrome/browser/sync/profile_sync_service.h" 26 #include "chrome/browser/sync/profile_sync_service_factory.h" 27 #include "chromeos/dbus/dbus_thread_manager.h" 28 #include "chromeos/dbus/session_manager_client.h" 29 #include "content/public/browser/browser_thread.h" 30 #include "content/public/browser/user_metrics.h" 31 #include "crypto/random.h" 32 #include "google_apis/gaia/google_service_auth_error.h" 33 34 namespace chromeos { 35 36 namespace { 37 38 const int kUserCreationTimeoutSeconds = 30; // 30 seconds. 39 40 bool StoreManagedUserFiles(const std::string& token, 41 const base::FilePath& base_path) { 42 if (!base::SysInfo::IsRunningOnChromeOS()) { 43 // If running on desktop, cryptohome stub does not create home directory. 44 base::CreateDirectory(base_path); 45 } 46 base::FilePath token_file = base_path.Append(kSupervisedUserTokenFilename); 47 int bytes = base::WriteFile(token_file, token.c_str(), token.length()); 48 return bytes >= 0; 49 } 50 51 } // namespace 52 53 ManagedUserCreationControllerOld::UserCreationContext::UserCreationContext() 54 : avatar_index(kDummyAvatarIndex), 55 token_acquired(false), 56 token_succesfully_written(false), 57 creation_type(NEW_USER), 58 manager_profile(NULL) {} 59 60 ManagedUserCreationControllerOld::UserCreationContext::~UserCreationContext() {} 61 62 ManagedUserCreationControllerOld::ManagedUserCreationControllerOld( 63 ManagedUserCreationControllerOld::StatusConsumer* consumer, 64 const std::string& manager_id) 65 : ManagedUserCreationController(consumer), weak_factory_(this) { 66 creation_context_.reset( 67 new ManagedUserCreationControllerOld::UserCreationContext()); 68 creation_context_->manager_id = manager_id; 69 } 70 71 ManagedUserCreationControllerOld::~ManagedUserCreationControllerOld() {} 72 73 void ManagedUserCreationControllerOld::StartCreation( 74 const base::string16& display_name, 75 const std::string& password, 76 int avatar_index) { 77 DCHECK(creation_context_); 78 creation_context_->display_name = display_name; 79 creation_context_->password = password; 80 creation_context_->avatar_index = avatar_index; 81 StartCreation(); 82 } 83 84 void ManagedUserCreationControllerOld::StartImport( 85 const base::string16& display_name, 86 const std::string& password, 87 int avatar_index, 88 const std::string& sync_id, 89 const std::string& master_key) { 90 DCHECK(creation_context_); 91 creation_context_->creation_type = USER_IMPORT; 92 creation_context_->display_name = display_name; 93 creation_context_->password = password; 94 creation_context_->avatar_index = avatar_index; 95 creation_context_->sync_user_id = sync_id; 96 creation_context_->master_key = master_key; 97 StartCreation(); 98 } 99 100 void ManagedUserCreationControllerOld::StartImport( 101 const base::string16& display_name, 102 int avatar_index, 103 const std::string& sync_id, 104 const std::string& master_key, 105 const base::DictionaryValue* password_data, 106 const std::string& encryption_key, 107 const std::string& signature_key) { 108 NOTREACHED(); 109 } 110 111 void ManagedUserCreationControllerOld::SetManagerProfile( 112 Profile* manager_profile) { 113 creation_context_->manager_profile = manager_profile; 114 } 115 116 Profile* ManagedUserCreationControllerOld::GetManagerProfile() { 117 return creation_context_->manager_profile; 118 } 119 120 void ManagedUserCreationControllerOld::StartCreation() { 121 DCHECK(creation_context_); 122 VLOG(1) << "Starting supervised user creation"; 123 124 ProfileSyncService* sync_service = 125 ProfileSyncServiceFactory::GetInstance()->GetForProfile( 126 creation_context_->manager_profile); 127 ProfileSyncService::SyncStatusSummary status = 128 sync_service->QuerySyncStatusSummary(); 129 130 if (status == ProfileSyncService::DATATYPES_NOT_INITIALIZED) 131 consumer_->OnLongCreationWarning(); 132 133 timeout_timer_.Start( 134 FROM_HERE, 135 base::TimeDelta::FromSeconds(kUserCreationTimeoutSeconds), 136 this, 137 &ManagedUserCreationControllerOld::CreationTimedOut); 138 SupervisedUserManager* manager = 139 UserManager::Get()->GetSupervisedUserManager(); 140 manager->StartCreationTransaction(creation_context_->display_name); 141 142 creation_context_->local_user_id = manager->GenerateUserId(); 143 144 if (creation_context_->creation_type == NEW_USER) { 145 creation_context_->sync_user_id = 146 SupervisedUserRegistrationUtility::GenerateNewSupervisedUserId(); 147 } 148 149 manager->CreateUserRecord(creation_context_->manager_id, 150 creation_context_->local_user_id, 151 creation_context_->sync_user_id, 152 creation_context_->display_name); 153 154 manager->SetCreationTransactionUserId(creation_context_->local_user_id); 155 SupervisedUserAuthentication* authentication = manager->GetAuthentication(); 156 base::DictionaryValue extra; 157 if (authentication->FillDataForNewUser(creation_context_->local_user_id, 158 creation_context_->password, 159 &creation_context_->password_data, 160 &extra)) { 161 authentication->StorePasswordData(creation_context_->local_user_id, 162 creation_context_->password_data); 163 } 164 165 VLOG(1) << "Creating cryptohome"; 166 167 UserContext context(creation_context_->local_user_id); 168 context.SetKey(Key(creation_context_->password)); 169 authenticator_ = new ManagedUserAuthenticator(this); 170 authenticator_->AuthenticateToCreate( 171 context.GetUserID(), 172 authentication->TransformKey(context).GetKey()->GetSecret()); 173 } 174 175 void ManagedUserCreationControllerOld::OnAuthenticationFailure( 176 ManagedUserAuthenticator::AuthState error) { 177 timeout_timer_.Stop(); 178 ErrorCode code = NO_ERROR; 179 switch (error) { 180 case ManagedUserAuthenticator::NO_MOUNT: 181 code = CRYPTOHOME_NO_MOUNT; 182 break; 183 case ManagedUserAuthenticator::FAILED_MOUNT: 184 code = CRYPTOHOME_FAILED_MOUNT; 185 break; 186 case ManagedUserAuthenticator::FAILED_TPM: 187 code = CRYPTOHOME_FAILED_TPM; 188 break; 189 default: 190 NOTREACHED(); 191 } 192 if (consumer_) 193 consumer_->OnCreationError(code); 194 } 195 196 void ManagedUserCreationControllerOld::OnMountSuccess( 197 const std::string& mount_hash) { 198 creation_context_->mount_hash = mount_hash; 199 200 SupervisedUserAuthentication* authentication = 201 UserManager::Get()->GetSupervisedUserManager()->GetAuthentication(); 202 203 if (creation_context_->creation_type == NEW_USER) { 204 // Generate master password. 205 creation_context_->master_key = authentication->GenerateMasterKey(); 206 } 207 208 VLOG(1) << "Adding master key"; 209 210 UserContext context(creation_context_->local_user_id); 211 context.SetKey(Key(creation_context_->password)); 212 authenticator_->AddMasterKey( 213 creation_context_->local_user_id, 214 authentication->TransformKey(context).GetKey()->GetSecret(), 215 creation_context_->master_key); 216 } 217 218 void ManagedUserCreationControllerOld::OnAddKeySuccess() { 219 creation_context_->registration_utility = 220 SupervisedUserRegistrationUtility::Create( 221 creation_context_->manager_profile); 222 223 VLOG(1) << "Creating user on server"; 224 // TODO(antrim) : add password data to sync once API is ready. 225 // http://crbug.com/316168 226 SupervisedUserRegistrationInfo info(creation_context_->display_name, 227 creation_context_->avatar_index); 228 info.master_key = creation_context_->master_key; 229 timeout_timer_.Stop(); 230 creation_context_->registration_utility->Register( 231 creation_context_->sync_user_id, 232 info, 233 base::Bind(&ManagedUserCreationControllerOld::RegistrationCallback, 234 weak_factory_.GetWeakPtr())); 235 } 236 237 void ManagedUserCreationControllerOld::RegistrationCallback( 238 const GoogleServiceAuthError& error, 239 const std::string& token) { 240 if (error.state() == GoogleServiceAuthError::NONE) { 241 timeout_timer_.Start( 242 FROM_HERE, 243 base::TimeDelta::FromSeconds(kUserCreationTimeoutSeconds), 244 this, 245 &ManagedUserCreationControllerOld::CreationTimedOut); 246 TokenFetched(token); 247 } else { 248 LOG(ERROR) << "Managed user creation failed. Error code " << error.state(); 249 if (consumer_) 250 consumer_->OnCreationError(CLOUD_SERVER_ERROR); 251 } 252 } 253 254 void ManagedUserCreationControllerOld::CreationTimedOut() { 255 LOG(ERROR) << "Supervised user creation timed out."; 256 if (consumer_) 257 consumer_->OnCreationTimeout(); 258 } 259 260 void ManagedUserCreationControllerOld::FinishCreation() { 261 chrome::AttemptUserExit(); 262 } 263 264 void ManagedUserCreationControllerOld::CancelCreation() { 265 creation_context_->registration_utility.reset(); 266 chrome::AttemptUserExit(); 267 } 268 269 std::string ManagedUserCreationControllerOld::GetManagedUserId() { 270 DCHECK(creation_context_); 271 return creation_context_->local_user_id; 272 } 273 274 void ManagedUserCreationControllerOld::TokenFetched(const std::string& token) { 275 creation_context_->token_acquired = true; 276 creation_context_->token = token; 277 278 PostTaskAndReplyWithResult( 279 content::BrowserThread::GetBlockingPool(), 280 FROM_HERE, 281 base::Bind(&StoreManagedUserFiles, 282 creation_context_->token, 283 MountManager::GetHomeDir(creation_context_->mount_hash)), 284 base::Bind(&ManagedUserCreationControllerOld::OnManagedUserFilesStored, 285 weak_factory_.GetWeakPtr())); 286 } 287 288 void ManagedUserCreationControllerOld::OnManagedUserFilesStored(bool success) { 289 timeout_timer_.Stop(); 290 291 content::RecordAction( 292 base::UserMetricsAction("ManagedMode_LocallyManagedUserCreated")); 293 294 if (!success) { 295 if (consumer_) 296 consumer_->OnCreationError(TOKEN_WRITE_FAILED); 297 return; 298 } 299 // Assume that new token is valid. It will be automatically invalidated if 300 // sync service fails to use it. 301 UserManager::Get()->SaveUserOAuthStatus(creation_context_->local_user_id, 302 User::OAUTH2_TOKEN_STATUS_VALID); 303 UserManager::Get()->GetSupervisedUserManager()->CommitCreationTransaction(); 304 if (consumer_) 305 consumer_->OnCreationSuccess(); 306 } 307 308 } // namespace chromeos 309