diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2015-07-07 14:53:48 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2015-07-13 13:11:41 +0200 |
commit | 71cbeaad9a929ba6a7b62d9b37a09b214ae00c1a (patch) | |
tree | 63148f270b290394d416ea7d4063d3bc1bbe7541 /src/bitcoin-cli.cpp | |
parent | 3d9362d5ac1ec405955503dc67caf59e716df5e4 (diff) |
rpc: Implement random-cookie based authentication
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 #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.
Diffstat (limited to 'src/bitcoin-cli.cpp')
-rw-r--r-- | src/bitcoin-cli.cpp | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 903777ba51..1c5a312874 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -97,12 +97,6 @@ static bool AppInitRPC(int argc, char* argv[]) UniValue CallRPC(const string& strMethod, const UniValue& params) { - if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "") - throw runtime_error(strprintf( - _("You must set rpcpassword=<password> in the configuration file:\n%s\n" - "If the file does not exist, create it with owner-readable-only file permissions."), - GetConfigFile().string().c_str())); - // Connect to localhost bool fUseSSL = GetBoolArg("-rpcssl", false); boost::asio::io_service io_service; @@ -116,10 +110,24 @@ UniValue CallRPC(const string& strMethod, const UniValue& params) if (!fConnected) throw CConnectionFailed("couldn't connect to server"); + // Find credentials to use + std::string strRPCUserColonPass; + if (mapArgs["-rpcpassword"] == "") { + // 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" + "If the file does not exist, create it with owner-readable-only file permissions."), + GetConfigFile().string().c_str())); + + } + } else { + strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; + } + // HTTP basic authentication - string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]); map<string, string> mapRequestHeaders; - mapRequestHeaders["Authorization"] = string("Basic ") + strUserPass64; + mapRequestHeaders["Authorization"] = string("Basic ") + EncodeBase64(strRPCUserColonPass); // Send request string strRequest = JSONRPCRequest(strMethod, params, 1); |