diff --git a/src/command_dynamic.cc b/src/command_dynamic.cc index 08857cb8..bbd1c4f8 100644 --- a/src/command_dynamic.cc +++ b/src/command_dynamic.cc @@ -444,16 +444,18 @@ initialize_command_dynamic() { CMD2_ANY ("catch", std::bind(&cmd_catch, std::placeholders::_1, std::placeholders::_2)); - CMD2_ANY ("strings.choke_heuristics", std::bind(&torrent::option_list_strings, torrent::OPTION_CHOKE_HEURISTICS)); - CMD2_ANY ("strings.choke_heuristics.upload", std::bind(&torrent::option_list_strings, torrent::OPTION_CHOKE_HEURISTICS_UPLOAD)); - CMD2_ANY ("strings.choke_heuristics.download", std::bind(&torrent::option_list_strings, torrent::OPTION_CHOKE_HEURISTICS_DOWNLOAD)); - CMD2_ANY ("strings.connection_type", std::bind(&torrent::option_list_strings, torrent::OPTION_CONNECTION_TYPE)); - CMD2_ANY ("strings.encryption", std::bind(&torrent::option_list_strings, torrent::OPTION_ENCRYPTION)); - CMD2_ANY ("strings.ip_filter", std::bind(&torrent::option_list_strings, torrent::OPTION_IP_FILTER)); - CMD2_ANY ("strings.ip_tos", std::bind(&torrent::option_list_strings, torrent::OPTION_IP_TOS)); - CMD2_ANY ("strings.log_group", std::bind(&torrent::option_list_strings, torrent::OPTION_LOG_GROUP)); - CMD2_ANY ("strings.tracker_event", std::bind(&torrent::option_list_strings, torrent::OPTION_TRACKER_EVENT)); - CMD2_ANY ("strings.tracker_mode", std::bind(&torrent::option_list_strings, torrent::OPTION_TRACKER_MODE)); + CMD2_ANY ("strings.choke_heuristics", [](auto, auto) { return torrent::option_list_strings(torrent::OPTION_CHOKE_HEURISTICS); }); + CMD2_ANY ("strings.choke_heuristics.upload", [](auto, auto) { return torrent::option_list_strings(torrent::OPTION_CHOKE_HEURISTICS_UPLOAD); }); + CMD2_ANY ("strings.choke_heuristics.download", [](auto, auto) { return torrent::option_list_strings(torrent::OPTION_CHOKE_HEURISTICS_DOWNLOAD); }); + CMD2_ANY ("strings.connection_type", [](auto, auto) { return torrent::option_list_strings(torrent::OPTION_CONNECTION_TYPE); }); + CMD2_ANY ("strings.encryption", [](auto, auto) { return torrent::Object::create_list(); }); + CMD2_ANY ("strings.encryption.handshake", [](auto, auto) { return torrent::option_list_strings(torrent::OPTION_ENCRYPTION_HANDSHAKE); }); + CMD2_ANY ("strings.encryption.stream", [](auto, auto) { return torrent::option_list_strings(torrent::OPTION_ENCRYPTION_STREAM); }); + CMD2_ANY ("strings.ip_filter", [](auto, auto) { return torrent::option_list_strings(torrent::OPTION_IP_FILTER); }); + CMD2_ANY ("strings.ip_tos", [](auto, auto) { return torrent::option_list_strings(torrent::OPTION_IP_TOS); }); + CMD2_ANY ("strings.log_group", [](auto, auto) { return torrent::option_list_strings(torrent::OPTION_LOG_GROUP); }); + CMD2_ANY ("strings.tracker_event", [](auto, auto) { return torrent::option_list_strings(torrent::OPTION_TRACKER_EVENT); }); + CMD2_ANY ("strings.tracker_mode", [](auto, auto) { return torrent::option_list_strings(torrent::OPTION_TRACKER_MODE); }); // clang-format on #ifdef HAVE_XMLRPC_TINYXML2 diff --git a/src/command_network.cc b/src/command_network.cc index 046a6142..9d37df2f 100644 --- a/src/command_network.cc +++ b/src/command_network.cc @@ -55,21 +55,95 @@ set_listen_port_range(const std::string& arg) { } torrent::Object -apply_encryption(const torrent::Object::list_type& args) { - uint32_t options_mask = torrent::runtime::NetworkConfig::encryption_none; +get_encryption() { + auto encryption_modes = torrent::runtime::network_config()->encryption_modes(); - for (const auto& arg : args) { - uint32_t opt = torrent::option_find_string(torrent::OPTION_ENCRYPTION, arg.as_string().c_str()); + return torrent::option_to_str_or_throw(torrent::OPTION_ENCRYPTION_HANDSHAKE, encryption_modes.first) + "," + + torrent::option_to_str_or_throw(torrent::OPTION_ENCRYPTION_STREAM, encryption_modes.second); +} - if (opt == torrent::runtime::NetworkConfig::encryption_none) - options_mask = torrent::runtime::NetworkConfig::encryption_none; - else - options_mask |= opt; +torrent::Object +get_handshake_encryption() { + auto encryption_modes = torrent::runtime::network_config()->encryption_modes(); + + return torrent::option_to_str_or_throw(torrent::OPTION_ENCRYPTION_MODE, encryption_modes.first); +} + +torrent::Object +get_stream_encryption() { + auto encryption_modes = torrent::runtime::network_config()->encryption_modes(); + + return torrent::option_to_str_or_throw(torrent::OPTION_ENCRYPTION_MODE, encryption_modes.second); +} + +torrent::Object +apply_obsolete_encryption(const torrent::Object::list_type& args) { + torrent::encryption_mode handshake_mode{torrent::ENCRYPTION_MODE_ALLOW}; + torrent::encryption_mode stream_mode{torrent::ENCRYPTION_MODE_ALLOW}; + + for (auto& itr : args) { + auto arg = itr.as_string(); + + if (arg == "none") { + handshake_mode = torrent::ENCRYPTION_MODE_DENY; + stream_mode = torrent::ENCRYPTION_MODE_DENY; + break; + + } else if (arg == "allow_incoming") { + } else if (arg == "try_outgoing") { + } else if (arg == "require") { + handshake_mode = torrent::ENCRYPTION_MODE_REQUIRE; + + } else if (arg == "require_RC4" || arg == "require_rc4") { + handshake_mode = torrent::ENCRYPTION_MODE_REQUIRE; + stream_mode = torrent::ENCRYPTION_MODE_REQUIRE; + break; + + } else if (arg == "enable_retry") { + } else if (arg == "prefer_plaintext") { + } else { + throw torrent::input_error("Invalid encryption option: '" + arg + "'"); + } } - torrent::runtime::network_config()->set_encryption_options(options_mask); + lt_log_print(torrent::LOG_WARN, "Obsolete encryption options used, use 'handshake_{deny,allow,prefer,require}, stream_{deny,allow,prefer,require}' instead."); - return torrent::Object(); + torrent::runtime::network_config()->set_encryption_modes(handshake_mode, stream_mode); + return {}; +} + +torrent::Object +apply_encryption(const torrent::Object::list_type& args) { + if (args.empty()) + throw torrent::input_error("No encryption options specified."); + + torrent::encryption_mode encryption_mode, handshake_mode, stream_mode; + + if (args.size() == 1) { + try { + encryption_mode = static_cast(torrent::option_find_string_str(torrent::OPTION_ENCRYPTION_MODE, args.front().as_string())); + + } catch (torrent::input_error& e) { + return apply_obsolete_encryption(args); + } + + torrent::runtime::network_config()->set_encryption_modes(encryption_mode, encryption_mode); + return {}; + } + + if (args.size() != 2) + return apply_obsolete_encryption(args); + + try { + handshake_mode = static_cast(torrent::option_find_string_str(torrent::OPTION_ENCRYPTION_HANDSHAKE, args.front().as_string())); + stream_mode = static_cast(torrent::option_find_string_str(torrent::OPTION_ENCRYPTION_STREAM, args.back().as_string())); + + } catch (torrent::input_error& e) { + return apply_obsolete_encryption(args); + } + + torrent::runtime::network_config()->set_encryption_modes(handshake_mode, stream_mode); + return {}; } torrent::Object @@ -251,8 +325,12 @@ initialize_command_network() { CMD_ANY ("network.listen.backlog", [](auto, auto) { return torrent::runtime::network_config()->listen_backlog(); }); CMD_ANY_VALUE_V ("network.listen.backlog.set", [](auto, auto& value) { return torrent::runtime::network_config()->set_listen_backlog(value); }); - CMD_VAR_BOOL ("protocol.pex", true); - CMD_ANY_LIST ("protocol.encryption.set", [](auto, auto& args) { return apply_encryption(args); }); + CMD_VAR_BOOL ("protocol.pex", true); + + CMD_ANY_LIST ("protocol.encryption", [](auto, auto) { return get_encryption(); }); + CMD_ANY_LIST ("protocol.encryption.set", [](auto, auto& args) { return apply_encryption(args); }); + CMD_ANY_LIST ("protocol.encryption.handshake", [](auto, auto) { return get_handshake_encryption(); }); + CMD_ANY_LIST ("protocol.encryption.stream", [](auto, auto) { return get_stream_encryption(); }); CMD_VAR_STRING ("protocol.connection.leech", "leech"); CMD_VAR_STRING ("protocol.connection.seed", "seed"); diff --git a/test/rpc/test_parse_options.cc b/test/rpc/test_parse_options.cc index 6176a0fa..9cc383e5 100644 --- a/test/rpc/test_parse_options.cc +++ b/test/rpc/test_parse_options.cc @@ -169,20 +169,3 @@ TestParseOptions::test_flag_libtorrent() { FLAG_LT_LOG_ASSERT_ERROR("resume_data|rpc_dump"); } - -#define FLAGS_LT_ENCRYPTION_ASSERT(flags, result) \ - CPPUNIT_ASSERT(rpc::parse_option_flags(flags, std::bind(&torrent::option_find_string_str, torrent::OPTION_ENCRYPTION, std::placeholders::_1)) == (result)) - -#define FLAGS_LT_ENCRYPTION_ASSERT_ERROR(flags) \ - ASSERT_CATCH_INPUT_ERROR(rpc::parse_option_flags(flags, std::bind(&torrent::option_find_string_str, torrent::OPTION_ENCRYPTION, std::placeholders::_1))) - -void -TestParseOptions::test_flags_libtorrent() { - FLAGS_LT_ENCRYPTION_ASSERT("", torrent::runtime::NetworkConfig::encryption_none); - FLAGS_LT_ENCRYPTION_ASSERT("none", torrent::runtime::NetworkConfig::encryption_none); - FLAGS_LT_ENCRYPTION_ASSERT("require_rc4", torrent::runtime::NetworkConfig::encryption_require_RC4); - FLAGS_LT_ENCRYPTION_ASSERT("require_RC4", torrent::runtime::NetworkConfig::encryption_require_RC4); - FLAGS_LT_ENCRYPTION_ASSERT("require_RC4 | enable_retry", torrent::runtime::NetworkConfig::encryption_require_RC4 | torrent::runtime::NetworkConfig::encryption_enable_retry); - - FLAGS_LT_ENCRYPTION_ASSERT_ERROR("require_"); -} diff --git a/test/rpc/test_parse_options.h b/test/rpc/test_parse_options.h index ac25948b..7e736faa 100644 --- a/test/rpc/test_parse_options.h +++ b/test/rpc/test_parse_options.h @@ -14,7 +14,6 @@ class TestParseOptions : public test_fixture { CPPUNIT_TEST(test_flags_print_flags); CPPUNIT_TEST(test_flag_libtorrent); - CPPUNIT_TEST(test_flags_libtorrent); CPPUNIT_TEST_SUITE_END(); @@ -30,5 +29,4 @@ public: void test_flags_print_flags(); void test_flag_libtorrent(); - void test_flags_libtorrent(); };