diff --git a/test/unittests/test_optfilt.cpp b/test/unittests/test_optfilt.cpp index a0384caa..02d68331 100644 --- a/test/unittests/test_optfilt.cpp +++ b/test/unittests/test_optfilt.cpp @@ -24,7 +24,7 @@ using namespace openvpn; -const std::string filtered_options( +const std::string nopull_options( "ip-win32\n" "tap-sleep\n" "block-ipv6\n" @@ -36,7 +36,9 @@ const std::string filtered_options( "dhcp-release\n" "dhcp-pre-release\n" - "route\n" + "route 1.2.3.4\n" + "route 192.168.0.0 255.255.255.0\n" + "route 10.0.0.0 255.0.0.0\n" "route-ipv6\n" "route-delay\n" "route-metric\n" @@ -46,15 +48,30 @@ const std::string filtered_options( "redirect-private\n" ); +const std::string pull_filter_options( + "option1 arg1\n" + "option1 arg2\n" + "option2 \"arg with space\"\n" + "option2 \"arg with more space\"\n" + "option3 arg1 arg2\n" + "option3 arg1 arg2\n" + "option10 something else\n" +); + TEST(PushedOptionsFilter, RouteNopullEnabled) { - PushedOptionsFilter route_nopull_enabled(true); + OptionList cfg; + cfg.parse_from_config("route-nopull", nullptr); + cfg.update_map(); + + PushedOptionsFilter route_nopull_enabled(cfg); const std::string extra_option("unfiltered-option"); + OptionList src; OptionList dst; testLog->startCollecting(); - src.parse_from_config(filtered_options + extra_option, nullptr); + src.parse_from_config(nopull_options + extra_option, nullptr); dst.extend(src, &route_nopull_enabled); std::string filter_output(testLog->stopCollecting()); @@ -65,19 +82,22 @@ TEST(PushedOptionsFilter, RouteNopullEnabled) dst.update_map(); ASSERT_TRUE(dst.exists(extra_option)) << "The wrong options have been filtered by --route-nopull:" << std::endl - << "expected: " << extra_option << " got: " << dst[0].get(0, 0) << std::endl + << "expected: " << extra_option << " got: " << dst[0].ref(0) << std::endl << filter_output; } TEST(PushedOptionsFilter, RouteNopullDisabled) { - PushedOptionsFilter route_nopull_disabled(false); + OptionList cfg; + + PushedOptionsFilter route_nopull_disabled(cfg); const std::string extra_option("unfiltered-option"); + OptionList src; OptionList dst; testLog->startCollecting(); - src.parse_from_config(filtered_options + extra_option, nullptr); + src.parse_from_config(nopull_options + extra_option, nullptr); dst.extend(src, &route_nopull_disabled); std::string filter_output(testLog->stopCollecting()); @@ -85,3 +105,185 @@ TEST(PushedOptionsFilter, RouteNopullDisabled) << "Too many options have been filtered by --route-nopull" << std::endl << filter_output; } + +TEST(PushedOptionsFilter, PullFilterAcceptAll) +{ + OptionList cfg; + cfg.parse_from_config("pull-filter accept option", nullptr); + cfg.update_map(); + + PushedOptionsFilter filter_none(cfg); + + OptionList src; + OptionList dst; + + testLog->startCollecting(); + src.parse_from_config(pull_filter_options, nullptr); + dst.extend(src, &filter_none); + std::string filter_output(testLog->stopCollecting()); + + ASSERT_EQ(src.size(), dst.size()) + << "Not all options have been accepted by --pull-filter" << std::endl + << filter_output; +} + +TEST(PushedOptionsFilter, PullFilterMalformedAction) +{ + OptionList cfg; + cfg.parse_from_config("pull-filter myaction match", nullptr); + cfg.update_map(); + + ASSERT_THROW(PushedOptionsFilter x(cfg), option_error); +} + +TEST(PushedOptionsFilter, PullFilterMalformedShort) +{ + OptionList cfg; + cfg.parse_from_config("pull-filter ignore", nullptr); + cfg.update_map(); + + ASSERT_THROW(PushedOptionsFilter x(cfg), option_error); +} + +TEST(PushedOptionsFilter, PullFilterMalformedLong) +{ + OptionList cfg; + cfg.parse_from_config("pull-filter ignore one two", nullptr); + cfg.update_map(); + + ASSERT_THROW(PushedOptionsFilter x(cfg), option_error); +} + +TEST(PushedOptionsFilter, PullFilterIgnoreAll) +{ + OptionList cfg; + cfg.parse_from_config("pull-filter ignore option", nullptr); + cfg.update_map(); + + PushedOptionsFilter filter_all(cfg); + + OptionList src; + OptionList dst; + + testLog->startCollecting(); + src.parse_from_config(pull_filter_options, nullptr); + dst.extend(src, &filter_all); + std::string filter_output(testLog->stopCollecting()); + + ASSERT_EQ(0, dst.size()) + << "Not all options have been ignored by --pull-filter" << std::endl + << filter_output; +} + +TEST(PushedOptionsFilter, PullFilterRejectOne) +{ + OptionList cfg; + cfg.parse_from_config("pull-filter reject option10", nullptr); + cfg.update_map(); + + PushedOptionsFilter reject_opt10(cfg); + + OptionList src; + OptionList dst; + + testLog->startCollecting(); + src.parse_from_config(pull_filter_options, nullptr); + JY_EXPECT_THROW(dst.extend(src, &reject_opt10), Option::RejectedException, "option10") + testLog->stopCollecting(); +} + +TEST(PushedOptionsFilter, PullFilterAcceptWhitespace) +{ + OptionList cfg; + cfg.parse_from_config( + "pull-filter accept \"option3 arg1 arg2\"\n" + "pull-filter ignore option" + , nullptr + ); + cfg.update_map(); + + PushedOptionsFilter accept_opt3(cfg); + + OptionList src; + OptionList dst; + + testLog->startCollecting(); + src.parse_from_config(pull_filter_options, nullptr); + dst.extend(src, &accept_opt3); + std::string filter_output(testLog->stopCollecting()); + + ASSERT_EQ(2, dst.size()) + << "Not all option3's have been accepted by --pull-filter" << std::endl + << filter_output; +} + +TEST(PushedOptionsFilter, PullFilterIgnoreQuotedWhitespace) +{ + OptionList cfg; + cfg.parse_from_config( + "pull-filter accept \"option2 \\\"arg with space\\\"\"\n" + "pull-filter ignore option" + , nullptr + ); + cfg.update_map(); + + PushedOptionsFilter accept_opt2_single_space(cfg); + + OptionList src; + OptionList dst; + + testLog->startCollecting(); + src.parse_from_config(pull_filter_options, nullptr); + dst.extend(src, &accept_opt2_single_space); + std::string filter_output(testLog->stopCollecting()); + + ASSERT_EQ(1, dst.size()) + << "Too many options have been accepted by --pull-filter" << std::endl + << filter_output; + + dst.update_map(); + ASSERT_EQ(dst[0].ref(1), "arg with space") + << "Too many options have been accepted by --pull-filter" << std::endl + << filter_output; +} + +TEST(PushedOptionsFilter, PullFilterOverrideRouteNopull) +{ + OptionList cfg; + cfg.parse_from_config( + "pull-filter ignore \"route 1.2.3.4\"\n" + "pull-filter ignore route-\n" + "route-nopull\n" + "pull-filter accept route\n" + , nullptr + ); + cfg.update_map(); + + PushedOptionsFilter override_route_nopull(cfg); + + OptionList src; + OptionList dst; + + testLog->startCollecting(); + src.parse_from_config(nopull_options, nullptr); + dst.extend(src, &override_route_nopull); + std::string filter_output(testLog->stopCollecting()); + + ASSERT_EQ(2, dst.size()) + << "Expected two route option to be accepted" << std::endl + << filter_output; + + dst.update_map(); + ASSERT_EQ(dst[0].ref(0), "route") + << dst[0].ref(0) << " instead of route option has been accepted" << std::endl + << filter_output; + ASSERT_EQ(dst[1].ref(0), "route") + << dst[1].ref(0) << " instead of route option has been accepted" << std::endl + << filter_output; + ASSERT_EQ(3, dst[0].size()) + << "The host route option has been accepted, expected network route" << std::endl + << filter_output; + ASSERT_EQ(3, dst[1].size()) + << "The host route option has been accepted, expected network route" << std::endl + << filter_output; +}