// Copyright (c) 2012 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 <poll.h>
#include <signal.h>
#include <stddef.h>
#include <sys/wait.h>

#include <string>

#include <base/command_line.h>
#include <base/files/scoped_temp_dir.h>
#include <base/logging.h>
#include <brillo/flag_helper.h>
#include <brillo/process/process.h>
#include <brillo/syslog_logging.h>

#include "vpn-manager/daemon.h"
#include "vpn-manager/ipsec_manager.h"
#include "vpn-manager/l2tp_manager.h"

using vpn_manager::IpsecManager;
using vpn_manager::L2tpManager;
using vpn_manager::ServiceManager;

// True if a signal has requested termination.
static bool s_terminate_request = false;

void HandleSignal(int sig_num) {
  LOG(INFO) << "Caught signal " << sig_num;
  switch (sig_num) {
    case SIGTERM:
    case SIGINT:
      s_terminate_request = true;
      break;
    case SIGALRM:
      break;
  }
}

static void InstallSignalHandlers() {
  struct sigaction sa;
  memset(&sa, 0, sizeof(sa));
  sa.sa_handler = HandleSignal;
  sigaction(SIGTERM, &sa, nullptr);
  sigaction(SIGINT, &sa, nullptr);
  sigaction(SIGALRM, &sa, nullptr);
}

static void LockDownUmask() {
  // Only user and group may access configuration files we create.
  umask(S_IWGRP | S_IROTH | S_IWOTH);
}

// Run the main event loop.  The events to handle are:
// 1) timeout from poll
// 2) caught signal
// 3) stdout/err of child process ready
// 4) child process dies
static void RunEventLoop(IpsecManager* ipsec, L2tpManager* l2tp) {
  do {
    int status;
    int ipsec_poll_timeout = ipsec->Poll();
    int l2tp_poll_timeout = l2tp->Poll();
    int poll_timeout = (ipsec_poll_timeout > l2tp_poll_timeout)
                           ? ipsec_poll_timeout
                           : l2tp_poll_timeout;

    const int poll_input_count = 3;
    struct pollfd poll_inputs[poll_input_count] = {
        {ipsec->output_fd(), POLLIN},    // ipsec output
        {l2tp->output_fd(), POLLIN},     // l2tp output
        {l2tp->ppp_output_fd(), POLLIN}  // ppp output
    };
    int poll_result = poll(poll_inputs, poll_input_count, poll_timeout);
    if (poll_result < 0 && errno != EINTR) {
      int saved_errno = errno;
      LOG(ERROR) << "Unexpected poll error: " << saved_errno;
      return;
    }

    // Check if there are any child processes to be reaped without
    // blocking.
    pid_t pid = waitpid(-1, &status, WNOHANG);
    if (pid > 0 && (ipsec->IsChild(pid) || l2tp->IsChild(pid))) {
      LOG(WARNING) << "Child process " << pid << " stopped early";
      s_terminate_request = true;
    }

    if (poll_inputs[0].revents & POLLIN)
      ipsec->ProcessOutput();
    if (poll_inputs[1].revents & POLLIN)
      l2tp->ProcessOutput();
    if (poll_inputs[2].revents & POLLIN)
      l2tp->ProcessPppOutput();
  } while (!ipsec->was_stopped() && !s_terminate_request);
}

