Permalink
Browse files

Merge multiwallet_rpc-0.14

  • Loading branch information...
2 parents f080323 + 860c8ba commit f582ed6d7c2e6da6e3a3f9485b73ebfd88259f38 @luke-jr luke-jr committed Mar 7, 2017
Showing with 48 additions and 11 deletions.
  1. +29 −5 src/httprpc.cpp
  2. +7 −0 src/qt/rpcconsole.cpp
  3. +10 −2 src/rpc/server.h
  4. +1 −2 src/wallet/rpcwallet.cpp
  5. +1 −2 src/wallet/test/wallet_tests.cpp
View
@@ -17,6 +17,9 @@
#include "crypto/hmac_sha256.h"
#include <stdio.h>
#include "utilstrencodings.h"
+#ifdef ENABLE_WALLET
+#include "wallet/wallet.h"
+#endif
#include <boost/algorithm/string.hpp> // boost::trim
#include <boost/foreach.hpp> //BOOST_FOREACH
@@ -85,7 +88,7 @@ static void JSONErrorReply(HTTPRequest* req, const UniValue& objError, const Uni
//This function checks username and password against -rpcauth
//entries from config file.
-static bool multiUserAuthorized(std::string strUserPass)
+static bool multiUserAuthorized(std::string strUserPass, std::string& walletNameOut)
{
if (strUserPass.find(":") == std::string::npos) {
return false;
@@ -99,7 +102,7 @@ static bool multiUserAuthorized(std::string strUserPass)
{
std::vector<std::string> vFields;
boost::split(vFields, strRPCAuth, boost::is_any_of(":$"));
- if (vFields.size() != 3) {
+ if (vFields.size() < 3 || vFields.size() > 4) {
//Incorrect formatting in config file
continue;
}
@@ -120,14 +123,17 @@ static bool multiUserAuthorized(std::string strUserPass)
std::string strHashFromPass = HexStr(hexvec);
if (TimingResistantEqual(strHashFromPass, strHash)) {
+ if (vFields.size() > 3) {
+ walletNameOut = vFields[3];
+ }
return true;
}
}
}
return false;
}
-static bool RPCAuthorized(const std::string& strAuth, std::string& strAuthUsernameOut)
+static bool RPCAuthorized(const std::string& strAuth, std::string& strAuthUsernameOut, std::string& walletNameOut)
{
if (strRPCUserColonPass.empty()) // Belt-and-suspenders measure if InitRPCAuthentication was not called
return false;
@@ -144,7 +150,7 @@ static bool RPCAuthorized(const std::string& strAuth, std::string& strAuthUserna
if (TimingResistantEqual(strUserPass, strRPCUserColonPass)) {
return true;
}
- return multiUserAuthorized(strUserPass);
+ return multiUserAuthorized(strUserPass, walletNameOut);
}
static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &)
@@ -163,7 +169,8 @@ static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &)
}
JSONRPCRequest jreq;
- if (!RPCAuthorized(authHeader.second, jreq.authUser)) {
+ std::string walletName;
+ if (!RPCAuthorized(authHeader.second, jreq.authUser, walletName)) {
LogPrintf("ThreadRPCServer incorrect password attempt from %s\n", req->GetPeer().ToString());
/* Deter brute-forcing
@@ -185,6 +192,23 @@ static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &)
// Set the URI
jreq.URI = req->GetURI();
+#ifdef ENABLE_WALLET
+ if (walletName.empty()) {
+ // Any wallet is permitted, so just use the first
+ jreq.wallet = vpwallets.empty() ? NULL : vpwallets[0];
+ } else if (walletName == "-") {
+ // Block wallet access always
+ jreq.wallet = NULL;
+ } else {
+ // Select specifically a named wallet
+ for (CWallet_ptr pwallet : vpwallets) {
+ if (walletName == pwallet->strWalletFile) {
+ jreq.wallet = pwallet;
+ }
+ }
+ }
+#endif
+
std::string strReply;
// singleton request
if (valRequest.isObject()) {
View
@@ -20,6 +20,9 @@
#include "rpc/server.h"
#include "rpc/client.h"
#include "util.h"
+#ifdef ENABLE_WALLET
+#include "wallet/wallet.h"
+#endif
#include <openssl/crypto.h>
@@ -300,6 +303,10 @@ bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &
JSONRPCRequest req;
req.params = RPCConvertValues(stack.back()[0], std::vector<std::string>(stack.back().begin() + 1, stack.back().end()));
req.strMethod = stack.back()[0];
+#ifdef ENABLE_WALLET
+ // TODO: Some way to access secondary wallets
+ req.wallet = vpwallets.empty() ? NULL : vpwallets[0];
+#endif
lastResult = tableRPC.execute(req);
}
View
@@ -33,6 +33,7 @@ namespace RPCServer
class CBlockIndex;
class CNetAddr;
+class CWallet;
/** Wrapper for UniValue::VType, which includes typeAny:
* Used to denote don't care type. Only used by RPCTypeCheckObj */
@@ -52,8 +53,15 @@ class JSONRPCRequest
bool fHelp;
std::string URI;
std::string authUser;
-
- JSONRPCRequest() { id = NullUniValue; params = NullUniValue; fHelp = false; }
+#ifdef ENABLE_WALLET
+ CWallet *wallet;
+#endif
+
+ JSONRPCRequest() : id(NullUniValue), params(NullUniValue), fHelp(false)
+#ifdef ENABLE_WALLET
+ , wallet(NULL)
+#endif
+ {}
void parse(const UniValue& valRequest);
};
View
@@ -32,8 +32,7 @@ using namespace std;
CWallet *GetWalletForJSONRPCRequest(const JSONRPCRequest& request)
{
- // TODO: Some way to access secondary wallets
- return vpwallets.empty() ? NULL : vpwallets[0];
+ return request.wallet;
}
std::string HelpRequiringPassphrase(CWallet * const pwallet)
@@ -400,7 +400,6 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup)
// after.
{
CWallet wallet;
- vpwallets.insert(vpwallets.begin(), &wallet);
UniValue keys;
keys.setArray();
UniValue key;
@@ -418,12 +417,12 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup)
key.pushKV("internal", UniValue(true));
keys.push_back(key);
JSONRPCRequest request;
+ request.wallet = &wallet;
request.params.setArray();
request.params.push_back(keys);
UniValue response = importmulti(request);
BOOST_CHECK_EQUAL(response.write(), strprintf("[{\"success\":false,\"error\":{\"code\":-1,\"message\":\"Failed to rescan before time %d, transactions may be missing.\"}},{\"success\":true}]", newTip->GetBlockTimeMax()));
- vpwallets.erase(vpwallets.begin());
}
}

0 comments on commit f582ed6

Please sign in to comment.