acl.c 7.09 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*  Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <sys/types.h>
#include <sys/socket.h>
19
#include <tap/basic.h>
20

21
#include "test_conf.h"
22
#include "libknot/libknot.h"
Jan Včelák's avatar
Jan Včelák committed
23
#include "knot/updates/acl.h"
24
#include "contrib/sockaddr.h"
25

26 27 28 29 30
#define ZONE	"example.zone"
#define KEY1	"key1_md5"
#define KEY2	"key2_md5"
#define KEY3	"key3_sha256"

31 32 33 34
static void check_sockaddr_set(struct sockaddr_storage *ss, int family,
                               const char *straddr, int port)
{
	int ret = sockaddr_set(ss, family, straddr, port);
35
	ok(ret == 0, "set address '%s'", straddr);
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
}

static void test_acl_allowed(void)
{
	int ret;
	conf_val_t acl;
	struct sockaddr_storage addr = { 0 };

	knot_dname_t *zone_name = knot_dname_from_str_alloc(ZONE);
	ok(zone_name != NULL, "create zone dname");
	knot_dname_t *key1_name = knot_dname_from_str_alloc(KEY1);
	ok(key1_name != NULL, "create "KEY1);
	knot_dname_t *key2_name = knot_dname_from_str_alloc(KEY2);
	ok(key2_name != NULL, "create "KEY2);
	knot_dname_t *key3_name = knot_dname_from_str_alloc(KEY3);
	ok(key3_name != NULL, "create "KEY3);

53 54 55 56
	knot_tsig_key_t key0 = { 0 };
	knot_tsig_key_t key1 = { DNSSEC_TSIG_HMAC_MD5,    key1_name };
	knot_tsig_key_t key2 = { DNSSEC_TSIG_HMAC_MD5,    key2_name };
	knot_tsig_key_t key3 = { DNSSEC_TSIG_HMAC_SHA256, key3_name };
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78

	const char *conf_str =
		"key:\n"
		"  - id: "KEY1"\n"
		"    algorithm: hmac-md5\n"
		"    secret: Zm9v\n"
		"  - id: "KEY2"\n"
		"    algorithm: hmac-md5\n"
		"    secret: Zm9v\n"
		"  - id: "KEY3"\n"
		"    algorithm: hmac-sha256\n"
		"    secret: Zm8=\n"
		"\n"
		"acl:\n"
		"  - id: acl_key_addr\n"
		"    address: [ 2001::1 ]\n"
		"    key: [ key1_md5 ]\n"
		"    action: [ transfer ]\n"
		"  - id: acl_deny\n"
		"    address: [ 240.0.0.2 ]\n"
		"    action: [ notify ]\n"
		"    deny: on\n"
79 80 81
		"  - id: acl_no_action_deny\n"
		"    address: [ 240.0.0.3 ]\n"
		"    deny: on\n"
82 83 84 85 86 87
		"  - id: acl_multi_addr\n"
		"    address: [ 192.168.1.1, 240.0.0.0/24 ]\n"
		"    action: [ notify, update ]\n"
		"  - id: acl_multi_key\n"
		"    key: [ key2_md5, key3_sha256 ]\n"
		"    action: [ notify, update ]\n"
88 89 90
		"  - id: acl_range_addr\n"
		"    address: [ 100.0.0.0-100.0.0.5, ::0-::5 ]\n"
		"    action: [ transfer ]\n"
91 92 93
		"\n"
		"zone:\n"
		"  - domain: "ZONE"\n"
94 95 96
		"    acl: [ acl_key_addr, acl_deny, acl_no_action_deny ]\n"
		"    acl: [ acl_multi_addr, acl_multi_key ]\n"
		"    acl: [ acl_range_addr ]";
97 98 99 100

	ret = test_conf(conf_str, NULL);
	ok(ret == KNOT_EOK, "Prepare configuration");

101 102 103
	acl = conf_zone_get(conf(), C_ACL, zone_name);
	ok(acl.code == KNOT_EOK, "Get zone ACL");
	check_sockaddr_set(&addr, AF_INET6, "2001::1", 0);
104
	ret = acl_allowed(conf(), &acl, ACL_ACTION_NONE, &addr, &key1);
105 106
	ok(ret == true, "Address, key, empty action");

107 108 109
	acl = conf_zone_get(conf(), C_ACL, zone_name);
	ok(acl.code == KNOT_EOK, "Get zone ACL");
	check_sockaddr_set(&addr, AF_INET6, "2001::1", 0);
110
	ret = acl_allowed(conf(), &acl, ACL_ACTION_TRANSFER, &addr, &key1);
111 112 113 114 115
	ok(ret == true, "Address, key, action match");

	acl = conf_zone_get(conf(), C_ACL, zone_name);
	ok(acl.code == KNOT_EOK, "Get zone ACL");
	check_sockaddr_set(&addr, AF_INET6, "2001::2", 0);
116
	ret = acl_allowed(conf(), &acl, ACL_ACTION_TRANSFER, &addr, &key1);
117 118 119 120 121
	ok(ret == false, "Address not match, key, action match");

	acl = conf_zone_get(conf(), C_ACL, zone_name);
	ok(acl.code == KNOT_EOK, "Get zone ACL");
	check_sockaddr_set(&addr, AF_INET6, "2001::1", 0);
122
	ret = acl_allowed(conf(), &acl, ACL_ACTION_TRANSFER, &addr, &key0);
123 124 125 126 127
	ok(ret == false, "Address match, no key, action match");

	acl = conf_zone_get(conf(), C_ACL, zone_name);
	ok(acl.code == KNOT_EOK, "Get zone ACL");
	check_sockaddr_set(&addr, AF_INET6, "2001::1", 0);
128
	ret = acl_allowed(conf(), &acl, ACL_ACTION_TRANSFER, &addr, &key2);
129 130 131 132 133
	ok(ret == false, "Address match, key not match, action match");

	acl = conf_zone_get(conf(), C_ACL, zone_name);
	ok(acl.code == KNOT_EOK, "Get zone ACL");
	check_sockaddr_set(&addr, AF_INET6, "2001::1", 0);
134
	ret = acl_allowed(conf(), &acl, ACL_ACTION_NOTIFY, &addr, &key1);
135 136 137 138 139
	ok(ret == false, "Address, key match, action not match");

	acl = conf_zone_get(conf(), C_ACL, zone_name);
	ok(acl.code == KNOT_EOK, "Get zone ACL");
	check_sockaddr_set(&addr, AF_INET, "240.0.0.1", 0);
140
	ret = acl_allowed(conf(), &acl, ACL_ACTION_NOTIFY, &addr, &key0);
141 142 143 144 145
	ok(ret == true, "Second address match, no key, action match");

	acl = conf_zone_get(conf(), C_ACL, zone_name);
	ok(acl.code == KNOT_EOK, "Get zone ACL");
	check_sockaddr_set(&addr, AF_INET, "240.0.0.1", 0);
146
	ret = acl_allowed(conf(), &acl, ACL_ACTION_NOTIFY, &addr, &key1);
147 148 149 150 151
	ok(ret == false, "Second address match, extra key, action match");

	acl = conf_zone_get(conf(), C_ACL, zone_name);
	ok(acl.code == KNOT_EOK, "Get zone ACL");
	check_sockaddr_set(&addr, AF_INET, "240.0.0.2", 0);
152
	ret = acl_allowed(conf(), &acl, ACL_ACTION_NOTIFY, &addr, &key0);
153 154 155 156 157
	ok(ret == false, "Denied address match, no key, action match");

	acl = conf_zone_get(conf(), C_ACL, zone_name);
	ok(acl.code == KNOT_EOK, "Get zone ACL");
	check_sockaddr_set(&addr, AF_INET, "240.0.0.2", 0);
158
	ret = acl_allowed(conf(), &acl, ACL_ACTION_UPDATE, &addr, &key0);
159 160
	ok(ret == true, "Denied address match, no key, action not match");

161 162 163
	acl = conf_zone_get(conf(), C_ACL, zone_name);
	ok(acl.code == KNOT_EOK, "Get zone ACL");
	check_sockaddr_set(&addr, AF_INET, "240.0.0.3", 0);
164
	ret = acl_allowed(conf(), &acl, ACL_ACTION_UPDATE, &addr, &key0);
165 166
	ok(ret == false, "Denied address match, no key, no action");

167 168 169
	acl = conf_zone_get(conf(), C_ACL, zone_name);
	ok(acl.code == KNOT_EOK, "Get zone ACL");
	check_sockaddr_set(&addr, AF_INET, "1.1.1.1", 0);
170
	ret = acl_allowed(conf(), &acl, ACL_ACTION_UPDATE, &addr, &key3);
171 172
	ok(ret == true, "Arbitrary address, second key, action match");

173 174 175
	acl = conf_zone_get(conf(), C_ACL, zone_name);
	ok(acl.code == KNOT_EOK, "Get zone ACL");
	check_sockaddr_set(&addr, AF_INET, "100.0.0.1", 0);
176
	ret = acl_allowed(conf(), &acl, ACL_ACTION_TRANSFER, &addr, &key0);
177 178 179 180 181
	ok(ret == true, "IPv4 address from range, no key, action match");

	acl = conf_zone_get(conf(), C_ACL, zone_name);
	ok(acl.code == KNOT_EOK, "Get zone ACL");
	check_sockaddr_set(&addr, AF_INET6, "::1", 0);
182
	ret = acl_allowed(conf(), &acl, ACL_ACTION_TRANSFER, &addr, &key0);
183 184
	ok(ret == true, "IPv6 address from range, no key, action match");

185
	conf_free(conf());
186 187 188 189 190 191 192 193 194 195
	knot_dname_free(&zone_name, NULL);
	knot_dname_free(&key1_name, NULL);
	knot_dname_free(&key2_name, NULL);
	knot_dname_free(&key3_name, NULL);
}

int main(int argc, char *argv[])
{
	plan_lazy();

196
	diag("acl_allowed");
197
	test_acl_allowed();
198

199 200
	return 0;
}