int main(int argc, char* argv[]) {
  DEFINE_string(client_cert_id, "", "PKCS#11 key ID with client certificate");
  DEFINE_string(client_cert_slot, "", "PKCS#11 slot for client certificate");
  DEFINE_int32(log_level, 0, "Log verbosity; negative values enable debugging");
  DEFINE_string(psk_file, "", "File with IPsec pre-shared key");
  DEFINE_string(remote_host, "", "VPN server hostname");
  DEFINE_string(server_ca_file, "", "File with IPsec server CA in DER format");
  DEFINE_string(server_id, "", "ID expected from server");
  DEFINE_string(user_pin, "", "PKCS#11 User PIN");
  DEFINE_string(xauth_credentials_file, "", "File with Xauth user credentials");
  DEFINE_string(shill_task_service, "", "RPC Connection Identifier");
  DEFINE_string(shill_task_path, "", "RPC Object Identifier");

  // IpsecManager related flags.

  // Phase 1 ciphersuites:
  // aes128-sha256-modp3072: new strongSwan default
  // aes128-sha1-modp2048: old strongSwan default
  // 3des-sha1-modp1536: strongSwan fallback
  // 3des-sha1-modp1024: for compatibility with Windows RRAS, which requires
  //                     using the modp1024 dh-group
  DEFINE_string(ike,
                "aes128-sha256-modp3072,"
                "aes128-sha1-modp2048,"
                "3des-sha1-modp1536,"
                "3des-sha1-modp1024",
                "ike proposals");

  // Phase 2 ciphersuites:
  // Cisco ASA L2TP/IPsec setup instructions indicate using md5 for
  // authentication for the IPsec SA.  Default StrongS/WAN setup is
  // to only propose SHA1.
  DEFINE_string(esp,
                "aes128gcm16,"
                "aes128-sha256,"
                "aes128-sha1,"
                "3des-sha1,"
                "aes128-md5,"
                "3des-md5",
                "esp proposals");

  DEFINE_int32(ipsec_timeout, 30, "timeout for ipsec to be established");
  DEFINE_string(leftprotoport, "17/1701", "client protocol/port");
  DEFINE_bool(nat_traversal, true, "Enable NAT-T nat traversal");
  DEFINE_bool(rekey, true, "rekey");
  DEFINE_string(rightprotoport, "17/1701", "server protocol/port");
  DEFINE_string(tunnel_group, "", "Cisco Tunnel Group Name");
  DEFINE_string(type, "transport", "IPsec type (transport or tunnel)");

  // L2tpManager related flags.
  DEFINE_bool(defaultroute, true, "defaultroute");
  DEFINE_bool(length_bit, true, "length bit");
  DEFINE_bool(require_chap, true, "require chap");
  DEFINE_bool(refuse_pap, false, "refuse chap");
  DEFINE_bool(require_authentication, true, "require authentication");
  DEFINE_string(password, "", "password (insecure - use pppd plugin instead)");
  DEFINE_bool(ppp_lcp_echo, true, "ppp lcp echo connection monitoring");
  DEFINE_int32(ppp_setup_timeout, 60, "timeout to setup ppp (seconds)");
  DEFINE_string(pppd_plugin, "", "pppd plugin");
  DEFINE_bool(usepeerdns, true, "usepeerdns - ask peer for DNS");
  DEFINE_string(user, "", "user name");
  DEFINE_bool(systemconfig, true, "enable ppp to configure IPs/routes/DNS");

  base::FilePath run_path("/run/l2tpipsec_vpn");
  base::FilePath persistent_path = run_path.Append("current");

  // Make sure the run path exists. Since shill no longer runs as root user, we
  // can't create the run path dir here. It should have been created in shill
  // init scripts.
  if (!base::DirectoryExists(run_path)) {
    PLOG(ERROR) << "Directory does not exist " << run_path.value();
    return vpn_manager::kServiceErrorInternal;
  }

  // Make sure the persistent path exists and is accessible for read by
  // non-root users. This will allow items like CA certificates to be
  // visible by the l2tpipsec process even after it has dropped privileges.
  if (!base::DirectoryExists(persistent_path) &&
      !base::CreateDirectory(persistent_path)) {
    PLOG(ERROR) << "Unable to create directory " << persistent_path.value();
    return vpn_manager::kServiceErrorInternal;
  }
  if (chmod(persistent_path.value().c_str(),
            S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != 0) {
    PLOG(ERROR) << "Unable to change permissions of directory "
                << persistent_path.value();
    return vpn_manager::kServiceErrorInternal;
  }

  // Create temp_path directory under run_path, to be deleted at exit.
  base::ScopedTempDir scoped_temp_dir;
  if (!scoped_temp_dir.CreateUniqueTempDirUnderPath(run_path)) {
    PLOG(ERROR) << "Unable create temp directory under " << run_path.value();
    return vpn_manager::kServiceErrorInternal;
  }
  const base::FilePath& temp_path = scoped_temp_dir.GetPath();

  brillo::FlagHelper::Init(argc, argv, "Chromium OS l2tpipsec VPN");
  int log_flags = brillo::kLogToSyslog;
  if (isatty(STDOUT_FILENO))
    log_flags |= brillo::kLogToStderr;
  brillo::InitLog(log_flags);
  logging::SetMinLogLevel(FLAGS_log_level);
  brillo::OpenLog("l2tpipsec_vpn", true);

  // TODO(mortonm): When shill sandboxing lands and sticks, simplify this code
  // by removing this if statement, since we will always be spawned in a
  // minijail after that.
  if (getenv("SHILL_TASK_SERVICE") == nullptr ||
      getenv("SHILL_TASK_SERVICE") == nullptr) {
    // The necessary env vars were not passed in, implying we were spawned in a
    // minijail. Clear the env vars left over from the parent and then set
    // RPC-related vars to reflect the values that were passed in on the command
    // line.
    if (clearenv() != 0) {
      PLOG(ERROR) << "Unable to clear environment vars";
      return vpn_manager::kServiceErrorInternal;
    }
    if (setenv("SHILL_TASK_SERVICE", FLAGS_shill_task_service.c_str(), 0) !=
        0) {
      PLOG(ERROR) << "Unable to set SHILL_TASK_SERVICE to: "
                  << FLAGS_shill_task_service.c_str();
      return vpn_manager::kServiceErrorInternal;
    }
    if (setenv("SHILL_TASK_PATH", FLAGS_shill_task_path.c_str(), 0) != 0) {
      PLOG(ERROR) << "Unable to set SHILL_TASK_PATH to: "
                  << FLAGS_shill_task_path.c_str();
      return vpn_manager::kServiceErrorInternal;
    }
  }

  IpsecManager ipsec(FLAGS_esp, FLAGS_ike, FLAGS_ipsec_timeout,
                     FLAGS_leftprotoport, FLAGS_rekey, FLAGS_rightprotoport,
                     FLAGS_tunnel_group, FLAGS_type, temp_path,
                     persistent_path);
  L2tpManager l2tp(FLAGS_defaultroute, FLAGS_length_bit, FLAGS_require_chap,
                   FLAGS_refuse_pap, FLAGS_require_authentication,
                   FLAGS_password, FLAGS_ppp_lcp_echo, FLAGS_ppp_setup_timeout,
                   FLAGS_pppd_plugin, FLAGS_usepeerdns, FLAGS_user,
                   FLAGS_systemconfig, temp_path);

  LockDownUmask();

  sockaddr_storage remote_address;
  if (!ServiceManager::ResolveNameToSockAddr(FLAGS_remote_host,
                                             &remote_address)) {
    LOG(ERROR) << "Unable to resolve hostname " << FLAGS_remote_host;
    return vpn_manager::kServiceErrorResolveHostnameFailed;
  }

  if (FLAGS_psk_file.empty() && !FLAGS_xauth_credentials_file.empty()) {
    LOG(ERROR) << "Providing XAUTH credentials without a PSK is invalid";
    return vpn_manager::kServiceErrorInvalidArgument;
  }

  if (!ipsec.Initialize(1, remote_address, FLAGS_psk_file,
                        FLAGS_xauth_credentials_file, FLAGS_server_ca_file,
                        FLAGS_server_id, FLAGS_client_cert_slot,
                        FLAGS_client_cert_id, FLAGS_user_pin)) {
    return ipsec.GetError();
  }
  if (!l2tp.Initialize(remote_address)) {
    return l2tp.GetError();
  }
  ServiceManager::SetLayerOrder(&ipsec, &l2tp);

  InstallSignalHandlers();
  if (!ipsec.Start()) {
    LOG(ERROR) << "Unable to start IPsec layer";
    return ipsec.GetError();
  }

  RunEventLoop(&ipsec, &l2tp);

  LOG(INFO) << "Shutting down...";
  l2tp.Stop();
  return ipsec.GetError();
}
