// Copyright 2020 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 "system-proxy/sandboxed_worker.h"

#include <inttypes.h>
#include <stdlib.h>
#include <sys/types.h>

#include <string>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/callback_helpers.h>
#include <base/files/file_util.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <brillo/http/http_transport.h>
#include <chromeos/patchpanel/net_util.h>
#include <google/protobuf/repeated_field.h>

#include "system-proxy/protobuf_util.h"
#include "system-proxy/system_proxy_adaptor.h"

namespace {
constexpr char kSystemProxyWorkerBin[] = "/usr/sbin/system_proxy_worker";
constexpr char kSeccompFilterPath[] =
    "/usr/share/policy/system-proxy-worker-seccomp.policy";
constexpr int kMaxWorkerMessageSize = 4096;
// Size of the buffer array used to read data from the worker's stderr.
constexpr int kWorkerBufferSize = 1024;
constexpr char kPrefixDirect[] = "direct://";
constexpr char kPrefixHttp[] = "http://";
}  // namespace

namespace system_proxy {

SandboxedWorker::SandboxedWorker(base::WeakPtr<SystemProxyAdaptor> adaptor)
    : jail_(minijail_new()), adaptor_(adaptor), pid_(0) {}

bool SandboxedWorker::Start() {
  DCHECK(!IsRunning()) << "Worker is already running.";

  if (!jail_)
    return false;

  minijail_namespace_pids(jail_.get());
  minijail_namespace_net(jail_.get());
  minijail_no_new_privs(jail_.get());
  minijail_use_seccomp_filter(jail_.get());
  minijail_parse_seccomp_filters(jail_.get(), kSeccompFilterPath);
  // Required to forward SIGTERM to the child process.
  minijail_forward_signals(jail_.get());
  // Resets the signal mask to ensure signals are not unintentionally blocked.
  minijail_reset_signal_mask(jail_.get());
  // Resets the signal handlers to the default behaviours. This is needed so
  // that the child process terminates when receiving the SIGTERM signal.
  minijail_reset_signal_handlers(jail_.get());

  int child_stdin = -1, child_stdout = -1, child_stderr = -1;

  std::vector<char*> args_ptr;

  args_ptr.push_back(const_cast<char*>(kSystemProxyWorkerBin));
  args_ptr.push_back(nullptr);

  // Execute the command.
  int res =
      minijail_run_pid_pipes(jail_.get(), args_ptr[0], args_ptr.data(), &pid_,
                             &child_stdin, &child_stdout, &child_stderr);

  if (res != 0) {
    LOG(ERROR) << "Failed to start sandboxed worker: " << strerror(-res);
    return false;
  }

  // Make sure the pipes never block.
  if (!base::SetNonBlocking(child_stdin))
    LOG(WARNING) << "Failed to set stdin non-blocking";
  if (!base::SetNonBlocking(child_stdout))
    LOG(WARNING) << "Failed to set stdout non-blocking";
  if (!base::SetNonBlocking(child_stderr))
    LOG(WARNING) << "Failed to set stderr non-blocking";

  stdin_pipe_.reset(child_stdin);
  stdout_pipe_.reset(child_stdout);
  stderr_pipe_.reset(child_stderr);

  stdout_watcher_ = base::FileDescriptorWatcher::WatchReadable(
      stdout_pipe_.get(),
      base::BindRepeating(&SandboxedWorker::OnMessageReceived,
                          base::Unretained(this)));

  stderr_watcher_ = base::FileDescriptorWatcher::WatchReadable(
      stderr_pipe_.get(), base::BindRepeating(&SandboxedWorker::OnErrorReceived,
                                              base::Unretained(this)));
  return true;
}

void SandboxedWorker::SetCredentials(const worker::Credentials& credentials) {
  worker::WorkerConfigs configs;
  *configs.mutable_credentials() = credentials;
  if (!WriteProtobuf(stdin_pipe_.get(), configs)) {
    LOG(ERROR) << "Failed to set credentials for worker " << pid_;
  }
}

bool SandboxedWorker::SetListeningAddress(uint32_t addr, int port) {
  worker::SocketAddress address;
  address.set_addr(addr);
  address.set_port(port);
  worker::WorkerConfigs configs;
  *configs.mutable_listening_address() = address;

  if (!WriteProtobuf(stdin_pipe_.get(), configs)) {
    LOG(ERROR) << "Failed to set local proxy address for worker " << pid_;
    return false;
  }
  local_proxy_host_and_port_ = base::StringPrintf(
      "%s:%d", patchpanel::IPv4AddressToString(addr).c_str(), port);
  LOG(INFO) << "Set proxy address " << local_proxy_host_and_port_
            << " for worker " << pid_;
  return true;
}

bool SandboxedWorker::SetKerberosEnabled(bool enabled,
                                         const std::string& krb5_conf_path,
                                         const std::string& krb5_ccache_path) {
  worker::KerberosConfig kerberos_config;
  kerberos_config.set_enabled(enabled);
  kerberos_config.set_krb5cc_path(krb5_ccache_path);
  kerberos_config.set_krb5conf_path(krb5_conf_path);
  worker::WorkerConfigs configs;
  *configs.mutable_kerberos_config() = kerberos_config;

  if (!WriteProtobuf(stdin_pipe_.get(), configs)) {
    LOG(ERROR) << "Failed to set kerberos enabled for worker " << pid_;
    return false;
  }
  return true;
}

bool SandboxedWorker::ClearUserCredentials() {
  worker::ClearUserCredentials clear_user_credentials;
  worker::WorkerConfigs configs;
  *configs.mutable_clear_user_credentials() = clear_user_credentials;

  if (!WriteProtobuf(stdin_pipe_.get(), configs)) {
    LOG(ERROR) << "Failed to send request to clear user credentials for worker "
               << pid_;
    return false;
  }
  return true;
}

bool SandboxedWorker::Stop() {
  if (is_being_terminated_)
    return true;
  LOG(INFO) << "Killing " << pid_;
  is_being_terminated_ = true;

  if (kill(pid_, SIGTERM) < 0) {
    if (errno == ESRCH) {
      // No process or group found for pid, assume already terminated.
      return true;
    }
    PLOG(ERROR) << "Failed to terminate process " << pid_;
    return false;
  }
  return true;
}

bool SandboxedWorker::IsRunning() {
  return pid_ != 0 && !is_being_terminated_;
}

void SandboxedWorker::OnMessageReceived() {
  worker::WorkerRequest request;

  if (!ReadProtobuf(stdout_pipe_.get(), &request)) {
    LOG(ERROR) << "Failed to read request from worker " << pid_;
    // The message is corrupted or the pipe closed, either way stop listening.
    stdout_watcher_ = nullptr;
    return;
  }
  if (request.has_log_request()) {
    LOG(INFO) << "[worker: " << pid_ << "]" << request.log_request().message();
  }

  if (request.has_proxy_resolution_request()) {
    const worker::ProxyResolutionRequest& proxy_request =
        request.proxy_resolution_request();

    // This callback will always be called with at least one proxy entry. Even
    // if the dbus call itself fails, the proxy server list will contain the
    // direct proxy.
    adaptor_->GetChromeProxyServersAsync(
        proxy_request.target_url(),
        base::BindRepeating(&SandboxedWorker::OnProxyResolved,
                            weak_ptr_factory_.GetWeakPtr(),
                            proxy_request.target_url()));
  }
  if (request.has_auth_required_request()) {
    const worker::AuthRequiredRequest& auth_request =
        request.auth_required_request();
    adaptor_->RequestAuthenticationCredentials(
        auth_request.protection_space(), auth_request.bad_cached_credentials());
  }
}

void SandboxedWorker::SetNetNamespaceLifelineFd(
    base::ScopedFD net_namespace_lifeline_fd) {
  // Sanity check that only one network namespace is setup for the worker
  // process.
  DCHECK(!net_namespace_lifeline_fd_.is_valid());
  net_namespace_lifeline_fd_ = std::move(net_namespace_lifeline_fd);
}

void SandboxedWorker::OnErrorReceived() {
  std::vector<char> buf;
  buf.resize(kWorkerBufferSize);

  std::string message;
  std::string worker_msg = "[worker: " + std::to_string(pid_) + "] ";

  ssize_t count = kWorkerBufferSize;
  ssize_t total_count = 0;

  while (count == kWorkerBufferSize) {
    count = HANDLE_EINTR(read(stderr_pipe_.get(), buf.data(), buf.size()));

    if (count < 0) {
      PLOG(ERROR) << worker_msg << "Failed to read from stdio";
      return;
    }

    if (count == 0) {
      if (!message.empty())
        break;  // Full message was read at the first iteration.

      PLOG(INFO) << worker_msg << "Pipe closed";
      // Stop watching, otherwise the handler will fire forever.
      stderr_watcher_ = nullptr;
    }

    total_count += count;
    if (total_count > kMaxWorkerMessageSize) {
      LOG(ERROR) << "Failure to read message from woker: message size exceeds "
                    "maximum allowed";
      stderr_watcher_ = nullptr;
      return;
    }
    message.append(buf.begin(), buf.begin() + count);
  }

  LOG(ERROR) << worker_msg << message;
}

void SandboxedWorker::OnProxyResolved(
    const std::string& target_url,
    bool success,
    const std::vector<std::string>& proxy_servers) {
  worker::ProxyResolutionReply reply;
  reply.set_target_url(target_url);

  // Only http and direct proxies are supported at the moment.
  for (const auto& proxy : proxy_servers) {
    if (base::StartsWith(proxy, kPrefixHttp,
                         base::CompareCase::INSENSITIVE_ASCII) ||
        base::StartsWith(proxy, kPrefixDirect,
                         base::CompareCase::INSENSITIVE_ASCII)) {
      // Make sure the local proxy doesn't try to connect to itself.
      if (!adaptor_->IsLocalProxy(proxy)) {
        reply.add_proxy_servers(proxy);
      }
    }
  }

  worker::WorkerConfigs configs;
  *configs.mutable_proxy_resolution_reply() = reply;

  if (!WriteProtobuf(stdin_pipe_.get(), configs)) {
    LOG(ERROR) << "Failed to send proxy resolution reply to worker" << pid_;
  }
}

}  // namespace system_proxy
