hide password in -stdin `walletpassphrase` command

This commit is contained in:
Alfredo Garcia 2020-12-30 12:02:57 -03:00 committed by Daira Hopwood
parent e528caf7fb
commit ab55776189
1 changed files with 46 additions and 2 deletions

View File

@ -19,6 +19,13 @@
#include <univalue.h>
#ifdef WIN32
#include <windows.h>
#else
#include <termios.h>
#include <unistd.h>
#endif
const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;
static const char DEFAULT_RPCCONNECT[] = "127.0.0.1";
@ -32,6 +39,7 @@ std::string HelpMessageCli()
strUsage += HelpMessageOpt("-?", _("This help message"));
strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), BITCOIN_CONF_FILENAME));
strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory"));
strUsage += HelpMessageOpt("-stdin", _("Read extra arguments from standard input, one per line until EOF/Ctrl-D (recommended for sensitive information such as passphrases). If first extra argument is `walletpassphrase` then the first line(password) will not be echoed."));
AppendParamsHelpMessages(strUsage);
strUsage += HelpMessageOpt("-rpcconnect=<ip>", strprintf(_("Send commands to node running on <ip> (default: %s)"), DEFAULT_RPCCONNECT));
strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Connect to JSON-RPC on <port> (default: %u or testnet: %u)"), 8232, 18232));
@ -39,7 +47,6 @@ std::string HelpMessageCli()
strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
strUsage += HelpMessageOpt("-rpcclienttimeout=<n>", strprintf(_("Timeout in seconds during HTTP requests, or 0 for no timeout. (default: %d)"), DEFAULT_HTTP_CLIENT_TIMEOUT));
strUsage += HelpMessageOpt("-stdin", _("Read extra arguments from standard input, one per line until EOF/Ctrl-D (recommended for sensitive information such as passphrases)"));
return strUsage;
}
@ -263,6 +270,32 @@ UniValue CallRPC(const std::string& strMethod, const UniValue& params)
return reply;
}
void SetStdinEcho(bool enable = true)
{
#ifdef WIN32
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode;
GetConsoleMode(hStdin, &mode);
if (!enable)
mode &= ~ENABLE_ECHO_INPUT;
else
mode |= ENABLE_ECHO_INPUT;
SetConsoleMode(hStdin, mode);
#else
struct termios tty;
tcgetattr(STDIN_FILENO, &tty);
if (!enable)
tty.c_lflag &= ~ECHO;
else
tty.c_lflag |= ECHO;
(void) tcsetattr(STDIN_FILENO, TCSANOW, &tty);
#endif
}
int CommandLineRPC(int argc, char *argv[])
{
std::string strPrint;
@ -275,10 +308,21 @@ int CommandLineRPC(int argc, char *argv[])
}
std::vector<std::string> args = std::vector<std::string>(&argv[1], &argv[argc]);
if (GetBoolArg("-stdin", false)) {
bool hide = false;
if (strncmp(argv[1], "walletpassphrase", 16) == 0) {
SetStdinEcho(false);
hide = true;
}
// Read one arg per line from stdin and append
std::string line;
while (std::getline(std::cin,line))
while (std::getline(std::cin,line)) {
args.push_back(line);
if (hide) {
SetStdinEcho(true);
hide = false;
}
}
}
if (args.size() < 1)
throw std::runtime_error("too few parameters (need at least command)");