diff options
author | Luke Dashjr <luke-jr+git@utopios.org> | 2016-11-16 11:36:21 +0000 |
---|---|---|
committer | Luke Dashjr <luke-jr+git@utopios.org> | 2016-12-29 11:46:26 +0000 |
commit | 629cd423644b1f6d180eb5eeb3fb8a204881db97 (patch) | |
tree | de9dc28baae2c1f10705c482a7ffce34baa926e9 /src/qt | |
parent | e2d9213c32e51fe197756709e24c6694f28bf842 (diff) |
Qt/RPCConsole: Teach RPCParseCommandLine how to filter out arguments to sensitive commands
Diffstat (limited to 'src/qt')
-rw-r--r-- | src/qt/rpcconsole.cpp | 32 | ||||
-rw-r--r-- | src/qt/rpcconsole.h | 6 |
2 files changed, 33 insertions, 5 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: diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 9567341ae2..dfc1cc26d6 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -36,9 +36,9 @@ public: explicit RPCConsole(const PlatformStyle *platformStyle, QWidget *parent); ~RPCConsole(); - static bool RPCParseCommandLine(std::string &strResult, const std::string &strCommand, bool fExecute); - static bool RPCExecuteCommandLine(std::string &strResult, const std::string &strCommand) { - return RPCParseCommandLine(strResult, strCommand, true); + static bool RPCParseCommandLine(std::string &strResult, const std::string &strCommand, bool fExecute, std::string * const pstrFilteredOut = NULL); + static bool RPCExecuteCommandLine(std::string &strResult, const std::string &strCommand, std::string * const pstrFilteredOut = NULL) { + return RPCParseCommandLine(strResult, strCommand, true, pstrFilteredOut); } void setClientModel(ClientModel *model); |