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

#ifndef CROS_DISKS_FUSE_MOUNTER_H_
#define CROS_DISKS_FUSE_MOUNTER_H_

#include <sys/types.h>

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

#include <base/files/file.h>
#include <base/files/file_path.h>
#include <base/strings/string_piece.h>

#include "cros-disks/metrics.h"
#include "cros-disks/mounter.h"
#include "cros-disks/sandboxed_process.h"
#include "cros-disks/user.h"

namespace brillo {
class ProcessReaper;
}  // namespace brillo

namespace cros_disks {

class Platform;
class Process;
class SandboxedProcess;

// Class for creating instances of SandboxedProcess with appropriate
// configuration.
class FUSESandboxedProcessFactory : public SandboxedProcessFactory {
 public:
  FUSESandboxedProcessFactory(
      const Platform* platform,
      SandboxedExecutable executable,
      OwnerUser run_as,
      bool has_network_access = false,
      std::vector<gid_t> supplementary_groups = {},
      std::optional<base::FilePath> mount_namespace = {});
  ~FUSESandboxedProcessFactory() override;

  // Returns pre-configured sandbox with the most essential set up. Additional
  // per-instance configuration should be done by the caller if needed.
  std::unique_ptr<SandboxedProcess> CreateSandboxedProcess() const override;

  const base::FilePath& executable() const { return executable_; }
  const OwnerUser& run_as() const { return run_as_; }

 private:
  friend class FUSESandboxedProcessFactoryTest;

  bool ConfigureSandbox(SandboxedProcess* sandbox) const;

  const Platform* const platform_;

  // Path to the FUSE daemon executable.
  const base::FilePath executable_;

  // Path to the seccomp policy configuration.
  const std::optional<base::FilePath> seccomp_policy_;

  // UID/GID to run the FUSE daemon as.
  const OwnerUser run_as_;

  // Whether to leave network accessible from the sandbox.
  const bool has_network_access_;

  // Additional groups to associate with the FUSE daemon process.
  const std::vector<gid_t> supplementary_groups_;

  // Path identifying the mount namespace to use.
  const std::optional<base::FilePath> mount_namespace_;
};

// Uprivileged mounting of any FUSE filesystem. Filesystem-specific set up
// and sandboxing is to be done in a subclass.
class FUSEMounter : public Mounter {
 public:
  struct Config {
    bool nosymfollow = true;
    bool read_only = false;
  };

  FUSEMounter(const Platform* platform,
              brillo::ProcessReaper* process_reaper,
              std::string filesystem_type,
              Config config);
  FUSEMounter(const FUSEMounter&) = delete;
  FUSEMounter& operator=(const FUSEMounter&) = delete;
  ~FUSEMounter() override;

  const Platform* platform() const { return platform_; }
  brillo::ProcessReaper* process_reaper() const { return process_reaper_; }

  // Mounter overrides:
  std::unique_ptr<MountPoint> Mount(const std::string& source,
                                    const base::FilePath& target_path,
                                    std::vector<std::string> params,
                                    MountErrorType* error) const final;

 protected:
  // Translates mount app's return codes into errors. The base
  // implementation just assumes any non-zero return code to be a
  // MOUNT_ERROR_MOUNT_PROGRAM_FAILED, but subclasses can implement more
  // elaborate mappings.
  virtual MountErrorType InterpretReturnCode(int return_code) const;

  // Performs necessary set up and makes a SandboxedProcess ready to be
  // launched to serve a mount. The returned instance will have one more
  // last argument added to indicate the FUSE mount path according to
  // fusermount's conventions, so implementation doesn't have to do this,
  // |target_path| is purely informational.
  virtual std::unique_ptr<SandboxedProcess> PrepareSandbox(
      const std::string& source,
      const base::FilePath& target_path,
      std::vector<std::string> params,
      MountErrorType* error) const = 0;

 private:
  // Performs necessary set up and launches FUSE daemon that communicates to
  // FUSE kernel layer via the |fuse_file|. Returns PID of the daemon process.
  pid_t StartDaemon(const base::File& fuse_file,
                    const std::string& source,
                    const base::FilePath& target_path,
                    std::vector<std::string> params,
                    MountErrorType* error) const;

 private:
  const Platform* const platform_;
  brillo::ProcessReaper* const process_reaper_;
  const std::string filesystem_type_;
  const Config config_;
};

// A convenience class to tie FUSE mounter with a sandbox configuration.
class FUSEMounterHelper : public FUSEMounter {
 public:
  FUSEMounterHelper(const Platform* platform,
                    brillo::ProcessReaper* process_reaper,
                    std::string filesystem_type,
                    bool nosymfollow,
                    const SandboxedProcessFactory* sandbox_factory);
  FUSEMounterHelper(const FUSEMounterHelper&) = delete;
  FUSEMounterHelper& operator=(const FUSEMounterHelper&) = delete;
  ~FUSEMounterHelper() override;

 protected:
  const SandboxedProcessFactory* sandbox_factory() const {
    return sandbox_factory_;
  }

  // FUSEMounter overrides:
  std::unique_ptr<SandboxedProcess> PrepareSandbox(
      const std::string& source,
      const base::FilePath& target_path,
      std::vector<std::string> params,
      MountErrorType* error) const final;

  virtual MountErrorType ConfigureSandbox(const std::string& source,
                                          const base::FilePath& target_path,
                                          std::vector<std::string> params,
                                          SandboxedProcess* sandbox) const = 0;

 private:
  const SandboxedProcessFactory* const sandbox_factory_;
};

}  // namespace cros_disks

#endif  // CROS_DISKS_FUSE_MOUNTER_H_
