diff --git a/doc/old/rtorrent.1 b/doc/old/rtorrent.1 index 86a1016e..15eb1870 100644 --- a/doc/old/rtorrent.1 +++ b/doc/old/rtorrent.1 @@ -214,21 +214,15 @@ Add a preferred filename encoding to the list. The encodings are attempted in the order they are inserted, if none match the torrent default is used. .TP -\fBencryption = \fIoption\fB,\fI\&...\fB\fR -Set how rtorrent should deal with encrypted Bittorrent connections. By -default, encryption is disabled, equivalent to specifying the option -\fBnone\fR\&. Alternatively, any number of the following -options may be specified: - -\fBallow_incoming\fR (allow incoming encrypted connections), -\fBtry_outgoing\fR (use encryption for outgoing connections), -\fBrequire\fR (disable unencrypted handshakes), -\fBrequire_RC4\fR (also disable plaintext transmission after the -initial encrypted handshake), -\fBenable_retry\fR (if the initial outgoing connection fails, retry -with encryption turned on if it was off or off if it was on), -\fBprefer_plaintext\fR (choose plaintext when peer offers a choice -between plaintext transmission and RC4 encryption, otherwise RC4 will be used). +\fBprotocol.encryption.handshake.set\fR (deny, allow, prefer, require) +and \fBprotocol.encryption.stream.set\fR (deny, allow, prefer, +require) control how rtorrent deals with encrypted Bittorrent +connections. Handshake \fBallow\fR accepts plain or PE inbound and +tries plain first outbound with one PE retry on failure. +\fBprefer\fR tries PE first with one plain retry. Stream \fBallow\fR +and \fBprefer\fR offer both handshake-only and RC4 on outgoing PE +connections. The default is handshake=allow, stream=allow. Use +\fBprotocol.encryption\fR to inspect the effective policy. .TP \fBpeer_exchange = \fIyes | no\fB\fR Enable/disable peer exchange for torrents that aren't marked private. Disabled by default. diff --git a/doc/old/rtorrent.1.xml b/doc/old/rtorrent.1.xml index e605d96e..10b6682d 100644 --- a/doc/old/rtorrent.1.xml +++ b/doc/old/rtorrent.1.xml @@ -484,25 +484,19 @@ default is used. - encryption = option,... + protocol.encryption.handshake.set = policy -Set how rtorrent should deal with encrypted Bittorrent connections. By -default, encryption is disabled, equivalent to specifying the option -none. Alternatively, any number of the following -options may be specified: - - - -allow_incoming (allow incoming encrypted connections), -try_outgoing (use encryption for outgoing connections), -require (disable unencrypted handshakes), -require_RC4 (also disable plaintext transmission after the -initial encrypted handshake), -enable_retry (if the initial outgoing connection fails, retry -with encryption turned on if it was off or off if it was on), -prefer_plaintext (choose plaintext when peer offers a choice -between plaintext transmission and RC4 encryption, otherwise RC4 will be used). +Control how rtorrent deals with encrypted Bittorrent connections. +protocol.encryption.handshake.set (deny, allow, prefer, +require) and protocol.encryption.stream.set (deny, allow, +prefer, require). Handshake allow accepts plain or PE +inbound and tries plain first outbound with one PE retry on failure. +prefer tries PE first with one plain retry. Stream +allow and prefer offer both +handshake-only and RC4 on outgoing PE connections. The default is +handshake=allow, stream=allow. Use protocol.encryption to +inspect the effective policy. diff --git a/doc/rtorrent.rc b/doc/rtorrent.rc index 08c35267..ca93f709 100644 --- a/doc/rtorrent.rc +++ b/doc/rtorrent.rc @@ -95,14 +95,40 @@ #schedule2 = ip_tick,0,1800,ip=rakshasa #schedule2 = bind_tick,0,1800,bind=rakshasa -# Encryption options, set to none (default) or any combination of the following: -# allow_incoming, try_outgoing, require, require_RC4, enable_retry, prefer_plaintext +# --- Protocol encryption (PE handshake / optional RC4 stream) --- +# Default at startup: handshake=allow stream=allow # -# The example value allows incoming encrypted connections, starts unencrypted -# outgoing connections but retries with encryption if they fail, preferring -# plain-text to RC4 encryption after the encrypted handshake. +# Handshake (PE handshake; incoming accepts plain or PE for allow/prefer): +# deny - plain BT handshake only both ways; no retry +# allow - accept plain or PE inbound; plain first outbound with one PE retry +# prefer - accept plain or PE inbound; PE first outbound with one plain retry +# require - PE handshake required both ways; no retry # -# protocol.encryption.set = allow_incoming,enable_retry,prefer_plaintext +# protocol.encryption.handshake.set = allow +# +# Stream (cipher negotiation after PE handshake succeeds): +# deny - offer handshake-only; require handshake-only (no RC4) +# allow - incoming: prefer handshake-only if offered, else RC4 +# outgoing: offer both handshake-only and RC4 +# prefer - incoming: pick RC4 if offered, else handshake-only +# outgoing: offer both handshake-only and RC4 +# require - offer RC4 only; require RC4 +# +# Outgoing retry summary with handshake=allow (plain first): +# stream=allow/prefer -> plain BT -> PE (both) +# stream=deny -> plain BT -> PE (handshake-only) +# stream=require -> plain BT -> PE (RC4-only) +# +# Outgoing retry summary with handshake=prefer (PE first): +# stream=allow/prefer -> PE (both) -> plain BT +# stream=deny -> PE (handshake-only) -> plain BT +# stream=require -> PE (RC4-only) -> plain BT +# +# Negotiated stream cipher is logged at connection_handshake level. +# +# protocol.encryption.stream.set = allow +# +# Use protocol.encryption to inspect the effective policy. # Enable DHT support for trackerless torrents or when all trackers are down. # May be set to "disable" (completely disable DHT), "off" (do not start DHT), diff --git a/doc/rtorrent.rc-example b/doc/rtorrent.rc-example index 9cfe8747..d45b7a3b 100644 --- a/doc/rtorrent.rc-example +++ b/doc/rtorrent.rc-example @@ -42,7 +42,8 @@ throttle.min_peers.seed.set = 30 throttle.max_peers.seed.set = 80 trackers.numwant.set = 80 -protocol.encryption.set = allow_incoming,try_outgoing,enable_retry +protocol.encryption.handshake.set = allow +protocol.encryption.stream.set = prefer # Limits for file handle resources, this is optimized for # an `ulimit` of 1024 (a common default). You MUST leave diff --git a/doc/rtorrent.rc.lua-example b/doc/rtorrent.rc.lua-example index be3d0ffd..3b641b6f 100644 --- a/doc/rtorrent.rc.lua-example +++ b/doc/rtorrent.rc.lua-example @@ -72,7 +72,8 @@ rc.throttle.min_peers.seed = 30 rc.throttle.max_peers.seed = 80 rc.trackers.numwant = 80 -rc.protocol.encryption.set('allow_incoming', 'try_outgoing', 'enable_retry') +rc.protocol.encryption.handshake.set('allow') +rc.protocol.encryption.stream.set('prefer') -- Limits for file handle resources, this is optimized for -- an `ulimit` of 1024 (a common default). You MUST leave diff --git a/doc/scripts/print_option_string.sh b/doc/scripts/print_option_string.sh index 76abe002..27048ae6 100755 --- a/doc/scripts/print_option_string.sh +++ b/doc/scripts/print_option_string.sh @@ -12,7 +12,7 @@ echo "Client version: " `xmlrpc2scgi.py -p scgi://127.0.0.1:${PORT_NUMBER} syste echo echo "Generated by 'rtorrent/doc/scripts/print_option_string.sh' on `date -u`." -for i in strings.choke_heuristics strings.choke_heuristics.upload strings.choke_heuristics.download strings.connection_type strings.encryption strings.ip_filter strings.ip_tos strings.log_group strings.tracker_event strings.tracker_mode; do +for i in strings.choke_heuristics strings.choke_heuristics.upload strings.choke_heuristics.download strings.connection_type strings.encryption.handshake strings.encryption.stream strings.ip_filter strings.ip_tos strings.log_group strings.tracker_event strings.tracker_mode; do echo echo $i echo `echo $i | tr 'a-z_.' '-'` diff --git a/src/Makefile.am b/src/Makefile.am index 147a1997..1c159eb4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -188,6 +188,8 @@ libsub_root_a_SOURCES = \ command_local.cc \ command_logging.cc \ command_network.cc \ + encryption_config.cc \ + encryption_config.h \ command_peer.cc \ command_throttle.cc \ command_tracker.cc \ diff --git a/src/command_dynamic.cc b/src/command_dynamic.cc index 08857cb8..ca117032 100644 --- a/src/command_dynamic.cc +++ b/src/command_dynamic.cc @@ -448,7 +448,8 @@ initialize_command_dynamic() { 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.encryption.handshake", std::bind(&torrent::option_list_strings, torrent::OPTION_ENCRYPTION_MODE)); + CMD2_ANY ("strings.encryption.stream", std::bind(&torrent::option_list_strings, torrent::OPTION_ENCRYPTION_MODE)); 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)); @@ -472,7 +473,8 @@ initialize_command_dynamic() { rpc::rpc.mark_safe("strings.choke_heuristics.upload"); rpc::rpc.mark_safe("strings.choke_heuristics.download"); rpc::rpc.mark_safe("strings.connection_type"); - rpc::rpc.mark_safe("strings.encryption"); + rpc::rpc.mark_safe("strings.encryption.handshake"); + rpc::rpc.mark_safe("strings.encryption.stream"); rpc::rpc.mark_safe("strings.ip_filter"); rpc::rpc.mark_safe("strings.ip_tos"); rpc::rpc.mark_safe("strings.log_group"); diff --git a/src/command_network.cc b/src/command_network.cc index af32461f..3e8efaaa 100644 --- a/src/command_network.cc +++ b/src/command_network.cc @@ -17,6 +17,7 @@ #include #include +#include "encryption_config.h" #include "globals.h" #include "control.h" #include "command_helpers.h" @@ -32,24 +33,6 @@ #include #endif -torrent::Object -apply_encryption(const torrent::Object::list_type& args) { - uint32_t options_mask = torrent::runtime::NetworkConfig::encryption_none; - - for (const auto& arg : args) { - uint32_t opt = torrent::option_find_string(torrent::OPTION_ENCRYPTION, arg.as_string().c_str()); - - if (opt == torrent::runtime::NetworkConfig::encryption_none) - options_mask = torrent::runtime::NetworkConfig::encryption_none; - else - options_mask |= opt; - } - - torrent::runtime::network_config()->set_encryption_options(options_mask); - - return torrent::Object(); -} - torrent::Object apply_tos(const torrent::Object::string_type& arg) { rpc::command_base::value_type value; @@ -230,7 +213,8 @@ initialize_command_network() { CMD_ANY_VALUE_V ("network.listen.backlog.set", [nw_config](auto, auto& value) { return nw_config->set_listen_backlog(value); }); CMD_VAR_BOOL ("protocol.pex", true); - CMD_ANY_LIST ("protocol.encryption.set", [](auto, auto& args) { return apply_encryption(args); }); + + encryption_config::initialize_commands(); CMD_VAR_STRING ("protocol.connection.leech", "leech"); CMD_VAR_STRING ("protocol.connection.seed", "seed"); diff --git a/src/display/window_peer_list.cc b/src/display/window_peer_list.cc index 92389dac..055a41e7 100644 --- a/src/display/window_peer_list.cc +++ b/src/display/window_peer_list.cc @@ -16,6 +16,21 @@ namespace display { +namespace { + +char +connection_type_char(const torrent::Peer* p) { + if (p->is_encrypted()) + return p->is_incoming() ? 'R' : 'L'; + + if (p->is_obfuscated()) + return p->is_incoming() ? 'H' : 'h'; + + return p->is_incoming() ? 'r' : 'l'; +} + +} // namespace + WindowPeerList::WindowPeerList(core::Download* d, PList* l, PList::iterator* f) : Window(new Canvas, 0, 0, 0, extent_full, extent_full), m_download(d), @@ -35,6 +50,7 @@ WindowPeerList::redraw() { m_canvas->print(x, y, "UP"); x += 7; m_canvas->print(x, y, "DOWN"); x += 7; m_canvas->print(x, y, "PEER"); x += 7; + // CT: R/H/r or L/h/l (RC4 / handshake-only / plain) + peer type (u/p/ ) m_canvas->print(x, y, "CT/RE/LO"); x += 10; m_canvas->print(x, y, "QS"); x += 6; m_canvas->print(x, y, "DONE"); x += 6; @@ -95,7 +111,7 @@ WindowPeerList::redraw() { peerType = ' '; m_canvas->print(x, y, "%c%c/%c%c/%c%c", - p->is_encrypted() ? (p->is_incoming() ? 'R' : 'L') : (p->is_incoming() ? 'r' : 'l'), + connection_type_char(p), peerType, p->is_down_choked() ? std::tolower(remoteChoked) : remoteChoked, diff --git a/src/encryption_config.cc b/src/encryption_config.cc new file mode 100644 index 00000000..a8fafe34 --- /dev/null +++ b/src/encryption_config.cc @@ -0,0 +1,88 @@ +#include "config.h" + +#include "encryption_config.h" + +#include +#include +#include + +#include "command_helpers.h" +#include "globals.h" + +namespace encryption_config { +namespace { + +Policy +current_policy() { + return torrent::runtime::network_config()->encryption_policy(); +} + +} // namespace + +Policy +default_policy() { + Policy policy; + policy.handshake = Policy::Mode::allow; + policy.stream = Policy::Mode::allow; + return policy; +} + +std::string +mode_to_string(Policy::Mode value) { + return torrent::option_to_str_or_throw(torrent::OPTION_ENCRYPTION_MODE, + static_cast(value)); +} + +void +apply_mode_value(Policy& policy, Policy::Mode Policy::*field, const std::string& value) { + policy.*field = static_cast( + torrent::option_find_string_str(torrent::OPTION_ENCRYPTION_MODE, value)); +} + +std::string +summary_string(const Policy& policy) { + return "handshake=" + mode_to_string(policy.handshake) + + " stream=" + mode_to_string(policy.stream); +} + +void +apply_policy(const Policy& policy) { + torrent::runtime::network_config()->set_encryption_policy(policy); +} + +torrent::Object +apply_handshake_set(const std::string& value) { + Policy policy = current_policy(); + apply_mode_value(policy, &Policy::handshake, value); + apply_policy(policy); + return torrent::Object(); +} + +torrent::Object +apply_stream_set(const std::string& value) { + Policy policy = current_policy(); + apply_mode_value(policy, &Policy::stream, value); + apply_policy(policy); + return torrent::Object(); +} + +void +initialize_commands() { + apply_policy(default_policy()); + + CMD2_ANY("protocol.encryption", [](auto, auto) { return summary_string(current_policy()); }); + + CMD2_ANY("protocol.encryption.handshake", [](auto, auto) { return mode_to_string(current_policy().handshake); }); + CMD2_ANY_STRING_V("protocol.encryption.handshake.set", [](auto, auto& str) { return apply_handshake_set(str); }); + + CMD2_ANY("protocol.encryption.stream", [](auto, auto) { return mode_to_string(current_policy().stream); }); + CMD2_ANY_STRING_V("protocol.encryption.stream.set", [](auto, auto& str) { return apply_stream_set(str); }); + + rpc::rpc.mark_safe("protocol.encryption"); + rpc::rpc.mark_safe("protocol.encryption.handshake"); + rpc::rpc.mark_safe("protocol.encryption.handshake.set"); + rpc::rpc.mark_safe("protocol.encryption.stream"); + rpc::rpc.mark_safe("protocol.encryption.stream.set"); +} + +} // namespace encryption_config \ No newline at end of file diff --git a/src/encryption_config.h b/src/encryption_config.h new file mode 100644 index 00000000..bba34f80 --- /dev/null +++ b/src/encryption_config.h @@ -0,0 +1,29 @@ +#ifndef RTORRENT_ENCRYPTION_CONFIG_H +#define RTORRENT_ENCRYPTION_CONFIG_H + +#include +#include + +#include +#include + +namespace encryption_config { + +using Policy = torrent::EncryptionPolicy; + +Policy default_policy(); + +std::string mode_to_string(Policy::Mode value); +void apply_mode_value(Policy& policy, Policy::Mode Policy::*field, const std::string& value); + +std::string summary_string(const Policy& policy); + +void apply_policy(const Policy& policy); +torrent::Object apply_handshake_set(const std::string& value); +torrent::Object apply_stream_set(const std::string& value); + +void initialize_commands(); + +} // namespace encryption_config + +#endif \ No newline at end of file diff --git a/src/main.cc b/src/main.cc index 8c0aab14..cdb736d7 100644 --- a/src/main.cc +++ b/src/main.cc @@ -298,7 +298,8 @@ main(int argc, char** argv) { "schedule = low_diskspace,5,60,((close_low_diskspace,500M))\n" "schedule = prune_file_status,3600,86400,((system.file_status_cache.prune))\n" - "protocol.encryption.set=allow_incoming,prefer_plaintext,enable_retry\n" + "protocol.encryption.handshake.set=allow\n" + "protocol.encryption.stream.set=allow\n" "ui.color.focus.set=reverse\n" ); @@ -318,8 +319,6 @@ main(int argc, char** argv) { CMD_REDIRECT("ratio.max.set", "group.seeding.ratio.max.set"); CMD_REDIRECT("ratio.upload.set", "group.seeding.ratio.upload.set"); - CMD_REDIRECT("encryption", "protocol.encryption.set"); - CMD_REDIRECT("check_hash", "pieces.hash.on_completion.set"); CMD_REDIRECT("connection_leech", "protocol.connection.leech.set"); diff --git a/src/ui/element_peer_list.cc b/src/ui/element_peer_list.cc index 7d6bb07a..574d1c2a 100644 --- a/src/ui/element_peer_list.cc +++ b/src/ui/element_peer_list.cc @@ -111,7 +111,7 @@ ElementPeerList::create_info() { element->push_column("Client:", te_command("p.client_version=")); element->push_column("Options:", te_command("p.options_str=")); element->push_column("Connected:", te_command("if=$p.is_incoming=,incoming,outgoing")); - element->push_column("Encrypted:", te_command("if=$p.is_encrypted=,yes,$p.is_obfuscated=,handshake,no")); + element->push_column("Encrypted:", te_command("if=$p.is_encrypted=,yes,$if=$p.is_obfuscated=\\,handshake\\,no")); element->push_back(""); element->push_column("Snubbed:", te_command("if=$p.is_snubbed=,yes,no")); diff --git a/test/Makefile.am b/test/Makefile.am index aae18225..fda92deb 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -49,6 +49,8 @@ rtorrent_Test_Rpc_SOURCES = $(rtorrent_Test_Common) \ rtorrent_Test_Src_SOURCES = $(rtorrent_Test_Common) \ src/test_command_dynamic.cc \ src/test_command_dynamic.h \ + src/test_encryption_config.cc \ + src/test_encryption_config.h \ src/test_watch_ready_queue.cc \ src/test_watch_ready_queue.h diff --git a/test/rpc/test_parse_options.cc b/test/rpc/test_parse_options.cc index 6176a0fa..c77344a4 100644 --- a/test/rpc/test_parse_options.cc +++ b/test/rpc/test_parse_options.cc @@ -170,19 +170,18 @@ 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_IP_TOS_ASSERT(flags, result) \ + CPPUNIT_ASSERT(rpc::parse_option_flags(flags, std::bind(&torrent::option_find_string_str, torrent::OPTION_IP_TOS, 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))) +#define FLAGS_LT_IP_TOS_ASSERT_ERROR(flags) \ + ASSERT_CATCH_INPUT_ERROR(rpc::parse_option_flags(flags, std::bind(&torrent::option_find_string_str, torrent::OPTION_IP_TOS, 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_IP_TOS_ASSERT("throughput", torrent::option_find_string(torrent::OPTION_IP_TOS, "throughput")); + FLAGS_LT_IP_TOS_ASSERT("lowdelay | throughput", + torrent::option_find_string(torrent::OPTION_IP_TOS, "lowdelay") + | torrent::option_find_string(torrent::OPTION_IP_TOS, "throughput")); - FLAGS_LT_ENCRYPTION_ASSERT_ERROR("require_"); + FLAGS_LT_IP_TOS_ASSERT_ERROR("throughput_"); } diff --git a/test/src/test_encryption_config.cc b/test/src/test_encryption_config.cc new file mode 100644 index 00000000..07ab47b0 --- /dev/null +++ b/test/src/test_encryption_config.cc @@ -0,0 +1,45 @@ +#include "config.h" + +#include "test/src/test_encryption_config.h" + +#include + +#include "encryption_config.h" + +CPPUNIT_TEST_SUITE_REGISTRATION(TestEncryptionConfig); + +void +TestEncryptionConfig::test_default_policy() { + const auto policy = encryption_config::default_policy(); + + CPPUNIT_ASSERT(policy.handshake == encryption_config::Policy::Mode::allow); + CPPUNIT_ASSERT(policy.stream == encryption_config::Policy::Mode::allow); + + CPPUNIT_ASSERT_EQUAL(std::string("handshake=allow stream=allow"), + encryption_config::summary_string(policy)); +} + +void +TestEncryptionConfig::test_granular_round_trip() { + auto round_trip_handshake = [](const std::string& value) { + encryption_config::Policy policy; + encryption_config::apply_mode_value(policy, &encryption_config::Policy::handshake, value); + return encryption_config::mode_to_string(policy.handshake); + }; + + CPPUNIT_ASSERT_EQUAL(std::string("deny"), round_trip_handshake("deny")); + CPPUNIT_ASSERT_EQUAL(std::string("allow"), round_trip_handshake("allow")); + CPPUNIT_ASSERT_EQUAL(std::string("prefer"), round_trip_handshake("prefer")); + CPPUNIT_ASSERT_EQUAL(std::string("require"), round_trip_handshake("require")); + + auto round_trip_stream = [](const std::string& value) { + encryption_config::Policy policy; + encryption_config::apply_mode_value(policy, &encryption_config::Policy::stream, value); + return encryption_config::mode_to_string(policy.stream); + }; + + CPPUNIT_ASSERT_EQUAL(std::string("deny"), round_trip_stream("deny")); + CPPUNIT_ASSERT_EQUAL(std::string("allow"), round_trip_stream("allow")); + CPPUNIT_ASSERT_EQUAL(std::string("prefer"), round_trip_stream("prefer")); + CPPUNIT_ASSERT_EQUAL(std::string("require"), round_trip_stream("require")); +} \ No newline at end of file diff --git a/test/src/test_encryption_config.h b/test/src/test_encryption_config.h new file mode 100644 index 00000000..9d9933b9 --- /dev/null +++ b/test/src/test_encryption_config.h @@ -0,0 +1,12 @@ +#include "test/helpers/test_fixture.h" + +class TestEncryptionConfig : public test_fixture { + CPPUNIT_TEST_SUITE(TestEncryptionConfig); + CPPUNIT_TEST(test_default_policy); + CPPUNIT_TEST(test_granular_round_trip); + CPPUNIT_TEST_SUITE_END(); + +public: + void test_default_policy(); + void test_granular_round_trip(); +}; \ No newline at end of file