Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding the Downloadable and Dynamic ACL enforcement to FortiSwitch #8529

Open
wants to merge 4 commits into
base: devel
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 103 additions & 1 deletion lib/pf/Switch/Fortinet/FortiSwitchOS_v7_x.pm
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use pf::accounting qw(node_accounting_dynauth_attr);
use pf::config qw(
$WIRED_802_1X
$WIRED_MAC_AUTH
%ConfigRoles
);

use base ('pf::Switch::Fortinet');
Expand All @@ -41,7 +42,8 @@ sub description { 'FortiSwitchOS v7.x' }
use pf::SwitchSupports qw(
WiredMacAuth
WiredDot1x
~AccessListBasedEnforcement
AccessListBasedEnforcement
RoleBasedEnforcement
);

=head2 wiredeauthTechniques
Expand Down Expand Up @@ -102,6 +104,106 @@ sub deauthenticateMacDefault {
);
}

=head2 returnRadiusAccessAccept

Prepares the RADIUS Access-Accept reponse for the network device.

Overrides the default implementation to add the dynamic acls

=cut

sub returnRadiusAccessAccept {
my ($self, $args) = @_;
my $logger = $self->logger;
$args->{'unfiltered'} = $TRUE;
my @super_reply = @{$self->SUPER::returnRadiusAccessAccept($args)};
my $status = shift @super_reply;
my %radius_reply = @super_reply;
my $radius_reply_ref = \%radius_reply;
return [$status, %$radius_reply_ref] if($status == $RADIUS::RLM_MODULE_USERLOCK);
my @acls = defined($radius_reply_ref->{'NAS-Filter-Rule'}) ? @{$radius_reply_ref->{'NAS-Filter-Rule'}} : ();

if ( isenabled($self->{_AccessListMap}) && $self->supportsAccessListBasedEnforcement ){
if( defined($args->{'user_role'}) && $args->{'user_role'} ne "" && defined(my $access_list = $self->getAccessListByName($args->{'user_role'}, $args->{mac})) && !($self->usePushACLs && exists $ConfigRoles{$args->{'user_role'}} )){
if ($access_list) {
while($access_list =~ /([^\n]+)\n?/g){
my ($test, $formated_acl) = $self->returnAccessListAttribute('',$1);
if ($test) {
push(@acls, $formated_acl);
$logger->info("(".$self->{'_id'}.") Adding access list : $formated_acl to the RADIUS reply");
}
}
$logger->info("(".$self->{'_id'}.") Added access lists to the RADIUS reply.");
} else {
$logger->info("(".$self->{'_id'}.") No access lists defined for this role ".$args->{'user_role'});
}
}
}

$radius_reply_ref->{'NAS-Filter-Rule'} = \@acls;

my $filter = pf::access_filter::radius->new;
my $rule = $filter->test('returnRadiusAccessAccept', $args);
($radius_reply_ref, $status) = $filter->handleAnswerInRule($rule,$args,$radius_reply_ref);
return [$status, %$radius_reply_ref];
}

=head2 returnInAccessListAttribute

Returns the attribute to use when pushing an input ACL using RADIUS

=cut

sub returnInAccessListAttribute {
my ($self) = @_;
return '';
}

=head2 returnOutAccessListAttribute

Returns the attribute to use when pushing an output ACL using RADIUS

=cut

sub returnOutAccessListAttribute {
my ($self) = @_;
return '';
}

=head2 returnAccessListAttribute

Returns the attribute to use when pushing an ACL using RADIUS

=cut

sub returnAccessListAttribute {
my ($self, $acl_num, $acl) = @_;
if ($acl =~ /^out\|(.*)/) {
if ($self->supportsOutAcl) {
return $TRUE, $self->returnOutAccessListAttribute.$acl_num.$1;
} else {
return $FALSE, '';
}
} elsif ($acl =~ /^in\|(.*)/) {
return $TRUE, $self->returnInAccessListAttribute.$acl_num.$1;
} else {
return $TRUE, $self->returnInAccessListAttribute.$acl_num.$acl;
}
}


=head2 returnRoleAttribute

What RADIUS Attribute (usually VSA) should the role be returned into.

=cut

sub returnRoleAttribute {
my ($self) = @_;

return 'Filter-Id';
}

=head2 getVersion

return a constant since there is no api for this
Expand Down