-
Notifications
You must be signed in to change notification settings - Fork 37.8k
rpc: Implement random-cookie based authentication #6388
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@@ -287,3 +289,68 @@ UniValue JSONRPCError(int code, const string& message) | |||
error.push_back(Pair("message", message)); | |||
return error; | |||
} | |||
|
|||
/** Username used when cookie authentication is in use (arbitrary, only for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not convinced that this code actually belongs in rpcprotocol
, it is here because that file is shared between bitcoin-cli and bitcoind server, but conceptually it exists on a higher level than the protocol. Feel free to suggest a better place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think rpcprotocol.h/.cpp
is a good place for this extension. A new cookieauth.h/cpp
file would be possible but i think is more compact and neatly arranged if it stays in rpcprotocol.h/cpp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Making a new file pair e.g. rpcauthcookie
sounds good to me too. But I don't feel strongly about it either.
The low-level code from rpcprotocol will be unnecessary with the libevent-based HTTP server (#5677), so this will at least leave something there :)
Nice! Reviewing this... |
I spent some time trying to break this, and was unable to do so. This grinds off one of bitcoind's most annoying burrs, very nice! One thing to note is that some of the init scripts in the contrib directory have checks for a set rpcpassword, so when this goes in those should be removed. |
@@ -597,28 +597,16 @@ void StartRPCThreads() | |||
strAllowed += subnet.ToString() + " "; | |||
LogPrint("rpc", "Allowing RPC connections from: %s\n", strAllowed); | |||
|
|||
strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; | |||
if (((mapArgs["-rpcpassword"] == "") || | |||
(mapArgs["-rpcuser"] == mapArgs["-rpcpassword"])) && Params().RequireRPCPassword()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this if needs to be rewritten because at the moment the cookie system does not work in regtest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd personally love to get rid of Params().RequireRPCPassword()
, also for consistency reasons. But I think it's unrelated to this pull - on regtest, setting an empty password is currently just allowed, so takes precedence.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm... but the following way don't work.
jonasschnelli$ ./src/bitcoind --regtest --datadir=/tmp/dummy2 --printtoconsole
(fresh datadir)
jonasschnelli$ ./src/bitcoin-cli --regtest --datadir=/tmp/dummy2/ help
error: You must set rpcpassword=<password> in the configuration file:
/tmp/dummy2/bitcoin.conf
If the file does not exist, create it with owner-readable-only file permissions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, so bitcoin-cli should mind that flag as well (for now). Thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bleh, that'd mean moving the flag to BaseParams...
Nice work! |
// Try fall back to cookie-based authentication if no password is provided | ||
if (!GetAuthCookie(&strRPCUserColonPass)) { | ||
throw runtime_error(strprintf( | ||
_("You must set rpcpassword=<password> in the configuration file:\n%s\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mention in this help text that the ability to write to [authfilepath] would also solve the problem? Now it may be confusing as being unable to write a file results in a help text mentioning some unrelated config option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This message triggers if it is unable to read from the file, e.g. if it doesn't exist, but is somehow able to connect. This is a very strange situation, but it won't be solved by ability to write anywhere.
(bitcoind won't even start if no rpcpassword is set but it is unable to write the cookie file)
I've never liked the chain-specific exception to having to set a password. It gives issues with bitcoin#6388 which makes it valid to set no password in every case (as it enables random cookie authentication). This pull removes the flag, so that all chains are regarded the same. It also removes the username==password test, which doesn't provide any substantial extra security.
return; | ||
LogPrintf("No rpcpassword set - using random cookie authentication\n"); | ||
if (!GenerateAuthCookie(&strRPCUserColonPass)) { | ||
StartShutdown(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to move the rpcpassword warning into here, instead of removing it entirely? This would give the user warning if GenerateAuthCookie() fails to write to disk for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GenerateAuthCookie already logs an error when it is unable to create the file. The data directory must be writable (otherwise creating the lock file will fail, earlier), so it is an extremely rare error. IMO it doesn't need an extensive translated message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is reasonable to show an error here before shutting down, but can just as well be a standard "Initialization failed, check the error log for details".
When no `-rpcpassword` is specified, use a special 'cookie' file for authentication. This file is generated with random content when the daemon starts, and deleted when it exits. Read access to this file controls who can access through RPC. By default this file is stored in the data directory but it be overriden with `-rpccookiefile`. This is similar to Tor CookieAuthentication: see https://www.torproject.org/docs/tor-manual.html.en Alternative to bitcoin#6258. Like that pull, this allows running bitcoind without any manual configuration. However, daemons should ideally never write to their configuration files, so I prefer this solution.
3f84f46
to
71cbeaa
Compare
Rebased against #6398, added generic UI error message before shutting down when writing cookie fails. |
a046144
to
0937290
Compare
0937290 doc: mention RPC random cookie authentication in release notes (Wladimir J. van der Laan) 71cbeaa rpc: Implement random-cookie based authentication (Wladimir J. van der Laan)
rpc: Implement random-cookie based authentication Cherry-picked from bitcoin/bitcoin#6388. Closes #1950.
I've never liked the chain-specific exception to having to set a password. It gives issues with #6388 which makes it valid to set no password in every case (as it enables random cookie authentication). This pull removes the flag, so that all chains are regarded the same. It also removes the username==password test, which doesn't provide any substantial extra security.
When no
-rpcpassword
is specified, use a special 'cookie' file for authentication. This file is generated with random content when the daemon starts, and deleted when it exits. Read access to this file controls who can access through RPC. By default this file is stored in the data directory but it be overridden with-rpccookiefile
.This is similar to Tor CookieAuthentication: see https://www.torproject.org/docs/tor-manual.html.en
Alternative to #6258. Like that pull, this allows running bitcoind without any manual configuration. However, daemons should ideally never write to their configuration files, so I prefer this solution.