From fe37c350185c946cb735d1415c124657e7839558 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 15 Sep 2010 22:10:13 +0000 Subject: [PATCH] config option -rpcallowip= to accept json-rpc connections from another machine git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@155 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- main.cpp | 5 ----- rpc.cpp | 24 ++++++++++++++++++------ serialize.h | 2 +- util.cpp | 48 +++++++++++++++++++++++++++++++++++++++--------- util.h | 19 ++++++++++++++++++- 5 files changed, 76 insertions(+), 22 deletions(-) diff --git a/main.cpp b/main.cpp index c26755f7..5b7829e8 100644 --- a/main.cpp +++ b/main.cpp @@ -3170,11 +3170,6 @@ int64 GetBalance() } -int GetRandInt(int nMax) -{ - return GetRand(nMax); -} - bool SelectCoins(int64 nTargetValue, set& setCoinsRet) { setCoinsRet.clear(); diff --git a/rpc.cpp b/rpc.cpp index 0970c87b..9a475739 100644 --- a/rpc.cpp +++ b/rpc.cpp @@ -783,8 +783,9 @@ int ReadHTTPStatus(tcp::iostream& stream) getline(stream, str); vector vWords; boost::split(vWords, str, boost::is_any_of(" ")); - int nStatus = atoi(vWords[1].c_str()); - return nStatus; + if (vWords.size() < 2) + return 500; + return atoi(vWords[1].c_str()); } int ReadHTTPHeader(tcp::iostream& stream, map& mapHeadersRet) @@ -918,6 +919,17 @@ string JSONRPCReply(const Value& result, const Value& error, const Value& id) return write_string(Value(reply), false) + "\n"; } +bool ClientAllowed(const string& strAddress) +{ + if (strAddress == asio::ip::address_v4::loopback().to_string()) + return true; + const vector& vAllow = mapMultiArgs["-rpcallowip"]; + foreach(string strAllow, vAllow) + if (WildcardMatch(strAddress, strAllow)) + return true; + return false; +} + @@ -962,7 +974,7 @@ void ThreadRPCServer2(void* parg) // 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); + tcp::endpoint endpoint(mapArgs.count("-rpcallowip") ? asio::ip::address_v4::any() : asio::ip::address_v4::loopback(), 8332); tcp::acceptor acceptor(io_service, endpoint); loop @@ -976,8 +988,8 @@ void ThreadRPCServer2(void* parg) if (fShutdown) return; - // Shouldn't be possible for anyone else to connect, but just in case - if (peer.address().to_string() != "127.0.0.1") + // Restrict callers by IP + if (!ClientAllowed(peer.address().to_string())) continue; // Receive request @@ -1090,7 +1102,7 @@ Object CallRPC(const string& strMethod, const Array& params) GetConfigFile().c_str())); // Connect to localhost - tcp::iostream stream("127.0.0.1", "8332"); + tcp::iostream stream(GetArg("-rpcconnect", "127.0.0.1"), "8332"); if (stream.fail()) throw runtime_error("couldn't connect to server"); diff --git a/serialize.h b/serialize.h index e9f7e2db..b3ab9b5e 100644 --- a/serialize.h +++ b/serialize.h @@ -23,7 +23,7 @@ class CAutoFile; static const unsigned int MAX_SIZE = 0x02000000; static const int VERSION = 312; -static const char* pszSubVer = ".5"; +static const char* pszSubVer = ".6"; diff --git a/util.cpp b/util.cpp index 9efa20ed..b63b795b 100644 --- a/util.cpp +++ b/util.cpp @@ -127,6 +127,11 @@ uint64 GetRand(uint64 nMax) return (nRand % nMax); } +int GetRandInt(int nMax) +{ + return GetRand(nMax); +} + @@ -405,7 +410,7 @@ vector ParseHex(const char* psz) return vch; } -vector ParseHex(const std::string& str) +vector ParseHex(const string& str) { return ParseHex(str.c_str()); } @@ -473,6 +478,34 @@ const char* wxGetTranslation(const char* pszEnglish) } +bool WildcardMatch(const char* psz, const char* mask) +{ + loop + { + switch (*mask) + { + case '\0': + return (*psz == '\0'); + case '*': + return WildcardMatch(psz, mask+1) || (*psz && WildcardMatch(psz+1, mask)); + case '?': + if (*psz == '\0') + return false; + break; + default: + if (*psz != *mask) + return false; + break; + } + psz++; + mask++; + } +} + +bool WildcardMatch(const string& str, const string& mask) +{ + return WildcardMatch(str.c_str(), mask.c_str()); +} @@ -650,7 +683,7 @@ string GetDataDir() string GetConfigFile() { namespace fs = boost::filesystem; - fs::path pathConfig(mapArgs.count("-conf") ? mapArgs["-conf"] : string("bitcoin.conf")); + fs::path pathConfig(GetArg("-conf", "bitcoin.conf")); if (!pathConfig.is_complete()) pathConfig = fs::path(GetDataDir()) / pathConfig; return pathConfig.string(); @@ -718,13 +751,10 @@ void ShrinkDebugFile() // // "Never go to sea with two chronometers; take one or three." -// Our three chronometers are: +// Our three time sources are: // - System clock -// - Median of other server's clocks -// - NTP servers -// -// note: NTP isn't implemented yet, so until then we just use the median -// of other nodes clocks to correct ours. +// - Median of other nodes's clocks +// - The user (asking the user to fix the system clock if the first two disagree) // int64 GetTime() { @@ -768,7 +798,7 @@ void AddTimeData(unsigned int ip, int64 nTime) // If nobody else has the same time as us, give a warning bool fMatch = false; foreach(int64 nOffset, vTimeOffsets) - if (nOffset != 0 && abs64(nOffset) < 10 * 60) + if (nOffset != 0 && abs64(nOffset) < 5 * 60) fMatch = true; static bool fDone; if (!fMatch && !fDone) diff --git a/util.h b/util.h index 42d1fe46..2e6bf2a6 100644 --- a/util.h +++ b/util.h @@ -160,9 +160,11 @@ string FormatMoney(int64 n, bool fPlus=false); bool ParseMoney(const string& str, int64& nRet); bool ParseMoney(const char* pszIn, int64& nRet); vector ParseHex(const char* psz); -vector ParseHex(const std::string& str); +vector ParseHex(const string& str); void ParseParameters(int argc, char* argv[]); const char* wxGetTranslation(const char* psz); +bool WildcardMatch(const char* psz, const char* mask); +bool WildcardMatch(const string& str, const string& mask); int GetFilesize(FILE* file); void GetDataDir(char* pszDirRet); string GetConfigFile(); @@ -173,6 +175,7 @@ string MyGetSpecialFolderPath(int nFolder, bool fCreate); string GetDefaultDataDir(); string GetDataDir(); void ShrinkDebugFile(); +int GetRandInt(int nMax); uint64 GetRand(uint64 nMax); int64 GetTime(); int64 GetAdjustedTime(); @@ -399,6 +402,20 @@ inline bool IsSwitchChar(char c) #endif } +inline string GetArg(const string& strArg, const string& strDefault) +{ + if (mapArgs.count(strArg)) + return mapArgs[strArg]; + return strDefault; +} + +inline int64 GetArg(const string& strArg, int64 nDefault) +{ + if (mapArgs.count(strArg)) + return atoi64(mapArgs[strArg]); + return nDefault; +} +