// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file is responsible for the masque_client binary. It allows testing
// our MASQUE client code by connecting to a MASQUE proxy and then sending
// HTTP/3 requests to web servers tunnelled over that MASQUE connection.
// e.g.: masque_client $PROXY_HOST:$PROXY_PORT $URL1 $URL2

#include <cstddef>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "absl/strings/escaping.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "openssl/curve25519.h"
#include "quiche/quic/core/crypto/certificate_view.h"
#include "quiche/quic/core/crypto/client_proof_source.h"
#include "quiche/quic/core/crypto/proof_verifier.h"
#include "quiche/quic/core/http/quic_spdy_client_stream.h"
#include "quiche/quic/core/io/quic_default_event_loop.h"
#include "quiche/quic/core/io/quic_event_loop.h"
#include "quiche/quic/core/quic_default_clock.h"
#include "quiche/quic/core/quic_time.h"
#include "quiche/quic/core/quic_udp_socket.h"
#include "quiche/quic/masque/masque_client.h"
#include "quiche/quic/masque/masque_client_session.h"
#include "quiche/quic/masque/masque_client_tools.h"
#include "quiche/quic/masque/masque_encapsulated_client.h"
#include "quiche/quic/masque/masque_utils.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"
#include "quiche/quic/platform/api/quic_default_proof_providers.h"
#include "quiche/quic/platform/api/quic_ip_address.h"
#include "quiche/quic/platform/api/quic_logging.h"
#include "quiche/quic/tools/fake_proof_verifier.h"
#include "quiche/common/capsule.h"
#include "quiche/common/platform/api/quiche_command_line_flags.h"
#include "quiche/common/platform/api/quiche_googleurl.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/platform/api/quiche_reference_counted.h"
#include "quiche/common/platform/api/quiche_system_event_loop.h"

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    bool, disable_certificate_verification, false,
    "If true, don't verify the server certificate.");

DEFINE_QUICHE_COMMAND_LINE_FLAG(int, address_family, 0,
                                "IP address family to use. Must be 0, 4 or 6. "
                                "Defaults to 0 which means any.");

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    std::string, masque_mode, "",
    "Allows setting MASQUE mode, currently only valid value is \"open\".");

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    std::string, proxy_headers, "",
    "A list of HTTP headers to add to request to the MASQUE proxy. "
    "Separated with colons and semicolons. "
    "For example: \"name1:value1;name2:value2\".");

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    std::string, concealed_auth, "",
    "Enables HTTP Concealed Authentication. Pass in the string \"new\" to "
    "generate new keys. Otherwise, pass in the key ID in ASCII followed by a "
    "colon and the 32-byte private key as hex. For example: \"kid:0123...f\".");

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    bool, bring_up_tun, false,
    "If set to true, no URLs need to be specified and instead a TUN device "
    "is brought up with the assigned IP from the MASQUE CONNECT-IP server.");

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    bool, dns_on_client, false,
    "If set to true, masque_client will perform DNS for encapsulated URLs and "
    "send the IP litteral in the CONNECT request. If set to false, "
    "masque_client send the hostname in the CONNECT request.");

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    bool, bind_use_uncompressed_context, false,
    "If set, an uncompressed context will be created for the client."
    "Otherwise, a compressed context will be requested.");

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    bool, bring_up_tap, false,
    "If set to true, no URLs need to be specified and instead a TAP device "
    "is brought up for a MASQUE CONNECT-ETHERNET session.");

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    std::string, client_cert_file, "",
    "Path to the PEM-encoded client certificate chain.");

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    std::string, client_cert_key_file, "",
    "Path to the PEM/PKCS8-encoded client certificate private key.");

