// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Unit tests for Mount.

#include "cryptohome/mount.h"

#include <memory>
#include <openssl/evp.h>
#include <openssl/sha.h>
#include <pwd.h>
#include <stdlib.h>
#include <string.h>  // For memset(), memcpy()
#include <sys/types.h>
#include <vector>

#include <base/bind.h>
#include <base/bind_helpers.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/time/time.h>
#include <brillo/cryptohome.h>
#include <brillo/secure_blob.h>
#include <gtest/gtest.h>
#include <policy/libpolicy.h>
#include <policy/mock_device_policy.h>

#include "cryptohome/bootlockbox/mock_boot_lockbox.h"
#include "cryptohome/crypto.h"
#include "cryptohome/cryptohome_common.h"
#include "cryptohome/cryptolib.h"
#include "cryptohome/fake_le_credential_backend.h"
#include "cryptohome/homedirs.h"
#include "cryptohome/make_tests.h"
#include "cryptohome/mock_chaps_client_factory.h"
#include "cryptohome/mock_crypto.h"
#include "cryptohome/mock_homedirs.h"
#include "cryptohome/mock_le_credential_manager.h"
#include "cryptohome/mock_platform.h"
#include "cryptohome/mock_tpm.h"
#include "cryptohome/mock_tpm_init.h"
#include "cryptohome/mock_user_session.h"
#include "cryptohome/mock_vault_keyset.h"
#include "cryptohome/user_oldest_activity_timestamp_cache.h"
#include "cryptohome/username_passkey.h"
#include "cryptohome/vault_keyset.h"


#include "vault_keyset.pb.h"  // NOLINT(build/include)

using brillo::SecureBlob;
using base::FilePath;
using ::testing::AllOf;
using ::testing::AnyNumber;
using ::testing::AnyOf;
using ::testing::DoAll;
using ::testing::EndsWith;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::Mock;
using ::testing::NiceMock;
using ::testing::Not;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::SetArgPointee;
using ::testing::StartsWith;
using ::testing::StrEq;
using ::testing::StrictMock;
using ::testing::Unused;
using ::testing::WithArgs;
using ::testing::_;

namespace {

const FilePath kImageDir("test_image_dir");
const FilePath kImageSaltFile = kImageDir.Append("salt");
const FilePath kSkelDir = kImageDir.Append("skel");
const gid_t kDaemonGid = 400;  // TODO(wad): expose this in mount.h
const int kPinUserIndex = 14;
const char kHexHeSecret[] =
    "F3D9D5B126C36676689E18BB8517D95DF4F30947E71D4A840824425760B1D3FA";
const char kHexResetSecret[] =
    "B133D2450392335BA8D33AA95AD52488254070C66F5D79AEA1A46AC4A30760D4";
const char kHexWrappedKeyset[] =
    "B737B5D73E39BD390A4F361CE2FC166CF1E89EC6AEAA35D4B34456502C48B4F5EFA310077"\
    "324B393E13AF633DF3072FF2EC78BD2B80D919035DB97C30F1AD418737DA3F26A4D35DF6B"\
    "6A9743BD0DF3D37D8A68DE0932A9905452D05ECF92701B9805937F76EE01D10924268F057"\
    "EDD66087774BB86C2CB92B01BD3A3C41C10C52838BD3A3296474598418E5191DEE9E8D831"\
    "3C859C9EDB0D5F2BC1D7FC3C108A0D4ABB2D90E413086BCFFD0902AB68E2BF787817EB10C"\
    "25E2E43011CAB3FB8AA";
const char kHexSalt[] = "D470B9B108902241";
const char kHexVaultKey[] =
    "665A58534E684F2B61516B6D42624B514E6749732B4348427450305453754158377232347"\
    "37A79466C6B383D";
const char kHexFekIv[] = "EA80F14BF29C6D580D536E7F0CC47F3E";
const char kHexChapsIv[] = "ED85D928940E5B02ED218F29225AA34F";
const char kHexWrappedChapsKey[] =
    "7D7D01EECC8DAE7906CAD56310954BBEB3CC81765210D29902AB92DDE074217771AD284F2"\
    "12C13897C6CBB30CEC4CD75";

}  // namespace

namespace cryptohome {

ACTION_P2(SetOwner, owner_known, owner) {
  if (owner_known)
    *arg0 = owner;
  return owner_known;
}

ACTION_P(SetEphemeralUsersEnabled, ephemeral_users_enabled) {
  *arg0 = ephemeral_users_enabled;
  return true;
}

// Straight pass through.
Tpm::TpmRetryAction TpmPassthroughSealWithAuthorization(
    uint32_t _key, const SecureBlob &plaintext, Unused, Unused,
    SecureBlob *ciphertext) {
  ciphertext->resize(plaintext.size());
  memcpy(ciphertext->data(), plaintext.data(), plaintext.size());
  return Tpm::kTpmRetryNone;
}

Tpm::TpmRetryAction TpmPassthroughDecrypt(uint32_t _key,
                                          const SecureBlob &ciphertext,
                                          Unused,
                                          Unused,
                                          SecureBlob *plaintext) {
  plaintext->resize(ciphertext.size());
  memcpy(plaintext->data(), ciphertext.data(), ciphertext.size());
  return Tpm::kTpmRetryNone;
}

std::string HexDecode(const std::string& hex) {
  std::vector<uint8_t> output;
  CHECK(base::HexStringToBytes(hex, &output));
  return std::string(output.begin(), output.end());
}

class MountTest
    : public ::testing::TestWithParam<bool /* should_test_ecryptfs */> {
 public:
  MountTest() : crypto_(&platform_) { }
  virtual ~MountTest() { }

  void SetUp() {
    // Populate the system salt
    helper_.SetUpSystemSalt();
    helper_.InjectSystemSalt(&platform_, kImageSaltFile);

    // Setup default uid/gid values
    chronos_uid_ = 1000;
    chronos_gid_ = 1000;
    shared_gid_ = 1001;
    chaps_uid_ = 223;

    crypto_.set_tpm(&tpm_);
    crypto_.set_use_tpm(false);

    user_timestamp_cache_.reset(new UserOldestActivityTimestampCache());
    mount_ = new Mount();
    mount_->set_homedirs(&homedirs_);
    mount_->set_use_tpm(false);
    mount_->set_shadow_root(kImageDir);
    mount_->set_skel_source(kSkelDir);
    mount_->set_chaps_client_factory(&chaps_client_factory_);
    homedirs_.set_crypto(&crypto_);
    homedirs_.set_platform(&platform_);
    homedirs_.set_shadow_root(kImageDir);
    EXPECT_TRUE(homedirs_.GetSystemSalt(nullptr /* blob */));
    set_policy(false, "", false);
    premount_callback_counter_ = 0;
  }

  void TearDown() {
    mount_ = NULL;
    helper_.TearDownSystemSalt();
  }

  void InsertTestUsers(const TestUserInfo* user_info_list, int count) {
    helper_.InitTestData(kImageDir, user_info_list,
                         static_cast<size_t>(count), ShouldTestEcryptfs());
  }

  void PreMountCallback() {
    premount_callback_counter_ += 1;
  }

  bool DoMountInit() {
    EXPECT_CALL(platform_, GetUserId("chronos", _, _))
      .WillOnce(DoAll(SetArgPointee<1>(chronos_uid_),
                      SetArgPointee<2>(chronos_gid_),
                      Return(true)));
    EXPECT_CALL(platform_, GetUserId("chaps", _, _))
      .WillOnce(DoAll(SetArgPointee<1>(chaps_uid_),
                      SetArgPointee<2>(shared_gid_),
                      Return(true)));
    EXPECT_CALL(platform_, GetGroupId("chronos-access", _))
      .WillOnce(DoAll(SetArgPointee<1>(shared_gid_),
                      Return(true)));
    return mount_->Init(&platform_, &crypto_,
                        user_timestamp_cache_.get(),
                        base::BindRepeating(&MountTest::PreMountCallback,
                                            base::Unretained(this)));
  }

  bool LoadSerializedKeyset(const brillo::Blob& contents,
                            cryptohome::SerializedVaultKeyset* serialized) {
    CHECK_NE(contents.size(), 0U);
    return serialized->ParseFromArray(contents.data(), contents.size());
  }

  bool StoreSerializedKeyset(const SerializedVaultKeyset& serialized,
                             TestUser *user) {
    user->credentials.resize(serialized.ByteSize());
    serialized.SerializeWithCachedSizesToArray(
        static_cast<google::protobuf::uint8*>(&user->credentials[0]));
    return true;
  }

  void GetKeysetBlob(const SerializedVaultKeyset& serialized,
                     SecureBlob* blob) {
    SecureBlob local_wrapped_keyset(serialized.wrapped_keyset().length());
    serialized.wrapped_keyset().copy(
        local_wrapped_keyset.char_data(),
        serialized.wrapped_keyset().length(), 0);
    blob->swap(local_wrapped_keyset);
  }

  void set_policy(bool owner_known,
                  const std::string& owner,
                  bool ephemeral_users_enabled) {
    policy::MockDevicePolicy* device_policy = new policy::MockDevicePolicy();
    EXPECT_CALL(*device_policy, LoadPolicy())
        .Times(AnyNumber())
        .WillRepeatedly(Return(true));
    EXPECT_CALL(*device_policy, GetOwner(_))
        .WillRepeatedly(SetOwner(owner_known, owner));
    EXPECT_CALL(*device_policy, GetEphemeralUsersEnabled(_))
        .WillRepeatedly(SetEphemeralUsersEnabled(ephemeral_users_enabled));
    mount_->set_policy_provider(new policy::PolicyProvider(
        std::unique_ptr<policy::MockDevicePolicy>(device_policy)));
  }

  // Returns true if the test is running for eCryptfs, false if for dircrypto.
  bool ShouldTestEcryptfs() const { return GetParam(); }

  Mount::MountArgs GetDefaultMountArgs() const {
    Mount::MountArgs args;
    args.create_as_ecryptfs = ShouldTestEcryptfs();
    return args;
  }

  bool SetUserAsLECredential(TestUser* user) {
    SerializedVaultKeyset serialized;
    if (!LoadSerializedKeyset(user->credentials, &serialized)) {
      LOG(ERROR) << "Failed to parse keyset for " << user->username;
      return false;
    }
    serialized.set_flags(SerializedVaultKeyset::TPM_WRAPPED |
                         SerializedVaultKeyset::LE_CREDENTIAL);
    serialized.set_le_fek_iv(HexDecode(kHexFekIv));
    serialized.set_le_chaps_iv(HexDecode(kHexChapsIv));
    serialized.set_wrapped_keyset(HexDecode(kHexWrappedKeyset));
    serialized.set_wrapped_chaps_key(HexDecode(kHexWrappedChapsKey));
    serialized.set_salt(HexDecode(kHexSalt));
    if (!StoreSerializedKeyset(serialized, user)) {
      LOG(ERROR) << "Failed to serialize new timestamp'd keyset for "
                 << user->username;
      return false;
    }
    return true;
  }

  void InitializeLECredential() {
    EXPECT_CALL(platform_, DirectoryExists(kImageDir))
      .WillRepeatedly(Return(true));
    EXPECT_TRUE(DoMountInit());

    mount_->set_use_tpm(true);
    crypto_.set_use_tpm(true);

    EXPECT_CALL(tpm_init_, HasCryptohomeKey())
      .WillOnce(Return(false))
      .WillRepeatedly(Return(true));
    EXPECT_CALL(tpm_init_, SetupTpm(true))
      .WillOnce(Return(true))  // This is by crypto.Init() and
      .WillOnce(Return(true));  // because HasCryptohomeKey returned false once.

    EXPECT_CALL(tpm_, IsEnabled())
      .WillRepeatedly(Return(true));
    EXPECT_CALL(tpm_, IsOwned())
      .WillRepeatedly(Return(true));

    EXPECT_CALL(platform_, CreateDirectory(_))
      .WillRepeatedly(Return(true));

    le_cred_manager_ =
        new cryptohome::MockLECredentialManager(&le_cred_backend_, kImageDir);
    EXPECT_CALL(*le_cred_manager_, CheckCredential(_, _, _, _))
      .WillRepeatedly(
          DoAll(SetArgPointee<2>(SecureBlob(HexDecode(kHexHeSecret))),
                SetArgPointee<3>(SecureBlob(HexDecode(kHexResetSecret))),
                Return(LE_CRED_SUCCESS)));
    crypto_.set_le_manager_for_testing(
        std::unique_ptr<cryptohome::LECredentialManager>(le_cred_manager_));

    crypto_.Init(&tpm_init_);

    InsertTestUsers(&kDefaultUsers[kPinUserIndex], 1);
    pin_user_ = &helper_.users[0];
    pin_up_ = std::make_unique<UsernamePasskey>(
        pin_user_->username,
        SecureBlob(HexDecode(kHexVaultKey)));
    KeyData pin_label;
    pin_label.set_label("PIN");
    pin_up_->set_key_data(pin_label);

    pin_user_->InjectKeyset(&platform_, true);
    SetUserAsLECredential(pin_user_);
    EXPECT_CALL(platform_, ReadFile(pin_user_->keyset_path, _))
      .WillOnce(DoAll(SetArgPointee<1>(pin_user_->credentials),
                           Return(true)));
  }

  // Sets expectations for cryptohome key setup.
  void ExpectCryptohomeKeySetup(const TestUser& user) {
    if (ShouldTestEcryptfs()) {
      ExpectCryptohomeKeySetupForEcryptfs(user);
    } else {
      ExpectCryptohomeKeySetupForDircrypto(user);
    }
  }

  // Sets expectations for cryptohome key setup for ecryptfs.
  void ExpectCryptohomeKeySetupForEcryptfs(const TestUser& user) {
    EXPECT_CALL(platform_, AddEcryptfsAuthToken(_, _, _))
        .Times(2)
        .WillRepeatedly(Return(true));
  }

  // Sets expectations for cryptohome key setup for dircrypto.
  void ExpectCryptohomeKeySetupForDircrypto(const TestUser& user) {
    const key_serial_t kDirCryptoKeyId = 12345;
    EXPECT_CALL(platform_, AddDirCryptoKeyToKeyring(_, _, _))
        .WillOnce(DoAll(SetArgPointee<2>(kDirCryptoKeyId), Return(true)));
    EXPECT_CALL(platform_, SetDirCryptoKey(user.vault_mount_path, _))
        .WillOnce(Return(true));
    EXPECT_CALL(platform_, InvalidateDirCryptoKey(kDirCryptoKeyId, kImageDir))
        .WillRepeatedly(Return(true));
  }

  void ExpectCryptohomeMountShadowOnly(const TestUser& user) {
    ExpectCryptohomeKeySetup(user);
    if (ShouldTestEcryptfs()) {
      EXPECT_CALL(platform_,
                  Mount(user.vault_path, user.vault_mount_path,
                        "ecryptfs", kDefaultMountFlags, _))
          .WillOnce(Return(true));
    }
    EXPECT_CALL(platform_, CreateDirectory(user.vault_mount_path))
        .WillRepeatedly(Return(true));
    EXPECT_CALL(platform_, IsDirectoryMounted(user.vault_mount_path))
        .WillOnce(Return(false));
  }

  // Sets expectations for cryptohome mount.
  void ExpectCryptohomeMount(const TestUser& user) {
    ExpectCryptohomeKeySetup(user);
    ExpectDaemonStoreMounts(user, false /* ephemeral_mount */);
    if (ShouldTestEcryptfs()) {
      EXPECT_CALL(platform_, Mount(user.vault_path, user.vault_mount_path,
                                   "ecryptfs", kDefaultMountFlags, _))
          .WillOnce(Return(true));
    }
    EXPECT_CALL(platform_, CreateDirectory(user.vault_mount_path))
        .WillRepeatedly(Return(true));
    EXPECT_CALL(platform_,
                CreateDirectory(Mount::GetNewUserPath(user.username)))
        .WillRepeatedly(Return(true));

    EXPECT_CALL(platform_, IsDirectoryMounted(user.vault_mount_path))
        .WillOnce(Return(false));
    EXPECT_CALL(platform_, IsDirectoryMounted(FilePath("/home/chronos/user")))
        .WillOnce(Return(false));

    EXPECT_CALL(platform_, Bind(user.user_vault_mount_path,
                                user.user_mount_path))
        .WillOnce(Return(true));
    EXPECT_CALL(platform_, Bind(user.user_vault_mount_path,
                                user.legacy_user_mount_path))
        .WillOnce(Return(true));
    EXPECT_CALL(platform_, Bind(user.user_vault_mount_path,
                                Mount::GetNewUserPath(user.username)))
        .WillOnce(Return(true));
    EXPECT_CALL(platform_, Bind(user.root_vault_mount_path,
                                user.root_mount_path))
        .WillOnce(Return(true));
    ExpectDownloadsBindMounts(user);
    EXPECT_CALL(platform_,
                RestoreSELinuxContexts(
                    base::FilePath(user.vault_mount_path),
                    true))
        .WillOnce(Return(true));
  }

  void ExpectDownloadsBindMounts(const TestUser& user) {
    // Mounting Downloads to MyFiles/Downloads in:
    //   - /home/chronos/u-<hash>
    //   - /home/user/<hash>
    //   - /home/chronos/user
    FilePath user_dirs[] = {
      Mount::GetNewUserPath(user.username),
      brillo::cryptohome::home::GetUserPath(user.username),
      FilePath("/home/chronos/user"),
    };

    for (auto const& home : user_dirs) {
      auto downloads_path = home.Append("Downloads");
      auto downloads_in_myfiles = home.Append("MyFiles").Append("Downloads");

      EXPECT_CALL(platform_, DirectoryExists(home)).WillOnce(Return(true));
      EXPECT_CALL(platform_, DirectoryExists(downloads_path))
          .WillOnce(Return(true));
      EXPECT_CALL(platform_, DirectoryExists(downloads_in_myfiles))
          .WillOnce(Return(true));
      EXPECT_CALL(platform_, Bind(downloads_path, downloads_in_myfiles))
          .WillOnce(Return(true));
    }
  }

  void ExpectDownloadsUnmounts(const TestUser& user) {
    // Mounting Downloads to MyFiles/Downloads in:
    //   - /home/chronos/u-<hash>
    //   - /home/user/<hash>
    //   - /home/chronos/user
    FilePath user_dirs[] = {
      Mount::GetNewUserPath(user.username),
      brillo::cryptohome::home::GetUserPath(user.username),
      FilePath("/home/chronos/user"),
    };
    for (auto const& home : user_dirs) {
      EXPECT_CALL(platform_,
                  Unmount(home.Append("MyFiles").Append("Downloads"), _, _))
          .WillOnce(Return(true));
    }
  }

  void ExpectEphemeralCryptohomeMount(const TestUser& user) {
    EXPECT_CALL(platform_, StatVFS(FilePath(kEphemeralCryptohomeDir), _))
        .WillOnce(Return(true));
    const FilePath ephemeral_filename =
        Mount::GetEphemeralSparseFile(user.obfuscated_username);
    EXPECT_CALL(platform_, CreateSparseFile(ephemeral_filename, _))
        .WillOnce(Return(true));
    EXPECT_CALL(platform_, AttachLoop(ephemeral_filename))
        .WillOnce(Return(FilePath("/dev/loop7")));
    EXPECT_CALL(platform_, FormatExt4(ephemeral_filename,
                                      kDefaultExt4FormatOpts, 0))
        .WillOnce(Return(true));

    EXPECT_CALL(platform_,
                Mount(FilePath("/dev/loop7"), _, kEphemeralMountType,
                      kDefaultMountFlags, _))
        .WillRepeatedly(Return(true));
    EXPECT_CALL(platform_, IsDirectoryMounted(FilePath("/home/chronos/user")))
        .WillOnce(Return(false));  // first mount
    EXPECT_CALL(platform_, Bind(_, _))
        .WillRepeatedly(Return(true));

    EXPECT_CALL(platform_, GetFileEnumerator(kSkelDir, _, _))
        .WillOnce(Return(new NiceMock<MockFileEnumerator>()))
        .WillOnce(Return(new NiceMock<MockFileEnumerator>()));
    EXPECT_CALL(platform_, DirectoryExists(_))
        .WillRepeatedly(Return(true));
    EXPECT_CALL(platform_, CreateDirectory(user.vault_path))
        .Times(0);
    EXPECT_CALL(platform_, CreateDirectory(_))
        .WillRepeatedly(Return(true));
    EXPECT_CALL(platform_, FileExists(_))
        .WillRepeatedly(Return(true));
    EXPECT_CALL(platform_, SetOwnership(_, _, _, _))
        .WillRepeatedly(Return(true));
    EXPECT_CALL(platform_, SetPermissions(_, _)).WillRepeatedly(Return(true));
    ExpectDaemonStoreMounts(user, true /* ephemeral_mount */);
  }

  // Sets expectations for Mount::MountDaemonStoreDirectories. In particular,
  // sets up |platform_| to pretend that all daemon store directories exists, so
  // that they're all mounted. Without calling this method, daemon store
  // directories are pretended to not exist.
  void ExpectDaemonStoreMounts(const TestUser& user, bool ephemeral_mount) {
    // Return a mock daemon store directory in /etc/daemon-store.
    constexpr char kDaemonName[] = "mock-daemon";
    constexpr uid_t kDaemonUid = 123;
    constexpr gid_t kDaemonGid = 234;
    struct stat stat_data = {};
    stat_data.st_mode = S_IFDIR;
    stat_data.st_uid = kDaemonUid;
    stat_data.st_gid = kDaemonGid;
    const base::FilePath daemon_store_base_dir(kEtcDaemonStoreBaseDir);
    const FileEnumerator::FileInfo daemon_info(
        daemon_store_base_dir.AppendASCII(kDaemonName), stat_data);
    NiceMock<MockFileEnumerator>* daemon_enumerator =
        new NiceMock<MockFileEnumerator>();
    daemon_enumerator->entries_.push_back(daemon_info);
    EXPECT_CALL(platform_, GetFileEnumerator(daemon_store_base_dir, false,
                                             base::FileEnumerator::DIRECTORIES))
        .WillOnce(Return(daemon_enumerator));

    const FilePath run_daemon_store_path =
        FilePath(kRunDaemonStoreBaseDir).Append(kDaemonName);

    EXPECT_CALL(platform_, DirectoryExists(run_daemon_store_path))
        .WillOnce(Return(true));

    const FilePath root_home = ephemeral_mount ? user.root_ephemeral_mount_path
                                               : user.root_vault_mount_path;
    const FilePath mount_source = root_home.Append(kDaemonName);
    const FilePath mount_target =
        run_daemon_store_path.Append(user.obfuscated_username);

    EXPECT_CALL(platform_, CreateDirectory(mount_source))
        .WillOnce(Return(true));
    EXPECT_CALL(platform_, CreateDirectory(mount_target))
        .WillOnce(Return(true));

    EXPECT_CALL(platform_, SetOwnership(mount_source, stat_data.st_uid,
                                        stat_data.st_gid, false))
        .WillOnce(Return(true));

    EXPECT_CALL(platform_, SetPermissions(mount_source, stat_data.st_mode))
        .WillOnce(Return(true));

    EXPECT_CALL(platform_, Bind(mount_source, mount_target))
        .WillOnce(Return(true));
  }

  void ExpectCryptohomeRemoval(const TestUser& user) {
    EXPECT_CALL(platform_, DeleteFile(user.base_path, true)).Times(1);
    EXPECT_CALL(platform_, DeleteFile(user.user_mount_path, true)).Times(1);
    EXPECT_CALL(platform_, DeleteFile(user.root_mount_path, true)).Times(1);
  }

 protected:
  // Protected for trivial access.
  MakeTests helper_;
  uid_t chronos_uid_;
  gid_t chronos_gid_;
  uid_t chaps_uid_;
  gid_t shared_gid_;
  NiceMock<MockPlatform> platform_;
  NiceMock<MockTpm> tpm_;
  NiceMock<MockTpmInit> tpm_init_;
  Crypto crypto_;
  HomeDirs homedirs_;
  FakeLECredentialBackend le_cred_backend_;
  cryptohome::MockLECredentialManager* le_cred_manager_;
  TestUser* pin_user_;
  std::unique_ptr<UsernamePasskey> pin_up_;
  MockChapsClientFactory chaps_client_factory_;
  std::unique_ptr<UserOldestActivityTimestampCache> user_timestamp_cache_;
  scoped_refptr<Mount> mount_;
  int premount_callback_counter_;

 private:
  DISALLOW_COPY_AND_ASSIGN(MountTest);
};

INSTANTIATE_TEST_CASE_P(WithEcryptfs, MountTest, ::testing::Values(true));
INSTANTIATE_TEST_CASE_P(WithDircrypto, MountTest, ::testing::Values(false));

TEST_P(MountTest, BadInitTest) {
  // Create a Mount instance that points to a bad shadow root.
  mount_->set_shadow_root(FilePath("/dev/null"));

  SecureBlob passkey;
  cryptohome::Crypto::PasswordToPasskey(kDefaultUsers[0].password,
                                        helper_.system_salt, &passkey);
  UsernamePasskey up(kDefaultUsers[0].username, passkey);

  // Shadow root creation should fail.
  EXPECT_CALL(platform_, DirectoryExists(FilePath("/dev/null")))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_, CreateDirectory(FilePath("/dev/null")))
      .WillRepeatedly(Return(false));
  // Salt creation failure because shadow_root is bogus.
  EXPECT_CALL(platform_, FileExists(FilePath("/dev/null/salt")))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_,
              WriteSecureBlobToFileAtomicDurable(
                  FilePath("/dev/null/salt"), _, _))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_, GetUserId("chronos", _, _))
    .WillOnce(DoAll(SetArgPointee<1>(1000), SetArgPointee<2>(1000),
                    Return(true)));
  EXPECT_CALL(platform_, GetUserId("chaps", _, _))
    .WillOnce(DoAll(SetArgPointee<1>(1001), SetArgPointee<2>(1001),
                    Return(true)));
  EXPECT_CALL(platform_, GetGroupId("chronos-access", _))
    .WillOnce(DoAll(SetArgPointee<1>(1002), Return(true)));
  EXPECT_FALSE(mount_->Init(&platform_, &crypto_,
                            user_timestamp_cache_.get(),
                            base::BindRepeating(&base::DoNothing)));
  ASSERT_FALSE(mount_->AreValid(up));
}

