// 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/storage/mount.h"

#include <map>
#include <memory>
#include <openssl/evp.h>
#include <openssl/sha.h>
#include <pwd.h>
#include <regex>  // NOLINT(build/c++11)
#include <stdlib.h>
#include <string.h>  // For memset(), memcpy()
#include <sys/types.h>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/callback_helpers.h>
#include <base/check.h>
#include <base/check_op.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/stl_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/time/time.h>
#include <brillo/cryptohome.h>
#include <brillo/process/process_mock.h>
#include <brillo/secure_blob.h>
#include <chromeos/constants/cryptohome.h>
#include <gtest/gtest.h>
#include <libhwsec-foundation/crypto/secure_blob_util.h>
#include <policy/libpolicy.h>

#include "cryptohome/crypto.h"
#include "cryptohome/cryptohome_common.h"
#include "cryptohome/filesystem_layout.h"
#include "cryptohome/keyset_management.h"
#include "cryptohome/mock_crypto.h"
#include "cryptohome/mock_keyset_management.h"
#include "cryptohome/mock_platform.h"
#include "cryptohome/mock_tpm.h"
#include "cryptohome/mock_vault_keyset.h"
#include "cryptohome/storage/encrypted_container/encrypted_container.h"
#include "cryptohome/storage/encrypted_container/fake_backing_device.h"
#include "cryptohome/storage/encrypted_container/fake_encrypted_container_factory.h"
#include "cryptohome/storage/file_system_keyset.h"
#include "cryptohome/storage/homedirs.h"
#include "cryptohome/storage/keyring/fake_keyring.h"
#include "cryptohome/storage/mock_homedirs.h"
#include "cryptohome/storage/mount_helper.h"
#include "cryptohome/vault_keyset.h"
#include "cryptohome/vault_keyset.pb.h"

