// Copyright 2014 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 "debugd/src/dev_features_tool.h"

#include <functional>

#include <base/bind.h>
#include <base/callback.h>
#include <chromeos/dbus/service_constants.h>

#include "debugd/src/error_utils.h"
#include "debugd/src/process_with_output.h"

namespace debugd {

namespace {

using ArgList = ProcessWithOutput::ArgList;

const char kDefaultRootPassword[] = "test0000";

const char kDevFeaturesErrorString[] = "org.chromium.debugd.error.DevFeatures";
const char kRootfsLockedErrorString[] =
    "Rootfs verification must be removed first";

// Executes a helper process with the expectation that any message printed to
// stderr indicates a failure that should be passed back over the D-Bus.
// Returns false if any errors launching the process occur. Returns true
// otherwise, and sets |exit_status| if it isn't null.
bool RunHelper(const std::string& command,
               const ArgList& arguments,
               bool requires_root,
               const std::string* stdin,
               int* exit_status,
               brillo::ErrorPtr* error) {
  std::string stderr;
  int result =
      ProcessWithOutput::RunHelper(command, arguments, requires_root, stdin,
                                   nullptr,  // Don't need stdout.
                                   &stderr, error);
  if (!stderr.empty()) {
    DEBUGD_ADD_ERROR(error, kDevFeaturesErrorString, stderr.c_str());
    return false;
  }

  if (exit_status)
    *exit_status = result;
  return true;
}

bool RemoveRootfsVerificationQuery(int* exit_status, brillo::ErrorPtr* error) {
  return RunHelper("dev_features_rootfs_verification", ArgList{"-q"},
                   true,     // requires root to check if / is writable by root.
                   nullptr,  // no stdin.
                   exit_status, error);
}

bool EnableBootFromUsbQuery(int* exit_status, brillo::ErrorPtr* error) {
  return RunHelper("dev_features_usb_boot", ArgList{"-q"},
                   true,     // requires root for crossystem queries.
                   nullptr,  // no stdin.
                   exit_status, error);
}

bool ConfigureSshServerQuery(int* exit_status, brillo::ErrorPtr* error) {
  return RunHelper("dev_features_ssh", ArgList{"-q"},
                   true,     // needs root to check for files in 700 folders.
                   nullptr,  // no stdin.
                   exit_status, error);
}

bool EnableChromeRemoteDebuggingQuery(int* exit_status,
                                      brillo::ErrorPtr* error) {
  return RunHelper("dev_features_chrome_remote_debugging", ArgList{"-q"}, false,
                   nullptr,  // no stdin.
                   exit_status, error);
}

bool SetUserPasswordQuery(const std::string& username,
                          bool system,
                          int* exit_status,
                          brillo::ErrorPtr* error) {
  ArgList args{"-q", "--user=" + username};
  if (system)
    args.push_back("--system");

  return RunHelper("dev_features_password", args,
                   true,     // requires root to read either password file.
                   nullptr,  // no stdin.
                   exit_status, error);
}

}  // namespace

bool DevFeaturesTool::RemoveRootfsVerification(brillo::ErrorPtr* error) const {
  return RunHelper("dev_features_rootfs_verification", ArgList{},
                   true,     // requires root for make_dev_ssd.sh script.
                   nullptr,  // no stdin.
                   nullptr,  // exit status doesn't matter.
                   error);
}

bool DevFeaturesTool::EnableBootFromUsb(brillo::ErrorPtr* error) const {
  return RunHelper("dev_features_usb_boot", ArgList{},
                   true,     // requires root for enable_dev_usb_boot script.
                   nullptr,  // no stdin.
                   nullptr,  // exit status doesn't matter.
                   error);
}

bool DevFeaturesTool::ConfigureSshServer(brillo::ErrorPtr* error) const {
  // SSH server configuration requires writing to rootfs.
  int exit_status;
  if (!RemoveRootfsVerificationQuery(&exit_status, error) || exit_status != 0) {
    DEBUGD_ADD_ERROR(error, kDevFeaturesErrorString, kRootfsLockedErrorString);
    return false;
  }

  return RunHelper("dev_features_ssh", ArgList{},
                   true,     // requires root to write to rootfs directories.
                   nullptr,  // no stdin.
                   nullptr,  // exit status doesn't matter.
                   error);
}

bool DevFeaturesTool::EnableChromeRemoteDebugging(
    brillo::ErrorPtr* error) const {
  int exit_status;
  if (!RemoveRootfsVerificationQuery(&exit_status, error) || exit_status != 0) {
    DEBUGD_ADD_ERROR(error, kDevFeaturesErrorString, kRootfsLockedErrorString);
    return false;
  }

  return RunHelper("dev_features_chrome_remote_debugging", ArgList{},
                   true,     // requires root to write to rootfs directories.
                   nullptr,  // no stdin.
                   nullptr,  // exit status doesn't matter.
                   error);
}

bool DevFeaturesTool::SetUserPassword(const std::string& username,
                                      const std::string& password,
                                      brillo::ErrorPtr* error) const {
  ArgList args{"--user=" + username};

  // Set the devmode password regardless of rootfs verification state.
  if (!RunHelper("dev_features_password", args,
                 true,       // requires root to write devmode password file.
                 &password,  // pipe the password through stdin.
                 nullptr,    // exit status doesn't matter.
                 error)) {
    return false;
  }

  // If rootfs is locked, don't bother setting the system password.
  int exit_status;
  if (!RemoveRootfsVerificationQuery(&exit_status, error) || exit_status != 0)
    return true;

  args.push_back("--system");
  return RunHelper("dev_features_password", args,
                   true,       // requires root to write system password file.
                   &password,  // pipe the password through stdin.
                   nullptr,    // exit status doesn't matter.
                   error);
}

bool DevFeaturesTool::EnableChromeDevFeatures(const std::string& root_password,
                                              brillo::ErrorPtr* error) const {
  if (!EnableBootFromUsb(error))
    return false;

  if (!ConfigureSshServer(error))
    return false;

  return SetUserPassword(
      "root", root_password.empty() ? kDefaultRootPassword : root_password,
      error);
}

namespace {

struct Query {
  // The callback should launch the query program. If launching fails, return
  // false and set the error. If it succeeds, put the exit status in the
  // integer out-argument.
  using Function = base::Callback<bool(int*, brillo::ErrorPtr*)>;

