Home | History | Annotate | Download | only in managed
      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