// Copyright 2015 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 "lorgnette/firewall_manager.h"

#include <algorithm>
#include <vector>

#include <base/bind.h>
#include <base/check.h>
#include <brillo/errors/error.h>

using std::string;

namespace lorgnette {

namespace {

const uint16_t kCanonBjnpPort = 8612;

}  // namespace

PortToken::PortToken(base::WeakPtr<FirewallManager> firewall_manager,
                     uint16_t port)
    : firewall_manager_(firewall_manager), port_(port) {}

PortToken::PortToken(PortToken&& token) : firewall_manager_(nullptr), port_(0) {
  firewall_manager_ = token.firewall_manager_;
  port_ = token.port_;

  token.firewall_manager_ = nullptr;
  token.port_ = 0;
}

PortToken::~PortToken() {
  if (firewall_manager_)
    firewall_manager_->ReleaseUdpPortAccess(port_);
}

FirewallManager::FirewallManager(const std::string& interface)
    : interface_(interface) {}

void FirewallManager::Init(const scoped_refptr<dbus::Bus>& bus) {
  CHECK(!permission_broker_proxy_) << "Already started";

  if (!SetupLifelinePipe()) {
    return;
  }

  if (!bus) {
    LOG(ERROR) << "Bus is null; assuming we are in tests.";
    return;
  }

  permission_broker_proxy_.reset(new org::chromium::PermissionBrokerProxy(bus));

  // This will connect the name owner changed signal in DBus object proxy,
  // The callback will be invoked as soon as service is avalilable and will
  // be cleared after it is invoked. So this will be an one time callback.
  permission_broker_proxy_->GetObjectProxy()->WaitForServiceToBeAvailable(
      base::BindOnce(&FirewallManager::OnServiceAvailable,
                     weak_factory_.GetWeakPtr()));

  // This will continuously monitor the name owner of the service. However,
  // it does not connect the name owner changed signal in DBus object proxy
  // for some reason. In order to connect the name owner changed signal,
  // either WaitForServiceToBeAvaiable or ConnectToSignal need to be invoked.
  // Since we're not interested in any signals from the proxy,
  // WaitForServiceToBeAvailable is used.
  permission_broker_proxy_->GetObjectProxy()->SetNameOwnerChangedCallback(
      base::BindRepeating(&FirewallManager::OnServiceNameChanged,
                          weak_factory_.GetWeakPtr()));
}

PortToken FirewallManager::RequestPixmaPortAccess() {
  // Request access for the well-known port used by the Pixma backend.
  return RequestUdpPortAccess(kCanonBjnpPort);
}

bool FirewallManager::SetupLifelinePipe() {
  if (lifeline_read_.is_valid()) {
    LOG(ERROR) << "Lifeline pipe already created";
    return false;
  }

  // Setup lifeline pipe.
  int fds[2];
  if (pipe(fds) != 0) {
    PLOG(ERROR) << "Failed to create lifeline pipe";
    return false;
  }
  lifeline_read_ = base::ScopedFD(fds[0]);
  lifeline_write_ = base::ScopedFD(fds[1]);

  return true;
}

void FirewallManager::OnServiceAvailable(bool service_available) {
  LOG(INFO) << "FirewallManager::OnServiceAvailabe " << service_available;
  // Nothing to be done if proxy service is not available.
  if (!service_available) {
    return;
  }
  RequestAllPortsAccess();
}

void FirewallManager::OnServiceNameChanged(const string& old_owner,
                                           const string& new_owner) {
  LOG(INFO) << "FirewallManager::OnServiceNameChanged old " << old_owner
            << " new " << new_owner;
  // Nothing to be done if no owner is attached to the proxy service.
  if (new_owner.empty()) {
    return;
  }
  RequestAllPortsAccess();
}

void FirewallManager::RequestAllPortsAccess() {
  std::set<uint16_t> attempted_ports;
  attempted_ports.swap(requested_ports_);
  for (const auto& port : attempted_ports) {
    SendPortAccessRequest(port);
  }
}

void FirewallManager::SendPortAccessRequest(uint16_t port) {
  if (!permission_broker_proxy_) {
    LOG(INFO) << "Permission broker does not exist (yet); adding request for "
              << "port " << port << " to queue.";
    requested_ports_.insert(port);
    return;
  }

  bool allowed = false;
  // Pass the read end of the pipe to permission_broker, for it to monitor this
  // process.
  brillo::ErrorPtr error;
  if (!permission_broker_proxy_->RequestUdpPortAccess(
          port, interface_, lifeline_read_.get(), &allowed, &error)) {
    LOG(ERROR) << "Failed to request UDP port access: " << error->GetCode()
               << " " << error->GetMessage();
    return;
  }
  if (!allowed) {
    LOG(ERROR) << "Access request for UDP port " << port << " on interface "
               << interface_ << " is denied";
    return;
  }
  LOG(INFO) << "Access granted for UDP port " << port << " on interface "
            << interface_;
  requested_ports_.insert(port);
}

PortToken FirewallManager::RequestUdpPortAccess(uint16_t port) {
  SendPortAccessRequest(port);
  return PortToken(weak_factory_.GetWeakPtr(), port);
}

void FirewallManager::ReleaseUdpPortAccess(uint16_t port) {
  brillo::ErrorPtr error;
  bool success;
  if (requested_ports_.find(port) == requested_ports_.end()) {
    LOG(ERROR) << "UDP access has not been requested for port: " << port;
    return;
  }
  if (!permission_broker_proxy_) {
    requested_ports_.erase(port);
    return;
  }

  if (!permission_broker_proxy_->ReleaseUdpPort(port, interface_, &success,
                                                &error)) {
    LOG(ERROR) << "Failed to release UDP port access: " << error->GetCode()
               << " " << error->GetMessage();
    return;
  }
  if (!success) {
    LOG(ERROR) << "Release request for UDP port " << port << " on interface "
               << interface_ << " is denied";
    return;
  }
  LOG(INFO) << "Access released for UDP port " << port << " on interface "
            << interface_;
  requested_ports_.erase(port);
}

}  // namespace lorgnette
