diff --git a/Knot.files b/Knot.files index d35359273146f9dd89ef2ecb24835e24432ea811..e3de0a3b1defcb427a7c71682379b4a542a229cd 100644 --- a/Knot.files +++ b/Knot.files @@ -148,6 +148,8 @@ src/knot/conf/conf.c src/knot/conf/conf.h src/knot/conf/logconf.c src/knot/conf/logconf.h +src/tests/common/acl_tests.c +src/tests/common/acl_tests.h src/tests/common/da_tests.c src/tests/common/da_tests.h src/tests/common/events_tests.c diff --git a/src/Makefile.am b/src/Makefile.am index f3737548ad2bc52f787c830cdf901850e57d6518..f1902ef5fad32ea4e31cbfa6a12fe0b3e0eee6c5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -46,6 +46,8 @@ knot_zcompile_SOURCES = \ zcompile/parser-descriptor.c unittests_SOURCES = \ + tests/common/acl_tests.c \ + tests/common/acl_tests.h \ tests/common/da_tests.c \ tests/common/da_tests.h \ tests/common/events_tests.c \ diff --git a/src/common/acl.c b/src/common/acl.c index ae51fd53cd3a9ce8afe94e6a882b8308188a97f1..a2a5059569e7ff03611264769bbd2516371f56fa 100644 --- a/src/common/acl.c +++ b/src/common/acl.c @@ -34,7 +34,10 @@ static int acl_compare(void *k1, void *k2) /* Compare ports on address match. */ ldiff = ntohs(a1->addr4.sin_port) - ntohs(a2->addr4.sin_port); - return ldiff < 0 ? -1 : 1; + if (ldiff != 0) { + return ldiff < 0 ? -1 : 1; + } + return 0; } /* IPv6 matching. */ @@ -63,7 +66,10 @@ static int acl_compare(void *k1, void *k2) /* Compare ports on address match. */ ldiff = ntohs(a1->addr6.sin6_port) - ntohs(a2->addr6.sin6_port); - return ldiff < 0 ? -1 : 1; + if (ldiff != 0) { + return ldiff < 0 ? -1 : 1; + } + return 0; } #endif diff --git a/src/common/acl.h b/src/common/acl.h index 8229547027accb9189ec38d5d7f4bf83b89333e1..8f383a01e619ab9a786486665f8c0e1266e8bae6 100644 --- a/src/common/acl.h +++ b/src/common/acl.h @@ -96,6 +96,10 @@ int acl_truncate(acl_t *acl); * \retval ACL name. */ static inline const char* acl_name(acl_t *acl) { + if (!acl) { + return 0; + } + return acl->name; } diff --git a/src/knot/server/name-server.c b/src/knot/server/name-server.c index c9ca63ca7e4c0db3f9fbceb6484201116e9b593a..d39e210f707e0fd866b50dd80bf0de917ad7f5ce 100644 --- a/src/knot/server/name-server.c +++ b/src/knot/server/name-server.c @@ -2007,7 +2007,7 @@ DEBUG_NS( if (acl_match(zone->acl.xfr_out, &xfr->from) == ACL_DENY) { /*! \todo What should we return here? */ debug_ns("Request for AXFR OUT is not authorized.\n"); - dnslib_response_set_rcode(xfr->response, DNSLIB_RCODE_NOTAUTH); + dnslib_response_set_rcode(xfr->response, DNSLIB_RCODE_REFUSED); return KNOT_EOK; } else { debug_ns("Authorized AXFR OUT request.\n"); diff --git a/src/tests/common/acl_tests.c b/src/tests/common/acl_tests.c new file mode 100644 index 0000000000000000000000000000000000000000..d5a7cd8e03e03cce0cf7f1527ca42bf11cee3ac3 --- /dev/null +++ b/src/tests/common/acl_tests.c @@ -0,0 +1,93 @@ +#include "tests/common/acl_tests.h" +#include "common/sockaddr.h" +#include "common/acl.h" + +static int acl_tests_count(int argc, char *argv[]); +static int acl_tests_run(int argc, char *argv[]); + +/*! Exported unit API. + */ +unit_api acl_tests_api = { + "ACL", //! Unit name + &acl_tests_count, //! Count scheduled tests + &acl_tests_run //! Run scheduled tests +}; + +static int acl_tests_count(int argc, char *argv[]) +{ + return 13; +} + +static int acl_tests_run(int argc, char *argv[]) +{ + // 1. Create an ACL + acl_t *acl = acl_new(ACL_DENY, "simple ACL"); + ok(acl != 0, "acl: new"); + + // 2. Create IPv4 address + sockaddr_t test_v4; + int ret = sockaddr_set(&test_v4, AF_INET, "127.0.0.1", 12345); + ok(ret > 0, "acl: new IPv4 address"); + + // 3. Create IPv6 address + sockaddr_t test_v6; + ret = sockaddr_set(&test_v6, AF_INET6, "::1", 54321); + ok(ret > 0, "acl: new IPv6 address"); + + // 4. Create simple IPv4 rule + ret = acl_create(acl, &test_v4, ACL_ACCEPT); + ok(ret == ACL_ACCEPT, "acl: inserted IPv4 rule"); + + // 5. Create simple IPv6 rule + ret = acl_create(acl, &test_v6, ACL_ACCEPT); + ok(ret == ACL_ACCEPT, "acl: inserted IPv6 rule"); + + // 6. Create simple IPv4 'any port' rule + sockaddr_t test_v4a; + sockaddr_set(&test_v4a, AF_INET, "20.20.20.20", 0); + ret = acl_create(acl, &test_v4a, ACL_ACCEPT); + ok(ret == ACL_ACCEPT, "acl: inserted IPv4 'any port' rule"); + + // 7. Attempt to match unmatching address + sockaddr_t unmatch_v4; + sockaddr_set(&unmatch_v4, AF_INET, "10.10.10.10", 24424); + ret = acl_match(acl, &unmatch_v4); + ok(ret == ACL_DENY, "acl: matching non-existing address"); + + // 8. Attempt to match unmatching IPv6 address + sockaddr_t unmatch_v6; + sockaddr_set(&unmatch_v6, AF_INET6, "2001:db8::1428:57ab", 24424); + ret = acl_match(acl, &unmatch_v6); + ok(ret == ACL_DENY, "acl: matching non-existing IPv6 address"); + + // 9. Attempt to match matching address + ret = acl_match(acl, &test_v4); + ok(ret == ACL_ACCEPT, "acl: matching existing address"); + + // 10. Attempt to match matching address + ret = acl_match(acl, &test_v6); + ok(ret == ACL_ACCEPT, "acl: matching existing IPv6 address"); + + // 11. Attempt to match matching 'any port' address + sockaddr_t match_v4a; + sockaddr_set(&match_v4a, AF_INET, "20.20.20.20", 24424); + ret = acl_match(acl, &match_v4a); + ok(ret == ACL_ACCEPT, "acl: matching existing IPv4 'any port' address"); + + // 12. Attempt to match matching address without matching port + sockaddr_set(&unmatch_v4, AF_INET, "127.0.0.1", 54321); + ret = acl_match(acl, &unmatch_v4); + ok(ret == ACL_DENY, "acl: matching address without matching port"); + + // 13. Invalid parameters + lives_ok({ + acl_delete(0); + acl_create(0, 0, ACL_ERROR); + acl_match(0, 0); + acl_truncate(0); + acl_name(0); + }, "acl: won't crash with NULL parameters"); + + // Return + return 0; +} diff --git a/src/tests/common/acl_tests.h b/src/tests/common/acl_tests.h new file mode 100644 index 0000000000000000000000000000000000000000..18c73cd0e6f748491994e6ac657ce1a4fb770794 --- /dev/null +++ b/src/tests/common/acl_tests.h @@ -0,0 +1,9 @@ +#ifndef _KNOT_ACL_TESTS_H_ +#define _KNOT_ACL_TESTS_H_ + +#include "common/libtap/tap_unit.h" + +/* Unit API. */ +unit_api acl_tests_api; + +#endif /* _KNOT_ACL_TESTS_H_ */ diff --git a/src/tests/unittests_main.c b/src/tests/unittests_main.c index f5e7777814a104bee3d07698a30f9ea86880335e..60c72ef98e06f07cea0a3a361a3b4b065eb2caa5 100644 --- a/src/tests/unittests_main.c +++ b/src/tests/unittests_main.c @@ -7,6 +7,7 @@ #include "tests/common/skiplist_tests.h" #include "tests/common/events_tests.h" #include "tests/common/da_tests.h" +#include "tests/common/acl_tests.h" #include "tests/knot/dthreads_tests.h" #include "tests/knot/server_tests.h" #include "tests/knot/conf_tests.h" @@ -25,6 +26,7 @@ int main(int argc, char *argv[]) &dthreads_tests_api, //! DThreads testing unit &events_tests_api, //! Events testing unit &da_tests_api, //! Dynamic array unit + &acl_tests_api, //! ACLs /* Server parts. */ &conf_tests_api, //! Configuration parser tests