mirror of
https://github.com/monero-project/monero.git
synced 2024-11-17 16:27:39 +00:00
rpc: add a sanity limit to a few RPC in restricted mode
This commit is contained in:
parent
77a008f714
commit
4d3c2d0b7b
2 changed files with 46 additions and 6 deletions
|
@ -68,6 +68,11 @@ using namespace epee;
|
||||||
#define DEFAULT_PAYMENT_DIFFICULTY 1000
|
#define DEFAULT_PAYMENT_DIFFICULTY 1000
|
||||||
#define DEFAULT_PAYMENT_CREDITS_PER_HASH 100
|
#define DEFAULT_PAYMENT_CREDITS_PER_HASH 100
|
||||||
|
|
||||||
|
#define RESTRICTED_BLOCK_HEADER_RANGE 1000
|
||||||
|
#define RESTRICTED_TRANSACTIONS_COUNT 100
|
||||||
|
#define RESTRICTED_SPENT_KEY_IMAGES_COUNT 5000
|
||||||
|
#define RESTRICTED_BLOCK_COUNT 1000
|
||||||
|
|
||||||
#define RPC_TRACKER(rpc) \
|
#define RPC_TRACKER(rpc) \
|
||||||
PERF_TIMER(rpc); \
|
PERF_TIMER(rpc); \
|
||||||
RPCTracker tracker(#rpc, PERF_TIMER_NAME(rpc))
|
RPCTracker tracker(#rpc, PERF_TIMER_NAME(rpc))
|
||||||
|
@ -639,6 +644,13 @@ namespace cryptonote
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_BLOCKS_BY_HEIGHT>(invoke_http_mode::BIN, "/getblocks_by_height.bin", req, res, r))
|
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_BLOCKS_BY_HEIGHT>(invoke_http_mode::BIN, "/getblocks_by_height.bin", req, res, r))
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
const bool restricted = m_restricted && ctx;
|
||||||
|
if (restricted && req.heights.size() > RESTRICTED_BLOCK_COUNT)
|
||||||
|
{
|
||||||
|
res.status = "Too many blocks requested in restricted mode";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
res.status = "Failed";
|
res.status = "Failed";
|
||||||
res.blocks.clear();
|
res.blocks.clear();
|
||||||
res.blocks.reserve(req.heights.size());
|
res.blocks.reserve(req.heights.size());
|
||||||
|
@ -793,11 +805,17 @@ namespace cryptonote
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_TRANSACTIONS>(invoke_http_mode::JON, "/gettransactions", req, res, ok))
|
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_TRANSACTIONS>(invoke_http_mode::JON, "/gettransactions", req, res, ok))
|
||||||
return ok;
|
return ok;
|
||||||
|
|
||||||
CHECK_PAYMENT_MIN1(req, res, req.txs_hashes.size() * COST_PER_TX, false);
|
|
||||||
|
|
||||||
const bool restricted = m_restricted && ctx;
|
const bool restricted = m_restricted && ctx;
|
||||||
const bool request_has_rpc_origin = ctx != NULL;
|
const bool request_has_rpc_origin = ctx != NULL;
|
||||||
|
|
||||||
|
if (restricted && req.txs_hashes.size() > RESTRICTED_TRANSACTIONS_COUNT)
|
||||||
|
{
|
||||||
|
res.status = "Too many transactions requested in restricted mode";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_PAYMENT_MIN1(req, res, req.txs_hashes.size() * COST_PER_TX, false);
|
||||||
|
|
||||||
std::vector<crypto::hash> vh;
|
std::vector<crypto::hash> vh;
|
||||||
for(const auto& tx_hex_str: req.txs_hashes)
|
for(const auto& tx_hex_str: req.txs_hashes)
|
||||||
{
|
{
|
||||||
|
@ -1027,11 +1045,17 @@ namespace cryptonote
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_IS_KEY_IMAGE_SPENT>(invoke_http_mode::JON, "/is_key_image_spent", req, res, ok))
|
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_IS_KEY_IMAGE_SPENT>(invoke_http_mode::JON, "/is_key_image_spent", req, res, ok))
|
||||||
return ok;
|
return ok;
|
||||||
|
|
||||||
CHECK_PAYMENT_MIN1(req, res, req.key_images.size() * COST_PER_KEY_IMAGE, false);
|
|
||||||
|
|
||||||
const bool restricted = m_restricted && ctx;
|
const bool restricted = m_restricted && ctx;
|
||||||
const bool request_has_rpc_origin = ctx != NULL;
|
const bool request_has_rpc_origin = ctx != NULL;
|
||||||
|
|
||||||
|
if (restricted && req.key_images.size() > RESTRICTED_SPENT_KEY_IMAGES_COUNT)
|
||||||
|
{
|
||||||
|
res.status = "Too many key images queried in restricted mode";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_PAYMENT_MIN1(req, res, req.key_images.size() * COST_PER_KEY_IMAGE, false);
|
||||||
|
|
||||||
std::vector<crypto::key_image> key_images;
|
std::vector<crypto::key_image> key_images;
|
||||||
for(const auto& ki_hex_str: req.key_images)
|
for(const auto& ki_hex_str: req.key_images)
|
||||||
{
|
{
|
||||||
|
@ -2034,6 +2058,14 @@ namespace cryptonote
|
||||||
|
|
||||||
CHECK_PAYMENT_MIN1(req, res, COST_PER_BLOCK_HEADER, false);
|
CHECK_PAYMENT_MIN1(req, res, COST_PER_BLOCK_HEADER, false);
|
||||||
|
|
||||||
|
const bool restricted = m_restricted && ctx;
|
||||||
|
if (restricted && req.hashes.size() > RESTRICTED_BLOCK_COUNT)
|
||||||
|
{
|
||||||
|
error_resp.code = CORE_RPC_ERROR_CODE_RESTRICTED;
|
||||||
|
error_resp.message = "Too many block headers requested in restricted mode";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto get = [this](const std::string &hash, bool fill_pow_hash, block_header_response &block_header, bool restricted, epee::json_rpc::error& error_resp) -> bool {
|
auto get = [this](const std::string &hash, bool fill_pow_hash, block_header_response &block_header, bool restricted, epee::json_rpc::error& error_resp) -> bool {
|
||||||
crypto::hash block_hash;
|
crypto::hash block_hash;
|
||||||
bool hash_parsed = parse_hash256(hash, block_hash);
|
bool hash_parsed = parse_hash256(hash, block_hash);
|
||||||
|
@ -2069,7 +2101,6 @@ namespace cryptonote
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const bool restricted = m_restricted && ctx;
|
|
||||||
if (!req.hash.empty())
|
if (!req.hash.empty())
|
||||||
{
|
{
|
||||||
if (!get(req.hash, req.fill_pow_hash, res.block_header, restricted, error_resp))
|
if (!get(req.hash, req.fill_pow_hash, res.block_header, restricted, error_resp))
|
||||||
|
@ -2101,6 +2132,14 @@ namespace cryptonote
|
||||||
error_resp.message = "Invalid start/end heights.";
|
error_resp.message = "Invalid start/end heights.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
const bool restricted = m_restricted && ctx;
|
||||||
|
if (restricted && req.end_height - req.start_height > RESTRICTED_BLOCK_HEADER_RANGE)
|
||||||
|
{
|
||||||
|
error_resp.code = CORE_RPC_ERROR_CODE_RESTRICTED;
|
||||||
|
error_resp.message = "Too many block headers requested.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
CHECK_PAYMENT_MIN1(req, res, (req.end_height - req.start_height + 1) * COST_PER_BLOCK_HEADER, false);
|
CHECK_PAYMENT_MIN1(req, res, (req.end_height - req.start_height + 1) * COST_PER_BLOCK_HEADER, false);
|
||||||
for (uint64_t h = req.start_height; h <= req.end_height; ++h)
|
for (uint64_t h = req.start_height; h <= req.end_height; ++h)
|
||||||
{
|
{
|
||||||
|
@ -2127,7 +2166,6 @@ namespace cryptonote
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
res.headers.push_back(block_header_response());
|
res.headers.push_back(block_header_response());
|
||||||
const bool restricted = m_restricted && ctx;
|
|
||||||
bool response_filled = fill_block_header_response(blk, false, block_height, block_hash, res.headers.back(), req.fill_pow_hash && !restricted);
|
bool response_filled = fill_block_header_response(blk, false, block_height, block_hash, res.headers.back(), req.fill_pow_hash && !restricted);
|
||||||
if (!response_filled)
|
if (!response_filled)
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#define CORE_RPC_ERROR_CODE_PAYMENT_TOO_LOW -16
|
#define CORE_RPC_ERROR_CODE_PAYMENT_TOO_LOW -16
|
||||||
#define CORE_RPC_ERROR_CODE_DUPLICATE_PAYMENT -17
|
#define CORE_RPC_ERROR_CODE_DUPLICATE_PAYMENT -17
|
||||||
#define CORE_RPC_ERROR_CODE_STALE_PAYMENT -18
|
#define CORE_RPC_ERROR_CODE_STALE_PAYMENT -18
|
||||||
|
#define CORE_RPC_ERROR_CODE_RESTRICTED -19
|
||||||
|
|
||||||
static inline const char *get_rpc_server_error_message(int64_t code)
|
static inline const char *get_rpc_server_error_message(int64_t code)
|
||||||
{
|
{
|
||||||
|
@ -70,6 +71,7 @@ static inline const char *get_rpc_server_error_message(int64_t code)
|
||||||
case CORE_RPC_ERROR_CODE_PAYMENT_TOO_LOW: return "Payment too low";
|
case CORE_RPC_ERROR_CODE_PAYMENT_TOO_LOW: return "Payment too low";
|
||||||
case CORE_RPC_ERROR_CODE_DUPLICATE_PAYMENT: return "Duplicate payment";
|
case CORE_RPC_ERROR_CODE_DUPLICATE_PAYMENT: return "Duplicate payment";
|
||||||
case CORE_RPC_ERROR_CODE_STALE_PAYMENT: return "Stale payment";
|
case CORE_RPC_ERROR_CODE_STALE_PAYMENT: return "Stale payment";
|
||||||
|
case CORE_RPC_ERROR_CODE_RESTRICTED: return "Parameters beyond restricted allowance";
|
||||||
default: MERROR("Unknown error: " << code); return "Unknown error";
|
default: MERROR("Unknown error: " << code); return "Unknown error";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue