Skip to content
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

rpc: Implement random-cookie based authentication #6388

Merged
merged 2 commits into from Jul 14, 2015

Conversation

laanwj
Copy link
Member

@laanwj laanwj commented Jul 7, 2015

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.

@@ -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
Copy link
Member Author

@laanwj laanwj Jul 7, 2015

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.

Copy link
Contributor

@jonasschnelli jonasschnelli Jul 7, 2015

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

Copy link
Member Author

@laanwj laanwj Jul 8, 2015

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 :)

@ajweiss
Copy link
Contributor

ajweiss commented Jul 7, 2015

Nice! Reviewing this...

@ajweiss
Copy link
Contributor

ajweiss commented Jul 7, 2015

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())
Copy link
Contributor

@jonasschnelli jonasschnelli Jul 7, 2015

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.

Copy link
Member Author

@laanwj laanwj Jul 8, 2015

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.

Copy link
Contributor

@jonasschnelli jonasschnelli Jul 8, 2015

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.

Copy link
Member Author

@laanwj laanwj Jul 8, 2015

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.

Copy link
Member Author

@laanwj laanwj Jul 8, 2015

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...

@jonasschnelli
Copy link
Contributor

jonasschnelli commented Jul 7, 2015

Nice work!
Tested ACK (nit: doesn't work in regtest atm).

// 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"
Copy link
Member

@sipa sipa Jul 9, 2015

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.

Copy link
Member Author

@laanwj laanwj Jul 10, 2015

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)

laanwj added a commit to laanwj/bitcoin that referenced this issue Jul 10, 2015
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();
Copy link

@ghost ghost Jul 13, 2015

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.

Copy link
Member Author

@laanwj laanwj Jul 13, 2015

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.

Copy link
Member Author

@laanwj laanwj Jul 13, 2015

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.
@laanwj laanwj force-pushed the 2015_07_cookie_monsters branch from 3f84f46 to 71cbeaa Compare Jul 13, 2015
@laanwj
Copy link
Member Author

laanwj commented Jul 13, 2015

Rebased against #6398, added generic UI error message before shutting down when writing cookie fails.

@laanwj laanwj force-pushed the 2015_07_cookie_monsters branch from a046144 to 0937290 Compare Jul 13, 2015
@laanwj laanwj merged commit 0937290 into bitcoin:master Jul 14, 2015
1 check passed
laanwj added a commit that referenced this issue Jul 14, 2015
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)
zkbot added a commit to zcash/zcash that referenced this issue Jan 18, 2017
rpc: Implement random-cookie based authentication

Cherry-picked from bitcoin/bitcoin#6388.

Closes #1950.
AllanDoensen referenced this issue in AllanDoensen/BitcoinUnlimited Apr 23, 2017
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.
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants