From: Vincent Bernat Date: Thu, 6 Mar 2014 17:09:27 +0000 (+0100) Subject: interfaces: allow whitelisting an interface X-Git-Tag: 0.7.8~33 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8b53fc2c2ad51ad9e52d153acc40670a3ec5d613;p=thirdparty%2Flldpd.git interfaces: allow whitelisting an interface Currently, this means that an interface can be both blacklisted and whitelisted and in this case, it is accepted as valid. --- diff --git a/NEWS b/NEWS index 30537444..e77168aa 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,9 @@ lldpd (0.7.8) + Android support + Add the possibility to disable privilege separation (lower memory consumption, lower security, don't do it). + + Interfaces can now be whitelisted. For example, *,!eth*,!!eth1 + is a valid pattern for all interfaces except eth ones, except + eth1. lldpd (0.7.7) * Features: diff --git a/src/daemon/lldpd.8 b/src/daemon/lldpd.8 index cfb0191f..da10a6eb 100644 --- a/src/daemon/lldpd.8 +++ b/src/daemon/lldpd.8 @@ -194,8 +194,10 @@ Specify which interface to listen to. Without this option, will listen on all available interfaces. This option can use wildcards. Several interfaces can be specified separated by commas. It is also possible to blacklist an interface by suffixing it with an -exclamation mark. When an interface is both specified with and without -an exclamation mark, it is blacklisted. For example, with +exclamation mark. It is possible to whitelist an interface by +suffixing it with two exclamation marks. A whitelisted interface beats +a blacklisted interfaces which beats a simple matched interface. For +example, with .Em eth*,!eth1,!eth2 .Nm will only listen to interfaces starting by @@ -204,6 +206,13 @@ with the exception of .Em eth1 and .Em eth2 . +While with +.Em *,!eth*,!!eth1 +.Nm +will listen to all interfaces, except interfaces starting by +.Em eth +with the exception of +.Em eth1 . .It Fl C Ar interfaces Specify which interfaces to use for computing chassis ID. Without this option, all interfaces are considered. diff --git a/src/daemon/pattern.c b/src/daemon/pattern.c index 10aa770e..059effdd 100644 --- a/src/daemon/pattern.c +++ b/src/daemon/pattern.c @@ -26,21 +26,24 @@ * @param string String to match against the list of patterns * @param patterns List of comma separated patterns. A pattern may * begin by `!` to negate it. In this case, it is - * blacklisted. Each pattern will then be matched - * against `fnmatch()` function. + * blacklisted. A pattern may begin with `!!`. In this + * case, it is whitelisted. Each pattern will then be + * matched against `fnmatch()` function. * @param found Value to return if the pattern isn't found. * * If a pattern is found matching and blacklisted at the same time, it - * will be blacklisted. + * will be blacklisted. If it is both whitelisted and blacklisted, it + * will be whitelisted. * - * @return 0 if the string matches a blacklisted pattern or if the - * pattern wasn't found and `found` was set to 0. Otherwise, - * return 1. + * @return 0 if the string matches a blacklisted pattern which is not + * whitelisted or if the pattern wasn't found and `found` was + * set to 0. Otherwise, return 1. */ int pattern_match(char *string, char *patterns, int found) { char *pattern; + int blacklisted = 0; if ((patterns = strdup(patterns)) == NULL) { log_warnx("interfaces", "unable to allocate memory"); @@ -50,13 +53,17 @@ pattern_match(char *string, char *patterns, int found) for (pattern = strtok(patterns, ","); pattern != NULL; pattern = strtok(NULL, ",")) { - if ((pattern[0] == '!') && - ((fnmatch(pattern + 1, string, 0) == 0))) { - /* Blacklisted. No need to search further. */ - found = 0; + if ((pattern[0] == '!') && (pattern[1] == '!') && + (fnmatch(pattern + 2, string, 0) == 0)) { + /* Whitelisted. No need to search further. */ + found = 1; break; } - if (fnmatch(pattern, string, 0) == 0) + if ((pattern[0] == '!') && + (fnmatch(pattern + 1, string, 0) == 0)) { + blacklisted = 1; + found = 0; + } else if (!blacklisted && fnmatch(pattern, string, 0) == 0) found = 1; } diff --git a/tests/check_pattern.c b/tests/check_pattern.c index 58e63a33..939b1f99 100644 --- a/tests/check_pattern.c +++ b/tests/check_pattern.c @@ -86,6 +86,24 @@ START_TEST(test_blacklist_wildcard) { } END_TEST +START_TEST(test_whitelist) { + ck_assert_int_eq(pattern_match("eth0", "!!eth0", 0), 1); + ck_assert_int_eq(pattern_match("eth0", "!!eth0", 1), 1); + ck_assert_int_eq(pattern_match("eth0", "!eth*,!!eth0", 0), 1); + ck_assert_int_eq(pattern_match("eth0", "!eth*,!!eth0", 1), 1); + ck_assert_int_eq(pattern_match("eth1", "!eth*,!!eth0", 0), 0); + ck_assert_int_eq(pattern_match("eth1", "!eth*,!!eth0", 1), 0); + ck_assert_int_eq(pattern_match("vlan0", "*,!eth*,!!eth0", 0), 1); + ck_assert_int_eq(pattern_match("vlan0", "*,!eth*,!!eth0", 1), 1); + ck_assert_int_eq(pattern_match("eth0", "*,!eth*,!!eth0", 0), 1); + ck_assert_int_eq(pattern_match("eth0", "*,!eth*,!!eth0", 1), 1); + ck_assert_int_eq(pattern_match("eth1", "*,!eth*,!!eth0", 0), 0); + ck_assert_int_eq(pattern_match("eth1", "*,!!eth0,!eth*", 1), 0); + ck_assert_int_eq(pattern_match("eth0", "*,!!eth0,!eth*", 0), 1); + ck_assert_int_eq(pattern_match("eth0", "*,!!eth0,!eth*", 1), 1); +} +END_TEST + Suite * pattern_suite(void) { @@ -100,6 +118,7 @@ pattern_suite(void) tcase_add_test(tc_pattern, test_simple_blacklist); tcase_add_test(tc_pattern, test_match_and_blacklist); tcase_add_test(tc_pattern, test_blacklist_wildcard); + tcase_add_test(tc_pattern, test_whitelist); suite_add_tcase(s, tc_pattern); return s;