// Copyright 2018 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 <arpa/inet.h>
#include <net/if.h>

#include <fuzzer/FuzzedDataProvider.h>
#include <set>

#include "base/logging.h"
#include "base/notreached.h"

#include "permission_broker/port_tracker.h"

namespace permission_broker {

class FakePortTracker : public PortTracker {
 public:
  FakePortTracker() : PortTracker(nullptr), next_fd_{1} {}
  FakePortTracker(const FakePortTracker&) = delete;
  FakePortTracker& operator=(const FakePortTracker&) = delete;
  ~FakePortTracker() override = default;

  bool ModifyPortRule(patchpanel::ModifyPortRuleRequest::Operation,
                      const PortRule& rule) override {
    return true;
  }
  int AddLifelineFd(int dbus_fd) override { return next_fd_++; }
  bool DeleteLifelineFd(int fd) override { return true; }

 private:
  int next_fd_;
};

// Helper struct for keeping track of randomly generated request.
struct FuzzRequest {
  PortTracker::PortRuleType type;
  Protocol proto;
  uint16_t port;
  std::string ifname;
};

// Implements a total order for FuzzRequest to insert them in std::set.
bool operator<(const FuzzRequest& lhs, const FuzzRequest& rhs) {
  if (lhs.type != rhs.type) {
    return lhs.type < rhs.type;
  }
  if (lhs.proto != rhs.proto) {
    return lhs.proto < rhs.proto;
  }
  if (lhs.port != rhs.port) {
    return lhs.port < rhs.port;
  }
  return lhs.ifname < rhs.ifname;
}

struct FuzzRequest MakeRandomRequest(FuzzedDataProvider& provider) {
  return {
      .type = provider.ConsumeEnum<PortTracker::PortRuleType>(),
      .proto = provider.ConsumeBool() ? ModifyPortRuleRequest::TCP
                                      : ModifyPortRuleRequest::UDP,
      .port = provider.ConsumeIntegral<uint16_t>(),
      .ifname = provider.ConsumeRandomLengthString(IFNAMSIZ - 1),
  };
}

bool AddRule(FuzzedDataProvider& provider,
             FakePortTracker& port_tracker,
             const FuzzRequest& request) {
  int dbus_fd = provider.ConsumeIntegral<int>();
  switch (request.type) {
    case PortTracker::kUnknownRule:
      // Ignore random rule generated with this default type value.
      return false;
    case PortTracker::kAccessRule:
      if (request.proto == ModifyPortRuleRequest::TCP) {
        return port_tracker.AllowTcpPortAccess(request.port, request.ifname,
                                               dbus_fd);
      } else {
        return port_tracker.AllowUdpPortAccess(request.port, request.ifname,
                                               dbus_fd);
      }
    case PortTracker::kLockdownRule:
      if (request.proto == ModifyPortRuleRequest::UDP) {
        // Invalid lockdown rule request, ignore.
        return false;
      }
      return port_tracker.LockDownLoopbackTcpPort(request.port, dbus_fd);
    case PortTracker::kForwardingRule: {
      struct in_addr ip_addr = {.s_addr = provider.ConsumeIntegral<uint32_t>()};
      char buffer[INET_ADDRSTRLEN];
      memset(buffer, 0, INET_ADDRSTRLEN);
      inet_ntop(AF_INET, &ip_addr, buffer, INET_ADDRSTRLEN);
      std::string dst_ip = buffer;
      uint16_t dst_port = provider.ConsumeIntegral<uint16_t>();
      if (request.proto == ModifyPortRuleRequest::TCP) {
        return port_tracker.StartTcpPortForwarding(request.port, request.ifname,
                                                   dst_ip, dst_port, dbus_fd);
      } else {
        return port_tracker.StartUdpPortForwarding(request.port, request.ifname,
                                                   dst_ip, dst_port, dbus_fd);
      }
    }
    default:
      NOTREACHED();
      return false;
  }
}

bool RemoveRule(FakePortTracker& port_tracker, const FuzzRequest& request) {
  switch (request.type) {
    case PortTracker::kUnknownRule:
      // Ignore random rule generated with this default type value.
      return false;
    case PortTracker::kAccessRule:
      if (request.proto == ModifyPortRuleRequest::TCP) {
        return port_tracker.RevokeTcpPortAccess(request.port, request.ifname);
      } else {
        return port_tracker.RevokeUdpPortAccess(request.port, request.ifname);
      }
    case PortTracker::kLockdownRule:
      if (request.proto == ModifyPortRuleRequest::UDP) {
        // Invalid lockdown rule request, ignore.
        return false;
      }
      return port_tracker.ReleaseLoopbackTcpPort(request.port);
    case PortTracker::kForwardingRule:
      if (request.proto == ModifyPortRuleRequest::TCP) {
        return port_tracker.StopTcpPortForwarding(request.port, request.ifname);
      } else {
        return port_tracker.StopUdpPortForwarding(request.port, request.ifname);
      }
    default:
      NOTREACHED();
      return false;
  }
}
}  // namespace permission_broker

struct Environment {
  Environment() { logging::SetMinLogLevel(logging::LOGGING_FATAL); }
};

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  static Environment env;

  permission_broker::FakePortTracker port_tracker;
  std::set<permission_broker::FuzzRequest> existing_rules;
  FuzzedDataProvider provider(data, size);

  while (provider.remaining_bytes() > 0) {
    float p = provider.ConsumeProbability<float>();
    if (p < 0.05) {
      // Try removing a non-existing rule 5% of the time.
      while (provider.remaining_bytes() > 0) {
        permission_broker::FuzzRequest r =
            permission_broker::MakeRandomRequest(provider);
        if (existing_rules.find(r) != existing_rules.end()) {
          // Collision with existing rule, retry.
          continue;
        }
        if (RemoveRule(port_tracker, r)) {
          // RemoveRule should fail.
          return -1;
        }
        break;
      }
    } else if (p < 0.10 && !existing_rules.empty()) {
      // Try re-adding an existing rule another 5% of the time.
      auto it = std::begin(existing_rules);
      std::advance(it, provider.ConsumeIntegralInRange<int>(
                           0, existing_rules.size() - 1));
      if (AddRule(provider, port_tracker, *it)) {
        // AddRule should fail.
        return -1;
      }
    } else if (p < existing_rules.size() / 100) {
      // Otherwise either generate a new rule or delete an existing rule.
      // Deletion attempts are more likely the more rules already exist.
      auto it = std::begin(existing_rules);
      std::advance(it, provider.ConsumeIntegralInRange<int>(
                           0, existing_rules.size() - 1));
      if (!RemoveRule(port_tracker, *it)) {
        // RemoveRule should succeed.
        return -1;
      }
      existing_rules.erase(it);
    } else {
      permission_broker::FuzzRequest r =
          permission_broker::MakeRandomRequest(provider);
      // Ignore invalid requests.
      if (AddRule(provider, port_tracker, r)) {
        existing_rules.insert(r);
      }
    }
  }

  return 0;
}
