// Copyright 2019 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.

// MountHelper objects carry out mount(2) and unmount(2) operations for a single
// cryptohome mount.

#ifndef CRYPTOHOME_STORAGE_MOUNT_HELPER_H_
#define CRYPTOHOME_STORAGE_MOUNT_HELPER_H_

#include <sys/types.h>

#include <memory>
#include <string>
#include <vector>

#include <base/files/file_path.h>
#include <base/macros.h>
#include <brillo/process/process.h>
#include <brillo/secure_blob.h>
#include <chromeos/dbus/service_constants.h>

#include "cryptohome/credentials.h"
#include "cryptohome/platform.h"
#include "cryptohome/storage/mount_constants.h"
#include "cryptohome/storage/mount_stack.h"

using base::FilePath;

namespace cryptohome {

extern const char kDefaultHomeDir[];
extern const char kEphemeralCryptohomeRootContext[];

// Objects that implement MountHelperInterface can perform mount operations.
// This interface will be used as we transition all cryptohome mounts to be
// performed out-of-process.
class MountHelperInterface {
 public:
  virtual ~MountHelperInterface() {}

  struct Options {
    MountType type = MountType::NONE;
    bool to_migrate_from_ecryptfs = false;
    bool shadow_only = false;
  };

  // Ephemeral mounts cannot be performed twice, so cryptohome needs to be able
  // to check whether an ephemeral mount can be performed.
  virtual bool CanPerformEphemeralMount() const = 0;

  // Returns whether an ephemeral mount has been performed.
  virtual bool MountPerformed() const = 0;

  // Returns whether |path| is currently mounted as part of the ephemeral mount.
  virtual bool IsPathMounted(const base::FilePath& path) const = 0;

  // Carries out an ephemeral mount for user |username|.
  virtual bool PerformEphemeralMount(const std::string& username) = 0;

  // Tears down the existing ephemeral mount.
  virtual bool TearDownEphemeralMount() = 0;

  // Tears down non-ephemeral cryptohome mount.
  virtual void TearDownNonEphemeralMount() = 0;

  // Carries out mount operations for a regular cryptohome.
  virtual bool PerformMount(const Options& mount_opts,
                            const std::string& username,
                            const std::string& fek_signature,
                            const std::string& fnek_signature,
                            bool is_pristine,
                            MountError* error) = 0;
};

class MountHelper : public MountHelperInterface {
 public:
  MountHelper(uid_t uid,
              gid_t gid,
              gid_t access_gid,
              const brillo::SecureBlob& system_salt,
              bool legacy_mount,
              bool bind_mount_downloads,
              Platform* platform)
      : default_uid_(uid),
        default_gid_(gid),
        default_access_gid_(access_gid),
        system_salt_(system_salt),
        legacy_mount_(legacy_mount),
        bind_mount_downloads_(bind_mount_downloads),
        platform_(platform) {}
  MountHelper(const MountHelper&) = delete;
  MountHelper& operator=(const MountHelper&) = delete;

  ~MountHelper() = default;

  // Returns the temporary user path while we're migrating for
  // http://crbug.com/224291.
  static base::FilePath GetNewUserPath(const std::string& username);

  // Returns the path to sparse file used for ephemeral cryptohome for the user.
  static FilePath GetEphemeralSparseFile(
      const std::string& obfuscated_username);

  // Ensures that root and user mountpoints for the specified user are present.
  // Returns false if the mountpoints were not present and could not be created.
  bool EnsureUserMountPoints(const std::string& username) const;

  // Gets the directory to temporarily mount the user's cryptohome at.
  //
  // Parameters
  //   obfuscated_username - Obfuscated username field of the credentials.
  FilePath GetUserTemporaryMountDirectory(
      const std::string& obfuscated_username) const;

  // Creates the tracked subdirectories in a user's cryptohome.
  // If the cryptohome did not have tracked directories, but had them untracked,
  // migrate their contents.
  //
  // Parameters
  //   obfuscated_username - The obfuscated form of the username
  //   type - Mount type: eCryptfs or dircrypto
  bool CreateTrackedSubdirectories(const std::string& obfuscated_username,
                                   const MountType& type) const;

  // Sets up the ecryptfs mount.
  bool SetUpEcryptfsMount(const std::string& obfuscated_username,
                          const std::string& fek_signature,
                          const std::string& fnek_signature,
                          bool should_migrate);

  // Sets up the dircrypto mount.
  void SetUpDircryptoMount(const std::string& obfuscated_username);