TEST_P(MountTest, CurrentCredentialsTest) {
  // Create a Mount instance that points to a good shadow root, test that it
  // properly authenticates against the first key.
  SecureBlob passkey;
  cryptohome::Crypto::PasswordToPasskey(kDefaultUsers[3].password,
                                        helper_.system_salt, &passkey);
  UsernamePasskey up(kDefaultUsers[3].username, passkey);

  EXPECT_TRUE(DoMountInit());

  NiceMock<MockUserSession> user_session;
  user_session.Init(SecureBlob());
  user_session.SetUser(up);
  mount_->set_current_user(&user_session);

  EXPECT_CALL(user_session, CheckUser(_))
      .WillOnce(Return(true));
  EXPECT_CALL(user_session, Verify(_))
      .WillOnce(Return(true));

  ASSERT_TRUE(mount_->AreValid(up));
}

TEST_P(MountTest, BadDecryptTest) {
  // Create a Mount instance that points to a good shadow root, test that it
  // properly denies access with a bad passkey.
  SecureBlob passkey;
  cryptohome::Crypto::PasswordToPasskey("bogus", helper_.system_salt, &passkey);
  UsernamePasskey up(kDefaultUsers[4].username, passkey);

  EXPECT_TRUE(DoMountInit());
  ASSERT_FALSE(mount_->AreValid(up));
}

TEST_P(MountTest, MountCryptohomeNoPrivileges) {
  // Check that Mount only works if the mount permission is given.
  InsertTestUsers(&kDefaultUsers[10], 1);
  EXPECT_CALL(platform_, SetMask(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(kImageDir))
    .WillRepeatedly(Return(true));
  EXPECT_TRUE(DoMountInit());

  TestUser *user = &helper_.users[0];
  user->key_data.set_label("my key!");
  user->use_key_data = true;
  user->key_data.mutable_privileges()->set_mount(false);
  // Regenerate the serialized vault keyset.
  user->GenerateCredentials(ShouldTestEcryptfs());
  UsernamePasskey up(user->username, user->passkey);
  // Let the legacy key iteration work here.

  user->InjectUserPaths(&platform_, chronos_uid_, chronos_gid_, shared_gid_,
                        kDaemonGid, ShouldTestEcryptfs());
  user->InjectKeyset(&platform_, true);

  if (ShouldTestEcryptfs()) {
    EXPECT_CALL(platform_, ClearUserKeyring())
        .WillOnce(Return(true));
  }

  EXPECT_CALL(platform_, CreateDirectory(user->vault_mount_path))
    .WillRepeatedly(Return(true));

  EXPECT_CALL(platform_,
              CreateDirectory(mount_->GetNewUserPath(user->username)))
    .WillRepeatedly(Return(true));

  EXPECT_CALL(platform_, RestoreSELinuxContexts(_, _)).Times(0);

  MountError error = MOUNT_ERROR_NONE;
  EXPECT_FALSE(mount_->MountCryptohome(up, GetDefaultMountArgs(), &error));
  EXPECT_EQ(MOUNT_ERROR_KEY_FAILURE, error);
}

TEST_P(MountTest, MountCryptohomeHasPrivileges) {
  // Check that Mount only works if the mount permission is given.
  InsertTestUsers(&kDefaultUsers[10], 1);
  EXPECT_CALL(platform_, SetMask(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(kImageDir))
    .WillRepeatedly(Return(true));
  EXPECT_TRUE(DoMountInit());

  TestUser *user = &helper_.users[0];
  user->key_data.set_label("my key!");
  user->use_key_data = true;
  user->key_data.mutable_privileges()->set_mount(true);
  // Regenerate the serialized vault keyset.
  user->GenerateCredentials(ShouldTestEcryptfs());
  UsernamePasskey up(user->username, user->passkey);
  // Let the legacy key iteration work here.

  user->InjectUserPaths(&platform_, chronos_uid_, chronos_gid_, shared_gid_,
                        kDaemonGid, ShouldTestEcryptfs());
  user->InjectKeyset(&platform_, true);

  ExpectCryptohomeMount(*user);
  EXPECT_CALL(platform_, ClearUserKeyring())
    .WillOnce(Return(true));

  // user exists, so there'll be no skel copy after.

  MountError error = MOUNT_ERROR_NONE;
  ASSERT_TRUE(mount_->MountCryptohome(up, GetDefaultMountArgs(), &error));

  EXPECT_CALL(platform_, Unmount(_, _, _)).WillRepeatedly(Return(true));

  // Unmount here to avoid the scoped Mount doing it implicitly.
  EXPECT_CALL(platform_, GetCurrentTime())
      .WillOnce(Return(base::Time::Now()));
  EXPECT_CALL(platform_,
              WriteFileAtomicDurable(user->keyset_path, _, _))
      .WillOnce(Return(true));
  EXPECT_CALL(platform_, ClearUserKeyring())
    .WillOnce(Return(true));
  EXPECT_TRUE(mount_->UnmountCryptohome());
}

TEST_P(MountTest, BindMyFilesDownloadsSuccess) {
  EXPECT_TRUE(DoMountInit());

  FilePath dest_dir("/home/chronos/u-userhash");
  auto downloads_path = dest_dir.Append("Downloads");
  auto downloads_in_myfiles = dest_dir.Append("MyFiles").Append("Downloads");

  // All directories must exist for bind mount succeed.
  EXPECT_CALL(platform_, DirectoryExists(dest_dir)).WillOnce(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(downloads_path))
      .WillOnce(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(downloads_in_myfiles))
      .WillOnce(Return(true));
  EXPECT_CALL(platform_, Bind(downloads_path, downloads_in_myfiles))
      .WillOnce(Return(true));

  EXPECT_TRUE(mount_->BindMyFilesDownloads(dest_dir));
}

TEST_P(MountTest, BindMyFilesDownloadsMissingUserHome) {
  EXPECT_TRUE(DoMountInit());

  FilePath dest_dir("/home/chronos/u-userhash");

  // When dest_dir doesn't exists BindMyFilesDownloads returns false.
  EXPECT_CALL(platform_, DirectoryExists(dest_dir)).WillOnce(Return(false));

  EXPECT_FALSE(mount_->BindMyFilesDownloads(dest_dir));
}

TEST_P(MountTest, BindMyFilesDownloadsMissingDownloads) {
  EXPECT_TRUE(DoMountInit());

  FilePath dest_dir("/home/chronos/u-userhash");
  auto downloads_path = dest_dir.Append("Downloads");

  // When Downloads doesn't exists BindMyFilesDownloads returns false.
  EXPECT_CALL(platform_, DirectoryExists(dest_dir)).WillOnce(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(downloads_path))
      .WillOnce(Return(false));

  EXPECT_FALSE(mount_->BindMyFilesDownloads(dest_dir));
}

TEST_P(MountTest, BindMyFilesDownloadsMissingMyFilesDownloads) {
  EXPECT_TRUE(DoMountInit());

  FilePath dest_dir("/home/chronos/u-userhash");
  auto downloads_path = dest_dir.Append("Downloads");
  auto downloads_in_myfiles = dest_dir.Append("MyFiles").Append("Downloads");

  // When MyFiles/Downloads doesn't exists BindMyFilesDownloads returns false.
  EXPECT_CALL(platform_, DirectoryExists(dest_dir)).WillOnce(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(downloads_path))
      .WillOnce(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(downloads_in_myfiles))
      .WillOnce(Return(false));

  EXPECT_FALSE(mount_->BindMyFilesDownloads(dest_dir));
}

// A fixture for testing chaps directory checks.
class ChapsDirectoryTest : public ::testing::Test {
 public:
  ChapsDirectoryTest()
      : kBaseDir("/base_chaps_dir"),
        kSaltFile("/base_chaps_dir/auth_data_salt"),
        kDatabaseDir("/base_chaps_dir/database"),
        kDatabaseFile("/base_chaps_dir/database/file"),
        kLegacyDir("/legacy"),
        kRootUID(0), kRootGID(0), kChapsUID(1), kSharedGID(2),
        mount_(new Mount()),
        user_timestamp_cache_(new UserOldestActivityTimestampCache()) {
    crypto_.set_platform(&platform_);
    mount_->Init(&platform_, &crypto_,
                 user_timestamp_cache_.get(),
                 base::BindRepeating(&base::DoNothing));
    mount_->chaps_user_ = kChapsUID;
    mount_->default_access_group_ = kSharedGID;
    // By default, set stats to the expected values.
    InitStat(&base_stat_, 040750, kChapsUID, kSharedGID);
    InitStat(&salt_stat_, 0600, kRootUID, kRootGID);
    InitStat(&database_dir_stat_, 040750, kChapsUID, kSharedGID);
    InitStat(&database_file_stat_, 0640, kChapsUID, kSharedGID);
  }

  virtual ~ChapsDirectoryTest() {}

  void SetupFakeChapsDirectory() {
    // Configure the base directory.
    EXPECT_CALL(platform_, DirectoryExists(kBaseDir))
        .WillRepeatedly(Return(true));
    EXPECT_CALL(platform_, Stat(kBaseDir, _))
        .WillRepeatedly(DoAll(SetArgPointee<1>(base_stat_), Return(true)));

    // Configure a fake enumerator.
    MockFileEnumerator* enumerator = platform_.mock_enumerator();
    enumerator->entries_.push_back(
        FileEnumerator::FileInfo(kBaseDir, base_stat_));
    enumerator->entries_.push_back(
        FileEnumerator::FileInfo(kSaltFile, salt_stat_));
    enumerator->entries_.push_back(
        FileEnumerator::FileInfo(kDatabaseDir, database_dir_stat_));
    enumerator->entries_.push_back(
        FileEnumerator::FileInfo(kDatabaseFile, database_file_stat_));
  }

  bool RunCheck() {
    return mount_->CheckChapsDirectory(kBaseDir, kLegacyDir);
  }

 protected:
  const FilePath kBaseDir;
  const FilePath kSaltFile;
  const FilePath kDatabaseDir;
  const FilePath kDatabaseFile;
  const FilePath kLegacyDir;
  const uid_t kRootUID;
  const gid_t kRootGID;
  const uid_t kChapsUID;
  const gid_t kSharedGID;

  struct stat base_stat_;
  struct stat salt_stat_;
  struct stat database_dir_stat_;
  struct stat database_file_stat_;

  scoped_refptr<Mount> mount_;
  NiceMock<MockPlatform> platform_;
  NiceMock<MockCrypto> crypto_;
  std::unique_ptr<UserOldestActivityTimestampCache> user_timestamp_cache_;

 private:
  void InitStat(struct stat* s, mode_t mode, uid_t uid, gid_t gid) {
    memset(s, 0, sizeof(struct stat));
    s->st_mode = mode;
    s->st_uid = uid;
    s->st_gid = gid;
  }

  DISALLOW_COPY_AND_ASSIGN(ChapsDirectoryTest);
};

TEST_F(ChapsDirectoryTest, DirectoryOK) {
  SetupFakeChapsDirectory();
  ASSERT_TRUE(RunCheck());
}

TEST_F(ChapsDirectoryTest, DirectoryDoesNotExist) {
  // Specify directory does not exist.
  EXPECT_CALL(platform_, DirectoryExists(kBaseDir))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_, DirectoryExists(kLegacyDir))
      .WillRepeatedly(Return(false));
  // Expect basic setup.
  EXPECT_CALL(platform_, CreateDirectory(kBaseDir))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetPermissions(kBaseDir, 0750))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetOwnership(kBaseDir, kChapsUID, kSharedGID, true))
      .WillRepeatedly(Return(true));
  ASSERT_TRUE(RunCheck());
}

TEST_F(ChapsDirectoryTest, CreateFailure) {
  // Specify directory does not exist.
  EXPECT_CALL(platform_, DirectoryExists(kBaseDir))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_, DirectoryExists(kLegacyDir))
      .WillRepeatedly(Return(false));
  // Expect basic setup but fail.
  EXPECT_CALL(platform_, CreateDirectory(kBaseDir))
      .WillRepeatedly(Return(false));
  ASSERT_FALSE(RunCheck());
}

TEST_F(ChapsDirectoryTest, FixBadPerms) {
  // Specify some bad perms.
  base_stat_.st_mode = 040700;
  salt_stat_.st_mode = 0640;
  database_dir_stat_.st_mode = 040755;
  database_file_stat_.st_mode = 0666;
  SetupFakeChapsDirectory();
  // Expect corrections.
  EXPECT_CALL(platform_, SetPermissions(kBaseDir, 0750))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetPermissions(kSaltFile, 0600))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetPermissions(kDatabaseDir, 0750))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetPermissions(kDatabaseFile, 0640))
      .WillRepeatedly(Return(true));
  ASSERT_TRUE(RunCheck());
}

TEST_F(ChapsDirectoryTest, FixBadOwnership) {
  // Specify bad ownership.
  base_stat_.st_uid = kRootUID;
  salt_stat_.st_gid = kChapsUID;
  database_dir_stat_.st_gid = kChapsUID;
  database_file_stat_.st_uid = kSharedGID;
  SetupFakeChapsDirectory();
  // Expect corrections.
  EXPECT_CALL(platform_, SetOwnership(kBaseDir, kChapsUID, kSharedGID, true))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetOwnership(kSaltFile, kRootUID, kRootGID, true))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_,
              SetOwnership(kDatabaseDir, kChapsUID, kSharedGID, true))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_,
              SetOwnership(kDatabaseFile, kChapsUID, kSharedGID, true))
      .WillRepeatedly(Return(true));
  ASSERT_TRUE(RunCheck());
}

