aboutsummaryrefslogtreecommitdiff
path: root/src/qt/rpcconsole.cpp
diff options
context:
space:
mode:
authorLuke Dashjr <luke-jr+git@utopios.org>2016-11-16 11:36:21 +0000
committerLuke Dashjr <luke-jr+git@utopios.org>2016-12-29 11:46:26 +0000
commit629cd423644b1f6d180eb5eeb3fb8a204881db97 (patch)
treede9dc28baae2c1f10705c482a7ffce34baa926e9 /src/qt/rpcconsole.cpp
parente2d9213c32e51fe197756709e24c6694f28bf842 (diff)
downloadbitcoin-629cd423644b1f6d180eb5eeb3fb8a204881db97.tar.xz
Qt/RPCConsole: Teach RPCParseCommandLine how to filter out arguments to sensitive commands
Diffstat (limited to 'src/qt/rpcconsole.cpp')
-rw-r--r--src/qt/rpcconsole.cpp32
1 files changed, 30 insertions, 2 deletions
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index f453833416..63a23dc496 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -151,9 +151,10 @@ public:
* @param[out] result stringified Result from the executed command(chain)
* @param[in] strCommand Command line to split
* @param[in] fExecute set true if you want the command to be executed
+ * @param[out] pstrFilteredOut Command line, filtered to remove any sensitive data
*/
-bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &strCommand, const bool fExecute)
+bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &strCommand, const bool fExecute, std::string * const pstrFilteredOut)
{
std::vector< std::vector<std::string> > stack;
stack.push_back(std::vector<std::string>());
@@ -173,12 +174,16 @@ bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &
} state = STATE_EATING_SPACES;
std::string curarg;
UniValue lastResult;
+ unsigned nDepthInsideSensitive = 0;
+ size_t filter_begin_pos = 0;
+ std::vector<std::pair<size_t, size_t>> filter_ranges;
std::string strCommandTerminated = strCommand;
if (strCommandTerminated.back() != '\n')
strCommandTerminated += "\n";
- for(char ch: strCommandTerminated)
+ for (size_t chpos = 0; chpos < strCommandTerminated.size(); ++chpos)
{
+ char ch = strCommandTerminated[chpos];
switch(state)
{
case STATE_COMMAND_EXECUTED_INNER:
@@ -222,6 +227,13 @@ bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &
breakParsing = false;
// pop the stack and return the result to the current command arguments
+ if (nDepthInsideSensitive) {
+ if (!--nDepthInsideSensitive) {
+ assert(filter_begin_pos);
+ filter_ranges.push_back(std::make_pair(filter_begin_pos, chpos));
+ filter_begin_pos = 0;
+ }
+ }
stack.pop_back();
// don't stringify the json in case of a string to avoid doublequotes
@@ -260,7 +272,12 @@ bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &
if (state == STATE_ARGUMENT)
{
if (ch == '(' && stack.size() && stack.back().size() > 0)
+ {
+ if (nDepthInsideSensitive) {
+ ++nDepthInsideSensitive;
+ }
stack.push_back(std::vector<std::string>());
+ }
// don't allow commands after executed commands on baselevel
if (!stack.size())
@@ -291,6 +308,11 @@ bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &
else if(state == STATE_ARGUMENT) // Space ends argument
{
+ // This is the only place where the method name should get pushed (as the first stack item)
+ if ((!nDepthInsideSensitive) && historyFilter.contains(QString::fromStdString(curarg), Qt::CaseInsensitive)) {
+ nDepthInsideSensitive = 1;
+ filter_begin_pos = chpos;
+ }
stack.back().push_back(curarg);
curarg.clear();
}
@@ -328,6 +350,12 @@ bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &
break;
}
}
+ if (pstrFilteredOut) {
+ *pstrFilteredOut = strCommand;
+ for (auto i = filter_ranges.rbegin(); i != filter_ranges.rend(); ++i) {
+ pstrFilteredOut->replace(i->first, i->second - i->first, "...");
+ }
+ }
switch(state) // final state
{
case STATE_COMMAND_EXECUTED: