@ -35,21 +35,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 +114,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 +139,49 @@ 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:1234::1234 " , TACL_A , TACL_A , TACL_A , TACL_D , TACL_A , TACL_A , TACL_D , TACL_D , } ,
{ " 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_ha v6 = ast_append_ha ( denyall v6 . access , denyall v6 . host , deny_ha v6 , & 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_res v6 ! = 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_res v6 ! = 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_ha v6 ) {
ast_free_ha ( deny_ha v6 ) ;
}
if ( ha1 ) {
ast_free_ha ( ha1 ) ;
}
if ( ha1 ) {
if ( ha 2 ) {
ast_free_ha ( ha2 ) ;
}
if ( ha3 ) {
ast_free_ha ( ha3 ) ;
}
if ( ha4 ) {
ast_free_ha ( ha4 ) ;
}
return res ;
}