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

#include "cros-disks/sshfs_helper.h"

#include <algorithm>
#include <utility>

#include <base/base64.h>
#include <base/check.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>

#include "cros-disks/fuse_mounter.h"
#include "cros-disks/mount_options.h"
#include "cros-disks/mount_point.h"
#include "cros-disks/platform.h"
#include "cros-disks/quote.h"
#include "cros-disks/sandboxed_process.h"
#include "cros-disks/uri.h"

namespace cros_disks {

namespace {

constexpr char kUserName[] = "fuse-sshfs";
constexpr char kHelperTool[] = "/usr/bin/sshfs";
constexpr char kType[] = "sshfs";

constexpr char kOptionIdentityFile[] = "IdentityFile";
constexpr char kOptionIdentityBase64[] = "IdentityBase64";
constexpr char kOptionUserKnownHostsFile[] = "UserKnownHostsFile";
constexpr char kOptionUserKnownHostsBase64[] = "UserKnownHostsBase64";
constexpr char kOptionHostName[] = "HostName";
constexpr char kOptionPort[] = "Port";

constexpr char kIdentityFile[] = "id";
constexpr char kUserKnownHostsFile[] = "known_hosts";

OwnerUser ResolveSshfsUser(const Platform* platform) {
  OwnerUser user;
  PCHECK(platform->GetUserAndGroupId(kUserName, &user.uid, &user.gid));
  return user;
}

MountErrorType WriteConfigurationFile(const Platform* platform,
                                      const OwnerUser& owner,
                                      const base::FilePath& path,
                                      const std::string& b64_data) {
  std::string data;
  if (!base::Base64Decode(b64_data, &data)) {
    LOG(ERROR) << "Invalid base64 value for " << quote(path);
    return MOUNT_ERROR_INVALID_MOUNT_OPTIONS;
  }

  if (platform->WriteFile(path.value(), data.c_str(), data.size()) !=
      static_cast<int>(data.size())) {
    PLOG(ERROR) << "Cannot write file " << quote(path);
    return MOUNT_ERROR_INSUFFICIENT_PERMISSIONS;
  }

  if (!platform->SetPermissions(path.value(), 0600) ||
      !platform->SetOwnership(path.value(), owner.uid, owner.gid)) {
    PLOG(ERROR) << "Cannot change owner of file " << quote(path);
    return MOUNT_ERROR_INSUFFICIENT_PERMISSIONS;
  }

  return MOUNT_ERROR_NONE;
}

}  // namespace

SshfsHelper::SshfsHelper(const Platform* platform,
                         brillo::ProcessReaper* process_reaper,
                         base::FilePath working_dir)
    : FUSEMounterHelper(platform,
                        process_reaper,
                        kType,
                        /* nosymfollow= */ true,
                        &sandbox_factory_),
      sandbox_factory_(platform,
                       SandboxedExecutable{base::FilePath(kHelperTool)},
                       ResolveSshfsUser(platform),
                       /* has_network_access= */ true),
      working_dir_(std::move(working_dir)) {}

SshfsHelper::~SshfsHelper() = default;

bool SshfsHelper::CanMount(const std::string& source,
                           const std::vector<std::string>& params,
                           base::FilePath* suggested_name) const {
  const Uri uri = Uri::Parse(source);
  if (!uri.valid() || uri.scheme() != kType)
    return false;

  if (uri.path().empty()) {
    *suggested_name = base::FilePath(kType);
  } else {
    std::string path = uri.path();
    std::replace(path.begin(), path.end(), '/', '$');
    std::replace(path.begin(), path.end(), '.', '_');
    *suggested_name = base::FilePath(path);
  }
  return true;
}

MountErrorType SshfsHelper::ConfigureSandbox(const std::string& source,
                                             const base::FilePath& target_path,
                                             std::vector<std::string> params,
                                             SandboxedProcess* sandbox) const {
  const Uri uri = Uri::Parse(source);
  if (!uri.valid() || uri.scheme() != kType || uri.path().empty()) {
    LOG(ERROR) << "Invalid source " << quote(source);
    return MOUNT_ERROR_INVALID_DEVICE_PATH;
  }

  std::string b64_identity;
  if (!GetParamValue(params, kOptionIdentityBase64, &b64_identity) ||
      b64_identity.empty()) {
    LOG(ERROR) << "Missing required parameter " << kOptionIdentityBase64;
    return MOUNT_ERROR_INVALID_MOUNT_OPTIONS;
  }
  std::string b64_known_hosts;
  if (!GetParamValue(params, kOptionUserKnownHostsBase64, &b64_known_hosts) ||
      b64_known_hosts.empty()) {
    LOG(ERROR) << "Missing required parameter " << kOptionUserKnownHostsBase64;
    return MOUNT_ERROR_INVALID_MOUNT_OPTIONS;
  }

  std::string path;

  // TODO(dats): Consider plumbing hooks that would allow removing this
  // directory after unmount.
  if (!platform()->CreateTemporaryDirInDir(working_dir_.value(), "sshfs-",
                                           &path)) {
    PLOG(ERROR) << "Cannot create temporary directory inside "
                << quote(working_dir_);
    return MOUNT_ERROR_INSUFFICIENT_PERMISSIONS;
  }
  base::FilePath working_dir(path);
  base::FilePath identity_file = working_dir.Append(kIdentityFile);
  base::FilePath known_hosts_file = working_dir.Append(kUserKnownHostsFile);

  MountErrorType error = WriteConfigurationFile(
      platform(), sandbox_factory_.run_as(), identity_file, b64_identity);
  if (error != MOUNT_ERROR_NONE) {
    return error;
  }
  error = WriteConfigurationFile(platform(), sandbox_factory_.run_as(),
                                 known_hosts_file, b64_known_hosts);
  if (error != MOUNT_ERROR_NONE) {
    return error;
  }

  // We retain group ownership on the directory to allow potential cleanup
  // of its contents.
  if (!platform()->SetPermissions(working_dir.value(), 0770) ||
      !platform()->SetOwnership(working_dir.value(),
                                sandbox_factory_.run_as().uid, getgid())) {
    LOG(ERROR) << "Cannot set proper ownership of working directory "
               << quote(working_dir);
    return MOUNT_ERROR_INSUFFICIENT_PERMISSIONS;
  }

  if (!sandbox->BindMount(working_dir.value(), working_dir.value(), false,
                          false)) {
    LOG(ERROR) << "Cannot bind working directory " << quote(working_dir);
    return MOUNT_ERROR_INTERNAL;
  }

  std::vector<std::string> options = {
      "KbdInteractiveAuthentication=no",
      "PasswordAuthentication=no",
      "BatchMode=yes",
      "follow_symlinks",
      "cache=no",
  };

  SetParamValue(&options, "uid", base::NumberToString(kChronosUID));
  SetParamValue(&options, "gid", base::NumberToString(kChronosAccessGID));
  SetParamValue(&options, kOptionIdentityFile, identity_file.value());
  SetParamValue(&options, kOptionUserKnownHostsFile, known_hosts_file.value());

  std::string value;
  if (GetParamValue(params, kOptionHostName, &value)) {
    SetParamValue(&options, kOptionHostName, value);
  }
  if (GetParamValue(params, kOptionPort, &value)) {
    SetParamValue(&options, kOptionPort, value);
  }

  sandbox->AddArgument(uri.path());

  std::string option_string;
  if (!JoinParamsIntoOptions(options, &option_string)) {
    return MOUNT_ERROR_INVALID_MOUNT_OPTIONS;
  }
  sandbox->AddArgument("-o");
  sandbox->AddArgument(option_string);

  return MOUNT_ERROR_NONE;
}

}  // namespace cros_disks
