// Copyright 2014 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "iptables.h"

#include <linux/capability.h>

#include <string>
#include <vector>

#include <base/bind.h>
#include <base/bind_helpers.h>
#include <base/callback.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <brillo/minijail/minijail.h>

namespace {

using IpTablesCallback = base::Callback<bool(const std::string&, bool)>;

const char kIPv4[] = "IPv4";
const char kIPv6[] = "IPv6";

// Interface names must be shorter than 'IFNAMSIZ' chars.
// See http://man7.org/linux/man-pages/man7/netdevice.7.html
// 'IFNAMSIZ' is 16 in recent kernels.
// See http://lxr.free-electrons.com/source/include/uapi/linux/if.h#L26
const size_t kInterfaceNameSize = 16;

const char kMarkForUserTraffic[] = "1";

const char kTableIdForUserTraffic[] = "1";

bool IsValidInterfaceName(const std::string& iface) {
  // |iface| should be shorter than |kInterfaceNameSize| chars and have only
  // alphanumeric characters (embedded hypens and periods are also permitted).
  if (iface.length() >= kInterfaceNameSize) {
    return false;
  }
  if (base::StartsWith(iface, "-", base::CompareCase::SENSITIVE) ||
      base::EndsWith(iface, "-", base::CompareCase::SENSITIVE) ||
      base::StartsWith(iface, ".", base::CompareCase::SENSITIVE) ||
      base::EndsWith(iface, ".", base::CompareCase::SENSITIVE)) {
    return false;
  }
  for (auto c : iface) {
    if (!std::isalnum(c) && (c != '-') && (c != '.')) {
      return false;
    }
  }
  return true;
}

bool RunForAllArguments(const IpTablesCallback& iptables_cmd,
                        const std::vector<std::string>& arguments,
                        bool add) {
  bool success = true;
  for (const auto& argument : arguments) {
    if (!iptables_cmd.Run(argument, add)) {
      // On failure, only abort if rules are being added.
      // If removing a rule fails, attempt the remaining removals but still
      // return 'false'.
      success = false;
      if (add)
        break;
    }
  }
  return success;
}

}  // namespace