namespace cryptohome {

using base::FilePath;
using brillo::SecureBlob;
using hwsec_foundation::SecureBlobToHex;

using ::testing::_;
using ::testing::DoAll;
using ::testing::Eq;
using ::testing::InSequence;
using ::testing::NiceMock;
using ::testing::Pointee;
using ::testing::Return;
using ::testing::SetArgPointee;
using ::testing::StartsWith;

namespace {
constexpr int kEphemeralVFSFragmentSize = 1 << 10;
constexpr int kEphemeralVFSSize = 1 << 12;

struct Attributes {
  mode_t mode;
  uid_t uid;
  gid_t gid;
};

constexpr char kEtc[] = "/etc";
constexpr char kEtcSkel[] = "/etc/skel";
constexpr char kEtcDaemonStore[] = "/etc/daemon-store";

constexpr char kRun[] = "/run";
constexpr char kRunCryptohome[] = "/run/cryptohome";
constexpr char kRunDaemonStore[] = "/run/daemon-store";

constexpr char kHome[] = "/home";
constexpr char kHomeChronos[] = "/home/chronos";
constexpr char kHomeChronosUser[] = "/home/chronos/user";
constexpr char kHomeUser[] = "/home/user";
constexpr char kHomeRoot[] = "/home/root";

constexpr char kDir1[] = "dir1";
constexpr char kFile1[] = "file1";
constexpr char kDir1File2[] = "dir1/file2";
constexpr char kDir1Dir2[] = "dir1/dir2";
constexpr char kDir1Dir2File3[] = "dir1/dir2/file3";

constexpr char kFile1Content[] = "content1";
constexpr char kDir1File2Content[] = "content2";
constexpr char kDir1Dir2File3Content[] = "content3";

constexpr char kSomeDaemon[] = "some_daemon";
constexpr Attributes kSomeDaemonAttributes{01735, 12, 27};
constexpr char kAnotherDaemon[] = "another_daemon";
constexpr Attributes kAnotherDaemonAttributes{0600, 0, 0};

constexpr char kDevLoopPrefix[] = "/dev/loop";

constexpr char kUser[] = "someuser";

MATCHER_P(DirCryptoReferenceMatcher, reference, "") {
  if (reference.reference != arg.reference) {
    return false;
  }
  if (reference.policy_version != arg.policy_version) {
    return false;
  }
  return true;
}

base::FilePath ChronosHashPath(const std::string& username) {
  const std::string obfuscated_username =
      brillo::cryptohome::home::SanitizeUserName(username);
  return base::FilePath(kHomeChronos)
      .Append(base::StringPrintf("u-%s", obfuscated_username.c_str()));
}

void PrepareDirectoryStructure(Platform* platform) {
  // Create environment as defined in
  // src/platform2/cryptohome/tmpfiles.d/cryptohome.conf
  ASSERT_TRUE(platform->SafeCreateDirAndSetOwnershipAndPermissions(
      base::FilePath(kRun), 0755, kRootUid, kRootGid));
  ASSERT_TRUE(platform->SafeCreateDirAndSetOwnershipAndPermissions(
      base::FilePath(kRunCryptohome), 0700, kRootUid, kRootGid));
  ASSERT_TRUE(platform->SafeCreateDirAndSetOwnershipAndPermissions(
      base::FilePath(kRunDaemonStore), 0755, kRootUid, kRootGid));
  ASSERT_TRUE(platform->SafeCreateDirAndSetOwnershipAndPermissions(
      base::FilePath(kHome), 0755, kRootUid, kRootGid));
  ASSERT_TRUE(platform->SafeCreateDirAndSetOwnershipAndPermissions(
      base::FilePath(kHomeChronos), 0755, kChronosUid, kChronosGid));
  ASSERT_TRUE(platform->SafeCreateDirAndSetOwnershipAndPermissions(
      base::FilePath(kHomeChronosUser), 01755, kChronosUid, kChronosGid));
  ASSERT_TRUE(platform->SafeCreateDirAndSetOwnershipAndPermissions(
      base::FilePath(kHomeUser), 0755, kRootUid, kRootGid));
  ASSERT_TRUE(platform->SafeCreateDirAndSetOwnershipAndPermissions(
      base::FilePath(kHomeRoot), 01751, kRootUid, kRootGid));

  // Setup some skel directories to make sure they are copied over.
  // TODO(dlunev): for now setting permissions is useless, for the code
  // relies on Copy to copy it over for files, meaning we can't intercept it.
  // It can be fixed by setting permissions explicitly in RecursiveCopy.
  ASSERT_TRUE(platform->CreateDirectory(base::FilePath(kEtc)));
  ASSERT_TRUE(platform->CreateDirectory(base::FilePath(kEtcSkel)));
  ASSERT_TRUE(
      platform->CreateDirectory(base::FilePath(kEtcSkel).Append(kDir1)));
  ASSERT_TRUE(platform->WriteStringToFile(
      base::FilePath(kEtcSkel).Append(kFile1), kFile1Content));
  ASSERT_TRUE(platform->WriteStringToFile(
      base::FilePath(kEtcSkel).Append(kDir1File2), kDir1File2Content));
  ASSERT_TRUE(
      platform->CreateDirectory(base::FilePath(kEtcSkel).Append(kDir1Dir2)));
  ASSERT_TRUE(platform->WriteStringToFile(
      base::FilePath(kEtcSkel).Append(kDir1Dir2File3), kDir1Dir2File3Content));

  // Setup daemon-store templates
  ASSERT_TRUE(platform->CreateDirectory(base::FilePath(kEtcDaemonStore)));
  ASSERT_TRUE(platform->SafeCreateDirAndSetOwnershipAndPermissions(
      base::FilePath(kEtcDaemonStore).Append(kSomeDaemon),
      kSomeDaemonAttributes.mode, kSomeDaemonAttributes.uid,
      kSomeDaemonAttributes.gid));
  ASSERT_TRUE(platform->SafeCreateDirAndSetOwnershipAndPermissions(
      base::FilePath(kEtcDaemonStore).Append(kAnotherDaemon),
      kAnotherDaemonAttributes.mode, kAnotherDaemonAttributes.uid,
      kAnotherDaemonAttributes.gid));
  ASSERT_TRUE(platform->CreateDirectory(
      base::FilePath(kRunDaemonStore).Append(kSomeDaemon)));
  ASSERT_TRUE(platform->CreateDirectory(
      base::FilePath(kRunDaemonStore).Append(kAnotherDaemon)));
}

void CheckExistanceAndPermissions(Platform* platform,
                                  const base::FilePath& path,
                                  mode_t expected_mode,
                                  uid_t expected_uid,
                                  gid_t expected_gid,
                                  bool expect_present) {
  ASSERT_THAT(platform->FileExists(path), expect_present)
      << "PATH: " << path.value();

  if (!expect_present) {
    return;
  }

  mode_t mode;
  uid_t uid;
  gid_t gid;

  ASSERT_THAT(platform->GetOwnership(path, &uid, &gid, false), true)
      << "PATH: " << path.value();
  ASSERT_THAT(platform->GetPermissions(path, &mode), true)
      << "PATH: " << path.value();

  ASSERT_THAT(mode, expected_mode) << "PATH: " << path.value();
  ASSERT_THAT(uid, expected_uid) << "PATH: " << path.value();
  ASSERT_THAT(gid, expected_gid) << "PATH: " << path.value();
}

void CheckRootAndDaemonStoreMounts(Platform* platform,
                                   const std::string& username,
                                   const base::FilePath& vault_mount_point,
                                   bool expect_present) {
  const std::string obfuscated_username =
      brillo::cryptohome::home::SanitizeUserName(username);
  const std::multimap<const base::FilePath, const base::FilePath>
      expected_root_mount_map{
          {
              vault_mount_point.Append(kRootHomeSuffix),
              brillo::cryptohome::home::GetRootPath(username),
          },
          {
              vault_mount_point.Append(kRootHomeSuffix).Append(kSomeDaemon),
              base::FilePath(kRunDaemonStore)
                  .Append(kSomeDaemon)
                  .Append(obfuscated_username),
          },
          {
              vault_mount_point.Append(kRootHomeSuffix).Append(kAnotherDaemon),
              base::FilePath(kRunDaemonStore)
                  .Append(kAnotherDaemon)
                  .Append(obfuscated_username),
          },
      };
  std::multimap<const base::FilePath, const base::FilePath> root_mount_map;

  ASSERT_THAT(platform->IsDirectoryMounted(
                  brillo::cryptohome::home::GetRootPath(username)),
              expect_present);
  if (expect_present) {
    ASSERT_TRUE(platform->GetMountsBySourcePrefix(
        vault_mount_point.Append(kRootHomeSuffix), &root_mount_map));
    ASSERT_THAT(root_mount_map,
                ::testing::UnorderedElementsAreArray(expected_root_mount_map));
  }
  CheckExistanceAndPermissions(platform,
                               vault_mount_point.Append(kRootHomeSuffix), 01770,
                               kRootUid, kDaemonStoreGid, expect_present);
  CheckExistanceAndPermissions(
      platform, vault_mount_point.Append(kRootHomeSuffix).Append(kSomeDaemon),
      kSomeDaemonAttributes.mode, kSomeDaemonAttributes.uid,
      kSomeDaemonAttributes.gid, expect_present);
  CheckExistanceAndPermissions(
      platform,
      vault_mount_point.Append(kRootHomeSuffix).Append(kAnotherDaemon),
      kAnotherDaemonAttributes.mode, kAnotherDaemonAttributes.uid,
      kAnotherDaemonAttributes.gid, expect_present);

  if (expect_present) {
    // TODO(dlunev): make this directories to go away on unmount.
    ASSERT_THAT(platform->DirectoryExists(base::FilePath(kRunDaemonStore)
                                              .Append(kSomeDaemon)
                                              .Append(obfuscated_username)),
                expect_present);
    ASSERT_THAT(platform->DirectoryExists(base::FilePath(kRunDaemonStore)
                                              .Append(kAnotherDaemon)
                                              .Append(obfuscated_username)),
                expect_present);
    CheckExistanceAndPermissions(
        platform, brillo::cryptohome::home::GetRootPath(username), 01770,
        kRootUid, kDaemonStoreGid, expect_present);
  }
}

void CheckUserMountPoints(Platform* platform,
                          const std::string& username,
                          const base::FilePath& vault_mount_point,
                          bool expect_present,
                          bool downloads_bind_mount = true) {
  const base::FilePath chronos_hash_user_mount_point =
      ChronosHashPath(username);

  std::multimap<const base::FilePath, const base::FilePath>
      expected_user_mount_map{
          {vault_mount_point.Append(kUserHomeSuffix),
           vault_mount_point.Append(kUserHomeSuffix)},
          {vault_mount_point.Append(kUserHomeSuffix),
           brillo::cryptohome::home::GetUserPath(username)},
          {vault_mount_point.Append(kUserHomeSuffix),
           chronos_hash_user_mount_point},
          {vault_mount_point.Append(kUserHomeSuffix),
           base::FilePath(kHomeChronosUser)},
      };

  if (downloads_bind_mount) {
    expected_user_mount_map.insert(
        {vault_mount_point.Append(kUserHomeSuffix).Append(kDownloadsDir),
         vault_mount_point.Append(kUserHomeSuffix)
             .Append(kMyFilesDir)
             .Append(kDownloadsDir)});
  }
  std::multimap<const base::FilePath, const base::FilePath> user_mount_map;

  ASSERT_THAT(platform->IsDirectoryMounted(base::FilePath(kHomeChronosUser)),
              expect_present);
  ASSERT_THAT(platform->IsDirectoryMounted(
                  brillo::cryptohome::home::GetUserPath(username)),
              expect_present);
  ASSERT_THAT(platform->IsDirectoryMounted(chronos_hash_user_mount_point),
              expect_present);

  ASSERT_THAT(
      platform->IsDirectoryMounted(vault_mount_point.Append(kUserHomeSuffix)
                                       .Append(kMyFilesDir)
                                       .Append(kDownloadsDir)),
      expect_present && downloads_bind_mount);
  if (expect_present) {
    ASSERT_TRUE(platform->GetMountsBySourcePrefix(
        vault_mount_point.Append(kUserHomeSuffix), &user_mount_map));
    ASSERT_THAT(user_mount_map,
                ::testing::UnorderedElementsAreArray(expected_user_mount_map));
  }
}

void CheckUserMountPaths(Platform* platform,
                         const base::FilePath& base_path,
                         bool expect_present) {
  // The path itself.
  // TODO(dlunev): the mount paths should be cleaned up upon unmount.
  if (expect_present) {
    CheckExistanceAndPermissions(platform, base_path, 0750, kChronosUid,
                                 kChronosAccessGid, expect_present);
  }

  // Subdirectories
  CheckExistanceAndPermissions(platform, base_path.Append(kDownloadsDir), 0750,
                               kChronosUid, kChronosAccessGid, expect_present);

  CheckExistanceAndPermissions(platform, base_path.Append(kMyFilesDir), 0750,
                               kChronosUid, kChronosAccessGid, expect_present);

  CheckExistanceAndPermissions(
      platform, base_path.Append(kMyFilesDir).Append(kDownloadsDir), 0750,
      kChronosUid, kChronosAccessGid, expect_present);

  CheckExistanceAndPermissions(platform, base_path.Append(kCacheDir), 0700,
                               kChronosUid, kChronosGid, expect_present);

  CheckExistanceAndPermissions(platform, base_path.Append(kGCacheDir), 0750,
                               kChronosUid, kChronosAccessGid, expect_present);

  CheckExistanceAndPermissions(
      platform, base_path.Append(kGCacheDir).Append(kGCacheVersion2Dir), 0770,
      kChronosUid, kChronosAccessGid, expect_present);
}

void CheckSkel(Platform* platform,
               const base::FilePath& base_path,
               bool expect_present) {
  // Presence
  // TODO(dlunev) unfortunately we can not verify if Copy correctly deals with
  // the attributes, because it actually deals with those at the point where
  // we can not intercept it. We can make that explicit by setting those in
  // the copy skel itself.
  CheckExistanceAndPermissions(platform, base_path.Append(kDir1), 0750,
                               kChronosUid, kChronosGid, expect_present);
  CheckExistanceAndPermissions(
      platform, base_path.Append(kFile1),
      0750,  // NOT A PART OF THE CONTRACT, SEE TODO ABOVE.
      kChronosUid, kChronosGid, expect_present);
  CheckExistanceAndPermissions(platform, base_path.Append(kDir1Dir2), 0750,
                               kChronosUid, kChronosGid, expect_present);
  CheckExistanceAndPermissions(
      platform, base_path.Append(kDir1File2),
      0750,  // NOT A PART OF THE CONTRACT, SEE TODO ABOVE.
      kChronosUid, kChronosGid, expect_present);
  CheckExistanceAndPermissions(
      platform, base_path.Append(kDir1Dir2File3),
      0750,  // NOT A PART OF THE CONTRACT, SEE TODO ABOVE.
      kChronosUid, kChronosGid, expect_present);

  // Content
  if (expect_present) {
    std::string result;
    ASSERT_TRUE(platform->ReadFileToString(base_path.Append(kFile1), &result));
    ASSERT_THAT(result, kFile1Content);
    ASSERT_TRUE(
        platform->ReadFileToString(base_path.Append(kDir1File2), &result));
    ASSERT_THAT(result, kDir1File2Content);
    ASSERT_TRUE(
        platform->ReadFileToString(base_path.Append(kDir1Dir2File3), &result));
    ASSERT_THAT(result, kDir1Dir2File3Content);
  }
}

}  // namespace

// TODO(dlunev): add test ecryptfs blasts "mount".
class PersistentSystemTest : public ::testing::Test {
 public:
  PersistentSystemTest() : crypto_(&platform_) {}

  void SetUp() {
    ASSERT_NO_FATAL_FAILURE(PrepareDirectoryStructure(&platform_));
    std::unique_ptr<EncryptedContainerFactory> container_factory =
        std::make_unique<FakeEncryptedContainerFactory>(
            &platform_, std::make_unique<FakeKeyring>());
    homedirs_ = std::make_unique<HomeDirs>(
        &platform_, std::make_unique<policy::PolicyProvider>(),
        base::BindRepeating([](const std::string& unused) {}),
        std::make_unique<CryptohomeVaultFactory>(&platform_,
                                                 std::move(container_factory)));

    mount_ =
        new Mount(&platform_, homedirs_.get(), /*legacy_mount=*/true,
                  /*bind_mount_downloads=*/true, /*use_local_mounter=*/true);
  }

 protected:
  // Protected for trivial access.
  NiceMock<MockPlatform> platform_;
  Crypto crypto_;
  std::unique_ptr<HomeDirs> homedirs_;
  scoped_refptr<Mount> mount_;

  void VerifyFS(const std::string& username,
                MountType type,
                bool expect_present,
                bool downloads_bind_mount = true) {
    const std::string obfuscated_username =
        brillo::cryptohome::home::SanitizeUserName(username);
    if (type == MountType::ECRYPTFS) {
      CheckEcryptfsMount(username, expect_present);
    } else if (type == MountType::DIR_CRYPTO) {
      CheckDircryptoMount(username, expect_present);
    } else if (type == MountType::DMCRYPT) {
      CheckDmcryptMount(username, expect_present);
    } else {
      NOTREACHED();
    }
    ASSERT_NO_FATAL_FAILURE(CheckRootAndDaemonStoreMounts(
        &platform_, username, GetUserMountDirectory(obfuscated_username),
        expect_present));
    ASSERT_NO_FATAL_FAILURE(CheckUserMountPoints(
        &platform_, username, GetUserMountDirectory(obfuscated_username),
        expect_present, downloads_bind_mount));

    const std::vector<base::FilePath> user_vault_and_mounts{
        GetUserMountDirectory(obfuscated_username).Append(kUserHomeSuffix),
        base::FilePath(kHomeChronosUser),
        brillo::cryptohome::home::GetUserPath(username),
        ChronosHashPath(username),
    };

    for (const auto& base_path : user_vault_and_mounts) {
      ASSERT_NO_FATAL_FAILURE(
          CheckUserMountPaths(&platform_, base_path, expect_present));
      ASSERT_NO_FATAL_FAILURE(CheckSkel(&platform_, base_path, expect_present));
    }

    if (type == MountType::DIR_CRYPTO && expect_present) {
      CheckTrackingXattr(username);
    }
  }

  void MockPreclearKeyring(bool success) {
    EXPECT_CALL(platform_, ClearUserKeyring()).WillOnce(Return(success));
  }

  void MockDircryptoPolicy(const std::string& username, bool existing_dir) {
    const std::string obfuscated_username =
        brillo::cryptohome::home::SanitizeUserName(username);
    const base::FilePath backing_dir =
        GetUserMountDirectory(obfuscated_username);
    EXPECT_CALL(platform_, GetDirectoryPolicyVersion(backing_dir))
        .WillRepeatedly(Return(existing_dir ? FSCRYPT_POLICY_V1 : -1));
    EXPECT_CALL(platform_, GetDirCryptoKeyState(ShadowRoot()))
        .WillRepeatedly(Return(dircrypto::KeyState::NO_KEY));
    EXPECT_CALL(platform_, GetDirCryptoKeyState(backing_dir))
        .WillRepeatedly(Return(existing_dir ? dircrypto::KeyState::ENCRYPTED
                                            : dircrypto::KeyState::NO_KEY));
  }

  void MockDircryptoKeyringSetup(const std::string& username,
                                 const FileSystemKeyset& keyset,
                                 bool existing_dir,
                                 bool success) {
    const std::string obfuscated_username =
        brillo::cryptohome::home::SanitizeUserName(username);
    const base::FilePath backing_dir =
        GetUserMountDirectory(obfuscated_username);
    const dircrypto::KeyReference reference = {
        .policy_version = FSCRYPT_POLICY_V1,
        .reference = keyset.KeyReference().fek_sig,
    };

    MockDircryptoPolicy(username, existing_dir);
    // EXPECT_CALL(platform_,
    // CheckDircryptoKeyIoctlSupport()).WillOnce(Return(true));
    EXPECT_CALL(
        platform_,
        SetDirCryptoKey(backing_dir, DirCryptoReferenceMatcher(reference)))
        .WillOnce(Return(success));
  }

  void SetHomedir(const std::string& username) {
    const std::string obfuscated_username =
        brillo::cryptohome::home::SanitizeUserName(username);
    ASSERT_TRUE(platform_.CreateDirectory(UserPath(obfuscated_username)));
  }

  void SetDmcryptPrereqs(const std::string& username) {
    const std::string obfuscated_username =
        brillo::cryptohome::home::SanitizeUserName(username);
    SetHomedir(username);
    ASSERT_TRUE(
        platform_.TouchFileDurable(GetDmcryptDataVolume(obfuscated_username)));
    ASSERT_TRUE(
        platform_.TouchFileDurable(GetDmcryptCacheVolume(obfuscated_username)));
    ON_CALL(platform_, GetStatefulDevice())
        .WillByDefault(Return(base::FilePath("/dev/somedev")));
    ON_CALL(platform_, GetBlkSize(_, _))
        .WillByDefault(DoAll(SetArgPointee<1>(4096), Return(true)));
    ON_CALL(platform_, UdevAdmSettle(_, _)).WillByDefault(Return(true));
    ON_CALL(platform_, FormatExt4(_, _, _)).WillByDefault(Return(true));
    ON_CALL(platform_, Tune2Fs(_, _)).WillByDefault(Return(true));
  }

 private:
  void CheckEcryptfsMount(const std::string& username, bool expect_present) {
    const std::string obfuscated_username =
        brillo::cryptohome::home::SanitizeUserName(username);
    const base::FilePath ecryptfs_vault =
        GetEcryptfsUserVaultPath(obfuscated_username);
    const base::FilePath ecryptfs_mount_point =
        GetUserMountDirectory(obfuscated_username);
    const std::multimap<const base::FilePath, const base::FilePath>
        expected_ecryptfs_mount_map{
            {ecryptfs_vault, ecryptfs_mount_point},
        };
    std::multimap<const base::FilePath, const base::FilePath>
        ecryptfs_mount_map;
    ASSERT_THAT(platform_.IsDirectoryMounted(ecryptfs_mount_point),
                expect_present);
    if (expect_present) {
      ASSERT_THAT(platform_.DirectoryExists(ecryptfs_mount_point),
                  expect_present);
      ASSERT_TRUE(platform_.GetMountsBySourcePrefix(ecryptfs_vault,
                                                    &ecryptfs_mount_map));
      ASSERT_THAT(ecryptfs_mount_map, ::testing::UnorderedElementsAreArray(
                                          expected_ecryptfs_mount_map));
    }
  }