  // Carries out eCryptfs/dircrypto mount(2) operations for a regular
  // cryptohome.
  bool PerformMount(const Options& mount_opts,
                    const std::string& username,
                    const std::string& fek_signature,
                    const std::string& fnek_signature,
                    bool is_pristine,
                    MountError* error) override;

  // Carries out dircrypto mount(2) operations for an ephemeral cryptohome.
  // Does not clean up on failure.
  bool PerformEphemeralMount(const std::string& username) override;

  // Tears down an ephemeral cryptohome mount in-process by calling umount(2).
  bool TearDownEphemeralMount() override;

  // Tears down non-ephemeral cryptohome mount in-process by calling umount(2).
  void TearDownNonEphemeralMount() override;

  // Unmounts all mount points.
  // Relies on ForceUnmount() internally; see the caveat listed for it.
  void UnmountAll();

  // Deletes loop device used for ephemeral cryptohome and underlying temporary
  // sparse file.
  bool CleanUpEphemeral();

  // Returns whether an ephemeral mount operation can be performed.
  bool CanPerformEphemeralMount() const override;

  // Returns whether a mount operation has been performed.
  bool MountPerformed() const override;

  // Returns whether |path| is the destination of an existing mount.
  bool IsPathMounted(const base::FilePath& path) const override;

  // Returns a list of paths that have been mounted as part of the mount.
  std::vector<base::FilePath> MountedPaths() const;

 private:
  // Returns the names of all tracked subdirectories.
  static std::vector<base::FilePath> GetTrackedSubdirectories();

  // Returns the mounted userhome path (e.g. /home/.shadow/.../mount/user)
  //
  // Parameters
  //   obfuscated_username - Obfuscated username field of the credentials.
  FilePath GetMountedUserHomePath(const std::string& obfuscated_username) const;

  // Returns the mounted roothome path (e.g. /home/.shadow/.../mount/root)
  //
  // Parameters
  //   obfuscated_username - Obfuscated username field of the credentials.
  FilePath GetMountedRootHomePath(const std::string& obfuscated_username) const;

  // Mounts a mount point and pushes it to the mount stack.
  // Returns true if the mount succeeds, false otherwise.
  //
  // Parameters
  //   src - Path to mount from
  //   dest - Path to mount to
  //   type - Filesystem type to mount with
  //   options - Filesystem options to supply
  bool MountAndPush(const base::FilePath& src,
                    const base::FilePath& dest,
                    const std::string& type,
                    const std::string& options);

  // Binds a mount point, remembering it for later unmounting.
  // Returns true if the bind succeeds, false otherwise.
  //
  // Parameters
  //   src - Path to bind from
  //   dest - Path to bind to
  //   is_shared - bind mount as MS_SHARED
  bool BindAndPush(const FilePath& src,
                   const FilePath& dest,
                   bool is_shared = false);

  // Bind mounts |user_home|/Downloads to |user_home|/MyFiles/Downloads so Files
  // app can manage MyFiles as user volume instead of just Downloads.
  bool BindMyFilesDownloads(const base::FilePath& user_home);

  // Copies the skeleton directory to the user's cryptohome.
  void CopySkeleton(const FilePath& destination) const;

  // Ensures that a specified directory exists, with all path components but the
  // last one owned by kMountOwnerUid:kMountOwnerGid and the last component
  // owned by desired_uid:desired_gid.
  //
  // Parameters
  //   dir - Directory to check
  //   desired_uid - uid that must own the directory
  //   desired_gid - gid that muts own the directory
  bool EnsureDirHasOwner(const base::FilePath& dir,
                         uid_t desired_uid,
                         gid_t desired_gid) const;

  // Ensures that the |num|th component of |path| is owned by |uid|:|gid| and is
  // a directory.
  bool EnsurePathComponent(const FilePath& path,
                           size_t num,
                           uid_t uid,
                           gid_t gid) const;

  // Ensures that the permissions on every parent of /home/chronos/u-$hash are
  // correct and that they are all directories. Since we're going to bind-mount
  // over the directory, we don't care what the permissions on it are, just that
  // it exists.
  // /home needs to be root:root.
  // /home/chronos needs to be default_uid_:default_gid_.
  bool EnsureNewUserDirExists(const std::string& username) const;

  // Attempts to unmount a mountpoint. If the unmount fails, logs processes with
  // open handles to it and performs a lazy unmount.
  //
  // Parameters
  //   src - Path mounted at |dest|
  //   dest - Mount point to unmount
  void ForceUnmount(const base::FilePath& src, const base::FilePath& dest);

