Skip to content

Commit

Permalink
Fixed deauth on Ruckus-Unleashed
Browse files Browse the repository at this point in the history
  • Loading branch information
fdurand committed Jan 24, 2025
1 parent b107da2 commit c599fdb
Showing 1 changed file with 117 additions and 1 deletion.
118 changes: 117 additions & 1 deletion lib/pf/Switch/Ruckus/Unleashed.pm
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ use pf::config qw (
$WEBAUTH_WIRELESS
);
use pf::log;
use pf::util::radius qw(perform_disconnect);
use Try::Tiny;

sub description { 'Ruckus Unleashed' }
use pf::SwitchSupports qw(
Expand All @@ -44,6 +46,121 @@ sub supportsWebFormRegistration {
return $TRUE;
}

=item deauthTechniques
Return the reference to the deauth technique or the default deauth technique.
=cut

sub deauthTechniques {
my ($self, $method, $connection_type) = @_;
my $logger = $self->logger;
my $default = $SNMP::RADIUS;
my %tech = (
$SNMP::RADIUS => 'deauthenticateMacRadius',
);

if (!defined($method) || !defined($tech{$method})) {
$method = $default;
}
return $method,$tech{$method};
}

=item deauthenticateMacDefault
De-authenticate a MAC address from wireless network (including 802.1x).
New implementation using RADIUS Disconnect-Request.
=cut

sub deauthenticateMacRadius {
my ( $self, $mac, $is_dot1x ) = @_;
my $logger = $self->logger;

if ( !$self->isProductionMode() ) {
$logger->info("not in production mode... we won't perform deauthentication");
return 1;
}

$logger->debug("deauthenticate $mac using RADIUS Disconnect-Request deauth method");
return $self->radiusDisconnect($mac);
}


=item radiusDisconnect
Sends a RADIUS Disconnect-Request to the NAS with the MAC as the Calling-Station-Id to disconnect.
Optionally you can provide other attributes as an hashref.
Uses L<pf::util::radius> for the low-level RADIUS stuff.
=cut

# TODO consider whether we should handle retries or not?
sub radiusDisconnect {
my ($self, $mac, $add_attributes_ref) = @_;
my $logger = $self->logger;

# initialize
$add_attributes_ref = {} if (!defined($add_attributes_ref));

if (!defined($self->{'_radiusSecret'})) {
$logger->warn(
"Unable to perform RADIUS Disconnect-Request on $self->{'_ip'}: RADIUS Shared Secret not configured"
);
return;
}

$logger->info("deauthenticating $mac");

# Where should we send the RADIUS Disconnect-Request?
# to network device by default
my $send_disconnect_to = $self->{'_ip'};
# but if controllerIp is set, we send there
if (defined($self->{'_controllerIp'}) && $self->{'_controllerIp'} ne '') {
$logger->info("controllerIp is set, we will use controller $self->{_controllerIp} to perform deauth");
$send_disconnect_to = $self->{'_controllerIp'};
}
# allowing client code to override where we connect with NAS-IP-Address
$send_disconnect_to = $add_attributes_ref->{'NAS-IP-Address'}
if (defined($add_attributes_ref->{'NAS-IP-Address'}));

my $response;
try {
my $connection_info = $self->radius_deauth_connection_info($send_disconnect_to);

# transforming MAC to the expected format 00-11-22-33-CA-FE
$mac = uc($mac);
$mac =~ s/:/-/g;

# Standard Attributes
my $attributes_ref = {
'Calling-Station-Id' => $mac,
};

# merging additional attributes provided by caller to the standard attributes
$attributes_ref = { %$attributes_ref, %$add_attributes_ref };

$response = perform_disconnect($connection_info, $attributes_ref);
} catch {
chomp;
$logger->warn("Unable to perform RADIUS Disconnect-Request: $_");
$logger->error("Wrong RADIUS secret or unreachable network device...") if ($_ =~ /^Timeout/);
};
return if (!defined($response));

return $TRUE if ( ($response->{'Code'} eq 'Disconnect-ACK') || ($response->{'Code'} eq 'CoA-ACK') );

$logger->warn(
"Unable to perform RADIUS Disconnect-Request."
. ( defined($response->{'Code'}) ? " $response->{'Code'}" : 'no RADIUS code' ) . ' received'
. ( defined($response->{'Error-Cause'}) ? " with Error-Cause: $response->{'Error-Cause'}." : '' )
);
return;
}

=item parseExternalPortalRequest
Parse external portal request using URI and it's parameters then return an hash reference with the appropriate parameters
Expand Down Expand Up @@ -135,7 +252,6 @@ Generates the RADIUS attribute value for Ruckus-DPSK given an SSID name and the

sub generate_dpsk_attribute_value {
my ($self, $ssid, $dpsk) = @_;

my $pbkdf2 = Crypt::PBKDF2->new(
iterations => 4096,
output_len => 32,
Expand Down

0 comments on commit c599fdb

Please sign in to comment.