Skip to content

Commit 746f880

Browse files
committed
Merge bitcoin/bitcoin#30401: fix: increase consistency of rpcauth parsing
27c976d fix: increase consistency of rpcauth parsing (tdb3) 2ad3689 test: add norpcauth test (tdb3) 67df0de test: blank rpcauth CLI interaction (tdb3) ecc98cc test: add cases for blank rpcauth (tdb3) Pull request description: The current `rpcauth` parsing behavior is inconsistent and unintuitive (see bitcoin/bitcoin#29141 (comment) and additional details below). The current behavior inconsistently treats empty `rpcauth` as an error (or not) depending on the location within CLI/bitcoin.conf and the location of adjacent valid `rpcauth` params. Empty `rpcauth` is now consistently treated as an error and prevents bitcoind from starting. Continuation of the upforgrabs PR #29141. ### Additional details: Current `rpcauth` behavior is nonsensical: - If an empty `rpcauth` argument was specified as the last command line argument, it would cause all other `rpcauth` arguments to be ignored. - If an empty `rpcauth` argument was specified on the command line followed by any nonempty `rpcauth` argument, it would cause an error. - If an empty `rpcauth=` line was specified after non-empty rpcauth line in the config file it would cause an error. - If an empty `rpcauth=` line in a config file was first it would cause other rpcauth entries in the config file to be ignored, unless there were `-rpcauth` command line arguments and the last one was nonempty, in which case it would cause an error. New behavior is simple: - If an empty rpcauth config line or command line argument is used it will cause an error ACKs for top commit: naiyoma: Tested ACK [https://github.com/bitcoin/bitcoin/commit/27c976d11a68d66db97d9a7a30c6a6a71c6ab586](https://github.com/bitcoin/bitcoin/commit/27c976d11a68d66db97d9a7a30c6a6a71c6ab586) achow101: ACK 27c976d ryanofsky: Code review ACK 27c976d. Since last review commit message was just tweaked to clarify previous behavior. Tree-SHA512: af2e9dd60d1ad030409ae2c3805ab139c7435327823d9f8bbeede815f376cb696a5929b08a6e8c8b5f7278ed49cfb231789f9041bd57f1f03ec96501b669da5b
2 parents df86a4f + 27c976d commit 746f880

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

src/httprpc.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,8 +314,9 @@ static bool InitRPCAuthentication()
314314
LogPrintf("Config options rpcuser and rpcpassword will soon be deprecated. Locally-run instances may remove rpcuser to use cookie-based auth, or may be replaced with rpcauth. Please see share/rpcauth for rpcauth auth generation.\n");
315315
strRPCUserColonPass = gArgs.GetArg("-rpcuser", "") + ":" + gArgs.GetArg("-rpcpassword", "");
316316
}
317-
if (gArgs.GetArg("-rpcauth", "") != "") {
318-
LogPrintf("Using rpcauth authentication.\n");
317+
318+
if (!gArgs.GetArgs("-rpcauth").empty()) {
319+
LogInfo("Using rpcauth authentication.\n");
319320
for (const std::string& rpcauth : gArgs.GetArgs("-rpcauth")) {
320321
std::vector<std::string> fields{SplitString(rpcauth, ':')};
321322
const std::vector<std::string> salt_hmac{SplitString(fields.back(), '$')};

test/functional/rpc_users.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,15 +139,32 @@ def run_test(self):
139139
init_error = 'Error: Unable to start HTTP server. See debug log for details.'
140140

141141
self.log.info('Check -rpcauth are validated')
142-
# Empty -rpcauth= are ignored
143-
self.restart_node(0, extra_args=['-rpcauth='])
142+
self.log.info('Empty -rpcauth are treated as error')
144143
self.stop_node(0)
144+
self.nodes[0].assert_start_raises_init_error(expected_msg=init_error, extra_args=['-rpcauth'])
145+
self.nodes[0].assert_start_raises_init_error(expected_msg=init_error, extra_args=['-rpcauth='])
146+
self.nodes[0].assert_start_raises_init_error(expected_msg=init_error, extra_args=['-rpcauth=""'])
147+
self.log.info('Check malformed -rpcauth')
145148
self.nodes[0].assert_start_raises_init_error(expected_msg=init_error, extra_args=['-rpcauth=foo'])
146149
self.nodes[0].assert_start_raises_init_error(expected_msg=init_error, extra_args=['-rpcauth=foo:bar'])
147150
self.nodes[0].assert_start_raises_init_error(expected_msg=init_error, extra_args=['-rpcauth=foo:bar:baz'])
148151
self.nodes[0].assert_start_raises_init_error(expected_msg=init_error, extra_args=['-rpcauth=foo$bar:baz'])
149152
self.nodes[0].assert_start_raises_init_error(expected_msg=init_error, extra_args=['-rpcauth=foo$bar$baz'])
150153

154+
self.log.info('Check interactions between blank and non-blank rpcauth')
155+
# pw = bitcoin
156+
rpcauth_user1 = '-rpcauth=user1:6dd184e5e69271fdd69103464630014f$eb3d7ce67c4d1ff3564270519b03b636c0291012692a5fa3dd1d2075daedd07b'
157+
rpcauth_user2 = '-rpcauth=user2:57b2f77c919eece63cfa46c2f06e46ae$266b63902f99f97eeaab882d4a87f8667ab84435c3799f2ce042ef5a994d620b'
158+
self.nodes[0].assert_start_raises_init_error(expected_msg=init_error, extra_args=[rpcauth_user1, rpcauth_user2, '-rpcauth='])
159+
self.nodes[0].assert_start_raises_init_error(expected_msg=init_error, extra_args=[rpcauth_user1, '-rpcauth=', rpcauth_user2])
160+
self.nodes[0].assert_start_raises_init_error(expected_msg=init_error, extra_args=['-rpcauth=', rpcauth_user1, rpcauth_user2])
161+
162+
self.log.info('Check -norpcauth disables previous -rpcauth params')
163+
self.restart_node(0, extra_args=[rpcauth_user1, rpcauth_user2, '-norpcauth'])
164+
assert_equal(401, call_with_auth(self.nodes[0], 'user1', 'bitcoin').status)
165+
assert_equal(401, call_with_auth(self.nodes[0], 'rt', self.rtpassword).status)
166+
self.stop_node(0)
167+
151168
self.log.info('Check that failure to write cookie file will abort the node gracefully')
152169
(self.nodes[0].chain_path / ".cookie.tmp").mkdir()
153170
self.nodes[0].assert_start_raises_init_error(expected_msg=init_error)

0 commit comments

Comments
 (0)