From bab5e9ef7cdccdcf6eeee5b6312d60eb5ecadddb Mon Sep 17 00:00:00 2001 From: instagibbs Date: Fri, 3 Jun 2016 09:12:39 -0400 Subject: [PATCH] Rework CallRPC, use bitcoind cookie auth --- src/bitcoin-cli.cpp | 2 +- src/callrpc.cpp | 36 ++++++++++++++++++++++++++++-------- src/callrpc.h | 4 ++-- src/rpc/protocol.cpp | 27 +++++++++++++++++++++++++++ src/rpc/protocol.h | 2 ++ 5 files changed, 60 insertions(+), 11 deletions(-) diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 052f2b9efc..6e7f758115 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -30,7 +30,7 @@ std::string HelpMessageCli() strUsage += HelpMessageOpt("-conf=", strprintf(_("Specify configuration file (default: %s)"), BITCOIN_CONF_FILENAME)); strUsage += HelpMessageOpt("-datadir=", _("Specify data directory")); AppendParamsHelpMessages(strUsage); - strUsage += HelpMessageOpt("-rpcconnect=", strprintf(_("Send commands to node running on (default: %s)"), DEFAULT_RPCCONNECT)); + strUsage += HelpMessageOpt("-rpcconnect=", strprintf(_("Send commands to node running on (default: %s)"), DEFAULT_RPCHOST)); strUsage += HelpMessageOpt("-rpcport=", strprintf(_("Connect to JSON-RPC on (default: %u)"), defaultBaseParams->RPCPort())); strUsage += HelpMessageOpt("-rpcwait", _("Wait for RPC server to start")); strUsage += HelpMessageOpt("-rpcuser=", _("Username for JSON-RPC connections")); diff --git a/src/callrpc.cpp b/src/callrpc.cpp index 15f1693031..40405447be 100644 --- a/src/callrpc.cpp +++ b/src/callrpc.cpp @@ -43,11 +43,22 @@ static void http_request_done(struct evhttp_request *req, void *ctx) } } -UniValue CallRPC(const string& strMethod, const UniValue& params, int port) +UniValue CallRPC(const string& strMethod, const UniValue& params, int port, bool connectToMainchain) { - std::string host = GetArg("-rpcconnect", DEFAULT_RPCCONNECT); + std::string strhost = "-rpcconnect"; + std::string strport = "-rpcport"; + std::string struser = "-rpcuser"; + std::string strpassword = "-rpcpassword"; + if (connectToMainchain) { + strhost = "-mainchainhost"; + strport = "-mainchainrpcport"; + strpassword = "-mainchainrpcpassword"; + struser = "-mainchainrpcuser"; + } + + std::string host = GetArg(strhost, DEFAULT_RPCHOST); if (port < 0) - port = GetArg("-rpcport", BaseParams().RPCPort()); + port = GetArg(strport, BaseParams().RPCPort()); // Create event base struct event_base *base = event_base_new(); // TODO RAII @@ -67,16 +78,24 @@ UniValue CallRPC(const string& strMethod, const UniValue& params, int port) // Get credentials std::string strRPCUserColonPass; - if (mapArgs["-rpcpassword"] == "") { + if (mapArgs[strpassword] == "") { + // Try fall back to cookie-based authentication if no password is provided - if (!GetAuthCookie(&strRPCUserColonPass)) { + if (!connectToMainchain && !GetAuthCookie(&strRPCUserColonPass)) { + throw runtime_error(strprintf( + _("Could not locate RPC credentials. No authentication cookie could be found, and no rpcpassword is set in the configuration file (%s)"), + GetConfigFile().string().c_str())); + } + + // Try fall back to cookie-based authentication if no password is provided + if (connectToMainchain && !GetMainchainAuthCookie(&strRPCUserColonPass)) { throw runtime_error(strprintf( _("Could not locate RPC credentials. No authentication cookie could be found, and no rpcpassword is set in the configuration file (%s)"), GetConfigFile().string().c_str())); } } else { - strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; + strRPCUserColonPass = mapArgs[struser] + ":" + mapArgs[strpassword]; } struct evkeyvalq *output_headers = evhttp_request_get_output_headers(req); @@ -124,10 +143,11 @@ UniValue CallRPC(const string& strMethod, const UniValue& params, int port) bool IsConfirmedBitcoinBlock(const uint256& genesishash, const uint256& hash, int nMinConfirmationDepth) { + try { UniValue params(UniValue::VARR); params.push_back(UniValue(0)); - UniValue reply = CallRPC("getblockhash", params, GetArg("-rpcconnectport", 18332)); + UniValue reply = CallRPC("getblockhash", params, GetArg("-mainchainrpcport", 18332)); if (!find_value(reply, "error").isNull()) return false; UniValue result = find_value(reply, "result"); @@ -138,7 +158,7 @@ bool IsConfirmedBitcoinBlock(const uint256& genesishash, const uint256& hash, in params = UniValue(UniValue::VARR); params.push_back(hash.GetHex()); - reply = CallRPC("getblock", params, GetArg("-rpcconnectport", 18332)); + reply = CallRPC("getblock", params, GetArg("-mainchainrpcport", 18332)); if (!find_value(reply, "error").isNull()) return false; result = find_value(reply, "result"); diff --git a/src/callrpc.h b/src/callrpc.h index 2efb74748b..31bbe08365 100644 --- a/src/callrpc.h +++ b/src/callrpc.h @@ -15,7 +15,7 @@ #include -static const char DEFAULT_RPCCONNECT[] = "127.0.0.1"; +static const char DEFAULT_RPCHOST[] = "127.0.0.1"; static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900; // @@ -32,7 +32,7 @@ public: }; -UniValue CallRPC(const std::string& strMethod, const UniValue& params, int port=-1); +UniValue CallRPC(const std::string& strMethod, const UniValue& params, int port=-1, bool connectToMainchain=false); bool IsConfirmedBitcoinBlock(const uint256& genesishash, const uint256& hash, int nMinConfirmationDepth); #endif // BITCOIN_CALLRPC_H diff --git a/src/rpc/protocol.cpp b/src/rpc/protocol.cpp index bb885bb5a6..bed2688418 100644 --- a/src/rpc/protocol.cpp +++ b/src/rpc/protocol.cpp @@ -75,6 +75,16 @@ boost::filesystem::path GetAuthCookieFile() return path; } +boost::filesystem::path GetMainchainAuthCookieFile() +{ + boost::filesystem::path path(GetArg("-mainchainrpccookiefile", COOKIEAUTH_FILE)); + //Change to default false for live network + if (!path.is_complete() && GetBoolArg("-testnet", true)) path = "testnet3" / path; + if (!path.is_complete() && GetBoolArg("-regtest", false)) path = "regtest" / path; + if (!path.is_complete()) path = GetDataDir(false) / path; + return path; +} + bool GenerateAuthCookie(std::string *cookie_out) { const size_t COOKIE_SIZE = 32; @@ -117,6 +127,23 @@ bool GetAuthCookie(std::string *cookie_out) return true; } +bool GetMainchainAuthCookie(std::string *cookie_out) +{ + std::ifstream file; + std::string cookie; + + boost::filesystem::path filepath = GetMainchainAuthCookieFile(); + file.open(filepath.string().c_str()); + if (!file.is_open()) + return false; + std::getline(file, cookie); + file.close(); + + if (cookie_out) + *cookie_out = cookie; + return true; +} + void DeleteAuthCookie() { try { diff --git a/src/rpc/protocol.h b/src/rpc/protocol.h index 988e0fc5fa..6fed667a1a 100644 --- a/src/rpc/protocol.h +++ b/src/rpc/protocol.h @@ -87,6 +87,8 @@ boost::filesystem::path GetAuthCookieFile(); bool GenerateAuthCookie(std::string *cookie_out); /** Read the RPC authentication cookie from disk */ bool GetAuthCookie(std::string *cookie_out); +/** Needs to know cookiedir path info -cli doesn't require*/ +bool GetMainchainAuthCookie(std::string *cookie_out); /** Delete RPC authentication cookie from disk */ void DeleteAuthCookie();