TEST_F(ChapsDirectoryTest, FixBadPermsFailure) {
  // Specify some bad perms.
  base_stat_.st_mode = 040700;
  SetupFakeChapsDirectory();
  // Expect corrections but fail to apply.
  EXPECT_CALL(platform_, SetPermissions(_, _))
      .WillRepeatedly(Return(false));
  ASSERT_FALSE(RunCheck());
}

TEST_F(ChapsDirectoryTest, FixBadOwnershipFailure) {
  // Specify bad ownership.
  base_stat_.st_uid = kRootUID;
  SetupFakeChapsDirectory();
  // Expect corrections but fail to apply.
  EXPECT_CALL(platform_, SetOwnership(_, _, _, _))
      .WillRepeatedly(Return(false));
  ASSERT_FALSE(RunCheck());
}

TEST_P(MountTest, CheckChapsDirectoryMigration) {
  EXPECT_CALL(platform_, DirectoryExists(kImageDir))
    .WillRepeatedly(Return(true));

  // Configure stub methods.
  EXPECT_CALL(platform_, Copy(_, _))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, DeleteFile(_, _))
      .WillRepeatedly(Return(true));

  // Stubs which will trigger the migration code path.
  EXPECT_CALL(platform_, DirectoryExists(FilePath("/fake")))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_, DirectoryExists(FilePath("/fake_legacy")))
      .WillRepeatedly(Return(true));

  // Configure stat for the base directory.
  struct stat base_stat = {0};
  base_stat.st_mode = 040123;
  base_stat.st_uid = 1;
  base_stat.st_gid = 2;
  EXPECT_CALL(platform_, Stat(_, _))
      .WillRepeatedly(DoAll(SetArgPointee<1>(base_stat), Return(true)));

  // Configure a fake enumerator.
  MockFileEnumerator* enumerator = platform_.mock_enumerator();
  struct stat file_info1 = {0};
  file_info1.st_mode = 0555;
  file_info1.st_uid = 3;
  file_info1.st_gid = 4;
  struct stat file_info2 = {0};
  file_info2.st_mode = 0777;
  file_info2.st_uid = 5;
  file_info2.st_gid = 6;
  enumerator->entries_.push_back(
      FileEnumerator::FileInfo(
        FilePath("/fake_legacy/test_file1"), file_info1));
  enumerator->entries_.push_back(
      FileEnumerator::FileInfo(
        FilePath("test_file2"), file_info2));

  // These expectations will ensure the ownership and permissions are being
  // correctly applied after the directory has been moved.
  EXPECT_CALL(platform_, SetOwnership(FilePath("/fake/test_file1"), 3, 4, true))
      .Times(1);
  EXPECT_CALL(platform_,
      SetPermissions(FilePath("/fake/test_file1"), 0555)).Times(1);
  EXPECT_CALL(platform_, SetOwnership(FilePath("/fake/test_file2"), 5, 6, true))
      .Times(1);
  EXPECT_CALL(platform_,
      SetPermissions(FilePath("/fake/test_file2"), 0777)).Times(1);
  EXPECT_CALL(platform_, SetOwnership(FilePath("/fake"), 1, 2, true)).Times(1);
  EXPECT_CALL(platform_,
      SetPermissions(FilePath("/fake"), 0123)).Times(1);

  DoMountInit();
  EXPECT_TRUE(mount_->CheckChapsDirectory(
        FilePath("/fake"), FilePath("/fake_legacy")));
}

TEST_P(MountTest, CreateCryptohomeTest) {
  InsertTestUsers(&kDefaultUsers[5], 1);
  // Creates a cryptohome and tests credentials.
  HomeDirs homedirs;
  homedirs.set_shadow_root(kImageDir);

  TestUser *user = &helper_.users[0];
  UsernamePasskey up(user->username, user->passkey);

  EXPECT_TRUE(DoMountInit());
  EXPECT_TRUE(homedirs.Init(&platform_, mount_->crypto(),
                            user_timestamp_cache_.get()));

  // TODO(wad) Make this into a UserDoesntExist() helper.
  EXPECT_CALL(platform_, FileExists(user->image_path))
    .WillOnce(Return(false));
  EXPECT_CALL(platform_,
      CreateDirectory(
        AnyOf(user->mount_prefix,
              user->user_mount_prefix,
              user->user_mount_path,
              user->root_mount_prefix,
              user->root_mount_path)))
    .Times(7)
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_,
      CreateDirectory(
        AnyOf(FilePath("/home/chronos"),
              mount_->GetNewUserPath(user->username))))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(user->vault_path))
    .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_, DirectoryExists(user->vault_mount_path))
    .WillRepeatedly(Return(false));
  if (ShouldTestEcryptfs()) {
    EXPECT_CALL(platform_, CreateDirectory(user->vault_path))
      .WillOnce(Return(true));
  }
  EXPECT_CALL(platform_, CreateDirectory(user->base_path))
    .WillOnce(Return(true));
  brillo::Blob creds;
  EXPECT_CALL(platform_,
              WriteFileAtomicDurable(user->keyset_path, _, _))
    .WillOnce(DoAll(SaveArg<1>(&creds), Return(true)));

  bool created;
  ASSERT_TRUE(mount_->EnsureCryptohome(up, GetDefaultMountArgs(), &created));
  ASSERT_TRUE(created);
  ASSERT_NE(creds.size(), 0);
  ASSERT_FALSE(mount_->AreValid(up));
  {
    InSequence s;
    MockFileEnumerator* files = new MockFileEnumerator();
    EXPECT_CALL(platform_, GetFileEnumerator(user->base_path, false, _))
      .WillOnce(Return(files));
     // Single key.
    EXPECT_CALL(*files, Next())
      .WillOnce(Return(user->keyset_path));
    EXPECT_CALL(*files, Next())
      .WillRepeatedly(Return(FilePath()));
  }

  EXPECT_CALL(platform_, ReadFile(user->keyset_path, _))
    .WillOnce(DoAll(SetArgPointee<1>(creds), Return(true)));

  ASSERT_TRUE(homedirs.AreCredentialsValid(up));
}

TEST_P(MountTest, GoodReDecryptTest) {
  InsertTestUsers(&kDefaultUsers[6], 1);
  // Create a Mount instance that points to a good shadow root, test that it
  // properly re-authenticates against the first key.
  mount_->set_use_tpm(true);
  crypto_.set_use_tpm(true);

  TestUser *user = &helper_.users[0];
  UsernamePasskey up(user->username, user->passkey);

  EXPECT_CALL(tpm_init_, HasCryptohomeKey())
    .WillOnce(Return(false))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_init_, SetupTpm(true))
    .WillOnce(Return(true))  // This is by crypto.Init() and
    .WillOnce(Return(true));  // cause we forced HasCryptohomeKey to false once.
  crypto_.Init(&tpm_init_);

  EXPECT_CALL(tpm_, IsEnabled())
    .WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_, IsOwned())
    .WillRepeatedly(Return(true));

  EXPECT_TRUE(DoMountInit());

  // Load the pre-generated keyset
  FilePath key_path = mount_->GetUserLegacyKeyFileForUser(
      up.GetObfuscatedUsername(helper_.system_salt), 0);
  EXPECT_GT(key_path.value().size(), 0u);
  cryptohome::SerializedVaultKeyset serialized;
  EXPECT_TRUE(serialized.ParseFromArray(user->credentials.data(),
                                        user->credentials.size()));
  // Ensure we're starting from scrypt so we can test migrate to a mock-TPM.
  EXPECT_EQ((serialized.flags() & SerializedVaultKeyset::SCRYPT_WRAPPED),
            SerializedVaultKeyset::SCRYPT_WRAPPED);
  EXPECT_EQ((serialized.flags() & SerializedVaultKeyset::TPM_WRAPPED), 0);

  // Call DecryptVaultKeyset first, allowing migration (the test data is not
  // scrypt nor TPM wrapped) to a TPM-wrapped keyset
  VaultKeyset vault_keyset;
  vault_keyset.Initialize(&platform_, mount_->crypto());
  MountError error = MOUNT_ERROR_NONE;
  // Inject the pre-generated, scrypt-wrapped keyset.
  EXPECT_CALL(platform_, FileExists(user->keyset_path))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, ReadFile(user->keyset_path, _))
    .WillRepeatedly(DoAll(SetArgPointee<1>(user->credentials),
                          Return(true)));
  EXPECT_CALL(platform_, FileExists(user->salt_path))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, ReadFile(user->salt_path, _))
    .WillRepeatedly(DoAll(SetArgPointee<1>(user->user_salt),
                          Return(true)));

  EXPECT_CALL(platform_,
      Move(user->keyset_path, user->keyset_path.AddExtension("bak")))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      Move(user->salt_path, user->salt_path.AddExtension("bak")))
    .WillOnce(Return(true));

  // Create the "TPM-wrapped" value by letting it save the plaintext.
  EXPECT_CALL(tpm_, SealToPcrWithAuthorization(_, _, _, _, _))
    .WillRepeatedly(Invoke(TpmPassthroughSealWithAuthorization));
  brillo::SecureBlob fake_pub_key("A");
  EXPECT_CALL(tpm_, GetPublicKeyHash(_, _))
    .WillRepeatedly(DoAll(SetArgPointee<1>(fake_pub_key),
                          Return(Tpm::kTpmRetryNone)));

  brillo::Blob migrated_keyset;
  EXPECT_CALL(platform_,
              WriteFileAtomicDurable(user->keyset_path, _, _))
    .WillOnce(DoAll(SaveArg<1>(&migrated_keyset), Return(true)));
  int key_index = 0;

  user->InjectKeyset(&platform_, true);

  EXPECT_TRUE(mount_->DecryptVaultKeyset(up, &vault_keyset, &serialized,
                                         &key_index, &error));
  ASSERT_EQ(error, MOUNT_ERROR_NONE);
  ASSERT_NE(migrated_keyset.size(), 0);

  cryptohome::SerializedVaultKeyset serialized_tpm;
  EXPECT_TRUE(serialized_tpm.ParseFromArray(migrated_keyset.data(),
                                            migrated_keyset.size()));
  // Did it migrate?
  EXPECT_EQ(SerializedVaultKeyset::TPM_WRAPPED,
            (serialized_tpm.flags() & SerializedVaultKeyset::TPM_WRAPPED));
  EXPECT_EQ(0, (serialized.flags() & SerializedVaultKeyset::SCRYPT_WRAPPED));
  // Does it use scrypt for key derivation?
  EXPECT_EQ(SerializedVaultKeyset::SCRYPT_DERIVED,
            (serialized_tpm.flags() & SerializedVaultKeyset::SCRYPT_DERIVED));

  // Inject the migrated keyset
  Mock::VerifyAndClearExpectations(&platform_);
  EXPECT_CALL(platform_, FileExists(user->keyset_path))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, ReadFile(user->keyset_path, _))
    .WillRepeatedly(DoAll(SetArgPointee<1>(migrated_keyset),
                          Return(true)));
  EXPECT_CALL(platform_, FileExists(user->salt_path))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, ReadFile(user->salt_path, _))
    .WillRepeatedly(DoAll(SetArgPointee<1>(user->user_salt),
                          Return(true)));
  EXPECT_CALL(tpm_, UnsealWithAuthorization(_, _, _, _, _))
    .WillRepeatedly(Invoke(TpmPassthroughDecrypt));

    MockFileEnumerator* files = new MockFileEnumerator();
    EXPECT_CALL(platform_, GetFileEnumerator(user->base_path, false, _))
      .WillOnce(Return(files));
     // Single key.
  {
    InSequence s;
    EXPECT_CALL(*files, Next())
      .WillOnce(Return(user->keyset_path));
    EXPECT_CALL(*files, Next())
      .WillOnce(Return(FilePath()));
  }

  ASSERT_TRUE(homedirs_.AreCredentialsValid(up));
}

TEST_P(MountTest, MountCryptohome) {
  // checks that cryptohome tries to mount successfully, and tests that the
  // tracked directories are created/replaced as expected
  InsertTestUsers(&kDefaultUsers[10], 1);
  EXPECT_CALL(platform_, DirectoryExists(kImageDir))
    .WillRepeatedly(Return(true));
  EXPECT_TRUE(DoMountInit());

  TestUser *user = &helper_.users[0];
  UsernamePasskey up(user->username, user->passkey);

  user->InjectUserPaths(&platform_, chronos_uid_, chronos_gid_, shared_gid_,
                        kDaemonGid, ShouldTestEcryptfs());
  user->InjectKeyset(&platform_, true);

  ExpectCryptohomeMount(*user);
  EXPECT_CALL(platform_, ClearUserKeyring())
    .WillRepeatedly(Return(true));

  // user exists, so there'll be no skel copy after.

  MountError error = MOUNT_ERROR_NONE;
  EXPECT_TRUE(mount_->MountCryptohome(up, GetDefaultMountArgs(), &error));
}

TEST_P(MountTest, MountCryptohomeChapsKey) {
  // Test to check if Cryptohome mount saves the chaps key correctly,
  // and doesn't regenerate it.
  EXPECT_CALL(platform_, DirectoryExists(kImageDir))
    .WillRepeatedly(Return(true));
  EXPECT_TRUE(DoMountInit());

  InsertTestUsers(&kDefaultUsers[0], 1);
  TestUser* user = &helper_.users[0];
  UsernamePasskey up(user->username, user->passkey);

  user->InjectKeyset(&platform_, true);
  VaultKeyset vault_keyset;
  vault_keyset.Initialize(&platform_, mount_->crypto());
  SerializedVaultKeyset serialized;
  MountError error;
  int key_index = -1;

  // First we decrypt the vault to load the chaps key.
  ASSERT_TRUE(mount_->DecryptVaultKeyset(up, &vault_keyset, &serialized,
                                         &key_index, &error));
  EXPECT_EQ(key_index, 0);
  EXPECT_EQ(serialized.has_wrapped_chaps_key(), true);

  SecureBlob local_chaps(vault_keyset.chaps_key().begin(),
                         vault_keyset.chaps_key().end());
  user->InjectUserPaths(&platform_, chronos_uid_, chronos_gid_,
                        shared_gid_, kDaemonGid, ShouldTestEcryptfs());
  user->InjectKeyset(&platform_, true);

  ExpectCryptohomeMount(*user);

  ASSERT_TRUE(mount_->MountCryptohome(up, GetDefaultMountArgs(), &error));

  user->InjectKeyset(&platform_, true);

  ASSERT_TRUE(mount_->DecryptVaultKeyset(up, &vault_keyset, &serialized,
                                         &key_index, &error));

  // Compare the pre mount chaps key to the post mount key.
  ASSERT_EQ(local_chaps.size(), vault_keyset.chaps_key().size());
  ASSERT_EQ(0, brillo::SecureMemcmp(local_chaps.data(),
    vault_keyset.chaps_key().data(), local_chaps.size()));
}

TEST_P(MountTest, MountCryptohomeNoChapsKey) {
  // This test checks if the mount operation recreates the chaps key
  // if it isn't present in the vault.
  EXPECT_CALL(platform_, DirectoryExists(kImageDir))
    .WillRepeatedly(Return(true));
  EXPECT_TRUE(DoMountInit());

  InsertTestUsers(&kDefaultUsers[0], 1);
  TestUser* user = &helper_.users[0];
  UsernamePasskey up(user->username, user->passkey);

  user->InjectKeyset(&platform_, true);
  VaultKeyset vault_keyset;
  vault_keyset.Initialize(&platform_, mount_->crypto());
  SerializedVaultKeyset serialized;
  MountError error;
  int key_index = -1;
  EXPECT_CALL(platform_, ReadFile(user->keyset_path, _))
    .WillOnce(DoAll(SetArgPointee<1>(user->credentials),
                         Return(true)));

  ASSERT_TRUE(mount_->DecryptVaultKeyset(up, &vault_keyset, &serialized,
                                         &key_index, &error));

  vault_keyset.clear_chaps_key();
  EXPECT_CALL(platform_, FileExists(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, DeleteFile(_, _))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, Move(_, _))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_,
              WriteFileAtomicDurable(user->keyset_path, _, _))
    .WillRepeatedly(DoAll(SaveArg<1>(&(user->credentials)), Return(true)));
  ASSERT_TRUE(mount_->ReEncryptVaultKeyset(up, vault_keyset, key_index,
                                           &serialized));
  EXPECT_CALL(platform_, ReadFile(user->keyset_path, _))
    .WillRepeatedly(DoAll(SetArgPointee<1>(user->credentials),
                          Return(true)));
  user->InjectKeyset(&platform_, true);
  ASSERT_TRUE(mount_->DecryptVaultKeyset(up, &vault_keyset, &serialized,
                                         &key_index, &error));

  EXPECT_EQ(key_index, 0);
  EXPECT_EQ(serialized.has_wrapped_chaps_key(), false);

  user->InjectUserPaths(&platform_, chronos_uid_, chronos_gid_,
                        shared_gid_, kDaemonGid, ShouldTestEcryptfs());
  user->InjectKeyset(&platform_, true);

  ExpectCryptohomeMount(*user);

  ASSERT_TRUE(mount_->MountCryptohome(up, GetDefaultMountArgs(), &error));
  EXPECT_CALL(platform_, ReadFile(user->keyset_path, _))
    .WillRepeatedly(DoAll(SetArgPointee<1>(user->credentials),
                          Return(true)));
  user->InjectKeyset(&platform_, true);
  ASSERT_TRUE(mount_->DecryptVaultKeyset(up, &vault_keyset, &serialized,
                                         &key_index, &error));
  EXPECT_EQ(serialized.has_wrapped_chaps_key(), true);
  EXPECT_EQ(vault_keyset.chaps_key().size(), CRYPTOHOME_CHAPS_KEY_LENGTH);
}

TEST_P(MountTest, MountCryptohomeLECredentials) {
  // This test checks the mount operation with the LE credentials.
  InitializeLECredential();
  EXPECT_CALL(*le_cred_manager_, NeedsPcrBinding(_))
    .WillRepeatedly(Return(false));

  VaultKeyset pin_vault_keyset;
  pin_vault_keyset.Initialize(&platform_, mount_->crypto());

  SerializedVaultKeyset serialized;
  MountError error;
  int key_index = -1;
  SecureBlob passkey;
  pin_up_->GetPasskey(&passkey);
  ASSERT_TRUE(mount_->DecryptVaultKeyset(*pin_up_.get(), &pin_vault_keyset,
                                         &serialized, &key_index, &error));
}

TEST_P(MountTest, MountCryptohomeLECredentialsMigrate) {
  // This test checks if the mount operation recreates the LE credentials
  // when the switch to protocol 1 happens.
  InitializeLECredential();
  EXPECT_CALL(*le_cred_manager_, NeedsPcrBinding(_))
    .WillRepeatedly(Return(true));

  brillo::Blob creds;
  EXPECT_CALL(platform_, FileExists(_))
    .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_, WriteFileAtomicDurable(pin_user_->keyset_path, _, _))
    .WillOnce(DoAll(SaveArg<1>(&creds), Return(true)));

  // Make sure the same reset_secret is inserted.
  EXPECT_CALL(
      *le_cred_manager_,
      InsertCredential(_, _, SecureBlob(HexDecode(kHexResetSecret)), _, _, _))
    .WillOnce(Return(LE_CRED_SUCCESS));
  EXPECT_CALL(*le_cred_manager_, RemoveCredential(_))
    .WillOnce(Return(LE_CRED_SUCCESS));

  VaultKeyset pin_vault_keyset;
  pin_vault_keyset.Initialize(&platform_, mount_->crypto());

  SerializedVaultKeyset serialized;
  MountError error;
  int key_index = -1;
  SecureBlob passkey;
  pin_up_->GetPasskey(&passkey);
  ASSERT_TRUE(mount_->DecryptVaultKeyset(*pin_up_.get(), &pin_vault_keyset,
                                         &serialized, &key_index, &error));

  // Check the inserted data from migration.
  ASSERT_TRUE(LoadSerializedKeyset(creds, &serialized));
  ASSERT_TRUE(serialized.flags() & SerializedVaultKeyset::LE_CREDENTIAL);
}

