test_acl.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  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. * \file
  20. * \brief ACL unit tests
  21. *
  22. * \author Mark Michelson <mmichelson@digium.com>
  23. *
  24. */
  25. /*** MODULEINFO
  26. <depend>TEST_FRAMEWORK</depend>
  27. <support_level>extended</support_level>
  28. ***/
  29. #include "asterisk.h"
  30. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  31. #include "asterisk/test.h"
  32. #include "asterisk/acl.h"
  33. #include "asterisk/module.h"
  34. #include "asterisk/netsock2.h"
  35. #include "asterisk/config.h"
  36. AST_TEST_DEFINE(invalid_acl)
  37. {
  38. const char * invalid_acls[] = {
  39. /* Negative netmask */
  40. "1.3.3.7/-1",
  41. /* Netmask too large */
  42. "1.3.3.7/33",
  43. /* Netmask waaaay too large */
  44. "1.3.3.7/92342348927389492307420",
  45. /* Netmask non-numeric */
  46. "1.3.3.7/California",
  47. /* Too many octets in Netmask */
  48. "1.3.3.7/255.255.255.255.255",
  49. /* Octets in IP address exceed 255 */
  50. "57.60.278.900/31",
  51. /* Octets in IP address exceed 255 and are negative */
  52. "400.32.201029.-6/24",
  53. /* Invalidly formatted IP address */
  54. "EGGSOFDEATH/4000",
  55. /* Too many octets in IP address */
  56. "33.4.7.8.3/300030",
  57. /* Too many octets in Netmask */
  58. "1.2.3.4/6.7.8.9.0",
  59. /* Too many octets in IP address */
  60. "3.1.4.1.5.9/3",
  61. /* IPv6 address has multiple double colons */
  62. "ff::ff::ff/3",
  63. /* IPv6 address is too long */
  64. "1234:5678:90ab:cdef:1234:5678:90ab:cdef:1234/56",
  65. /* IPv6 netmask is too large */
  66. "::ffff/129",
  67. /* IPv4-mapped IPv6 address has too few octets */
  68. "::ffff:255.255.255/128",
  69. /* Leading and trailing colons for IPv6 address */
  70. ":1234:/15",
  71. /* IPv6 address and IPv4 netmask */
  72. "fe80::1234/255.255.255.0",
  73. };
  74. enum ast_test_result_state res = AST_TEST_PASS;
  75. struct ast_ha *ha = NULL;
  76. int i;
  77. switch (cmd) {
  78. case TEST_INIT:
  79. info->name = "invalid_acl";
  80. info->category = "/main/acl/";
  81. info->summary = "Invalid ACL unit test";
  82. info->description =
  83. "Ensures that garbage ACL values are not accepted";
  84. return AST_TEST_NOT_RUN;
  85. case TEST_EXECUTE:
  86. break;
  87. }
  88. for (i = 0; i < ARRAY_LEN(invalid_acls); ++i) {
  89. int err = 0;
  90. ha = ast_append_ha("permit", invalid_acls[i], ha, &err);
  91. if (ha || !err) {
  92. ast_test_status_update(test, "ACL %s accepted even though it is total garbage.\n",
  93. invalid_acls[i]);
  94. if (ha) {
  95. ast_free_ha(ha);
  96. }
  97. res = AST_TEST_FAIL;
  98. }
  99. }
  100. return res;
  101. }
  102. struct acl {
  103. const char *host;
  104. const char *access;
  105. };
  106. /* These constants are defined for the sole purpose of being shorter
  107. * than their real names. It makes lines in this test quite a bit shorter
  108. */
  109. #define TACL_A AST_SENSE_ALLOW
  110. #define TACL_D AST_SENSE_DENY
  111. AST_TEST_DEFINE(acl)
  112. {
  113. struct acl permitallv4 = { "0.0.0.0/0", "permit" };
  114. struct acl denyallv4 = { "0.0.0.0/0", "deny" };
  115. struct acl permitallv6 = { "::/0", "permit" };
  116. struct acl denyallv6 = { "::/0", "deny" };
  117. struct acl acl1[] = {
  118. { "0.0.0.0/0.0.0.0", "deny" },
  119. { "10.0.0.0/255.0.0.0", "permit" },
  120. { "192.168.0.0/255.255.255.0", "permit" },
  121. };
  122. struct acl acl2[] = {
  123. { "10.0.0.0/8", "deny" },
  124. { "10.0.0.0/8", "permit" },
  125. { "10.0.0.0/16", "deny" },
  126. { "10.0.0.0/24", "permit" },
  127. };
  128. struct acl acl3[] = {
  129. { "::/0", "deny" },
  130. { "fe80::/64", "permit" },
  131. };
  132. struct acl acl4[] = {
  133. { "::/0", "deny" },
  134. { "fe80::/64", "permit" },
  135. { "fe80::ffff:0:0:0/80", "deny" },
  136. { "fe80::ffff:0:ffff:0/112", "permit" },
  137. };
  138. struct {
  139. const char *test_address;
  140. int v4_permitall_result;
  141. int v4_denyall_result;
  142. int v6_permitall_result;
  143. int v6_denyall_result;
  144. int acl1_result;
  145. int acl2_result;
  146. int acl3_result;
  147. int acl4_result;
  148. } acl_tests[] = {
  149. { "10.1.1.5", TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A },
  150. { "192.168.0.5", TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A },
  151. { "192.168.1.5", TACL_A, TACL_D, TACL_A, TACL_A, TACL_D, TACL_A, TACL_A, TACL_A },
  152. { "10.0.0.1", TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A, TACL_A },
  153. { "10.0.10.10", TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_D, TACL_A, TACL_A },
  154. { "172.16.0.1", TACL_A, TACL_D, TACL_A, TACL_A, TACL_D, TACL_A, TACL_A, TACL_A },
  155. { "fe80::1234", TACL_A, TACL_A, TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_A },
  156. { "fe80::ffff:1213:dead:beef", TACL_A, TACL_A, TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_D },
  157. { "fe80::ffff:0:ffff:ABCD", TACL_A, TACL_A, TACL_A, TACL_D, TACL_A, TACL_A, TACL_A, TACL_A },
  158. };
  159. struct ast_ha *permit_hav4 = NULL;
  160. struct ast_ha *deny_hav4 = NULL;
  161. struct ast_ha *permit_hav6 = NULL;
  162. struct ast_ha *deny_hav6 = NULL;
  163. struct ast_ha *ha1 = NULL;
  164. struct ast_ha *ha2 = NULL;
  165. struct ast_ha *ha3 = NULL;
  166. struct ast_ha *ha4 = NULL;
  167. enum ast_test_result_state res = AST_TEST_PASS;
  168. int err = 0;
  169. int i;
  170. switch (cmd) {
  171. case TEST_INIT:
  172. info->name = "acl";
  173. info->category = "/main/acl/";
  174. info->summary = "ACL unit test";
  175. info->description =
  176. "Tests that hosts are properly permitted or denied";
  177. return AST_TEST_NOT_RUN;
  178. case TEST_EXECUTE:
  179. break;
  180. }
  181. if (!(permit_hav4 = ast_append_ha(permitallv4.access, permitallv4.host, permit_hav4, &err))) {
  182. ast_test_status_update(test, "Failed to create permit_all ACL\n");
  183. res = AST_TEST_FAIL;
  184. goto acl_cleanup;
  185. }
  186. if (!(deny_hav4 = ast_append_ha(denyallv4.access, denyallv4.host, deny_hav4, &err))) {
  187. ast_test_status_update(test, "Failed to create deny_all ACL\n");
  188. res = AST_TEST_FAIL;
  189. goto acl_cleanup;
  190. }
  191. if (!(permit_hav6 = ast_append_ha(permitallv6.access, permitallv6.host, permit_hav6, &err))) {
  192. ast_test_status_update(test, "Failed to create permit_all ACL\n");
  193. res = AST_TEST_FAIL;
  194. goto acl_cleanup;
  195. }
  196. if (!(deny_hav6 = ast_append_ha(denyallv6.access, denyallv6.host, deny_hav6, &err))) {
  197. ast_test_status_update(test, "Failed to create deny_all ACL\n");
  198. res = AST_TEST_FAIL;
  199. goto acl_cleanup;
  200. }
  201. for (i = 0; i < ARRAY_LEN(acl1); ++i) {
  202. if (!(ha1 = ast_append_ha(acl1[i].access, acl1[i].host, ha1, &err))) {
  203. ast_test_status_update(test, "Failed to add rule %s with access %s to ha1\n",
  204. acl1[i].host, acl1[i].access);
  205. res = AST_TEST_FAIL;
  206. goto acl_cleanup;
  207. }
  208. }
  209. for (i = 0; i < ARRAY_LEN(acl2); ++i) {
  210. if (!(ha2 = ast_append_ha(acl2[i].access, acl2[i].host, ha2, &err))) {
  211. ast_test_status_update(test, "Failed to add rule %s with access %s to ha2\n",
  212. acl2[i].host, acl2[i].access);
  213. res = AST_TEST_FAIL;
  214. goto acl_cleanup;
  215. }
  216. }
  217. for (i = 0; i < ARRAY_LEN(acl3); ++i) {
  218. if (!(ha3 = ast_append_ha(acl3[i].access, acl3[i].host, ha3, &err))) {
  219. ast_test_status_update(test, "Failed to add rule %s with access %s to ha3\n",
  220. acl3[i].host, acl3[i].access);
  221. res = AST_TEST_FAIL;
  222. goto acl_cleanup;
  223. }
  224. }
  225. for (i = 0; i < ARRAY_LEN(acl4); ++i) {
  226. if (!(ha4 = ast_append_ha(acl4[i].access, acl4[i].host, ha4, &err))) {
  227. ast_test_status_update(test, "Failed to add rule %s with access %s to ha4\n",
  228. acl4[i].host, acl4[i].access);
  229. res = AST_TEST_FAIL;
  230. goto acl_cleanup;
  231. }
  232. }
  233. for (i = 0; i < ARRAY_LEN(acl_tests); ++i) {
  234. struct ast_sockaddr addr;
  235. int permit_resv4;
  236. int permit_resv6;
  237. int deny_resv4;
  238. int deny_resv6;
  239. int acl1_res;
  240. int acl2_res;
  241. int acl3_res;
  242. int acl4_res;
  243. ast_sockaddr_parse(&addr, acl_tests[i].test_address, PARSE_PORT_FORBID);
  244. permit_resv4 = ast_apply_ha(permit_hav4, &addr);
  245. deny_resv4 = ast_apply_ha(deny_hav4, &addr);
  246. permit_resv6 = ast_apply_ha(permit_hav6, &addr);
  247. deny_resv6 = ast_apply_ha(deny_hav6, &addr);
  248. acl1_res = ast_apply_ha(ha1, &addr);
  249. acl2_res = ast_apply_ha(ha2, &addr);
  250. acl3_res = ast_apply_ha(ha3, &addr);
  251. acl4_res = ast_apply_ha(ha4, &addr);
  252. if (permit_resv4 != acl_tests[i].v4_permitall_result) {
  253. ast_test_status_update(test, "Access not as expected to %s on permitallv4. Expected %d but "
  254. "got %d instead\n", acl_tests[i].test_address, acl_tests[i].v4_permitall_result, permit_resv4);
  255. res = AST_TEST_FAIL;
  256. goto acl_cleanup;
  257. }
  258. if (deny_resv4 != acl_tests[i].v4_denyall_result) {
  259. ast_test_status_update(test, "Access not as expected to %s on denyallv4. Expected %d but "
  260. "got %d instead\n", acl_tests[i].test_address, acl_tests[i].v4_denyall_result, deny_resv4);
  261. res = AST_TEST_FAIL;
  262. goto acl_cleanup;
  263. }
  264. if (permit_resv6 != acl_tests[i].v6_permitall_result) {
  265. ast_test_status_update(test, "Access not as expected to %s on permitallv6. Expected %d but "
  266. "got %d instead\n", acl_tests[i].test_address, acl_tests[i].v6_permitall_result, permit_resv6);
  267. res = AST_TEST_FAIL;
  268. goto acl_cleanup;
  269. }
  270. if (deny_resv6 != acl_tests[i].v6_denyall_result) {
  271. ast_test_status_update(test, "Access not as expected to %s on denyallv6. Expected %d but "
  272. "got %d instead\n", acl_tests[i].test_address, acl_tests[i].v6_denyall_result, deny_resv6);
  273. res = AST_TEST_FAIL;
  274. goto acl_cleanup;
  275. }
  276. if (acl1_res != acl_tests[i].acl1_result) {
  277. ast_test_status_update(test, "Access not as expected to %s on acl1. Expected %d but "
  278. "got %d instead\n", acl_tests[i].test_address, acl_tests[i].acl1_result, acl1_res);
  279. res = AST_TEST_FAIL;
  280. goto acl_cleanup;
  281. }
  282. if (acl2_res != acl_tests[i].acl2_result) {
  283. ast_test_status_update(test, "Access not as expected to %s on acl2. Expected %d but "
  284. "got %d instead\n", acl_tests[i].test_address, acl_tests[i].acl2_result, acl2_res);
  285. res = AST_TEST_FAIL;
  286. goto acl_cleanup;
  287. }
  288. if (acl3_res != acl_tests[i].acl3_result) {
  289. ast_test_status_update(test, "Access not as expected to %s on acl3. Expected %d but "
  290. "got %d instead\n", acl_tests[i].test_address, acl_tests[i].acl3_result, acl3_res);
  291. res = AST_TEST_FAIL;
  292. goto acl_cleanup;
  293. }
  294. if (acl4_res != acl_tests[i].acl4_result) {
  295. ast_test_status_update(test, "Access not as expected to %s on acl4. Expected %d but "
  296. "got %d instead\n", acl_tests[i].test_address, acl_tests[i].acl4_result, acl4_res);
  297. res = AST_TEST_FAIL;
  298. goto acl_cleanup;
  299. }
  300. }
  301. acl_cleanup:
  302. if (permit_hav4) {
  303. ast_free_ha(permit_hav4);
  304. }
  305. if (deny_hav4) {
  306. ast_free_ha(deny_hav4);
  307. }
  308. if (permit_hav6) {
  309. ast_free_ha(permit_hav6);
  310. }
  311. if (deny_hav6) {
  312. ast_free_ha(deny_hav6);
  313. }
  314. if (ha1) {
  315. ast_free_ha(ha1);
  316. }
  317. if (ha2) {
  318. ast_free_ha(ha2);
  319. }
  320. if (ha3) {
  321. ast_free_ha(ha3);
  322. }
  323. if (ha4) {
  324. ast_free_ha(ha4);
  325. }
  326. return res;
  327. }
  328. static int unload_module(void)
  329. {
  330. AST_TEST_UNREGISTER(invalid_acl);
  331. AST_TEST_UNREGISTER(acl);
  332. return 0;
  333. }
  334. static int load_module(void)
  335. {
  336. AST_TEST_REGISTER(invalid_acl);
  337. AST_TEST_REGISTER(acl);
  338. return AST_MODULE_LOAD_SUCCESS;
  339. }
  340. AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "ACL test module");