aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2010-03-25 17:52:20 +0000
committermmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2010-03-25 17:52:20 +0000
commitd1f11fd3a03a9b3dc505691592b10ee82563a839 (patch)
tree6e4ef6c4252d013af68ec3981b0ae441e067c75b
parent8e882d50c9fc48473448c9222a4afcd809560124 (diff)
Add unit test for testing ACL functionality.
There are two unit tests contained here. 1. "Invalid ACL" This attempts to read a bunch of badly formatted ACL entries and add them to a host access rule. The goal of this test is to be sure that all invalid entries are rejected as they should be. 2. "ACL" This sets up four ACLs. One is a permit all, one is a deny all, and the other two have specific rules about which subnets are allowed and which are not. Then a set of test addresses is used to determine whether we would allow those addresses to access us when each ACL is applied. This test, by the way, was what resulted in AST-2010-003's creation. Review: https://reviewboard.asterisk.org/r/532 git-svn-id: http://svn.digium.com/svn/asterisk/trunk@254557 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--tests/test_acl.c244
1 files changed, 244 insertions, 0 deletions
diff --git a/tests/test_acl.c b/tests/test_acl.c
new file mode 100644
index 000000000..61bffe5de
--- /dev/null
+++ b/tests/test_acl.c
@@ -0,0 +1,244 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * Mark Michelson <mmichelson@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief ACL unit tests
+ *
+ * \author Mark Michelson <mmichelson@digium.com>
+ *
+ */
+
+/*** MODULEINFO
+ <depend>TEST_FRAMEWORK</depend>
+ ***/
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/test.h"
+#include "asterisk/acl.h"
+#include "asterisk/module.h"
+
+AST_TEST_DEFINE(invalid_acl)
+{
+ const char * invalid_acls[] = {
+ "1.3.3.7/-1",
+ "1.3.3.7/33",
+ "1.3.3.7/92342348927389492307420",
+ "1.3.3.7/California",
+ "1.3.3.7/255.255.255.255.255",
+ "57.60.278.900/31",
+ "400.32.201029.-6/24",
+ "EGGSOFDEATH/4000",
+ "33.4.7.8.3/300030",
+ "1.2.3.4/6.7.8.9.0",
+ "3.1.4.1.5.9/3",
+ };
+
+ enum ast_test_result_state res = AST_TEST_PASS;
+ struct ast_ha *ha = NULL;
+ int i;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "invalid_acl";
+ info->category = "main/acl/";
+ info->summary = "Invalid ACL unit test";
+ info->description =
+ "Ensures that garbage ACL values are not accepted";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ for (i = 0; i < ARRAY_LEN(invalid_acls); ++i) {
+ int err = 0;
+ ha = ast_append_ha("permit", invalid_acls[i], ha, &err);
+ if (ha || !err) {
+ ast_test_status_update(test, "ACL %s accepted even though it is total garbage.\n",
+ invalid_acls[i]);
+ if (ha) {
+ ast_free_ha(ha);
+ }
+ res = AST_TEST_FAIL;
+ }
+ }
+
+ return res;
+}
+
+struct acl {
+ const char *host;
+ const char *access;
+};
+
+AST_TEST_DEFINE(acl)
+{
+ struct acl permitall = { "0.0.0.0/0", "permit" };
+ struct acl denyall = { "0.0.0.0/0", "deny" };
+ struct acl acl1[] = {
+ { "0.0.0.0/0.0.0.0", "deny" },
+ { "10.0.0.0/255.0.0.0", "permit" },
+ { "192.168.0.0/255.255.255.0", "permit" },
+ };
+ struct acl acl2[] = {
+ { "10.0.0.0/8", "deny" },
+ { "10.0.0.0/8", "permit" },
+ { "10.0.0.0/16", "deny" },
+ { "10.0.0.0/24", "permit" },
+ };
+
+ struct {
+ const char *test_address;
+ int acl1_result;
+ int acl2_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 },
+ };
+
+ struct ast_ha *permit_ha = NULL;
+ struct ast_ha *deny_ha = NULL;
+ struct ast_ha *ha1 = NULL;
+ struct ast_ha *ha2 = NULL;
+ enum ast_test_result_state res = AST_TEST_PASS;
+ int err = 0;
+ int i;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "acl";
+ info->category = "main/acl/";
+ info->summary = "ACL unit test";
+ info->description =
+ "Tests that hosts are properly permitted or denied";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ if (!(permit_ha = ast_append_ha(permitall.access, permitall.host, permit_ha, &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))) {
+ ast_test_status_update(test, "Failed to create deny_all ACL\n");
+ res = AST_TEST_FAIL;
+ goto acl_cleanup;
+ }
+
+ for (i = 0; i < ARRAY_LEN(acl1); ++i) {
+ if (!(ha1 = ast_append_ha(acl1[i].access, acl1[i].host, ha1, &err))) {
+ ast_test_status_update(test, "Failed to add rule %s with access %s to ha1\n",
+ acl1[i].host, acl1[i].access);
+ res = AST_TEST_FAIL;
+ goto acl_cleanup;
+ }
+ }
+
+ for (i = 0; i < ARRAY_LEN(acl2); ++i) {
+ if (!(ha2 = ast_append_ha(acl2[i].access, acl2[i].host, ha2, &err))) {
+ ast_test_status_update(test, "Failed to add rule %s with access %s to ha2\n",
+ acl2[i].host, acl2[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;
+ int acl1_res;
+ int acl2_res;
+
+ inet_aton(acl_tests[i].test_address, &sin.sin_addr);
+
+ 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 (permit_res != AST_SENSE_ALLOW) {
+ ast_test_status_update(test, "Access denied to %s on permit_all ACL\n",
+ acl_tests[i].test_address);
+ 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);
+ 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"
+ "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"
+ "got %d instead\n", acl_tests[i].test_address, acl_tests[i].acl2_result, acl2_res);
+ res = AST_TEST_FAIL;
+ goto acl_cleanup;
+ }
+ }
+
+acl_cleanup:
+ if (permit_ha) {
+ ast_free_ha(permit_ha);
+ }
+ if (deny_ha) {
+ ast_free_ha(deny_ha);
+ }
+ if (ha1) {
+ ast_free_ha(ha1);
+ }
+ if (ha1) {
+ ast_free_ha(ha2);
+ }
+ return res;
+}
+
+static int unload_module(void)
+{
+ AST_TEST_UNREGISTER(invalid_acl);
+ AST_TEST_UNREGISTER(acl);
+ return 0;
+}
+
+static int load_module(void)
+{
+ AST_TEST_REGISTER(invalid_acl);
+ AST_TEST_REGISTER(acl);
+ return AST_MODULE_LOAD_SUCCESS;
+}
+
+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "ACL test module");