// 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 <chromeos/dbus/service_constants.h>

#include "debugd/src/process_with_output.h"

namespace debugd {

namespace {

typedef ProcessWithOutput::ArgList 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.
int RunHelper(const std::string& command,
              const ArgList& arguments,
              bool requires_root,
              const std::string* stdin,
              DBus::Error* error) {
  std::string stderr;
  int result = ProcessWithOutput::RunHelper(command,
                                            arguments,
                                            requires_root,
                                            stdin,
                                            nullptr,  // Don't need stdout.
                                            &stderr,
                                            error);
  if (!stderr.empty()) {
    if (error && !error->is_set()) {
      error->set(kDevFeaturesErrorString, stderr.c_str());
    }
  }
  return result;
}

}  // namespace

void DevFeaturesTool::RemoveRootfsVerification(DBus::Error* error) const {
  RunHelper("dev_features_rootfs_verification", ArgList{},
            true,  // requires root for make_dev_ssd.sh script.
            nullptr,  // no stdin.
            error);
}

bool DevFeaturesTool::RemoveRootfsVerificationQuery(DBus::Error* error) const {
  return RunHelper("dev_features_rootfs_verification", ArgList{"-q"},
                   true,  // requires root to check if / is writable by root.
                   nullptr,  // no stdin.
                   error) == 0;
}

void DevFeaturesTool::EnableBootFromUsb(DBus::Error* error) const {
  RunHelper("dev_features_usb_boot", ArgList{},
            true,  // requires root for enable_dev_usb_boot script.
            nullptr,  // no stdin.
            error);
}

bool DevFeaturesTool::EnableBootFromUsbQuery(DBus::Error* error) const {
  return RunHelper("dev_features_usb_boot", ArgList{"-q"},
                   true,  // requires root for crossystem queries.
                   nullptr,  // no stdin.
                   error) == 0;
}

void DevFeaturesTool::ConfigureSshServer(DBus::Error* error) const {
  // SSH server configuration requires writing to rootfs.
  if (RemoveRootfsVerificationQuery(error)) {
    RunHelper("dev_features_ssh", ArgList{},
              true,  // requires root to write to rootfs directories.
              nullptr,  // no stdin.
              error);
  } else if (!error->is_set()) {
    error->set(kDevFeaturesErrorString, kRootfsLockedErrorString);
  }
}

bool DevFeaturesTool::ConfigureSshServerQuery(DBus::Error* error) const {
  return RunHelper("dev_features_ssh", ArgList{"-q"},
                   true,  // needs root to check for files in 700 folders.
                   nullptr,  // no stdin.
                   error) == 0;
}

void DevFeaturesTool::EnableChromeRemoteDebugging(DBus::Error* error) const {
  if (RemoveRootfsVerificationQuery(error)) {
    RunHelper("dev_features_chrome_remote_debugging", ArgList{},
              true,  // requires root to write to rootfs directories.
              nullptr,  // no stdin.
              error);
  } else if (!error->is_set()) {
    error->set(kDevFeaturesErrorString, kRootfsLockedErrorString);
  }
}

bool DevFeaturesTool::EnableChromeRemoteDebuggingQuery(
    DBus::Error* error) const {
  return RunHelper("dev_features_chrome_remote_debugging", ArgList{"-q"},
                   false,
                   nullptr,  // no stdin.
                   error) == 0;
}

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

  // Set the devmode password regardless of rootfs verification state.
  RunHelper("dev_features_password", args,
            true,  // requires root to write devmode password file.
            &password,  // pipe the password through stdin.
            error);
  if (!error->is_set()) {
    // If rootfs is unlocked, we should set the system password as well.
    if (RemoveRootfsVerificationQuery(error)) {
      args.push_back("--system");
      RunHelper("dev_features_password", args,
                true,  // requires root to write system password file.
                &password,  // pipe the password through stdin.
                error);
    }
  }
}

bool DevFeaturesTool::SetUserPasswordQuery(const std::string& username,
                                           bool system,
                                           DBus::Error* error) const {
  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.
                   error) == 0;
}

void DevFeaturesTool::EnableChromeDevFeatures(const std::string& root_password,
                                              DBus::Error* error) const {
  EnableBootFromUsb(error);
  if (error->is_set()) {
    return;
  }
  ConfigureSshServer(error);
  if (error->is_set()) {
    return;
  }
  SetUserPassword("root",
                  root_password.empty() ? kDefaultRootPassword : root_password,
                  error);
}

namespace {

struct Query {
  typedef std::function<bool(void)> Function;

  Query(Function _function, DevFeatureFlag _flag)
      : function(_function), flag(_flag) {
  }

  Function function;
  DevFeatureFlag flag;
};

}  // namespace

int32_t DevFeaturesTool::QueryDevFeatures(DBus::Error* error) const {
  Query queries[] = {
      Query(std::bind(&DevFeaturesTool::RemoveRootfsVerificationQuery,
                      this, error),
            DEV_FEATURE_ROOTFS_VERIFICATION_REMOVED),
      Query(std::bind(&DevFeaturesTool::EnableBootFromUsbQuery,
                      this, error),
            DEV_FEATURE_BOOT_FROM_USB_ENABLED),
      Query(std::bind(&DevFeaturesTool::EnableChromeRemoteDebuggingQuery,
                      this, error),
            DEV_FEATURE_CHROME_REMOTE_DEBUGGING_ENABLED),
      Query(std::bind(&DevFeaturesTool::ConfigureSshServerQuery,
                      this, error),
            DEV_FEATURE_SSH_SERVER_CONFIGURED),
      Query(std::bind(&DevFeaturesTool::SetUserPasswordQuery,
                      this, "root", false, error),  // false = devmode password.
            DEV_FEATURE_DEV_MODE_ROOT_PASSWORD_SET),
      Query(std::bind(&DevFeaturesTool::SetUserPasswordQuery,
                      this, "root", true, error),  // true = system password.
            DEV_FEATURE_SYSTEM_ROOT_PASSWORD_SET)
  };

  int32_t flags = 0;
  for (const auto& query : queries) {
    if (query.function()) {
      flags |= query.flag;
    }
    // D-Bus is only set up to handle a single error so exit as soon as we
    // hit one.
    if (error->is_set()) {
      return 0;
    }
  }
  return flags;
}

}  // namespace debugd
