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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/chromeos/login/managed/locally_managed_user_creation_controller.h" 6 7 #include "base/bind.h" 8 #include "base/chromeos/chromeos_version.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/task_runner_util.h" 14 #include "base/threading/sequenced_worker_pool.h" 15 #include "base/values.h" 16 #include "chrome/browser/chromeos/login/managed/locally_managed_user_constants.h" 17 #include "chrome/browser/chromeos/login/mount_manager.h" 18 #include "chrome/browser/chromeos/login/user.h" 19 #include "chrome/browser/chromeos/login/user_manager.h" 20 #include "chrome/browser/lifetime/application_lifetime.h" 21 #include "chromeos/dbus/dbus_thread_manager.h" 22 #include "chromeos/dbus/session_manager_client.h" 23 #include "content/public/browser/browser_thread.h" 24 #include "crypto/random.h" 25 #include "google_apis/gaia/google_service_auth_error.h" 26 27 namespace chromeos { 28 29 namespace { 30 31 const int kMasterKeySize = 32; 32 const int kUserCreationTimeoutSeconds = 60; // 60 seconds. 33 34 bool StoreManagedUserFiles(const std::string& token, 35 const base::FilePath& base_path) { 36 if (!base::chromeos::IsRunningOnChromeOS()) { 37 // If running on desktop, cryptohome stub does not create home directory. 38 file_util::CreateDirectory(base_path); 39 } 40 base::FilePath token_file = base_path.Append(kManagedUserTokenFilename); 41 int bytes = file_util::WriteFile(token_file, token.c_str(), token.length()); 42 return bytes >= 0; 43 } 44 45 } // namespace 46 47 LocallyManagedUserCreationController::StatusConsumer::~StatusConsumer() {} 48 49 LocallyManagedUserCreationController::UserCreationContext::UserCreationContext() 50 : token_acquired(false), 51 token_succesfully_written(false), 52 manager_profile(NULL) {} 53 54 LocallyManagedUserCreationController::UserCreationContext:: 55 ~UserCreationContext() {} 56 57 // static 58 LocallyManagedUserCreationController* 59 LocallyManagedUserCreationController::current_controller_ = NULL; 60 61 LocallyManagedUserCreationController::LocallyManagedUserCreationController( 62 LocallyManagedUserCreationController::StatusConsumer* consumer, 63 const std::string& manager_id) 64 : consumer_(consumer), 65 weak_factory_(this) { 66 DCHECK(!current_controller_) << "More than one controller exist."; 67 current_controller_ = this; 68 creation_context_.reset( 69 new LocallyManagedUserCreationController::UserCreationContext()); 70 creation_context_->manager_id = manager_id; 71 } 72 73 LocallyManagedUserCreationController::~LocallyManagedUserCreationController() { 74 current_controller_ = NULL; 75 } 76 77 void LocallyManagedUserCreationController::SetUpCreation(string16 display_name, 78 std::string password) { 79 DCHECK(creation_context_); 80 creation_context_->display_name = display_name; 81 creation_context_->password = password; 82 } 83 84 void LocallyManagedUserCreationController::SetManagerProfile( 85 Profile* manager_profile) { 86 creation_context_->manager_profile = manager_profile; 87 } 88 89 void LocallyManagedUserCreationController::StartCreation() { 90 DCHECK(creation_context_); 91 VLOG(1) << "Starting supervised user creation"; 92 timeout_timer_.Start( 93 FROM_HERE, base::TimeDelta::FromSeconds(kUserCreationTimeoutSeconds), 94 this, 95 &LocallyManagedUserCreationController::CreationTimedOut); 96 97 UserManager::Get()->StartLocallyManagedUserCreationTransaction( 98 creation_context_->display_name); 99 100 creation_context_->local_user_id = 101 UserManager::Get()->GenerateUniqueLocallyManagedUserId(); 102 creation_context_->sync_user_id = 103 ManagedUserRegistrationUtility::GenerateNewManagedUserId(); 104 105 UserManager::Get()->CreateLocallyManagedUserRecord( 106 creation_context_->manager_id, 107 creation_context_->local_user_id, 108 creation_context_->sync_user_id, 109 creation_context_->display_name); 110 111 UserManager::Get()->SetLocallyManagedUserCreationTransactionUserId( 112 creation_context_->local_user_id); 113 VLOG(1) << "Creating cryptohome"; 114 authenticator_ = new ManagedUserAuthenticator(this); 115 authenticator_->AuthenticateToCreate(creation_context_->local_user_id, 116 creation_context_->password); 117 } 118 119 void LocallyManagedUserCreationController::OnAuthenticationFailure( 120 ManagedUserAuthenticator::AuthState error) { 121 timeout_timer_.Stop(); 122 ErrorCode code = NO_ERROR; 123 switch (error) { 124 case ManagedUserAuthenticator::NO_MOUNT: 125 code = CRYPTOHOME_NO_MOUNT; 126 break; 127 case ManagedUserAuthenticator::FAILED_MOUNT: 128 code = CRYPTOHOME_FAILED_MOUNT; 129 break; 130 case ManagedUserAuthenticator::FAILED_TPM: 131 code = CRYPTOHOME_FAILED_TPM; 132 break; 133 default: 134 NOTREACHED(); 135 } 136 if (consumer_) 137 consumer_->OnCreationError(code); 138 } 139 140 void LocallyManagedUserCreationController::OnMountSuccess( 141 const std::string& mount_hash) { 142 creation_context_->mount_hash = mount_hash; 143 144 // Generate master password. 145 char master_key_bytes[kMasterKeySize]; 146 crypto::RandBytes(&master_key_bytes, sizeof(master_key_bytes)); 147 creation_context_->master_key = StringToLowerASCII(base::HexEncode( 148 reinterpret_cast<const void*>(master_key_bytes), 149 sizeof(master_key_bytes))); 150 VLOG(1) << "Adding master key"; 151 authenticator_->AddMasterKey(creation_context_->local_user_id, 152 creation_context_->password, 153 creation_context_->master_key); 154 } 155 156 void LocallyManagedUserCreationController::OnAddKeySuccess() { 157 creation_context_->registration_utility = 158 ManagedUserRegistrationUtility::Create( 159 creation_context_->manager_profile); 160 161 VLOG(1) << "Creating user on server"; 162 ManagedUserRegistrationInfo info(creation_context_->display_name); 163 info.master_key = creation_context_->master_key; 164 creation_context_->registration_utility->Register( 165 creation_context_->sync_user_id, 166 info, 167 base::Bind(&LocallyManagedUserCreationController::RegistrationCallback, 168 weak_factory_.GetWeakPtr())); 169 } 170 171 void LocallyManagedUserCreationController::RegistrationCallback( 172 const GoogleServiceAuthError& error, 173 const std::string& token) { 174 if (error.state() == GoogleServiceAuthError::NONE) { 175 TokenFetched(token); 176 } else { 177 timeout_timer_.Stop(); 178 LOG(ERROR) << "Managed user creation failed. Error code " << error.state(); 179 if (consumer_) 180 consumer_->OnCreationError(CLOUD_SERVER_ERROR); 181 } 182 } 183 184 void LocallyManagedUserCreationController::CreationTimedOut() { 185 LOG(ERROR) << "Supervised user creation timed out."; 186 if (consumer_) 187 consumer_->OnCreationTimeout(); 188 } 189 190 void LocallyManagedUserCreationController::FinishCreation() { 191 chrome::AttemptUserExit(); 192 } 193 194 void LocallyManagedUserCreationController::CancelCreation() { 195 creation_context_->registration_utility.reset(); 196 chrome::AttemptUserExit(); 197 } 198 199 std::string LocallyManagedUserCreationController::GetManagedUserId() { 200 DCHECK(creation_context_); 201 return creation_context_->local_user_id; 202 } 203 204 void LocallyManagedUserCreationController::TokenFetched( 205 const std::string& token) { 206 creation_context_->token_acquired = true; 207 creation_context_->token = token; 208 209 PostTaskAndReplyWithResult( 210 content::BrowserThread::GetBlockingPool(), 211 FROM_HERE, 212 base::Bind(&StoreManagedUserFiles, 213 creation_context_->token, 214 MountManager::GetHomeDir(creation_context_->mount_hash)), 215 base::Bind( 216 &LocallyManagedUserCreationController::OnManagedUserFilesStored, 217 weak_factory_.GetWeakPtr())); 218 } 219 220 void LocallyManagedUserCreationController::OnManagedUserFilesStored( 221 bool success) { 222 timeout_timer_.Stop(); 223 if (!success) { 224 if (consumer_) 225 consumer_->OnCreationError(TOKEN_WRITE_FAILED); 226 return; 227 } 228 // Assume that new token is valid. It will be automatically invalidated if 229 // sync service fails to use it. 230 UserManager::Get()->SaveUserOAuthStatus(creation_context_->local_user_id, 231 User::OAUTH2_TOKEN_STATUS_VALID); 232 UserManager::Get()->CommitLocallyManagedUserCreationTransaction(); 233 if (consumer_) 234 consumer_->OnCreationSuccess(); 235 } 236 237 } // namespace chromeos 238