From ab15f65aeb487f899789c2191f1e8520d14e53a4 Mon Sep 17 00:00:00 2001 From: jed Date: Fri, 22 Jun 2012 09:14:45 -0700 Subject: [PATCH] block some RPC commands from being used remotely --- src/Config.h | 1 + src/RPCDoor.cpp | 5 ++- src/RPCServer.cpp | 106 +++++++++++++++++++++++++++++----------------- src/RPCServer.h | 6 +++ 4 files changed, 78 insertions(+), 40 deletions(-) diff --git a/src/Config.h b/src/Config.h index 44eb864e57..f7a443b96d 100644 --- a/src/Config.h +++ b/src/Config.h @@ -89,6 +89,7 @@ public: std::string RPC_PASSWORD; bool RPC_ALLOW_REMOTE; + // Validation NewcoinAddress VALIDATION_SEED; diff --git a/src/RPCDoor.cpp b/src/RPCDoor.cpp index b3ea1eaac0..5fb00a3ffc 100644 --- a/src/RPCDoor.cpp +++ b/src/RPCDoor.cpp @@ -1,6 +1,7 @@ #include "RPCDoor.h" #include "Application.h" #include "Config.h" +#include "Log.h" #include #include @@ -10,7 +11,7 @@ using namespace boost::asio::ip; RPCDoor::RPCDoor(boost::asio::io_service& io_service) : mAcceptor(io_service, tcp::endpoint(address::from_string(theConfig.RPC_IP), theConfig.RPC_PORT)) { - cerr << "RPC port: " << theConfig.RPC_IP << " " << theConfig.RPC_PORT << " allow remote: " << theConfig.RPC_ALLOW_REMOTE << endl; + Log(lsINFO) << "RPC port: " << theConfig.RPC_IP << " " << theConfig.RPC_PORT << " allow remote: " << theConfig.RPC_ALLOW_REMOTE; startListening(); } @@ -44,7 +45,7 @@ void RPCDoor::handleConnect(RPCServer::pointer new_connection, new_connection->connected(); } - else cout << "Error: " << error; + else Log(lsINFO) << "RPCDoor::handleConnect Error: " << error; startListening(); } diff --git a/src/RPCServer.cpp b/src/RPCServer.cpp index c215d10f3e..958b72f801 100644 --- a/src/RPCServer.cpp +++ b/src/RPCServer.cpp @@ -28,6 +28,7 @@ RPCServer::RPCServer(boost::asio::io_service& io_service , NetworkOPs* nopNetwork) : mNetOps(nopNetwork), mSocket(io_service) { + mRole=GUEST; } Json::Value RPCServer::RPCError(int iError) @@ -72,6 +73,8 @@ Json::Value RPCServer::RPCError(int iError) { rpcUNKNOWN_COMMAND, "unknownCmd", "Unknown command." }, { rpcWRONG_PASSWORD, "wrongPassword", "Wrong password." }, { rpcWRONG_SEED, "wrongSeed", "The regular key does not point as the master key." }, + { rpcNO_PERMISSION, "noPermission", "You don't have permission for this command." }, + }; int i; @@ -94,6 +97,8 @@ Json::Value RPCServer::RPCError(int iError) void RPCServer::connected() { //std::cout << "RPC request" << std::endl; + if(mSocket.remote_endpoint().address().to_string()=="127.0.0.1") mRole=ADMIN; + else mRole=GUEST; mSocket.async_read_some(boost::asio::buffer(mReadBuffer), boost::bind(&RPCServer::handle_read, shared_from_this(), @@ -1960,12 +1965,31 @@ Json::Value RPCServer::doUnlScore(Json::Value& params) return "scoring requested"; } -Json::Value RPCServer::doStop(Json::Value& params) { +Json::Value RPCServer::doStop(Json::Value& params) +{ theApp->stop(); return SYSTEM_NAME " server stopping"; } +// TODO: for now this simply checks if this is the admin account +// TODO: need to prevent them hammering this over and over +// TODO: maybe a better way is only allow admin from local host +Json::Value RPCServer::doLogin(Json::Value& params) +{ + std::string username = params[0u].asString(); + std::string password = params[1u].asString(); + + if(username==theConfig.RPC_USER && password==theConfig.RPC_PASSWORD) + { + //mRole=ADMIN; + return "logged in"; + }else + { + return "nope"; + } +} + Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params) { Log(lsTRACE) << "RPC:" << command; @@ -1975,48 +1999,51 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params doFuncPtr dfpFunc; int iMinParams; int iMaxParams; + bool mAdminRequired; unsigned int iOptions; } commandsA[] = { - { "account_email_set", &RPCServer::doAccountEmailSet, 2, 3, optCurrent }, - { "account_info", &RPCServer::doAccountInfo, 1, 2, optCurrent }, - { "account_lines", &RPCServer::doAccountLines, 1, 2, optCurrent|optClosed }, - { "account_message_set", &RPCServer::doAccountMessageSet, 3, 3, optCurrent }, - { "account_tx", &RPCServer::doAccountTransactions, 2, 3, optNetwork }, - { "account_wallet_set", &RPCServer::doAccountWalletSet, 2, 3, optCurrent }, - { "connect", &RPCServer::doConnect, 1, 2, }, - { "credit_set", &RPCServer::doCreditSet, 4, 6, optCurrent }, - { "data_delete", &RPCServer::doDataDelete, 1, 1, }, - { "data_fetch", &RPCServer::doDataFetch, 1, 1, }, - { "data_store", &RPCServer::doDataStore, 2, 2, }, - { "ledger", &RPCServer::doLedger, 0, 2, optNetwork }, - { "nickname_info", &RPCServer::doNicknameInfo, 1, 1, optCurrent }, - { "nickname_set", &RPCServer::doNicknameSet, 2, 3, optCurrent }, - { "password_fund", &RPCServer::doPasswordFund, 2, 3, optCurrent }, - { "password_set", &RPCServer::doPasswordSet, 2, 3, optNetwork }, - { "peers", &RPCServer::doPeers, 0, 0, }, - { "send", &RPCServer::doSend, 3, 7, optCurrent }, - { "server_info", &RPCServer::doServerInfo, 0, 0, }, - { "stop", &RPCServer::doStop, 0, 0, }, - { "transit_set", &RPCServer::doTransitSet, 5, 5, optCurrent }, - { "tx", &RPCServer::doTx, 1, 1, }, + { "account_email_set", &RPCServer::doAccountEmailSet, 2, 3, true,optCurrent }, + { "account_info", &RPCServer::doAccountInfo, 1, 2, false,optCurrent }, + { "account_lines", &RPCServer::doAccountLines, 1, 2, true,optCurrent|optClosed }, + { "account_message_set", &RPCServer::doAccountMessageSet, 3, 3, true,optCurrent }, + { "account_tx", &RPCServer::doAccountTransactions, 2, 3, true,optNetwork }, + { "account_wallet_set", &RPCServer::doAccountWalletSet, 2, 3, true,optCurrent }, + { "connect", &RPCServer::doConnect, 1, 2, true }, + { "credit_set", &RPCServer::doCreditSet, 4, 6, true,optCurrent }, + { "data_delete", &RPCServer::doDataDelete, 1, 1, true }, + { "data_fetch", &RPCServer::doDataFetch, 1, 1, true }, + { "data_store", &RPCServer::doDataStore, 2, 2, true }, + { "ledger", &RPCServer::doLedger, 0, 2, false,optNetwork }, + { "nickname_info", &RPCServer::doNicknameInfo, 1, 1, true,optCurrent }, + { "nickname_set", &RPCServer::doNicknameSet, 2, 3, true,optCurrent }, + { "password_fund", &RPCServer::doPasswordFund, 2, 3, true,optCurrent }, + { "password_set", &RPCServer::doPasswordSet, 2, 3, true,optNetwork }, + { "peers", &RPCServer::doPeers, 0, 0, true }, + { "send", &RPCServer::doSend, 3, 7, false, optCurrent }, + { "server_info", &RPCServer::doServerInfo, 0, 0, true }, + { "stop", &RPCServer::doStop, 0, 0, true }, + { "transit_set", &RPCServer::doTransitSet, 5, 5, true, optCurrent }, + { "tx", &RPCServer::doTx, 1, 1, true }, - { "unl_add", &RPCServer::doUnlAdd, 1, 2, }, - { "unl_delete", &RPCServer::doUnlDelete, 1, 1, }, - { "unl_list", &RPCServer::doUnlList, 0, 0, }, - { "unl_load", &RPCServer::doUnlLoad, 0, 0, }, - { "unl_network", &RPCServer::doUnlNetwork, 0, 0, }, - { "unl_reset", &RPCServer::doUnlReset, 0, 0, }, - { "unl_score", &RPCServer::doUnlScore, 0, 0, }, + { "unl_add", &RPCServer::doUnlAdd, 1, 2, true }, + { "unl_delete", &RPCServer::doUnlDelete, 1, 1, true }, + { "unl_list", &RPCServer::doUnlList, 0, 0, true }, + { "unl_load", &RPCServer::doUnlLoad, 0, 0, true }, + { "unl_network", &RPCServer::doUnlNetwork, 0, 0, true }, + { "unl_reset", &RPCServer::doUnlReset, 0, 0, true }, + { "unl_score", &RPCServer::doUnlScore, 0, 0, true }, - { "validation_create", &RPCServer::doValidationCreate, 0, 1, }, - { "validation_seed", &RPCServer::doValidationSeed, 0, 1, }, + { "validation_create", &RPCServer::doValidationCreate, 0, 1, false }, + { "validation_seed", &RPCServer::doValidationSeed, 0, 1, false }, - { "wallet_accounts", &RPCServer::doWalletAccounts, 1, 1, optCurrent }, - { "wallet_add", &RPCServer::doWalletAdd, 3, 5, optCurrent }, - { "wallet_claim", &RPCServer::doWalletClaim, 2, 4, optNetwork }, - { "wallet_create", &RPCServer::doWalletCreate, 3, 4, optCurrent }, - { "wallet_propose", &RPCServer::doWalletPropose, 0, 0, }, - { "wallet_seed", &RPCServer::doWalletSeed, 0, 1, }, + { "wallet_accounts", &RPCServer::doWalletAccounts, 1, 1, false, optCurrent }, + { "wallet_add", &RPCServer::doWalletAdd, 3, 5, false, optCurrent }, + { "wallet_claim", &RPCServer::doWalletClaim, 2, 4, false, optNetwork }, + { "wallet_create", &RPCServer::doWalletCreate, 3, 4, false, optCurrent }, + { "wallet_propose", &RPCServer::doWalletPropose, 0, 0, false, }, + { "wallet_seed", &RPCServer::doWalletSeed, 0, 1, false, }, + + { "login", &RPCServer::doLogin, 2, 2, true }, }; int i = NUMBER(commandsA); @@ -2027,6 +2054,9 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params if (i < 0) { return RPCError(rpcUNKNOWN_COMMAND); + }else if (commandsA[i].mAdminRequired && mRole!=ADMIN) + { + return RPCError(rpcNO_PERMISSION); } else if (params.size() < commandsA[i].iMinParams || params.size() > commandsA[i].iMaxParams) { diff --git a/src/RPCServer.h b/src/RPCServer.h index 3869c236ae..532b1675f3 100644 --- a/src/RPCServer.h +++ b/src/RPCServer.h @@ -22,6 +22,7 @@ public: // Misc failure rpcLOAD_FAILED, + rpcNO_PERMISSION, // Networking rpcNO_CLOSED, @@ -87,6 +88,9 @@ private: HttpRequest mIncomingRequest; HttpRequestParser mRequestParser; + enum { GUEST, USER, ADMIN }; + int mRole; + RPCServer(boost::asio::io_service& io_service, NetworkOPs* nopNetwork); RPCServer(const RPCServer&); // no implementation @@ -159,6 +163,8 @@ private: Json::Value doWalletUnlock(Json::Value& params); Json::Value doWalletVerify(Json::Value& params); + Json::Value doLogin(Json::Value& params); + public: typedef boost::shared_ptr pointer;