namespace firewalld {

IpTables::IpTables() {
}

IpTables::~IpTables() {
  // Plug all holes when destructed.
  PlugAllHoles();
}

bool IpTables::PunchTcpHole(uint16_t in_port, const std::string& in_interface) {
  return PunchHole(in_port, in_interface, &tcp_holes_, kProtocolTcp);
}

bool IpTables::PunchUdpHole(uint16_t in_port, const std::string& in_interface) {
  return PunchHole(in_port, in_interface, &udp_holes_, kProtocolUdp);
}

bool IpTables::PlugTcpHole(uint16_t in_port, const std::string& in_interface) {
  return PlugHole(in_port, in_interface, &tcp_holes_, kProtocolTcp);
}

bool IpTables::PlugUdpHole(uint16_t in_port, const std::string& in_interface) {
  return PlugHole(in_port, in_interface, &udp_holes_, kProtocolUdp);
}

bool IpTables::RequestVpnSetup(const std::vector<std::string>& usernames,
                               const std::string& interface) {
  return ApplyVpnSetup(usernames, interface, true /* add */);
}

bool IpTables::RemoveVpnSetup(const std::vector<std::string>& usernames,
                              const std::string& interface) {
  return ApplyVpnSetup(usernames, interface, false /* delete */);
}

bool IpTables::PunchHole(uint16_t port,
                         const std::string& interface,
                         std::set<Hole>* holes,
                         ProtocolEnum protocol) {
  if (port == 0) {
    // Port 0 is not a valid TCP/UDP port.
    return false;
  }

  if (!IsValidInterfaceName(interface)) {
    LOG(ERROR) << "Invalid interface name '" << interface << "'";
    return false;
  }

  Hole hole = std::make_pair(port, interface);
  if (holes->find(hole) != holes->end()) {
    // We have already punched a hole for |port| on |interface|.
    // Be idempotent: do nothing and succeed.
    return true;
  }

  std::string sprotocol = protocol == kProtocolTcp ? "TCP" : "UDP";
  LOG(INFO) << "Punching hole for " << sprotocol << " port " << port
            << " on interface '" << interface << "'";
  if (!AddAcceptRules(protocol, port, interface)) {
    // If the 'iptables' command fails, this method fails.
    LOG(ERROR) << "Adding ACCEPT rules failed.";
    return false;
  }

  // Track the hole we just punched.
  holes->insert(hole);

  return true;
}

bool IpTables::PlugHole(uint16_t port,
                        const std::string& interface,
                        std::set<Hole>* holes,
                        ProtocolEnum protocol) {
  if (port == 0) {
    // Port 0 is not a valid TCP/UDP port.
    return false;
  }

  Hole hole = std::make_pair(port, interface);

  if (holes->find(hole) == holes->end()) {
    // There is no firewall hole for |port| on |interface|.
    // Even though this makes |PlugHole| not idempotent,
    // and Punch/Plug not entirely symmetrical, fail. It might help catch bugs.
    return false;
  }

  std::string sprotocol = protocol == kProtocolTcp ? "TCP" : "UDP";
  LOG(INFO) << "Plugging hole for " << sprotocol << " port " << port
            << " on interface '" << interface << "'";
  if (!DeleteAcceptRules(protocol, port, interface)) {
    // If the 'iptables' command fails, this method fails.
    LOG(ERROR) << "Deleting ACCEPT rules failed.";
    return false;
  }

  // Stop tracking the hole we just plugged.
  holes->erase(hole);

  return true;
}

void IpTables::PlugAllHoles() {
  // Copy the container so that we can remove elements from the original.
  // TCP
  std::set<Hole> holes = tcp_holes_;
  for (auto hole : holes) {
    PlugHole(hole.first /* port */, hole.second /* interface */, &tcp_holes_,
             kProtocolTcp);
  }

  // UDP
  holes = udp_holes_;
  for (auto hole : holes) {
    PlugHole(hole.first /* port */, hole.second /* interface */, &udp_holes_,
             kProtocolUdp);
  }

  CHECK(tcp_holes_.size() == 0) << "Failed to plug all TCP holes.";
  CHECK(udp_holes_.size() == 0) << "Failed to plug all UDP holes.";
}

bool IpTables::AddAcceptRules(ProtocolEnum protocol,
                              uint16_t port,
                              const std::string& interface) {
  if (!AddAcceptRule(kIpTablesPath, protocol, port, interface)) {
    LOG(ERROR) << "Could not add ACCEPT rule using '" << kIpTablesPath << "'";
    return false;
  }

  if (AddAcceptRule(kIp6TablesPath, protocol, port, interface)) {
    // This worked, record this fact and insist that it works thereafter.
    ip6_enabled_ = true;
  } else if (ip6_enabled_) {
    // It's supposed to work, fail.
    LOG(ERROR) << "Could not add ACCEPT rule using '" << kIp6TablesPath
               << "', aborting operation.";
    DeleteAcceptRule(kIpTablesPath, protocol, port, interface);
    return false;
  } else {
    // It never worked, just ignore it.
    LOG(WARNING) << "Could not add ACCEPT rule using '" << kIp6TablesPath
                 << "', ignoring.";
  }

  return true;
}

bool IpTables::DeleteAcceptRules(ProtocolEnum protocol,
                                 uint16_t port,
                                 const std::string& interface) {
  bool ip4_success = DeleteAcceptRule(kIpTablesPath, protocol, port,
                                      interface);
  bool ip6_success = !ip6_enabled_ || DeleteAcceptRule(kIp6TablesPath, protocol,
                                                       port, interface);
  return ip4_success && ip6_success;
}

bool IpTables::ApplyVpnSetup(const std::vector<std::string>& usernames,
                             const std::string& interface,
                             bool add) {
  bool success = true;
  std::vector<std::string> added_usernames;

  if (!ApplyRuleForUserTraffic(add)) {
    if (add) {
      ApplyRuleForUserTraffic(false /* remove */);
      return false;
    }
    success = false;
  }

  if (!ApplyMasquerade(interface, add)) {
    if (add) {
      ApplyVpnSetup(added_usernames, interface, false /* remove */);
      return false;
    }
    success = false;
  }

  for (const auto& username : usernames) {
    if (!ApplyMarkForUserTraffic(username, add)) {
      if (add) {
        ApplyVpnSetup(added_usernames, interface, false /* remove */);
        return false;
      }
      success = false;
    }
    if (add) {
      added_usernames.push_back(username);
    }
  }

  return success;
}

bool IpTables::ApplyMasquerade(const std::string& interface, bool add) {
  const IpTablesCallback apply_masquerade =
      base::Bind(&IpTables::ApplyMasqueradeWithExecutable,
                 base::Unretained(this),
                 interface);

  return RunForAllArguments(
      apply_masquerade, {kIpTablesPath, kIp6TablesPath}, add);
}

bool IpTables::ApplyMarkForUserTraffic(const std::string& username, bool add) {
  const IpTablesCallback apply_mark =
      base::Bind(&IpTables::ApplyMarkForUserTrafficWithExecutable,
                 base::Unretained(this),
                 username);

  return RunForAllArguments(apply_mark, {kIpTablesPath, kIp6TablesPath}, add);
}

bool IpTables::ApplyRuleForUserTraffic(bool add) {
  const IpTablesCallback apply_rule = base::Bind(
      &IpTables::ApplyRuleForUserTrafficWithVersion, base::Unretained(this));

  return RunForAllArguments(apply_rule, {kIPv4, kIPv6}, add);
}

bool IpTables::AddAcceptRule(const std::string& executable_path,
                             ProtocolEnum protocol,
                             uint16_t port,
                             const std::string& interface) {
  std::vector<std::string> argv;
  argv.push_back(executable_path);
  argv.push_back("-I");  // insert
  argv.push_back("INPUT");
  argv.push_back("-p");  // protocol
  argv.push_back(protocol == kProtocolTcp ? "tcp" : "udp");
  argv.push_back("--dport");  // destination port
  argv.push_back(std::to_string(port));
  if (!interface.empty()) {
    argv.push_back("-i");  // interface
    argv.push_back(interface);
  }
  argv.push_back("-j");
  argv.push_back("ACCEPT");
  argv.push_back("-w");  // Wait for xtables lock.

  // Use CAP_NET_ADMIN|CAP_NET_RAW.
  return RunInMinijail(argv) == 0;
}

bool IpTables::DeleteAcceptRule(const std::string& executable_path,
                                ProtocolEnum protocol,
                                uint16_t port,
                                const std::string& interface) {
  std::vector<std::string> argv;
  argv.push_back(executable_path);
  argv.push_back("-D");  // delete
  argv.push_back("INPUT");
  argv.push_back("-p");  // protocol
  argv.push_back(protocol == kProtocolTcp ? "tcp" : "udp");
  argv.push_back("--dport");  // destination port
  argv.push_back(std::to_string(port));
  if (interface != "") {
    argv.push_back("-i");  // interface
    argv.push_back(interface);
  }
  argv.push_back("-j");
  argv.push_back("ACCEPT");
  argv.push_back("-w");  // Wait for xtables lock.

  // Use CAP_NET_ADMIN|CAP_NET_RAW.
  return RunInMinijail(argv) == 0;
}

bool IpTables::ApplyMasqueradeWithExecutable(const std::string& interface,
                                             const std::string& executable_path,
                                             bool add) {
  bool success = true;
  std::vector<std::string> argv;

  argv.push_back(executable_path);
  argv.push_back("-t");  // table
  argv.push_back("nat");
  argv.push_back(add ? "-A" : "-D");  // rule
  argv.push_back("POSTROUTING");
  argv.push_back("-o");  // output interface
  argv.push_back(interface);
  argv.push_back("-j");
  argv.push_back("MASQUERADE");
  argv.push_back("-w");  // Wait for xtables lock

  // Use CAP_NET_ADMIN|CAP_NET_RAW.
  if (RunInMinijail(argv)) {
    LOG(ERROR) << (add ? "Adding" : "Removing")
               << " masquerade failed for interface " << interface
               << " using '" << executable_path << "'";
    success = false;
    if (add)
      return false;
  }

  argv.clear();
  argv.push_back(executable_path);
  argv.push_back("-t");  // table
  argv.push_back("mangle");
  argv.push_back(add ? "-A" : "-D");  // rule
  argv.push_back("POSTROUTING");
  argv.push_back("-p");
  argv.push_back("tcp");
  argv.push_back("-o");  // output interface
  argv.push_back(interface);
  argv.push_back("--tcp-flags");
  argv.push_back("SYN,RST");
  argv.push_back("SYN");
  argv.push_back("-j");
  argv.push_back("TCPMSS");
  argv.push_back("--clamp-mss-to-pmtu");
  argv.push_back("-w");  // Wait for xtables lock

  if (RunInMinijail(argv)) {
    LOG(ERROR) << (add ? "Adding" : "Removing")
               << " tcpmss rule failed for interface " << interface
               << " using '" << executable_path << "'";
    success = false;
  }

  return success;
}

bool IpTables::ApplyMarkForUserTrafficWithExecutable(
    const std::string& username, const std::string& executable_path, bool add) {
  std::vector<std::string> argv;
  argv.push_back(executable_path);
  argv.push_back("-t");  // table
  argv.push_back("mangle");
  argv.push_back(add ? "-A" : "-D");  // rule
  argv.push_back("OUTPUT");
  argv.push_back("-m");
  argv.push_back("owner");
  argv.push_back("--uid-owner");
  argv.push_back(username);
  argv.push_back("-j");
  argv.push_back("MARK");
  argv.push_back("--set-mark");
  argv.push_back(kMarkForUserTraffic);
  argv.push_back("-w");  // Wait for xtables lock

  // Use CAP_NET_ADMIN|CAP_NET_RAW.
  bool success = RunInMinijail(argv) == 0;

  if (!success) {
      LOG(ERROR) << (add ? "Adding" : "Removing")
                 << " mark failed for user " << username
                 << " using '" << kIpTablesPath << "'";
  }
  return success;
}

bool IpTables::ApplyRuleForUserTrafficWithVersion(const std::string& ip_version,
                                                  bool add) {
  std::vector<std::string> argv;
  argv.push_back(kIpPath);
  if (ip_version == kIPv6)
    argv.push_back("-6");
  argv.push_back("rule");
  argv.push_back(add ? "add" : "delete");
  argv.push_back("fwmark");
  argv.push_back(kMarkForUserTraffic);
  argv.push_back("table");
  argv.push_back(kTableIdForUserTraffic);

  bool success = RunInMinijail(argv) == 0;

  if (!success) {
    LOG(ERROR) << (add ? "Adding" : "Removing")
               << " rule failed for user traffic"
               << " using '" << kIpPath << "'";
  }

  return success;
}

int IpTables::RunInMinijail(const std::vector<std::string>& argv) {
  brillo::Minijail* m = brillo::Minijail::GetInstance();
  minijail* jail = m->New();

  std::vector<char*> args;
  for (const auto& arg : argv) {
    args.push_back(const_cast<char*>(arg.c_str()));
  }
  args.push_back(nullptr);

  int status;
  bool ran = m->RunSyncAndDestroy(jail, args, &status);
  return ran ? status : -1;
}

}  // namespace firewalld