TEST_P(MountTest, MountCryptohomeLECredentialsMigrationFails) {
  // This test checks the scenario when mount operation tries to recreate
  // vault keyset for LE credentials and insert operation fails.
  InitializeLECredential();
  EXPECT_CALL(platform_, FileExists(_)).WillRepeatedly(Return(false));
  EXPECT_CALL(*le_cred_manager_, NeedsPcrBinding(_))
    .WillRepeatedly(Return(true));

  EXPECT_CALL(platform_, FileExists(_))
    .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_,
              WriteSecureBlobToFileAtomicDurable(_, _, _)).Times(0);

  EXPECT_CALL(*le_cred_manager_, InsertCredential(
      _, _, SecureBlob(HexDecode(kHexResetSecret)), _, _, _))
    .WillOnce(Return(LE_CRED_ERROR_NO_FREE_LABEL));
  EXPECT_CALL(*le_cred_manager_, RemoveCredential(_)).Times(0);

  VaultKeyset pin_vault_keyset;
  pin_vault_keyset.Initialize(&platform_, mount_->crypto());

  SerializedVaultKeyset serialized;
  MountError error;
  int key_index = -1;
  SecureBlob passkey;
  pin_up_->GetPasskey(&passkey);
  ASSERT_TRUE(mount_->DecryptVaultKeyset(*pin_up_.get(), &pin_vault_keyset,
                                         &serialized, &key_index, &error));

  // Check the returned data.
  ASSERT_TRUE(serialized.flags() & SerializedVaultKeyset::LE_CREDENTIAL);
}

TEST_P(MountTest, MountCryptohomeNoChange) {
  // Checks that cryptohome doesn't by default re-save the cryptohome on mount.
  EXPECT_CALL(platform_, DirectoryExists(kImageDir))
    .WillRepeatedly(Return(true));
  EXPECT_TRUE(DoMountInit());

  InsertTestUsers(&kDefaultUsers[11], 1);
  TestUser* user = &helper_.users[0];
  UsernamePasskey up(user->username, user->passkey);

  user->InjectKeyset(&platform_, true);
  VaultKeyset vault_keyset;
  vault_keyset.Initialize(&platform_, mount_->crypto());
  SerializedVaultKeyset serialized;
  MountError error;
  int key_index = -1;

  ASSERT_TRUE(mount_->DecryptVaultKeyset(up, &vault_keyset, &serialized,
                                         &key_index, &error));
  EXPECT_EQ(key_index, 0);

  user->InjectUserPaths(&platform_, chronos_uid_, chronos_gid_,
                        shared_gid_, kDaemonGid, ShouldTestEcryptfs());
  user->InjectKeyset(&platform_, true);

  ExpectCryptohomeMount(*user);

  ASSERT_TRUE(mount_->MountCryptohome(up, GetDefaultMountArgs(), &error));

  user->InjectKeyset(&platform_, true);

  SerializedVaultKeyset new_serialized;
  ASSERT_TRUE(mount_->DecryptVaultKeyset(up, &vault_keyset, &new_serialized,
                                         &key_index, &error));

  SecureBlob lhs;
  GetKeysetBlob(serialized, &lhs);
  SecureBlob rhs;
  GetKeysetBlob(new_serialized, &rhs);
  ASSERT_EQ(lhs.size(), rhs.size());
  ASSERT_EQ(0, brillo::SecureMemcmp(lhs.data(), rhs.data(), lhs.size()));
}

TEST_P(MountTest, MountCryptohomeNoCreate) {
  // Checks that doesn't create the cryptohome for the user on Mount without
  // being told to do so.
  EXPECT_CALL(platform_, DirectoryExists(kImageDir))
    .WillRepeatedly(Return(true));
  EXPECT_TRUE(DoMountInit());

  // Test user at index 12 hasn't been created
  InsertTestUsers(&kDefaultUsers[12], 1);
  TestUser* user = &helper_.users[0];
  UsernamePasskey up(user->username, user->passkey);

  // Doesn't exist.
  EXPECT_CALL(platform_, DirectoryExists(user->vault_path))
    .WillOnce(Return(false));
  EXPECT_CALL(platform_, DirectoryExists(user->vault_mount_path))
    .WillOnce(Return(false));

  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.create_if_missing = false;
  MountError error = MOUNT_ERROR_NONE;
  ASSERT_FALSE(mount_->MountCryptohome(up, mount_args, &error));
  ASSERT_EQ(MOUNT_ERROR_USER_DOES_NOT_EXIST, error);

  // Now let it create the vault.
  // TODO(wad) Drop NiceMock and replace with InSequence EXPECT_CALL()s.
  // It will complain about creating tracked subdirs, but that is non-fatal.
  Mock::VerifyAndClearExpectations(&platform_);
  user->InjectKeyset(&platform_, true);

  EXPECT_CALL(platform_,
      DirectoryExists(AnyOf(user->vault_path, user->vault_mount_path,
                            user->user_vault_path)))
    .Times(4)
    .WillRepeatedly(Return(false));

  // Not legacy
  EXPECT_CALL(platform_, FileExists(user->image_path))
    .WillRepeatedly(Return(false));

  EXPECT_CALL(platform_, GetFileEnumerator(kSkelDir, _, _))
      .WillOnce(Return(new NiceMock<MockFileEnumerator>()))
      .WillOnce(Return(new NiceMock<MockFileEnumerator>()));

  EXPECT_CALL(platform_, CreateDirectory(_))
    .WillRepeatedly(Return(true));
  brillo::Blob creds;
  EXPECT_CALL(platform_,
              WriteFileAtomicDurable(user->keyset_path, _, _))
    .WillOnce(DoAll(SaveArg<1>(&creds), Return(true)))
    .WillRepeatedly(Return(true));

  EXPECT_CALL(platform_, SetOwnership(_, _, _, _)).WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetPermissions(_, _)).WillRepeatedly(Return(true));

  ExpectCryptohomeMount(*user);

  // Fake successful mount to /home/chronos/user/*
  EXPECT_CALL(platform_,
      FileExists(
        Property(&FilePath::value, AnyOf(
            StartsWith(user->legacy_user_mount_path.value()),
            StartsWith(user->vault_mount_path.value())))))
    .WillRepeatedly(Return(true));

  mount_args.create_if_missing = true;
  error = MOUNT_ERROR_NONE;
  ASSERT_TRUE(mount_->MountCryptohome(up, mount_args, &error));
  ASSERT_EQ(MOUNT_ERROR_NONE, error);
}

TEST_P(MountTest, UserActivityTimestampUpdated) {
  // checks that user activity timestamp is updated during Mount() and
  // periodically while mounted, other Keyset fields remains the same
  EXPECT_CALL(platform_, DirectoryExists(kImageDir))
    .WillRepeatedly(Return(true));
  EXPECT_TRUE(DoMountInit());

  InsertTestUsers(&kDefaultUsers[9], 1);
  TestUser* user = &helper_.users[0];
  UsernamePasskey up(user->username, user->passkey);

  EXPECT_CALL(platform_,
      CreateDirectory(
        AnyOf(
          mount_->GetNewUserPath(user->username),
          Property(&FilePath::value, StartsWith(kImageDir.value())))))
    .WillRepeatedly(Return(true));

  user->InjectKeyset(&platform_, true);
  user->InjectUserPaths(&platform_, chronos_uid_, chronos_gid_,
                        shared_gid_, kDaemonGid, ShouldTestEcryptfs());

  // Mount()
  MountError error;
  ExpectCryptohomeMount(*user);
  ASSERT_TRUE(mount_->MountCryptohome(up, GetDefaultMountArgs(), &error));

  // Update the timestamp. Normally it is called in MountTaskMount::Run() in
  // background but here in the test we must call it manually.
  static const int kMagicTimestamp = 123;
  brillo::Blob updated_keyset;
  EXPECT_CALL(platform_, WriteFileAtomicDurable(user->keyset_path, _, _))
    .WillRepeatedly(DoAll(SaveArg<1>(&updated_keyset), Return(true)));
  EXPECT_CALL(platform_, GetCurrentTime())
      .WillOnce(Return(base::Time::FromInternalValue(kMagicTimestamp)));
  mount_->UpdateCurrentUserActivityTimestamp(0);
  SerializedVaultKeyset serialized1;
  ASSERT_TRUE(serialized1.ParseFromArray(updated_keyset.data(),
                                         updated_keyset.size()));

  // Check that last activity timestamp is updated.
  ASSERT_TRUE(serialized1.has_last_activity_timestamp());
  EXPECT_EQ(kMagicTimestamp, serialized1.last_activity_timestamp());

  // Unmount the user. This must update user's activity timestamps.
  static const int kMagicTimestamp2 = 234;
  EXPECT_CALL(platform_, GetCurrentTime())
      .WillOnce(Return(base::Time::FromInternalValue(kMagicTimestamp2)));
  EXPECT_CALL(platform_, Unmount(_, _, _)).WillRepeatedly(Return(true));
  mount_->UnmountCryptohome();
  SerializedVaultKeyset serialized2;
  ASSERT_TRUE(serialized2.ParseFromArray(updated_keyset.data(),
                                         updated_keyset.size()));
  ASSERT_TRUE(serialized2.has_last_activity_timestamp());
  EXPECT_EQ(kMagicTimestamp2, serialized2.last_activity_timestamp());

  // Update timestamp again, after user is unmounted. User's activity
  // timestamp must not change this.
  mount_->UpdateCurrentUserActivityTimestamp(0);
  SerializedVaultKeyset serialized3;
  ASSERT_TRUE(serialized3.ParseFromArray(updated_keyset.data(),
                                         updated_keyset.size()));
  ASSERT_TRUE(serialized3.has_last_activity_timestamp());
  EXPECT_EQ(serialized3.has_last_activity_timestamp(),
            serialized2.has_last_activity_timestamp());
}

TEST_P(MountTest, RememberMountOrderingTest) {
  // Checks that mounts made with RememberMount/RememberBind are undone in the
  // right order.
  EXPECT_CALL(platform_, DirectoryExists(kImageDir))
    .WillRepeatedly(Return(true));
  EXPECT_TRUE(DoMountInit());
  SecureBlob salt;
  salt.assign('A', 16);

  FilePath src("/src");
  FilePath dest0("/dest/foo");
  FilePath dest1("/dest/bar");
  FilePath dest2("/dest/baz");
  {
    InSequence sequence;
    EXPECT_CALL(platform_, Mount(src, dest0, _, kDefaultMountFlags, _))
        .WillOnce(Return(true));
    EXPECT_CALL(platform_, Bind(src, dest1))
        .WillOnce(Return(true));
    EXPECT_CALL(platform_, Mount(src, dest2, _, kDefaultMountFlags, _))
        .WillOnce(Return(true));
    EXPECT_CALL(platform_, Unmount(dest2, _, _))
        .WillOnce(Return(true));
    EXPECT_CALL(platform_, Unmount(dest1, _, _))
        .WillOnce(Return(true));
    EXPECT_CALL(platform_, Unmount(dest0, _, _))
        .WillOnce(Return(true));

    EXPECT_TRUE(mount_->RememberMount(src, dest0, "", ""));
    EXPECT_TRUE(mount_->RememberBind(src, dest1));
    EXPECT_TRUE(mount_->RememberMount(src, dest2, "", ""));
    mount_->UnmountAll();
  }
}

TEST_P(MountTest, LockboxGetsFinalized) {
  StrictMock<MockBootLockbox> lockbox;
  mount_->set_boot_lockbox(&lockbox);
  ASSERT_TRUE(DoMountInit());
  EXPECT_CALL(lockbox, FinalizeBoot()).Times(2).WillRepeatedly(Return(true));
  UsernamePasskey up("username", SecureBlob("password"));
  Mount::MountArgs args = GetDefaultMountArgs();
  MountError error = MOUNT_ERROR_NONE;
  EXPECT_EQ(premount_callback_counter_, 0);
  mount_->MountCryptohome(up, args, &error);
  mount_->MountGuestCryptohome();
  EXPECT_EQ(premount_callback_counter_, 2);
}

TEST_P(MountTest, TwoWayKeysetMigrationTest) {
  // Checks that in the following scenario the keyset is not corrupted
  // 1) Have TPM present - keys are TPM wrapped.
  // 2) Decrypt while no TPM - keys are migrated to Scrypt.
  // 3) Decrypt with TPM again - keys are migrated back to TPM.

  // Start with TPM enabled
  mount_->set_use_tpm(true);
  crypto_.set_use_tpm(true);

  // TPM-wrapped is just plaintext
  brillo::SecureBlob fake_pub_key("A");
  EXPECT_CALL(tpm_, GetPublicKeyHash(_, _))
    .WillRepeatedly(DoAll(SetArgPointee<1>(fake_pub_key),
                          Return(Tpm::kTpmRetryNone)));
  EXPECT_CALL(tpm_, DecryptBlob(_, _, _, _, _))
    .WillRepeatedly(Invoke(TpmPassthroughDecrypt));

  // TPM calls are always ok. Control TPM presence with set_use_tpm()
  EXPECT_CALL(tpm_init_, HasCryptohomeKey())
    .WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_init_, SetupTpm(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_, IsEnabled())
    .WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_, IsOwned())
    .WillRepeatedly(Return(true));
  crypto_.Init(&tpm_init_);

  InsertTestUsers(&kDefaultUsers[7], 1);
  TestUser *user = &helper_.users[0];
  UsernamePasskey up(user->username, user->passkey);
  user->InjectKeyset(&platform_, true);
  // We now have Scrypt-wrapped key injected

  // Mock file and homedir ops
  HomeDirs homedirs;
  homedirs.set_shadow_root(kImageDir);
  EXPECT_CALL(platform_, DirectoryExists(kImageDir))
    .WillRepeatedly(Return(true));
  EXPECT_TRUE(DoMountInit());

  int key_index = 0;

  // Allow the "backup"s to be written during migrations
  EXPECT_CALL(platform_, FileExists(user->keyset_path.AddExtension("bak")))
    .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_, FileExists(user->salt_path.AddExtension("bak")))
    .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_,
      Move(user->keyset_path, user->keyset_path.AddExtension("bak")))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_,
      Move(user->salt_path, user->salt_path.AddExtension("bak")))
    .WillRepeatedly(Return(true));

  // Capture the migrated keysets when written to file
  brillo::Blob migrated_keyset;
  EXPECT_CALL(platform_, WriteFileAtomicDurable(user->keyset_path, _, _))
    .WillRepeatedly(DoAll(SaveArg<1>(&migrated_keyset), Return(true)));

  EXPECT_CALL(platform_, FileExists(user->salt_path))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, ReadFile(user->salt_path, _))
    .WillRepeatedly(DoAll(SetArgPointee<1>(user->user_salt),
                          Return(true)));

  // Step 1: TPM is present. Get a TPM-wrapped key.
  VaultKeyset vault_keyset;
  vault_keyset.Initialize(&platform_, mount_->crypto());

  MountError error;
  cryptohome::SerializedVaultKeyset serialized;

  // Migrate to TPM-wrapped from the original Scrypt-wrapped
  error = MOUNT_ERROR_NONE;
  EXPECT_TRUE(mount_->DecryptVaultKeyset(up, &vault_keyset, &serialized,
                                         &key_index, &error));
  ASSERT_EQ(error, MOUNT_ERROR_NONE);
  ASSERT_NE(migrated_keyset.size(), 0);

  // Check and fix the flags if needed
  // Erroneous cryptohome code might have set the TPM vs Scrypt flags
  // incorrectly. We (a) check for it here, (b) reset flags to the
  // correct value to complete the rest of the test that needs
  // TPM-wrapped keys with correct flags
  error = MOUNT_ERROR_NONE;
  user->InjectKeyset(&platform_, true);

  EXPECT_TRUE(mount_->DecryptVaultKeyset(up, &vault_keyset, &serialized,
                                         &key_index, &error));

  unsigned int flags = serialized.flags();
  EXPECT_EQ((flags & SerializedVaultKeyset::TPM_WRAPPED),
            SerializedVaultKeyset::TPM_WRAPPED);
  EXPECT_EQ((flags & SerializedVaultKeyset::SCRYPT_WRAPPED), 0);

  if (flags & SerializedVaultKeyset::SCRYPT_WRAPPED) {
    EXPECT_CALL(platform_, ReadFile(user->keyset_path, _))
      .WillOnce(DoAll(SetArgPointee<1>(migrated_keyset),
                      Return(true)));
    serialized.set_flags(flags & ~SerializedVaultKeyset::SCRYPT_WRAPPED);
    EXPECT_TRUE(mount_->ReEncryptVaultKeyset(up, vault_keyset, 0, &serialized));
  }
  // Now we have the TPM-wrapped keyset with correct flags

  // Step 2: No TPM. Migrate to Scrypt-wrapped.
  mount_->set_use_tpm(false);
  crypto_.set_use_tpm(false);

  error = MOUNT_ERROR_NONE;
  user->InjectKeyset(&platform_, true);

  EXPECT_TRUE(mount_->DecryptVaultKeyset(up, &vault_keyset, &serialized,
                                         &key_index, &error));
  ASSERT_EQ(error, MOUNT_ERROR_NONE);
  ASSERT_NE(migrated_keyset.size(), 0);

  // Step 3: TPM back on. Migrate to TPM-wrapped.
  // If flags were set incorrectly by the previous migration (i.e it is
  // Scrypt-wrapped w/ both TPM and Scrypt flags set), Decrypt will fail.
  mount_->set_use_tpm(true);
  crypto_.set_use_tpm(true);

  error = MOUNT_ERROR_NONE;
  user->InjectKeyset(&platform_, true);

  ASSERT_TRUE(mount_->DecryptVaultKeyset(up, &vault_keyset, &serialized,
                                         &key_index, &error));
  ASSERT_EQ(error, MOUNT_ERROR_NONE);
}

