Move iAdminGet to Config::getAdminRole

This commit is contained in:
Vinnie Falco
2013-08-31 20:46:27 -07:00
parent e22c1c3495
commit bbfbdabe76
8 changed files with 89 additions and 146 deletions

View File

@@ -36,7 +36,7 @@ std::string RPCServerHandler::processRequest (std::string const& request, std::s
} }
} }
int role = iAdminGet (jvRequest, remoteAddress); Config::Role const role (getConfig ().getAdminRole (jvRequest, remoteAddress));
// Parse id now so errors from here on will have the id // Parse id now so errors from here on will have the id
// //
@@ -71,7 +71,7 @@ std::string RPCServerHandler::processRequest (std::string const& request, std::s
// VFALCO TODO Shouldn't we handle this earlier? // VFALCO TODO Shouldn't we handle this earlier?
// //
if (role == RPCHandler::FORBID) if (role == Config::FORBID)
{ {
// VFALCO TODO Needs implementing // VFALCO TODO Needs implementing
// FIXME Needs implementing // FIXME Needs implementing

View File

@@ -41,7 +41,7 @@ void startServer ()
// VFALCO TODO Clean up this magic number // VFALCO TODO Clean up this magic number
LoadType loadType = LT_RPCReference; LoadType loadType = LT_RPCReference;
Json::Value jvResult = rhHandler.doCommand (jvCommand, RPCHandler::ADMIN, &loadType); Json::Value jvResult = rhHandler.doCommand (jvCommand, Config::ADMIN, &loadType);
if (!getConfig ().QUIET) if (!getConfig ().QUIET)
Log::out() << "Result: " << jvResult; Log::out() << "Result: " << jvResult;

View File

@@ -10,57 +10,22 @@
SETUP_LOG (RPCHandler) SETUP_LOG (RPCHandler)
int iAdminGet (const Json::Value& params, const std::string& strRemoteIp) RPCHandler::RPCHandler (NetworkOPs* netOps)
: mNetOps (netOps)
, mRole (Config::FORBID)
{ {
int iRole;
bool bPasswordSupplied = params.isMember ("admin_user") || params.isMember ("admin_password");
bool bPasswordRequired = !getConfig ().RPC_ADMIN_USER.empty () || !getConfig ().RPC_ADMIN_PASSWORD.empty ();
bool bPasswordWrong = bPasswordSupplied
? bPasswordRequired
// Supplied, required, and incorrect.
? getConfig ().RPC_ADMIN_USER != (params.isMember ("admin_user") ? params["admin_user"].asString () : "")
|| getConfig ().RPC_ADMIN_PASSWORD != (params.isMember ("admin_user") ? params["admin_password"].asString () : "")
// Supplied and not required.
: true
: false;
// Meets IP restriction for admin.
bool bAdminIP = false;
BOOST_FOREACH (const std::string & strAllowIp, getConfig ().RPC_ADMIN_ALLOW)
{
if (strAllowIp == strRemoteIp)
bAdminIP = true;
}
if (bPasswordWrong // Wrong
|| (bPasswordSupplied && !bAdminIP)) // Supplied and doesn't meet IP filter.
{
iRole = RPCHandler::FORBID;
}
// If supplied, password is correct.
else
{
// Allow admin, if from admin IP and no password is required or it was supplied and correct.
iRole = bAdminIP && (!bPasswordRequired || bPasswordSupplied) ? RPCHandler::ADMIN : RPCHandler::GUEST;
}
return iRole;
} }
RPCHandler::RPCHandler (NetworkOPs* netOps) : mNetOps (netOps), mRole (FORBID) RPCHandler::RPCHandler (NetworkOPs* netOps, InfoSub::pointer infoSub)
: mNetOps (netOps)
, mInfoSub (infoSub)
, mRole (Config::FORBID)
{ {
;
}
RPCHandler::RPCHandler (NetworkOPs* netOps, InfoSub::pointer infoSub) : mNetOps (netOps), mInfoSub (infoSub), mRole (FORBID)
{
;
} }
Json::Value RPCHandler::transactionSign (Json::Value params, bool bSubmit, bool bFailHard, Application::ScopedLockType& mlh) Json::Value RPCHandler::transactionSign (Json::Value params, bool bSubmit, bool bFailHard, Application::ScopedLockType& mlh)
{ {
if (getApp().getFeeTrack().isLoadedCluster() && (mRole != ADMIN)) if (getApp().getFeeTrack().isLoadedCluster() && (mRole != Config::ADMIN))
return rpcError(rpcTOO_BUSY); return rpcError(rpcTOO_BUSY);
Json::Value jvResult; Json::Value jvResult;
@@ -353,7 +318,7 @@ Json::Value RPCHandler::transactionSign (Json::Value params, bool bSubmit, bool
try try
{ {
// FIXME: For performance, should use asynch interface // FIXME: For performance, should use asynch interface
tpTrans = mNetOps->submitTransactionSync (tpTrans, mRole == ADMIN, bFailHard, bSubmit); tpTrans = mNetOps->submitTransactionSync (tpTrans, mRole == Config::ADMIN, bFailHard, bSubmit);
if (!tpTrans) if (!tpTrans)
{ {
@@ -1707,7 +1672,7 @@ Json::Value RPCHandler::doSubmit (Json::Value params, LoadType* loadType, Applic
try try
{ {
(void) mNetOps->processTransaction (tpTrans, mRole == ADMIN, (void) mNetOps->processTransaction (tpTrans, mRole == Config::ADMIN,
params.isMember ("fail_hard") && params["fail_hard"].asBool ()); params.isMember ("fail_hard") && params["fail_hard"].asBool ());
} }
catch (std::exception& e) catch (std::exception& e)
@@ -1778,7 +1743,7 @@ Json::Value RPCHandler::doServerInfo (Json::Value, LoadType* loadType, Applicati
{ {
Json::Value ret (Json::objectValue); Json::Value ret (Json::objectValue);
ret["info"] = mNetOps->getServerInfo (true, mRole == ADMIN); ret["info"] = mNetOps->getServerInfo (true, mRole == Config::ADMIN);
return ret; return ret;
} }
@@ -1787,7 +1752,7 @@ Json::Value RPCHandler::doServerState (Json::Value, LoadType* loadType, Applicat
{ {
Json::Value ret (Json::objectValue); Json::Value ret (Json::objectValue);
ret["state"] = mNetOps->getServerInfo (false, mRole == ADMIN); ret["state"] = mNetOps->getServerInfo (false, mRole == Config::ADMIN);
return ret; return ret;
} }
@@ -1804,7 +1769,7 @@ Json::Value RPCHandler::doTxHistory (Json::Value params, LoadType* loadType, App
unsigned int startIndex = params["start"].asUInt (); unsigned int startIndex = params["start"].asUInt ();
if ((startIndex > 10000) && (mRole != ADMIN)) if ((startIndex > 10000) && (mRole != Config::ADMIN))
return rpcError (rpcNO_PERMISSION); return rpcError (rpcNO_PERMISSION);
Json::Value obj; Json::Value obj;
@@ -1962,7 +1927,7 @@ Json::Value RPCHandler::doLedger (Json::Value params, LoadType* loadType, Applic
| (bTransactions ? LEDGER_JSON_DUMP_TXRP : 0) | (bTransactions ? LEDGER_JSON_DUMP_TXRP : 0)
| (bAccounts ? LEDGER_JSON_DUMP_STATE : 0); | (bAccounts ? LEDGER_JSON_DUMP_STATE : 0);
if ((bFull || bAccounts) && getApp().getFeeTrack().isLoadedLocal() && (mRole != ADMIN)) if ((bFull || bAccounts) && getApp().getFeeTrack().isLoadedLocal() && (mRole != Config::ADMIN))
{ {
WriteLog (lsDEBUG, Peer) << "Too busy to give full ledger"; WriteLog (lsDEBUG, Peer) << "Too busy to give full ledger";
return rpcError(rpcTOO_BUSY); return rpcError(rpcTOO_BUSY);
@@ -2064,7 +2029,7 @@ Json::Value RPCHandler::doAccountTransactions (Json::Value params, LoadType* loa
if (bBinary) if (bBinary)
{ {
std::vector<NetworkOPs::txnMetaLedgerType> txns = std::vector<NetworkOPs::txnMetaLedgerType> txns =
mNetOps->getAccountTxsB (raAccount, uLedgerMin, uLedgerMax, bDescending, offset, limit, mRole == ADMIN); mNetOps->getAccountTxsB (raAccount, uLedgerMin, uLedgerMax, bDescending, offset, limit, mRole == Config::ADMIN);
for (std::vector<NetworkOPs::txnMetaLedgerType>::const_iterator it = txns.begin (), end = txns.end (); for (std::vector<NetworkOPs::txnMetaLedgerType>::const_iterator it = txns.begin (), end = txns.end ();
it != end; ++it) it != end; ++it)
@@ -2081,7 +2046,7 @@ Json::Value RPCHandler::doAccountTransactions (Json::Value params, LoadType* loa
} }
else else
{ {
std::vector< std::pair<Transaction::pointer, TransactionMetaSet::pointer> > txns = mNetOps->getAccountTxs (raAccount, uLedgerMin, uLedgerMax, bDescending, offset, limit, mRole == ADMIN); std::vector< std::pair<Transaction::pointer, TransactionMetaSet::pointer> > txns = mNetOps->getAccountTxs (raAccount, uLedgerMin, uLedgerMax, bDescending, offset, limit, mRole == Config::ADMIN);
for (std::vector< std::pair<Transaction::pointer, TransactionMetaSet::pointer> >::iterator it = txns.begin (), end = txns.end (); it != end; ++it) for (std::vector< std::pair<Transaction::pointer, TransactionMetaSet::pointer> >::iterator it = txns.begin (), end = txns.end (); it != end; ++it)
{ {
@@ -2214,7 +2179,7 @@ Json::Value RPCHandler::doTxAccount (Json::Value params, LoadType* loadType, App
if (bBinary) if (bBinary)
{ {
std::vector<NetworkOPs::txnMetaLedgerType> txns = std::vector<NetworkOPs::txnMetaLedgerType> txns =
mNetOps->getTxsAccountB (raAccount, uLedgerMin, uLedgerMax, bForward, resumeToken, limit, mRole == ADMIN); mNetOps->getTxsAccountB (raAccount, uLedgerMin, uLedgerMax, bForward, resumeToken, limit, mRole == Config::ADMIN);
for (std::vector<NetworkOPs::txnMetaLedgerType>::const_iterator it = txns.begin (), end = txns.end (); for (std::vector<NetworkOPs::txnMetaLedgerType>::const_iterator it = txns.begin (), end = txns.end ();
it != end; ++it) it != end; ++it)
@@ -2232,7 +2197,7 @@ Json::Value RPCHandler::doTxAccount (Json::Value params, LoadType* loadType, App
else else
{ {
std::vector< std::pair<Transaction::pointer, TransactionMetaSet::pointer> > txns = std::vector< std::pair<Transaction::pointer, TransactionMetaSet::pointer> > txns =
mNetOps->getTxsAccount (raAccount, uLedgerMin, uLedgerMax, bForward, resumeToken, limit, mRole == ADMIN); mNetOps->getTxsAccount (raAccount, uLedgerMin, uLedgerMax, bForward, resumeToken, limit, mRole == Config::ADMIN);
for (std::vector< std::pair<Transaction::pointer, TransactionMetaSet::pointer> >::iterator it = txns.begin (), end = txns.end (); it != end; ++it) for (std::vector< std::pair<Transaction::pointer, TransactionMetaSet::pointer> >::iterator it = txns.begin (), end = txns.end (); it != end; ++it)
{ {
@@ -2275,7 +2240,7 @@ Json::Value RPCHandler::doTxAccount (Json::Value params, LoadType* loadType, App
// secret: <string> // optional // secret: <string> // optional
// } // }
// //
// This command requires admin access because it makes no sense to ask an untrusted server for this. // This command requires Config::ADMIN access because it makes no sense to ask an untrusted server for this.
Json::Value RPCHandler::doValidationCreate (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder) Json::Value RPCHandler::doValidationCreate (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
{ {
RippleAddress raSeed; RippleAddress raSeed;
@@ -2488,9 +2453,9 @@ Json::Value RPCHandler::doWalletSeed (Json::Value params, LoadType* loadType, Ap
} }
#if ENABLE_INSECURE #if ENABLE_INSECURE
// TODO: for now this simply checks if this is the admin account // TODO: for now this simply checks if this is the Config::ADMIN account
// TODO: need to prevent them hammering this over and over // TODO: need to prevent them hammering this over and over
// TODO: maybe a better way is only allow admin from local host // TODO: maybe a better way is only allow Config::ADMIN from local host
// { // {
// username: <string>, // username: <string>,
// password: <string> // password: <string>
@@ -3247,7 +3212,7 @@ Json::Value RPCHandler::doSubscribe (Json::Value params, LoadType* loadType, App
if (params.isMember ("url")) if (params.isMember ("url"))
{ {
if (mRole != ADMIN) if (mRole != Config::ADMIN)
return rpcError (rpcNO_PERMISSION); return rpcError (rpcNO_PERMISSION);
std::string strUrl = params["url"].asString (); std::string strUrl = params["url"].asString ();
@@ -3534,7 +3499,7 @@ Json::Value RPCHandler::doUnsubscribe (Json::Value params, LoadType* loadType, A
if (params.isMember ("url")) if (params.isMember ("url"))
{ {
if (mRole != ADMIN) if (mRole != Config::ADMIN)
return rpcError (rpcNO_PERMISSION); return rpcError (rpcNO_PERMISSION);
std::string strUrl = params["url"].asString (); std::string strUrl = params["url"].asString ();
@@ -3754,7 +3719,7 @@ Json::Value RPCHandler::doInternal (Json::Value params, LoadType* loadType, Appl
Json::Value RPCHandler::doCommand (const Json::Value& params, int iRole, LoadType* loadType) Json::Value RPCHandler::doCommand (const Json::Value& params, int iRole, LoadType* loadType)
{ {
if (iRole != ADMIN) if (iRole != Config::ADMIN)
{ {
int jc = getApp().getJobQueue ().getJobCountGE (jtCLIENT); int jc = getApp().getJobQueue ().getJobCountGE (jtCLIENT);
@@ -3862,7 +3827,7 @@ Json::Value RPCHandler::doCommand (const Json::Value& params, int iRole, LoadTyp
{ {
return rpcError (rpcUNKNOWN_COMMAND); return rpcError (rpcUNKNOWN_COMMAND);
} }
else if (commandsA[i].bAdminRequired && mRole != ADMIN) else if (commandsA[i].bAdminRequired && mRole != Config::ADMIN)
{ {
return rpcError (rpcNO_PERMISSION); return rpcError (rpcNO_PERMISSION);
} }

View File

@@ -20,14 +20,6 @@ class InfoSub;
class RPCHandler class RPCHandler
{ {
public: public:
enum
{
GUEST,
USER,
ADMIN,
FORBID
};
explicit RPCHandler (NetworkOPs* netOps); explicit RPCHandler (NetworkOPs* netOps);
RPCHandler (NetworkOPs* netOps, InfoSub::pointer infoSub); RPCHandler (NetworkOPs* netOps, InfoSub::pointer infoSub);
@@ -185,8 +177,4 @@ private:
handler_t mHandler; handler_t mHandler;
}; };
// VFALCO TODO tidy up this loose function
int iAdminGet (const Json::Value& jvRequest, const std::string& strRemoteIp);
#endif #endif
// vim:ts=4

View File

@@ -134,17 +134,17 @@ public:
RPCHandler mRPCHandler (&mNetwork, boost::dynamic_pointer_cast<InfoSub> (this->shared_from_this ())); RPCHandler mRPCHandler (&mNetwork, boost::dynamic_pointer_cast<InfoSub> (this->shared_from_this ()));
Json::Value jvResult (Json::objectValue); Json::Value jvResult (Json::objectValue);
int iRole = mHandler->getPublic () Config::Role const role = mHandler->getPublic ()
? RPCHandler::GUEST // Don't check on the public interface. ? Config::GUEST // Don't check on the public interface.
: iAdminGet (jvRequest, mRemoteIP); : getConfig ().getAdminRole (jvRequest, mRemoteIP);
if (RPCHandler::FORBID == iRole) if (Config::FORBID == role)
{ {
jvResult["result"] = rpcError (rpcFORBIDDEN); jvResult["result"] = rpcError (rpcFORBIDDEN);
} }
else else
{ {
jvResult["result"] = mRPCHandler.doCommand (jvRequest, iRole, &loadType); jvResult["result"] = mRPCHandler.doCommand (jvRequest, role, &loadType);
} }
// Debit/credit the load and see if we should include a warning. // Debit/credit the load and see if we should include a warning.

View File

@@ -4,61 +4,10 @@
*/ */
//============================================================================== //==============================================================================
/** Add this to get the @ref ripple_client module. #include "BeastConfig.h"
@file ripple_client.cpp #include "../ripple_client/ripple_client.h"
@ingroup ripple_client
*/
/* namespace ripple
#include <set> {
}
#include <boost/unordered_set.hpp>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include "ripple_client.h"
#include "../ripple_basics/ripple_basics.h"
#include "../ripple_data/ripple_data.h"
*/
/*
#include "src/cpp/ripple/ripple_InfoSub.h"
// Order and indentation reflect the hierarchy of dependencies
// VFALCO NOTE Don't add anything here!!!
#include "src/cpp/ripple/ripple_HashedObject.h"
#include "src/cpp/ripple/ripple_SHAMapItem.h"
#include "src/cpp/ripple/ripple_SHAMapNode.h"
#include "src/cpp/ripple/ripple_SHAMapAddNode.h"
#include "src/cpp/ripple/ripple_SHAMapMissingNode.h"
#include "src/cpp/ripple/ripple_SHAMapTreeNode.h"
#include "src/cpp/ripple/ripple_SHAMapSyncFilter.h"
#include "src/cpp/ripple/ripple_SHAMap.h"
#include "src/cpp/ripple/ripple_SerializedTransaction.h"
#include "src/cpp/ripple/ripple_SerializedLedger.h"
#include "src/cpp/ripple/TransactionMeta.h"
#include "src/cpp/ripple/Transaction.h"
#include "src/cpp/ripple/ripple_AccountState.h"
#include "src/cpp/ripple/ripple_NicknameState.h"
#include "src/cpp/ripple/Ledger.h"
#include "src/cpp/ripple/ripple_LedgerEntrySet.h"
#include "src/cpp/ripple/TransactionEngine.h"
#include "src/cpp/ripple/ripple_ILoadManager.h"
#include "src/cpp/ripple/ripple_Peer.h"
#include "src/cpp/ripple/ripple_PeerSet.h"
#include "src/cpp/ripple/ripple_InboundLedger.h"
#include "src/cpp/ripple/ripple_LedgerHistory.h"
#include "src/cpp/ripple/ripple_CanonicalTXSet.h"
#include "src/cpp/ripple/LedgerMaster.h"
#include "src/cpp/ripple/ripple_InfoSub.h"
#include "src/cpp/ripple/SerializedValidation.h"
#include "src/cpp/ripple/LedgerProposal.h"
#include "src/cpp/ripple/ripple_AcceptedLedgerTx.h"
#include "src/cpp/ripple/NetworkOPs.h"
#include "src/cpp/ripple/ripple_IApplication.h"
//#include "src/cpp/ripple/NetworkOPs.cpp"
*/

View File

@@ -579,3 +579,43 @@ void Config::setRpcIpAndOptionalPort (std::string const& newAddress)
} }
} }
//------------------------------------------------------------------------------
Config::Role Config::getAdminRole (Json::Value const& params, std::string const& strRemoteIp) const
{
Config::Role role;
bool bPasswordSupplied = params.isMember ("admin_user") || params.isMember ("admin_password");
bool bPasswordRequired = !this->RPC_ADMIN_USER.empty () || !this->RPC_ADMIN_PASSWORD.empty ();
bool bPasswordWrong = bPasswordSupplied
? bPasswordRequired
// Supplied, required, and incorrect.
? this->RPC_ADMIN_USER != (params.isMember ("admin_user") ? params["admin_user"].asString () : "")
|| this->RPC_ADMIN_PASSWORD != (params.isMember ("admin_user") ? params["admin_password"].asString () : "")
// Supplied and not required.
: true
: false;
// Meets IP restriction for admin.
bool bAdminIP = false;
BOOST_FOREACH (const std::string & strAllowIp, this->RPC_ADMIN_ALLOW)
{
if (strAllowIp == strRemoteIp)
bAdminIP = true;
}
if (bPasswordWrong // Wrong
|| (bPasswordSupplied && !bAdminIP)) // Supplied and doesn't meet IP filter.
{
role = Config::FORBID;
}
// If supplied, password is correct.
else
{
// Allow admin, if from admin IP and no password is required or it was supplied and correct.
role = bAdminIP && (!bPasswordRequired || bPasswordSupplied) ? Config::ADMIN : Config::GUEST;
}
return role;
}

View File

@@ -216,41 +216,31 @@ public:
// //
public: public:
/** Get the client or server RPC IP address. /** Get the client or server RPC IP address.
@note The string may not always be in a valid parsable state. @note The string may not always be in a valid parsable state.
@return A string representing the address. @return A string representing the address.
*/ */
std::string getRpcIP () const { return m_rpcIP; } std::string getRpcIP () const { return m_rpcIP; }
/** Get the client or server RPC port number. /** Get the client or server RPC port number.
@note The port number may be invalid (out of range or zero) @note The port number may be invalid (out of range or zero)
@return The RPC port number. @return The RPC port number.
*/ */
int getRpcPort () const { return m_rpcPort; } int getRpcPort () const { return m_rpcPort; }
/** Set the client or server RPC IP and optional port. /** Set the client or server RPC IP and optional port.
@note The string is not syntax checked. @note The string is not syntax checked.
@param newAddress A string in the format <ip-address>[':'<port-number>] @param newAddress A string in the format <ip-address>[':'<port-number>]
*/ */
void setRpcIpAndOptionalPort (std::string const& newAddress); void setRpcIpAndOptionalPort (std::string const& newAddress);
/** Set the client or server RPC IP. /** Set the client or server RPC IP.
@note The string is not syntax-checked. @note The string is not syntax-checked.
@param newIP A string representing the IP address to use. @param newIP A string representing the IP address to use.
*/ */
void setRpcIP (std::string const& newIP) { m_rpcIP = newIP; } void setRpcIP (std::string const& newIP) { m_rpcIP = newIP; }
/** Set the client or server RPC port number. /** Set the client or server RPC port number.
@note The port number is not range checked. @note The port number is not range checked.
@param newPort The RPC port number to use. @param newPort The RPC port number to use.
*/ */
void setRpcPort (int newPort) { m_rpcPort = newPort; } void setRpcPort (int newPort) { m_rpcPort = newPort; }
@@ -266,6 +256,17 @@ public:
return s; return s;
} }
/** Determine the level of administrative permission to grant.
*/
enum Role
{
GUEST,
USER,
ADMIN,
FORBID
};
Role getAdminRole (Json::Value const& params, std::string const& strRemoteIp) const;
private: private:
std::string m_rpcIP; std::string m_rpcIP;
// VFALCO TODO This should be a short. // VFALCO TODO This should be a short.