  void CheckDircryptoMount(const std::string& username, bool expect_present) {
    const std::string obfuscated_username =
        brillo::cryptohome::home::SanitizeUserName(username);
    const base::FilePath dircrypto_mount_point =
        GetUserMountDirectory(obfuscated_username);
    if (expect_present) {
      ASSERT_THAT(platform_.DirectoryExists(dircrypto_mount_point),
                  expect_present);
    }
  }

  void CheckDmcryptMount(const std::string& username, bool expect_present) {
    const base::FilePath kDevMapperPath(kDeviceMapperDir);
    const std::string obfuscated_username =
        brillo::cryptohome::home::SanitizeUserName(username);
    const std::multimap<const base::FilePath, const base::FilePath>
        expected_volume_mount_map{
            {GetDmcryptDataVolume(obfuscated_username),
             GetUserMountDirectory(obfuscated_username)},
            {GetDmcryptCacheVolume(obfuscated_username),
             GetDmcryptUserCacheDirectory(obfuscated_username)},
        };
    const std::multimap<const base::FilePath, const base::FilePath>
        expected_cache_mount_map{
            {GetDmcryptUserCacheDirectory(obfuscated_username)
                 .Append(kUserHomeSuffix)
                 .Append(kCacheDir),
             GetUserMountDirectory(obfuscated_username)
                 .Append(kUserHomeSuffix)
                 .Append(kCacheDir)},
            {GetDmcryptUserCacheDirectory(obfuscated_username)
                 .Append(kUserHomeSuffix)
                 .Append(kGCacheDir),
             GetUserMountDirectory(obfuscated_username)
                 .Append(kUserHomeSuffix)
                 .Append(kGCacheDir)},
        };
    std::multimap<const base::FilePath, const base::FilePath> volume_mount_map;
    std::multimap<const base::FilePath, const base::FilePath> cache_mount_map;
    ASSERT_THAT(platform_.IsDirectoryMounted(
                    GetUserMountDirectory(obfuscated_username)),
                expect_present);
    ASSERT_THAT(platform_.IsDirectoryMounted(
                    GetDmcryptUserCacheDirectory(obfuscated_username)),
                expect_present);
    ASSERT_THAT(
        platform_.IsDirectoryMounted(GetUserMountDirectory(obfuscated_username)
                                         .Append(kUserHomeSuffix)
                                         .Append(kCacheDir)),
        expect_present);
    ASSERT_THAT(
        platform_.IsDirectoryMounted(GetUserMountDirectory(obfuscated_username)
                                         .Append(kUserHomeSuffix)
                                         .Append(kGCacheDir)),
        expect_present);
    if (expect_present) {
      ASSERT_TRUE(
          platform_.GetMountsBySourcePrefix(kDevMapperPath, &volume_mount_map));
      ASSERT_THAT(volume_mount_map, ::testing::UnorderedElementsAreArray(
                                        expected_volume_mount_map));
      ASSERT_TRUE(platform_.GetMountsBySourcePrefix(
          GetDmcryptUserCacheDirectory(obfuscated_username), &cache_mount_map));
      ASSERT_THAT(cache_mount_map, ::testing::UnorderedElementsAreArray(
                                       expected_cache_mount_map));
    }
  }

  void CheckTrackingXattr(const std::string& username) {
    const std::string obfuscated_username =
        brillo::cryptohome::home::SanitizeUserName(username);
    const base::FilePath mount_point =
        GetUserMountDirectory(obfuscated_username);

    std::string result;
    ASSERT_TRUE(platform_.GetExtendedFileAttributeAsString(
        mount_point.Append(kRootHomeSuffix), kTrackedDirectoryNameAttribute,
        &result));
    ASSERT_THAT(result, Eq(kRootHomeSuffix));

    ASSERT_TRUE(platform_.GetExtendedFileAttributeAsString(
        mount_point.Append(kUserHomeSuffix), kTrackedDirectoryNameAttribute,
        &result));
    ASSERT_THAT(result, Eq(kUserHomeSuffix));

    ASSERT_TRUE(platform_.GetExtendedFileAttributeAsString(
        mount_point.Append(kUserHomeSuffix).Append(kGCacheDir),
        kTrackedDirectoryNameAttribute, &result));
    ASSERT_THAT(result, Eq(kGCacheDir));

    ASSERT_TRUE(platform_.GetExtendedFileAttributeAsString(
        mount_point.Append(kUserHomeSuffix)
            .Append(kGCacheDir)
            .Append(kGCacheVersion2Dir),
        kTrackedDirectoryNameAttribute, &result));
    ASSERT_THAT(result, Eq(kGCacheVersion2Dir));

    ASSERT_TRUE(platform_.GetExtendedFileAttributeAsString(
        mount_point.Append(kUserHomeSuffix).Append(kCacheDir),
        kTrackedDirectoryNameAttribute, &result));
    ASSERT_THAT(result, Eq(kCacheDir));

    ASSERT_TRUE(platform_.GetExtendedFileAttributeAsString(
        mount_point.Append(kUserHomeSuffix).Append(kDownloadsDir),
        kTrackedDirectoryNameAttribute, &result));
    ASSERT_THAT(result, Eq(kDownloadsDir));

    ASSERT_TRUE(platform_.GetExtendedFileAttributeAsString(
        mount_point.Append(kUserHomeSuffix).Append(kMyFilesDir),
        kTrackedDirectoryNameAttribute, &result));
    ASSERT_THAT(result, Eq(kMyFilesDir));

    ASSERT_TRUE(platform_.GetExtendedFileAttributeAsString(
        mount_point.Append(kUserHomeSuffix)
            .Append(kMyFilesDir)
            .Append(kDownloadsDir),
        kTrackedDirectoryNameAttribute, &result));
    ASSERT_THAT(result, Eq(kDownloadsDir));
  }
};

TEST_F(PersistentSystemTest, MountOrdering) {
  // Checks that mounts made with MountAndPush/BindAndPush are undone in the
  // right order. We mock everything here, so we can isolate testing of the
  // ordering only.
  // TODO(dlunev): once mount_helper is refactored, change this test to be able
  // to live within an anonymous namespace.
  SetHomedir(kUser);
  MountHelper mnt_helper(true /*legacy_mount*/, true /* bind_mount_downloads */,
                         &platform_);

  FilePath src("/src");
  FilePath dest0("/dest/foo");
  FilePath dest1("/dest/bar");
  FilePath dest2("/dest/baz");
  {
    InSequence sequence;
    EXPECT_CALL(platform_,
                Mount(src, dest0, _, kDefaultMountFlags | MS_NOSYMFOLLOW, _))
        .WillOnce(Return(true));
    EXPECT_CALL(platform_, Bind(src, dest1, _, true)).WillOnce(Return(true));
    EXPECT_CALL(platform_,
                Mount(src, dest2, _, kDefaultMountFlags | MS_NOSYMFOLLOW, _))
        .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(mnt_helper.MountAndPush(src, dest0, "", ""));
    EXPECT_TRUE(mnt_helper.BindAndPush(src, dest1, RemountOption::kShared));
    EXPECT_TRUE(mnt_helper.MountAndPush(src, dest2, "", ""));
    mnt_helper.UnmountAll();
  }
}

namespace {

TEST_F(PersistentSystemTest, BindDownloads) {
  // Make sure that the flag to bind downloads is honoured and the file
  // migration happens to `user/Downloads`.
  const std::string kContent{"some_content"};
  const base::FilePath kFile{"some_file"};
  const FileSystemKeyset keyset = FileSystemKeyset::CreateRandom();

  SetHomedir(kUser);
  MountHelper mnt_helper(true /*legacy_mount*/, true /* bind_mount_downloads */,
                         &platform_);

  ASSERT_THAT(
      mnt_helper.PerformMount(MountType::DIR_CRYPTO, kUser,
                              SecureBlobToHex(keyset.KeyReference().fek_sig),
                              SecureBlobToHex(keyset.KeyReference().fnek_sig)),
      Eq(MOUNT_ERROR_NONE));
  VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/true);

  mnt_helper.UnmountAll();
  // TODO(dlunev): figure out how to properly abstract the unmount on dircrypto
  // VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/false);

