Skip to content

Commit affe927

Browse files
committed
Merge #10997: RPC: Add option -stdinrpcpass to bitcoin-cli to allow RPC password to be read from standard input
79191f5 Add option -stdinrpcpass to allow RPC password to be read from standard input (Joe Harvell) Pull request description: Add a new command-line option to bitcoin-cli that allows the RPC password to be read from standard intput. The purpose of this option is to allow secure RPC password input to bitcoin-cli through an external program that is capable of disabling terminal echo. This option works similarly to the existing -stdin option, and also works when combined with that option. I have also written a simple ncurses based program that disables echo, gets input from the terminal and writes to standard output. I couldn't find an existing askpass program that doesn't require graphics libraries, since they are primarily used for getting passwords in a graphics environment. Unless someone can point out a suitable existing askpass program, I plan to submit my ncurses program to the contrib directory separately from this pull request. Tree-SHA512: 6d426d757de325d928fab42ea8e423273a7dea9f838acb745ccf9f9daa2b47e23044ec1c019cda1a081253f5145fc10f79ae82dfe7f8e952e1f271ec56018e14
2 parents 00ada17 + 79191f5 commit affe927

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

src/bitcoin-cli.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ std::string HelpMessageCli()
4545
strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
4646
strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
4747
strUsage += HelpMessageOpt("-rpcclienttimeout=<n>", strprintf(_("Timeout in seconds during HTTP requests, or 0 for no timeout. (default: %d)"), DEFAULT_HTTP_CLIENT_TIMEOUT));
48-
strUsage += HelpMessageOpt("-stdin", _("Read extra arguments from standard input, one per line until EOF/Ctrl-D (recommended for sensitive information such as passphrases)"));
48+
strUsage += HelpMessageOpt("-stdinrpcpass", strprintf(_("Read RPC password from standard input as a single line. When combined with -stdin, the first line from standard input is used for the RPC password.")));
49+
strUsage += HelpMessageOpt("-stdin", _("Read extra arguments from standard input, one per line until EOF/Ctrl-D (recommended for sensitive information such as passphrases). When combined with -stdinrpcpass, the first line from standard input is used for the RPC password."));
4950
strUsage += HelpMessageOpt("-rpcwallet=<walletname>", _("Send RPC for non-default wallet on RPC server (argument is wallet filename in bitcoind directory, required if bitcoind/-Qt runs with multiple wallets)"));
5051

5152
return strUsage;
@@ -190,7 +191,7 @@ static void http_error_cb(enum evhttp_request_error err, void *ctx)
190191
}
191192
#endif
192193

193-
UniValue CallRPC(const std::string& strMethod, const UniValue& params)
194+
static UniValue CallRPC(const std::string& strMethod, const UniValue& params)
194195
{
195196
std::string host;
196197
// In preference order, we choose the following for the port:
@@ -222,7 +223,7 @@ UniValue CallRPC(const std::string& strMethod, const UniValue& params)
222223
// Try fall back to cookie-based authentication if no password is provided
223224
if (!GetAuthCookie(&strRPCUserColonPass)) {
224225
throw std::runtime_error(strprintf(
225-
_("Could not locate RPC credentials. No authentication cookie could be found, and no rpcpassword is set in the configuration file (%s)"),
226+
_("Could not locate RPC credentials. No authentication cookie could be found, and RPC password is not set. See -rpcpassword and -stdinrpcpass. Configuration file: (%s)"),
226227
GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)).string().c_str()));
227228

228229
}
@@ -293,6 +294,12 @@ int CommandLineRPC(int argc, char *argv[])
293294
argc--;
294295
argv++;
295296
}
297+
std::string rpcPass;
298+
if (gArgs.GetBoolArg("-stdinrpcpass", false)) {
299+
if(!std::getline(std::cin,rpcPass))
300+
throw std::runtime_error("-stdinrpcpass specified but failed to read from standard input");
301+
gArgs.ForceSetArg("-rpcpassword", rpcPass);
302+
}
296303
std::vector<std::string> args = std::vector<std::string>(&argv[1], &argv[argc]);
297304
if (gArgs.GetBoolArg("-stdin", false)) {
298305
// Read one arg per line from stdin and append

0 commit comments

Comments
 (0)