TEST_P(MountTest, BothFlagsMigrationTest) {
  // Checks that in the following scenario works:
  // TPM is enabled.
  // We have a keyset that has both TPM and Scrypt flags set.
  // When we decrypt it, mount re-encrypts and keeps only TPM
  // flag set

  mount_->set_use_tpm(true);
  crypto_.set_use_tpm(true);

  // TPM-wrapped is just plaintext
  brillo::SecureBlob fake_pub_key("A");
  EXPECT_CALL(tpm_, GetPublicKeyHash(_, _))
    .WillRepeatedly(DoAll(SetArgPointee<1>(fake_pub_key),
                          Return(Tpm::kTpmRetryNone)));
  EXPECT_CALL(tpm_, DecryptBlob(_, _, _, _, _))
    .WillRepeatedly(Invoke(TpmPassthroughDecrypt));

  // TPM calls are always ok. Control TPM presence with set_use_tpm()
  EXPECT_CALL(tpm_init_, HasCryptohomeKey())
    .WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_init_, SetupTpm(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_, IsEnabled())
    .WillRepeatedly(Return(true));
  EXPECT_CALL(tpm_, IsOwned())
    .WillRepeatedly(Return(true));
  crypto_.Init(&tpm_init_);

  InsertTestUsers(&kDefaultUsers[7], 1);
  TestUser *user = &helper_.users[0];
  UsernamePasskey up(user->username, user->passkey);
  user->InjectKeyset(&platform_, true);
  // We now have Scrypt-wrapped key injected

  // Mock file and homedir ops
  HomeDirs homedirs;
  homedirs.set_shadow_root(kImageDir);
  EXPECT_CALL(platform_, DirectoryExists(kImageDir))
    .WillRepeatedly(Return(true));
  EXPECT_TRUE(DoMountInit());

  int key_index = 0;

  // Allow the "backup"s to be written during migrations
  EXPECT_CALL(platform_,
      FileExists(user->keyset_path.AddExtension("bak")))
    .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_,
      FileExists(user->salt_path.AddExtension("bak")))
    .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_,
      Move(user->keyset_path,
           user->keyset_path.AddExtension("bak")))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_,
      Move(user->salt_path, user->salt_path.AddExtension("bak")))
    .WillRepeatedly(Return(true));

  // Capture the migrated keysets when written to file
  brillo::Blob migrated_keyset;
  EXPECT_CALL(platform_, WriteFileAtomicDurable(user->keyset_path, _, _))
    .WillRepeatedly(DoAll(SaveArg<1>(&migrated_keyset), Return(true)));

  EXPECT_CALL(platform_, FileExists(user->salt_path))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, ReadFile(user->salt_path, _))
    .WillRepeatedly(DoAll(SetArgPointee<1>(user->user_salt),
                          Return(true)));

  // First, get a TPM-wrapped key from the original Scrypt-wrapped
  VaultKeyset vault_keyset;
  vault_keyset.Initialize(&platform_, mount_->crypto());

  MountError error;
  cryptohome::SerializedVaultKeyset serialized;

  error = MOUNT_ERROR_NONE;
  EXPECT_TRUE(mount_->DecryptVaultKeyset(up, &vault_keyset, &serialized,
                                         &key_index, &error));
  ASSERT_EQ(error, MOUNT_ERROR_NONE);
  ASSERT_NE(migrated_keyset.size(), 0);

  // Now set both flags and write it
  unsigned int flags = serialized.flags();
  EXPECT_EQ((flags & SerializedVaultKeyset::TPM_WRAPPED),
            SerializedVaultKeyset::TPM_WRAPPED);
  EXPECT_EQ((flags & SerializedVaultKeyset::SCRYPT_WRAPPED), 0);

  serialized.set_flags(flags |
    SerializedVaultKeyset::TPM_WRAPPED |
    SerializedVaultKeyset::SCRYPT_WRAPPED);
  EXPECT_TRUE(mount_->StoreVaultKeysetForUser(user->obfuscated_username,
                                              0, serialized));

  // When we call DecryptVaultKeyset, it should re-encrypt
  // the keys and write with only one flag set
  error = MOUNT_ERROR_NONE;
  user->InjectKeyset(&platform_, true);

  EXPECT_TRUE(mount_->DecryptVaultKeyset(up, &vault_keyset, &serialized,
                                         &key_index, &error));
  ASSERT_EQ(error, MOUNT_ERROR_NONE);
  ASSERT_NE(migrated_keyset.size(), 0);

  flags = serialized.flags();
  ASSERT_EQ(SerializedVaultKeyset::TPM_WRAPPED,
            (flags & SerializedVaultKeyset::TPM_WRAPPED));
  ASSERT_EQ(0, (flags & SerializedVaultKeyset::SCRYPT_WRAPPED));
  ASSERT_EQ(SerializedVaultKeyset::SCRYPT_DERIVED,
            (flags & SerializedVaultKeyset::SCRYPT_DERIVED));
}

TEST_P(MountTest, CreateTrackedSubdirectories) {
  EXPECT_TRUE(DoMountInit());
  InsertTestUsers(&kDefaultUsers[0], 1);
  TestUser *user = &helper_.users[0];
  UsernamePasskey up(user->username, user->passkey);

  FilePath dest_dir;
  if (ShouldTestEcryptfs()) {
    dest_dir = user->vault_path;
    mount_->mount_type_ = Mount::MountType::ECRYPTFS;
  } else {
    dest_dir = user->vault_mount_path;
    mount_->mount_type_ = Mount::MountType::DIR_CRYPTO;
  }
  EXPECT_CALL(platform_, DirectoryExists(dest_dir))
    .WillOnce(Return(true));
  // Expectations for each tracked subdirectory.
  for (const auto& tracked_dir : Mount::GetTrackedSubdirectories()) {
    const FilePath tracked_dir_path = dest_dir.Append(tracked_dir);
    EXPECT_CALL(platform_, DirectoryExists(tracked_dir_path))
      .WillOnce(Return(false));
    EXPECT_CALL(platform_, CreateDirectory(tracked_dir_path))
      .WillOnce(Return(true));
    EXPECT_CALL(
        platform_,
        SetOwnership(tracked_dir_path, chronos_uid_, chronos_gid_, true))
        .WillOnce(Return(true));
    if (!ShouldTestEcryptfs()) {
      // For dircrypto, xattr should be set.
      EXPECT_CALL(platform_, SetExtendedFileAttribute(
          tracked_dir_path,
          kTrackedDirectoryNameAttribute,
          StrEq(tracked_dir_path.BaseName().value()),
          tracked_dir_path.BaseName().value().size())).WillOnce(Return(true));
    }
  }
  // Run the method.
  EXPECT_TRUE(mount_->CreateTrackedSubdirectories(up, true /* is_new */));
}

TEST_P(MountTest, CreateTrackedSubdirectoriesReplaceExistingDir) {
  EXPECT_TRUE(DoMountInit());
  InsertTestUsers(&kDefaultUsers[0], 1);
  TestUser *user = &helper_.users[0];
  UsernamePasskey up(user->username, user->passkey);

  FilePath dest_dir;
  if (ShouldTestEcryptfs()) {
    dest_dir = user->vault_path;
    mount_->mount_type_ = Mount::MountType::ECRYPTFS;
  } else {
    dest_dir = user->vault_mount_path;
    mount_->mount_type_ = Mount::MountType::DIR_CRYPTO;
  }
  EXPECT_CALL(platform_, DirectoryExists(dest_dir))
    .WillOnce(Return(true));
  // Expectations for each tracked subdirectory.
  for (const auto& tracked_dir : Mount::GetTrackedSubdirectories()) {
    const FilePath tracked_dir_path = dest_dir.Append(tracked_dir);
    const FilePath userside_dir = user->vault_mount_path.Append(tracked_dir);
    // Simulate the case there already exists a non-passthrough-dir
    if (ShouldTestEcryptfs()) {
      // For ecryptfs, delete and replace the existing directory.
      EXPECT_CALL(platform_, DirectoryExists(userside_dir))
        .WillOnce(Return(true));
      EXPECT_CALL(platform_, DeleteFile(userside_dir, true))
        .WillOnce(Return(true));
      EXPECT_CALL(platform_, DirectoryExists(tracked_dir_path))
        .WillOnce(Return(false))
        .WillOnce(Return(false));
      EXPECT_CALL(platform_, CreateDirectory(tracked_dir_path))
        .WillOnce(Return(true));
      EXPECT_CALL(
          platform_,
          SetOwnership(tracked_dir_path, chronos_uid_, chronos_gid_, true))
        .WillOnce(Return(true));
    } else {
      // For dircrypto, just skip the directory creation.
      EXPECT_CALL(platform_, DirectoryExists(tracked_dir_path))
        .WillOnce(Return(true));
      EXPECT_CALL(platform_, SetExtendedFileAttribute(
          tracked_dir_path,
          kTrackedDirectoryNameAttribute,
          StrEq(tracked_dir_path.BaseName().value()),
          tracked_dir_path.BaseName().value().size())).WillOnce(Return(true));
    }
  }
  // Run the method.
  EXPECT_TRUE(mount_->CreateTrackedSubdirectories(up, false /* is_new */));
}

TEST_P(MountTest, MountCryptohomePreviousMigrationIncomplete) {
  // Checks that if both ecryptfs and dircrypto home directories
  // exist, fails with an error.
  EXPECT_CALL(platform_, DirectoryExists(kImageDir))
    .WillRepeatedly(Return(true));
  EXPECT_TRUE(DoMountInit());

  // Prepare a dummy user and a key.
  InsertTestUsers(&kDefaultUsers[10], 1);
  TestUser* user = &helper_.users[0];
  user->InjectKeyset(&platform_, true);
  UsernamePasskey up(user->username, user->passkey);

  // Not legacy
  EXPECT_CALL(platform_, FileExists(user->image_path))
    .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_, CreateDirectory(_))
    .WillRepeatedly(Return(true));

  // Mock the situation that both types of data directory exists.
  EXPECT_CALL(platform_,
    DirectoryExists(AnyOf(user->vault_path, user->vault_mount_path,
                          user->user_vault_path)))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, GetDirCryptoKeyState(user->vault_mount_path))
    .WillRepeatedly(Return(dircrypto::KeyState::ENCRYPTED));

  MountError error = MOUNT_ERROR_NONE;
  ASSERT_FALSE(mount_->MountCryptohome(up, GetDefaultMountArgs(), &error));
  ASSERT_EQ(MOUNT_ERROR_PREVIOUS_MIGRATION_INCOMPLETE, error);
}

TEST_P(MountTest, MountCryptohomeToMigrateFromEcryptfs) {
  // Checks that to_migrate_from_ecryptfs option is handled correctly.
  // When the existing vault is ecryptfs, mount it to a temporary location while
  // setting up a new dircrypto directory.
  // When the existing vault is dircrypto, just fail.
  InsertTestUsers(&kDefaultUsers[10], 1);
  EXPECT_CALL(platform_, DirectoryExists(kImageDir))
    .WillRepeatedly(Return(true));
  EXPECT_TRUE(DoMountInit());

  TestUser *user = &helper_.users[0];
  UsernamePasskey up(user->username, user->passkey);

  user->InjectKeyset(&platform_, ShouldTestEcryptfs());

  // Inject dircrypto user paths.
  user->InjectUserPaths(&platform_, chronos_uid_, chronos_gid_, shared_gid_,
                        kDaemonGid, false /* is_ecryptfs */);

  if (ShouldTestEcryptfs()) {
    // Inject user ecryptfs paths too.
    user->InjectUserPaths(&platform_, chronos_uid_, chronos_gid_, shared_gid_,
                          kDaemonGid, true /* is_ecryptfs */);

    // When an ecryptfs vault exists, mount it to a temporary location.
    FilePath temporary_mount = user->base_path.Append(kTemporaryMountDir);
    EXPECT_CALL(platform_, CreateDirectory(temporary_mount))
      .WillOnce(Return(true));
    EXPECT_CALL(platform_, Mount(user->vault_path, temporary_mount,
                                 "ecryptfs", kDefaultMountFlags, _))
      .WillOnce(Return(true));

    // Key set up for both dircrypto and ecryptfs.
    ExpectCryptohomeKeySetupForDircrypto(*user);
    ExpectCryptohomeKeySetupForEcryptfs(*user);

    EXPECT_CALL(platform_, DirectoryExists(user->vault_path))
      .WillRepeatedly(Return(true));

    EXPECT_CALL(platform_, IsDirectoryMounted(user->vault_mount_path))
      .WillOnce(Return(false));

    EXPECT_CALL(platform_, CreateDirectory(user->vault_mount_path))
      .WillRepeatedly(Return(true));
  }

  EXPECT_CALL(platform_,
              CreateDirectory(mount_->GetNewUserPath(user->username)))
    .WillRepeatedly(Return(true));

  MountError error = MOUNT_ERROR_NONE;
  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.to_migrate_from_ecryptfs = true;
  if (ShouldTestEcryptfs()) {
    EXPECT_TRUE(mount_->MountCryptohome(up, mount_args, &error));
  } else {
    // Fail if the existing vault is not ecryptfs.
    EXPECT_FALSE(mount_->MountCryptohome(up, mount_args, &error));
  }
}

TEST_P(MountTest, MountCryptohomeShadowOnly) {
  // Checks that the shadow_only option is handled correctly.
  InsertTestUsers(&kDefaultUsers[10], 1);
  EXPECT_CALL(platform_, DirectoryExists(kImageDir))
      .WillRepeatedly(Return(true));
  EXPECT_TRUE(DoMountInit());

  TestUser* user = &helper_.users[0];
  UsernamePasskey up(user->username, user->passkey);

  user->InjectKeyset(&platform_, true);

  // Inject dircrypto user paths.
  user->InjectUserPaths(&platform_, chronos_uid_, chronos_gid_, shared_gid_,
                        kDaemonGid, ShouldTestEcryptfs());

  ExpectCryptohomeMountShadowOnly(*user);

  MountError error = MOUNT_ERROR_NONE;
  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.shadow_only = true;
  EXPECT_TRUE(mount_->MountCryptohome(up, mount_args, &error));
}

TEST_P(MountTest, MountCryptohomeForceDircrypto) {
  // Checks that the force-dircrypto flag correctly rejects to mount ecryptfs.
  EXPECT_CALL(platform_, DirectoryExists(kImageDir))
    .WillRepeatedly(Return(true));
  EXPECT_TRUE(DoMountInit());

  // Prepare a dummy user and a key.
  InsertTestUsers(&kDefaultUsers[10], 1);
  TestUser* user = &helper_.users[0];
  user->InjectKeyset(&platform_, true);
  user->InjectUserPaths(&platform_, chronos_uid_, chronos_gid_, shared_gid_,
                        kDaemonGid, ShouldTestEcryptfs());

  EXPECT_CALL(platform_, CreateDirectory(_))
    .WillRepeatedly(Return(true));

  // Mock setup for successful mount when dircrypto is tested.
  if (!ShouldTestEcryptfs()) {
    ExpectCryptohomeMount(*user);

    // Expectations for tracked subdirectories
    EXPECT_CALL(platform_, DirectoryExists(
        Property(&FilePath::value, StartsWith(user->vault_mount_path.value()))))
      .WillRepeatedly(Return(true));
    EXPECT_CALL(platform_, SetExtendedFileAttribute(
        Property(&FilePath::value, StartsWith(user->vault_mount_path.value())),
        _, _, _))
      .WillRepeatedly(Return(true));
    EXPECT_CALL(platform_, FileExists(
        Property(&FilePath::value, StartsWith(user->vault_mount_path.value()))))
      .WillRepeatedly(Return(true));
    EXPECT_CALL(platform_, SetGroupAccessible(
        Property(&FilePath::value, StartsWith(user->vault_mount_path.value())),
        _, _))
      .WillRepeatedly(Return(true));
  }

  UsernamePasskey up(user->username, user->passkey);

  MountError error = MOUNT_ERROR_NONE;
  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.force_dircrypto = true;

  if (ShouldTestEcryptfs()) {
    // Should reject mounting ecryptfs vault.
    EXPECT_FALSE(mount_->MountCryptohome(up, mount_args, &error));
    EXPECT_EQ(MOUNT_ERROR_OLD_ENCRYPTION, error);
  } else {
    // Should succeed in mounting in dircrypto.
    EXPECT_TRUE(mount_->MountCryptohome(up, mount_args, &error));
    EXPECT_EQ(MOUNT_ERROR_NONE, error);
  }
}

// Test setup that initially has no cryptohomes.
const TestUserInfo kNoUsers[] = {
  {"user0@invalid.domain", "zero", false},
  {"user1@invalid.domain", "odin", false},
  {"user2@invalid.domain", "dwaa", false},
  {"owner@invalid.domain", "1234", false},
};
const int kNoUserCount = arraysize(kNoUsers);

// Test setup that initially has a cryptohome for the owner only.
const TestUserInfo kOwnerOnlyUsers[] = {
  {"user0@invalid.domain", "zero", false},
  {"user1@invalid.domain", "odin", false},
  {"user2@invalid.domain", "dwaa", false},
  {"owner@invalid.domain", "1234", true},
};
const int kOwnerOnlyUserCount = arraysize(kOwnerOnlyUsers);

// Test setup that initially has cryptohomes for all users.
const TestUserInfo kAlternateUsers[] = {
  {"user0@invalid.domain", "zero", true},
  {"user1@invalid.domain", "odin", true},
  {"user2@invalid.domain", "dwaa", true},
  {"owner@invalid.domain", "1234", true},
};
const int kAlternateUserCount = arraysize(kAlternateUsers);

class AltImageTest : public MountTest {
 public:
  AltImageTest() {}
  ~AltImageTest() {
    MountTest::TearDown();
  }

  void SetUpAltImage(const TestUserInfo *users, int user_count) {
    // Set up fresh users.
    MountTest::SetUp();
    InsertTestUsers(users, user_count);

    EXPECT_CALL(platform_, DirectoryExists(kImageDir))
      .WillRepeatedly(Return(true));
    EXPECT_TRUE(DoMountInit());
  }

  // Set the user with specified |key_file| old.
  bool SetUserTimestamp(TestUser* user, base::Time timestamp) {
    SerializedVaultKeyset serialized;
    if (!LoadSerializedKeyset(user->credentials, &serialized)) {
      LOG(ERROR) << "Failed to parse keyset for "
                 << user->username;
      return false;
    }
    serialized.set_last_activity_timestamp(timestamp.ToInternalValue());
    bool ok = StoreSerializedKeyset(serialized, user);
    if (!ok) {
      LOG(ERROR) << "Failed to serialize new timestamp'd keyset for "
                 << user->username;
    }
    return ok;
  }

  void PrepareHomedirs(bool inject_keyset,
                       const std::vector<int>* delete_vaults,
                       const std::vector<int>* mounted_vaults) {
    bool populate_vaults = (vaults_.size() == 0);
    // const string contents = "some encrypted contents";
    for (int user = 0; user != static_cast<int>(helper_.users.size()); user++) {
      // Let their Cache dirs be filled with some data.
      // Guarded to keep this function reusable.
      if (populate_vaults) {
        EXPECT_CALL(platform_,
            DirectoryExists(
              Property(&FilePath::value,
                StartsWith(helper_.users[user].base_path.value()))))
          .WillRepeatedly(Return(true));
        vaults_.push_back(helper_.users[user].base_path);
      }
      bool delete_user = false;
      if (delete_vaults && delete_vaults->size() != 0) {
        if (std::find(delete_vaults->begin(), delete_vaults->end(), user) !=
            delete_vaults->end())
          delete_user = true;
      }
      bool mounted_user = false;
      if (mounted_vaults && mounted_vaults->size() != 0) {
        if (std::find(mounted_vaults->begin(), mounted_vaults->end(), user) !=
            mounted_vaults->end())
          mounted_user = true;
      }

      // After Cache & GCache are depleted. Users are deleted. To do so cleanly,
      // their keysets timestamps are read into an in-memory.
      if (inject_keyset && !mounted_user)
        helper_.users[user].InjectKeyset(&platform_, false);
      if (delete_user) {
        EXPECT_CALL(platform_,
            DeleteFile(helper_.users[user].base_path, true))
          .WillOnce(Return(true));
      }
    }
  }

  std::vector<FilePath> vaults_;

 private:
  DISALLOW_COPY_AND_ASSIGN(AltImageTest);
};

class EphemeralNoUserSystemTest : public AltImageTest {
 public:
  EphemeralNoUserSystemTest() { }

