Skip to content

Commit 283f22c

Browse files
author
MarcoFalke
committed
Merge bitcoin#20461: rpc: Validate -rpcauth arguments
053b4fb doc: Release note regarding -rpcauth validation (João Barbosa) 4600132 rpc: Validate -rpcauth arguments (João Barbosa) d37c813 rpc: Refactor to process -rpcauth once (João Barbosa) Pull request description: Invalid `-rpcauth` arguments are currently silently ignored. This make server initialization fail if any `-rpcauth` is invalid. ACKs for top commit: MarcoFalke: review ACK 053b4fb jonatack: ACK 053b4fb ryanofsky: Code review ACK 053b4fb. Only changes since last review are moving a variable declaration and adding a comment, release notes, and a `const`. Tree-SHA512: c99923d4a121f0c9f882b07f5402ea53e9b2d9455ad34468a094ffab1d64df26c82e1279734c0d42bc2e113eae7b581fbc3be52f3ed4a2d7450d11793afcf406
2 parents 607c844 + 053b4fb commit 283f22c

File tree

3 files changed

+24
-11
lines changed

3 files changed

+24
-11
lines changed

doc/release-notes.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ Updated settings
8080

8181
Changes to Wallet or GUI related settings can be found in the GUI or Wallet section below.
8282

83+
- Passing an invalid `-rpcauth` argument now cause bitcoind to fail to start. (#20461)
84+
8385
Tools and Utilities
8486
-------------------
8587

src/httprpc.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ class HTTPRPCTimerInterface : public RPCTimerInterface
6868
static std::string strRPCUserColonPass;
6969
/* Stored RPC timer interface (for unregistration) */
7070
static std::unique_ptr<HTTPRPCTimerInterface> httpRPCTimerInterface;
71+
/* List of -rpcauth values */
72+
static std::vector<std::vector<std::string>> g_rpcauth;
7173
/* RPC Auth Whitelist */
7274
static std::map<std::string, std::set<std::string>> g_rpc_whitelist;
7375
static bool g_rpc_whitelist_default = false;
@@ -99,15 +101,7 @@ static bool multiUserAuthorized(std::string strUserPass)
99101
std::string strUser = strUserPass.substr(0, strUserPass.find(':'));
100102
std::string strPass = strUserPass.substr(strUserPass.find(':') + 1);
101103

102-
for (const std::string& strRPCAuth : gArgs.GetArgs("-rpcauth")) {
103-
//Search for multi-user login/pass "rpcauth" from config
104-
std::vector<std::string> vFields;
105-
boost::split(vFields, strRPCAuth, boost::is_any_of(":$"));
106-
if (vFields.size() != 3) {
107-
//Incorrect formatting in config file
108-
continue;
109-
}
110-
104+
for (const auto& vFields : g_rpcauth) {
111105
std::string strName = vFields[0];
112106
if (!TimingResistantEqual(strName, strUser)) {
113107
continue;
@@ -259,6 +253,16 @@ static bool InitRPCAuthentication()
259253
if (gArgs.GetArg("-rpcauth","") != "")
260254
{
261255
LogPrintf("Using rpcauth authentication.\n");
256+
for (const std::string& rpcauth : gArgs.GetArgs("-rpcauth")) {
257+
std::vector<std::string> fields;
258+
boost::split(fields, rpcauth, boost::is_any_of(":$"));
259+
if (fields.size() == 3) {
260+
g_rpcauth.push_back(fields);
261+
} else {
262+
LogPrintf("Invalid -rpcauth argument.\n");
263+
return false;
264+
}
265+
}
262266
}
263267

264268
g_rpc_whitelist_default = gArgs.GetBoolArg("-rpcwhitelistdefault", gArgs.IsArgSet("-rpcwhitelist"));

test/functional/rpc_users.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,18 @@ def run_test(self):
9999

100100
self.test_auth(self.nodes[1], self.rpcuser, self.rpcpassword)
101101

102-
self.log.info('Check that failure to write cookie file will abort the node gracefully')
102+
init_error = 'Error: Unable to start HTTP server. See debug log for details.'
103+
104+
self.log.info('Check -rpcauth are validated')
105+
# Empty -rpcauth= are ignored
106+
self.restart_node(0, extra_args=['-rpcauth='])
103107
self.stop_node(0)
108+
self.nodes[0].assert_start_raises_init_error(expected_msg=init_error, extra_args=['-rpcauth=foo'])
109+
self.nodes[0].assert_start_raises_init_error(expected_msg=init_error, extra_args=['-rpcauth=foo:bar'])
110+
111+
self.log.info('Check that failure to write cookie file will abort the node gracefully')
104112
cookie_file = os.path.join(get_datadir_path(self.options.tmpdir, 0), self.chain, '.cookie.tmp')
105113
os.mkdir(cookie_file)
106-
init_error = 'Error: Unable to start HTTP server. See debug log for details.'
107114
self.nodes[0].assert_start_raises_init_error(expected_msg=init_error)
108115

109116

0 commit comments

Comments
 (0)