// Copyright 2017 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/rename_manager.h"

#include <linux/capability.h>

#include <string>

#include <base/bind.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <brillo/process.h>

#include "cros-disks/platform.h"
#include "cros-disks/rename_manager_observer_interface.h"

using base::FilePath;
using std::string;

namespace {

struct RenameParameters {
  const char* filesystem_type;
  const char* program_path;
  const size_t max_volume_name_length;
  const char* rename_group;
};

// Forbidden characters in volume name
const char kForbiddenCharacters[] = "*?.,;:/\\|+=<>[]\"'\t";

const char kRenameUser[] = "cros-disks";

// Supported file systems and their parameters
const RenameParameters kSupportedRenameParameters[] = {
    {"vfat", "/usr/sbin/dosfslabel", 11, "disk"},
    {"exfat", "/usr/sbin/exfatlabel", 15, "fuse-exfat"}};

const RenameParameters* FindRenameParameters(
    const std::string& filesystem_type) {
  for (const auto& parameters : kSupportedRenameParameters) {
    if (filesystem_type == parameters.filesystem_type) {
      return &parameters;
    }
  }

  return nullptr;
}

}  // namespace

namespace cros_disks {

RenameManager::RenameManager(Platform* platform,
                             brillo::ProcessReaper* process_reaper)
    : platform_(platform),
      process_reaper_(process_reaper),
      weak_ptr_factory_(this) {}

RenameManager::~RenameManager() {}

RenameErrorType RenameManager::StartRenaming(const string& device_path,
                                             const string& device_file,
                                             const string& volume_name,
                                             const string& filesystem_type) {
  std::string source_path;
  if (!platform_->GetRealPath(device_path, &source_path) ||
      !CanRename(source_path)) {
    LOG(WARNING) << "Device with path: '" << device_path
                 << "' is not allowed for renaming.";
    return RENAME_ERROR_DEVICE_NOT_ALLOWED;
  }

  RenameErrorType error_code = ValidateParameters(volume_name, filesystem_type);
  if (error_code != RENAME_ERROR_NONE) {
    return error_code;
  }

  const RenameParameters* parameters = FindRenameParameters(filesystem_type);
  // Check if tool for renaming exists
  if (!base::PathExists(FilePath(parameters->program_path))) {
    LOG(WARNING) << "Could not find a rename program for filesystem '"
                 << filesystem_type << "'";
    return RENAME_ERROR_RENAME_PROGRAM_NOT_FOUND;
  }

  if (base::ContainsKey(rename_process_, device_path)) {
    LOG(WARNING) << "Device '" << device_path << "' is already being renamed";
    return RENAME_ERROR_DEVICE_BEING_RENAMED;
  }

  uid_t rename_user_id;
  gid_t rename_group_id;
  if (!platform_->GetUserAndGroupId(kRenameUser, &rename_user_id, nullptr) ||
      !platform_->GetGroupId(parameters->rename_group, &rename_group_id)) {
    LOG(WARNING) << "Could not find a user with name '" << kRenameUser
                 << "' or a group with name: '" << parameters->rename_group
                 << "'";
    return RENAME_ERROR_INTERNAL;
  }

  // TODO(klemenko): Further restrict the capabilities
  SandboxedProcess* process = &rename_process_[device_path];
  process->SetUserId(rename_user_id);
  process->SetGroupId(rename_group_id);
  process->SetNoNewPrivileges();
  process->NewMountNamespace();
  process->NewIpcNamespace();
  process->NewNetworkNamespace();

  process->AddArgument(parameters->program_path);

  // TODO(klemenko): To improve and provide more general solution, the
  // per-filesystem argument setup should be parameterized with RenameParameter.
  // Construct program-name arguments
  // Example: dosfslabel /dev/sdb1 "NEWNAME"
  // Example: exfatlabel /dev/sdb1 "NEWNAME"
  if (filesystem_type == "vfat" || filesystem_type == "exfat") {
    process->AddArgument(device_file);
    process->AddArgument(volume_name);
  }

  if (!process->Start()) {
    LOG(WARNING) << "Cannot start a process for renaming '" << device_path
                 << "' as filesystem '" << filesystem_type << "' "
                 << " as volume name '" << volume_name << "'";
    rename_process_.erase(device_path);
    return RENAME_ERROR_RENAME_PROGRAM_FAILED;
  }

  process_reaper_->WatchForChild(
      FROM_HERE, process->pid(),
      base::Bind(&RenameManager::OnRenameProcessTerminated,
                 weak_ptr_factory_.GetWeakPtr(), device_path));
  return RENAME_ERROR_NONE;
}

void RenameManager::OnRenameProcessTerminated(const string& device_path,
                                              const siginfo_t& info) {
  rename_process_.erase(device_path);
  RenameErrorType error_type = RENAME_ERROR_UNKNOWN;
  switch (info.si_code) {
    case CLD_EXITED:
      if (info.si_status == 0) {
        error_type = RENAME_ERROR_NONE;
        LOG(INFO) << "Process " << info.si_pid << " for renaming '"
                  << device_path << "' completed successfully";
      } else {
        error_type = RENAME_ERROR_RENAME_PROGRAM_FAILED;
        LOG(ERROR) << "Process " << info.si_pid << " for renaming '"
                   << device_path << "' exited with a status "
                   << info.si_status;
      }
      break;

    case CLD_DUMPED:
    case CLD_KILLED:
      error_type = RENAME_ERROR_RENAME_PROGRAM_FAILED;
      LOG(ERROR) << "Process " << info.si_pid << " for renaming '"
                 << device_path << "' killed by a signal " << info.si_status;
      break;

    default:
      break;
  }
  if (observer_)
    observer_->OnRenameCompleted(device_path, error_type);
}

RenameErrorType RenameManager::ValidateParameters(
    const std::string& volume_name, const std::string& filesystem_type) const {
  // Check if the file system is supported for renaming
  const RenameParameters* parameters = FindRenameParameters(filesystem_type);
  if (!parameters) {
    LOG(WARNING) << filesystem_type
                 << " filesystem is not supported for renaming";
    return RENAME_ERROR_UNSUPPORTED_FILESYSTEM;
  }

  // Check if new volume names satisfies file system volume name conditions
  // Volume name length
  if (volume_name.size() > parameters->max_volume_name_length) {
    LOG(WARNING) << "New volume name '" << volume_name << "' exceeds "
                 << "the limit of '" << parameters->max_volume_name_length
                 << "' characters"
                 << " for the file system '" << parameters->filesystem_type
                 << "'";
    return RENAME_ERROR_LONG_NAME;
  }

  // Check if new volume name contains only printable ASCII characters and
  // none of forbidden.
  for (char value : volume_name) {
    if (!std::isprint(value) || strchr(kForbiddenCharacters, value)) {
      LOG(WARNING) << "New volume name '" << volume_name << "' contains "
                   << "forbidden character: '" << value << "'";
      return RENAME_ERROR_INVALID_CHARACTER;
    }
  }

  return RENAME_ERROR_NONE;
}

bool RenameManager::CanRename(const std::string& source_path) const {
  return base::StartsWith(source_path, "/sys/", base::CompareCase::SENSITIVE) ||
         base::StartsWith(source_path, "/devices/",
                          base::CompareCase::SENSITIVE) ||
         base::StartsWith(source_path, "/dev/", base::CompareCase::SENSITIVE);
}

}  // namespace cros_disks
