// Copyright (c) 2011 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 "vpn-manager/ipsec_manager.h"

#include <grp.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <string>
#include <vector>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/posix/eintr_wrapper.h>
#include <base/strings/pattern.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <brillo/process.h>
#include <openssl/pem.h>
#include <openssl/x509.h>

#include "vpn-manager/daemon.h"

using ::base::FilePath;
using ::base::StringPrintf;
using ::brillo::Process;
using ::brillo::ProcessImpl;

namespace vpn_manager {

namespace {

const char kDefaultCertSlot[] = "0";
const char kIpsecCaCertsName[] = "cacert.der";
const char kIpsecStarterConfName[] = "ipsec.conf";
const char kIpsecSecretsName[] = "ipsec.secrets";
const char kIpsecGroupName[] = "ipsec";
const char kIpsecUpFile[] = "/run/ipsec/up";
const char kIpsecServiceName[] = "ipsec";
const char kStarterPidFile[] = "/run/ipsec/starter.pid";
const char kStrongswanConfName[] = "strongswan.conf";
const char kCharonPidFile[] = "/run/ipsec/charon.pid";
const char kIpsecAuthenticationFailurePattern[] =
    "*discarding duplicate packet*STATE_MAIN_I3*";
const char kSmartcardModuleName[] = "crypto_module";

}  // namespace

IpsecManager::IpsecManager(const std::string& esp,
                           const std::string& ike,
                           int ipsec_timeout,
                           const std::string& left_protoport,
                           bool rekey,
                           const std::string& right_protoport,
                           const std::string& tunnel_group,
                           const std::string& type,
                           const base::FilePath& temp_path,
                           const base::FilePath& persistent_path)
    : ServiceManager(kIpsecServiceName, temp_path),
      esp_(esp),
      ike_(ike),
      ipsec_timeout_(ipsec_timeout),
      left_protoport_(left_protoport),
      rekey_(rekey),
      right_protoport_(right_protoport),
      tunnel_group_(tunnel_group),
      type_(type),
      force_local_address_(nullptr),
      output_fd_(-1),
      ike_version_(0),
      ipsec_group_(0),
      persistent_path_(persistent_path),
      ipsec_up_file_(kIpsecUpFile),
      starter_daemon_(new Daemon(kStarterPidFile)),
      charon_daemon_(new Daemon(kCharonPidFile)) {}

bool IpsecManager::Initialize(int ike_version,
                              const struct sockaddr& remote_address,
                              const std::string& psk_file,
                              const std::string& xauth_credentials_file,
                              const std::string& server_ca_file,
                              const std::string& server_id,
                              const std::string& client_cert_slot,
                              const std::string& client_cert_id,
                              const std::string& user_pin) {
  if (!ConvertSockAddrToIPString(remote_address, &remote_address_text_)) {
    LOG(ERROR) << "Unable to convert sockaddr to name for remote host";
    RegisterError(kServiceErrorInternal);
    return false;
  }
  remote_address_ = remote_address;

  if (psk_file.empty()) {
    if (server_ca_file.empty() && server_id.empty() && client_cert_id.empty() &&
        user_pin.empty()) {
      LOG(ERROR) << "Must specify either PSK or certificates for IPsec layer";
      RegisterError(kServiceErrorInvalidArgument);
      return false;
    }

    if (ike_version != 1) {
      LOG(ERROR) << "Only IKE version 1 is supported with certificates";
      RegisterError(kServiceErrorInvalidArgument);
      return false;
    }

    // Must be a certificate based connection.
    FilePath server_ca_path(server_ca_file);
    if (!base::PathExists(server_ca_path)) {
      LOG(ERROR) << "Invalid server CA file for IPsec layer: "
                 << server_ca_file;
      RegisterError(kServiceErrorInvalidArgument);
      return false;
    }
    if (!ReadCertificateSubject(server_ca_path, &server_ca_subject_)) {
      LOG(ERROR) << "Unable to read certificate subject from: "
                 << server_ca_file;
      RegisterError(kServiceErrorInvalidArgument);
      return false;
    }
    server_ca_file_ = server_ca_file;
    server_id_ = server_id;

    if (client_cert_slot.empty()) {
      client_cert_slot_ = kDefaultCertSlot;
    } else {
      client_cert_slot_ = client_cert_slot;
    }

    if (client_cert_id.empty()) {
      LOG(ERROR) << "Must specify the PKCS#11 ID for the certificate";
      RegisterError(kServiceErrorInvalidArgument);
      return false;
    }
    client_cert_id_ = client_cert_id;

    if (user_pin.empty()) {
      LOG(ERROR) << "Must specify the PKCS#11 user PIN for the certificate";
      RegisterError(kServiceErrorInvalidArgument);
      return false;
    }
    user_pin_ = user_pin;
  } else {
    if (!server_ca_file.empty() || !server_id.empty() ||
        !client_cert_id.empty()) {
      LOG(WARNING) << "Specified both certificates and PSK to IPsec layer";
    }
    if (!base::PathExists(FilePath(psk_file))) {
      LOG(ERROR) << "Invalid PSK file for IPsec layer: " << psk_file;
      RegisterError(kServiceErrorInvalidArgument);
      return false;
    }
    psk_file_ = psk_file;
  }

  if (!xauth_credentials_file.empty()) {
    if (!base::PathExists(FilePath(xauth_credentials_file))) {
      LOG(ERROR) << "Invalid xauth credentials file: "
                 << xauth_credentials_file;
      RegisterError(kServiceErrorInvalidArgument);
      return false;
    }
    xauth_credentials_file_ = xauth_credentials_file;
  }

  if (ike_version != 1 && ike_version != 2) {
    LOG(ERROR) << "Unsupported IKE version" << ike_version;
    RegisterError(kServiceErrorInvalidArgument);
    return false;
  }
  ike_version_ = ike_version;

  base::DeleteFile(FilePath(kIpsecUpFile), false);

  return true;
}

bool IpsecManager::ReadCertificateSubject(const FilePath& filepath,
                                          std::string* output) {
  FILE* fp = fopen(filepath.value().c_str(), "rb");
  if (!fp) {
    LOG(ERROR) << "Unable to read certificate";
    return false;
  }
  X509* cert = d2i_X509_fp(fp, nullptr);
  if (cert == nullptr) {
    fseek(fp, 0, SEEK_SET);
    cert = PEM_read_X509(fp, nullptr, nullptr, nullptr);
  }
  fclose(fp);
  if (!cert) {
    LOG(ERROR) << "Error parsing certificate";
    return false;
  }
  BIO* bio = BIO_new(BIO_s_mem());
  if (!X509_NAME_print_ex(bio, X509_get_subject_name(cert), 0,
                          XN_FLAG_SEP_CPLUS_SPC)) {
    LOG(ERROR) << "Could not print certificate name";
    BIO_free(bio);
    X509_free(cert);
    return false;
  }
  char* name_ptr;
  int length = BIO_get_mem_data(bio, &name_ptr);
  output->assign(name_ptr, length);
  BIO_free(bio);
  X509_free(cert);
  return true;
}

bool IpsecManager::FormatIpsecSecret(std::string* formatted) {
  std::string secret_mode;
  std::string secret;
  if (psk_file_.empty()) {
    secret_mode =
        StringPrintf("PIN %%smartcard%s@%s:%s", client_cert_slot_.c_str(),
                     kSmartcardModuleName, client_cert_id_.c_str());
    secret = user_pin_;
  } else {
    secret_mode = "PSK";
    if (!base::ReadFileToString(FilePath(psk_file_), &secret)) {
      LOG(ERROR) << "Unable to read PSK from " << psk_file_;
      return false;
    }
    base::TrimWhitespaceASCII(secret, base::TRIM_TRAILING, &secret);
  }
  std::string local_address_text;
  if (force_local_address_ != nullptr) {
    local_address_text = force_local_address_;
  } else {
    struct sockaddr local_address;
    if (!GetLocalAddressFromRemote(remote_address_, &local_address)) {
      LOG(ERROR) << "Local IP address could not be determined for PSK mode";
      return false;
    }
    if (!ConvertSockAddrToIPString(local_address, &local_address_text)) {
      LOG(ERROR) << "Unable to convert local address to string";
      return false;
    }
  }
  *formatted = StringPrintf("%s %s : %s \"%s\"\n", local_address_text.c_str(),
                            remote_address_text_.c_str(), secret_mode.c_str(),
                            secret.c_str());
  return true;
}

bool IpsecManager::FormatXauthSecret(std::string* formatted) {
  if (xauth_credentials_file_.empty()) {
    xauth_identity_ = "";
    return true;
  }

  std::string xauth_contents;
  if (!base::ReadFileToString(FilePath(xauth_credentials_file_),
                              &xauth_contents)) {
    LOG(ERROR) << "Unable to read XAUTH credentials from "
               << xauth_credentials_file_;
    return false;
  }
  std::vector<std::string> xauth_parts = base::SplitString(
      xauth_contents, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  if (xauth_parts.size() < 2) {
    LOG(ERROR) << "Unable to parse XAUTH credentials from "
               << xauth_credentials_file_;
    return false;
  }

  // Save this identity for use in the ipsec starter file.
  xauth_identity_ = xauth_parts[0];
  std::string xauth_password = xauth_parts[1];
  *formatted = StringPrintf("%s : XAUTH \"%s\"\n", xauth_identity_.c_str(),
                            xauth_password.c_str());
  return true;
}

bool IpsecManager::FormatSecrets(std::string* formatted) {
  std::string ipsec_secret, xauth_secret;
  if (!FormatIpsecSecret(&ipsec_secret) || !FormatXauthSecret(&xauth_secret)) {
    return false;
  }

  *formatted = ipsec_secret + xauth_secret;
  return true;
}

void IpsecManager::KillCurrentlyRunning() {
  starter_daemon_->FindProcess();
  charon_daemon_->FindProcess();
  starter_daemon_->ClearProcess();
  charon_daemon_->ClearProcess();
}

bool IpsecManager::StartStarter() {
  KillCurrentlyRunning();
  LOG(INFO) << "Starting starter";
  Process* starter = starter_daemon_->CreateProcess();
  starter->AddArg(IPSEC_STARTER);
  starter->AddArg("--nofork");
  starter->RedirectUsingPipe(STDERR_FILENO, false);
  if (!starter->Start()) {
    LOG(ERROR) << "Starter did not start successfully";
    return false;
  }
  output_fd_ = starter->GetPipe(STDERR_FILENO);
  pid_t starter_pid = starter->pid();
  LOG(INFO) << "Starter started as pid " << starter_pid;
  ipsec_prefix_ = StringPrintf("ipsec[%d]: ", starter_pid);
  return true;
}

inline void AppendBoolSetting(std::string* config,
                              const char* key,
                              bool value) {
  config->append(StringPrintf("\t%s=%s\n", key, value ? "yes" : "no"));
}

inline void AppendStringSetting(std::string* config,
                                const char* key,
                                const std::string& value) {
  config->append(StringPrintf("\t%s=\"%s\"\n", key, value.c_str()));
}

inline void AppendIntSetting(std::string* config, const char* key, int value) {
  config->append(StringPrintf("\t%s=%d\n", key, value));
}

std::string IpsecManager::FormatStrongswanConfigFile() {
  std::string config;
  config.append("libstrongswan {\n");
  config.append("  plugins {\n");
  config.append("    pkcs11 {\n");
  config.append("      modules {\n");
  config.append(StringPrintf("        %s {\n", kSmartcardModuleName));
  config.append(StringPrintf("          path = %s\n", PKCS11_LIB));
  config.append("        }\n");
  config.append("      }\n");
  config.append("    }\n");
  config.append("  }\n");
  config.append("}\n");
  config.append("charon {\n");
  config.append("  accept_unencrypted_mainmode_messages = yes\n");
  config.append("  ignore_routing_tables = 0\n");
  config.append("  install_routes = no\n");
  config.append("  routing_table = 0\n");
  config.append("}\n");
  return config;
}

std::string IpsecManager::FormatStarterConfigFile() {
  std::string config;
  config.append("config setup\n");

  std::string charondebug;
  if (VLOG_IS_ON(6)) {
    // "enc 4" shows details of each IKE transform payload. Very noisy.
    charondebug = "ike 4, cfg 2, knl 4, net 3, enc 4";
  } else if (VLOG_IS_ON(5)) {
    // "ike 4" logs the session key for the IKE SA.
    // "knl 4" logs netlink messages containing the ESP session keys.
    // This information is needed to make sense of IKE packet captures.
    charondebug = "ike 4, cfg 2, knl 4, net 3, enc 1";
  } else if (VLOG_IS_ON(3)) {
    // "net 3" logs raw IKE packets (some are encrypted, some not).
    charondebug = "ike 2, cfg 2, knl 2, net 3, enc 1";
  } else {
    // By default: do not log packet data or keys.
    // "ike 2" logs some traffic selector info.
    // "cfg 2" logs algorithm proposals.
    // "knl 2" logs high-level xfrm crypto parameters.
    // "net 1" and "enc 1" are strongSwan's defaults.
    charondebug = "ike 2, cfg 2, knl 2, net 1, enc 1";
  }
  AppendStringSetting(&config, "charondebug", charondebug);

  AppendStringSetting(&config, "uniqueids", "no");
  config.append("conn managed\n");
  AppendStringSetting(&config, "ike", ike_);
  AppendStringSetting(&config, "esp", esp_);
  AppendStringSetting(&config, "keyexchange",
                      ike_version_ == 1 ? "ikev1" : "ikev2");
  if (!psk_file_.empty()) {
    if (!xauth_identity_.empty()) {
      AppendStringSetting(&config, "authby", "xauthpsk");
      AppendStringSetting(&config, "xauth", "client");
      AppendStringSetting(&config, "xauth_identity", xauth_identity_);
    } else {
      AppendStringSetting(&config, "authby", "psk");
    }
  }
  AppendBoolSetting(&config, "rekey", rekey_);
  AppendStringSetting(&config, "left", "%defaultroute");
  if (!client_cert_slot_.empty()) {
    std::string smartcard =
        StringPrintf("%%smartcard%s@%s:%s", client_cert_slot_.c_str(),
                     kSmartcardModuleName, client_cert_id_.c_str());
    AppendStringSetting(&config, "leftcert", smartcard);
  }
  if (!tunnel_group_.empty()) {
    AppendStringSetting(&config, "aggressive", "yes");
    std::string hex_tunnel_id =
        base::HexEncode(tunnel_group_.c_str(), tunnel_group_.length());
    std::string left_id = StringPrintf("@#%s", hex_tunnel_id.c_str());
    AppendStringSetting(&config, "leftid", left_id);
  }
  AppendStringSetting(&config, "leftprotoport", left_protoport_);
  AppendStringSetting(&config, "leftupdown", IPSEC_UPDOWN);
  AppendStringSetting(&config, "right", remote_address_text_);
  if (!server_ca_subject_.empty()) {
    AppendStringSetting(&config, "rightca", server_ca_subject_);
  }
  if (server_id_.empty()) {
    AppendStringSetting(&config, "rightid", "%any");
  } else {
    AppendStringSetting(&config, "rightid", server_id_);
  }
  AppendStringSetting(&config, "rightprotoport", right_protoport_);
  AppendStringSetting(&config, "type", type_);
  AppendStringSetting(&config, "auto", "start");
  return config;
}

// Even without root privs or CAP_CHOWN, we can still chgrp() to a group that
// the 'shill' user is a member of -- in this case the 'ipsec' group.
bool IpsecManager::SetIpsecGroup(const FilePath& file_path) {
  return chown(file_path.value().c_str(), -1, ipsec_group_) == 0;
}

bool IpsecManager::WriteConfigFile(const std::string& output_name,
                                   const std::string& contents) {
  FilePath temp_file = temp_path().Append(output_name);
  base::DeleteFile(temp_file, false);
  if (base::PathExists(temp_file)) {
    LOG(ERROR) << "Unable to remove existing file " << temp_file.value();
    return false;
  }
  // Dir in temp_path must be accessible to both 'shill' and 'ipsec' users
  // so this code (running as 'shill') can create config files which can be
  // accessed by user/group 'ipsec'.
  if (!base::WriteFile(temp_file, contents.c_str(), contents.length()) ||
      !SetIpsecGroup(temp_file)) {
    LOG(ERROR) << "Unable to write " << output_name << " file "
               << temp_file.value();
    return false;
  }

  return MakeSymbolicLink(output_name, temp_file);
}

bool IpsecManager::MakeSymbolicLink(const std::string& output_name,
                                    const FilePath& source_path) {
  FilePath symlink_path = persistent_path_.Append(output_name);
  // Use unlink to remove the symlink directly since base::DeleteFile
  // cannot delete dangling symlinks.
  unlink(symlink_path.value().c_str());
  if (base::PathExists(symlink_path)) {
    LOG(ERROR) << "Unable to remove existing file " << symlink_path.value();
    return false;
  }
  if (symlink(source_path.value().c_str(), symlink_path.value().c_str()) < 0) {
    PLOG(ERROR) << "Unable to symlink config file " << symlink_path.value()
                << " -> " << source_path.value();
    return false;
  }
  return true;
}

bool IpsecManager::WriteConfigFiles() {
  // The strongSwan binaries have hard-coded paths to /etc, which on a
  // ChromeOS image are symlinks to a fixed place |persistent_path_|.
  // We create the configuration files in /run and link from the
  // |persistent_path_| to these newly created files.

  std::string formatted_secrets;
  if (!FormatSecrets(&formatted_secrets)) {
    LOG(ERROR) << "Unable to create secrets contents";
    return false;
  }

  if (!WriteConfigFile(kIpsecSecretsName, formatted_secrets)) {
    return false;
  }

  if (!WriteConfigFile(kStrongswanConfName, FormatStrongswanConfigFile())) {
    return false;
  }
  if (!WriteConfigFile(kIpsecStarterConfName, FormatStarterConfigFile())) {
    return false;
  }

  if (!server_ca_file_.empty()) {
    // We have a contract with shill that certificate files it
    // creates will be readable by the ipsec client.  As such we do
    // not need to copy this file, and can link to it directly.
    return MakeSymbolicLink(kIpsecCaCertsName, FilePath(server_ca_file_));
  }

  return true;
}

bool IpsecManager::Start() {
  if (!ipsec_group_) {
    struct group group_buffer;
    struct group* group_result = nullptr;
    char buffer[256];
    if (getgrnam_r(kIpsecGroupName, &group_buffer, buffer, sizeof(buffer),
                   &group_result) != 0 ||
        !group_result) {
      LOG(ERROR) << "Cannot find group id for " << kIpsecGroupName;
      RegisterError(kServiceErrorInternal);
      return false;
    }
    ipsec_group_ = group_result->gr_gid;
    DLOG(INFO) << "Using ipsec group " << ipsec_group_;
  }
  if (!WriteConfigFiles() || !StartStarter()) {
    RegisterError(kServiceErrorInternal);
    return false;
  }

  start_ticks_ = base::TimeTicks::Now();

  return true;
}

int IpsecManager::Poll() {
  if (is_running())
    return -1;
  if (start_ticks_.is_null())
    return -1;
  if (!base::PathExists(FilePath(ipsec_up_file_))) {
    if (base::TimeTicks::Now() - start_ticks_ >
        base::TimeDelta::FromSeconds(ipsec_timeout_)) {
      LOG(ERROR) << "IPsec connection timed out";
      RegisterError(kServiceErrorIpsecConnectionFailed);
      OnStopped(false);
      // Poll in 1 second in order to check exit conditions.
    }
    return 1000;
  }

  // This indicates that the connection came up successfully.
  LOG(INFO) << "IPsec connection now up";
  OnStarted();
  return -1;
}

void IpsecManager::ProcessOutput() {
  WriteFdToSyslog(output_fd_, ipsec_prefix_, &partial_output_line_);
}

bool IpsecManager::IsChild(pid_t pid) {
  return pid == starter_daemon_->GetPid();
}

void IpsecManager::Stop() {
  // If the process started in StartStarter() is no longer running, see if
  // there is a pid file associated to a different running instance of the
  // starter.
  if (!starter_daemon_->IsRunning())
    starter_daemon_->FindProcess();
  charon_daemon_->FindProcess();

  bool unclean_termination = !starter_daemon_->Terminate();
  charon_daemon_->Terminate();
  OnStopped(unclean_termination);
}

void IpsecManager::OnSyslogOutput(const std::string& prefix,
                                  const std::string& line) {
  if (base::MatchPattern(line, kIpsecAuthenticationFailurePattern)) {
    if (psk_file_.empty()) {
      LOG(ERROR) << "IPsec certificate authentication failed";
      RegisterError(kServiceErrorIpsecCertificateAuthenticationFailed);
    } else {
      LOG(ERROR) << "IPsec pre-shared key authentication failed";
      RegisterError(kServiceErrorIpsecPresharedKeyAuthenticationFailed);
    }
  }
}

}  // namespace vpn_manager
