|
| 1 | +package pf::Switch::Ruckus::Unleashed; |
| 2 | + |
| 3 | +=head1 NAME |
| 4 | +
|
| 5 | +pf::Switch::Ruckus::Unleashed |
| 6 | +
|
| 7 | +=head1 SYNOPSIS |
| 8 | +
|
| 9 | +Implements methods to manage Ruckus Unleashed AP |
| 10 | +
|
| 11 | +=head1 BUGS AND LIMITATIONS |
| 12 | +
|
| 13 | +=cut |
| 14 | + |
| 15 | +use strict; |
| 16 | +use warnings; |
| 17 | + |
| 18 | +use base ('pf::Switch::Ruckus::SmartZone'); |
| 19 | + |
| 20 | +use pf::constants; |
| 21 | +use pf::util; |
| 22 | +use pf::util::wpa; |
| 23 | +use pf::node; |
| 24 | +use pf::config qw ( |
| 25 | + $WEBAUTH_WIRELESS |
| 26 | +); |
| 27 | +use pf::log; |
| 28 | + |
| 29 | +sub description { 'Ruckus Unleashed' } |
| 30 | +use pf::SwitchSupports qw( |
| 31 | + WirelessMacAuth |
| 32 | +); |
| 33 | + |
| 34 | +=over |
| 35 | +
|
| 36 | +=item supportsWebFormRegistration |
| 37 | +
|
| 38 | +Will be activated only if HTTP is selected as a deauth method |
| 39 | +
|
| 40 | +=cut |
| 41 | + |
| 42 | +sub supportsWebFormRegistration { |
| 43 | + my ($self) = @_; |
| 44 | + return $TRUE; |
| 45 | +} |
| 46 | + |
| 47 | +=item parseExternalPortalRequest |
| 48 | +
|
| 49 | +Parse external portal request using URI and it's parameters then return an hash reference with the appropriate parameters |
| 50 | +
|
| 51 | +See L<pf::web::externalportal::handle> |
| 52 | +
|
| 53 | +=cut |
| 54 | + |
| 55 | +sub parseExternalPortalRequest { |
| 56 | + my ( $self, $r, $req ) = @_; |
| 57 | + my $logger = $self->logger; |
| 58 | + |
| 59 | + # Using a hash to contain external portal parameters |
| 60 | + my %params = (); |
| 61 | + |
| 62 | + %params = ( |
| 63 | + client_mac => clean_mac($req->param('client_mac')), |
| 64 | + client_ip => defined($req->param('uip')) ? $req->param('uip') : undef, |
| 65 | + ssid => $req->param('ssid'), |
| 66 | + redirect_url => $req->param('url'), |
| 67 | + switch_id => $req->param('sip'), |
| 68 | + switch_mac => clean_mac($req->param('mac')), |
| 69 | + synchronize_locationlog => $TRUE, |
| 70 | + connection_type => $WEBAUTH_WIRELESS, |
| 71 | + ); |
| 72 | + |
| 73 | + return \%params; |
| 74 | +} |
| 75 | + |
| 76 | +sub getAcceptForm { |
| 77 | + my ( $self, $mac, $destination_url, $portalSession ) = @_; |
| 78 | + my $logger = $self->logger; |
| 79 | + $logger->debug("Creating web release form"); |
| 80 | + |
| 81 | + my $node = node_view($mac); |
| 82 | + my $last_ssid = $node->{last_ssid}; |
| 83 | + $mac =~ s/:/-/g; |
| 84 | + my $html_form = qq[ |
| 85 | + <form name="weblogin_form" data-autosubmit="1000" method="POST" action="https://unleashed.ruckuswireless.com:9998/login"> |
| 86 | + <input type="hidden" name="username" value="$mac"> |
| 87 | + <input type="hidden" name="password" value="$mac"> |
| 88 | + </form> |
| 89 | + <script src="/content/autosubmit.js" type="text/javascript"></script> |
| 90 | + ]; |
| 91 | + |
| 92 | + $logger->debug("Generated the following html form : ".$html_form); |
| 93 | + return $html_form; |
| 94 | +} |
| 95 | +sub find_user_by_psk { |
| 96 | + my ($self, $radius_request, $args) = @_; |
| 97 | + my $pid; |
| 98 | + if($radius_request->{"Ruckus-DPSK-Cipher"} != 4) { |
| 99 | + get_logger->error("Ruckus-DPSK-Cipher isn't for WPA2 that uses AES and HMAC-SHA1. This isn't supported by this module."); |
| 100 | + return $pid; |
| 101 | + } |
| 102 | + |
| 103 | + my $ssid = $radius_request->{'Ruckus-SSID'}; |
| 104 | + my $bssid = pack("H*", sprintf("%v02x", $radius_request->{"Ruckus-BSSID"}) =~ s/\.//rg); |
| 105 | + my $username = pack("H*", $radius_request->{'User-Name'}); |
| 106 | + my $anonce = pack('H*', sprintf("%v02x",$radius_request->{'Ruckus-DPSK-Anonce'}) =~ s/\.//rg); |
| 107 | + my $snonce = pf::util::wpa::snonce_from_eapol_key_frame(pack("H*",sprintf("%v02x",$radius_request->{"Ruckus-DPSK-EAPOL-Key-Frame"}) =~ s/\.//rg)); |
| 108 | + my $eapol_key_frame = pack("H*", sprintf("%v02x",$radius_request->{"Ruckus-DPSK-EAPOL-Key-Frame"}) =~ s/\.//rg); |
| 109 | + my $cache = $self->cache; |
| 110 | + # Try first the pid of the mac address |
| 111 | + if (exists $args->{'owner'} && $args->{'owner'}->{'pid'} ne "" && exists $args->{'owner'}->{'psk'} && defined $args->{'owner'}->{'psk'} && $args->{'owner'}->{'psk'} ne "") { |
| 112 | + if (check_if_radius_request_psk_matches($cache, $radius_request, $args->{'owner'}->{'psk'}, $ssid, $bssid, $username, $anonce, $snonce, $eapol_key_frame)) { |
| 113 | + get_logger->info("PSK matches the pid associated with the mac ".$args->{'owner'}->{'pid'}); |
| 114 | + return $args->{'owner'}->{'pid'}; |
| 115 | + } |
| 116 | + } |
| 117 | + |
| 118 | + my ($status, $iter) = pf::dal::person->search( |
| 119 | + -where => { |
| 120 | + psk => {'!=' => [-and => '', undef]}, |
| 121 | + }, |
| 122 | + -columns => [qw(pid psk)], |
| 123 | + -no_default_join => 1, |
| 124 | + ); |
| 125 | + |
| 126 | + while (my $person = $iter->next) { |
| 127 | + get_logger->debug("User ".$person->{pid}." has a PSK. Checking if it matches the one in the packet"); |
| 128 | + if (check_if_radius_request_psk_matches($cache, $radius_request, $person->{psk}, $ssid, $bssid, $username, $anonce, $snonce, $eapol_key_frame)) { |
| 129 | + get_logger->info("PSK matches the one of ".$person->{pid}); |
| 130 | + $pid = $person->{pid}; |
| 131 | + last; |
| 132 | + } |
| 133 | + } |
| 134 | + return $pid; |
| 135 | +} |
| 136 | + |
| 137 | + |
| 138 | +=back |
| 139 | +
|
| 140 | +=head1 AUTHOR |
| 141 | +
|
| 142 | + |
| 143 | +
|
| 144 | +=head1 COPYRIGHT |
| 145 | +
|
| 146 | +Copyright (C) 2005-2022 Inverse inc. |
| 147 | +
|
| 148 | +=head1 LICENSE |
| 149 | +
|
| 150 | +This program is free software; you can redistribute it and/or |
| 151 | +modify it under the terms of the GNU General Public License |
| 152 | +as published by the Free Software Foundation; either version 2 |
| 153 | +of the License, or (at your option) any later version. |
| 154 | +
|
| 155 | +This program is distributed in the hope that it will be useful, |
| 156 | +but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 157 | +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 158 | +GNU General Public License for more details. |
| 159 | +
|
| 160 | +You should have received a copy of the GNU General Public License |
| 161 | +along with this program; if not, write to the Free Software |
| 162 | +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, |
| 163 | +USA. |
| 164 | +
|
| 165 | +=cut |
| 166 | + |
| 167 | +1; |
0 commit comments