typedef Value(*rpcfn_type)(const Array& params, bool fHelp);
extern map<string, rpcfn_type> mapCallTable;
+static string strRPCPassword;
+
{
if (fHelp || params.size() != 0)
throw runtime_error(
- "help\n"
+ "help <pw>\n"
"List commands.");
string strRet;
+ set<rpcfn_type> setDone;
for (map<string, rpcfn_type>::iterator mi = mapCallTable.begin(); mi != mapCallTable.end(); ++mi)
{
+ string strMethod = (*mi).first;
+ // We already filter duplicates, but these deprecated screw up the sort order
+ if (strMethod == "getamountreceived" ||
+ strMethod == "getallreceived")
+ continue;
try
{
Array params;
- (*(*mi).second)(params, true);
+ rpcfn_type pfn = (*mi).second;
+ if (setDone.insert(pfn).second)
+ (*pfn)(params, true);
}
catch (std::exception& e)
{
{
if (fHelp || params.size() != 0)
throw runtime_error(
- "stop\n"
+ "stop <pw>\n"
"Stop bitcoin server.");
// Shutdown will take long enough that the response should get back
{
if (fHelp || params.size() != 0)
throw runtime_error(
- "getblockcount\n"
+ "getblockcount <pw>\n"
"Returns the number of blocks in the longest block chain.");
return nBestHeight + 1;
{
if (fHelp || params.size() != 0)
throw runtime_error(
- "getblocknumber\n"
+ "getblocknumber <pw>\n"
"Returns the block number of the latest block in the longest block chain.");
return nBestHeight;
{
if (fHelp || params.size() != 0)
throw runtime_error(
- "getconnectioncount\n"
+ "getconnectioncount <pw>\n"
"Returns the number of connections to other nodes.");
return (int)vNodes.size();
{
if (fHelp || params.size() != 0)
throw runtime_error(
- "getdifficulty\n"
+ "getdifficulty <pw>\n"
"Returns the proof-of-work difficulty as a multiple of the minimum difficulty.");
return GetDifficulty();
{
if (fHelp || params.size() != 0)
throw runtime_error(
- "getbalance\n"
+ "getbalance <pw>\n"
"Returns the server's available balance.");
return ((double)GetBalance() / (double)COIN);
{
if (fHelp || params.size() != 0)
throw runtime_error(
- "getgenerate\n"
+ "getgenerate <pw>\n"
"Returns true or false.");
return (bool)fGenerateBitcoins;
{
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
- "setgenerate <generate> [genproclimit]\n"
+ "setgenerate <pw> <generate> [genproclimit]\n"
"<generate> is true or false to turn generation on or off.\n"
"Generation is limited to [genproclimit] processors, -1 is unlimited.");
{
if (fHelp || params.size() != 0)
throw runtime_error(
- "getinfo");
+ "getinfo <pw>");
Object obj;
obj.push_back(Pair("balance", (double)GetBalance() / (double)COIN));
{
if (fHelp || params.size() > 1)
throw runtime_error(
- "getnewaddress [label]\n"
+ "getnewaddress <pw> [label]\n"
"Returns a new bitcoin address for receiving payments. "
"If [label] is specified (recommended), it is added to the address book "
"so payments received with the address will be labeled.");
{
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
- "setlabel <bitcoinaddress> <label>\n"
+ "setlabel <pw> <bitcoinaddress> <label>\n"
"Sets the label associated with the given address.");
string strAddress = params[0].get_str();
{
if (fHelp || params.size() != 1)
throw runtime_error(
- "getlabel <bitcoinaddress>\n"
+ "getlabel <pw> <bitcoinaddress>\n"
"Returns the label associated with the given address.");
string strAddress = params[0].get_str();
{
if (fHelp || params.size() != 1)
throw runtime_error(
- "getaddressesbylabel <label>\n"
+ "getaddressesbylabel <pw> <label>\n"
"Returns the list of addresses with the given label.");
string strLabel = params[0].get_str();
{
if (fHelp || params.size() < 2 || params.size() > 4)
throw runtime_error(
- "sendtoaddress <bitcoinaddress> <amount> [comment] [comment-to]\n"
+ "sendtoaddress <pw> <bitcoinaddress> <amount> [comment] [comment-to]\n"
"<amount> is a real and is rounded to the nearest 0.01");
string strAddress = params[0].get_str();
{
if (fHelp || params.size() > 2)
throw runtime_error(
- "listtransactions [count=10] [includegenerated=false]\n"
+ "listtransactions <pw> [count=10] [includegenerated=false]\n"
"Returns up to [count] most recent transactions.");
int64 nCount = 10;
{
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
- "getreceivedbyaddress <bitcoinaddress> [minconf=1]\n"
+ "getreceivedbyaddress <pw> <bitcoinaddress> [minconf=1]\n"
"Returns the total amount received by <bitcoinaddress> in transactions with at least [minconf] confirmations.");
// Bitcoin address
{
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
- "getreceivedbylabel <label> [minconf=1]\n"
+ "getreceivedbylabel <pw> <label> [minconf=1]\n"
"Returns the total amount received by addresses with <label> in transactions with at least [minconf] confirmations.");
// Get the set of pub keys that have the label
{
if (fHelp || params.size() > 2)
throw runtime_error(
- "listreceivedbyaddress [minconf=1] [includeempty=false]\n"
+ "listreceivedbyaddress <pw> [minconf=1] [includeempty=false]\n"
"[minconf] is the minimum number of confirmations before payments are included.\n"
"[includeempty] whether to include addresses that haven't received any payments.\n"
"Returns an array of objects containing:\n"
{
if (fHelp || params.size() > 2)
throw runtime_error(
- "listreceivedbylabel [minconf=1] [includeempty=false]\n"
+ "listreceivedbylabel <pw> [minconf=1] [includeempty=false]\n"
"[minconf] is the minimum number of confirmations before payments are included.\n"
"[includeempty] whether to include labels that haven't received any payments.\n"
"Returns an array of objects containing:\n"
make_pair("getlabel", &getlabel),
make_pair("getaddressesbylabel", &getaddressesbylabel),
make_pair("sendtoaddress", &sendtoaddress),
- make_pair("listtransactions", &listtransactions),
make_pair("getamountreceived", &getreceivedbyaddress), // deprecated, renamed to getreceivedbyaddress
make_pair("getallreceived", &listreceivedbyaddress), // deprecated, renamed to listreceivedbyaddress
make_pair("getreceivedbyaddress", &getreceivedbyaddress),
{
printf("ThreadRPCServer started\n");
+ if (mapArgs.count("-rpcpw"))
+ strRPCPassword = mapArgs["-rpcpw"];
+ if (strRPCPassword == "")
+ {
+#if defined(__WXMSW__) && wxUSE_GUI
+ MyMessageBox("Warning: rpc password is blank, use -rpcpw=<password>\n", "Bitcoin", wxOK | wxICON_EXCLAMATION);
+#else
+ fprintf(stdout, "Warning: rpc password is blank, use -rpcpw=<password>\n");
+#endif
+ }
+
// Bind to loopback 127.0.0.1 so the socket can only be accessed locally
boost::asio::io_service io_service;
tcp::endpoint endpoint(boost::asio::ip::address_v4::loopback(), 8332);
// Receive request
string strRequest = ReadHTTP(stream);
- printf("ThreadRPCServer request=%s", strRequest.c_str());
// Handle multiple invocations per request
string::iterator begin = strRequest.begin();
const Array& params = find_value(request, "params").get_array();
id = find_value(request, "id");
+ printf("ThreadRPCServer method=%s\n", strMethod.c_str());
+
+ // Check password
+ if (params.size() < 1 || params[0].type() != str_type)
+ throw runtime_error("First parameter must be the password.");
+ if (params[0].get_str() != strRPCPassword)
+ {
+ if (strRPCPassword.size() < 15)
+ Sleep(50);
+ begin = strRequest.end();
+ printf("ThreadRPCServer incorrect password attempt\n");
+ throw runtime_error("Incorrect password.");
+ }
+
// Execute
map<string, rpcfn_type>::iterator mi = mapCallTable.find(strMethod);
if (mi == mapCallTable.end())
throw runtime_error("Method not found.");
- Value result = (*(*mi).second)(params, false);
+ Value result = (*(*mi).second)(Array(params.begin()+1, params.end()), false);
// Send reply
string strReply = JSONRPCReply(result, Value::null, id);