// 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 "shill/openvpn_management_server.h"

#include <arpa/inet.h>
#include <netinet/in.h>

#include <base/bind.h>
#include <base/string_number_conversions.h>
#include <base/string_split.h>
#include <base/string_util.h>
#include <base/stringprintf.h>
#include <chromeos/dbus/service_constants.h>

#include "shill/error.h"
#include "shill/event_dispatcher.h"
#include "shill/glib.h"
#include "shill/logging.h"
#include "shill/openvpn_driver.h"
#include "shill/sockets.h"

using base::Bind;
using base::IntToString;
using base::SplitString;
using base::StringPrintf;
using base::Unretained;
using std::string;
using std::vector;

namespace shill {

namespace {
const char kPasswordTagAuth[] = "Auth";
}  // namespace

const char OpenVPNManagementServer::kStateReconnecting[] = "RECONNECTING";
const char OpenVPNManagementServer::kStateResolve[] = "RESOLVE";

OpenVPNManagementServer::OpenVPNManagementServer(OpenVPNDriver *driver,
                                                 GLib *glib)
    : driver_(driver),
      glib_(glib),
      sockets_(NULL),
      socket_(-1),
      dispatcher_(NULL),
      connected_socket_(-1),
      hold_waiting_(false),
      hold_release_(false) {}

OpenVPNManagementServer::~OpenVPNManagementServer() {
  OpenVPNManagementServer::Stop();
}

bool OpenVPNManagementServer::Start(EventDispatcher *dispatcher,
                                    Sockets *sockets,
                                    vector<string> *options) {
  SLOG(VPN, 2) << __func__;
  if (IsStarted()) {
    return true;
  }

  int socket = sockets->Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (socket < 0) {
    PLOG(ERROR) << "Unable to create management server socket.";
    return false;
  }

  struct sockaddr_in addr;
  socklen_t addrlen = sizeof(addr);
  memset(&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  if (sockets->Bind(
          socket, reinterpret_cast<struct sockaddr *>(&addr), addrlen) < 0 ||
      sockets->Listen(socket, 1) < 0 ||
      sockets->GetSockName(
          socket, reinterpret_cast<struct sockaddr *>(&addr), &addrlen) < 0) {
    PLOG(ERROR) << "Socket setup failed.";
    sockets->Close(socket);
    return false;
  }

  SLOG(VPN, 2) << "Listening socket: " << socket;
  sockets_ = sockets;
  socket_ = socket;
  ready_handler_.reset(
      dispatcher->CreateReadyHandler(
          socket, IOHandler::kModeInput,
          Bind(&OpenVPNManagementServer::OnReady, Unretained(this))));
  dispatcher_ = dispatcher;

  // Append openvpn management API options.
  options->push_back("--management");
  options->push_back(inet_ntoa(addr.sin_addr));
  options->push_back(IntToString(ntohs(addr.sin_port)));
  options->push_back("--management-client");

  options->push_back("--management-hold");
  hold_release_ = false;
  hold_waiting_ = false;

  options->push_back("--management-query-passwords");
  if (driver_->AppendValueOption(flimflam::kOpenVPNStaticChallengeProperty,
                                 "--static-challenge",
                                 options)) {
    options->push_back("1");  // Force echo.
  }
  return true;
}

void OpenVPNManagementServer::Stop() {
  SLOG(VPN, 2) << __func__;
  if (!IsStarted()) {
    return;
  }
  state_.clear();
  input_handler_.reset();
  if (connected_socket_ >= 0) {
    sockets_->Close(connected_socket_);
    connected_socket_ = -1;
  }
  dispatcher_ = NULL;
  ready_handler_.reset();
  if (socket_ >= 0) {
    sockets_->Close(socket_);
    socket_ = -1;
  }
  sockets_ = NULL;
}

void OpenVPNManagementServer::ReleaseHold() {
  SLOG(VPN, 2) << __func__;
  hold_release_ = true;
  if (!hold_waiting_) {
    return;
  }
  LOG(INFO) << "Releasing hold.";
  hold_waiting_ = false;
  SendHoldRelease();
}

void OpenVPNManagementServer::Hold() {
  SLOG(VPN, 2) << __func__;
  hold_release_ = false;
}

void OpenVPNManagementServer::Restart() {
  LOG(INFO) << "Restart.";
  SendSignal("SIGUSR1");
}

void OpenVPNManagementServer::OnReady(int fd) {
  SLOG(VPN, 2) << __func__ << "(" << fd << ")";
  connected_socket_ = sockets_->Accept(fd, NULL, NULL);
  if (connected_socket_ < 0) {
    PLOG(ERROR) << "Connected socket accept failed.";
    return;
  }
  ready_handler_.reset();
  input_handler_.reset(dispatcher_->CreateInputHandler(
      connected_socket_,
      Bind(&OpenVPNManagementServer::OnInput, Unretained(this)),
      Bind(&OpenVPNManagementServer::OnInputError, Unretained(this))));
  SendState("on");
}

void OpenVPNManagementServer::OnInput(InputData *data) {
  SLOG(VPN, 2) << __func__ << "(" << data->len << ")";
  vector<string> messages;
  SplitString(
      string(reinterpret_cast<char *>(data->buf), data->len), '\n', &messages);
  for (vector<string>::const_iterator it = messages.begin();
       it != messages.end() && IsStarted(); ++it) {
    ProcessMessage(*it);
  }
}

void OpenVPNManagementServer::OnInputError(const Error &error) {
  LOG(ERROR) << error;
  driver_->FailService(Service::kFailureInternal, Service::kErrorDetailsNone);
}

void OpenVPNManagementServer::ProcessMessage(const string &message) {
  SLOG(VPN, 2) << __func__ << "(" << message << ")";
  if (message.empty()) {
    return;
  }
  if (!ProcessInfoMessage(message) &&
      !ProcessNeedPasswordMessage(message) &&
      !ProcessFailedPasswordMessage(message) &&
      !ProcessAuthTokenMessage(message) &&
      !ProcessStateMessage(message) &&
      !ProcessHoldMessage(message) &&
      !ProcessSuccessMessage(message)) {
    LOG(WARNING) << "Message ignored: " << message;
  }
}

bool OpenVPNManagementServer::ProcessInfoMessage(const string &message) {
  if (!StartsWithASCII(message, ">INFO:", true)) {
    return false;
  }
  LOG(INFO) << message;
  return true;
}

bool OpenVPNManagementServer::ProcessNeedPasswordMessage(
    const string &message) {
  if (!StartsWithASCII(message, ">PASSWORD:Need ", true)) {
    return false;
  }
  LOG(INFO) << "Processing need-password message.";
  string tag = ParsePasswordTag(message);
  if (tag == kPasswordTagAuth) {
    if (message.find("SC:") != string::npos) {
      PerformStaticChallenge(tag);
    } else {
      PerformAuthentication(tag);
    }
  } else if (StartsWithASCII(tag, "User-Specific TPM Token", true)) {
    SupplyTPMToken(tag);
  } else {
    NOTIMPLEMENTED() << ": Unsupported need-password message: " << message;
    driver_->FailService(Service::kFailureInternal, Service::kErrorDetailsNone);
  }
  return true;
}

// static
string OpenVPNManagementServer::ParseSubstring(const string &message,
                                               const string &start,
                                               const string &end) {
  SLOG(VPN, 2) << __func__ << "(" << message
               << ", " << start << ", " << end << ")";
  DCHECK(!start.empty() && !end.empty());
  size_t start_pos = message.find(start);
  if (start_pos == string::npos) {
    return string();
  }
  size_t end_pos = message.find(end, start_pos + start.size());
  if (end_pos == string::npos) {
    return string();
  }
  return message.substr(start_pos + start.size(),
                        end_pos - start_pos - start.size());
}

// static
string OpenVPNManagementServer::ParsePasswordTag(const string &message) {
  return ParseSubstring(message, "'", "'");
}

// static
string OpenVPNManagementServer::ParsePasswordFailedReason(
    const string &message) {
  return ParseSubstring(message, "['", "']");
}

void OpenVPNManagementServer::PerformStaticChallenge(const string &tag) {
  LOG(INFO) << "Perform static challenge: " << tag;
  string user =
      driver_->args()->LookupString(flimflam::kOpenVPNUserProperty, "");
  string password =
      driver_->args()->LookupString(flimflam::kOpenVPNPasswordProperty, "");
  string otp =
      driver_->args()->LookupString(flimflam::kOpenVPNOTPProperty, "");
  if (user.empty() || password.empty() || otp.empty()) {
    NOTIMPLEMENTED() << ": Missing credentials:"
                     << (user.empty() ? " no-user" : "")
                     << (password.empty() ? " no-password" : "")
                     << (otp.empty() ? " no-otp" : "");
    driver_->FailService(Service::kFailureInternal, Service::kErrorDetailsNone);
    return;
  }
  string b64_password;
  string b64_otp;
  if (!glib_->B64Encode(password, &b64_password) ||
      !glib_->B64Encode(otp, &b64_otp)) {
    LOG(ERROR) << "Unable to base64-encode credentials.";
    return;
  }
  SendUsername(tag, user);
  SendPassword(tag, StringPrintf("SCRV1:%s:%s",
                                 b64_password.c_str(),
                                 b64_otp.c_str()));
  // Don't reuse OTP.
  driver_->args()->RemoveString(flimflam::kOpenVPNOTPProperty);
}

void OpenVPNManagementServer::PerformAuthentication(const string &tag) {
  LOG(INFO) << "Perform authentication: " << tag;
  string user =
      driver_->args()->LookupString(flimflam::kOpenVPNUserProperty, "");
  string password =
      driver_->args()->LookupString(flimflam::kOpenVPNPasswordProperty, "");
  if (user.empty() || password.empty()) {
    NOTIMPLEMENTED() << ": Missing credentials:"
                     << (user.empty() ? " no-user" : "")
                     << (password.empty() ? " no-password" : "");
    driver_->FailService(Service::kFailureInternal, Service::kErrorDetailsNone);
    return;
  }
  SendUsername(tag, user);
  SendPassword(tag, password);
}

void OpenVPNManagementServer::SupplyTPMToken(const string &tag) {
  SLOG(VPN, 2) << __func__ << "(" << tag << ")";
  string pin = driver_->args()->LookupString(flimflam::kOpenVPNPinProperty, "");
  if (pin.empty()) {
    NOTIMPLEMENTED() << ": Missing PIN.";
    driver_->FailService(Service::kFailureInternal, Service::kErrorDetailsNone);
    return;
  }
  SendPassword(tag, pin);
}

bool OpenVPNManagementServer::ProcessFailedPasswordMessage(
    const string &message) {
  if (!StartsWithASCII(message, ">PASSWORD:Verification Failed:", true)) {
    return false;
  }
  LOG(INFO) << message;
  string reason;
  if (ParsePasswordTag(message) == kPasswordTagAuth) {
    reason = ParsePasswordFailedReason(message);
  }
  driver_->FailService(Service::kFailureConnect, reason);
  return true;
}

bool OpenVPNManagementServer::ProcessAuthTokenMessage(const string &message) {
  if (!StartsWithASCII(message, ">PASSWORD:Auth-Token:", true)) {
    return false;
  }
  LOG(INFO) << "Auth-Token message ignored.";
  return true;
}

// >STATE:* message support. State messages are of the form:
//    >STATE:<date>,<state>,<detail>,<local-ip>,<remote-ip>
// where:
// <date> is the current time (since epoch) in seconds
// <state> is one of:
//    INITIAL, CONNECTING, WAIT, AUTH, GET_CONFIG, ASSIGN_IP, ADD_ROUTES,
//    CONNECTED, RECONNECTING, EXITING, RESOLVE, TCP_CONNECT
// <detail> is a free-form string giving details about the state change
// <local-ip> is a dotted-quad for the local IPv4 address (when available)
// <remote-ip> is a dotted-quad for the remote IPv4 address (when available)
bool OpenVPNManagementServer::ProcessStateMessage(const string &message) {
  if (!StartsWithASCII(message, ">STATE:", true)) {
    return false;
  }
  vector<string> details;
  SplitString(message, ',', &details);
  if (details.size() > 1) {
    state_ = details[1];
    LOG(INFO) << "OpenVPN state: " << state_;
    if (state_ == kStateReconnecting) {
      OpenVPNDriver::ReconnectReason reason =
          OpenVPNDriver::kReconnectReasonUnknown;
      if (details.size() > 2 && details[2] == "tls-error") {
        reason = OpenVPNDriver::kReconnectReasonTLSError;
      }
      driver_->OnReconnecting(reason);
    }
  }

  return true;
}

bool OpenVPNManagementServer::ProcessHoldMessage(const string &message) {
  if (!StartsWithASCII(message, ">HOLD:Waiting for hold release", true)) {
    return false;
  }
  LOG(INFO) << "Client waiting for hold release.";
  hold_waiting_ = true;
  if (hold_release_) {
    ReleaseHold();
  }
  return true;
}

bool OpenVPNManagementServer::ProcessSuccessMessage(const string &message) {
  if (!StartsWithASCII(message, "SUCCESS: ", true)) {
    return false;
  }
  LOG(INFO) << message;
  return true;
}

// static
string OpenVPNManagementServer::EscapeToQuote(const string &str) {
  string escaped;
  for (string::const_iterator it = str.begin(); it != str.end(); ++it) {
    if (*it == '\\' || *it == '"') {
      escaped += '\\';
    }
    escaped += *it;
  }
  return escaped;
}

void OpenVPNManagementServer::Send(const string &data) {
  SLOG(VPN, 2) << __func__;
  ssize_t len = sockets_->Send(connected_socket_, data.data(), data.size(), 0);
  PLOG_IF(ERROR, len < 0 || static_cast<size_t>(len) != data.size())
      << "Send failed.";
}

void OpenVPNManagementServer::SendState(const string &state) {
  SLOG(VPN, 2) << __func__ << "(" << state << ")";
  Send(StringPrintf("state %s\n", state.c_str()));
}

void OpenVPNManagementServer::SendUsername(const string &tag,
                                           const string &username) {
  SLOG(VPN, 2) << __func__;
  Send(StringPrintf("username \"%s\" %s\n", tag.c_str(), username.c_str()));
}

void OpenVPNManagementServer::SendPassword(const string &tag,
                                           const string &password) {
  SLOG(VPN, 2) << __func__;
  Send(StringPrintf("password \"%s\" \"%s\"\n",
                    tag.c_str(),
                    EscapeToQuote(password).c_str()));
}

void OpenVPNManagementServer::SendSignal(const string &signal) {
  SLOG(VPN, 2) << __func__ << "(" << signal << ")";
  Send(StringPrintf("signal %s\n", signal.c_str()));
}

void OpenVPNManagementServer::SendHoldRelease() {
  SLOG(VPN, 2) << __func__;
  Send("hold release\n");
}

}  // namespace shill