  // Creates subdirectories for the user's cryptohome.
  //
  // Parameters
  //   vault_path - path to create subdirectories under.
  void CreateHomeSubdirectories(const FilePath& vault_path) const;

  // Facilitates migration of files from one directory to another, removing the
  // duplicates.
  void MigrateDirectory(const base::FilePath& dst,
                        const base::FilePath& src) const;

  // Bind-mounts
  //   /home/.shadow/$hash/mount/root/$daemon (*)
  // to
  //   /run/daemon-store/$daemon/$hash
  // for a hardcoded list of $daemon directories.
  //
  // This can be used to make the Cryptohome mount propagate into the daemon's
  // mount namespace. See
  // https://chromium.googlesource.com/chromiumos/docs/+/HEAD/sandboxing.md#securely-mounting-cryptohome-daemon-store-folders
  // for details.
  //
  // (*) Path for a regular mount. The path is different for an ephemeral mount.
  bool MountDaemonStoreDirectories(const FilePath& root_home,
                                   const std::string& obfuscated_username);

  // Sets up bind mounts from |user_home| and |root_home| to
  //   - /home/chronos/user (see MountLegacyHome()),
  //   - /home/chronos/u-<user_hash>,
  //   - /home/user/<user_hash>,
  //   - /home/root/<user_hash> and
  //   - /run/daemon-store/$daemon/<user_hash>
  //     (see MountDaemonStoreDirectories()).
  // The parameters have the same meaning as in MountCryptohome resp.
  // MountEphemeralCryptohomeInner. Returns true if successful, false otherwise.
  bool MountHomesAndDaemonStores(const std::string& username,
                                 const std::string& obfuscated_username,
                                 const FilePath& user_home,
                                 const FilePath& root_home);

  // Mounts the legacy home directory.
  // The legacy home directory is from before multiprofile and is mounted at
  // /home/chronos/user.
  bool MountLegacyHome(const FilePath& from);

  // Creates a loop device formatted as an ext4 partition.
  bool PrepareEphemeralDevice(const std::string& obfuscated_username);

  // Recursively copies directory contents to the destination if the destination
  // file does not exist.  Sets ownership to |default_user_|.
  //
  // Parameters
  //   source - Where to copy files from
  //   destination - Where to copy files to
  void RecursiveCopy(const FilePath& source, const FilePath& destination) const;

  // Sets up a freshly mounted ephemeral cryptohome by adjusting its permissions
  // and populating it with a skeleton directory and file structure.
  bool SetUpEphemeralCryptohome(const FilePath& source_path);

  // Changes the group ownership and permissions on those directories inside
  // the cryptohome that need to be accessible by other system daemons.
  bool SetUpGroupAccess(const FilePath& home_dir) const;

  uid_t default_uid_;
  uid_t default_gid_;
  uid_t default_access_gid_;

  // Stores the global system salt.
  brillo::SecureBlob system_salt_;

  bool legacy_mount_ = true;
  bool bind_mount_downloads_ = true;

  // Stack of mounts (in the mount(2) sense) that have been made.
  MountStack stack_;

  // Tracks loop device used for ephemeral cryptohome.
  // Empty when the device is not present.
  base::FilePath ephemeral_loop_device_;

  // Tracks path to ephemeral cryptohome sparse file.
  // Empty when the file is not created or already deleted.
  base::FilePath ephemeral_file_path_;

  Platform* platform_;  // Un-owned.

  FRIEND_TEST(MountTest, BindMyFilesDownloadsSuccess);
  FRIEND_TEST(MountTest, BindMyFilesDownloadsMissingUserHome);
  FRIEND_TEST(MountTest, BindMyFilesDownloadsMissingDownloads);
  FRIEND_TEST(MountTest, BindMyFilesDownloadsMissingMyFilesDownloads);
  FRIEND_TEST(MountTest, BindMyFilesDownloadsRemoveExistingFiles);
  FRIEND_TEST(MountTest, BindMyFilesDownloadsMoveForgottenFiles);

  FRIEND_TEST(MountTest, CreateTrackedSubdirectories);
  FRIEND_TEST(MountTest, CreateTrackedSubdirectoriesReplaceExistingDir);

  FRIEND_TEST(MountTest, RememberMountOrderingTest);

  FRIEND_TEST(EphemeralNoUserSystemTest, CreateMyFilesDownloads);
  FRIEND_TEST(EphemeralNoUserSystemTest, CreateMyFilesDownloadsAlreadyExists);
};

}  // namespace cryptohome

#endif  // CRYPTOHOME_STORAGE_MOUNT_HELPER_H_
