Merged revisions 332177 via svnmerge from
[asterisk/asterisk.git] / tests / test_acl.c
index a0f005b..e597785 100644 (file)
@@ -26,6 +26,7 @@
 
 /*** MODULEINFO
        <depend>TEST_FRAMEWORK</depend>
+       <support_level>core</support_level>
  ***/
 
 #include "asterisk.h"
@@ -35,21 +36,46 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/test.h"
 #include "asterisk/acl.h"
 #include "asterisk/module.h"
+#include "asterisk/netsock2.h"
+#include "asterisk/config.h"
 
 AST_TEST_DEFINE(invalid_acl)
 {
        const char * invalid_acls[] = {
+               /* Negative netmask */
                "1.3.3.7/-1",
+               /* Netmask too large */
                "1.3.3.7/33",
+               /* Netmask waaaay too large */
                "1.3.3.7/92342348927389492307420",
+               /* Netmask non-numeric */
                "1.3.3.7/California",
+               /* Too many octets in Netmask */
                "1.3.3.7/255.255.255.255.255",
+               /* Octets in IP address exceed 255 */
                "57.60.278.900/31",
+               /* Octets in IP address exceed 255 and are negative */
                "400.32.201029.-6/24",
+               /* Invalidly formatted IP address */
                "EGGSOFDEATH/4000",
+               /* Too many octets in IP address */
                "33.4.7.8.3/300030",
+               /* Too many octets in Netmask */
                "1.2.3.4/6.7.8.9.0",
+               /* Too many octets in IP address */
                "3.1.4.1.5.9/3",
+               /* IPv6 address has multiple double colons */
+               "ff::ff::ff/3",
+               /* IPv6 address is too long */
+               "1234:5678:90ab:cdef:1234:5678:90ab:cdef:1234/56",
+               /* IPv6 netmask is too large */
+               "::ffff/129",
+               /* IPv4-mapped IPv6 address has too few octets */
+               "::ffff:255.255.255/128",
+               /* Leading and trailing colons for IPv6 address */
+               ":1234:/15",
+               /* IPv6 address and IPv4 netmask */
+               "fe80::1234/255.255.255.0",
        };
 
        enum ast_test_result_state res = AST_TEST_PASS;
@@ -89,10 +115,19 @@ struct acl {
        const char *access;
 };
 
+/* These constants are defined for the sole purpose of being shorter
+ * than their real names. It makes lines in this test quite a bit shorter
+ */
+
+#define TACL_A AST_SENSE_ALLOW
+#define TACL_D AST_SENSE_DENY
+
 AST_TEST_DEFINE(acl)
 {
-       struct acl permitall = { "0.0.0.0/0", "permit" };
-       struct acl denyall = { "0.0.0.0/0", "deny" };
+       struct acl permitallv4 = { "0.0.0.0/0", "permit" };
+       struct acl denyallv4 = { "0.0.0.0/0", "deny" };
+       struct acl permitallv6 = { "::/0", "permit" };
+       struct acl denyallv6 = { "::/0", "deny" };
        struct acl acl1[] = {
                { "0.0.0.0/0.0.0.0", "deny" },
                { "10.0.0.0/255.0.0.0", "permit" },
@@ -105,23 +140,48 @@ AST_TEST_DEFINE(acl)
                { "10.0.0.0/24", "permit" },
        };
 
+       struct acl acl3[] = {
+               { "::/0", "deny" },
+               { "fe80::/64", "permit" },
+       };
+
+       struct acl acl4[] = {
+               { "::/0", "deny" },
+               { "fe80::/64", "permit" },
+               { "fe80::ffff:0:0:0/80", "deny" },
+               { "fe80::ffff:0:ffff:0/112", "permit" },
+       };
+
        struct {
                const char *test_address;
+               int v4_permitall_result;
+               int v4_denyall_result;
+               int v6_permitall_result;
+               int v6_denyall_result;
                int acl1_result;
                int acl2_result;
+               int acl3_result;
+               int acl4_result;
        } acl_tests[] = {
-               { "10.1.1.5", AST_SENSE_ALLOW, AST_SENSE_ALLOW },
-               { "192.168.0.5", AST_SENSE_ALLOW, AST_SENSE_ALLOW },
-               { "192.168.1.5", AST_SENSE_DENY, AST_SENSE_ALLOW },
-               { "10.0.0.1", AST_SENSE_ALLOW, AST_SENSE_ALLOW },
-               { "10.0.10.10", AST_SENSE_ALLOW, AST_SENSE_DENY },
-               { "172.16.0.1", AST_SENSE_DENY, AST_SENSE_ALLOW },
+               { "10.1.1.5", TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A },
+               { "192.168.0.5", TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A },
+               { "192.168.1.5", TACL_A, TACL_D, TACL_A, TACL_A, TACL_D, TACL_A, TACL_A, TACL_A },
+               { "10.0.0.1", TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A },
+               { "10.0.10.10", TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_D, TACL_A, TACL_A },
+               { "172.16.0.1", TACL_A, TACL_D, TACL_A, TACL_A, TACL_D, TACL_A, TACL_A, TACL_A },
+               { "fe80::1234", TACL_A, TACL_A, TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_A },
+               { "fe80::ffff:1213:dead:beef", TACL_A, TACL_A, TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_D },
+               { "fe80::ffff:0:ffff:ABCD", TACL_A, TACL_A, TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_A },
        };
 
-       struct ast_ha *permit_ha = NULL;
-       struct ast_ha *deny_ha = NULL;
+       struct ast_ha *permit_hav4 = NULL;
+       struct ast_ha *deny_hav4 = NULL;
+       struct ast_ha *permit_hav6 = NULL;
+       struct ast_ha *deny_hav6 = NULL;
        struct ast_ha *ha1 = NULL;
        struct ast_ha *ha2 = NULL;
+       struct ast_ha *ha3 = NULL;
+       struct ast_ha *ha4 = NULL;
        enum ast_test_result_state res = AST_TEST_PASS;
        int err = 0;
        int i;
@@ -138,13 +198,25 @@ AST_TEST_DEFINE(acl)
                break;
        }
 
-       if (!(permit_ha = ast_append_ha(permitall.access, permitall.host, permit_ha, &err))) {
+       if (!(permit_hav4 = ast_append_ha(permitallv4.access, permitallv4.host, permit_hav4, &err))) {
+               ast_test_status_update(test, "Failed to create permit_all ACL\n");
+               res = AST_TEST_FAIL;
+               goto acl_cleanup;
+       }
+
+       if (!(deny_hav4 = ast_append_ha(denyallv4.access, denyallv4.host, deny_hav4, &err))) {
+               ast_test_status_update(test, "Failed to create deny_all ACL\n");
+               res = AST_TEST_FAIL;
+               goto acl_cleanup;
+       }
+
+       if (!(permit_hav6 = ast_append_ha(permitallv6.access, permitallv6.host, permit_hav6, &err))) {
                ast_test_status_update(test, "Failed to create permit_all ACL\n");
                res = AST_TEST_FAIL;
                goto acl_cleanup;
        }
 
-       if (!(deny_ha = ast_append_ha(denyall.access, denyall.host, deny_ha, &err))) {
+       if (!(deny_hav6 = ast_append_ha(denyallv6.access, denyallv6.host, deny_hav6, &err))) {
                ast_test_status_update(test, "Failed to create deny_all ACL\n");
                res = AST_TEST_FAIL;
                goto acl_cleanup;
@@ -168,62 +240,128 @@ AST_TEST_DEFINE(acl)
                }
        }
 
+       for (i = 0; i < ARRAY_LEN(acl3); ++i) {
+               if (!(ha3 = ast_append_ha(acl3[i].access, acl3[i].host, ha3, &err))) {
+                       ast_test_status_update(test, "Failed to add rule %s with access %s to ha3\n",
+                                       acl3[i].host, acl3[i].access);
+                       res = AST_TEST_FAIL;
+                       goto acl_cleanup;
+               }
+       }
+
+       for (i = 0; i < ARRAY_LEN(acl4); ++i) {
+               if (!(ha4 = ast_append_ha(acl4[i].access, acl4[i].host, ha4, &err))) {
+                       ast_test_status_update(test, "Failed to add rule %s with access %s to ha4\n",
+                                       acl4[i].host, acl4[i].access);
+                       res = AST_TEST_FAIL;
+                       goto acl_cleanup;
+               }
+       }
+
        for (i = 0; i < ARRAY_LEN(acl_tests); ++i) {
-               struct sockaddr_in sin;
-               int permit_res;
-               int deny_res;
+               struct ast_sockaddr addr;
+               int permit_resv4;
+               int permit_resv6;
+               int deny_resv4;
+               int deny_resv6;
                int acl1_res;
                int acl2_res;
+               int acl3_res;
+               int acl4_res;
 
-               inet_aton(acl_tests[i].test_address, &sin.sin_addr);
+               ast_sockaddr_parse(&addr, acl_tests[i].test_address, PARSE_PORT_FORBID);
+
+               permit_resv4 = ast_apply_ha(permit_hav4, &addr);
+               deny_resv4 = ast_apply_ha(deny_hav4, &addr);
+               permit_resv6 = ast_apply_ha(permit_hav6, &addr);
+               deny_resv6 = ast_apply_ha(deny_hav6, &addr);
+               acl1_res = ast_apply_ha(ha1, &addr);
+               acl2_res = ast_apply_ha(ha2, &addr);
+               acl3_res = ast_apply_ha(ha3, &addr);
+               acl4_res = ast_apply_ha(ha4, &addr);
+
+               if (permit_resv4 != acl_tests[i].v4_permitall_result) {
+                       ast_test_status_update(test, "Access not as expected to %s on permitallv4. Expected %d but "
+                                       "got %d instead\n", acl_tests[i].test_address, acl_tests[i].v4_permitall_result, permit_resv4);
+                       res = AST_TEST_FAIL;
+                       goto acl_cleanup;
+               }
 
-               permit_res = ast_apply_ha(permit_ha, &sin);
-               deny_res = ast_apply_ha(deny_ha, &sin);
-               acl1_res = ast_apply_ha(ha1, &sin);
-               acl2_res = ast_apply_ha(ha2, &sin);
+               if (deny_resv4 != acl_tests[i].v4_denyall_result) {
+                       ast_test_status_update(test, "Access not as expected to %s on denyallv4. Expected %d but "
+                                       "got %d instead\n", acl_tests[i].test_address, acl_tests[i].v4_denyall_result, deny_resv4);
+                       res = AST_TEST_FAIL;
+                       goto acl_cleanup;
+               }
 
-               if (permit_res != AST_SENSE_ALLOW) {
-                       ast_test_status_update(test, "Access denied to %s on permit_all ACL\n",
-                                       acl_tests[i].test_address);
+               if (permit_resv6 != acl_tests[i].v6_permitall_result) {
+                       ast_test_status_update(test, "Access not as expected to %s on permitallv6. Expected %d but "
+                                       "got %d instead\n", acl_tests[i].test_address, acl_tests[i].v6_permitall_result, permit_resv6);
                        res = AST_TEST_FAIL;
                        goto acl_cleanup;
                }
 
-               if (deny_res != AST_SENSE_DENY) {
-                       ast_test_status_update(test, "Access allowed to %s on deny_all ACL\n",
-                                       acl_tests[i].test_address);
+               if (deny_resv6 != acl_tests[i].v6_denyall_result) {
+                       ast_test_status_update(test, "Access not as expected to %s on denyallv6. Expected %d but "
+                                       "got %d instead\n", acl_tests[i].test_address, acl_tests[i].v6_denyall_result, deny_resv6);
                        res = AST_TEST_FAIL;
                        goto acl_cleanup;
                }
 
                if (acl1_res != acl_tests[i].acl1_result) {
-                       ast_test_status_update(test, "Access not as expected to %s on acl1. Expected %d but"
+                       ast_test_status_update(test, "Access not as expected to %s on acl1. Expected %d but "
                                        "got %d instead\n", acl_tests[i].test_address, acl_tests[i].acl1_result, acl1_res);
                        res = AST_TEST_FAIL;
                        goto acl_cleanup;
                }
 
                if (acl2_res != acl_tests[i].acl2_result) {
-                       ast_test_status_update(test, "Access not as expected to %s on acl2. Expected %d but"
+                       ast_test_status_update(test, "Access not as expected to %s on acl2. Expected %d but "
                                        "got %d instead\n", acl_tests[i].test_address, acl_tests[i].acl2_result, acl2_res);
                        res = AST_TEST_FAIL;
                        goto acl_cleanup;
                }
+
+               if (acl3_res != acl_tests[i].acl3_result) {
+                       ast_test_status_update(test, "Access not as expected to %s on acl3. Expected %d but "
+                                       "got %d instead\n", acl_tests[i].test_address, acl_tests[i].acl3_result, acl3_res);
+                       res = AST_TEST_FAIL;
+                       goto acl_cleanup;
+               }
+
+               if (acl4_res != acl_tests[i].acl4_result) {
+                       ast_test_status_update(test, "Access not as expected to %s on acl4. Expected %d but "
+                                       "got %d instead\n", acl_tests[i].test_address, acl_tests[i].acl4_result, acl4_res);
+                       res = AST_TEST_FAIL;
+                       goto acl_cleanup;
+               }
        }
 
 acl_cleanup:
-       if (permit_ha) {
-               ast_free_ha(permit_ha);
+       if (permit_hav4) {
+               ast_free_ha(permit_hav4);
+       }
+       if (deny_hav4) {
+               ast_free_ha(deny_hav4);
+       }
+       if (permit_hav6) {
+               ast_free_ha(permit_hav6);
        }
-       if (deny_ha) {
-               ast_free_ha(deny_ha);
+       if (deny_hav6) {
+               ast_free_ha(deny_hav6);
        }
        if (ha1) {
                ast_free_ha(ha1);
        }
-       if (ha1) {
+       if (ha2) {
                ast_free_ha(ha2);
        }
+       if (ha3) {
+               ast_free_ha(ha3);
+       }
+       if (ha4) {
+               ast_free_ha(ha4);
+       }
        return res;
 }