aboutsummaryrefslogtreecommitdiff
path: root/src/net_permissions.cpp
diff options
context:
space:
mode:
authornicolas.dorier <nicolas.dorier@gmail.com>2019-06-20 18:37:51 +0900
committernicolas.dorier <nicolas.dorier@gmail.com>2019-08-11 11:33:27 +0900
commite5b26deaaa6842f7dd7c4537ede000f965ea0189 (patch)
treec45a24d8290b86ef74bb6b95287de5972768caa2 /src/net_permissions.cpp
parente5fdda68c6d2313edb74443f0d1e6d2ce2d97f5e (diff)
downloadbitcoin-e5b26deaaa6842f7dd7c4537ede000f965ea0189.tar.xz
Make whitebind/whitelist permissions more flexible
Diffstat (limited to 'src/net_permissions.cpp')
-rw-r--r--src/net_permissions.cpp106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/net_permissions.cpp b/src/net_permissions.cpp
new file mode 100644
index 0000000000..736f19293a
--- /dev/null
+++ b/src/net_permissions.cpp
@@ -0,0 +1,106 @@
+// Copyright (c) 2009-2018 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <net_permissions.h>
+#include <util/system.h>
+#include <util/translation.h>
+#include <netbase.h>
+
+// The parse the following format "perm1,perm2@xxxxxx"
+bool TryParsePermissionFlags(const std::string str, NetPermissionFlags& output, size_t& readen, std::string& error)
+{
+ NetPermissionFlags flags = PF_NONE;
+ const auto atSeparator = str.find('@');
+
+ // if '@' is not found (ie, "xxxxx"), the caller should apply implicit permissions
+ if (atSeparator == std::string::npos) {
+ NetPermissions::AddFlag(flags, PF_ISIMPLICIT);
+ readen = 0;
+ }
+ // else (ie, "perm1,perm2@xxxxx"), let's enumerate the permissions by splitting by ',' and calculate the flags
+ else {
+ readen = 0;
+ // permissions == perm1,perm2
+ const auto permissions = str.substr(0, atSeparator);
+ while (readen < permissions.length()) {
+ const auto commaSeparator = permissions.find(',', readen);
+ const auto len = commaSeparator == std::string::npos ? permissions.length() - readen : commaSeparator - readen;
+ // permission == perm1
+ const auto permission = permissions.substr(readen, len);
+ readen += len; // We read "perm1"
+ if (commaSeparator != std::string::npos) readen++; // We read ","
+
+ if (permission == "bloomfilter" || permission == "bloom") NetPermissions::AddFlag(flags, PF_BLOOMFILTER);
+ else if (permission == "noban") NetPermissions::AddFlag(flags, PF_NOBAN);
+ else if (permission == "forcerelay") NetPermissions::AddFlag(flags, PF_FORCERELAY);
+ else if (permission == "mempool") NetPermissions::AddFlag(flags, PF_MEMPOOL);
+ else if (permission == "all") NetPermissions::AddFlag(flags, PF_ALL);
+ else if (permission == "relay") NetPermissions::AddFlag(flags, PF_RELAY);
+ else if (permission.length() == 0); // Allow empty entries
+ else {
+ error = strprintf(_("Invalid P2P permission: '%s'").translated, permission);
+ return false;
+ }
+ }
+ readen++;
+ }
+
+ output = flags;
+ error = "";
+ return true;
+}
+
+std::vector<std::string> NetPermissions::ToStrings(NetPermissionFlags flags)
+{
+ std::vector<std::string> strings;
+ if (NetPermissions::HasFlag(flags, PF_BLOOMFILTER)) strings.push_back("bloomfilter");
+ if (NetPermissions::HasFlag(flags, PF_NOBAN)) strings.push_back("noban");
+ if (NetPermissions::HasFlag(flags, PF_FORCERELAY)) strings.push_back("forcerelay");
+ if (NetPermissions::HasFlag(flags, PF_RELAY)) strings.push_back("relay");
+ if (NetPermissions::HasFlag(flags, PF_MEMPOOL)) strings.push_back("mempool");
+ return strings;
+}
+
+bool NetWhitebindPermissions::TryParse(const std::string str, NetWhitebindPermissions& output, std::string& error)
+{
+ NetPermissionFlags flags;
+ size_t offset;
+ if (!TryParsePermissionFlags(str, flags, offset, error)) return false;
+
+ const std::string strBind = str.substr(offset);
+ CService addrBind;
+ if (!Lookup(strBind.c_str(), addrBind, 0, false)) {
+ error = strprintf(_("Cannot resolve -%s address: '%s'").translated, "whitebind", strBind);
+ return false;
+ }
+ if (addrBind.GetPort() == 0) {
+ error = strprintf(_("Need to specify a port with -whitebind: '%s'").translated, strBind);
+ return false;
+ }
+
+ output.m_flags = flags;
+ output.m_service = addrBind;
+ error = "";
+ return true;
+}
+
+bool NetWhitelistPermissions::TryParse(const std::string str, NetWhitelistPermissions& output, std::string& error)
+{
+ NetPermissionFlags flags;
+ size_t offset;
+ if (!TryParsePermissionFlags(str, flags, offset, error)) return false;
+
+ const std::string net = str.substr(offset);
+ CSubNet subnet;
+ LookupSubNet(net.c_str(), subnet);
+ if (!subnet.IsValid()) {
+ error = strprintf(_("Invalid netmask specified in -whitelist: '%s'").translated, net);
+ return false;
+ }
+
+ output.m_flags = flags;
+ output.m_subnet = subnet;
+ error = "";
+ return true;
+}