  void SetUp() {
    SetUpAltImage(kNoUsers, kNoUserCount);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(EphemeralNoUserSystemTest);
};

INSTANTIATE_TEST_CASE_P(WithEcryptfs, EphemeralNoUserSystemTest,
                        ::testing::Values(true));
INSTANTIATE_TEST_CASE_P(WithDircrypto, EphemeralNoUserSystemTest,
                        ::testing::Values(false));

TEST_P(EphemeralNoUserSystemTest, CreateMyFilesDownloads) {
  // Checks that Mount::SetUpEphemeralCryptohome creates MyFiles/Downloads.
  const FilePath base_path("/ephemeral_home/");
  const FilePath downloads_path = base_path.Append("Downloads");
  const FilePath myfiles_path = base_path.Append("MyFiles");
  const FilePath myfiles_downloads_path = myfiles_path.Append("Downloads");
  const FilePath gcache_path = base_path.Append("GCache");
  const FilePath gcache_v2_path = base_path.Append("GCache").Append("v2");
  const auto gcache_dirs = Property(
      &FilePath::value, StartsWith(base_path.Append("GCache").value()));

  // Expecting Downloads to not exist and then be created.
  EXPECT_CALL(platform_, DirectoryExists(downloads_path))
      .WillOnce(Return(false));
  EXPECT_CALL(platform_, CreateDirectory(downloads_path))
      .WillOnce(Return(true));
  EXPECT_CALL(platform_,
              SetOwnership(downloads_path, chronos_uid_, chronos_gid_, _))
      .WillOnce(Return(true));
  // Expecting MyFiles to not exist and then be created.
  EXPECT_CALL(platform_, DirectoryExists(myfiles_path)).WillOnce(Return(false));
  EXPECT_CALL(platform_, CreateDirectory(myfiles_path)).WillOnce(Return(true));
  EXPECT_CALL(platform_,
              SetOwnership(myfiles_path, chronos_uid_, chronos_gid_, _))
      .WillOnce(Return(true));
  // Expecting MyFiles/Downloads to not exist and then be created, with right
  // user and group.
  EXPECT_CALL(platform_, DirectoryExists(myfiles_downloads_path))
      .WillOnce(Return(false));
  EXPECT_CALL(platform_, CreateDirectory(myfiles_downloads_path))
      .WillOnce(Return(true));
  EXPECT_CALL(platform_, SetOwnership(myfiles_downloads_path, chronos_uid_,
                                      chronos_gid_, _))
      .WillOnce(Return(true));

  // Expect GCache and Gcache/v2 to be created with the right user and group.
  EXPECT_CALL(platform_, DirectoryExists(gcache_path)).WillOnce(Return(false));
  EXPECT_CALL(platform_, CreateDirectory(gcache_path)).WillOnce(Return(true));
  EXPECT_CALL(platform_,
              SetOwnership(gcache_path, chronos_uid_, chronos_gid_, _))
      .WillOnce(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(gcache_v2_path))
      .WillOnce(Return(false));
  EXPECT_CALL(platform_, CreateDirectory(gcache_v2_path))
      .WillOnce(Return(true));
  EXPECT_CALL(platform_,
              SetOwnership(gcache_v2_path, chronos_uid_, chronos_gid_, _))
      .WillOnce(Return(true));

  EXPECT_CALL(platform_, SetOwnership(base_path, chronos_uid_, shared_gid_, _))
      .WillOnce(Return(true));

  // Expectaction for Mount::SetupGroupAccess
  // These files should exist. Then get group accessible called on them.
  EXPECT_CALL(platform_,
              FileExists(AnyOf(base_path, myfiles_path, downloads_path,
                               myfiles_downloads_path, gcache_dirs)))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_,
              SetGroupAccessible(AnyOf(base_path, myfiles_path, downloads_path,
                                       myfiles_downloads_path, gcache_dirs),
                                 shared_gid_, _))
      .WillRepeatedly(Return(true));

  ASSERT_TRUE(mount_->SetUpEphemeralCryptohome(base_path));
}

TEST_P(EphemeralNoUserSystemTest, CreateMyFilesDownloadsAlreadyExists) {
  // Checks that Mount::SetUpEphemeralCryptohome doesn't re-recreate if already
  // exists, just sets the ownership and group access for |base_path|.
  const FilePath base_path("/ephemeral_home/");
  const FilePath downloads_path = base_path.Append("Downloads");
  const FilePath myfiles_path = base_path.Append("MyFiles");
  const FilePath myfiles_downloads_path = myfiles_path.Append("Downloads");
  const FilePath gcache_path = base_path.Append("GCache");
  const FilePath gcache_v2_path = base_path.Append("GCache").Append("v2");
  const auto gcache_dirs = Property(
      &FilePath::value, StartsWith(base_path.Append("GCache").value()));

  // Expecting Downloads and MyFiles/Downloads to exist thus CreateDirectory
  // isn't called.
  EXPECT_CALL(platform_, DirectoryExists(downloads_path))
      .WillOnce(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(myfiles_path))
      .WillOnce(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(myfiles_downloads_path))
      .WillOnce(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(gcache_path)).WillOnce(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(gcache_v2_path))
      .WillOnce(Return(true));
  EXPECT_CALL(platform_, SetOwnership(base_path, chronos_uid_, shared_gid_, _))
      .WillOnce(Return(true));

  // Expectaction for Mount::SetupGroupAccess
  // These files should exist, then SetGroupAccessible is called on them.
  EXPECT_CALL(platform_,
              FileExists(AnyOf(base_path, myfiles_path, downloads_path,
                               myfiles_downloads_path, gcache_dirs)))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_,
              SetGroupAccessible(AnyOf(base_path, myfiles_path, downloads_path,
                                       myfiles_downloads_path, gcache_dirs),
                                 shared_gid_, _))
      .WillRepeatedly(Return(true));

  ASSERT_TRUE(mount_->SetUpEphemeralCryptohome(base_path));
}

TEST_P(EphemeralNoUserSystemTest, OwnerUnknownMountCreateTest) {
  // Checks that when a device is not enterprise enrolled and does not have a
  // known owner, a regular vault is created and mounted.
  set_policy(false, "", true);

  TestUser *user = &helper_.users[0];
  UsernamePasskey up(user->username, user->passkey);

  EXPECT_CALL(platform_, FileExists(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, FileExists(user->image_path))
    .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_, DirectoryExists(user->vault_path))
    .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_, DirectoryExists(user->vault_mount_path))
    .WillRepeatedly(Return(false));
  ExpectCryptohomeKeySetup(*user);
  EXPECT_CALL(platform_, CreateDirectory(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetOwnership(_, _, _, _)).WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetPermissions(_, _)).WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, WriteFileAtomicDurable(user->keyset_path, _, _))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, ReadFile(user->keyset_path, _))
    .WillRepeatedly(DoAll(SetArgPointee<1>(user->credentials),
                          Return(true)));
  EXPECT_CALL(platform_,
      DirectoryExists(
        Property(&FilePath::value,
                 StartsWith(user->user_vault_path.value()))))
    .WillRepeatedly(Return(true));

  EXPECT_CALL(platform_, Mount(_, _, kEphemeralMountType,
                               kDefaultMountFlags, _)).Times(0);
  EXPECT_CALL(platform_, Mount(_, _, _, kDefaultMountFlags, _))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, Bind(_, _))
      .WillRepeatedly(Return(true));
  ExpectDownloadsBindMounts(*user);
  ExpectDaemonStoreMounts(*user, false /* is_ephemeral */);

  // First user to login -> an owner.
  EXPECT_CALL(tpm_, SetUserType(Tpm::UserType::Owner))
      .WillOnce(Return(true));

  user->InjectKeyset(&platform_, true);

  EXPECT_CALL(platform_, GetFileEnumerator(kSkelDir, _, _))
      .WillOnce(Return(new NiceMock<MockFileEnumerator>()))
      .WillOnce(Return(new NiceMock<MockFileEnumerator>()));

  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.create_if_missing = true;
  MountError error;
  ASSERT_TRUE(mount_->MountCryptohome(up,
                                      mount_args,
                                      &error));

  // Unmount triggers setting user type to non-owner.
  testing::Mock::VerifyAndClearExpectations(&tpm_);
  EXPECT_CALL(tpm_, SetUserType(Tpm::UserType::NonOwner))
      .WillOnce(Return(true));

  ASSERT_TRUE(mount_->UnmountCryptohome());
}

TEST_P(EphemeralNoUserSystemTest, MountSetUserTypeFailTest) {
  // Checks that when a device is not enterprise enrolled and does not have a
  // known owner, a regular vault is created and mounted.
  set_policy(false, "", true);

  TestUser *user = &helper_.users[0];
  UsernamePasskey up(user->username, user->passkey);

  EXPECT_CALL(platform_, FileExists(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, FileExists(user->image_path))
    .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_, DirectoryExists(_)).WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(user->vault_path))
    .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_, DirectoryExists(user->vault_mount_path))
    .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_, GetFileEnumerator(_, _, _))
      .WillOnce(Return(new NiceMock<MockFileEnumerator>()))
      .WillOnce(Return(new NiceMock<MockFileEnumerator>()));
  EXPECT_CALL(platform_, SetOwnership(_, _, _, _)).WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetPermissions(_, _)).WillRepeatedly(Return(true));

  if (ShouldTestEcryptfs()) {
    EXPECT_CALL(platform_, AddEcryptfsAuthToken(_, _, _))
        .WillRepeatedly(Return(true));
  } else {
    const key_serial_t kDirCryptoKeyId = 12345;
    EXPECT_CALL(platform_, AddDirCryptoKeyToKeyring(_, _, _))
        .WillRepeatedly(DoAll(SetArgPointee<2>(kDirCryptoKeyId), Return(true)));
    EXPECT_CALL(platform_, SetDirCryptoKey(user->vault_mount_path, _))
        .WillRepeatedly(Return(true));
    EXPECT_CALL(platform_, InvalidateDirCryptoKey(kDirCryptoKeyId, kImageDir))
        .WillRepeatedly(Return(true));
  }

  EXPECT_CALL(platform_, CreateDirectory(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, WriteFileAtomicDurable(user->keyset_path, _, _))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, ReadFile(user->keyset_path, _))
    .WillRepeatedly(DoAll(SetArgPointee<1>(user->credentials),
                          Return(true)));
  EXPECT_CALL(platform_,
      DirectoryExists(
        Property(&FilePath::value, StartsWith(user->user_vault_path.value()))))
    .WillRepeatedly(Return(true));

  EXPECT_CALL(platform_, Mount(_, _, kEphemeralMountType,
                               kDefaultMountFlags, _)).Times(0);
  EXPECT_CALL(platform_, Mount(_, _, _, kDefaultMountFlags, _))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, Bind(_, _))
      .WillRepeatedly(Return(true));

  // Inject the failure.
  // In case of MOUNT_ERROR_TPM_COMM_ERROR, it will retry mounting once,
  // so an attempt to SetUserType will happen twice.
  EXPECT_CALL(tpm_, SetUserType(_))
      .Times(2)
      .WillRepeatedly(Return(false));

  // Keyset enumeration and skeleton walk will be repeated twice due to mount
  // retry logic. Note that InSequence is used here, as otherwise a single
  // series of mocks will be triggered twice and fail due to over-saturation.
  {
    InSequence s;
    for (int i = 0; i < 2; ++i) {
      user->InjectKeyset(&platform_, true);
      EXPECT_CALL(platform_, GetFileEnumerator(kSkelDir, _, _))
          .WillOnce(Return(new NiceMock<MockFileEnumerator>()))
          .WillOnce(Return(new NiceMock<MockFileEnumerator>()));
    }
  }

  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.create_if_missing = true;
  MountError error;
  ASSERT_FALSE(mount_->MountCryptohome(up,
                                       mount_args,
                                       &error));
  ASSERT_EQ(MOUNT_ERROR_TPM_COMM_ERROR, error);
}

// TODO(wad) Duplicate these tests with multiple mounts instead of one.

TEST_P(EphemeralNoUserSystemTest, EnterpriseMountNoCreateTest) {
  // Checks that when a device is enterprise enrolled, a tmpfs cryptohome is
  // mounted and no regular vault is created.
  set_policy(false, "", true);
  mount_->set_enterprise_owned(true);
  TestUser *user = &helper_.users[0];

  // Always removes non-owner cryptohomes.
  std::vector<FilePath> empty;
  EXPECT_CALL(platform_, EnumerateDirectoryEntries(_, _, _))
    .WillRepeatedly(DoAll(SetArgPointee<2>(empty), Return(true)));

  EXPECT_CALL(platform_, Unmount(_, _, _))
    .WillRepeatedly(Return(true));

  ExpectEphemeralCryptohomeMount(*user);

  // Enterprise enrolled -> no one is the owner.
  EXPECT_CALL(tpm_, SetUserType(Tpm::UserType::NonOwner))
      .WillOnce(Return(true));

  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.create_if_missing = true;
  mount_args.is_ephemeral = true;
  MountError error;
  UsernamePasskey up(user->username, user->passkey);
  ASSERT_TRUE(mount_->MountCryptohome(up, mount_args, &error));

  // Implicit unmount triggers setting user type to non-owner.
  testing::Mock::VerifyAndClearExpectations(&tpm_);
  EXPECT_CALL(tpm_, SetUserType(Tpm::UserType::NonOwner))
      .WillOnce(Return(true));
}

TEST_P(EphemeralNoUserSystemTest, OwnerUnknownMountIsEphemeralTest) {
  // Checks that when a device is not enterprise enrolled and does not have a
  // known owner, a mount request with the |ensure_ephemeral| flag set fails.
  TestUser* user = &helper_.users[0];

  EXPECT_CALL(platform_, Mount(_, _, _, kDefaultMountFlags, _)).Times(0);
  EXPECT_CALL(tpm_, SetUserType(_)).Times(0);

  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.create_if_missing = true;
  mount_args.is_ephemeral = true;
  MountError error;
  UsernamePasskey up(user->username, user->passkey);
  ASSERT_FALSE(mount_->MountCryptohome(up, mount_args, &error));
  ASSERT_EQ(MOUNT_ERROR_FATAL, error);
}

TEST_P(EphemeralNoUserSystemTest, EnterpriseMountIsEphemeralTest) {
  // Checks that when a device is enterprise enrolled, a mount request with the
  // |is_ephemeral| flag set causes a tmpfs cryptohome to be mounted and no
  // regular vault to be created.
  set_policy(true, "", false);
  mount_->set_enterprise_owned(true);
  TestUser *user = &helper_.users[0];

  // Always removes non-owner cryptohomes.
  std::vector<FilePath> empty;
  EXPECT_CALL(platform_, EnumerateDirectoryEntries(_, _, _))
    .WillRepeatedly(DoAll(SetArgPointee<2>(empty), Return(true)));

  ExpectEphemeralCryptohomeMount(*user);

  // Enterprise enrolled -> no one is the owner.
  EXPECT_CALL(tpm_, SetUserType(Tpm::UserType::NonOwner))
      .WillOnce(Return(true));

  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.create_if_missing = true;
  mount_args.is_ephemeral = true;
  MountError error;
  UsernamePasskey up(user->username, user->passkey);
  ASSERT_TRUE(mount_->MountCryptohome(up, mount_args, &error));

  EXPECT_CALL(platform_, Unmount(user->ephemeral_mount_path,  _, _))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      Unmount(
        Property(&FilePath::value, StartsWith("/home/chronos/u-")),
        _, _))
    .WillOnce(Return(true));  // user mount
  EXPECT_CALL(platform_,
      Unmount(
        Property(&FilePath::value, StartsWith("/home/user/")),
        _, _))
    .WillOnce(Return(true));  // user mount
  EXPECT_CALL(platform_,
      Unmount(
        Property(&FilePath::value, StartsWith("/home/root/")),
        _, _))
    .WillOnce(Return(true));  // user mount
  EXPECT_CALL(platform_, Unmount(FilePath("/home/chronos/user"), _, _))
    .WillOnce(Return(true));  // legacy mount
  EXPECT_CALL(platform_, Unmount(Property(&FilePath::value,
                                          StartsWith(kRunDaemonStoreBaseDir)),
                                 _, _))
      .WillOnce(Return(true));  // daemon store mounts
  EXPECT_CALL(platform_, ClearUserKeyring())
    .WillRepeatedly(Return(true));

  ExpectDownloadsUnmounts(*user);

  // Unmount triggers setting user type to non-owner.
  testing::Mock::VerifyAndClearExpectations(&tpm_);
  EXPECT_CALL(tpm_, SetUserType(Tpm::UserType::NonOwner))
      .WillOnce(Return(true));

  EXPECT_TRUE(mount_->UnmountCryptohome());
}

TEST_P(EphemeralNoUserSystemTest, EnterpriseMountStatVFSFailure) {
  // Checks the case when ephemeral statvfs call fails.
  set_policy(false, "", true);
  mount_->set_enterprise_owned(true);
  const TestUser* const user = &helper_.users[0];

  EXPECT_CALL(platform_, DetachLoop(_)).Times(0);
  ExpectCryptohomeRemoval(*user);

  EXPECT_CALL(platform_, StatVFS(FilePath(kEphemeralCryptohomeDir), _))
    .WillOnce(Return(false));

  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.create_if_missing = true;
  mount_args.is_ephemeral = true;
  MountError error;
  UsernamePasskey up(user->username, user->passkey);
  ASSERT_FALSE(mount_->MountCryptohome(up, mount_args, &error));
}

TEST_P(EphemeralNoUserSystemTest, EnterpriseMountCreateSparseDirFailure) {
  // Checks the case when directory for ephemeral sparse files fails to be
  // created.
  set_policy(false, "", true);
  mount_->set_enterprise_owned(true);
  const TestUser* const user = &helper_.users[0];

  EXPECT_CALL(platform_, DetachLoop(_)).Times(0);
  ExpectCryptohomeRemoval(*user);

  EXPECT_CALL(platform_, StatVFS(FilePath(kEphemeralCryptohomeDir), _))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      CreateDirectory(Mount::GetEphemeralSparseFile(user->obfuscated_username)
                          .DirName()))
    .WillOnce(Return(false));

  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.create_if_missing = true;
  mount_args.is_ephemeral = true;
  MountError error;
  UsernamePasskey up(user->username, user->passkey);
  ASSERT_FALSE(mount_->MountCryptohome(up, mount_args, &error));
}

TEST_P(EphemeralNoUserSystemTest, EnterpriseMountCreateSparseFailure) {
  // Checks the case when ephemeral sparse file fails to create.
  set_policy(false, "", true);
  mount_->set_enterprise_owned(true);
  const TestUser* const user = &helper_.users[0];

  EXPECT_CALL(platform_, DetachLoop(_)).Times(0);
  EXPECT_CALL(platform_,
      DeleteFile(Mount::GetEphemeralSparseFile(user->obfuscated_username), _))
    .Times(1);
  ExpectCryptohomeRemoval(*user);

  EXPECT_CALL(platform_, StatVFS(FilePath(kEphemeralCryptohomeDir), _))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      CreateDirectory(Mount::GetEphemeralSparseFile(user->obfuscated_username)
                          .DirName()))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      CreateSparseFile(
          Mount::GetEphemeralSparseFile(user->obfuscated_username), _))
    .WillOnce(Return(false));

  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.create_if_missing = true;
  mount_args.is_ephemeral = true;
  MountError error;
  UsernamePasskey up(user->username, user->passkey);
  ASSERT_FALSE(mount_->MountCryptohome(up, mount_args, &error));
}

TEST_P(EphemeralNoUserSystemTest, EnterpriseMountAttachLoopFailure) {
  // Checks that when ephemeral loop device fails to attach, clean up happens
  // appropriately.
  set_policy(false, "", true);
  mount_->set_enterprise_owned(true);
  const TestUser* const user = &helper_.users[0];

  EXPECT_CALL(platform_, DetachLoop(_)).Times(0);
  EXPECT_CALL(platform_,
      DeleteFile(Mount::GetEphemeralSparseFile(user->obfuscated_username), _))
    .Times(1);
  ExpectCryptohomeRemoval(*user);

  EXPECT_CALL(platform_, StatVFS(FilePath(kEphemeralCryptohomeDir), _))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      CreateDirectory(Mount::GetEphemeralSparseFile(user->obfuscated_username)
                          .DirName()))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      CreateSparseFile(
          Mount::GetEphemeralSparseFile(user->obfuscated_username), _))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      FormatExt4(Mount::GetEphemeralSparseFile(user->obfuscated_username),
                 kDefaultExt4FormatOpts, 0))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      AttachLoop(Mount::GetEphemeralSparseFile(user->obfuscated_username)))
    .WillOnce(Return(FilePath()));

  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.create_if_missing = true;
  mount_args.is_ephemeral = true;
  MountError error;
  UsernamePasskey up(user->username, user->passkey);
  ASSERT_FALSE(mount_->MountCryptohome(up, mount_args, &error));
}

TEST_P(EphemeralNoUserSystemTest, EnterpriseMountFormatFailure) {
  // Checks that when ephemeral loop device fails to be formatted, clean up
  // happens appropriately.
  set_policy(false, "", true);
  mount_->set_enterprise_owned(true);
  const TestUser* const user = &helper_.users[0];

  EXPECT_CALL(platform_, DetachLoop(_)).Times(0);
  EXPECT_CALL(platform_,
      DeleteFile(Mount::GetEphemeralSparseFile(user->obfuscated_username), _))
    .Times(1);
  ExpectCryptohomeRemoval(*user);

  EXPECT_CALL(platform_, StatVFS(FilePath(kEphemeralCryptohomeDir), _))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      CreateDirectory(Mount::GetEphemeralSparseFile(user->obfuscated_username)
                          .DirName()))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      CreateSparseFile(
          Mount::GetEphemeralSparseFile(user->obfuscated_username), _))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      FormatExt4(Mount::GetEphemeralSparseFile(user->obfuscated_username),
                 kDefaultExt4FormatOpts, 0))
    .WillOnce(Return(false));

  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.create_if_missing = true;
  mount_args.is_ephemeral = true;
  MountError error;
  UsernamePasskey up(user->username, user->passkey);
  ASSERT_FALSE(mount_->MountCryptohome(up, mount_args, &error));
}

TEST_P(EphemeralNoUserSystemTest, EnterpriseMountEnsureUserMountFailure) {
  // Checks that when ephemeral mount fails to ensure mount points, clean up
  // happens appropriately.
  set_policy(false, "", true);
  mount_->set_enterprise_owned(true);
  const TestUser* const user = &helper_.users[0];

  EXPECT_CALL(platform_, DetachLoop(_)).Times(1);
  EXPECT_CALL(platform_,
      DeleteFile(Mount::GetEphemeralSparseFile(user->obfuscated_username), _))
    .Times(1);
  ExpectCryptohomeRemoval(*user);

  EXPECT_CALL(platform_, StatVFS(FilePath(kEphemeralCryptohomeDir), _))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      CreateSparseFile(
          Mount::GetEphemeralSparseFile(user->obfuscated_username), _))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      FormatExt4(Mount::GetEphemeralSparseFile(user->obfuscated_username),
                 kDefaultExt4FormatOpts, 0))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      AttachLoop(Mount::GetEphemeralSparseFile(user->obfuscated_username)))
    .WillOnce(Return(FilePath("/dev/loop7")));
  EXPECT_CALL(platform_, Stat(_, _))
    .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_, CreateDirectory(_))
    .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_,
      CreateDirectory(Mount::GetEphemeralSparseFile(user->obfuscated_username)
                          .DirName()))
    .WillOnce(Return(true));


  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.create_if_missing = true;
  mount_args.is_ephemeral = true;
  MountError error;
  UsernamePasskey up(user->username, user->passkey);
  ASSERT_FALSE(mount_->MountCryptohome(up, mount_args, &error));
}

class EphemeralOwnerOnlySystemTest : public AltImageTest {
 public:
  EphemeralOwnerOnlySystemTest() { }

  void SetUp() {
    SetUpAltImage(kOwnerOnlyUsers, kOwnerOnlyUserCount);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(EphemeralOwnerOnlySystemTest);
};

INSTANTIATE_TEST_CASE_P(WithEcryptfs, EphemeralOwnerOnlySystemTest,
                        ::testing::Values(true));
INSTANTIATE_TEST_CASE_P(WithDircrypto, EphemeralOwnerOnlySystemTest,
                        ::testing::Values(false));

TEST_P(EphemeralOwnerOnlySystemTest, MountNoCreateTest) {
  // Checks that when a device is not enterprise enrolled and has a known owner,
  // a tmpfs cryptohome is mounted and no regular vault is created.
  TestUser* owner = &helper_.users[3];
  TestUser* user = &helper_.users[0];
  set_policy(true, owner->username, true);
  UsernamePasskey up(user->username, user->passkey);

  // Always removes non-owner cryptohomes.
  std::vector<FilePath> owner_only;
  owner_only.push_back(owner->base_path);

  EXPECT_CALL(platform_, EnumerateDirectoryEntries(_, _, _))
    .WillRepeatedly(DoAll(SetArgPointee<2>(owner_only), Return(true)));

  EXPECT_CALL(platform_, IsDirectoryMounted(_))
    .WillRepeatedly(Return(false));

  ExpectEphemeralCryptohomeMount(*user);

  // Different user -> not an owner.
  EXPECT_CALL(tpm_, SetUserType(Tpm::UserType::NonOwner))
      .WillOnce(Return(true));

  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.create_if_missing = true;
  mount_args.is_ephemeral = true;
  MountError error;
  ASSERT_TRUE(mount_->MountCryptohome(up, mount_args, &error));

  EXPECT_CALL(platform_, Unmount(user->ephemeral_mount_path, _, _))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      Unmount(
        Property(&FilePath::value, StartsWith("/home/chronos/u-")),
        _, _))
      .WillOnce(Return(true));  // user mount
  EXPECT_CALL(platform_,
      Unmount(
        Property(&FilePath::value, StartsWith("/home/user/")),
        _, _))
      .WillOnce(Return(true));  // user mount
  EXPECT_CALL(platform_,
      Unmount(
        Property(&FilePath::value, StartsWith("/home/root/")),
        _, _))
      .WillOnce(Return(true));  // user mount
  EXPECT_CALL(platform_, Unmount(FilePath("/home/chronos/user"), _, _))
      .WillOnce(Return(true));  // legacy mount
  EXPECT_CALL(platform_, Unmount(Property(&FilePath::value,
                                          StartsWith(kRunDaemonStoreBaseDir)),
                                 _, _))
      .WillOnce(Return(true));  // daemon store mounts
  EXPECT_CALL(platform_, ClearUserKeyring())
      .WillRepeatedly(Return(true));

  ExpectDownloadsUnmounts(*user);

  // Unmount triggers setting user type to non-owner.
  testing::Mock::VerifyAndClearExpectations(&tpm_);
  EXPECT_CALL(tpm_, SetUserType(Tpm::UserType::NonOwner))
      .WillOnce(Return(true));

  ASSERT_TRUE(mount_->UnmountCryptohome());
}

TEST_P(EphemeralOwnerOnlySystemTest, NonOwnerMountIsEphemeralTest) {
  // Checks that when a device is not enterprise enrolled and has a known owner,
  // a mount request for a non-owner user with the |is_ephemeral| flag set
  // causes a tmpfs cryptohome to be mounted and no regular vault to be created.
  TestUser* owner = &helper_.users[3];
  TestUser* user = &helper_.users[0];
  set_policy(true, owner->username, false);
  UsernamePasskey up(user->username, user->passkey);

  // Always removes non-owner cryptohomes.
  std::vector<FilePath> owner_only;
  owner_only.push_back(owner->base_path);

  EXPECT_CALL(platform_, EnumerateDirectoryEntries(_, _, _))
    .WillRepeatedly(DoAll(SetArgPointee<2>(owner_only), Return(true)));

  EXPECT_CALL(platform_, Unmount(_, _, _))
    .WillRepeatedly(Return(true));
  ExpectEphemeralCryptohomeMount(*user);

  // Different user -> not an owner.
  EXPECT_CALL(tpm_, SetUserType(Tpm::UserType::NonOwner))
      .WillOnce(Return(true));

  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.create_if_missing = true;
  mount_args.is_ephemeral = true;
  MountError error;
  ASSERT_TRUE(mount_->MountCryptohome(up, mount_args, &error));

  // Implicit unmount triggers setting user type to non-owner.
  testing::Mock::VerifyAndClearExpectations(&tpm_);
  EXPECT_CALL(tpm_, SetUserType(Tpm::UserType::NonOwner))
      .WillOnce(Return(true));
}

TEST_P(EphemeralOwnerOnlySystemTest, OwnerMountIsEphemeralTest) {
  // Checks that when a device is not enterprise enrolled and has a known owner,
  // a mount request for the owner with the |ensure_ephemeral| flag set fails.
  TestUser* owner = &helper_.users[3];
  set_policy(true, owner->username, false);
  UsernamePasskey up(owner->username, owner->passkey);

  EXPECT_CALL(platform_, Mount(_, _, _, kDefaultMountFlags, _)).Times(0);
  EXPECT_CALL(tpm_, SetUserType(_)).Times(0);

  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.create_if_missing = true;
  mount_args.is_ephemeral = true;
  MountError error;
  ASSERT_FALSE(mount_->MountCryptohome(up, mount_args, &error));
  ASSERT_EQ(MOUNT_ERROR_FATAL, error);
}

class EphemeralExistingUserSystemTest : public AltImageTest {
 public:
  EphemeralExistingUserSystemTest() { }

  void SetUp() {
    SetUpAltImage(kAlternateUsers, kAlternateUserCount);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(EphemeralExistingUserSystemTest);
};

INSTANTIATE_TEST_CASE_P(WithEcryptfs, EphemeralExistingUserSystemTest,
                        ::testing::Values(true));
INSTANTIATE_TEST_CASE_P(WithDircrypto, EphemeralExistingUserSystemTest,
                        ::testing::Values(false));

TEST_P(EphemeralExistingUserSystemTest, OwnerUnknownMountNoRemoveTest) {
  // Checks that when a device is not enterprise enrolled and does not have a
  // known owner, no stale cryptohomes are removed while mounting.
  set_policy(false, "", true);
  TestUser* user = &helper_.users[0];

  // No c-homes will be removed.  The rest of the mocking just gets us to
  // Mount().
  for (auto& user : helper_.users)
    user.InjectUserPaths(&platform_, chronos_uid_, chronos_gid_,
                         shared_gid_, kDaemonGid, ShouldTestEcryptfs());

  std::vector<FilePath> empty;
  EXPECT_CALL(platform_, EnumerateDirectoryEntries(_, _, _))
    .WillOnce(DoAll(SetArgPointee<2>(empty), Return(true)));

  EXPECT_CALL(platform_, Stat(_, _))
    .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_, CreateDirectory(user->vault_path))
    .Times(0);
  EXPECT_CALL(platform_, CreateDirectory(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetOwnership(_, _, _, _)).WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetPermissions(_, _))
    .WillRepeatedly(Return(true));

  ExpectCryptohomeMount(*user);
  EXPECT_CALL(platform_, ClearUserKeyring()).WillOnce(Return(true));

  EXPECT_CALL(platform_, SetGroupAccessible(_, _, _))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, DeleteFile(_, _))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, FileExists(_))
    .WillRepeatedly(Return(true));

  EXPECT_CALL(platform_, Mount(_, _, kEphemeralMountType,
                               kDefaultMountFlags, _)).Times(0);

  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.create_if_missing = true;
  MountError error;
  user->InjectKeyset(&platform_, true);
  UsernamePasskey up(user->username, user->passkey);
  ASSERT_TRUE(mount_->MountCryptohome(up, mount_args, &error));

  EXPECT_CALL(platform_, Unmount(_, _, _))
      .WillRepeatedly(Return(true));
  if (ShouldTestEcryptfs()) {
    EXPECT_CALL(platform_,
        Unmount(Property(&FilePath::value, EndsWith("/mount")), _, _))
        .WillOnce(Return(true));  // user mount
  }
  EXPECT_CALL(platform_,
      Unmount(
        Property(&FilePath::value, StartsWith("/home/chronos/u-")),
        _, _))
      .WillOnce(Return(true));  // user mount
  EXPECT_CALL(platform_,
      Unmount(
        Property(&FilePath::value, StartsWith("/home/user/")),
        _, _))
      .WillOnce(Return(true));  // user mount
  EXPECT_CALL(platform_,
      Unmount(
        Property(&FilePath::value, StartsWith("/home/root/")),
        _, _))
      .WillOnce(Return(true));  // user mount
  EXPECT_CALL(platform_, Unmount(FilePath("/home/chronos/user"), _, _))
      .WillOnce(Return(true));  // legacy mount
  EXPECT_CALL(platform_, Unmount(Property(&FilePath::value,
                                          StartsWith(kRunDaemonStoreBaseDir)),
                                 _, _))
      .WillOnce(Return(true));  // daemon store mounts
  EXPECT_CALL(platform_, ClearUserKeyring())
      .WillRepeatedly(Return(true));
  ExpectDownloadsUnmounts(*user);
  ASSERT_TRUE(mount_->UnmountCryptohome());
}

TEST_P(EphemeralExistingUserSystemTest, EnterpriseMountRemoveTest) {
  // Checks that when a device is enterprise enrolled, all stale cryptohomes are
  // removed while mounting.
  set_policy(false, "", true);
  mount_->set_enterprise_owned(true);
  TestUser* user = &helper_.users[0];
  UsernamePasskey up(user->username, user->passkey);

  std::vector<int> expect_deletion;
  expect_deletion.push_back(0);
  expect_deletion.push_back(1);
  expect_deletion.push_back(2);
  expect_deletion.push_back(3);
  PrepareHomedirs(true, &expect_deletion, NULL);

  // Let Mount know how many vaults there are.
  std::vector<FilePath> no_vaults;
  EXPECT_CALL(platform_, EnumerateDirectoryEntries(kImageDir, false, _))
    .WillOnce(DoAll(SetArgPointee<2>(vaults_), Return(true)))
    // Don't re-delete on Unmount.
    .WillRepeatedly(DoAll(SetArgPointee<2>(no_vaults), Return(true)));
  // Don't say any cryptohomes are mounted
  EXPECT_CALL(platform_, IsDirectoryMounted(_))
    .WillRepeatedly(Return(false));
  std::vector<FilePath> empty;
  EXPECT_CALL(platform_,
      EnumerateDirectoryEntries(
        AnyOf(
          FilePath("/home/root/"),
          FilePath("/home/user/")),
        _, _))
    .WillRepeatedly(DoAll(SetArgPointee<2>(empty), Return(true)));
  EXPECT_CALL(platform_,
      Stat(AnyOf(FilePath("/home/chronos"),
                 mount_->GetNewUserPath(user->username)),
           _))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_,
      Stat(AnyOf(FilePath("/home"),
                 FilePath("/home/root"),
                 brillo::cryptohome::home::GetRootPath(user->username),
                 FilePath("/home/user"),
                 brillo::cryptohome::home::GetUserPath(user->username)),
           _))
    .WillRepeatedly(Return(false));
  helper_.InjectEphemeralSkeleton(&platform_,
      FilePath(user->user_ephemeral_mount_path));
  user->InjectUserPaths(&platform_, chronos_uid_, chronos_gid_,
                        shared_gid_, kDaemonGid, ShouldTestEcryptfs());
  // Only expect the mounted user to "exist".
  EXPECT_CALL(platform_,
      DirectoryExists(
        Property(&FilePath::value, StartsWith(user->user_mount_path.value()))))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, CreateDirectory(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetOwnership(_, _, _, _)).WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetPermissions(_, _))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetGroupAccessible(_, _, _))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_,
      DeleteFile(Mount::GetEphemeralSparseFile(user->obfuscated_username), _))
    .WillRepeatedly(Return(true));

  EXPECT_CALL(platform_, Stat(user->root_ephemeral_mount_path, _))
    .WillOnce(Return(false));
  EXPECT_CALL(platform_,
      EnumerateDirectoryEntries(user->ephemeral_mount_path, _, _))
    .WillOnce(DoAll(SetArgPointee<2>(empty), Return(true)));
  EXPECT_CALL(platform_, DeleteFile(user->root_ephemeral_mount_path, true))
    .WillOnce(Return(true));

  ExpectEphemeralCryptohomeMount(*user);

  // Deleting users will cause each user's shadow root subdir to be
  // searched for LE credentials.
  for (const auto& user : helper_.users) {
    EXPECT_CALL(
        platform_,
        GetFileEnumerator(kImageDir.Append(user.obfuscated_username), false, _))
        .WillOnce(Return(new NiceMock<MockFileEnumerator>()));
  }

  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.create_if_missing = true;
  mount_args.is_ephemeral = true;
  MountError error;
  ASSERT_TRUE(mount_->MountCryptohome(up, mount_args, &error));

  EXPECT_CALL(platform_, Unmount(_, _, _))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_,
      Unmount(
        Property(&FilePath::value, StartsWith("/home/chronos/u-")),
        _, _))
      .WillOnce(Return(true));  // user mount
  EXPECT_CALL(platform_,
      Unmount(
        Property(&FilePath::value, StartsWith("/home/user/")),
        _, _))
      .WillOnce(Return(true));  // user mount
  EXPECT_CALL(platform_,
      Unmount(
        Property(&FilePath::value, StartsWith("/home/root/")),
        _, _))
      .WillOnce(Return(true));  // user mount
  EXPECT_CALL(platform_, Unmount(FilePath("/home/chronos/user"), _, _))
      .WillOnce(Return(true));  // legacy mount
  EXPECT_CALL(platform_, DeleteFile(user->ephemeral_mount_path, _))
      .WillOnce(Return(true));
  EXPECT_CALL(platform_, ClearUserKeyring())
      .WillRepeatedly(Return(true));
  ExpectDownloadsUnmounts(*user);
  ASSERT_TRUE(mount_->UnmountCryptohome());
}

