Browse Source

Qt/RPCConsole: Teach RPCParseCommandLine how to filter out arguments to sensitive commands

0.14
Luke Dashjr 8 years ago
parent
commit
629cd42364
  1. 32
      src/qt/rpcconsole.cpp
  2. 6
      src/qt/rpcconsole.h

32
src/qt/rpcconsole.cpp

@ -151,9 +151,10 @@ public:
* @param[out] result stringified Result from the executed command(chain) * @param[out] result stringified Result from the executed command(chain)
* @param[in] strCommand Command line to split * @param[in] strCommand Command line to split
* @param[in] fExecute set true if you want the command to be executed * @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; std::vector< std::vector<std::string> > stack;
stack.push_back(std::vector<std::string>()); stack.push_back(std::vector<std::string>());
@ -173,12 +174,16 @@ bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &
} state = STATE_EATING_SPACES; } state = STATE_EATING_SPACES;
std::string curarg; std::string curarg;
UniValue lastResult; 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; std::string strCommandTerminated = strCommand;
if (strCommandTerminated.back() != '\n') if (strCommandTerminated.back() != '\n')
strCommandTerminated += "\n"; strCommandTerminated += "\n";
for(char ch: strCommandTerminated) for (size_t chpos = 0; chpos < strCommandTerminated.size(); ++chpos)
{ {
char ch = strCommandTerminated[chpos];
switch(state) switch(state)
{ {
case STATE_COMMAND_EXECUTED_INNER: case STATE_COMMAND_EXECUTED_INNER:
@ -222,6 +227,13 @@ bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &
breakParsing = false; breakParsing = false;
// pop the stack and return the result to the current command arguments // 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(); stack.pop_back();
// don't stringify the json in case of a string to avoid doublequotes // 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 (state == STATE_ARGUMENT)
{ {
if (ch == '(' && stack.size() && stack.back().size() > 0) if (ch == '(' && stack.size() && stack.back().size() > 0)
{
if (nDepthInsideSensitive) {
++nDepthInsideSensitive;
}
stack.push_back(std::vector<std::string>()); stack.push_back(std::vector<std::string>());
}
// don't allow commands after executed commands on baselevel // don't allow commands after executed commands on baselevel
if (!stack.size()) if (!stack.size())
@ -291,6 +308,11 @@ bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &
else if(state == STATE_ARGUMENT) // Space ends argument 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); stack.back().push_back(curarg);
curarg.clear(); curarg.clear();
} }
@ -328,6 +350,12 @@ bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &
break; 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 switch(state) // final state
{ {
case STATE_COMMAND_EXECUTED: case STATE_COMMAND_EXECUTED:

6
src/qt/rpcconsole.h

@ -36,9 +36,9 @@ public:
explicit RPCConsole(const PlatformStyle *platformStyle, QWidget *parent); explicit RPCConsole(const PlatformStyle *platformStyle, QWidget *parent);
~RPCConsole(); ~RPCConsole();
static bool RPCParseCommandLine(std::string &strResult, const std::string &strCommand, bool fExecute); 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) { static bool RPCExecuteCommandLine(std::string &strResult, const std::string &strCommand, std::string * const pstrFilteredOut = NULL) {
return RPCParseCommandLine(strResult, strCommand, true); return RPCParseCommandLine(strResult, strCommand, true, pstrFilteredOut);
} }
void setClientModel(ClientModel *model); void setClientModel(ClientModel *model);

Loading…
Cancel
Save