mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-11 04:32:30 +00:00
Add untrusted connection security infrastructure (v3)
Replace the v2 blacklist approach with a per-command flag system. Commands must opt in to being available for untrusted connections via flag_untrusted_safe (0x400), checked in call_command() which catches all execution paths including nested commands. Infrastructure changes: - Add flag_untrusted_safe to CommandMap - Add untrusted_error exception type for proper error codes - Enforce trust check in both call_command() overloads - Add catch blocks in xmlrpc_c, xmlrpc_tinyxml2, and jsonrpc handlers - Port SCGI trust state management from v2 (thread_local, header parsing) - Add _U macro variants in command_helpers.h for safe command registration - Add CMD2_VAR_*_U and CMD2_VAR_*_U_GET variants for variables
This commit is contained in:
@@ -19,6 +19,11 @@ void initialize_commands();
|
||||
rpc::commands.insert_slot<rpc::command_base_is_type<rpc::function>::type>(key, slot, &rpc::function, \
|
||||
rpc::CommandMap::flag_dont_delete, NULL, NULL);
|
||||
|
||||
#define CMD2_A_FUNCTION_U(key, function, slot, parm, doc) \
|
||||
rpc::commands.insert_slot<rpc::command_base_is_type<rpc::function>::type>(key, slot, &rpc::function, \
|
||||
rpc::CommandMap::flag_dont_delete | rpc::CommandMap::flag_public_rpc | \
|
||||
rpc::CommandMap::flag_untrusted_safe, NULL, NULL);
|
||||
|
||||
#define CMD2_ANY(key, slot) CMD2_A_FUNCTION(key, command_base_call<rpc::target_type>, slot, "i:", "")
|
||||
|
||||
#define CMD2_ANY_P(key, slot) CMD2_A_FUNCTION_PRIVATE(key, command_base_call<rpc::target_type>, slot, "i:", "")
|
||||
@@ -35,6 +40,42 @@ void initialize_commands();
|
||||
|
||||
#define CMD2_ANY_LIST(key, slot) CMD2_A_FUNCTION(key, command_base_call_list<rpc::target_type>, slot, "i:", "")
|
||||
|
||||
#define CMD2_ANY_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call<rpc::target_type>, slot, "i:", "")
|
||||
#define CMD2_ANY_VOID_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call<rpc::target_type>, object_convert_void(slot), "i:", "")
|
||||
#define CMD2_ANY_V_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call_list<rpc::target_type>, object_convert_void(slot), "i:", "")
|
||||
#define CMD2_ANY_L_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call_list<rpc::target_type>, slot, "A:", "")
|
||||
|
||||
#define CMD2_ANY_VALUE_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call_value<rpc::target_type>, slot, "i:i", "")
|
||||
#define CMD2_ANY_VALUE_V_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call_value<rpc::target_type>, object_convert_void(slot), "i:i", "")
|
||||
#define CMD2_ANY_VALUE_KB_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call_value_kb<rpc::target_type>, object_convert_void(slot), "i:i", "")
|
||||
|
||||
#define CMD2_ANY_STRING_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call_string<rpc::target_type>, slot, "i:s", "")
|
||||
#define CMD2_ANY_STRING_V_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call_string<rpc::target_type>, object_convert_void(slot), "i:s", "")
|
||||
|
||||
#define CMD2_ANY_LIST_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call_list<rpc::target_type>, slot, "i:", "")
|
||||
|
||||
#define CMD2_DL_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call<core::Download*>, slot, "i:", "")
|
||||
#define CMD2_DL_V_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call<core::Download*>, object_convert_void(slot), "i:", "")
|
||||
#define CMD2_DL_VALUE_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call_value<core::Download*>, slot, "i:", "")
|
||||
#define CMD2_DL_VALUE_V_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call_value<core::Download*>, object_convert_void(slot), "i:", "")
|
||||
#define CMD2_DL_STRING_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call_string<core::Download*>, slot, "i:", "")
|
||||
#define CMD2_DL_STRING_V_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call_string<core::Download*>, object_convert_void(slot), "i:", "")
|
||||
#define CMD2_DL_LIST_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call_list<core::Download*>, slot, "i:", "")
|
||||
|
||||
#define CMD2_FILE_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call<torrent::File*>, slot, "i:", "")
|
||||
#define CMD2_FILE_V_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call<torrent::File*>, object_convert_void(slot), "i:", "")
|
||||
#define CMD2_FILE_VALUE_V_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call_value<torrent::File*>, object_convert_void(slot), "i:i", "")
|
||||
|
||||
#define CMD2_FILEITR_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call<torrent::FileListIterator*>, slot, "i:", "")
|
||||
|
||||
#define CMD2_PEER_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call<torrent::Peer*>, slot, "i:", "")
|
||||
#define CMD2_PEER_V_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call<torrent::Peer*>, object_convert_void(slot), "i:", "")
|
||||
#define CMD2_PEER_VALUE_V_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call_value<torrent::Peer*>, object_convert_void(slot), "i:i", "")
|
||||
|
||||
#define CMD2_TRACKER_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call<torrent::tracker::Tracker*>, slot, "i:", "")
|
||||
#define CMD2_TRACKER_V_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call<torrent::tracker::Tracker*>, object_convert_void(slot), "i:", "")
|
||||
#define CMD2_TRACKER_VALUE_V_U(key, slot) CMD2_A_FUNCTION_U(key, command_base_call_value<torrent::tracker::Tracker*>, object_convert_void(slot), "i:i", "")
|
||||
|
||||
#define CMD2_DL(key, slot) CMD2_A_FUNCTION(key, command_base_call<core::Download*>, slot, "i:", "")
|
||||
#define CMD2_DL_V(key, slot) CMD2_A_FUNCTION(key, command_base_call<core::Download*>, object_convert_void(slot), "i:", "")
|
||||
#define CMD2_DL_VALUE(key, slot) CMD2_A_FUNCTION(key, command_base_call_value<core::Download*>, slot, "i:", "")
|
||||
@@ -96,6 +137,71 @@ void initialize_commands();
|
||||
CMD2_ANY_VOID(key ".push_back", std::bind(&rpc::object_storage::list_push_back, control->object_storage(), \
|
||||
torrent::raw_string::from_c_str(key), std::placeholders::_2));
|
||||
|
||||
#define CMD2_VAR_BOOL_U(key, value) \
|
||||
control->object_storage()->insert_c_str(key, int64_t(value), rpc::object_storage::flag_bool_type); \
|
||||
CMD2_ANY_U(key, std::bind(&rpc::object_storage::get, control->object_storage(), \
|
||||
torrent::raw_string::from_c_str(key))); \
|
||||
CMD2_ANY_VALUE_U(key ".set", std::bind(&rpc::object_storage::set_bool, control->object_storage(), \
|
||||
torrent::raw_string::from_c_str(key), std::placeholders::_2));
|
||||
|
||||
#define CMD2_VAR_BOOL_U_GET(key, value) \
|
||||
control->object_storage()->insert_c_str(key, int64_t(value), rpc::object_storage::flag_bool_type); \
|
||||
CMD2_ANY_U(key, std::bind(&rpc::object_storage::get, control->object_storage(), \
|
||||
torrent::raw_string::from_c_str(key))); \
|
||||
CMD2_ANY_VALUE(key ".set", std::bind(&rpc::object_storage::set_bool, control->object_storage(), \
|
||||
torrent::raw_string::from_c_str(key), std::placeholders::_2));
|
||||
|
||||
#define CMD2_VAR_VALUE_U(key, value) \
|
||||
control->object_storage()->insert_c_str(key, int64_t(value), rpc::object_storage::flag_value_type); \
|
||||
CMD2_ANY_U(key, std::bind(&rpc::object_storage::get, control->object_storage(), \
|
||||
torrent::raw_string::from_c_str(key))); \
|
||||
CMD2_ANY_VALUE_U(key ".set", std::bind(&rpc::object_storage::set_value, control->object_storage(), \
|
||||
torrent::raw_string::from_c_str(key), std::placeholders::_2));
|
||||
|
||||
#define CMD2_VAR_VALUE_U_GET(key, value) \
|
||||
control->object_storage()->insert_c_str(key, int64_t(value), rpc::object_storage::flag_value_type); \
|
||||
CMD2_ANY_U(key, std::bind(&rpc::object_storage::get, control->object_storage(), \
|
||||
torrent::raw_string::from_c_str(key))); \
|
||||
CMD2_ANY_VALUE(key ".set", std::bind(&rpc::object_storage::set_value, control->object_storage(), \
|
||||
torrent::raw_string::from_c_str(key), std::placeholders::_2));
|
||||
|
||||
#define CMD2_VAR_STRING_U(key, value) \
|
||||
control->object_storage()->insert_c_str(key, value, rpc::object_storage::flag_string_type); \
|
||||
CMD2_ANY_U(key, std::bind(&rpc::object_storage::get, control->object_storage(), \
|
||||
torrent::raw_string::from_c_str(key))); \
|
||||
CMD2_ANY_STRING_U(key ".set", std::bind(&rpc::object_storage::set_string, control->object_storage(), \
|
||||
torrent::raw_string::from_c_str(key), std::placeholders::_2));
|
||||
|
||||
#define CMD2_VAR_STRING_U_GET(key, value) \
|
||||
control->object_storage()->insert_c_str(key, value, rpc::object_storage::flag_string_type); \
|
||||
CMD2_ANY_U(key, std::bind(&rpc::object_storage::get, control->object_storage(), \
|
||||
torrent::raw_string::from_c_str(key))); \
|
||||
CMD2_ANY_STRING(key ".set", std::bind(&rpc::object_storage::set_string, control->object_storage(), \
|
||||
torrent::raw_string::from_c_str(key), std::placeholders::_2));
|
||||
|
||||
#define CMD2_VAR_C_STRING_U(key, value) \
|
||||
control->object_storage()->insert_c_str(key, value, rpc::object_storage::flag_string_type); \
|
||||
CMD2_ANY_U(key, std::bind(&rpc::object_storage::get, control->object_storage(), \
|
||||
torrent::raw_string::from_c_str(key)));
|
||||
|
||||
#define CMD2_VAR_LIST_U(key) \
|
||||
control->object_storage()->insert_c_str(key, torrent::Object::create_list(), rpc::object_storage::flag_list_type); \
|
||||
CMD2_ANY_U(key, std::bind(&rpc::object_storage::get, control->object_storage(), \
|
||||
torrent::raw_string::from_c_str(key))); \
|
||||
CMD2_ANY_LIST_U(key ".set", std::bind(&rpc::object_storage::set_list, control->object_storage(), \
|
||||
torrent::raw_string::from_c_str(key), std::placeholders::_2)); \
|
||||
CMD2_ANY_VOID_U(key ".push_back", std::bind(&rpc::object_storage::list_push_back, control->object_storage(), \
|
||||
torrent::raw_string::from_c_str(key), std::placeholders::_2));
|
||||
|
||||
#define CMD2_VAR_LIST_U_GET(key) \
|
||||
control->object_storage()->insert_c_str(key, torrent::Object::create_list(), rpc::object_storage::flag_list_type); \
|
||||
CMD2_ANY_U(key, std::bind(&rpc::object_storage::get, control->object_storage(), \
|
||||
torrent::raw_string::from_c_str(key))); \
|
||||
CMD2_ANY_LIST(key ".set", std::bind(&rpc::object_storage::set_list, control->object_storage(), \
|
||||
torrent::raw_string::from_c_str(key), std::placeholders::_2)); \
|
||||
CMD2_ANY_VOID(key ".push_back", std::bind(&rpc::object_storage::list_push_back, control->object_storage(), \
|
||||
torrent::raw_string::from_c_str(key), std::placeholders::_2));
|
||||
|
||||
#define CMD2_FUNC_SINGLE(key, cmds) \
|
||||
CMD2_ANY(key, std::bind(&rpc::command_function_call_object, torrent::Object(torrent::raw_string::from_c_str(cmds)), \
|
||||
std::placeholders::_1, std::placeholders::_2));
|
||||
|
||||
Reference in New Issue
Block a user