From aad2f87a53eb8a1c0a20c96067d0c8066f5cab55 Mon Sep 17 00:00:00 2001
From: selsta <selsta@sent.at>
Date: Mon, 19 Oct 2020 21:02:59 +0200
Subject: [PATCH] net_node: add --ban-list option

---
 src/p2p/net_node.cpp |  1 +
 src/p2p/net_node.h   |  1 +
 src/p2p/net_node.inl | 31 +++++++++++++++++++++++++++++++
 3 files changed, 33 insertions(+)

diff --git a/src/p2p/net_node.cpp b/src/p2p/net_node.cpp
index 1c5dca0d7..aee1fa593 100644
--- a/src/p2p/net_node.cpp
+++ b/src/p2p/net_node.cpp
@@ -146,6 +146,7 @@ namespace nodetool
     const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_seed_node   = {"seed-node", "Connect to a node to retrieve peer addresses, and disconnect"};
     const command_line::arg_descriptor<std::vector<std::string> > arg_tx_proxy = {"tx-proxy", "Send local txes through proxy: <network-type>,<socks-ip:port>[,max_connections][,disable_noise] i.e. \"tor,127.0.0.1:9050,100,disable_noise\""};
     const command_line::arg_descriptor<std::vector<std::string> > arg_anonymous_inbound = {"anonymous-inbound", "<hidden-service-address>,<[bind-ip:]port>[,max_connections] i.e. \"x.onion,127.0.0.1:18083,100\""};
+    const command_line::arg_descriptor<std::string> arg_ban_list = {"ban-list", "Specify ban list file, one IP address per line"};
     const command_line::arg_descriptor<bool> arg_p2p_hide_my_port   =    {"hide-my-port", "Do not announce yourself as peerlist candidate", false, true};
     const command_line::arg_descriptor<bool> arg_no_sync = {"no-sync", "Don't synchronize the blockchain with other peers", false};
 
diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h
index 97835edd4..7204ce66b 100644
--- a/src/p2p/net_node.h
+++ b/src/p2p/net_node.h
@@ -523,6 +523,7 @@ namespace nodetool
     extern const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_seed_node;
     extern const command_line::arg_descriptor<std::vector<std::string> > arg_tx_proxy;
     extern const command_line::arg_descriptor<std::vector<std::string> > arg_anonymous_inbound;
+    extern const command_line::arg_descriptor<std::string> arg_ban_list;
     extern const command_line::arg_descriptor<bool> arg_p2p_hide_my_port;
     extern const command_line::arg_descriptor<bool> arg_no_sync;
 
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index aa16e93d5..3d96ead9f 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -106,6 +106,7 @@ namespace nodetool
     command_line::add_arg(desc, arg_p2p_seed_node);
     command_line::add_arg(desc, arg_tx_proxy);
     command_line::add_arg(desc, arg_anonymous_inbound);
+    command_line::add_arg(desc, arg_ban_list);
     command_line::add_arg(desc, arg_p2p_hide_my_port);
     command_line::add_arg(desc, arg_no_sync);
     command_line::add_arg(desc, arg_no_igd);
@@ -441,6 +442,36 @@ namespace nodetool
         return false;
     }
 
+    if (!command_line::is_arg_defaulted(vm, arg_ban_list))
+    {
+      const std::string ban_list = command_line::get_arg(vm, arg_ban_list);
+
+      const boost::filesystem::path ban_list_path(ban_list);
+      boost::system::error_code ec;
+      if (!boost::filesystem::exists(ban_list_path, ec))
+      {
+        throw std::runtime_error("Can't find ban list file " + ban_list + " - " + ec.message());
+      }
+
+      std::string banned_ips;
+      if (!epee::file_io_utils::load_file_to_string(ban_list_path.string(), banned_ips))
+      {
+        throw std::runtime_error("Failed to read ban list file " + ban_list);
+      }
+
+      std::istringstream iss(banned_ips);
+      for (std::string line; std::getline(iss, line); )
+      {
+        const expect<epee::net_utils::network_address> parsed_addr = net::get_network_address(line, 0);
+        if (!parsed_addr)
+        {
+          MERROR("Invalid IP address: " << line << " - " << parsed_addr.error());
+          continue;
+        }
+        block_host(*parsed_addr, std::numeric_limits<time_t>::max());
+      }
+    }
+
     if(command_line::has_arg(vm, arg_p2p_hide_my_port))
       m_hide_my_port = true;