SDP: Make process possible multiple fmtp attributes per rtpmap.
[asterisk/asterisk.git] / tests / test_acl.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2010, Digium, Inc.
5  *
6  * Mark Michelson <mmichelson@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*!
20  * \file
21  * \brief ACL unit tests
22  *
23  * \author Mark Michelson <mmichelson@digium.com>
24  *
25  */
26
27 /*** MODULEINFO
28         <depend>TEST_FRAMEWORK</depend>
29         <support_level>core</support_level>
30  ***/
31
32 #include "asterisk.h"
33
34 #include "asterisk/test.h"
35 #include "asterisk/acl.h"
36 #include "asterisk/module.h"
37 #include "asterisk/netsock2.h"
38 #include "asterisk/config.h"
39
40 AST_TEST_DEFINE(invalid_acl)
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
79         enum ast_test_result_state res = AST_TEST_PASS;
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 }
110
111 struct acl {
112         const char *host;
113         const char *access;
114 };
115
116 /* These constants are defined for the sole purpose of being shorter
117  * than their real names. It makes lines in this test quite a bit shorter
118  */
119
120 #define TACL_A AST_SENSE_ALLOW
121 #define TACL_D AST_SENSE_DENY
122
123 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) 
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 }
138
139 AST_TEST_DEFINE(acl)
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;
224         enum ast_test_result_state res = AST_TEST_PASS;
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 }
435
436 static int unload_module(void)
437 {
438         AST_TEST_UNREGISTER(invalid_acl);
439         AST_TEST_UNREGISTER(acl);
440         return 0;
441 }
442
443 static int load_module(void)
444 {
445         AST_TEST_REGISTER(invalid_acl);
446         AST_TEST_REGISTER(acl);
447         return AST_MODULE_LOAD_SUCCESS;
448 }
449
450 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "ACL test module");