  const std::string obfuscated_username =
      brillo::cryptohome::home::SanitizeUserName(kUser);
  const base::FilePath dircrypto_mount_point =
      GetUserMountDirectory(obfuscated_username);

  ASSERT_TRUE(
      platform_.WriteStringToFile(dircrypto_mount_point.Append(kUserHomeSuffix)
                                      .Append(kMyFilesDir)
                                      .Append(kDownloadsDir)
                                      .Append(kFile),
                                  kContent));

  ASSERT_THAT(
      mnt_helper.PerformMount(MountType::DIR_CRYPTO, kUser,
                              SecureBlobToHex(keyset.KeyReference().fek_sig),
                              SecureBlobToHex(keyset.KeyReference().fnek_sig)),
      Eq(MOUNT_ERROR_NONE));
  VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/true);

  mnt_helper.UnmountAll();
  // TODO(dlunev): figure out how to properly abstract the unmount on dircrypto
  // VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/false);

  // The file should migrate to user/Downloads
  ASSERT_FALSE(
      platform_.FileExists(dircrypto_mount_point.Append(kUserHomeSuffix)
                               .Append(kMyFilesDir)
                               .Append(kDownloadsDir)
                               .Append(kFile)));
  std::string result;
  ASSERT_TRUE(
      platform_.ReadFileToString(dircrypto_mount_point.Append(kUserHomeSuffix)
                                     .Append(kDownloadsDir)
                                     .Append(kFile),
                                 &result));
  ASSERT_THAT(result, kContent);
}

TEST_F(PersistentSystemTest, NoBindDownloads) {
  // Make sure that the flag to bind downloads is honoured and the file
  // migration happens to `user/MyFiles/Downloads`
  const std::string kContent{"some_content"};
  const base::FilePath kFile{"some_file"};
  const FileSystemKeyset keyset = FileSystemKeyset::CreateRandom();

  SetHomedir(kUser);
  MountHelper mnt_helper(true /*legacy_mount*/,
                         false /* bind_mount_downloads */, &platform_);

  ASSERT_THAT(
      mnt_helper.PerformMount(MountType::DIR_CRYPTO, kUser,
                              SecureBlobToHex(keyset.KeyReference().fek_sig),
                              SecureBlobToHex(keyset.KeyReference().fnek_sig)),
      Eq(MOUNT_ERROR_NONE));
  VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/true,
           /*downloads_bind_mount=*/false);

  mnt_helper.UnmountAll();
  // TODO(dlunev): figure out how to properly abstract the unmount on dircrypto
  // VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/false);

  const std::string obfuscated_username =
      brillo::cryptohome::home::SanitizeUserName(kUser);
  const base::FilePath dircrypto_mount_point =
      GetUserMountDirectory(obfuscated_username);

  ASSERT_TRUE(
      platform_.WriteStringToFile(dircrypto_mount_point.Append(kUserHomeSuffix)
                                      .Append(kDownloadsDir)
                                      .Append(kFile),
                                  kContent));

  ASSERT_THAT(
      mnt_helper.PerformMount(MountType::DIR_CRYPTO, kUser,
                              SecureBlobToHex(keyset.KeyReference().fek_sig),
                              SecureBlobToHex(keyset.KeyReference().fnek_sig)),
      Eq(MOUNT_ERROR_NONE));
  VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/true,
           /*downloads_bind_mount=*/false);

  mnt_helper.UnmountAll();
  // TODO(dlunev): figure out how to properly abstract the unmount on dircrypto
  // VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/false);

  // The file should migrate to user/MyFiles/Downloads
  ASSERT_FALSE(
      platform_.FileExists(dircrypto_mount_point.Append(kUserHomeSuffix)
                               .Append(kDownloadsDir)
                               .Append(kFile)));
  std::string result;
  ASSERT_TRUE(
      platform_.ReadFileToString(dircrypto_mount_point.Append(kUserHomeSuffix)
                                     .Append(kMyFilesDir)
                                     .Append(kDownloadsDir)
                                     .Append(kFile),
                                 &result));
  ASSERT_THAT(result, kContent);
}

TEST_F(PersistentSystemTest, IsFirstMountComplete_False) {
  const base::FilePath kSkelFile{"skel_file"};
  const std::string kSkelFileContent{"skel_content"};
  const FileSystemKeyset keyset = FileSystemKeyset::CreateRandom();
  const std::string obfuscated_username =
      brillo::cryptohome::home::SanitizeUserName(kUser);

  SetHomedir(kUser);
  MountHelper mnt_helper(true /*legacy_mount*/,
                         false /* bind_mount_downloads */, &platform_);

  ASSERT_THAT(
      mnt_helper.PerformMount(MountType::DIR_CRYPTO, kUser,
                              SecureBlobToHex(keyset.KeyReference().fek_sig),
                              SecureBlobToHex(keyset.KeyReference().fnek_sig)),
      Eq(MOUNT_ERROR_NONE));
  VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/true,
           /*downloads_bind_mount=*/false);

  mnt_helper.UnmountAll();
  // TODO(dlunev): figure out how to properly abstract the unmount on dircrypto
  // VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/false);

  // Add a file to skel dir.
  ASSERT_TRUE(platform_.WriteStringToFile(
      base::FilePath(kEtcSkel).Append(kSkelFile), kSkelFileContent));

  // No new files in the vault, so the freshly added skel file should be added.

  ASSERT_THAT(
      mnt_helper.PerformMount(MountType::DIR_CRYPTO, kUser,
                              SecureBlobToHex(keyset.KeyReference().fek_sig),
                              SecureBlobToHex(keyset.KeyReference().fnek_sig)),
      Eq(MOUNT_ERROR_NONE));
  VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/true,
           /*downloads_bind_mount=*/false);
  ASSERT_TRUE(platform_.FileExists(GetUserMountDirectory(obfuscated_username)
                                       .Append(kUserHomeSuffix)
                                       .Append(kSkelFile)));

  mnt_helper.UnmountAll();
  // TODO(dlunev): figure out how to properly abstract the unmount on dircrypto
  // VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/false);
}

TEST_F(PersistentSystemTest, IsFirstMountComplete_True) {
  const base::FilePath kSkelFile{"skel_file"};
  const std::string kSkelFileContent{"skel_content"};
  const base::FilePath kVaultFile{"vault_file"};
  const std::string kVaultFileContent{"vault_content"};
  const FileSystemKeyset keyset = FileSystemKeyset::CreateRandom();
  const std::string obfuscated_username =
      brillo::cryptohome::home::SanitizeUserName(kUser);

  SetHomedir(kUser);
  MountHelper mnt_helper(true /*legacy_mount*/,
                         false /* bind_mount_downloads */, &platform_);

  ASSERT_THAT(
      mnt_helper.PerformMount(MountType::DIR_CRYPTO, kUser,
                              SecureBlobToHex(keyset.KeyReference().fek_sig),
                              SecureBlobToHex(keyset.KeyReference().fnek_sig)),
      Eq(MOUNT_ERROR_NONE));
  VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/true,
           /*downloads_bind_mount=*/false);
  // Add a file to vault.
  ASSERT_TRUE(
      platform_.WriteStringToFile(GetUserMountDirectory(obfuscated_username)
                                      .Append(kUserHomeSuffix)
                                      .Append(kVaultFile),
                                  kVaultFileContent));

  mnt_helper.UnmountAll();
  // TODO(dlunev): figure out how to properly abstract the unmount on dircrypto
  // VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/false);

  // Add a file to skel dir.
  ASSERT_TRUE(platform_.WriteStringToFile(
      base::FilePath(kEtcSkel).Append(kSkelFile), kSkelFileContent));

  // Vault has a new file that is not a skel-copied file and not one of the
  // initial directories, thus we skip copying Skel over again.

  ASSERT_THAT(
      mnt_helper.PerformMount(MountType::DIR_CRYPTO, kUser,
                              SecureBlobToHex(keyset.KeyReference().fek_sig),
                              SecureBlobToHex(keyset.KeyReference().fnek_sig)),
      Eq(MOUNT_ERROR_NONE));
  VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/true,
           /*downloads_bind_mount=*/false);
  ASSERT_FALSE(platform_.FileExists(GetUserMountDirectory(obfuscated_username)
                                        .Append(kUserHomeSuffix)
                                        .Append(kSkelFile)));

  mnt_helper.UnmountAll();
  // TODO(dlunev): figure out how to properly abstract the unmount on dircrypto
  // VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/false);
}