TEST_P(EphemeralExistingUserSystemTest, MountRemoveTest) {
  // Checks that when a device is not enterprise enrolled and has a known owner,
  // all non-owner cryptohomes are removed while mounting.
  TestUser* owner = &helper_.users[3];
  set_policy(true, owner->username, true);
  TestUser* user = &helper_.users[0];
  UsernamePasskey up(user->username, user->passkey);

  std::vector<int> expect_deletion;
  expect_deletion.push_back(0);  // Mounting user shouldn't use be persistent.
  expect_deletion.push_back(1);
  expect_deletion.push_back(2);
  // Expect all users but the owner to be removed.
  PrepareHomedirs(true, &expect_deletion, NULL);

  // Let Mount know how many vaults there are.
  std::vector<FilePath> no_vaults;
  EXPECT_CALL(platform_, EnumerateDirectoryEntries(kImageDir, false, _))
    .WillOnce(DoAll(SetArgPointee<2>(vaults_), Return(true)))
    // Don't re-delete on Unmount.
    .WillRepeatedly(DoAll(SetArgPointee<2>(no_vaults), Return(true)));
  // Don't say any cryptohomes are mounted
  EXPECT_CALL(platform_, IsDirectoryMounted(_))
    .WillRepeatedly(Return(false));
  std::vector<FilePath> empty;
  EXPECT_CALL(platform_,
      EnumerateDirectoryEntries(
        AnyOf(FilePath("/home/root/"), FilePath("/home/user/")),
        _, _))
    .WillRepeatedly(DoAll(SetArgPointee<2>(empty), Return(true)));
  EXPECT_CALL(platform_,
      Stat(AnyOf(FilePath("/home/chronos"),
                 mount_->GetNewUserPath(user->username)),
           _))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_,
      Stat(AnyOf(FilePath("/home"),
                 FilePath("/home/root"),
                 brillo::cryptohome::home::GetRootPath(user->username),
                 FilePath("/home/user"),
                 brillo::cryptohome::home::GetUserPath(user->username)),
           _))
    .WillRepeatedly(Return(false));
  helper_.InjectEphemeralSkeleton(&platform_,
      FilePath(user->user_ephemeral_mount_path));
  user->InjectUserPaths(&platform_, chronos_uid_, chronos_gid_,
                        shared_gid_, kDaemonGid, ShouldTestEcryptfs());
  // Only expect the mounted user to "exist".
  EXPECT_CALL(platform_,
      DirectoryExists(
        Property(&FilePath::value, StartsWith(user->user_mount_path.value()))))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, CreateDirectory(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetOwnership(_, _, _, _)).WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetPermissions(_, _))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetGroupAccessible(_, _, _))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_,
      DeleteFile(Mount::GetEphemeralSparseFile(user->obfuscated_username), _))
    .WillRepeatedly(Return(true));

  EXPECT_CALL(platform_, Stat(user->root_ephemeral_mount_path, _))
    .WillOnce(Return(false));
  EXPECT_CALL(platform_,
      EnumerateDirectoryEntries(user->ephemeral_mount_path, _, _))
    .WillOnce(DoAll(SetArgPointee<2>(empty), Return(true)));
  EXPECT_CALL(platform_, DeleteFile(user->root_ephemeral_mount_path, true))
    .WillOnce(Return(true));

  ExpectEphemeralCryptohomeMount(*user);

  // Deleting users will cause "going-to-be-deleted" users' shadow root
  // subdir to be searched for LE credentials.
  for (int i = 0; i < helper_.users.size() - 1; i++) {
    TestUser* cur_user = &helper_.users[i];
    EXPECT_CALL(platform_,
                GetFileEnumerator(
                    kImageDir.Append(cur_user->obfuscated_username), false, _))
        .WillOnce(Return(new NiceMock<MockFileEnumerator>()));
  }

  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.create_if_missing = true;
  mount_args.is_ephemeral = true;
  MountError error;
  ASSERT_TRUE(mount_->MountCryptohome(up, mount_args, &error));

  EXPECT_CALL(platform_, Unmount(_, _, _))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_,
      Unmount(
        Property(&FilePath::value, StartsWith("/home/chronos/u-")),
        _, _))
    .WillOnce(Return(true));  // user mount
  EXPECT_CALL(platform_,
      Unmount(Property(&FilePath::value, StartsWith("/home/user/")),
        _, _))
    .WillOnce(Return(true));  // user mount
  EXPECT_CALL(platform_,
      Unmount(
        Property(&FilePath::value, StartsWith("/home/root/")),
        _, _))
    .WillOnce(Return(true));  // user mount
  EXPECT_CALL(platform_, Unmount(FilePath("/home/chronos/user"), _, _))
    .WillOnce(Return(true));  // legacy mount
  EXPECT_CALL(platform_, DeleteFile(user->ephemeral_mount_path, _))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_, ClearUserKeyring())
    .WillRepeatedly(Return(true));
  ExpectDownloadsUnmounts(*user);
  ASSERT_TRUE(mount_->UnmountCryptohome());
}

TEST_P(EphemeralExistingUserSystemTest, OwnerUnknownUnmountNoRemoveTest) {
  // Checks that when a device is not enterprise enrolled and does not have a
  // known owner, no stale cryptohomes are removed while unmounting.
  set_policy(false, "", true);
  EXPECT_CALL(platform_, ClearUserKeyring())
    .WillOnce(Return(true));
  ASSERT_TRUE(mount_->UnmountCryptohome());
}

TEST_P(EphemeralExistingUserSystemTest, EnterpriseUnmountRemoveTest) {
  // Checks that when a device is enterprise enrolled, all stale cryptohomes are
  // removed while unmounting.
  set_policy(false, "", true);
  mount_->set_enterprise_owned(true);

  std::vector<int> expect_deletion;
  expect_deletion.push_back(0);
  expect_deletion.push_back(1);
  expect_deletion.push_back(2);
  expect_deletion.push_back(3);
  PrepareHomedirs(false, &expect_deletion, NULL);

  // Let Mount know how many vaults there are.
  EXPECT_CALL(platform_, EnumerateDirectoryEntries(kImageDir, false, _))
    .WillRepeatedly(DoAll(SetArgPointee<2>(vaults_), Return(true)));

  // Don't say any cryptohomes are mounted
  EXPECT_CALL(platform_, IsDirectoryMounted(_))
    .WillRepeatedly(Return(false));
  std::vector<FilePath> empty;
  EXPECT_CALL(platform_,
      EnumerateDirectoryEntries(
        AnyOf(FilePath("/home/root/"), FilePath("/home/user/")),
        _, _))
    .WillRepeatedly(DoAll(SetArgPointee<2>(empty), Return(true)));

  EXPECT_CALL(platform_, ClearUserKeyring())
    .WillOnce(Return(true));

  ASSERT_TRUE(mount_->UnmountCryptohome());
}

TEST_P(EphemeralExistingUserSystemTest, UnmountRemoveTest) {
  // Checks that when a device is not enterprise enrolled and has a known owner,
  // all stale cryptohomes are removed while unmounting.
  TestUser* owner = &helper_.users[3];
  set_policy(true, owner->username, true);
  // All users but the owner.
  std::vector<int> expect_deletion;
  expect_deletion.push_back(0);
  expect_deletion.push_back(1);
  expect_deletion.push_back(2);
  PrepareHomedirs(false, &expect_deletion, NULL);

  // Let Mount know how many vaults there are.
  EXPECT_CALL(platform_, EnumerateDirectoryEntries(kImageDir, false, _))
    .WillRepeatedly(DoAll(SetArgPointee<2>(vaults_), Return(true)));

  // Don't say any cryptohomes are mounted
  EXPECT_CALL(platform_, IsDirectoryMounted(_))
    .WillRepeatedly(Return(false));
  std::vector<FilePath> empty;
  EXPECT_CALL(platform_,
      EnumerateDirectoryEntries(
        AnyOf(FilePath("/home/root/"), FilePath("/home/user/")),
        _, _))
    .WillRepeatedly(DoAll(SetArgPointee<2>(empty), Return(true)));

  EXPECT_CALL(platform_, ClearUserKeyring())
    .WillOnce(Return(true));

  ASSERT_TRUE(mount_->UnmountCryptohome());
}

TEST_P(EphemeralExistingUserSystemTest, NonOwnerMountIsEphemeralTest) {
  // Checks that when a device is not enterprise enrolled and has a known owner,
  // a mount request for a non-owner user with the |is_ephemeral| flag set
  // causes a tmpfs cryptohome to be mounted, even if a regular vault exists for
  // the user.
  // Since ephemeral users aren't enabled, no vaults will be deleted.
  TestUser* owner = &helper_.users[3];
  set_policy(true, owner->username, false);
  TestUser* user = &helper_.users[0];
  UsernamePasskey up(user->username, user->passkey);

  PrepareHomedirs(true, NULL, NULL);

  // Let Mount know how many vaults there are.
  EXPECT_CALL(platform_, EnumerateDirectoryEntries(kImageDir, false, _))
    .WillRepeatedly(DoAll(SetArgPointee<2>(vaults_), Return(true)));
  // Don't say any cryptohomes are mounted
  EXPECT_CALL(platform_, IsDirectoryMounted(_))
    .WillRepeatedly(Return(false));
  std::vector<FilePath> empty;
  EXPECT_CALL(platform_,
      EnumerateDirectoryEntries(
        AnyOf(FilePath("/home/root/"), FilePath("/home/user/")),
        _, _))
    .WillRepeatedly(DoAll(SetArgPointee<2>(empty), Return(true)));
  EXPECT_CALL(platform_,
      Stat(
        AnyOf(FilePath("/home/chronos"),
              mount_->GetNewUserPath(user->username)),
        _))
     .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_,
      Stat(
      AnyOf(FilePath("/home"),
            FilePath("/home/root"),
            brillo::cryptohome::home::GetRootPath(user->username),
            FilePath("/home/user"),
            brillo::cryptohome::home::GetUserPath(user->username)),
           _))
    .WillRepeatedly(Return(false));
  // Only expect the mounted user to "exist".
  EXPECT_CALL(platform_,
      DirectoryExists(
        Property(&FilePath::value, StartsWith(user->user_mount_path.value()))))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, CreateDirectory(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetOwnership(_, _, _, _)).WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetPermissions(_, _))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetGroupAccessible(_, _, _))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_,
      FileExists(
        Property(&FilePath::value, StartsWith("/home/chronos/user"))))
    .WillRepeatedly(Return(true));

  helper_.InjectEphemeralSkeleton(&platform_,
      FilePath(user->user_ephemeral_mount_path));

  EXPECT_CALL(platform_, Stat(user->root_ephemeral_mount_path, _))
    .WillOnce(Return(false));
  EXPECT_CALL(platform_,
      EnumerateDirectoryEntries(user->ephemeral_mount_path, _, _))
    .WillOnce(DoAll(SetArgPointee<2>(empty), Return(true)));

  EXPECT_CALL(platform_, Unmount(_, _, _))
    .WillRepeatedly(Return(true));
  ExpectEphemeralCryptohomeMount(*user);

  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.create_if_missing = true;
  mount_args.is_ephemeral = true;
  MountError error;
  ASSERT_TRUE(mount_->MountCryptohome(up, mount_args, &error));
}

TEST_P(EphemeralExistingUserSystemTest, EnterpriseMountIsEphemeralTest) {
  // Checks that when a device is enterprise enrolled, a mount request with the
  // |is_ephemeral| flag set causes a tmpfs cryptohome to be mounted, even
  // if a regular vault exists for the user.
  // Since ephemeral users aren't enabled, no vaults will be deleted.
  set_policy(true, "", false);
  mount_->set_enterprise_owned(true);

  TestUser* user = &helper_.users[0];
  UsernamePasskey up(user->username, user->passkey);

  // Mounting user vault won't be deleted, but tmpfs mount should still be
  // used.
  PrepareHomedirs(true, NULL, NULL);

  // Let Mount know how many vaults there are.
  EXPECT_CALL(platform_, EnumerateDirectoryEntries(kImageDir, false, _))
    .WillRepeatedly(DoAll(SetArgPointee<2>(vaults_), Return(true)));
  // Don't say any cryptohomes are mounted
  EXPECT_CALL(platform_, IsDirectoryMounted(_))
    .WillRepeatedly(Return(false));
  std::vector<FilePath> empty;
  EXPECT_CALL(platform_,
      EnumerateDirectoryEntries(
        AnyOf(FilePath("/home/root/"), FilePath("/home/user/")),
        _, _))
    .WillRepeatedly(DoAll(SetArgPointee<2>(empty), Return(true)));
  EXPECT_CALL(platform_,
      Stat(
        AnyOf(FilePath("/home/chronos"),
              mount_->GetNewUserPath(user->username)),
        _))
    .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_,
      Stat(
        AnyOf(FilePath("/home"),
              FilePath("/home/root"),
              brillo::cryptohome::home::GetRootPath(user->username),
              FilePath("/home/user"),
              brillo::cryptohome::home::GetUserPath(user->username)),
           _))
    .WillRepeatedly(Return(false));
  // Only expect the mounted user to "exist".
  EXPECT_CALL(platform_,
      DirectoryExists(
        Property(&FilePath::value, StartsWith(user->user_mount_path.value()))))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, CreateDirectory(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetOwnership(_, _, _, _)).WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetPermissions(_, _))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetGroupAccessible(_, _, _))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_,
      FileExists(
        Property(&FilePath::value, StartsWith("/home/chronos/user"))))
    .WillRepeatedly(Return(true));

  helper_.InjectEphemeralSkeleton(&platform_,
      FilePath(user->user_ephemeral_mount_path));

  EXPECT_CALL(platform_, Stat(user->root_ephemeral_mount_path, _))
    .WillOnce(Return(false));
  EXPECT_CALL(platform_,
      EnumerateDirectoryEntries(user->ephemeral_mount_path, _, _))
    .WillOnce(DoAll(SetArgPointee<2>(empty), Return(true)));

  EXPECT_CALL(platform_, Unmount(_, _, _))
    .WillRepeatedly(Return(true));
  ExpectEphemeralCryptohomeMount(*user);

  Mount::MountArgs mount_args = GetDefaultMountArgs();
  mount_args.create_if_missing = true;
  mount_args.is_ephemeral = true;
  MountError error;
  ASSERT_TRUE(mount_->MountCryptohome(up, mount_args, &error));
}

TEST_P(EphemeralNoUserSystemTest, MountGuestUserDir) {
  struct stat fake_root_st;
  fake_root_st.st_uid = 0;
  fake_root_st.st_gid = 0;
  fake_root_st.st_mode = S_IFDIR | S_IRWXU;
  EXPECT_CALL(platform_, Stat(FilePath("/home"), _))
    .Times(3)
    .WillRepeatedly(DoAll(SetArgPointee<1>(fake_root_st),
                          Return(true)));
  EXPECT_CALL(platform_, Stat(FilePath("/home/root"), _))
    .WillOnce(DoAll(SetArgPointee<1>(fake_root_st),
                    Return(true)));
  EXPECT_CALL(platform_,
      Stat(Property(&FilePath::value, StartsWith("/home/root/")), _))
    .WillOnce(Return(false));
  EXPECT_CALL(platform_, Stat(FilePath("/home/user"), _))
    .WillOnce(DoAll(SetArgPointee<1>(fake_root_st),
                    Return(true)));
  EXPECT_CALL(platform_,
      Stat(Property(&FilePath::value, StartsWith("/home/user/")), _))
    .WillOnce(Return(false));
  struct stat fake_user_st;
  fake_user_st.st_uid = chronos_uid_;
  fake_user_st.st_gid = chronos_gid_;
  fake_user_st.st_mode = S_IFDIR | S_IRWXU;
  EXPECT_CALL(platform_, Stat(FilePath("/home/chronos"), _))
    .WillOnce(DoAll(SetArgPointee<1>(fake_user_st),
                    Return(true)));
  EXPECT_CALL(platform_, CreateDirectory(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetOwnership(_, _, _, _)).WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetGroupAccessible(_, _, _))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, IsDirectoryMounted(_))
    .WillOnce(Return(false));
  EXPECT_CALL(platform_, DirectoryExists(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, FileExists(_))
    .WillRepeatedly(Return(true));

  EXPECT_CALL(platform_, StatVFS(FilePath(kEphemeralCryptohomeDir), _))
    .WillOnce(Return(true));
  const std::string sparse_prefix =
      FilePath(kEphemeralCryptohomeDir).Append(kSparseFileDir).value();
  EXPECT_CALL(platform_,
      CreateSparseFile(
          Property(&FilePath::value, StartsWith(sparse_prefix)), _))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      AttachLoop(Property(&FilePath::value, StartsWith(sparse_prefix))))
    .WillOnce(Return(FilePath("/dev/loop7")));
  EXPECT_CALL(platform_,
      FormatExt4(Property(&FilePath::value, StartsWith(sparse_prefix)),
                 kDefaultExt4FormatOpts, 0))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      Stat(Property(&FilePath::value, StartsWith(kEphemeralCryptohomeDir)), _))
    .WillOnce(Return(false));
  std::vector<FilePath> empty;
  EXPECT_CALL(platform_,
      EnumerateDirectoryEntries(
        Property(&FilePath::value, StartsWith(kEphemeralCryptohomeDir)),  _, _))
    .WillOnce(DoAll(SetArgPointee<2>(empty), Return(true)));
  EXPECT_CALL(platform_, Mount(_, _, _, kDefaultMountFlags, _))
    .Times(0);
  EXPECT_CALL(platform_,
      Mount(FilePath("/dev/loop7"), _, kEphemeralMountType,
            kDefaultMountFlags, _))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      Bind(Property(&FilePath::value, StartsWith(kEphemeralCryptohomeDir)),
           Property(&FilePath::value, StartsWith("/home/root/"))))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      Bind(
        Property(&FilePath::value, StartsWith(kEphemeralCryptohomeDir)),
        Property(&FilePath::value, StartsWith("/home/user/"))))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_, Bind(Property(&FilePath::value,
                                       StartsWith(kEphemeralCryptohomeDir)),
                              FilePath("/home/chronos/user")))
      .WillOnce(Return(true));
  EXPECT_CALL(
      platform_,
      Bind(Property(&FilePath::value, StartsWith(kEphemeralCryptohomeDir)),
           Property(&FilePath::value, StartsWith("/home/chronos/u-"))))
      .WillOnce(Return(true));
  // Binding Downloads to MyFiles/Downloads.
  EXPECT_CALL(platform_,
              Bind(Property(&FilePath::value, StartsWith("/home/chronos/u-")),
                   Property(&FilePath::value, StartsWith("/home/chronos/u-"))))
      .WillOnce(Return(true));
  EXPECT_CALL(
      platform_,
      Bind(Property(&FilePath::value, StartsWith("/home/chronos/user/")),
           Property(&FilePath::value, StartsWith("/home/chronos/user/"))))
      .WillOnce(Return(true));
  EXPECT_CALL(platform_,
              Bind(Property(&FilePath::value, StartsWith("/home/user/")),
                   Property(&FilePath::value, StartsWith("/home/user/"))))
      .WillOnce(Return(true));

  // Guest -> not an owner.
  // Also will be called on implicit Unmount.
  EXPECT_CALL(tpm_, SetUserType(Tpm::UserType::NonOwner))
      .WillOnce(Return(true));

  ASSERT_TRUE(mount_->MountGuestCryptohome());

  // Implicit unmount triggers setting user type to non-owner.
  testing::Mock::VerifyAndClearExpectations(&tpm_);
  EXPECT_CALL(tpm_, SetUserType(Tpm::UserType::NonOwner))
      .WillOnce(Return(true));
}

TEST_P(EphemeralNoUserSystemTest, MountGuestUserFailSetUserType) {
  struct stat fake_root_st;
  fake_root_st.st_uid = 0;
  fake_root_st.st_gid = 0;
  fake_root_st.st_mode = S_IFDIR | S_IRWXU;
  EXPECT_CALL(platform_, Stat(FilePath("/home"), _))
    .WillRepeatedly(DoAll(SetArgPointee<1>(fake_root_st),
                          Return(true)));
  EXPECT_CALL(platform_, Stat(FilePath("/home/root"), _))
    .WillOnce(DoAll(SetArgPointee<1>(fake_root_st),
                    Return(true)));
  EXPECT_CALL(platform_,
      Stat(Property(&FilePath::value, StartsWith("/home/root/")), _))
    .WillOnce(Return(false));
  EXPECT_CALL(platform_, Stat(FilePath("/home/user"), _))
    .WillOnce(DoAll(SetArgPointee<1>(fake_root_st),
                    Return(true)));
  EXPECT_CALL(platform_,
      Stat(Property(&FilePath::value, StartsWith("/home/user/")), _))
    .WillOnce(Return(false));
  struct stat fake_user_st;
  fake_user_st.st_uid = chronos_uid_;
  fake_user_st.st_gid = chronos_gid_;
  fake_user_st.st_mode = S_IFDIR | S_IRWXU;
  EXPECT_CALL(platform_, Stat(FilePath("/home/chronos"), _))
    .WillOnce(DoAll(SetArgPointee<1>(fake_user_st),
                    Return(true)));
  EXPECT_CALL(platform_, CreateDirectory(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetOwnership(_, _, _, _))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, SetGroupAccessible(_, _, _))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, IsDirectoryMounted(_))
    .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_, DirectoryExists(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, FileExists(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, StatVFS(_, _))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_, CreateSparseFile(_, _))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_, AttachLoop(_))
    .WillOnce(Return(FilePath("/dev/loop7")));
  EXPECT_CALL(platform_, FormatExt4(_, kDefaultExt4FormatOpts, 0))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      Stat(Property(&FilePath::value, StartsWith(kEphemeralCryptohomeDir)), _))
    .WillOnce(Return(false));
  EXPECT_CALL(platform_, Mount(_, _, _, kDefaultMountFlags, _))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, Bind(_, _))
    .WillRepeatedly(Return(true));

  EXPECT_CALL(tpm_, SetUserType(Tpm::UserType::NonOwner))
      .WillOnce(Return(false));

  ASSERT_FALSE(mount_->MountGuestCryptohome());
}

}  // namespace cryptohome
