basic implementation of named acls (need to tidy up calls to check_acl)
This commit is contained in:
@@ -26,7 +26,7 @@ subroutines.
|
|||||||
|
|
||||||
=head1 EXPORT_OK
|
=head1 EXPORT_OK
|
||||||
|
|
||||||
=head2 check_acl( $ip, \@config )
|
=head2 check_acl( $ip, \@config | $configitem )
|
||||||
|
|
||||||
Given a Device or IP address, compares it to the items in C<< \@config >>
|
Given a Device or IP address, compares it to the items in C<< \@config >>
|
||||||
then returns true or false. You can control whether any item must match or
|
then returns true or false. You can control whether any item must match or
|
||||||
@@ -58,6 +58,11 @@ C<vendor> (with enforced begin/end regexp anchors).
|
|||||||
|
|
||||||
=item *
|
=item *
|
||||||
|
|
||||||
|
"C<group:grpname>" to refer to a named access control list that is in the
|
||||||
|
C<host_groups> configuration (C<grpname> is the group name).
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
"C<op:and>" to require all items to match (or not match) the provided IP or
|
"C<op:and>" to require all items to match (or not match) the provided IP or
|
||||||
device. Note that this includes IP address version mismatches (v4-v6).
|
device. Note that this includes IP address version mismatches (v4-v6).
|
||||||
|
|
||||||
@@ -74,11 +79,14 @@ To match any device, use "C<any>". To match no devices we suggest using
|
|||||||
|
|
||||||
sub check_acl {
|
sub check_acl {
|
||||||
my ($thing, $config) = @_;
|
my ($thing, $config) = @_;
|
||||||
|
return 0 unless defined $thing and defined $config;
|
||||||
|
|
||||||
my $real_ip = (
|
my $real_ip = (
|
||||||
(blessed $thing and $thing->can('ip')) ? $thing->ip : (
|
(blessed $thing and $thing->can('ip')) ? $thing->ip : (
|
||||||
(blessed $thing and $thing->can('addr')) ? $thing->addr : $thing ));
|
(blessed $thing and $thing->can('addr')) ? $thing->addr : $thing ));
|
||||||
return 0 if blessed $real_ip; # class we do not understand
|
return 0 if blessed $real_ip; # class we do not understand
|
||||||
|
|
||||||
|
$config = [$config] if ref [] ne ref $config;
|
||||||
my $addr = NetAddr::IP::Lite->new($real_ip);
|
my $addr = NetAddr::IP::Lite->new($real_ip);
|
||||||
my $name = hostname_from_ip($addr->addr) || '!!NO_HOSTNAME!!';
|
my $name = hostname_from_ip($addr->addr) || '!!NO_HOSTNAME!!';
|
||||||
my $all = (scalar grep {m/^op:and$/} @$config);
|
my $all = (scalar grep {m/^op:and$/} @$config);
|
||||||
@@ -98,7 +106,20 @@ sub check_acl {
|
|||||||
|
|
||||||
my $neg = ($item =~ s/^!//);
|
my $neg = ($item =~ s/^!//);
|
||||||
|
|
||||||
if ($item =~ m/^([^:]+)\s*:\s*([^:]+)$/) {
|
if ($item =~ m/^group:(.+)$/) {
|
||||||
|
my $group = $1;
|
||||||
|
setting('host_groups')->{$group} ||= [];
|
||||||
|
|
||||||
|
if ($neg xor check_acl($thing, setting('host_groups')->{$group})) {
|
||||||
|
return 1 if not $all;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 0 if $all;
|
||||||
|
}
|
||||||
|
next INLIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($item =~ m/^([^:]+):([^:]+)$/) {
|
||||||
my $prop = $1;
|
my $prop = $1;
|
||||||
my $match = $2;
|
my $match = $2;
|
||||||
|
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ login_logo: ""
|
|||||||
|
|
||||||
# mibhome is discovered from environment
|
# mibhome is discovered from environment
|
||||||
# mibdirs defaults to contents of mibhome
|
# mibdirs defaults to contents of mibhome
|
||||||
|
host_groups: {}
|
||||||
community: ['public']
|
community: ['public']
|
||||||
community_rw: ['private']
|
community_rw: ['private']
|
||||||
snmp_auth: []
|
snmp_auth: []
|
||||||
|
|||||||
@@ -4,9 +4,12 @@ use strict; use warnings FATAL => 'all';
|
|||||||
use Test::More 1.302083;
|
use Test::More 1.302083;
|
||||||
|
|
||||||
BEGIN {
|
BEGIN {
|
||||||
|
use_ok( 'App::Netdisco::Configuration', 'check_acl' );
|
||||||
use_ok( 'App::Netdisco::Util::Permission', 'check_acl' );
|
use_ok( 'App::Netdisco::Util::Permission', 'check_acl' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use Dancer qw/:script !pass/;
|
||||||
|
|
||||||
my @conf = (
|
my @conf = (
|
||||||
# +ve match -ve match
|
# +ve match -ve match
|
||||||
'localhost', '!www.example.com', # 0, 1
|
'localhost', '!www.example.com', # 0, 1
|
||||||
@@ -22,7 +25,9 @@ my @conf = (
|
|||||||
qr/(?!:www.example.com)/, '!127.0.0.0/29', # 16,17
|
qr/(?!:www.example.com)/, '!127.0.0.0/29', # 16,17
|
||||||
'!127.0.0.1-10', qr/(?!:localhost)/, # 18,19
|
'!127.0.0.1-10', qr/(?!:localhost)/, # 18,19
|
||||||
|
|
||||||
'op:and', # 20
|
'op:and', # 20
|
||||||
|
'group:groupreftest', # 21
|
||||||
|
'!group:groupreftest', # 22
|
||||||
);
|
);
|
||||||
|
|
||||||
# name, ipv4, ipv6, v4 prefix, v6 prefix
|
# name, ipv4, ipv6, v4 prefix, v6 prefix
|
||||||
@@ -88,6 +93,12 @@ ok(check_acl('127.0.0.1',[@conf[9,0,20]]), 'AND: !prefix, name');
|
|||||||
ok(check_acl('127.0.0.1',[@conf[7,11,0,20]]), 'AND: !prefix, !range, name');
|
ok(check_acl('127.0.0.1',[@conf[7,11,0,20]]), 'AND: !prefix, !range, name');
|
||||||
ok(check_acl('127.0.0.1',[@conf[9,13,16,0,20]]), 'AND: !prefix, !range, !regexp, name');
|
ok(check_acl('127.0.0.1',[@conf[9,13,16,0,20]]), 'AND: !prefix, !range, !regexp, name');
|
||||||
|
|
||||||
|
is(check_acl('192.0.2.1',[$conf[22]]), 1, '!missing group ref');
|
||||||
|
is(check_acl('192.0.2.1',[$conf[21]]), 0, 'failed missing group ref');
|
||||||
|
setting('host_groups')->{'groupreftest'} = ['192.0.2.1'];
|
||||||
|
is(check_acl('192.0.2.1',[$conf[21]]), 1, 'group ref');
|
||||||
|
is(check_acl('192.0.2.1',[$conf[22]]), 0, 'failed !missing group ref');
|
||||||
|
|
||||||
# device property
|
# device property
|
||||||
# negated device property
|
# negated device property
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user