// For Dmcrypt we test only mount part, without container. In fact, we should do
// the same for all and rely on the vault container to setup things properly and
// uniformly.
TEST_F(PersistentSystemTest, Dmcrypt_MountUnmount) {
  const FileSystemKeyset keyset = FileSystemKeyset::CreateRandom();

  SetDmcryptPrereqs(kUser);
  MountHelper mnt_helper(true /*legacy_mount*/, true /* bind_mount_downloads */,
                         &platform_);

  ASSERT_THAT(
      mnt_helper.PerformMount(MountType::DMCRYPT, kUser,
                              SecureBlobToHex(keyset.KeyReference().fek_sig),
                              SecureBlobToHex(keyset.KeyReference().fnek_sig)),
      Eq(MOUNT_ERROR_NONE));
  VerifyFS(kUser, MountType::DMCRYPT, /*expect_present=*/true);

  mnt_helper.UnmountAll();
  VerifyFS(kUser, MountType::DMCRYPT, /*expect_present=*/false);
}

TEST_F(PersistentSystemTest, Ecryptfs_MountPristineTouchFileUnmountMountAgain) {
  // Verify mount and unmount of ecryptfs vault and file preservation.
  const std::string kContent{"some_content"};
  const base::FilePath kFile{"some_file"};
  const FileSystemKeyset keyset = FileSystemKeyset::CreateRandom();
  const CryptohomeVault::Options options = {
      .force_type = EncryptedContainerType::kEcryptfs,
  };

  MockPreclearKeyring(/*success=*/true);
  ASSERT_THAT(mount_->MountCryptohome(kUser, keyset, options),
              Eq(MOUNT_ERROR_NONE));
  VerifyFS(kUser, MountType::ECRYPTFS, /*expect_present=*/true);

  ASSERT_TRUE(platform_.WriteStringToFile(
      base::FilePath(kHomeChronosUser).Append(kFile), kContent));

  ASSERT_TRUE(mount_->UnmountCryptohome());
  VerifyFS(kUser, MountType::ECRYPTFS, /*expect_present=*/false);

  ASSERT_FALSE(
      platform_.FileExists(base::FilePath(kHomeChronosUser).Append(kFile)));

  MockPreclearKeyring(/*success=*/true);
  ASSERT_THAT(mount_->MountCryptohome(kUser, keyset, options),
              Eq(MOUNT_ERROR_NONE));
  VerifyFS(kUser, MountType::ECRYPTFS, /*expect_present=*/true);

  std::string result;
  ASSERT_TRUE(platform_.ReadFileToString(
      base::FilePath(kHomeChronosUser).Append(kFile), &result));
  ASSERT_THAT(result, kContent);

  ASSERT_TRUE(mount_->UnmountCryptohome());
  VerifyFS(kUser, MountType::ECRYPTFS, /*expect_present=*/false);
}

// TODO(dlunev): Add V2 policy test.
TEST_F(PersistentSystemTest,
       Dircrypto_MountPristineTouchFileUnmountMountAgain) {
  // Verify mount and unmount of fsrypt vault and file preservation.
  const std::string kContent{"some_content"};
  const base::FilePath kFile{"some_file"};
  const FileSystemKeyset keyset = FileSystemKeyset::CreateRandom();
  const CryptohomeVault::Options options = {
      .force_type = EncryptedContainerType::kFscrypt,
  };

  MockPreclearKeyring(/*success=*/true);
  MockDircryptoKeyringSetup(kUser, keyset, /*existing_dir=*/false,
                            /*success=*/true);
  ASSERT_THAT(mount_->MountCryptohome(kUser, keyset, options),
              Eq(MOUNT_ERROR_NONE));
  VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/true);

  ASSERT_TRUE(platform_.WriteStringToFile(
      base::FilePath(kHomeChronosUser).Append(kFile), kContent));

  ASSERT_TRUE(mount_->UnmountCryptohome());
  // TODO(dlunev): figure out how to properly abstract the unmount on dircrypto
  // VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/false);

  // ASSERT_FALSE(
  // platform_.FileExists(base::FilePath(kHomeChronosUser).Append(kFile)));

  MockPreclearKeyring(/*success=*/true);
  MockDircryptoKeyringSetup(kUser, keyset, /*existing_dir=*/true,
                            /*success=*/true);
  ASSERT_THAT(mount_->MountCryptohome(kUser, keyset, options),
              Eq(MOUNT_ERROR_NONE));
  VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/true);

  std::string result;
  ASSERT_TRUE(platform_.ReadFileToString(
      base::FilePath(kHomeChronosUser).Append(kFile), &result));
  ASSERT_THAT(result, kContent);

  ASSERT_TRUE(mount_->UnmountCryptohome());
  // TODO(dlunev): figure out how to properly abstract the unmount on dircrypto
  // VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/false);
}

TEST_F(PersistentSystemTest, NoEcryptfsMountWhenForcedDircrypto) {
  // Verify force_dircrypto flag prohibits ecryptfs mounts.
  const FileSystemKeyset keyset = FileSystemKeyset::CreateRandom();
  MountError error = MOUNT_ERROR_NONE;

  CryptohomeVault::Options options = {
      .force_type = EncryptedContainerType::kEcryptfs,
  };

  MockPreclearKeyring(/*success=*/true);
  ASSERT_THAT(mount_->MountCryptohome(kUser, keyset, options), MOUNT_ERROR_NONE)
      << "ERROR: " << error;
  VerifyFS(kUser, MountType::ECRYPTFS, /*expect_present=*/true);

  ASSERT_TRUE(mount_->UnmountCryptohome());
  VerifyFS(kUser, MountType::ECRYPTFS, /*expect_present=*/false);

  options = {
      .block_ecryptfs = true,
  };
  ASSERT_THAT(mount_->MountCryptohome(kUser, keyset, options),
              Eq(MOUNT_ERROR_OLD_ENCRYPTION));
}

TEST_F(PersistentSystemTest, MigrateEcryptfsToFscrypt) {
  // Verify ecryptfs->dircrypto migration.
  const std::string kContent{"some_content"};
  const base::FilePath kFile{"some_file"};
  const FileSystemKeyset keyset = FileSystemKeyset::CreateRandom();

  // Create ecryptfs
  CryptohomeVault::Options options = {
      .force_type = EncryptedContainerType::kEcryptfs,
  };
  MockPreclearKeyring(/*success=*/true);
  ASSERT_THAT(mount_->MountCryptohome(kUser, keyset, options),
              MOUNT_ERROR_NONE);

  ASSERT_TRUE(platform_.WriteStringToFile(
      base::FilePath(kHomeChronosUser).Append(kFile), kContent));

  ASSERT_TRUE(mount_->UnmountCryptohome());

  // Start migration
  options = {
      .migrate = true,
  };
  MockPreclearKeyring(/*success=*/true);
  MockDircryptoKeyringSetup(kUser, keyset, /*existing_dir=*/false,
                            /*success=*/true);
  ASSERT_THAT(mount_->MountCryptohome(kUser, keyset, options),
              MOUNT_ERROR_NONE);

  ASSERT_TRUE(mount_->UnmountCryptohome());

  // We can't mount in progress migration regularly
  options = {};
  MockDircryptoPolicy(kUser, /*existing_dir=*/true);
  ASSERT_THAT(mount_->MountCryptohome(kUser, keyset, options),
              MOUNT_ERROR_PREVIOUS_MIGRATION_INCOMPLETE);

  // We haven't migrated anything really, so we are in continuation.
  // Create a new mount object, because interface rises a flag prohibiting
  // migration on unmount.
  // TODO(dlunev): fix the behaviour.
  scoped_refptr<Mount> new_mount =
      new Mount(&platform_, homedirs_.get(), /*legacy_mount=*/true,
                /*bind_mount_downloads=*/true, /*use_local_mounter=*/true);
  options = {
      .migrate = true,
  };
  MockPreclearKeyring(/*success=*/true);
  MockDircryptoKeyringSetup(kUser, keyset, /*existing_dir=*/true,
                            /*success=*/true);
  ASSERT_THAT(new_mount->MountCryptohome(kUser, keyset, options),
              MOUNT_ERROR_NONE);

  ASSERT_TRUE(new_mount->MigrateEncryption(
      base::BindRepeating(
          [](const user_data_auth::DircryptoMigrationProgress& unused) {}),
      MigrationType::FULL));
  // TODO(dlunev): figure out how to properly abstract the unmount on dircrypto
  // VerifyFS(kUser, MountType::ECRYPTFS, /*expect_present=*/false);
  // VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/false);

  // "vault" should be gone.
  const std::string obfuscated_username =
      brillo::cryptohome::home::SanitizeUserName(kUser);
  const base::FilePath ecryptfs_vault =
      GetEcryptfsUserVaultPath(obfuscated_username);
  ASSERT_FALSE(platform_.DirectoryExists(ecryptfs_vault));

  // Now we should be able to mount with dircrypto.
  options = {
      .force_type = EncryptedContainerType::kFscrypt,
  };
  MockPreclearKeyring(/*success=*/true);
  MockDircryptoKeyringSetup(kUser, keyset, /*existing_dir=*/true,
                            /*success=*/true);
  ASSERT_THAT(mount_->MountCryptohome(kUser, keyset, options),
              MOUNT_ERROR_NONE);
  VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/true);

  std::string result;
  ASSERT_TRUE(platform_.ReadFileToString(
      base::FilePath(kHomeChronosUser).Append(kFile), &result));
  ASSERT_THAT(result, kContent);

  ASSERT_TRUE(mount_->UnmountCryptohome());
  // TODO(dlunev): figure out how to properly abstract the unmount on dircrypto
  // VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/false);
}

