Asterisk - The Open Source Telephony Project GIT-master-a358458
Data Structures | Macros | Functions | Variables
test_acl.c File Reference

ACL unit tests. More...

#include "asterisk.h"
#include "asterisk/test.h"
#include "asterisk/acl.h"
#include "asterisk/module.h"
#include "asterisk/netsock2.h"
#include "asterisk/config.h"
Include dependency graph for test_acl.c:

Go to the source code of this file.

Data Structures

struct  acl
 

Macros

#define TACL_A   AST_SENSE_ALLOW
 
#define TACL_D   AST_SENSE_DENY
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
 AST_TEST_DEFINE (acl)
 
 AST_TEST_DEFINE (invalid_acl)
 
static int build_ha (const struct acl *acl, size_t len, struct ast_ha **ha, const char *acl_name, int *err, struct ast_test *test, enum ast_test_result_state *res)
 
static int load_module (void)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "ACL test module" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 

Detailed Description

ACL unit tests.

Author
Mark Michelson mmich.nosp@m.elso.nosp@m.n@dig.nosp@m.ium..nosp@m.com

Definition in file test_acl.c.

Macro Definition Documentation

◆ TACL_A

#define TACL_A   AST_SENSE_ALLOW

Definition at line 120 of file test_acl.c.

◆ TACL_D

#define TACL_D   AST_SENSE_DENY

Definition at line 121 of file test_acl.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 450 of file test_acl.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 450 of file test_acl.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 450 of file test_acl.c.

◆ AST_TEST_DEFINE() [1/2]

AST_TEST_DEFINE ( acl  )

Definition at line 139 of file test_acl.c.

140{
141 struct acl permitallv4 = { "0.0.0.0/0", "permit" };
142 struct acl denyallv4 = { "0.0.0.0/0", "deny" };
143 struct acl permitallv6 = { "::/0", "permit" };
144 struct acl denyallv6 = { "::/0", "deny" };
145
146 struct acl acl1[] = {
147 { "0.0.0.0/0.0.0.0", "deny" },
148 { "10.0.0.0/255.0.0.0", "permit" },
149 { "192.168.0.0/255.255.255.0", "permit" },
150 };
151
152 struct acl acl2[] = {
153 { "10.0.0.0/8", "deny" },
154 { "10.0.0.0/8", "permit" },
155 { "10.0.0.0/16", "deny" },
156 { "10.0.0.0/24", "permit" },
157 };
158
159 struct acl acl3[] = {
160 { "::/0", "deny" },
161 { "fe80::/64", "permit" },
162 };
163
164 struct acl acl4[] = {
165 { "::/0", "deny" },
166 { "fe80::/64", "permit" },
167 { "fe80::ffff:0:0:0/80", "deny" },
168 { "fe80::ffff:0:ffff:0/112", "permit" },
169 };
170
171 struct acl acl5[] = {
172 { "0.0.0.0/0.0.0.0", "deny" },
173 { "10.0.0.0/255.0.0.0,192.168.0.0/255.255.255.0", "permit" },
174 };
175
176 struct acl acl6[] = {
177 { "10.0.0.0/8", "deny" },
178 { "10.0.0.0/8", "permit" },
179 { "10.0.0.0/16,!10.0.0.0/24", "deny" },
180 };
181
182 struct acl acl7[] = {
183 { "::/0,!fe80::/64", "deny" },
184 { "fe80::ffff:0:0:0/80", "deny" },
185 { "fe80::ffff:0:ffff:0/112", "permit" },
186 };
187
188 struct {
189 const char *test_address;
190 int v4_permitall_result;
191 int v4_denyall_result;
192 int v6_permitall_result;
193 int v6_denyall_result;
194 int acl1_result;
195 int acl2_result;
196 int acl3_result;
197 int acl4_result;
198 int acl5_result;
199 int acl6_result;
200 int acl7_result;
201 } acl_tests[] = {
203 { "192.168.0.5", TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A },
204 { "192.168.1.5", TACL_A, TACL_D, TACL_A, TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_D, TACL_A, TACL_A },
206 { "10.0.10.10", TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_D, TACL_A },
207 { "172.16.0.1", TACL_A, TACL_D, TACL_A, TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_D, TACL_A, TACL_A },
208 { "fe80::1234", TACL_A, TACL_A, TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A },
209 { "fe80::ffff:1213:dead:beef", TACL_A, TACL_A, TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_D, TACL_A, TACL_A, TACL_D },
210 { "fe80::ffff:0:ffff:ABCD", TACL_A, TACL_A, TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A },
211 };
212
213 struct ast_ha *permit_hav4 = NULL;
214 struct ast_ha *deny_hav4 = NULL;
215 struct ast_ha *permit_hav6 = NULL;
216 struct ast_ha *deny_hav6 = NULL;
217 struct ast_ha *ha1 = NULL;
218 struct ast_ha *ha2 = NULL;
219 struct ast_ha *ha3 = NULL;
220 struct ast_ha *ha4 = NULL;
221 struct ast_ha *ha5 = NULL;
222 struct ast_ha *ha6 = NULL;
223 struct ast_ha *ha7 = NULL;
225 int err = 0;
226 int i;
227
228
229 switch (cmd) {
230 case TEST_INIT:
231 info->name = "acl";
232 info->category = "/main/acl/";
233 info->summary = "ACL unit test";
234 info->description =
235 "Tests that hosts are properly permitted or denied";
236 return AST_TEST_NOT_RUN;
237 case TEST_EXECUTE:
238 break;
239 }
240
241 if (!(permit_hav4 = ast_append_ha(permitallv4.access, permitallv4.host, permit_hav4, &err))) {
242 ast_test_status_update(test, "Failed to create permit_all ACL\n");
243 res = AST_TEST_FAIL;
244 goto acl_cleanup;
245 }
246
247 if (!(deny_hav4 = ast_append_ha(denyallv4.access, denyallv4.host, deny_hav4, &err))) {
248 ast_test_status_update(test, "Failed to create deny_all ACL\n");
249 res = AST_TEST_FAIL;
250 goto acl_cleanup;
251 }
252
253 if (!(permit_hav6 = ast_append_ha(permitallv6.access, permitallv6.host, permit_hav6, &err))) {
254 ast_test_status_update(test, "Failed to create permit_all ACL\n");
255 res = AST_TEST_FAIL;
256 goto acl_cleanup;
257 }
258
259 if (!(deny_hav6 = ast_append_ha(denyallv6.access, denyallv6.host, deny_hav6, &err))) {
260 ast_test_status_update(test, "Failed to create deny_all ACL\n");
261 res = AST_TEST_FAIL;
262 goto acl_cleanup;
263 }
264
265 if (build_ha(acl1, ARRAY_LEN(acl1), &ha1, "ha1", &err, test, &res) != 0) {
266 goto acl_cleanup;
267 }
268
269 if (build_ha(acl2, ARRAY_LEN(acl2), &ha2, "ha2", &err, test, &res) != 0) {
270 goto acl_cleanup;
271 }
272
273 if (build_ha(acl3, ARRAY_LEN(acl3), &ha3, "ha3", &err, test, &res) != 0) {
274 goto acl_cleanup;
275 }
276
277 if (build_ha(acl4, ARRAY_LEN(acl4), &ha4, "ha4", &err, test, &res) != 0) {
278 goto acl_cleanup;
279 }
280
281 if (build_ha(acl5, ARRAY_LEN(acl5), &ha5, "ha5", &err, test, &res) != 0) {
282 goto acl_cleanup;
283 }
284
285 if (build_ha(acl6, ARRAY_LEN(acl6), &ha6, "ha6", &err, test, &res) != 0) {
286 goto acl_cleanup;
287 }
288
289 if (build_ha(acl7, ARRAY_LEN(acl7), &ha7, "ha7", &err, test, &res) != 0) {
290 goto acl_cleanup;
291 }
292
293 for (i = 0; i < ARRAY_LEN(acl_tests); ++i) {
294 struct ast_sockaddr addr;
295 int permit_resv4;
296 int permit_resv6;
297 int deny_resv4;
298 int deny_resv6;
299 int acl1_res;
300 int acl2_res;
301 int acl3_res;
302 int acl4_res;
303 int acl5_res;
304 int acl6_res;
305 int acl7_res;
306
307 ast_sockaddr_parse(&addr, acl_tests[i].test_address, PARSE_PORT_FORBID);
308
309 permit_resv4 = ast_apply_ha(permit_hav4, &addr);
310 deny_resv4 = ast_apply_ha(deny_hav4, &addr);
311 permit_resv6 = ast_apply_ha(permit_hav6, &addr);
312 deny_resv6 = ast_apply_ha(deny_hav6, &addr);
313 acl1_res = ast_apply_ha(ha1, &addr);
314 acl2_res = ast_apply_ha(ha2, &addr);
315 acl3_res = ast_apply_ha(ha3, &addr);
316 acl4_res = ast_apply_ha(ha4, &addr);
317 acl5_res = ast_apply_ha(ha5, &addr);
318 acl6_res = ast_apply_ha(ha6, &addr);
319 acl7_res = ast_apply_ha(ha7, &addr);
320
321 if (permit_resv4 != acl_tests[i].v4_permitall_result) {
322 ast_test_status_update(test, "Access not as expected to %s on permitallv4. Expected %d but "
323 "got %d instead\n", acl_tests[i].test_address, acl_tests[i].v4_permitall_result, permit_resv4);
324 res = AST_TEST_FAIL;
325 goto acl_cleanup;
326 }
327
328 if (deny_resv4 != acl_tests[i].v4_denyall_result) {
329 ast_test_status_update(test, "Access not as expected to %s on denyallv4. Expected %d but "
330 "got %d instead\n", acl_tests[i].test_address, acl_tests[i].v4_denyall_result, deny_resv4);
331 res = AST_TEST_FAIL;
332 goto acl_cleanup;
333 }
334
335 if (permit_resv6 != acl_tests[i].v6_permitall_result) {
336 ast_test_status_update(test, "Access not as expected to %s on permitallv6. Expected %d but "
337 "got %d instead\n", acl_tests[i].test_address, acl_tests[i].v6_permitall_result, permit_resv6);
338 res = AST_TEST_FAIL;
339 goto acl_cleanup;
340 }
341
342 if (deny_resv6 != acl_tests[i].v6_denyall_result) {
343 ast_test_status_update(test, "Access not as expected to %s on denyallv6. Expected %d but "
344 "got %d instead\n", acl_tests[i].test_address, acl_tests[i].v6_denyall_result, deny_resv6);
345 res = AST_TEST_FAIL;
346 goto acl_cleanup;
347 }
348
349 if (acl1_res != acl_tests[i].acl1_result) {
350 ast_test_status_update(test, "Access not as expected to %s on acl1. Expected %d but "
351 "got %d instead\n", acl_tests[i].test_address, acl_tests[i].acl1_result, acl1_res);
352 res = AST_TEST_FAIL;
353 goto acl_cleanup;
354 }
355
356 if (acl2_res != acl_tests[i].acl2_result) {
357 ast_test_status_update(test, "Access not as expected to %s on acl2. Expected %d but "
358 "got %d instead\n", acl_tests[i].test_address, acl_tests[i].acl2_result, acl2_res);
359 res = AST_TEST_FAIL;
360 goto acl_cleanup;
361 }
362
363 if (acl3_res != acl_tests[i].acl3_result) {
364 ast_test_status_update(test, "Access not as expected to %s on acl3. Expected %d but "
365 "got %d instead\n", acl_tests[i].test_address, acl_tests[i].acl3_result, acl3_res);
366 res = AST_TEST_FAIL;
367 goto acl_cleanup;
368 }
369
370 if (acl4_res != acl_tests[i].acl4_result) {
371 ast_test_status_update(test, "Access not as expected to %s on acl4. Expected %d but "
372 "got %d instead\n", acl_tests[i].test_address, acl_tests[i].acl4_result, acl4_res);
373 res = AST_TEST_FAIL;
374 goto acl_cleanup;
375 }
376
377 if (acl5_res != acl_tests[i].acl5_result) {
378 ast_test_status_update(test, "Access not as expected to %s on acl5. Expected %d but "
379 "got %d instead\n", acl_tests[i].test_address, acl_tests[i].acl5_result, acl5_res);
380 res = AST_TEST_FAIL;
381 goto acl_cleanup;
382 }
383
384 if (acl6_res != acl_tests[i].acl6_result) {
385 ast_test_status_update(test, "Access not as expected to %s on acl6. Expected %d but "
386 "got %d instead\n", acl_tests[i].test_address, acl_tests[i].acl6_result, acl6_res);
387 res = AST_TEST_FAIL;
388 goto acl_cleanup;
389 }
390
391 if (acl7_res != acl_tests[i].acl7_result) {
392 ast_test_status_update(test, "Access not as expected to %s on acl7. Expected %d but "
393 "got %d instead\n", acl_tests[i].test_address, acl_tests[i].acl7_result, acl7_res);
394 res = AST_TEST_FAIL;
395 goto acl_cleanup;
396 }
397 }
398
399acl_cleanup:
400 if (permit_hav4) {
401 ast_free_ha(permit_hav4);
402 }
403 if (deny_hav4) {
404 ast_free_ha(deny_hav4);
405 }
406 if (permit_hav6) {
407 ast_free_ha(permit_hav6);
408 }
409 if (deny_hav6) {
410 ast_free_ha(deny_hav6);
411 }
412 if (ha1) {
413 ast_free_ha(ha1);
414 }
415 if (ha2) {
416 ast_free_ha(ha2);
417 }
418 if (ha3) {
419 ast_free_ha(ha3);
420 }
421 if (ha4) {
422 ast_free_ha(ha4);
423 }
424 if (ha5) {
425 ast_free_ha(ha5);
426 }
427 if (ha6) {
428 ast_free_ha(ha6);
429 }
430 if (ha7) {
431 ast_free_ha(ha7);
432 }
433 return res;
434}
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
Definition: acl.c:222
enum ast_acl_sense ast_apply_ha(const struct ast_ha *ha, const struct ast_sockaddr *addr)
Apply a set of rules to a given IP address.
Definition: acl.c:807
struct ast_ha * ast_append_ha(const char *sense, const char *stuff, struct ast_ha *path, int *error)
Add a new rule to a list of HAs.
Definition: acl.c:712
def info(msg)
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
#define NULL
Definition: resample.c:96
Definition: test_acl.c:111
const char * access
Definition: test_acl.c:113
const char * host
Definition: test_acl.c:112
internal representation of ACL entries In principle user applications would have no need for this,...
Definition: acl.h:51
Socket address structure.
Definition: netsock2.h:97
@ TEST_INIT
Definition: test.h:200
@ TEST_EXECUTE
Definition: test.h:201
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
ast_test_result_state
Definition: test.h:193
@ AST_TEST_PASS
Definition: test.h:195
@ AST_TEST_FAIL
Definition: test.h:196
@ AST_TEST_NOT_RUN
Definition: test.h:194
#define TACL_A
Definition: test_acl.c:120
static int build_ha(const struct acl *acl, size_t len, struct ast_ha **ha, const char *acl_name, int *err, struct ast_test *test, enum ast_test_result_state *res)
Definition: test_acl.c:123
#define TACL_D
Definition: test_acl.c:121
#define ARRAY_LEN(a)
Definition: utils.h:666

References acl::access, ARRAY_LEN, ast_append_ha(), ast_apply_ha(), ast_free_ha(), ast_sockaddr_parse(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, build_ha(), acl::host, sip_to_pjsip::info(), NULL, PARSE_PORT_FORBID, TACL_A, TACL_D, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [2/2]

AST_TEST_DEFINE ( invalid_acl  )

Definition at line 40 of file test_acl.c.

41{
42 const char * invalid_acls[] = {
43 /* Negative netmask */
44 "1.3.3.7/-1",
45 /* Netmask too large */
46 "1.3.3.7/33",
47 /* Netmask waaaay too large */
48 "1.3.3.7/92342348927389492307420",
49 /* Netmask non-numeric */
50 "1.3.3.7/California",
51 /* Too many octets in Netmask */
52 "1.3.3.7/255.255.255.255.255",
53 /* Octets in IP address exceed 255 */
54 "57.60.278.900/31",
55 /* Octets in IP address exceed 255 and are negative */
56 "400.32.201029.-6/24",
57 /* Invalidly formatted IP address */
58 "EGGSOFDEATH/4000",
59 /* Too many octets in IP address */
60 "33.4.7.8.3/300030",
61 /* Too many octets in Netmask */
62 "1.2.3.4/6.7.8.9.0",
63 /* Too many octets in IP address */
64 "3.1.4.1.5.9/3",
65 /* IPv6 address has multiple double colons */
66 "ff::ff::ff/3",
67 /* IPv6 address is too long */
68 "1234:5678:90ab:cdef:1234:5678:90ab:cdef:1234/56",
69 /* IPv6 netmask is too large */
70 "::ffff/129",
71 /* IPv4-mapped IPv6 address has too few octets */
72 "::ffff:255.255.255/128",
73 /* Leading and trailing colons for IPv6 address */
74 ":1234:/15",
75 /* IPv6 address and IPv4 netmask */
76 "fe80::1234/255.255.255.0",
77 };
78
80 struct ast_ha *ha = NULL;
81 int i;
82
83 switch (cmd) {
84 case TEST_INIT:
85 info->name = "invalid_acl";
86 info->category = "/main/acl/";
87 info->summary = "Invalid ACL unit test";
88 info->description =
89 "Ensures that garbage ACL values are not accepted";
90 return AST_TEST_NOT_RUN;
91 case TEST_EXECUTE:
92 break;
93 }
94
95 for (i = 0; i < ARRAY_LEN(invalid_acls); ++i) {
96 int err = 0;
97 ha = ast_append_ha("permit", invalid_acls[i], ha, &err);
98 if (ha || !err) {
99 ast_test_status_update(test, "ACL %s accepted even though it is total garbage.\n",
100 invalid_acls[i]);
101 if (ha) {
102 ast_free_ha(ha);
103 }
104 res = AST_TEST_FAIL;
105 }
106 }
107
108 return res;
109}

References ARRAY_LEN, ast_append_ha(), ast_free_ha(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, TEST_EXECUTE, and TEST_INIT.

◆ build_ha()

static int build_ha ( const struct acl acl,
size_t  len,
struct ast_ha **  ha,
const char *  acl_name,
int *  err,
struct ast_test *  test,
enum ast_test_result_state res 
)
static

Definition at line 123 of file test_acl.c.

124{
125 size_t i;
126
127 for (i = 0; i < len; ++i) {
128 if (!(*ha = ast_append_ha(acl[i].access, acl[i].host, *ha, err))) {
129 ast_test_status_update(test, "Failed to add rule %s with access %s to %s\n",
130 acl[i].host, acl[i].access, acl_name);
131 *res = AST_TEST_FAIL;
132 return -1;
133 }
134 }
135
136 return 0;
137}
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

References ast_append_ha(), AST_TEST_FAIL, ast_test_status_update, and len().

Referenced by AST_TEST_DEFINE().

◆ load_module()

static int load_module ( void  )
static

Definition at line 443 of file test_acl.c.

444{
445 AST_TEST_REGISTER(invalid_acl);
448}
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
#define AST_TEST_REGISTER(cb)
Definition: test.h:127

References AST_MODULE_LOAD_SUCCESS, and AST_TEST_REGISTER.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 436 of file test_acl.c.

437{
438 AST_TEST_UNREGISTER(invalid_acl);
440 return 0;
441}
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128

References AST_TEST_UNREGISTER.

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "ACL test module" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 450 of file test_acl.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 450 of file test_acl.c.