namespace quic {

namespace {

using ::quiche::AddressAssignCapsule;
using ::quiche::AddressRequestCapsule;
using ::quiche::RouteAdvertisementCapsule;

class MasqueTunSession : public MasqueClientSession::EncapsulatedIpSession,
                         public QuicSocketEventListener {
 public:
  MasqueTunSession(QuicEventLoop* event_loop, MasqueClientSession* session)
      : event_loop_(event_loop), session_(session) {}
  ~MasqueTunSession() override = default;
  // MasqueClientSession::EncapsulatedIpSession
  void ProcessIpPacket(absl::string_view packet) override {
    QUIC_LOG(INFO) << " Received IP packets of length " << packet.length();
    if (fd_ == -1) {
      // TUN not open, early return
      return;
    }
    if (write(fd_, packet.data(), packet.size()) == -1) {
      QUIC_LOG(FATAL) << "Failed to write";
    }
  }
  void CloseIpSession(const std::string& details) override {
    QUIC_LOG(ERROR) << "Was asked to close IP session: " << details;
  }
  bool OnAddressAssignCapsule(const AddressAssignCapsule& capsule) override {
    for (auto assigned_address : capsule.assigned_addresses) {
      if (assigned_address.ip_prefix.address().IsIPv4()) {
        QUIC_LOG(INFO) << "MasqueTunSession saving local IPv4 address "
                       << assigned_address.ip_prefix.address();
        local_address_ = assigned_address.ip_prefix.address();
        break;
      }
    }
    // Bring up the TUN
    QUIC_LOG(ERROR) << "Bringing up tun with address " << local_address_;
    fd_ = CreateTunInterface(local_address_, false);
    if (fd_ < 0) {
      QUIC_LOG(FATAL) << "Failed to create TUN interface";
    }
    if (!event_loop_->RegisterSocket(fd_, kSocketEventReadable, this)) {
      QUIC_LOG(FATAL) << "Failed to register TUN fd with the event loop";
    }
    return true;
  }
  bool OnAddressRequestCapsule(
      const AddressRequestCapsule& /*capsule*/) override {
    // Always ignore the address request capsule from the server.
    return true;
  }
  bool OnRouteAdvertisementCapsule(
      const RouteAdvertisementCapsule& /*capsule*/) override {
    // Consider installing routes.
    return true;
  }

  // QuicSocketEventListener
  void OnSocketEvent(QuicEventLoop* /*event_loop*/, QuicUdpSocketFd fd,
                     QuicSocketEventMask events) override {
    if ((events & kSocketEventReadable) == 0) {
      QUIC_DVLOG(1) << "Ignoring OnEvent fd " << fd << " event mask " << events;
      return;
    }
    char datagram[kMasqueIpPacketBufferSize];
    while (true) {
      ssize_t read_size = read(fd, datagram, sizeof(datagram));
      if (read_size < 0) {
        break;
      }
      // Packet received from the TUN. Write it to the MASQUE CONNECT-IP
      // session.
      session_->SendIpPacket(absl::string_view(datagram, read_size), this);
    }
    if (!event_loop_->SupportsEdgeTriggered()) {
      if (!event_loop_->RearmSocket(fd, kSocketEventReadable)) {
        QUIC_BUG(MasqueServerSession_ConnectIp_OnSocketEvent_Rearm)
            << "Failed to re-arm socket " << fd << " for reading";
      }
    }
  }

 private:
  QuicEventLoop* event_loop_;
  MasqueClientSession* session_;
  QuicIpAddress local_address_;
  int fd_ = -1;
};

class MasqueTapSession
    : public MasqueClientSession::EncapsulatedEthernetSession,
      public QuicSocketEventListener {
 public:
  MasqueTapSession(QuicEventLoop* event_loop, MasqueClientSession* session)
      : event_loop_(event_loop), session_(session) {}
  ~MasqueTapSession() override = default;

  void CreateInterface(void) {
    QUIC_LOG(ERROR) << "Bringing up TAP";
    fd_ = CreateTapInterface();
    if (fd_ < 0) {
      QUIC_LOG(FATAL) << "Failed to create TAP interface";
    }
    if (!event_loop_->RegisterSocket(fd_, kSocketEventReadable, this)) {
      QUIC_LOG(FATAL) << "Failed to register TAP fd with the event loop";
    }
  }

  // MasqueClientSession::EncapsulatedEthernetSession
  void ProcessEthernetFrame(absl::string_view frame) override {
    QUIC_LOG(INFO) << " Received Ethernet frame of length " << frame.length();
    if (fd_ == -1) {
      // TAP not open, early return
      return;
    }
    if (write(fd_, frame.data(), frame.size()) == -1) {
      QUIC_LOG(FATAL) << "Failed to write";
    }
  }
  void CloseEthernetSession(const std::string& details) override {
    QUIC_LOG(ERROR) << "Was asked to close Ethernet session: " << details;
  }

  // QuicSocketEventListener
  void OnSocketEvent(QuicEventLoop* /*event_loop*/, QuicUdpSocketFd fd,
                     QuicSocketEventMask events) override {
    if ((events & kSocketEventReadable) == 0) {
      QUIC_DVLOG(1) << "Ignoring OnEvent fd " << fd << " event mask " << events;
      return;
    }
    char datagram[kMasqueEthernetFrameBufferSize];
    while (true) {
      ssize_t read_size = read(fd, datagram, sizeof(datagram));
      if (read_size < 0) {
        break;
      }
      // Frame received from the TAP. Write it to the MASQUE CONNECT-ETHERNET
      // session.
      session_->SendEthernetFrame(absl::string_view(datagram, read_size), this);
    }
    if (!event_loop_->SupportsEdgeTriggered()) {
      if (!event_loop_->RearmSocket(fd, kSocketEventReadable)) {
        QUIC_BUG(MasqueServerSession_ConnectIp_OnSocketEvent_Rearm)
            << "Failed to re-arm socket " << fd << " for reading";
      }
    }
  }

 private:
  QuicEventLoop* event_loop_;
  MasqueClientSession* session_;
  std::string local_mac_address_;  // string, uint8_t[6], or new wrapper type?
  int fd_ = -1;
};

std::unique_ptr<ClientProofSource> CreateClientProofSource(
    const std::string& client_cert_file,
    const std::string& client_cert_key_file) {
  if (client_cert_file.empty() || client_cert_key_file.empty()) {
    std::cerr << "Both client cert and client cert key need to be set."
              << std::endl;
    return nullptr;
  }
  std::ifstream cert_stream(client_cert_file, std::ios::binary);
  std::vector<std::string> certs =
      CertificateView::LoadPemFromStream(&cert_stream);
  if (certs.empty()) {
    std::cerr << "Failed to load client certs." << std::endl;
    return nullptr;
  }

  std::ifstream key_stream(client_cert_key_file, std::ios::binary);
  std::unique_ptr<CertificatePrivateKey> private_key =
      CertificatePrivateKey::LoadPemFromStream(&key_stream);
  if (private_key == nullptr) {
    std::cerr << "Failed to load client cert key." << std::endl;
    return nullptr;
  }

  auto proof_source = std::make_unique<DefaultClientProofSource>();
  if (!proof_source->AddCertAndKey(
          {"*"},
          quiche::QuicheReferenceCountedPointer<ClientProofSource::Chain>(
              new ClientProofSource::Chain(certs)),
          std::move(*private_key))) {
    std::cerr << "Failed to add client cert and key." << std::endl;
    return nullptr;
  }

  return proof_source;
}

int RunMasqueClient(int argc, char* argv[]) {
  const char* usage =
      "Usage: masque_client [options] <proxy-url> <urls>..\n"
      "  <proxy-url> is the URI template of the MASQUE server,\n"
      "  or host:port to use the default template";

  // The first non-flag argument is the URI template of the MASQUE server.
  // All subsequent ones are interpreted as URLs to fetch via the MASQUE server.
  // Note that the URI template expansion currently only supports string
  // replacement of {target_host} and {target_port}, not
  // {?target_host,target_port}.
  std::vector<std::string> urls =
      quiche::QuicheParseCommandLineFlags(usage, argc, argv);

  std::string concealed_auth_param =
      quiche::GetQuicheCommandLineFlag(FLAGS_concealed_auth);
  std::string concealed_auth_key_id;
  std::string concealed_auth_private_key;
  std::string concealed_auth_public_key;
  if (!concealed_auth_param.empty()) {
    static constexpr size_t kEd25519Rfc8032PrivateKeySize = 32;
    uint8_t public_key[ED25519_PUBLIC_KEY_LEN];
    uint8_t private_key[ED25519_PRIVATE_KEY_LEN];
    const bool is_new_key_pair = concealed_auth_param == "new";
    if (is_new_key_pair) {
      ED25519_keypair(public_key, private_key);
      QUIC_LOG(INFO) << "Generated new Concealed Authentication key pair";
    } else {
      std::vector<absl::string_view> concealed_auth_param_split =
          absl::StrSplit(concealed_auth_param, absl::MaxSplits(':', 1));
      std::string private_key_seed;
      if (concealed_auth_param_split.size() != 2) {
        QUIC_LOG(ERROR)
            << "Concealed authentication parameter is missing a colon";
        return 1;
      }
      concealed_auth_key_id = concealed_auth_param_split[0];
      if (concealed_auth_key_id.empty()) {
        QUIC_LOG(ERROR) << "Concealed authentication key ID cannot be empty";
        return 1;
      }
      if (!absl::HexStringToBytes(concealed_auth_param_split[1],
                                  &private_key_seed)) {
        QUIC_LOG(ERROR) << "Concealed authentication key hex value is invalid";
        return 1;
      }

      if (private_key_seed.size() != kEd25519Rfc8032PrivateKeySize) {
        QUIC_LOG(ERROR)
            << "Invalid Concealed authentication private key length "
            << private_key_seed.size();
        return 1;
      }
      ED25519_keypair_from_seed(
          public_key, private_key,
          reinterpret_cast<uint8_t*>(private_key_seed.data()));
      QUIC_LOG(INFO) << "Loaded Concealed Authentication key pair";
    }
    // Note that Ed25519 private keys are 32 bytes long per RFC 8032. However,
    // to reduce CPU costs, BoringSSL represents private keys in memory as the
    // concatenation of the 32-byte private key and the corresponding 32-byte
    // public key - which makes for a total of 64 bytes. The private key log
    // below relies on this BoringSSL implementation detail to extract the
    // RFC 8032 private key because BoringSSL does not provide a supported way
    // to access it. This is required to allow us to print the private key in a
    // format that can be passed back in to BoringSSL from the command-line. See
    // curve25519.h for details. The rest of our concealed authentication code
    // uses the BoringSSL representation without relying on this implementation
    // detail.
    static_assert(kEd25519Rfc8032PrivateKeySize <=
                  static_cast<size_t>(ED25519_PRIVATE_KEY_LEN));

    std::string private_key_hexstr = absl::BytesToHexString(absl::string_view(
        reinterpret_cast<char*>(private_key), kEd25519Rfc8032PrivateKeySize));
    std::string public_key_hexstr = absl::BytesToHexString(absl::string_view(
        reinterpret_cast<char*>(public_key), ED25519_PUBLIC_KEY_LEN));
    if (is_new_key_pair) {
      std::cout << "Generated new Concealed Authentication key pair."
                << std::endl;
      std::cout << "Private key: " << private_key_hexstr << std::endl;
      std::cout << "Public key: " << public_key_hexstr << std::endl;
      return 0;
    }
    QUIC_LOG(INFO) << "Private key: " << private_key_hexstr;
    QUIC_LOG(INFO) << "Public key: " << public_key_hexstr;
    concealed_auth_private_key = std::string(
        reinterpret_cast<char*>(private_key), ED25519_PRIVATE_KEY_LEN);
    concealed_auth_public_key = std::string(reinterpret_cast<char*>(public_key),
                                            ED25519_PUBLIC_KEY_LEN);
  }

  bool bring_up_tun = quiche::GetQuicheCommandLineFlag(FLAGS_bring_up_tun);
  bool bring_up_tap = quiche::GetQuicheCommandLineFlag(FLAGS_bring_up_tap);
  if (urls.empty() && !bring_up_tun && !bring_up_tap) {
    quiche::QuichePrintCommandLineFlagHelp(usage);
    return 1;
  }
  if (bring_up_tun && bring_up_tap) {
    quiche::QuichePrintCommandLineFlagHelp(usage);
    return 1;
  }

  quiche::QuicheSystemEventLoop system_event_loop("masque_client");
  const bool disable_certificate_verification =
      quiche::GetQuicheCommandLineFlag(FLAGS_disable_certificate_verification);
  MasqueMode masque_mode = MasqueMode::kOpen;
  std::string mode_string = quiche::GetQuicheCommandLineFlag(FLAGS_masque_mode);
  if (!mode_string.empty()) {
    if (mode_string == "open") {
      masque_mode = MasqueMode::kOpen;
    } else if (mode_string == "connectip" || mode_string == "connect-ip") {
      masque_mode = MasqueMode::kConnectIp;
    } else if (mode_string == "connectethernet" ||
               mode_string == "connect-ethernet") {
      masque_mode = MasqueMode::kConnectEthernet;
    } else if (mode_string == "connectudpbind" ||
               mode_string == "connect-udp-bind") {
      masque_mode = MasqueMode::kConnectUdpBind;
    } else {
      QUIC_LOG(ERROR) << "Invalid masque_mode \"" << mode_string << "\"";
      return 1;
    }
  }
  const int address_family =
      quiche::GetQuicheCommandLineFlag(FLAGS_address_family);
  int address_family_for_lookup;
  if (address_family == 0) {
    address_family_for_lookup = AF_UNSPEC;
  } else if (address_family == 4) {
    address_family_for_lookup = AF_INET;
  } else if (address_family == 6) {
    address_family_for_lookup = AF_INET6;
  } else {
    QUIC_LOG(ERROR) << "Invalid address_family " << address_family;
    return 1;
  }
  const bool dns_on_client =
      quiche::GetQuicheCommandLineFlag(FLAGS_dns_on_client);
  std::string client_cert_file =
      quiche::GetQuicheCommandLineFlag(FLAGS_client_cert_file);
  std::string client_cert_key_file =
      quiche::GetQuicheCommandLineFlag(FLAGS_client_cert_key_file);
  std::unique_ptr<QuicEventLoop> event_loop =
      GetDefaultEventLoop()->Create(QuicDefaultClock::Get());

  std::vector<std::unique_ptr<MasqueClient>> masque_clients;
  for (absl::string_view uri_template_sv : absl::StrSplit(urls[0], ',')) {
    std::string uri_template = std::string(uri_template_sv);
    if (!absl::StrContains(uri_template, '/')) {
      // If an authority is passed in instead of a URI template, use the default
      // URI template.
      uri_template =
          absl::StrCat("https://", uri_template,
                       "/.well-known/masque/udp/{target_host}/{target_port}/");
    }
    url::Parsed parsed_uri_template;
    url::ParseStandardURL(uri_template.c_str(), uri_template.length(),
                          &parsed_uri_template);
    if (!parsed_uri_template.scheme.is_nonempty() ||
        !parsed_uri_template.host.is_nonempty() ||
        !parsed_uri_template.path.is_nonempty()) {
      QUIC_LOG(ERROR) << "Failed to parse MASQUE URI template \""
                      << uri_template << "\"";
      return 1;
    }
    std::unique_ptr<MasqueClient> masque_client;
    if (masque_clients.empty()) {
      std::string host = uri_template.substr(parsed_uri_template.host.begin,
                                             parsed_uri_template.host.len);

      std::unique_ptr<ProofVerifier> proof_verifier;
      if (disable_certificate_verification) {
        proof_verifier = std::make_unique<FakeProofVerifier>();
      } else {
        proof_verifier = CreateDefaultProofVerifier(host);
        if (!proof_verifier) {
          QUICHE_LOG(ERROR)
              << "The default proof verifier is not supported. Pass "
                 "in --disable_certificate_verification.";
          return 1;
        }
      }

      std::unique_ptr<ClientProofSource> proof_source;
      if (!client_cert_file.empty() || !client_cert_key_file.empty()) {
        proof_source =
            CreateClientProofSource(client_cert_file, client_cert_key_file);
        if (proof_source == nullptr) {
          return 1;
        }
      }

      masque_client = MasqueClient::Create(
          uri_template, masque_mode, event_loop.get(),
          std::move(proof_verifier), std::move(proof_source));

    } else {
      masque_client = tools::CreateAndConnectMasqueEncapsulatedClient(
          masque_clients.back().get(), masque_mode, event_loop.get(),
          uri_template, disable_certificate_verification,
          address_family_for_lookup, dns_on_client,
          /*is_also_underlying=*/true);
    }
    if (masque_client == nullptr) {
      return 1;
    }

    QUIC_LOG(INFO) << "MASQUE[" << masque_clients.size() << "] to "
                   << uri_template << " is connected "
                   << masque_client->connection_id() << " in " << masque_mode
                   << " mode";

    masque_client->masque_client_session()->set_additional_headers(
        quiche::GetQuicheCommandLineFlag(FLAGS_proxy_headers));
    if (!concealed_auth_param.empty()) {
      masque_client->masque_client_session()->EnableConcealedAuth(
          concealed_auth_key_id, concealed_auth_private_key,
          concealed_auth_public_key);
    }
    masque_clients.push_back(std::move(masque_client));
  }
  std::unique_ptr<MasqueClient> masque_client =
      std::move(masque_clients.back());
  masque_clients.pop_back();

  if (bring_up_tun) {
    QUIC_LOG(INFO) << "Bringing up tun";
    MasqueTunSession tun_session(event_loop.get(),
                                 masque_client->masque_client_session());
    masque_client->masque_client_session()->SendIpPacket(
        absl::string_view("asdf"), &tun_session);
    while (true) {
      event_loop->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(50));
    }
    QUICHE_NOTREACHED();
  }
  if (bring_up_tap) {
    MasqueTapSession tap_session(event_loop.get(),
                                 masque_client->masque_client_session());
    tap_session.CreateInterface();
    while (true) {
      event_loop->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(50));
    }
    QUICHE_NOTREACHED();
  }

  if (masque_mode == MasqueMode::kConnectUdpBind) {
    bool uncompressed_context =
        quiche::GetQuicheCommandLineFlag(FLAGS_bind_use_uncompressed_context);
    masque_client->masque_client_session()->set_bind_use_uncompressed_context(
        uncompressed_context);
  }

  for (size_t i = 1; i < urls.size(); ++i) {
    if (absl::StartsWith(urls[i], "/")) {
      QuicSpdyClientStream* stream =
          masque_client->masque_client_session()->SendGetRequest(urls[i]);
      while (stream->time_to_response_complete().IsInfinite()) {
        event_loop->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(50));
      }
      // Print the response body to stdout.
      std::cout << std::endl << stream->data() << std::endl;
    } else {
      // For bind, DNS has to be done on client in the encapsulated client.
      std::unique_ptr<MasqueEncapsulatedClient> encapsulated_client =
          tools::CreateAndConnectMasqueEncapsulatedClient(
              masque_client.get(), masque_mode, event_loop.get(), urls[i],
              disable_certificate_verification, address_family_for_lookup,
              /*dns_on_client=*/dns_on_client ||
                  (masque_mode == MasqueMode::kConnectUdpBind),
              /*is_also_underlying=*/false);

      if (!encapsulated_client || !tools::SendRequestOnMasqueEncapsulatedClient(
                                      *encapsulated_client, urls[i])) {
        return 1;
      }
    }
  }

  return 0;
}

}  // namespace

}  // namespace quic

int main(int argc, char* argv[]) { return quic::RunMasqueClient(argc, argv); }