#if USE_LVM_STATEFUL_PARTITION

TEST_F(PersistentSystemTest, MigrateEcryptfsToDmcrypt) {
  // Verify ecryptfs->dircrypto migration.
  const std::string kContent{"some_content"};
  const base::FilePath kFile{"some_file"};
  const FileSystemKeyset keyset = FileSystemKeyset::CreateRandom();

  homedirs_->set_lvm_migration_enabled(true);

  // Create ecryptfs
  CryptohomeVault::Options options = {
      .force_type = EncryptedContainerType::kEcryptfs,
  };
  MockPreclearKeyring(/*success=*/true);
  ASSERT_THAT(mount_->MountCryptohome(kUser, keyset, options),
              MOUNT_ERROR_NONE);

  ASSERT_TRUE(platform_.WriteStringToFile(
      base::FilePath(kHomeChronosUser).Append(kFile), kContent));

  ASSERT_TRUE(mount_->UnmountCryptohome());

  // Start migration
  // Create a new mount object, because interface rises a flag prohibiting
  // migration on unmount.
  // TODO(dlunev): fix the behaviour.
  scoped_refptr<Mount> new_mount =
      new Mount(&platform_, homedirs_.get(), /*legacy_mount=*/true,
                /*bind_mount_downloads=*/true, /*use_local_mounter=*/true);
  options = {
      .migrate = true,
  };
  MockPreclearKeyring(/*success=*/true);
  SetDmcryptPrereqs(kUser);
  ASSERT_THAT(new_mount->MountCryptohome(kUser, keyset, options),
              MOUNT_ERROR_NONE);

  ASSERT_TRUE(new_mount->MigrateEncryption(
      base::BindRepeating(
          [](const user_data_auth::DircryptoMigrationProgress& unused) {}),
      MigrationType::FULL));
  VerifyFS(kUser, MountType::ECRYPTFS, /*expect_present=*/false);
  VerifyFS(kUser, MountType::DMCRYPT, /*expect_present=*/false);

  // "vault" should be gone.
  const std::string obfuscated_username =
      brillo::cryptohome::home::SanitizeUserName(kUser);
  const base::FilePath ecryptfs_vault =
      GetEcryptfsUserVaultPath(obfuscated_username);
  ASSERT_FALSE(platform_.DirectoryExists(ecryptfs_vault));

  // Now we should be able to mount with dircrypto.
  options = {
      .force_type = EncryptedContainerType::kDmcrypt,
  };
  MockPreclearKeyring(/*success=*/true);
  ASSERT_THAT(mount_->MountCryptohome(kUser, keyset, options),
              MOUNT_ERROR_NONE);
  VerifyFS(kUser, MountType::DMCRYPT, /*expect_present=*/true);

  std::string result;
  ASSERT_TRUE(platform_.ReadFileToString(
      base::FilePath(kHomeChronosUser).Append(kFile), &result));
  ASSERT_THAT(result, kContent);

  ASSERT_TRUE(mount_->UnmountCryptohome());
  VerifyFS(kUser, MountType::DMCRYPT, /*expect_present=*/false);
}

TEST_F(PersistentSystemTest, MigrateFscryptToDmcrypt) {
  // Verify ecryptfs->dircrypto migration.
  const std::string kContent{"some_content"};
  const base::FilePath kFile{"some_file"};
  const FileSystemKeyset keyset = FileSystemKeyset::CreateRandom();

  homedirs_->set_lvm_migration_enabled(true);

  // Create ecryptfs
  CryptohomeVault::Options options = {
      .force_type = EncryptedContainerType::kFscrypt,
  };
  MockPreclearKeyring(/*success=*/true);
  MockDircryptoKeyringSetup(kUser, keyset, /*existing_dir=*/false,
                            /*success=*/true);
  ASSERT_THAT(mount_->MountCryptohome(kUser, keyset, options),
              MOUNT_ERROR_NONE);

  ASSERT_TRUE(platform_.WriteStringToFile(
      base::FilePath(kHomeChronosUser).Append(kFile), kContent));

  ASSERT_TRUE(mount_->UnmountCryptohome());

  // Start migration
  // Create a new mount object, because interface rises a flag prohibiting
  // migration on unmount.
  // TODO(dlunev): fix the behaviour.
  scoped_refptr<Mount> new_mount =
      new Mount(&platform_, homedirs_.get(), /*legacy_mount=*/true,
                /*bind_mount_downloads=*/true, /*use_local_mounter=*/true);
  options = {
      .migrate = true,
  };
  MockPreclearKeyring(/*success=*/true);
  MockDircryptoKeyringSetup(kUser, keyset, /*existing_dir=*/true,
                            /*success=*/true);
  SetDmcryptPrereqs(kUser);
  ASSERT_THAT(new_mount->MountCryptohome(kUser, keyset, options),
              MOUNT_ERROR_NONE);

  ASSERT_TRUE(new_mount->MigrateEncryption(
      base::BindRepeating(
          [](const user_data_auth::DircryptoMigrationProgress& unused) {}),
      MigrationType::FULL));
  // VerifyFS(kUser, MountType::DIR_CRYPTO, /*expect_present=*/false);
  VerifyFS(kUser, MountType::DMCRYPT, /*expect_present=*/false);

  // "vault" should be gone.
  const std::string obfuscated_username =
      brillo::cryptohome::home::SanitizeUserName(kUser);
  const base::FilePath ecryptfs_vault =
      GetEcryptfsUserVaultPath(obfuscated_username);
  ASSERT_FALSE(platform_.DirectoryExists(ecryptfs_vault));

  // Now we should be able to mount with dircrypto.
  options = {
      .force_type = EncryptedContainerType::kDmcrypt,
  };
  MockPreclearKeyring(/*success=*/true);
  ASSERT_THAT(mount_->MountCryptohome(kUser, keyset, options),
              MOUNT_ERROR_NONE);
  VerifyFS(kUser, MountType::DMCRYPT, /*expect_present=*/true);

  std::string result;
  ASSERT_TRUE(platform_.ReadFileToString(
      base::FilePath(kHomeChronosUser).Append(kFile), &result));
  ASSERT_THAT(result, kContent);

  ASSERT_TRUE(mount_->UnmountCryptohome());
  VerifyFS(kUser, MountType::DMCRYPT, /*expect_present=*/false);
}

#endif  // USE_LVM_STATEFUL_PARTITION

}  // namespace

class EphemeralSystemTest : public ::testing::Test {
 public:
  EphemeralSystemTest() : crypto_(&platform_) {}

