Skip to content
Snippets Groups Projects
Commit 0db5e61c authored by Marek Vavruša's avatar Marek Vavruša
Browse files

lib/zonecut: filter ANY and loopback addresses

parent 26bec1aa
No related branches found
No related tags found
No related merge requests found
......@@ -143,6 +143,26 @@ int kr_zonecut_copy(struct kr_zonecut *dst, const struct kr_zonecut *src)
return map_walk((map_t *)&src->nsset, copy_addr_set, dst);
}
/** @internal Filter ANY or loopback addresses. */
static bool is_valid_addr(uint8_t *addr, size_t len)
{
if (len == sizeof(struct in_addr)) {
/* Filter ANY and 127.0.0.0/8 */
uint32_t ip_host = ntohl(*(uint32_t *)(addr));
if (ip_host == 0 || (ip_host & 0xff000000) == 0x7f000000) {
return false;
}
} else if (len == sizeof(struct in6_addr)) {
struct in6_addr ip6_mask;
memset(&ip6_mask, 0, sizeof(ip6_mask));
/* All except last byte are zeroed, last byte defines ANY/::1 */
if (memcmp(addr, ip6_mask.s6_addr, sizeof(ip6_mask.s6_addr) - 1) == 0) {
return (addr[len - 1] > 1);
}
}
return true;
}
int kr_zonecut_add(struct kr_zonecut *cut, const knot_dname_t *ns, const knot_rdata_t *rdata)
{
if (!cut || !ns) {
......@@ -162,9 +182,14 @@ int kr_zonecut_add(struct kr_zonecut *cut, const knot_dname_t *ns, const knot_rd
if (rdata == NULL) {
return kr_ok();
}
/* Check for duplicates */
/* Check for invalid */
uint16_t rdlen = knot_rdata_rdlen(rdata);
if (pack_obj_find(pack, knot_rdata_data(rdata), rdlen)) {
uint8_t *raw_addr = knot_rdata_data(rdata);
if (!is_valid_addr(raw_addr, rdlen)) {
return kr_error(EILSEQ);
}
/* Check for duplicates */
if (pack_obj_find(pack, raw_addr, rdlen)) {
return kr_ok();
}
/* Push new address */
......
......@@ -14,6 +14,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <netinet/in.h>
#include "tests/test.h"
#include "lib/zonecut.h"
......@@ -33,6 +35,40 @@ static void test_zonecut_params(void **state)
assert_int_not_equal(kr_zonecut_find_cached(NULL, NULL, NULL, NULL, 0), 0);
}
#define TEST_IP(cut, ip, expect) { \
knot_rdata_t rdata[knot_rdata_array_size(sizeof(ip))]; \
knot_rdata_init(rdata, sizeof(ip), (uint8_t *)&ip, 0); \
assert_int_equal(kr_zonecut_add(&(cut), (const uint8_t *)"\x02cz", rdata), (expect)); \
} while (0)
static void test_zonecut_filter(void **state)
{
struct kr_zonecut cut;
kr_zonecut_init(&cut, (const uint8_t *)"", NULL);
/* IPv4 */
uint32_t ip4 = 0; /* 0.0.0.0 */
TEST_IP(cut, ip4, kr_error(EILSEQ));
ip4 = htonl(0x7f000002); /* 127.0.0.2 */
TEST_IP(cut, ip4, kr_error(EILSEQ));
ip4 = htonl(0x7fffffff); /* 127.255.255.255 */
TEST_IP(cut, ip4, kr_error(EILSEQ));
ip4 = htonl(0xff000001); /* 255.0.0.1 */
TEST_IP(cut, ip4, 0);
/* IPv6 */
struct in6_addr ip6;
memset(&ip6, 0, sizeof(ip6)); /* :: */
TEST_IP(cut, ip6.s6_addr, kr_error(EILSEQ));
ip6.s6_addr[15] = 0x01; /* ::1 */
TEST_IP(cut, ip6.s6_addr, kr_error(EILSEQ));
ip6.s6_addr[15] = 0x02; /* ::2 */
TEST_IP(cut, ip6.s6_addr, 0);
kr_zonecut_deinit(&cut);
}
#undef TEST_IP
static void test_zonecut_copy(void **state)
{
const knot_dname_t *root = (const uint8_t *)"";
......@@ -56,6 +92,7 @@ int main(void)
{
const UnitTest tests[] = {
unit_test(test_zonecut_params),
unit_test(test_zonecut_filter),
unit_test(test_zonecut_copy)
};
......
......@@ -28,11 +28,12 @@ ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
ADJUST copy_id copy_query
REPLY QR NXDOMAIN
SECTION QUESTION
a.gtld-servers.net. IN AAAA
SECTION ANSWER
a.gtld-servers.net. IN AAAA
SECTION AUTHORITY
. SOA bla bla 1 2 3 4 5
ENTRY_END
ENTRY_BEGIN
......@@ -63,6 +64,26 @@ SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id copy_query
REPLY QR SERVFAIL
SECTION QUESTION
ns.example.com. IN AAAA
SECTION AUTHORITY
com. SOA bla bla 1 2 3 4 5
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id copy_query
REPLY QR SERVFAIL
SECTION QUESTION
ns2.example.com. IN AAAA
SECTION AUTHORITY
com. SOA bla bla 1 2 3 4 5
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
......@@ -77,6 +98,7 @@ SECTION ADDITIONAL
ns.example.com. IN A 127.255.255.255
ns2.example.com. IN A 127.0.0.2
ENTRY_END
RANGE_END
; ns.example.com.
......@@ -110,6 +132,17 @@ example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
; ns.example.com trap
RANGE_BEGIN 0 100
ADDRESS 127.255.255.255
RANGE_END
; ns.example.com trap
RANGE_BEGIN 0 100
ADDRESS 127.0.0.2
RANGE_END
STEP 1 QUERY
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment