Asterisk - The Open Source Telephony Project  18.5.0
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 (invalid_acl)
 
 AST_TEST_DEFINE (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.

Referenced by AST_TEST_DEFINE().

◆ TACL_D

#define TACL_D   AST_SENSE_DENY

Definition at line 121 of file test_acl.c.

Referenced by AST_TEST_DEFINE().

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 ( invalid_acl  )

Definition at line 40 of file test_acl.c.

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.

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 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define NULL
Definition: resample.c:96
internal representation of ACL entries In principle user applications would have no need for this...
Definition: acl.h:51
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
def info(msg)
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
Definition: acl.c:222
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:713
ast_test_result_state
Definition: test.h:200

◆ AST_TEST_DEFINE() [2/2]

AST_TEST_DEFINE ( acl  )

Definition at line 139 of file test_acl.c.

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.

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[] = {
202  { "10.1.1.5", TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A },
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 },
205  { "10.0.0.1", TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A, 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 
399 acl_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 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
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 TACL_D
Definition: test_acl.c:121
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:808
const char * access
Definition: test_acl.c:113
#define NULL
Definition: resample.c:96
Socket address structure.
Definition: netsock2.h:97
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
internal representation of ACL entries In principle user applications would have no need for this...
Definition: acl.h:51
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
def info(msg)
Definition: test_acl.c:111
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
Definition: acl.c:222
#define TACL_A
Definition: test_acl.c:120
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:713
ast_test_result_state
Definition: test.h:200
const char * host
Definition: test_acl.c:112

◆ 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.

References acl::access, ast_append_ha(), AST_TEST_FAIL, ast_test_status_update, acl::host, and len().

Referenced by AST_TEST_DEFINE().

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 char host[256]
Definition: muted.c:77
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
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:713

◆ load_module()

static int load_module ( void  )
static

Definition at line 443 of file test_acl.c.

References AST_MODULE_LOAD_SUCCESS, and AST_TEST_REGISTER.

444 {
445  AST_TEST_REGISTER(invalid_acl);
448 }
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
Definition: test_acl.c:111

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 436 of file test_acl.c.

References AST_TEST_UNREGISTER.

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

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.