aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoramadeuszpawlik <apawlik@protonmail.com>2021-05-27 14:07:35 +0200
committerAmadeusz Pawlik <amadeusz.pawlik@getinge.com>2022-10-05 19:30:15 +0200
commit04526787b5f6613d1f1ad78434e1dd24ab88dd76 (patch)
tree042d06ec0cafb8cd9d346ea55bb2ef9bc9b81a61
parentf8387c42343867779170a0f96ef64e6acff5c481 (diff)
downloadbitcoin-04526787b5f6613d1f1ad78434e1dd24ab88dd76.tar.xz
Validate `port` options
Check `port` options for invalid values (ports are parsed as uint16, so in practice values >65535 are invalid; port 0 is undefined and therefore considered invalid too). This allows for an early rejection of faulty values and an supplying an informative message to the user. Splits tests in `feature_proxy.py` to cover both invalid `hostname` and `port` values. Adds a release-note as previously valid `-port` and `-rpcport` values can now result in errors.
-rw-r--r--doc/release-notes-22087.md4
-rw-r--r--src/init.cpp45
-rw-r--r--src/util/error.cpp5
-rw-r--r--src/util/error.h2
-rwxr-xr-xtest/functional/feature_proxy.py33
5 files changed, 80 insertions, 9 deletions
diff --git a/doc/release-notes-22087.md b/doc/release-notes-22087.md
new file mode 100644
index 0000000000..8d7fd242b2
--- /dev/null
+++ b/doc/release-notes-22087.md
@@ -0,0 +1,4 @@
+Updated settings
+----------------
+
+- Ports specified in `-port` and `-rpcport` options are now validated at startup. Values that previously worked and were considered valid can now result in errors. (#22087)
diff --git a/src/init.cpp b/src/init.cpp
index 25b40c6c6e..8ffab64622 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1255,6 +1255,51 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// as they would never get updated.
if (!ignores_incoming_txs) node.fee_estimator = std::make_unique<CBlockPolicyEstimator>(FeeestPath(args));
+ // Check port numbers
+ for (const std::string port_option : {
+ "-port",
+ "-rpcport",
+ }) {
+ if (args.IsArgSet(port_option)) {
+ const std::string port = args.GetArg(port_option, "");
+ uint16_t n;
+ if (!ParseUInt16(port, &n) || n == 0) {
+ return InitError(InvalidPortErrMsg(port_option, port));
+ }
+ }
+ }
+
+ for (const std::string port_option : {
+ "-i2psam",
+ "-onion",
+ "-proxy",
+ "-rpcbind",
+ "-torcontrol",
+ "-whitebind",
+ "-zmqpubhashblock",
+ "-zmqpubhashtx",
+ "-zmqpubrawblock",
+ "-zmqpubrawtx",
+ "-zmqpubsequence",
+ }) {
+ for (const std::string& socket_addr : args.GetArgs(port_option)) {
+ std::string host_out;
+ uint16_t port_out{0};
+ if (!SplitHostPort(socket_addr, port_out, host_out)) {
+ return InitError(InvalidPortErrMsg(port_option, socket_addr));
+ }
+ }
+ }
+
+ for (const std::string& socket_addr : args.GetArgs("-bind")) {
+ std::string host_out;
+ uint16_t port_out{0};
+ std::string bind_socket_addr = socket_addr.substr(0, socket_addr.rfind('='));
+ if (!SplitHostPort(bind_socket_addr, port_out, host_out)) {
+ return InitError(InvalidPortErrMsg("-bind", socket_addr));
+ }
+ }
+
// sanitize comments per BIP-0014, format user agent and check total size
std::vector<std::string> uacomments;
for (const std::string& cmt : args.GetArgs("-uacomment")) {
diff --git a/src/util/error.cpp b/src/util/error.cpp
index 33a35a6d59..390cb6c11b 100644
--- a/src/util/error.cpp
+++ b/src/util/error.cpp
@@ -49,6 +49,11 @@ bilingual_str ResolveErrMsg(const std::string& optname, const std::string& strBi
return strprintf(_("Cannot resolve -%s address: '%s'"), optname, strBind);
}
+bilingual_str InvalidPortErrMsg(const std::string& optname, const std::string& invalid_value)
+{
+ return strprintf(_("Invalid port specified in %s: '%s'"), optname, invalid_value);
+}
+
bilingual_str AmountHighWarn(const std::string& optname)
{
return strprintf(_("%s is set very high!"), optname);
diff --git a/src/util/error.h b/src/util/error.h
index 0429de651a..27916501f0 100644
--- a/src/util/error.h
+++ b/src/util/error.h
@@ -39,6 +39,8 @@ bilingual_str TransactionErrorString(const TransactionError error);
bilingual_str ResolveErrMsg(const std::string& optname, const std::string& strBind);
+bilingual_str InvalidPortErrMsg(const std::string& optname, const std::string& strPort);
+
bilingual_str AmountHighWarn(const std::string& optname);
bilingual_str AmountErrMsg(const std::string& optname, const std::string& strValue);
diff --git a/test/functional/feature_proxy.py b/test/functional/feature_proxy.py
index c90852562e..18b079cd71 100755
--- a/test/functional/feature_proxy.py
+++ b/test/functional/feature_proxy.py
@@ -317,19 +317,34 @@ class ProxyTest(BitcoinTestFramework):
self.stop_node(1)
- self.log.info("Test passing invalid -proxy raises expected init error")
- self.nodes[1].extra_args = ["-proxy=abc:def"]
- msg = "Error: Invalid -proxy address or hostname: 'abc:def'"
+ self.log.info("Test passing invalid -proxy hostname raises expected init error")
+ self.nodes[1].extra_args = ["-proxy=abc..abc:23456"]
+ msg = "Error: Invalid -proxy address or hostname: 'abc..abc:23456'"
self.nodes[1].assert_start_raises_init_error(expected_msg=msg)
- self.log.info("Test passing invalid -onion raises expected init error")
- self.nodes[1].extra_args = ["-onion=xyz:abc"]
- msg = "Error: Invalid -onion address or hostname: 'xyz:abc'"
+ self.log.info("Test passing invalid -proxy port raises expected init error")
+ self.nodes[1].extra_args = ["-proxy=192.0.0.1:def"]
+ msg = "Error: Invalid port specified in -proxy: '192.0.0.1:def'"
self.nodes[1].assert_start_raises_init_error(expected_msg=msg)
- self.log.info("Test passing invalid -i2psam raises expected init error")
- self.nodes[1].extra_args = ["-i2psam=def:xyz"]
- msg = "Error: Invalid -i2psam address or hostname: 'def:xyz'"
+ self.log.info("Test passing invalid -onion hostname raises expected init error")
+ self.nodes[1].extra_args = ["-onion=xyz..xyz:23456"]
+ msg = "Error: Invalid -onion address or hostname: 'xyz..xyz:23456'"
+ self.nodes[1].assert_start_raises_init_error(expected_msg=msg)
+
+ self.log.info("Test passing invalid -onion port raises expected init error")
+ self.nodes[1].extra_args = ["-onion=192.0.0.1:def"]
+ msg = "Error: Invalid port specified in -onion: '192.0.0.1:def'"
+ self.nodes[1].assert_start_raises_init_error(expected_msg=msg)
+
+ self.log.info("Test passing invalid -i2psam hostname raises expected init error")
+ self.nodes[1].extra_args = ["-i2psam=def..def:23456"]
+ msg = "Error: Invalid -i2psam address or hostname: 'def..def:23456'"
+ self.nodes[1].assert_start_raises_init_error(expected_msg=msg)
+
+ self.log.info("Test passing invalid -i2psam port raises expected init error")
+ self.nodes[1].extra_args = ["-i2psam=192.0.0.1:def"]
+ msg = "Error: Invalid port specified in -i2psam: '192.0.0.1:def'"
self.nodes[1].assert_start_raises_init_error(expected_msg=msg)
self.log.info("Test passing invalid -onlynet=i2p without -i2psam raises expected init error")