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

#include <string>
#include <vector>

#include <base/files/file_path.h>
#include <base/files/file_util.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;
    }
  }

  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::DeleteFile(install_file.install_path(), true);
    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;
}
