// 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 <fcntl.h>
#include <stdio.h>
#include <stdlib.h>

#include <string>
#include <vector>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <brillo/flag_helper.h>

#include "debugd/src/process_with_output.h"

namespace {

const char kUsageMessage[] =
    "\n"
    "Configures sshd and installs SSH test keys, or queries whether sshd has\n"
    "been configured (based on the existence of the required files).\n"
    "\n";

// Source and install paths. Keeping paths and filenames separate is useful
// to avoid repeating filenames and get easy access to the individual parts when
// needed. The InstallFile class below is used to simplify combining paths.
const char kKeySourceDir[] = "/usr/share/chromeos-ssh-config/keys";
const char kKeyInstallDir[] = "/root/.ssh";
const char* const kKeyFilenames[] = {"authorized_keys", "id_rsa", "id_rsa.pub"};

const char kInitSourceDir[] = "/usr/share/chromeos-ssh-config/init";
const char kInitInstallDir[] = "/etc/init";
const char kInitFilename[] = "openssh-server.conf";

// Class to help simplify file path handling.
class InstallFile {
 public:
  InstallFile(const char* source_dir,
              const char* install_dir,
              const char* filename)
      : source_path_(base::FilePath(source_dir).Append(filename)),
        install_path_(base::FilePath(install_dir).Append(filename)) {}

  ~InstallFile() = default;

  const base::FilePath& source_path() const { return source_path_; }
  const base::FilePath& install_path() const { return install_path_; }

 private:
  base::FilePath source_path_, install_path_;
};

// Checks if a file exists and is not a directory. Symlinks will return true
// as long as the path they point to exists.
bool FileExists(const base::FilePath& path) {
  return base::PathExists(path) && !base::DirectoryExists(path);
}

// Reloads the Upstart configuration and starts the SSH job.
bool StartUpstartJob() {
  // The Upstart D-Bus interface isn't well documented and reload-configuration
  // isn't listed anywhere I can find, so just use initctl for this.
  std::string error;
  int result = debugd::ProcessWithOutput::RunProcessFromHelper(
      "initctl", {"reload-configuration"},
      nullptr,  // stdin.
      nullptr,  // stdout.
      &error);  // stderr.
  if (result != EXIT_SUCCESS) {
    LOG(WARNING) << "\"initctl reload-configuration\" failed with exit code "
                 << result << ": " << error;
    return false;
  }

  // Upstart job name is the init file name without the .conf extension.
  std::string job_name(base::FilePath(kInitFilename).RemoveExtension().value());

  // The job should be known to initctl now, otherwise something has gone wrong
  // and we can't start it.
  result = debugd::ProcessWithOutput::RunProcessFromHelper("initctl",
                                                           {"status", job_name},
                                                           nullptr,  // stdin.
                                                           nullptr,  // stdout.
                                                           &error);  // stderr.
  if (result != EXIT_SUCCESS) {
    LOG(WARNING) << "\"initctl status\" can't find job '" << job_name << "' ("
                 << result << "): " << error;
    return false;
  }

  // At this point we know initctl has the job loaded so try to start it. Any
  // error here can be ignored, it just means the job has already started.
  debugd::ProcessWithOutput::RunProcessFromHelper("initctl",
                                                  {"start", job_name},
                                                  nullptr,   // stdin.
                                                  nullptr,   // stdout.
                                                  nullptr);  // stderr.

  return true;
}

// Checks if all the necessary SSH files are installed.
bool AreSshFilesInstalled(const std::vector<InstallFile>& install_files) {
  for (const auto& install_file : install_files) {
    if (!FileExists(install_file.install_path())) {
      return false;
    }
  }
  return true;
}

// Installs the required SSH files and start sshd.
bool ConfigureSsh(const std::vector<InstallFile>& install_files) {
  // Check that sources exist ahead of time so we don't link to some and then
  // error out in a half-configured state.
  for (const auto& install_file : install_files) {
    if (!FileExists(install_file.source_path())) {
      LOG(WARNING) << "Required file \"" << install_file.source_path().value()
                   << "\" is missing";
      return false;
    }
  }

  base::ScopedFD init_ns_fd(open("/proc/1/ns/mnt", O_CLOEXEC));
  // Since debugd is running in a sandboxed envrionment, the check
  // whether '/' is writable needs to be done in the init namespace,
  // instead of the debugd sandboxed namespace.
  setns(init_ns_fd.get(), CLONE_NEWNS);

  if (!base::CreateDirectory(base::FilePath(kKeyInstallDir)) ||
      !base::CreateDirectory(base::FilePath(kInitInstallDir))) {
    return false;
  }

  // Install as many symlinks as possible, if one fails mark the failure but
  // keep going and try to complete the rest. SSH could still be partially
  // usable if, for example, the Upstart file installs but the test keys don't.
  bool install_success = true;
  for (const auto& install_file : install_files) {
    // We need to overwrite anything that might be at the install location.
    base::DeletePathRecursively(install_file.install_path());
    if (!base::CreateSymbolicLink(install_file.source_path(),
                                  install_file.install_path())) {
      install_success = false;
      PLOG(WARNING) << "Failed to create symlink at \""
                    << install_file.install_path().value() << "\"";
    }
  }

  // Upstart needs a kick to load and start the new .conf file. Still try to
  // start the job even if not all files were installed successfully, but
  // return false if either fails.
  return StartUpstartJob() && install_success;
}

}  // namespace

int main(int argc, char** argv) {
  DEFINE_bool(q, false, "Query whether SSH has been configured");
  brillo::FlagHelper::Init(argc, argv, kUsageMessage);

  std::vector<InstallFile> install_files;
  for (const char* filename : kKeyFilenames) {
    install_files.emplace_back(kKeySourceDir, kKeyInstallDir, filename);
  }
  install_files.emplace_back(kInitSourceDir, kInitInstallDir, kInitFilename);

  if (FLAGS_q) {
    return AreSshFilesInstalled(install_files) ? EXIT_SUCCESS : EXIT_FAILURE;
  }

  return ConfigureSsh(install_files) ? EXIT_SUCCESS : EXIT_FAILURE;
}