  Function function;
  DevFeatureFlag flag;
};

}  // namespace

bool DevFeaturesTool::QueryDevFeatures(int32_t* flags,
                                       brillo::ErrorPtr* error) const {
  DCHECK(flags);
  Query queries[] = {
      {base::Bind(&RemoveRootfsVerificationQuery),
       DEV_FEATURE_ROOTFS_VERIFICATION_REMOVED},
      {base::Bind(&EnableBootFromUsbQuery), DEV_FEATURE_BOOT_FROM_USB_ENABLED},
      {base::Bind(&EnableChromeRemoteDebuggingQuery),
       DEV_FEATURE_CHROME_REMOTE_DEBUGGING_ENABLED},
      {base::Bind(&ConfigureSshServerQuery), DEV_FEATURE_SSH_SERVER_CONFIGURED},
      {base::Bind(&SetUserPasswordQuery, "root", /* system = */ false),
       DEV_FEATURE_DEV_MODE_ROOT_PASSWORD_SET},
      {base::Bind(&SetUserPasswordQuery, "root", /* system = */ true),
       DEV_FEATURE_SYSTEM_ROOT_PASSWORD_SET}};

  int32_t result_flags = 0;
  for (const auto& query : queries) {
    int exit_status;
    if (!query.function.Run(&exit_status, error)) {
      // D-Bus is only set up to handle a single error so exit as soon as we
      // hit one.
      return false;
    }
    if (exit_status == 0)
      result_flags |= query.flag;
  }
  *flags = result_flags;
  return true;
}

}  // namespace debugd