  void SetUp() {
    ASSERT_NO_FATAL_FAILURE(PrepareDirectoryStructure(&platform_));
    std::unique_ptr<EncryptedContainerFactory> container_factory =
        std::make_unique<EncryptedContainerFactory>(
            &platform_, std::make_unique<FakeKeyring>(),
            std::make_unique<FakeBackingDeviceFactory>(&platform_));
    homedirs_ = std::make_unique<HomeDirs>(
        &platform_, std::make_unique<policy::PolicyProvider>(),
        base::BindRepeating([](const std::string& unused) {}),
        std::make_unique<CryptohomeVaultFactory>(&platform_,
                                                 std::move(container_factory)));

    mount_ =
        new Mount(&platform_, homedirs_.get(), /*legacy_mount=*/true,
                  /*bind_mount_downloads=*/true, /*use_local_mounter=*/true);

    SetupVFSMock();
  }

 protected:
  // Protected for trivial access.
  NiceMock<MockPlatform> platform_;
  Crypto crypto_;
  std::unique_ptr<HomeDirs> homedirs_;
  scoped_refptr<Mount> mount_;
  struct statvfs ephemeral_statvfs_;

  base::FilePath EphemeralBackingFile(const std::string& username) {
    const std::string obfuscated_username =
        brillo::cryptohome::home::SanitizeUserName(username);
    return base::FilePath(kEphemeralCryptohomeDir)
        .Append(kSparseFileDir)
        .Append(obfuscated_username);
  }

  base::FilePath EphemeralMountPoint(const std::string& username) {
    const std::string obfuscated_username =
        brillo::cryptohome::home::SanitizeUserName(username);
    return base::FilePath(kEphemeralCryptohomeDir)
        .Append(kEphemeralMountDir)
        .Append(obfuscated_username);
  }

  void VerifyFS(const std::string& username,
                bool expect_present) {
    CheckLoopDev(username, expect_present);
    ASSERT_NO_FATAL_FAILURE(CheckRootAndDaemonStoreMounts(
        &platform_, username, EphemeralMountPoint(username), expect_present));
    ASSERT_NO_FATAL_FAILURE(CheckUserMountPoints(
        &platform_, username, EphemeralMountPoint(username), expect_present));

    const std::vector<base::FilePath> user_vault_and_mounts{
        EphemeralMountPoint(username).Append(kUserHomeSuffix),
        base::FilePath(kHomeChronosUser),
        brillo::cryptohome::home::GetUserPath(username),
        ChronosHashPath(username),
    };

    for (const auto& base_path : user_vault_and_mounts) {
      ASSERT_NO_FATAL_FAILURE(
          CheckUserMountPaths(&platform_, base_path, expect_present));
      ASSERT_NO_FATAL_FAILURE(CheckSkel(&platform_, base_path, expect_present));
    }
  }

  base::FilePath GetLoopDevice() {
    return platform_.GetLoopDeviceManager()
        ->GetAttachedDeviceByName("ephemeral")
        ->GetDevicePath();
  }

 private:
  void CheckLoopDev(const std::string& username,
                    bool expect_present) {
    const base::FilePath ephemeral_backing_file =
        EphemeralBackingFile(username);
    const base::FilePath ephemeral_mount_point = EphemeralMountPoint(username);

    ASSERT_THAT(platform_.FileExists(ephemeral_backing_file), expect_present);
    ASSERT_THAT(platform_.DirectoryExists(ephemeral_mount_point),
                expect_present);
    ASSERT_THAT(platform_.IsDirectoryMounted(ephemeral_mount_point),
                expect_present);
    if (expect_present) {
      const std::multimap<const base::FilePath, const base::FilePath>
          expected_ephemeral_mount_map{
              {GetLoopDevice(), ephemeral_mount_point},
          };
      std::multimap<const base::FilePath, const base::FilePath>
          ephemeral_mount_map;
      ASSERT_TRUE(platform_.GetMountsBySourcePrefix(GetLoopDevice(),
                                                    &ephemeral_mount_map));
      ASSERT_THAT(ephemeral_mount_map, ::testing::UnorderedElementsAreArray(
                                           expected_ephemeral_mount_map));
    }
  }

  void SetupVFSMock() {
    ephemeral_statvfs_ = {0};
    ephemeral_statvfs_.f_frsize = kEphemeralVFSFragmentSize;
    ephemeral_statvfs_.f_blocks = kEphemeralVFSSize / kEphemeralVFSFragmentSize;

    ON_CALL(platform_, StatVFS(base::FilePath(kEphemeralCryptohomeDir), _))
        .WillByDefault(
            DoAll(SetArgPointee<1>(ephemeral_statvfs_), Return(true)));
  }
};

namespace {

TEST_F(EphemeralSystemTest, EphemeralMount) {
  EXPECT_CALL(platform_, FormatExt4(Property(&base::FilePath::value,
                                             StartsWith(kDevLoopPrefix)),
                                    _, _))
      .WillOnce(Return(true));
  EXPECT_CALL(platform_, SetSELinuxContext(EphemeralMountPoint(kUser), _))
      .WillOnce(Return(true));

  ASSERT_THAT(mount_->MountEphemeralCryptohome(kUser), MOUNT_ERROR_NONE);

  VerifyFS(kUser, /*expect_present=*/true);

  ASSERT_TRUE(mount_->UnmountCryptohome());

  VerifyFS(kUser, /*expect_present=*/false);
}

TEST_F(EphemeralSystemTest, EpmeneralMount_VFSFailure) {
  // Checks the case when ephemeral statvfs call fails.
  ON_CALL(platform_, StatVFS(base::FilePath(kEphemeralCryptohomeDir), _))
      .WillByDefault(Return(false));

  ASSERT_THAT(mount_->MountEphemeralCryptohome(kUser), MOUNT_ERROR_FATAL);

  VerifyFS(kUser, /*expect_present=*/false);
}

TEST_F(EphemeralSystemTest, EphemeralMount_CreateSparseDirFailure) {
  // Checks the case when directory for ephemeral sparse files fails to be
  // created.
  EXPECT_CALL(platform_, CreateDirectory(EphemeralBackingFile(kUser).DirName()))
      .WillOnce(Return(false));

  ASSERT_THAT(mount_->MountEphemeralCryptohome(kUser),
              MOUNT_ERROR_KEYRING_FAILED);

  VerifyFS(kUser, /*expect_present=*/false);
}

TEST_F(EphemeralSystemTest, EphemeralMount_CreateSparseFailure) {
  // Checks the case when ephemeral sparse file fails to create.
  EXPECT_CALL(platform_, CreateSparseFile(EphemeralBackingFile(kUser), _))
      .WillOnce(Return(false));

  ASSERT_THAT(mount_->MountEphemeralCryptohome(kUser),
              MOUNT_ERROR_KEYRING_FAILED);

  VerifyFS(kUser, /*expect_present=*/false);
}

TEST_F(EphemeralSystemTest, EphemeralMount_FormatFailure) {
  // Checks that when ephemeral loop device fails to be formatted, clean up
  // happens appropriately.
  EXPECT_CALL(platform_, FormatExt4(Property(&base::FilePath::value,
                                             StartsWith(kDevLoopPrefix)),
                                    _, _))
      .WillOnce(Return(false));

  ASSERT_THAT(mount_->MountEphemeralCryptohome(kUser),
              MOUNT_ERROR_KEYRING_FAILED);

  VerifyFS(kUser, /*expect_present=*/false);
}

TEST_F(EphemeralSystemTest, EphemeralMount_EnsureUserMountFailure) {
  // Checks that when ephemeral mount fails to ensure mount points, clean up
  // happens appropriately.
  EXPECT_CALL(platform_, FormatExt4(Property(&base::FilePath::value,
                                             StartsWith(kDevLoopPrefix)),
                                    _, _))
      .WillOnce(Return(true));
  EXPECT_CALL(platform_, Mount(Property(&base::FilePath::value,
                                        StartsWith(kDevLoopPrefix)),
                               EphemeralMountPoint(kUser), _, _, _))
      .WillOnce(Return(false));

  ASSERT_THAT(mount_->MountEphemeralCryptohome(kUser), MOUNT_ERROR_FATAL);

  VerifyFS(kUser, /*expect_present=*/false);
}

}  // namespace

}  // namespace cryptohome
