From b9720b333236286f14da8663e8e6a334a27f65a5 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Fri, 6 Sep 2013 08:54:19 -0400 Subject: [PATCH 001/369] Close tag in advanced search of nodes --- html/pfappserver/root/node/advanced_search.tt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/html/pfappserver/root/node/advanced_search.tt b/html/pfappserver/root/node/advanced_search.tt index d249918fdb19..d150462a8e06 100644 --- a/html/pfappserver/root/node/advanced_search.tt +++ b/html/pfappserver/root/node/advanced_search.tt @@ -53,7 +53,7 @@ [% l(node.status) %] [% node.mac %] [% node.computername %] - [% node.pid %] + [% node.pid %] [% IF node.last_ssid %] [% END %][% node.last_ip %] [% node.dhcp_fingerprint %] [% node.category %] From f9a2c2c5075b2a154f69b70a96ecc7b343786601 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Fri, 6 Sep 2013 12:27:03 -0400 Subject: [PATCH 002/369] Improve error messages in RADIUS modules --- NEWS.asciidoc | 18 ++++++++++++ lib/pf/radius/soapclient.pm | 57 +++++++++++++++++++++---------------- raddb/packetfence-soh.pm | 8 ++++-- raddb/packetfence.pm | 5 +++- 4 files changed, 61 insertions(+), 27 deletions(-) diff --git a/NEWS.asciidoc b/NEWS.asciidoc index a5f5b1341ec3..b5779c2e6b20 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -11,6 +11,24 @@ This is a list of noteworthy changes across releases. For more details and developer visible changes see the ChangeLog file. For a list of compatibility related changes see the UPGRADE.asciidoc file. +Version 4.x.y released on 2013-MM-DD +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +New Features +++++++++++++ + +* + +Enhancements +++++++++++++ + +* Improved error messages in RADIUS modules + +Bug Fixes ++++++++++ + +* + Version 4.0.6 released on 2013-09-05 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/lib/pf/radius/soapclient.pm b/lib/pf/radius/soapclient.pm index e4ca1d3002dd..8516767041c9 100644 --- a/lib/pf/radius/soapclient.pm +++ b/lib/pf/radius/soapclient.pm @@ -1,4 +1,5 @@ package pf::radius::soapclient; + =head1 NAME pf::radius::soapclient add documentation @@ -13,38 +14,46 @@ pf::radius::soapclient use strict; use warnings; -# Configuration parameter -use constant SOAP_PORT => '9090'; #TODO: See note1 -use constant API_URI => 'https://www.packetfence.org/PFAPI'; # don't change this unless you know what you are doing + +use HTML::Entities; +use Log::Log4perl; use WWW::Curl::Easy; use XML::Simple; -use HTML::Entities; + use base qw(Exporter); our @EXPORT = qw(send_soap_request build_soap_request); +# Configuration parameter +use constant SOAP_PORT => '9090'; #TODO: See note1 +use constant API_URI => 'https://www.packetfence.org/PFAPI'; # don't change this unless you know what you are doing + sub send_soap_request { my ($function,$data) = @_; my $response; - eval { - my $request = build_soap_request($function,$data); - my $curl = WWW::Curl::Easy->new; - my $response_body; - $curl->setopt(CURLOPT_HEADER, 0); - $curl->setopt(CURLOPT_URL, 'http://127.0.0.1:' . SOAP_PORT); # TODO: See note1 - # $curl->setopt(CURLOPT_URL, 'http://127.0.0.1:' . $Config{'ports'}{'soap'}); # TODO: See note1 - $curl->setopt(CURLOPT_HTTPHEADER, ['Content-Type: text/xml; charset=UTF-8']); - $curl->setopt(CURLOPT_POSTFIELDS, $request); - $curl->setopt(CURLOPT_WRITEDATA, \$response_body); - - # Starts the actual request - my $curl_return_code = $curl->perform; - - # Looking at the results... - if ( $curl_return_code == 0 ) { - my $xml = new XML::Simple; - $response = $xml->XMLin($response_body, NoAttr => 1); - } - }; + + my $request = build_soap_request($function,$data); + my $curl = WWW::Curl::Easy->new; + my $response_body; + $curl->setopt(CURLOPT_HEADER, 0); + $curl->setopt(CURLOPT_URL, 'http://127.0.0.1:' . SOAP_PORT); # TODO: See note1 +# $curl->setopt(CURLOPT_URL, 'http://127.0.0.1:' . $Config{'ports'}{'soap'}); # TODO: See note1 + $curl->setopt(CURLOPT_HTTPHEADER, ['Content-Type: text/xml; charset=UTF-8']); + $curl->setopt(CURLOPT_POSTFIELDS, $request); + $curl->setopt(CURLOPT_WRITEDATA, \$response_body); + + # Starts the actual request + my $curl_return_code = $curl->perform; + + # Looking at the results... + if ( $curl_return_code == 0 ) { + my $xml = new XML::Simple; + $response = $xml->XMLin($response_body, NoAttr => 1); + } + else { + my $msg = "An error occured while sending a SOAP request: $curl_return_code ".$curl->strerror($curl_return_code)." ".$curl->errbuf; + die $msg; + } + return $response; } diff --git a/raddb/packetfence-soh.pm b/raddb/packetfence-soh.pm index 3ad4ddbbc6fa..e78bf19c53fc 100644 --- a/raddb/packetfence-soh.pm +++ b/raddb/packetfence-soh.pm @@ -61,8 +61,8 @@ the only callback available inside an SoH virtual server. sub authorize { my $radius_return_code = $RADIUS::RLM_MODULE_REJECT; eval { - my $data = send_soap_request("soh_authorize",\%RAD_REQUEST); - if ( $data) { + my $data = send_soap_request("soh_authorize", \%RAD_REQUEST); + if ($data) { my $elements = $data->{'soap:Body'}->{'soh_authorizeResponse'}->{'soapenc:Array'}->{'item'}; @@ -85,6 +85,10 @@ sub authorize { # $Data::Dumper::Terse = 1; $Data::Dumper::Indent = 0; # pretty output for rad logs # &radiusd::radlog($RADIUS::L_DBG, "StatementOfHealth COMPLETE REPLY: ". Dumper(\%RAD_REPLY)); }; + if ($@) { + &radiusd::radlog($RADIUS::L_ERR, "An error occurred while processing the SoH authorize SOAP request: $@"); + } + return $radius_return_code; } diff --git a/raddb/packetfence.pm b/raddb/packetfence.pm index 2623a5791895..0e5c60bc6d57 100644 --- a/raddb/packetfence.pm +++ b/raddb/packetfence.pm @@ -97,7 +97,7 @@ sub post_auth { } my $data = send_soap_request("radius_authorize",\%RAD_REQUEST); - if($data) { + if ($data) { my $elements = $data->{'soap:Body'}->{'radius_authorizeResponse'}->{'soapenc:Array'}->{'item'}; @@ -139,6 +139,9 @@ sub post_auth { # $Data::Dumper::Terse = 1; $Data::Dumper::Indent = 0; # pretty output for rad logs # &radiusd::radlog($RADIUS::L_DBG, "PacketFence COMPLETE REPLY: ". Dumper(\%RAD_REPLY)); }; + if ($@) { + &radiusd::radlog($RADIUS::L_ERR, "An error occurred while processing the authorize SOAP request: $@"); + } return $radius_return_code; } From 52aec6646d380c4c032b27c9bfd2289bf6363415 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Fri, 6 Sep 2013 13:18:07 -0400 Subject: [PATCH 003/369] Syntax cleanup --- conf/log.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/log.conf b/conf/log.conf index ede8d557e4ba..d43e0860fc6c 100644 --- a/conf/log.conf +++ b/conf/log.conf @@ -1,7 +1,7 @@ ### Root/Parent (PacketFence) logger ### # Will log everything (even categories defined to log in another appender) unless # specified using the additivity parameter -log4perl.rootLogger=INFO, LOGFILE +log4perl.rootLogger = INFO, LOGFILE ### Catalyst logger ### # Used to separate Catalyst framework logs in a different log file From c0e8d4efe86c7699b3242cf53474dc98c5f3ad49 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Fri, 6 Sep 2013 15:37:36 -0400 Subject: [PATCH 004/369] Will clean the mac before try to validate it --- lib/pf/web/gaming.pm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/pf/web/gaming.pm b/lib/pf/web/gaming.pm index d8cf30d627da..fb25cc340bf2 100644 --- a/lib/pf/web/gaming.pm +++ b/lib/pf/web/gaming.pm @@ -26,6 +26,7 @@ use pf::web; use pf::authentication; use pf::Authentication::constants; +use List::MoreUtils qw(any); Readonly our $GAMING_LOGIN_TEMPLATE => 'gaming-login.html'; Readonly our $GAMING_LANDING_TEMPLATE => 'gaming-landing.html'; @@ -117,10 +118,8 @@ sub register_node { sub is_gaming_mac { my ($mac) = @_; $mac =~ s/O/0/i; - foreach my $oui (@GAMING_OUI) { - return 1 if $mac =~ /^\Q$oui\E/i; - } - return 0; + $mac = clean_mac($mac); + return any { $mac =~ /^\Q$_\E/i } @GAMING_OUI; } sub _sanitize_and_register { From 31fbf9feff2d4fdfb3948ce646655f64b7282fd0 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 9 Sep 2013 11:19:34 -0400 Subject: [PATCH 005/369] Avoid an undefined compare --- lib/pf/IniFiles.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pf/IniFiles.pm b/lib/pf/IniFiles.pm index 4678d866d253..39894c6a7247 100644 --- a/lib/pf/IniFiles.pm +++ b/lib/pf/IniFiles.pm @@ -158,7 +158,8 @@ sub IsExpired { my $imported = $self->{imported}; $imported_expired = $imported->IsExpired() if defined $imported; } - return ($imported_expired || ($self->GetLastModTimestamp != $self->GetCurrentModTimestamp )); + my $last_mod_timestamp = $self->GetLastModTimestamp; + return ($imported_expired || (defined $last_mod_timestamp && $last_mod_timestamp != $self->GetCurrentModTimestamp )); } =head2 SetLastModTimestamp From 1d6967dda0b68ef5f531024e08f4e93c554baa3a Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 9 Sep 2013 11:41:02 -0400 Subject: [PATCH 006/369] iptables will only stop/start/restart for pf service not all of them --- bin/pfcmd.pl | 6 +++--- lib/pf/services.pm | 24 ++++++++++++++---------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/bin/pfcmd.pl b/bin/pfcmd.pl index 38c1d22d89ce..8782d9d8e164 100755 --- a/bin/pfcmd.pl +++ b/bin/pfcmd.pl @@ -1269,7 +1269,7 @@ sub service { } } if ( $nb_running_services == 0 ) { - if(isenabled($Config{services}{iptables})) { + if(isenabled($Config{services}{iptables}) && $service eq 'pf') { $logger->info("saving current iptables to var/iptables.bak"); require pf::inline::custom; my $iptables = pf::inline::custom->new(); @@ -1285,7 +1285,7 @@ sub service { require pf::os; pf::os::import_dhcp_fingerprints(); pf::services::read_violations_conf(); - if(isenabled($Config{services}{iptables})) { + if(isenabled($Config{services}{iptables}) && $service eq 'pf') { print "iptables|$command\n"; require pf::inline::custom; my $iptables = pf::inline::custom->new(); @@ -1314,7 +1314,7 @@ sub service { } } if ( $nb_running_services == 0 ) { - if(isenabled($Config{services}{iptables})) { + if(isenabled($Config{services}{iptables}) && $service eq 'pf') { require pf::inline::custom; my $iptables = pf::inline::custom->new(); my $technique = $iptables->{_technique}; diff --git a/lib/pf/services.pm b/lib/pf/services.pm index d01796418c7f..ee5daf00036f 100644 --- a/lib/pf/services.pm +++ b/lib/pf/services.pm @@ -259,11 +259,13 @@ sub service_ctl { $pid = 0; if (-e "$install_dir/var/run/$daemon.pid") { chomp( $pid = `cat $install_dir/var/run/$daemon.pid`); - my $ppt = new Proc::ProcessTable; - my $proc = first { defined($_) } grep { $_->pid == $pid } @{ $ppt->table }; - if (!defined($proc)) { - unlink( $install_dir . "/var/run/$binary.pid" ); - return(0); + if($pid ne '' ) { + my $ppt = new Proc::ProcessTable; + my $proc = first { defined($_) } grep { $_->pid == $pid } @{ $ppt->table }; + if (!defined($proc)) { + unlink( $install_dir . "/var/run/$binary.pid" ); + return(0); + } } } return ($pid); @@ -273,11 +275,13 @@ sub service_ctl { if (defined $monitor_int) { if (-e "$install_dir/var/run/${daemon}_${monitor_int}.pid") { chomp( $pid = `cat $install_dir/var/run/${daemon}_${monitor_int}.pid`); - my $ppt = new Proc::ProcessTable; - my $proc = first { defined($_) } grep { $_->pid == $pid } @{ $ppt->table }; - if (!defined($proc)) { - unlink( $install_dir . "/var/run/${daemon}_${monitor_int}.pid" ); - return(0); + if($pid ne '' ) { + my $ppt = new Proc::ProcessTable; + my $proc = first { defined($_) } grep { $_->pid == $pid } @{ $ppt->table }; + if (!defined($proc)) { + unlink( $install_dir . "/var/run/${daemon}_${monitor_int}.pid" ); + return(0); + } } } } From e77455bf546ca22476a7e5eeb7f29a72e6249561 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 9 Sep 2013 12:03:48 -0400 Subject: [PATCH 007/369] Added help command for pftest --- lib/pf/cmd/roles/show_help.pm | 6 +++- lib/pf/pftest.pm | 5 +++ lib/pf/pftest/help.pm | 65 +++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 lib/pf/pftest/help.pm diff --git a/lib/pf/cmd/roles/show_help.pm b/lib/pf/cmd/roles/show_help.pm index 2bf3eb5f6a33..8c115d4e426c 100644 --- a/lib/pf/cmd/roles/show_help.pm +++ b/lib/pf/cmd/roles/show_help.pm @@ -22,7 +22,11 @@ use Role::Tiny; sub showHelp { my ($self,$package) = @_; $package ||= ref($self) || $self; - pod2usage( { -message => $self->{help_msg} , -input => pod_where({-inc => 1}, $package) } ); + my $location = pod_where({-inc => 1}, $package); + pod2usage({ + -message => $self->{help_msg} , + -input => $location + }); } diff --git a/lib/pf/pftest.pm b/lib/pf/pftest.pm index 94a1bf40517d..b8b76ce4da65 100644 --- a/lib/pf/pftest.pm +++ b/lib/pf/pftest.pm @@ -12,6 +12,8 @@ pftest [options] authentication | checks authentication sources mysql | runs the mysql tuner +Please view "pftest.pl help " for details on each option + =head1 DESCRIPTION pf::pftest @@ -21,6 +23,9 @@ pf::pftest use strict; use warnings; use base qw(pf::cmd::subcmd); +use pf::pftest::help; #Preload help + +sub helpActionCmd { "pf::pftest::help" } =head1 AUTHOR diff --git a/lib/pf/pftest/help.pm b/lib/pf/pftest/help.pm new file mode 100644 index 000000000000..bf69251b4073 --- /dev/null +++ b/lib/pf/pftest/help.pm @@ -0,0 +1,65 @@ +package pf::pftest::help; +=head1 NAME + +pf::pftest::help add documentation + +=cut + +=head1 DESCRIPTION + +pf::pftest::help + +=cut + +use strict; +use warnings; +use Pod::Find qw(pod_where); + +use base qw(pf::cmd::help); + +sub run { + my ($self) = @_; + my ($cmd) = $self->args; + if(!defined $cmd || $cmd eq 'help') { + return $self->SUPER::run; + } + my $package = "pf::pftest::${cmd}"; + my $location = pod_where( { -inc => 1 }, $package); + if ($location) { + return $self->showHelp("pf::pftest::${cmd}"); + } + $self->{parentCmd}->{help_msg} = "unknown command \"$cmd\""; + return $self->SUPER::run; +} + +=head1 AUTHOR + +Inverse inc. + +Minor parts of this file may have been contributed. See CREDITS. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + From ac425315a83b8734c1d6b2c6514979c0573cb0e0 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 9 Sep 2013 12:39:32 -0400 Subject: [PATCH 008/369] Refactored pf::pftest::help to pf::cmd::help --- lib/pf/pftest/help.pm | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/lib/pf/pftest/help.pm b/lib/pf/pftest/help.pm index bf69251b4073..05ed96887a09 100644 --- a/lib/pf/pftest/help.pm +++ b/lib/pf/pftest/help.pm @@ -13,25 +13,8 @@ pf::pftest::help use strict; use warnings; -use Pod::Find qw(pod_where); - use base qw(pf::cmd::help); -sub run { - my ($self) = @_; - my ($cmd) = $self->args; - if(!defined $cmd || $cmd eq 'help') { - return $self->SUPER::run; - } - my $package = "pf::pftest::${cmd}"; - my $location = pod_where( { -inc => 1 }, $package); - if ($location) { - return $self->showHelp("pf::pftest::${cmd}"); - } - $self->{parentCmd}->{help_msg} = "unknown command \"$cmd\""; - return $self->SUPER::run; -} - =head1 AUTHOR Inverse inc. From 936ca3fa40cca964e9c2b3a1d690b08fcb12c8c0 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 9 Sep 2013 12:42:24 -0400 Subject: [PATCH 009/369] Refactored pf::pftest::help to pf::cmd::help --- lib/pf/cmd/help.pm | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/pf/cmd/help.pm b/lib/pf/cmd/help.pm index 29ce37e6786b..c1aca46501db 100644 --- a/lib/pf/cmd/help.pm +++ b/lib/pf/cmd/help.pm @@ -16,10 +16,23 @@ A pf::cmd class that extracts the usage from the parentCmd use strict; use warnings; use base qw(pf::cmd); +use Pod::Find qw(pod_where); sub run { my ($self) = @_; - $self->{parentCmd}->showHelp; + my ($cmd) = $self->args; + my $parentCmd = $self->{parentCmd}; + if(!defined $cmd || $cmd eq 'help') { + return $parentCmd->showHelp; + } + my $base = ref($parentCmd) || $parentCmd; + my $package = "${base}::${cmd}"; + my $location = pod_where( { -inc => 1 }, $package); + if ($location) { + return $self->showHelp($package); + } + $parentCmd->{help_msg} = "unknown command \"$cmd\""; + return $parentCmd->showHelp; } =head1 AUTHOR From e88eb947b98323287dbec750d65b5ee062354314 Mon Sep 17 00:00:00 2001 From: Jean Raby Date: Mon, 9 Sep 2013 12:51:12 -0400 Subject: [PATCH 010/369] Remove dep on libterm-ansicolor-perl. This package doesn't exist. Term::ANSIColor is a core module. --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index 98204b35ab83..30fccefda8a5 100644 --- a/debian/control +++ b/debian/control @@ -88,7 +88,7 @@ Depends: ${misc:Depends}, vlan, make, # used by Captive Portal authentication modules libauthen-radius-perl, libauthen-krb5-simple-perl, # used by bin/pftest - libterm-ansicolor-perl, libio-interactive-perl, + libio-interactive-perl, # required for perl 5.12+ (made perl setuid optional) and most distros went without it packetfence-pfcmd-suid Description: PacketFence network registration / worm mitigation system From ad1bad3e105badbd3dc3858ea2700e8585b5f654 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 9 Sep 2013 22:09:37 -0400 Subject: [PATCH 011/369] Fixed issues with services not stopping --- lib/pf/services.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pf/services.pm b/lib/pf/services.pm index ee5daf00036f..f151c582637d 100644 --- a/lib/pf/services.pm +++ b/lib/pf/services.pm @@ -210,7 +210,7 @@ sub service_ctl { stopService($serv,$binary); } } else { - stopService($service,$binary); + stopService($daemon,$binary); } last CASE; }; From 91189ab48447085107be319ace23adc000d29a26 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 11 Sep 2013 09:42:37 -0400 Subject: [PATCH 012/369] Stop httpd services first to provide more time for them to shutdown --- lib/pf/services.pm | 79 +++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 50 deletions(-) diff --git a/lib/pf/services.pm b/lib/pf/services.pm index f151c582637d..95c7ffbca7ec 100644 --- a/lib/pf/services.pm +++ b/lib/pf/services.pm @@ -48,14 +48,13 @@ use pf::SwitchFactory; use pf::violation_config; use File::Slurp qw(read_file); -Readonly our @ALL_SERVICES => ( - 'pfdns', 'dhcpd', 'pfdetect', 'snort', 'suricata', 'radiusd', - 'httpd.webservices', 'httpd.admin', 'httpd.portal', 'snmptrapd', - 'pfsetvlan', 'pfdhcplistener', 'pfmon' +Readonly our @APACHE_SERVICES => ( + 'httpd.admin', 'httpd.webservices', 'httpd.portal' ); -Readonly our @APACHE_SERVICES => ( - 'httpd.webservices', 'httpd.admin', 'httpd.portal' +Readonly our @ALL_SERVICES => ( + @APACHE_SERVICES, 'pfdns', 'dhcpd', 'pfdetect', 'snort', 'suricata', 'radiusd', + 'snmptrapd', 'pfsetvlan', 'pfdhcplistener', 'pfmon' ); my $services = join("|", @ALL_SERVICES); @@ -225,7 +224,7 @@ sub service_ctl { $action eq "status" && do { my $pid; # -x: this causes the program to also return process id's of shells running the named scripts. - if (!( ($binary eq "pfdhcplistener") || ($daemon eq "httpd") || ($daemon eq "httpd.webservices") || ($daemon eq "httpd.admin") || ($daemon eq "httpd.portal") || ($daemon eq "snort") ) ) { + if (!( ($binary eq "pfdhcplistener") || ($daemon eq "httpd") || ($daemon eq "snort") ) ) { return getPidFromFile($daemon,$binary); } # Handle the pfdhcplistener case. Grab exact interfaces where pfdhcplistner should run, @@ -255,35 +254,10 @@ sub service_ctl { return (0); } } - elsif ($daemon =~ "httpd(.*)") { - $pid = 0; - if (-e "$install_dir/var/run/$daemon.pid") { - chomp( $pid = `cat $install_dir/var/run/$daemon.pid`); - if($pid ne '' ) { - my $ppt = new Proc::ProcessTable; - my $proc = first { defined($_) } grep { $_->pid == $pid } @{ $ppt->table }; - if (!defined($proc)) { - unlink( $install_dir . "/var/run/$binary.pid" ); - return(0); - } - } - } - return ($pid); - } elsif ($daemon =~ "snort") { $pid = 0; if (defined $monitor_int) { - if (-e "$install_dir/var/run/${daemon}_${monitor_int}.pid") { - chomp( $pid = `cat $install_dir/var/run/${daemon}_${monitor_int}.pid`); - if($pid ne '' ) { - my $ppt = new Proc::ProcessTable; - my $proc = first { defined($_) } grep { $_->pid == $pid } @{ $ppt->table }; - if (!defined($proc)) { - unlink( $install_dir . "/var/run/${daemon}_${monitor_int}.pid" ); - return(0); - } - } - } + $pid = getPidFromFile("${daemon}_${monitor_int}.pid",$binary); } return ($pid); } @@ -375,12 +349,12 @@ sub read_violations_conf { sub getPidFromFile { my ($daemon,$binary) = @_; my $logger = Log::Log4perl::get_logger('pf::services'); - my $pid; + my $pid = 0; my $pid_file = "$install_dir/var/run/$daemon.pid"; if (-e $pid_file) { chomp( $pid = read_file($pid_file) ); } - $pid = 0 if ( !$pid ); + $pid = 0 unless $pid; $logger->info("pidof -x $binary returned $pid"); if($pid && $pid =~ /^(.*)$/) { $pid = $1; @@ -433,21 +407,7 @@ sub stopService { if ( $service =~ /(dhcpd)/) { manage_Static_Route(); } - - my $maxWait = 10; - my $curWait = 0; - my $ppt; - my $proc = 0; - while ( ( ( $curWait < $maxWait ) - && ( service_ctl( $service, "status" ) ne "0" ) ) && defined($proc) ) - { - $ppt = new Proc::ProcessTable; - $proc = first { defined($_) } grep { $_->pid == $pid } @{ $ppt->table }; - $logger->info("Waiting for $binary to stop "); - sleep(2); - $curWait++; - } - if ( -e $install_dir . "/var/run/$binary.pid" ) { + if ( waitToShutdown($service, $pid) && -e $install_dir . "/var/run/$binary.pid" ) { $logger->info("Removing $install_dir/var/run/$binary.pid"); unlink( $install_dir . "/var/run/$binary.pid" ); } @@ -456,6 +416,25 @@ sub stopService { } +sub waitToShutdown { + my ($service, $pid) = @_; + my $logger = Log::Log4perl::get_logger('pf::services'); + my $maxWait = 10; + my $curWait = 0; + my $ppt; + my $proc = 0; + while ( ( ( $curWait < $maxWait ) + && ( service_ctl( $service, "status" ) ne "0" ) ) && defined($proc) ) + { + $ppt = new Proc::ProcessTable; + $proc = first { $_->pid == $pid } @{ $ppt->table }; + $logger->info("Waiting for $service to stop "); + sleep(2); + $curWait++; + } + return defined $proc; +} + =back From 3b2538793cd9a348c546bb35c361168e431bd457 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 11 Sep 2013 10:00:06 -0400 Subject: [PATCH 013/369] Display when iptables is stopping --- bin/pfcmd.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/pfcmd.pl b/bin/pfcmd.pl index 8782d9d8e164..13d052598a50 100755 --- a/bin/pfcmd.pl +++ b/bin/pfcmd.pl @@ -1315,6 +1315,7 @@ sub service { } if ( $nb_running_services == 0 ) { if(isenabled($Config{services}{iptables}) && $service eq 'pf') { + print "iptables|$command\n"; require pf::inline::custom; my $iptables = pf::inline::custom->new(); my $technique = $iptables->{_technique}; From f3c2ef95761d0f6ad9d087aa0c73854b50407629 Mon Sep 17 00:00:00 2001 From: lzammit Date: Wed, 11 Sep 2013 11:04:15 -0400 Subject: [PATCH 014/369] Update PacketFence_Administration_Guide.asciidoc update rpm forge package version --- docs/PacketFence_Administration_Guide.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/PacketFence_Administration_Guide.asciidoc b/docs/PacketFence_Administration_Guide.asciidoc index 989622605c70..cb6b7cdbc9e9 100644 --- a/docs/PacketFence_Administration_Guide.asciidoc +++ b/docs/PacketFence_Administration_Guide.asciidoc @@ -226,7 +226,7 @@ Install the proper repositories in `yum` so it can directly lookup for packages: .For RHEL 6.x / CentOS 6.x - # rpm -Uvh http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.2-2.el6.rf.`uname -m`.rpm + # rpm -Uvh http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.`uname -m`.rpm # rpm -Uvh http://download.fedoraproject.org/pub/epel/6/`uname -i`/epel-release-6-8.noarch.rpm # rpm -Uvh http://repo.openfusion.net/centos6-`uname -i`/openfusion-release-0.6.2-1.of.el6.noarch.rpm From 389b8db32e8a56906ddbfa3778f5376317af6189 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 22 Jul 2013 09:26:12 -0400 Subject: [PATCH 015/369] Added the ability save filter type switch --- html/pfappserver/lib/pfappserver/Form/Field/ProfileFilter.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/html/pfappserver/lib/pfappserver/Form/Field/ProfileFilter.pm b/html/pfappserver/lib/pfappserver/Form/Field/ProfileFilter.pm index 3219c27174ae..3b3dfb1d554a 100644 --- a/html/pfappserver/lib/pfappserver/Form/Field/ProfileFilter.pm +++ b/html/pfappserver/lib/pfappserver/Form/Field/ProfileFilter.pm @@ -45,6 +45,7 @@ has_field 'type' => options => [ {value => 'ssid', label => 'SSID'}, {value => 'vlan', label => 'VLAN'}, + {value => 'switch', label => 'SWITCH'}, ], ); From 51a62a16f994e54ebb03642a41a1412971a33fbb Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 22 Jul 2013 09:27:38 -0400 Subject: [PATCH 016/369] Added the ability to filter based off on last switch --- lib/pf/Portal/ProfileFactory.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pf/Portal/ProfileFactory.pm b/lib/pf/Portal/ProfileFactory.pm index eeda1db19bcf..dda980d22c2e 100644 --- a/lib/pf/Portal/ProfileFactory.pm +++ b/lib/pf/Portal/ProfileFactory.pm @@ -40,7 +40,7 @@ sub instantiate { # We apply portal profiles based on the SSID and VLAN, we check the last_ssid for the given MAC and try to match # a portal profile using the previously fetched filters. If no match, we instantiate the default portal profile. my $node_info = node_view($mac); - my @filter_ids = ((map { "$_:" . $node_info->{"last_$_"} } qw(ssid vlan)), @{$node_info}{'last_ssid','last_vlan'}); + my @filter_ids = ((map { "$_:" . $node_info->{"last_$_"} } qw(ssid vlan switch)), @{$node_info}{'last_ssid','last_vlan','last_switch'}); my $filtered_profile = first {exists $Profiles_Config{$_}} map { $Profile_Filters{$_} } From cf4ac4c3aad3ff4d33b8ada212b331a3c3eec9ad Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 11 Sep 2013 13:11:01 -0400 Subject: [PATCH 017/369] Updated NEWS file --- NEWS.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.asciidoc b/NEWS.asciidoc index b5779c2e6b20..d3c8f89c7d27 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -17,7 +17,7 @@ Version 4.x.y released on 2013-MM-DD New Features ++++++++++++ -* +* Profiles can be filter by switches Enhancements ++++++++++++ From a761ec4998b2f34ea86e30a99a6b7a230e33ee4d Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 11 Sep 2013 15:25:57 -0400 Subject: [PATCH 018/369] Clear an object internally when retreiving directly from chi --- lib/pf/config/cached.pm | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/pf/config/cached.pm b/lib/pf/config/cached.pm index 764a77954066..b95703662aca 100644 --- a/lib/pf/config/cached.pm +++ b/lib/pf/config/cached.pm @@ -529,12 +529,12 @@ sub _callPostReloadCallbacks { sub doCallbacks { my ($self,$file_reloaded,$cache_reloaded) = @_; - my $was_reloaded; - if($was_reloaded = $file_reloaded || $cache_reloaded) { - $self->_callReloadCallbacks if $was_reloaded; + if($file_reloaded || $cache_reloaded) { + get_logger()->trace("doing callbacks file_reloaded = " . ($file_reloaded ? 1 : 0) . " cache_reloaded = " . ($cache_reloaded ? 1 : 0)); + $self->_callReloadCallbacks; $self->_callFileReloadCallbacks if $file_reloaded; $self->_callCacheReloadCallbacks if $cache_reloaded; - $self->_callPostReloadCallbacks if $was_reloaded; + $self->_callPostReloadCallbacks; } } @@ -915,6 +915,8 @@ sub toHash { sub fromCacheUntainted { my ($self,$key) = @_; + my $cache = $self->cache; + $cache->l1_cache->remove($key); return untaint($self->cache->get($key)); } From 9c2dda37de33752eb2132b656974fd4ce31b8fd8 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 11 Sep 2013 15:27:07 -0400 Subject: [PATCH 019/369] move updating the profiles guest modes to the post reload callback --- lib/pf/authentication.pm | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/pf/authentication.pm b/lib/pf/authentication.pm index 5b952ace6036..a82c1562e5d3 100644 --- a/lib/pf/authentication.pm +++ b/lib/pf/authentication.pm @@ -209,21 +209,24 @@ sub readAuthenticationConfigFile { } $config->cache->set("authentication_lookup",\%authentication_lookup); $config->cache->set("authentication_sources",\@authentication_sources); - update_profiles_guest_modes($cached_profiles_config,"update_profiles_guest_modes"); }], -oncachereload => [ - on_cache_authentication_reload => sub { + on_cache_authentication_reload => sub { my ($config, $name) = @_; %authentication_lookup = %{$config->fromCacheUntainted("authentication_lookup")}; @authentication_sources = @{$config->fromCacheUntainted("authentication_sources")}; }, - ] + ], + -onpostreload => [ + on_post_authentication_reload => sub { + update_profiles_guest_modes($cached_profiles_config,"update_profiles_guest_modes"); + } + ], ); $cached_profiles_config->addPostReloadCallbacks(update_profiles_guest_modes => \&update_profiles_guest_modes); } else { $cached_authentication_config->ReadConfig(); - update_profiles_guest_modes($cached_profiles_config,"update_profiles_guest_modes"); } } @@ -321,7 +324,10 @@ sub writeAuthenticationConfigFile { } } $cached_authentication_config->ReorderByGroup(); - my $result = $cached_authentication_config->RewriteConfig(); + my $result; + eval { + $result = $cached_authentication_config->RewriteConfig(); + }; unless($result) { $cached_authentication_config->Rollback(); die "Error writing authentication configuration\n"; From 3b282102bfdb6d6841e28edf032f2714e7cb21a8 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Wed, 11 Sep 2013 16:12:52 -0400 Subject: [PATCH 020/369] Don't replace RADIUS configuration files --- addons/packages/packetfence.spec | 31 +++++++++++----- debian/packetfence.conffiles | 64 ++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 9 deletions(-) diff --git a/addons/packages/packetfence.spec b/addons/packages/packetfence.spec index a25486e49eee..84f80130084a 100644 --- a/addons/packages/packetfence.spec +++ b/addons/packages/packetfence.spec @@ -807,17 +807,30 @@ fi /usr/local/pf/raddb/* %config /usr/local/pf/raddb/clients.conf %attr(0755, pf, pf) %config /usr/local/pf/raddb/packetfence.pm -%attr(0755, pf, pf) %config /usr/local/pf/raddb/packetfence-soh.pm +%attr(0755, pf, pf) %config /usr/local/pf/raddb/packetfence-soh.pm %config /usr/local/pf/raddb/proxy.conf %config /usr/local/pf/raddb/users -%config /usr/local/pf/raddb/modules/mschap -%config /usr/local/pf/raddb/modules/perl -%attr(0755, pf, pf) %config /usr/local/pf/raddb/sites-available/packetfence -%attr(0755, pf, pf) %config /usr/local/pf/raddb/sites-available/packetfence-soh -%attr(0755, pf, pf) %config /usr/local/pf/raddb/sites-available/packetfence-tunnel -%attr(0755, pf, pf) %config /usr/local/pf/raddb/sites-enabled/packetfence -%attr(0755, pf, pf) %config /usr/local/pf/raddb/sites-enabled/packetfence-soh -%attr(0755, pf, pf) %config /usr/local/pf/raddb/sites-enabled/packetfence-tunnel +%config(noreplace) /usr/local/pf/raddb/modules/* +%attr(0755, pf, pf) %config(noreplace) /usr/local/pf/raddb/sites-available/buffered-sql +%attr(0755, pf, pf) %config(noreplace) /usr/local/pf/raddb/sites-available/coa +%attr(0755, pf, pf) %config(noreplace) /usr/local/pf/raddb/sites-available/control-socket +%attr(0755, pf, pf) %config(noreplace) /usr/local/pf/raddb/sites-available/copy-acct-to-home-server +%attr(0755, pf, pf) %config(noreplace) /usr/local/pf/raddb/sites-available/decoupled-accounting +%attr(0755, pf, pf) %config(noreplace) /usr/local/pf/raddb/sites-available/default +%attr(0755, pf, pf) %config(noreplace) /usr/local/pf/raddb/sites-available/dhcp +%attr(0755, pf, pf) %config(noreplace) /usr/local/pf/raddb/sites-available/dynamic-clients +%attr(0755, pf, pf) %config(noreplace) /usr/local/pf/raddb/sites-available/example +%attr(0755, pf, pf) %config(noreplace) /usr/local/pf/raddb/sites-available/inner-tunnel +%attr(0755, pf, pf) %config(noreplace) /usr/local/pf/raddb/sites-available/originate-coa +%attr(0755, pf, pf) %config(noreplace) /usr/local/pf/raddb/sites-available/packetfence +%attr(0755, pf, pf) %config(noreplace) /usr/local/pf/raddb/sites-available/packetfence-soh +%attr(0755, pf, pf) %config(noreplace) /usr/local/pf/raddb/sites-available/packetfence-tunnel +%attr(0755, pf, pf) %config(noreplace) /usr/local/pf/raddb/sites-available/proxy-inner-tunnel +%attr(0755, pf, pf) %config(noreplace) /usr/local/pf/raddb/sites-available/robust-proxy-accounting +%attr(0755, pf, pf) %config(noreplace) /usr/local/pf/raddb/sites-available/soh +%attr(0755, pf, pf) %config(noreplace) /usr/local/pf/raddb/sites-available/status +%attr(0755, pf, pf) %config(noreplace) /usr/local/pf/raddb/sites-available/virtual.example.com +%attr(0755, pf, pf) %config(noreplace) /usr/local/pf/raddb/sites-available/vmps %dir /usr/local/pf/var/run %dir /usr/local/pf/var/rrd %dir /usr/local/pf/var/session diff --git a/debian/packetfence.conffiles b/debian/packetfence.conffiles index 82929e123d48..80d2db84f20e 100644 --- a/debian/packetfence.conffiles +++ b/debian/packetfence.conffiles @@ -93,8 +93,72 @@ /usr/local/pf/raddb/packetfence-soh.pm /usr/local/pf/raddb/proxy.conf /usr/local/pf/raddb/users +/usr/local/pf/raddb/modules/acct_unique +/usr/local/pf/raddb/modules/always +/usr/local/pf/raddb/modules/attr_filter +/usr/local/pf/raddb/modules/attr_rewrite +/usr/local/pf/raddb/modules/chap +/usr/local/pf/raddb/modules/checkval +/usr/local/pf/raddb/modules/counter +/usr/local/pf/raddb/modules/cui +/usr/local/pf/raddb/modules/detail +/usr/local/pf/raddb/modules/detail.example.com +/usr/local/pf/raddb/modules/detail.log +/usr/local/pf/raddb/modules/digest +/usr/local/pf/raddb/modules/dynamic_clients +/usr/local/pf/raddb/modules/echo +/usr/local/pf/raddb/modules/etc_group +/usr/local/pf/raddb/modules/exec +/usr/local/pf/raddb/modules/expiration +/usr/local/pf/raddb/modules/expr +/usr/local/pf/raddb/modules/files +/usr/local/pf/raddb/modules/inner-eap +/usr/local/pf/raddb/modules/ippool +/usr/local/pf/raddb/modules/ldap +/usr/local/pf/raddb/modules/linelog +/usr/local/pf/raddb/modules/logintime +/usr/local/pf/raddb/modules/mac2ip +/usr/local/pf/raddb/modules/mac2vlan /usr/local/pf/raddb/modules/mschap +/usr/local/pf/raddb/modules/ntlm_auth +/usr/local/pf/raddb/modules/opendirectory +/usr/local/pf/raddb/modules/otp +/usr/local/pf/raddb/modules/pam +/usr/local/pf/raddb/modules/pap +/usr/local/pf/raddb/modules/passwd /usr/local/pf/raddb/modules/perl +/usr/local/pf/raddb/modules/policy +/usr/local/pf/raddb/modules/preprocess +/usr/local/pf/raddb/modules/radutmp +/usr/local/pf/raddb/modules/realm +/usr/local/pf/raddb/modules/redis +/usr/local/pf/raddb/modules/rediswho +/usr/local/pf/raddb/modules/replicate +/usr/local/pf/raddb/modules/smbpasswd +/usr/local/pf/raddb/modules/smsotp +/usr/local/pf/raddb/modules/soh +/usr/local/pf/raddb/modules/sqlcounter_expire_on_login +/usr/local/pf/raddb/modules/sql_log +/usr/local/pf/raddb/modules/sradutmp +/usr/local/pf/raddb/modules/unix +/usr/local/pf/raddb/modules/wimax +/usr/local/pf/raddb/sites-available/buffered-sql +/usr/local/pf/raddb/sites-available/coa +/usr/local/pf/raddb/sites-available/control-socket +/usr/local/pf/raddb/sites-available/copy-acct-to-home-server +/usr/local/pf/raddb/sites-available/decoupled-accounting +/usr/local/pf/raddb/sites-available/default +/usr/local/pf/raddb/sites-available/dhcp +/usr/local/pf/raddb/sites-available/dynamic-clients +/usr/local/pf/raddb/sites-available/example +/usr/local/pf/raddb/sites-available/inner-tunnel +/usr/local/pf/raddb/sites-available/originate-coa /usr/local/pf/raddb/sites-available/packetfence /usr/local/pf/raddb/sites-available/packetfence-soh /usr/local/pf/raddb/sites-available/packetfence-tunnel +/usr/local/pf/raddb/sites-available/proxy-inner-tunnel +/usr/local/pf/raddb/sites-available/robust-proxy-accounting +/usr/local/pf/raddb/sites-available/soh +/usr/local/pf/raddb/sites-available/status +/usr/local/pf/raddb/sites-available/virtual.example.com +/usr/local/pf/raddb/sites-available/vmps \ No newline at end of file From 067d5bd826c5591f5a4b4ff6544a0a17739caa0c Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Wed, 11 Sep 2013 16:20:56 -0400 Subject: [PATCH 021/369] Rotate log files as user pf --- addons/logrotate | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/logrotate b/addons/logrotate index 8f1d5c317a95..43e3e1e202be 100644 --- a/addons/logrotate +++ b/addons/logrotate @@ -8,6 +8,7 @@ delaycompress sharedscripts create 644 pf pf + su pf pf postrotate # uncomment the crm statements if you are running packetfence in a corosync cluster #/usr/sbin/crm resource unmanage PacketFence From 92e9339121f16d7b6d328f149fcb4b4c07944d73 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 11 Sep 2013 18:22:30 -0400 Subject: [PATCH 022/369] Removed the localization of lib/pf/authentication.pm in first filter --- lib/pf/authentication.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pf/authentication.pm b/lib/pf/authentication.pm index a82c1562e5d3..ed5a0e109d7c 100644 --- a/lib/pf/authentication.pm +++ b/lib/pf/authentication.pm @@ -501,7 +501,7 @@ sub match { @sources = ($source); } } - my $source = first { local $_ = $_; defined ($actions = $_->match($params)) } @sources; + my $source = first { defined ($actions = $_->match($params)) } @sources; if (defined $action && defined $actions) { my $found_action = first { $_->type eq $action } @{$actions}; From 8de4bd2e654c0a31f2b3b36497fe00786ce44227 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 12 Sep 2013 11:36:34 -0400 Subject: [PATCH 023/369] Remove item from all subcaches of type l1_cache --- lib/pf/config/cached.pm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/pf/config/cached.pm b/lib/pf/config/cached.pm index b95703662aca..9f4c95e2b86a 100644 --- a/lib/pf/config/cached.pm +++ b/lib/pf/config/cached.pm @@ -916,7 +916,11 @@ sub toHash { sub fromCacheUntainted { my ($self,$key) = @_; my $cache = $self->cache; - $cache->l1_cache->remove($key); + if($cache->has_subcaches( )) { + foreach my $subcache (@{$cache->subcaches}) { + $subcache->remove($key) if $subcache->subcache_type eq 'l1_cache'; + } + } return untaint($self->cache->get($key)); } From 5527837c980db1c91e756ad237eedb0eac5c38fd Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Thu, 12 Sep 2013 11:47:55 -0400 Subject: [PATCH 024/369] Consistent return values in clean_mac/mac2ip Also, an invalid MAC will not trigger an error log, but only a debugging log. --- lib/pf/iplog.pm | 2 +- lib/pf/util.pm | 11 ++++++----- t/util.t | 22 ++++++++++++++-------- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/lib/pf/iplog.pm b/lib/pf/iplog.pm index bbf4a72691c9..5a00736e802a 100644 --- a/lib/pf/iplog.pm +++ b/lib/pf/iplog.pm @@ -352,7 +352,7 @@ sub mac2ip { my ( $mac, $date ) = @_; my $logger = Log::Log4perl::get_logger('pf::iplog'); my $ip; - return (0) if ( !valid_mac($mac) ); + return () if ( !valid_mac($mac) ); if ($date) { return if ( !valid_date($date) ); diff --git a/lib/pf/util.pm b/lib/pf/util.pm index da3fbf0abf65..1c6365d45dbd 100644 --- a/lib/pf/util.pm +++ b/lib/pf/util.pm @@ -143,7 +143,7 @@ Returns an untainted string with MAC in format: xx:xx:xx:xx:xx:xx sub clean_mac { my ($mac) = @_; - return (0) if ( !$mac ); + return if ( !$mac ); # trim garbage $mac =~ s/[\s\-\.:]//g; @@ -209,16 +209,17 @@ Accepting xx-xx-xx-xx-xx-xx, xx:xx:xx:xx:xx:xx, xxxx-xxxx-xxxx and xxxx.xxxx.xxx sub valid_mac { my ($mac) = @_; my $logger = Log::Log4perl::get_logger('pf::util'); - if (! ($mac =~ /^[0-9a-f:\.-]+$/i)) { - $logger->error("invalid MAC: $mac"); + if (! ($mac && $mac =~ /^[0-9a-f:\.-]+$/i)) { + $logger->debug("invalid MAC: " . ($mac?$mac:"empty")); return (0); } $mac = clean_mac($mac); - if ( $mac =~ /^ff:ff:ff:ff:ff:ff$/ + if ( !$mac + || $mac =~ /^ff:ff:ff:ff:ff:ff$/ || $mac =~ /^00:00:00:00:00:00$/ || $mac !~ /^([0-9a-f]{2}(:|$)){6}$/i ) { - $logger->error("invalid MAC: $mac"); + $logger->debug("invalid MAC: " . ($mac?$mac:"empty")); return (0); } else { return (1); diff --git a/t/util.t b/t/util.t index fd212c5bab71..7472b2e07fc5 100755 --- a/t/util.t +++ b/t/util.t @@ -4,7 +4,7 @@ use strict; use warnings; use lib '/usr/local/pf/lib'; -use Test::More tests => 23; +use Test::More tests => 29; use Test::NoWarnings; BEGIN { @@ -12,13 +12,6 @@ BEGIN { use_ok('pf::util::apache'); } -# valid_mac -ok(valid_mac("aa:bb:cc:dd:ee:ff"), "validate MAC address of the form xx:xx:xx:xx:xx:xx"); -ok(valid_mac("aa-bb-cc-dd-ee-ff"), "validate MAC address of the form xx-xx-xx-xx-xx-xx"); -ok(valid_mac("aabb-ccdd-eeff"), "validate MAC address of the form xxxx-xxxx-xxxx"); -ok(valid_mac("aabb.ccdd.eeff"), "validate MAC address of the form xxxx.xxxx.xxxx"); -ok(valid_mac("aabbccddeeff"), "validate MAC address of the form xxxxxxxxxxxx"); - # clean_mac is(clean_mac("aabbccddeeff"), "aa:bb:cc:dd:ee:ff", "clean MAC address of the form xxxxxxxxxxxx"); is(clean_mac("aa:bb:cc:dd:ee:ff"), "aa:bb:cc:dd:ee:ff", "clean MAC address of the form xx:xx:xx:xx:xx:xx"); @@ -26,6 +19,19 @@ is(clean_mac("aa-bb-cc-dd-ee-ff"), "aa:bb:cc:dd:ee:ff", "clean MAC address of th is(clean_mac("aabb-ccdd-eeff"), "aa:bb:cc:dd:ee:ff", "clean MAC address of the form xxxx-xxxx-xxxx"); is(clean_mac("aabb.ccdd.eeff"), "aa:bb:cc:dd:ee:ff", "clean MAC address of the form xxxx.xxxx.xxxx"); is(clean_mac("aabbccddeeff"), "aa:bb:cc:dd:ee:ff", "clean MAC address of the form xxxxxxxxxxxx"); +is(clean_mac("abc"), undef, "clean invalid MAC address of the form xxx"); +is(clean_mac(""), undef, "clean empty MAC address"); +is(clean_mac(undef), undef, "clean undefined MAC address"); + +# valid_mac +ok(valid_mac("aa:bb:cc:dd:ee:ff"), "validate MAC address of the form xx:xx:xx:xx:xx:xx"); +ok(valid_mac("aa-bb-cc-dd-ee-ff"), "validate MAC address of the form xx-xx-xx-xx-xx-xx"); +ok(valid_mac("aabb-ccdd-eeff"), "validate MAC address of the form xxxx-xxxx-xxxx"); +ok(valid_mac("aabb.ccdd.eeff"), "validate MAC address of the form xxxx.xxxx.xxxx"); +ok(valid_mac("aabbccddeeff"), "validate MAC address of the form xxxxxxxxxxxx"); +ok(!valid_mac("abc"), "invalidate MAC address of the form xxx"); +ok(!valid_mac(""), "invalidate empty MAC address"); +ok(!valid_mac(undef), "invalidate undefined MAC address"); # oid2mac / mac2oid is( oid2mac('240.77.162.203.217.197'), 'f0:4d:a2:cb:d9:c5', "oid2mac legit conversion" ); From 8fb7a20904bc41227ae60c90446744b7cf1aef3f Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 12 Sep 2013 12:15:41 -0400 Subject: [PATCH 025/369] remove calling cat to read a file --- lib/pf/pfcmd/checkup.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pf/pfcmd/checkup.pm b/lib/pf/pfcmd/checkup.pm index 3b2f5de21320..af895da0e63d 100644 --- a/lib/pf/pfcmd/checkup.pm +++ b/lib/pf/pfcmd/checkup.pm @@ -24,6 +24,7 @@ use pf::util; use pf::services; use pf::trigger; use NetAddr::IP; +use File::Slurp qw(read_file); use lib $conf_dir; @@ -469,7 +470,7 @@ If some interfaces are configured to run in inline enforcement then these tests sub inline { - my $result = pf_run("cat /proc/sys/net/ipv4/ip_forward"); + my $result = read_file("/proc/sys/net/ipv4/ip_forward"); if ($result ne "1\n") { add_problem( $WARN, "inline mode needs ip_forward enabled to work properly. " . From c9645e1136b173941170afa30dc2f228088605ed Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 12 Sep 2013 13:51:44 -0400 Subject: [PATCH 026/369] Allow mac formats to be searched --- .../lib/pfappserver/Base/Model/Search.pm | 14 ++++++++++++++ lib/pf/node.pm | 9 ++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/html/pfappserver/lib/pfappserver/Base/Model/Search.pm b/html/pfappserver/lib/pfappserver/Base/Model/Search.pm index 39b2bd150a11..5b892016bbcb 100644 --- a/html/pfappserver/lib/pfappserver/Base/Model/Search.pm +++ b/html/pfappserver/lib/pfappserver/Base/Model/Search.pm @@ -15,6 +15,7 @@ use strict; use warnings; use Moose; use namespace::autoclean; +use pf::util; extends 'pfappserver::Base::Model'; my %OP_MAP = ( @@ -41,6 +42,7 @@ To create where arguements for the sql builder sub process_query { my ($self,$query) = (@_); + $self->_pre_process_query($query); my $op = $query->{op}; die "$op is not a supported search operation" unless exists $OP_MAP{$op}; @@ -65,6 +67,18 @@ sub process_query { return \@where_args; } +sub _pre_process_query { + my ($self,$query) = @_; + if( $query->{name} eq 'mac' && $query->{op} eq 'equal' ) { + my $value = $query->{value}; + $value =~ s/^ *//; + $value =~ s/ *$//; + if(valid_mac($value)) { + $query->{value} = clean_mac($value); + } + } +} + =item add_limit add limits to the sql builder diff --git a/lib/pf/node.pm b/lib/pf/node.pm index faebd1940429..d539c9e353a5 100644 --- a/lib/pf/node.pm +++ b/lib/pf/node.pm @@ -646,12 +646,15 @@ sub node_view_all { $node_view_all_sql .= " HAVING category='" . $params{'where'}{'value'} . "'"; } elsif ( $params{'where'}{'type'} eq 'any' ) { - if (valid_mac($params{'where'}{'like'})) { - my $mac = get_db_handle->quote($params{'where'}{'like'}); + my $like = $params{'where'}{'like'}; + $like =~ s/^ *//; + $like =~ s/ *$//; + if (valid_mac($like)) { + my $mac = get_db_handle->quote(clean_mac($like)); $node_view_all_sql .= " HAVING node.mac = $mac"; } else { - my $like = get_db_handle->quote('%' . $params{'where'}{'like'} . '%'); + my $like = get_db_handle->quote("\%$like\%"); $node_view_all_sql .= " HAVING node.mac LIKE $like" . " OR node.computername LIKE $like" . " OR node.pid LIKE $like"; From ee737151d1b1e7f466e116c9a3258c8c09475bce Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 12 Sep 2013 14:02:05 -0400 Subject: [PATCH 027/369] Refactored removing items from your subcache --- lib/pf/config/cached.pm | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/pf/config/cached.pm b/lib/pf/config/cached.pm index 9f4c95e2b86a..68166568d238 100644 --- a/lib/pf/config/cached.pm +++ b/lib/pf/config/cached.pm @@ -463,7 +463,7 @@ sub Rollback { my $cache = $self->cache; my $config = $self->config; my $file = $config->GetFileName; - $cache->l1_cache->remove($file); + $self->removeFromSubcaches($file); my $old_config = $cache->get($file); $$self = $old_config; $self->doCallbacks(0,1); @@ -914,6 +914,12 @@ sub toHash { } sub fromCacheUntainted { + my ($self,$key) = @_; + $self->removeFromSubcaches($key); + return untaint($self->cache->get($key)); +} + +sub removeFromSubcaches { my ($self,$key) = @_; my $cache = $self->cache; if($cache->has_subcaches( )) { @@ -921,7 +927,6 @@ sub fromCacheUntainted { $subcache->remove($key) if $subcache->subcache_type eq 'l1_cache'; } } - return untaint($self->cache->get($key)); } sub untaint { From 26510ff7a1f4019a99cd8ff1d3112130a700d5ea Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 12 Sep 2013 14:11:40 -0400 Subject: [PATCH 028/369] Allow ip address to searched in the simple search of nodes --- lib/pf/node.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pf/node.pm b/lib/pf/node.pm index d539c9e353a5..d85590ebf93e 100644 --- a/lib/pf/node.pm +++ b/lib/pf/node.pm @@ -657,7 +657,8 @@ sub node_view_all { my $like = get_db_handle->quote("\%$like\%"); $node_view_all_sql .= " HAVING node.mac LIKE $like" . " OR node.computername LIKE $like" - . " OR node.pid LIKE $like"; + . " OR node.pid LIKE $like" + . " OR iplog.ip LIKE $like"; } } } From 8f849c0fcb08f7ba31c017b5551360ebf539827b Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 12 Sep 2013 14:26:33 -0400 Subject: [PATCH 029/369] Updated News file --- NEWS.asciidoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS.asciidoc b/NEWS.asciidoc index d3c8f89c7d27..c6d0a306dc3e 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -23,6 +23,8 @@ Enhancements ++++++++++++ * Improved error messages in RADIUS modules +* Simple search for Nodes now include ip address +* Search by mac address for Node and User in multiple mac format Bug Fixes +++++++++ From f4060c3948f80aaa44c530cc8fc69d8310cd83bc Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Thu, 12 Sep 2013 15:27:06 -0400 Subject: [PATCH 030/369] pf::iplog::mac2ip now accepts a lookup table In order to avoid performing many SQL queries in pf::ipset::generate_mangle_rules, we now fetch all open entries from the iplog table to build a lookup table that we pass to pf::util::mac2ip. --- NEWS.asciidoc | 5 +++-- lib/pf/iplog.pm | 8 +++----- lib/pf/ipset.pm | 8 ++++++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/NEWS.asciidoc b/NEWS.asciidoc index c6d0a306dc3e..a7bd09f0ec5e 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -23,8 +23,9 @@ Enhancements ++++++++++++ * Improved error messages in RADIUS modules -* Simple search for Nodes now include ip address -* Search by mac address for Node and User in multiple mac format +* Simple search for nodes now includes IP address +* Search by MAC address for nodes and users now accepts any MAC format +* Improved starting delay when using inline mode Bug Fixes +++++++++ diff --git a/lib/pf/iplog.pm b/lib/pf/iplog.pm index 5a00736e802a..1b89d6667091 100644 --- a/lib/pf/iplog.pm +++ b/lib/pf/iplog.pm @@ -349,15 +349,13 @@ sub ip2macinarp { } sub mac2ip { - my ( $mac, $date ) = @_; + my ( $mac, $cache ) = @_; my $logger = Log::Log4perl::get_logger('pf::iplog'); my $ip; return () if ( !valid_mac($mac) ); - if ($date) { - return if ( !valid_date($date) ); - my @iplog = iplog_history_mac( $mac, ( 'date' => str2time($date) ) ); - $ip = $iplog[0]->{'ip'}; + if ($cache) { + $ip = $cache->{clean_mac($mac)}; } else { my $iplog = iplog_view_open_mac($mac); $ip = $iplog->{'ip'} || 0; diff --git a/lib/pf/ipset.pm b/lib/pf/ipset.pm index 9f79e6a0410b..8a0ff0c87919 100644 --- a/lib/pf/ipset.pm +++ b/lib/pf/ipset.pm @@ -113,6 +113,10 @@ sub generate_mangle_rules { } } + # Build lookup table for MAC/IP mapping + my @iplog_open = iplog_view_open(); + my %iplog_lookup = map { $_->{'mac'} => $_->{'ip'} } @iplog_open; + # mark registered nodes that should not be isolated # TODO performance: mark all *inline* registered users only my @registered = nodes_registered_not_violators(); @@ -121,7 +125,7 @@ sub generate_mangle_rules { next if ( !pf::config::is_network_type_inline($network) ); my $net_addr = NetAddr::IP->new($network,$ConfigNetworks{$network}{'netmask'}); my $mac = $row->{'mac'}; - my $iplog = mac2ip($mac); + my $iplog = mac2ip($mac, \%iplog_lookup); if (defined $iplog) { my $ip = new NetAddr::IP::Lite clean_ip($iplog); if ($net_addr->contains($ip)) { @@ -141,7 +145,7 @@ sub generate_mangle_rules { next if ( !pf::config::is_network_type_inline($network) ); my $net_addr = NetAddr::IP->new($network,$ConfigNetworks{$network}{'netmask'}); my $mac = $row->{'mac'}; - my $iplog = mac2ip($mac); + my $iplog = mac2ip($mac, \%iplog_lookup); if (defined $iplog) { my $ip = new NetAddr::IP::Lite clean_ip($iplog); if ($net_addr->contains($ip)) { From 871dd52373ce20f0603d087c07d221c019bfccd9 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Thu, 12 Sep 2013 15:42:21 -0400 Subject: [PATCH 031/369] Group ipset add commands into a "restore" command --- lib/pf/ipset.pm | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/pf/ipset.pm b/lib/pf/ipset.pm index 8a0ff0c87919..ad7e409b02dc 100644 --- a/lib/pf/ipset.pm +++ b/lib/pf/ipset.pm @@ -98,6 +98,7 @@ sub generate_mangle_rules { my ($self) =@_; my $logger = Log::Log4perl::get_logger(__PACKAGE__); my $mangle_rules = ''; + my @ops = (); # pfdhcplistener in most cases will be enforcing access # however we insert these marks on startup in case PacketFence is restarted @@ -129,8 +130,7 @@ sub generate_mangle_rules { if (defined $iplog) { my $ip = new NetAddr::IP::Lite clean_ip($iplog); if ($net_addr->contains($ip)) { - my $cmd = "LANG=C sudo ipset --add pfsession_$mark_type_to_str{$IPTABLES_MARK_REG}\_$network $iplog,$mac 2>&1"; - my @lines = pf_run($cmd); + push(@ops, "add pfsession_$mark_type_to_str{$IPTABLES_MARK_REG}\_$network $iplog,$mac"); } } } @@ -149,8 +149,7 @@ sub generate_mangle_rules { if (defined $iplog) { my $ip = new NetAddr::IP::Lite clean_ip($iplog); if ($net_addr->contains($ip)) { - my $cmd = "LANG=C sudo ipset --add pfsession_$mark_type_to_str{$IPTABLES_MARK_ISOLATION}\_$network $iplog,$mac 2>&1"; - my @lines = pf_run($cmd); + push(@ops, "add pfsession_$mark_type_to_str{$IPTABLES_MARK_ISOLATION}\_$network $iplog,$mac"); } } } @@ -165,6 +164,13 @@ sub generate_mangle_rules { ; } + if (@ops) { + my $cmd = "LANG=C sudo ipset restore 2>&1"; + open(IPSET, "| $cmd") || die "$cmd failed: $!\n"; + print IPSET join("\n", @ops); + close IPSET; + } + return $mangle_rules; } From 933be6a1d8dbafaac681d2260125ef6c0537b89a Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 12 Sep 2013 16:11:22 -0400 Subject: [PATCH 032/369] added memcached as a managed service --- conf/documentation.conf | 14 ++++++++ conf/pf.conf.defaults | 10 ++++++ lib/pf/pfcmd.pm | 73 +++++++++++++++++++++-------------------- lib/pf/services.pm | 5 +-- 4 files changed, 64 insertions(+), 38 deletions(-) diff --git a/conf/documentation.conf b/conf/documentation.conf index 858ef96790d3..98eff920e373 100644 --- a/conf/documentation.conf +++ b/conf/documentation.conf @@ -126,6 +126,13 @@ description=< to parse the options. =cut + use strict; use warnings; @@ -30,7 +31,7 @@ Readonly our $ERROR_CONFIG_NO_HELP => 11; # - update the appropriate regexp in lib/pfcmd/pfcmd.pm grammar too # - update the generic pid regex in pf::person (not meant for shell safety) # TODO try to consolidate what we should accept as a pid -my $pid_re = qr{(?: +my $pid_re = qr{(?: ( [a-zA-Z0-9\-\_\.\@\/\:\+\!,]+ ) # unquoted allowed | # OR \" ( [&=?\(\)\/,0-9a-zA-Z_\*\.\-\:\;\@\ \+\!\^\[\]\|\#\\]+ ) \" # quoted allowed @@ -54,9 +55,9 @@ sub parseCommandLine { ( [ a-zA-Z0-9_@\.\:=/\-,?]+) $ }xms, 'configfiles' => qr{ ^ ( push | pull ) $ }xms, - 'fingerprint' => qr{ ^ (view) - \s+ - ( all | \d+ (?: ,\d+)* ) + 'fingerprint' => qr{ ^ (view) + \s+ + ( all | \d+ (?: ,\d+)* ) $ }xms, 'floatingnetworkdeviceconfig' => qr/ ^ ( get | delete ) @@ -66,7 +67,7 @@ sub parseCommandLine { 'graph' => qr/ ^ (?: ( nodes | registered | unregistered - | violations ) + | violations ) (?: \s+ ( day | month | year ) @@ -154,7 +155,7 @@ sub parseCommandLine { ( [^,=]+ ) )? $ }xms, - 'import' => qr{ ^ + 'import' => qr{ ^ ( nodes ) # import nodes \s+ ( [a-zA-Z0-9_\-\.\/]+ ) # strict filename with path regexp @@ -192,12 +193,12 @@ sub parseCommandLine { ( [^,=]+ ) )? $ /xms, - 'lookup' => qr{ ^(?: + 'lookup' => qr{ ^(?: ( person ) \s+ $pid_re - | + | ( node ) \s+ ( $RE{net}{MAC} ) )$ }xms, - 'manage' => qr/ ^ + 'manage' => qr/ ^ (?: ( deregister ) \s+ @@ -217,9 +218,9 @@ sub parseCommandLine { 'node' => qr/ ^ (?: ( view ) \s+ - (?: - ( all ) - | ( $RE{net}{MAC} ) + (?: + ( all ) + | ( $RE{net}{MAC} ) # TODO be more strict on category names (but no time now) | (?: ( category | pid ) \s* [=] \s* $pid_re ) ) @@ -237,9 +238,9 @@ sub parseCommandLine { | ( count ) \s+ - (?: - ( all ) - | ( $RE{net}{MAC} ) + (?: + ( all ) + | ( $RE{net}{MAC} ) # TODO be more strict on category names (but no time now) | (?: ( category | pid ) \s* [=] \s* $pid_re ) ) @@ -251,7 +252,7 @@ sub parseCommandLine { 'nodeaccounting' => qr/ ^ ( view ) \s+ (?: - ( all ) + ( all ) | ( $RE{net}{MAC} ) ) $ /xms, @@ -263,19 +264,19 @@ sub parseCommandLine { (delete) \s+ (\s+) ) $ }xms, - 'nodeuseragent' => qr{ ^ (view) - \s+ - ( all | \d+ (?: ,\d+)* ) + 'nodeuseragent' => qr{ ^ (view) + \s+ + ( all | \d+ (?: ,\d+)* ) $ }xms, 'person' => qr{ ^ (view) \s+ - (?: + (?: ( all ) | $pid_re ) $ }xms, 'reload' => qr{ ^ ( fingerprints | violations ) $ }xms, 'report' => qr{ ^ (?: #for grouping only - ( active | inactive | openviolations + ( active | inactive | openviolations | os | osclass | registered | statics | ssid | unknownprints | unknownuseragents | unregistered | connectiontype | connectiontypereg | osclassbandwidth @@ -283,9 +284,9 @@ sub parseCommandLine { ) | (?: #for grouping only - ( openviolations | os | osclass + ( openviolations | os | osclass | registered | statics | ssid - | unknownprints | unknownuseragents | unregistered + | unknownprints | unknownuseragents | unregistered | connectiontype | connectiontypereg ) \s+ @@ -307,15 +308,15 @@ sub parseCommandLine { ( \d+ ) ) $ }xms, - 'service' => qr{ ^ ( dhcpd | httpd | pfdns | pfdetect - | pf | pfdhcplistener | pfmon - | pfsetvlan | radiusd | snmptrapd - | snort | suricata | httpd\.webservices | httpd\.admin | httpd\.portal) + 'service' => qr{ ^ ( dhcpd | httpd | pfdns | pfdetect + | pf | pfdhcplistener | pfmon + | pfsetvlan | radiusd | snmptrapd + | snort | suricata | httpd\.webservices | httpd\.admin | httpd\.portal | memcached) \s+ ( restart | start | status | stop | watch ) $ }xms, - 'switchconfig' => qr/ ^ ( get | delete ) + 'switchconfig' => qr/ ^ ( get | delete ) \s+ ( all | default | $RE{net}{IPv4} ) $ /xms, @@ -335,7 +336,7 @@ sub parseCommandLine { ) ) $ }xms, - 'trigger' => qr{ ^ ( view ) + 'trigger' => qr{ ^ ( view ) \s+ ( all | \d+ ) (?: @@ -343,12 +344,12 @@ sub parseCommandLine { ( scan | detect ) )? $ }xms, - 'ui' => qr{ ^ + 'ui' => qr{ ^ (?: (?: ( dashboard ) \s+ - ( current_grace | current_activity + ( current_grace | current_activity | current_node_status ) ) | @@ -367,16 +368,16 @@ sub parseCommandLine { (?: ( menus ) (?: - \s+ file \s* [=] \s* + \s+ file \s* [=] \s* ( [a-zA-Z\-_.]+ ) )? ) ) $ }xms, 'update' => qr{ ^ ( fingerprints | oui ) $ }xms, - 'useragent' => qr{ ^ (view) - \s+ - ( all | \d+ ) + 'useragent' => qr{ ^ (view) + \s+ + ( all | \d+ ) $ }xms, 'version' => qr{ ^ $ }xms, 'violation' => qr{ ^ ( view ) @@ -470,7 +471,7 @@ sub parseCommandLine { } return %cmd; } - + return parseWithGrammar($commandLine); } diff --git a/lib/pf/services.pm b/lib/pf/services.pm index 95c7ffbca7ec..3864d355fff4 100644 --- a/lib/pf/services.pm +++ b/lib/pf/services.pm @@ -53,7 +53,7 @@ Readonly our @APACHE_SERVICES => ( ); Readonly our @ALL_SERVICES => ( - @APACHE_SERVICES, 'pfdns', 'dhcpd', 'pfdetect', 'snort', 'suricata', 'radiusd', + 'memcached', @APACHE_SERVICES, 'pfdns', 'dhcpd', 'pfdetect', 'snort', 'suricata', 'radiusd', 'snmptrapd', 'pfsetvlan', 'pfdhcplistener', 'pfmon' ); @@ -92,6 +92,7 @@ $service_launchers{'dhcpd'} = "sudo %1\$s -lf $var_dir/dhcpd/dhcpd.leases -cf $g $service_launchers{'pfdns'} = '%1$s -d &'; $service_launchers{'snmptrapd'} = "%1\$s -n -c $generated_conf_dir/snmptrapd.conf -C -A -Lf $install_dir/logs/snmptrapd.log -p $install_dir/var/run/snmptrapd.pid -On"; $service_launchers{'radiusd'} = "sudo %1\$s -d $install_dir/raddb/"; +$service_launchers{'memcached'} = "%1\$s -d -p 11211 -u memcached -m 64 -c 1024 -P $install_dir/var/run/memcached.pid"; # TODO $monitor_int will cause problems with dynamic config reloading if ( isenabled( $Config{'trapping'}{'detection'} ) && $monitor_int && $Config{'trapping'}{'detection_engine'} eq 'snort' ) { @@ -352,7 +353,7 @@ sub getPidFromFile { my $pid = 0; my $pid_file = "$install_dir/var/run/$daemon.pid"; if (-e $pid_file) { - chomp( $pid = read_file($pid_file) ); + eval {chomp( $pid = read_file($pid_file) );}; } $pid = 0 unless $pid; $logger->info("pidof -x $binary returned $pid"); From 90a5565c610fbf538b8315ead87d222979b7e1d6 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 12 Sep 2013 16:12:39 -0400 Subject: [PATCH 033/369] Updated news file --- NEWS.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.asciidoc b/NEWS.asciidoc index a7bd09f0ec5e..6e2f839571f6 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -26,6 +26,7 @@ Enhancements * Simple search for nodes now includes IP address * Search by MAC address for nodes and users now accepts any MAC format * Improved starting delay when using inline mode +* Added memcached as a managed service Bug Fixes +++++++++ From a9f5dae20a8ad74aeafc07039c07f060707741bb Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Fri, 13 Sep 2013 11:04:28 -0400 Subject: [PATCH 034/369] Add notice regarding billing engine activation --- html/pfappserver/lib/pfappserver/Form/Portal/Profile.pm | 3 +++ .../pfappserver/lib/pfappserver/Form/Portal/Profile/Default.pm | 3 +++ 2 files changed, 6 insertions(+) diff --git a/html/pfappserver/lib/pfappserver/Form/Portal/Profile.pm b/html/pfappserver/lib/pfappserver/Form/Portal/Profile.pm index da0418b9075d..d0bc55e61d48 100644 --- a/html/pfappserver/lib/pfappserver/Form/Portal/Profile.pm +++ b/html/pfappserver/lib/pfappserver/Form/Portal/Profile.pm @@ -16,6 +16,7 @@ use HTML::FormHandler::Moose; use pfappserver::Form::Field::ProfileFilter; extends 'pfappserver::Base::Form'; with 'pfappserver::Form::Portal::Common'; +with 'pfappserver::Base::Form::Role::Help'; use pf::config; use List::MoreUtils qw(uniq); @@ -41,6 +42,8 @@ has_field 'billing_engine' => label => 'Enable Billing Engine', checkbox_value => 'enabled', unchecked_value => 'disabled', + tags => { after_element => \&help, + help => 'When enabling the billing engine, all authentication sources bellow are ignored.' }, ); has_block 'definition' => ( diff --git a/html/pfappserver/lib/pfappserver/Form/Portal/Profile/Default.pm b/html/pfappserver/lib/pfappserver/Form/Portal/Profile/Default.pm index 5ff9acb2f760..0486b4cfc5d0 100644 --- a/html/pfappserver/lib/pfappserver/Form/Portal/Profile/Default.pm +++ b/html/pfappserver/lib/pfappserver/Form/Portal/Profile/Default.pm @@ -15,6 +15,7 @@ use pf::authentication; use HTML::FormHandler::Moose; extends 'pfappserver::Base::Form'; with 'pfappserver::Form::Portal::Common'; +with 'pfappserver::Base::Form::Role::Help'; # Form fields has_field 'id' => @@ -44,6 +45,8 @@ has_field 'billing_engine' => label => 'Enable Billing Engine', checkbox_value => 'enabled', unchecked_value => 'disabled', + tags => { after_element => \&help, + help => 'When enabling the billing engine, all authentication sources bellow are ignored.' }, ); has_block 'definition' => ( From 8ddeb201ee2fe353c1ea8703b40c9e38203bc57e Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Fri, 13 Sep 2013 11:05:59 -0400 Subject: [PATCH 035/369] Improve logging in pf::email_activation --- lib/pf/email_activation.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pf/email_activation.pm b/lib/pf/email_activation.pm index ad82b10352cb..cc93f7b7a442 100644 --- a/lib/pf/email_activation.pm +++ b/lib/pf/email_activation.pm @@ -396,6 +396,7 @@ sub send_email { try { $msg->send('smtp', $smtpserver, Timeout => 20); $result = $msg->last_send_successful(); + $logger->info("Email sent to ".$info{'email'}." (".$info{'subject'}.")"); } catch { $logger->error("Can't send email to ".$info{'email'}); @@ -406,7 +407,6 @@ sub send_email { sub create_and_email_activation_code { my ($mac, $pid, $email_addr, $template, $activation_type, %info) = @_; - my $logger = Log::Log4perl::get_logger('pf::email_activation'); my ($success, $err) = ($TRUE, 0); my $activation_code = create($mac, $pid, $email_addr, $activation_type); From c553cb76061263fd163085d47ab009e079c8c1c8 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Fri, 13 Sep 2013 11:06:34 -0400 Subject: [PATCH 036/369] Fix template when creating portal profile --- .../pfappserver/root/portal/profile/create.tt | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/html/pfappserver/root/portal/profile/create.tt b/html/pfappserver/root/portal/profile/create.tt index be43d3d2d7b8..ab1d523416de 100644 --- a/html/pfappserver/root/portal/profile/create.tt +++ b/html/pfappserver/root/portal/profile/create.tt @@ -33,14 +33,28 @@
- [% FOREACH field IN form.fields %] - [% field.render %] - [% END %] -
-

- [% l('With no source selected, the sources of the default profile will be used.') %]
- [% l('Add a source.') %] -

+ [% form.block('definition').render %] + [% IF form.field('filter') %] +
+ +
+ [% form.field('filter').render %] +
+
+ [% END -%] +
+ +
+ [% form.field('sources').render %] +
+

+ + [% l('With no source specified, the sources of the default profile will be used.') %] +
+ [% l('Add a source.') %] +

+
+
[% l('Save') %] From 35b156a3a19824bdc7a2c19270dd4ef520551ced Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Fri, 13 Sep 2013 12:06:19 -0400 Subject: [PATCH 037/369] Add introduction on portal profiles config page --- docs/PacketFence_Administration_Guide.asciidoc | 2 +- html/pfappserver/root/admin/configuration.tt | 2 +- html/pfappserver/root/portal/profile/index.tt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/PacketFence_Administration_Guide.asciidoc b/docs/PacketFence_Administration_Guide.asciidoc index cb6b7cdbc9e9..82e5f99e0aa4 100644 --- a/docs/PacketFence_Administration_Guide.asciidoc +++ b/docs/PacketFence_Administration_Guide.asciidoc @@ -2050,7 +2050,7 @@ CAUTION: The use of different billing tiers requires different roles in PacketFe Portal Profiles ~~~~~~~~~~~~~~~ -In some cases, you may want to present a different captive portal (see below for the available customizations) according to the SSID clients connects to. To do so, PacketFence has the concept of portal profiles which gives you this possibility. +In some cases, you may want to present a different captive portal (see below for the available customizations) according to the SSID, the VLAN, or the switch IP the client connects to. To do so, PacketFence has the concept of portal profiles which gives you this possibility. When configured, portal profiles will override default values for which it is configured. When no values are configured in the profile, PacketFence will take its default ones (according to the "default" portal profile). diff --git a/html/pfappserver/root/admin/configuration.tt b/html/pfappserver/root/admin/configuration.tt index 1634fe3192bd..909312b5ae0b 100644 --- a/html/pfappserver/root/admin/configuration.tt +++ b/html/pfappserver/root/admin/configuration.tt @@ -87,7 +87,7 @@ table.sources { [% pf_section_entry( 'captive_portal', 'Captive portal') %] [% pf_section_entry( 'advanced', 'Advanced') %] [% pf_section_entry( 'provisioning', 'Provisioning') %] - [% list_entry('Portal::Profile', 'index', 'Portal Profiles and Pages') %] + [% list_entry('Portal::Profile', 'index', 'Portal Profiles') %] [% pf_section_entry( 'webservices', 'Web Services') %]
  • [% pf_section_entry( 'interfaces', 'Interfaces') %] diff --git a/html/pfappserver/root/portal/profile/index.tt b/html/pfappserver/root/portal/profile/index.tt index 8f559c41377b..f8e78a5a9521 100644 --- a/html/pfappserver/root/portal/profile/index.tt +++ b/html/pfappserver/root/portal/profile/index.tt @@ -18,7 +18,7 @@ [% l('Error!') %] [% error %]
  • [% END %] -

    [% l('Describe portal profiles') %]

    +

    [% l('Present a different captive portal according to the SSID, the VLAN, or the switch IP the client connects to.') %]

    [% IF message %]
    From 242556558ab3cf81138ed8d3dd68cb44f576ad3d Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Fri, 13 Sep 2013 13:58:42 -0400 Subject: [PATCH 038/369] Refactored to check if there is only a subcache exists --- lib/pf/config/cached.pm | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/pf/config/cached.pm b/lib/pf/config/cached.pm index 68166568d238..e743163973fd 100644 --- a/lib/pf/config/cached.pm +++ b/lib/pf/config/cached.pm @@ -922,11 +922,7 @@ sub fromCacheUntainted { sub removeFromSubcaches { my ($self,$key) = @_; my $cache = $self->cache; - if($cache->has_subcaches( )) { - foreach my $subcache (@{$cache->subcaches}) { - $subcache->remove($key) if $subcache->subcache_type eq 'l1_cache'; - } - } + $cache->l1_cache->remove($key) if $cache->has_subcaches; } sub untaint { From 560e23944a32ee823a5083d1cb49266143af5897 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Sat, 14 Sep 2013 11:26:41 -0400 Subject: [PATCH 039/369] fixed documentation for memcached_binary --- conf/documentation.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/documentation.conf b/conf/documentation.conf index 98eff920e373..af3bf151646a 100644 --- a/conf/documentation.conf +++ b/conf/documentation.conf @@ -181,7 +181,7 @@ Location of the arp binary. Only necessary to change if you are not running the RPMed version. EOT -[services.memcached] +[services.memcached_binary] type=text description=< Date: Sat, 14 Sep 2013 12:09:08 -0400 Subject: [PATCH 040/369] fixed the user of the memcached service --- lib/pf/services.pm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/pf/services.pm b/lib/pf/services.pm index 3864d355fff4..6a355ac25c02 100644 --- a/lib/pf/services.pm +++ b/lib/pf/services.pm @@ -92,7 +92,7 @@ $service_launchers{'dhcpd'} = "sudo %1\$s -lf $var_dir/dhcpd/dhcpd.leases -cf $g $service_launchers{'pfdns'} = '%1$s -d &'; $service_launchers{'snmptrapd'} = "%1\$s -n -c $generated_conf_dir/snmptrapd.conf -C -A -Lf $install_dir/logs/snmptrapd.log -p $install_dir/var/run/snmptrapd.pid -On"; $service_launchers{'radiusd'} = "sudo %1\$s -d $install_dir/raddb/"; -$service_launchers{'memcached'} = "%1\$s -d -p 11211 -u memcached -m 64 -c 1024 -P $install_dir/var/run/memcached.pid"; +$service_launchers{'memcached'} = "%1\$s -d -p 11211 -u pf -m 64 -c 1024 -P $install_dir/var/run/memcached.pid"; # TODO $monitor_int will cause problems with dynamic config reloading if ( isenabled( $Config{'trapping'}{'detection'} ) && $monitor_int && $Config{'trapping'}{'detection_engine'} eq 'snort' ) { @@ -408,9 +408,10 @@ sub stopService { if ( $service =~ /(dhcpd)/) { manage_Static_Route(); } - if ( waitToShutdown($service, $pid) && -e $install_dir . "/var/run/$binary.pid" ) { - $logger->info("Removing $install_dir/var/run/$binary.pid"); - unlink( $install_dir . "/var/run/$binary.pid" ); + my $pid_file = "$install_dir/var/run/$binary.pid"; + if ( waitToShutdown($service, $pid) && -e $pid_file) { + $logger->info("Removing $pid_file"); + unlink($pid_file); } } } From 36eef96f00c299f041dd1051eeae94b0093399b4 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 16 Sep 2013 10:34:37 -0400 Subject: [PATCH 041/369] Updated patch to reflect position file change --- debian/patches/debianize.patch | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/debian/patches/debianize.patch b/debian/patches/debianize.patch index 70fd957d35cb..b1db0571c00e 100644 --- a/debian/patches/debianize.patch +++ b/debian/patches/debianize.patch @@ -3,7 +3,7 @@ Author: Fabrice Durand --- a/conf/pf.conf.defaults +++ b/conf/pf.conf.defaults -@@ -573,7 +573,7 @@ snort_binary=/usr/sbin/snort +@@ -463,7 +463,7 @@ suricata_binary=/usr/bin/suricata # services.httpd_binary # # Location of the apache binary. Only necessary to change if you are not running the RPMed version. @@ -12,7 +12,7 @@ Author: Fabrice Durand # # services.dhcpd_binary # -@@ -593,12 +593,12 @@ snmptrapd_binary=/usr/sbin/snmptrapd +@@ -478,12 +478,12 @@ snmptrapd_binary=/usr/sbin/snmptrapd # services.radiusd_binary # # Location of the named binary. Only necessary to change if you are not running the RPMed version. @@ -24,6 +24,6 @@ Author: Fabrice Durand # Location of the arp binary. Only necessary to change if you are not running the RPMed version. -arp_binary=/sbin/arp +arp_binary=/usr/sbin/arp - - [vlan] - # + # + # services.memcached_binary + # From f5cfd3344bd1fd9f70c50ecb3f66230fb2bd1be5 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 16 Sep 2013 11:16:44 -0400 Subject: [PATCH 042/369] Added additional arguement checks --- lib/pf/SNMP.pm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/pf/SNMP.pm b/lib/pf/SNMP.pm index 0edf1990584a..49e239b75c46 100644 --- a/lib/pf/SNMP.pm +++ b/lib/pf/SNMP.pm @@ -33,7 +33,8 @@ use pf::roles::custom $ROLE_API_LEVEL; use pf::SNMP::constants; use pf::util; use pf::util::radius qw(perform_disconnect); -use List::MoreUtils qw(any); +use List::MoreUtils qw(any all); +use Scalar::Util qw(looks_like_number); =head1 SUBROUTINES @@ -982,7 +983,7 @@ sub getManagedIfIndexes { sub isManagedVlan { my ($this, $vlan) = @_; my $vlans = $this->{_vlans}; - return (defined $vlans && any {$_ == $vlan} values %$vlans) ? $TRUE : $FALSE; + return ( (all {defined $_ } $vlan,$vlans) && looks_like_number($vlan) && any {$_ == $vlan} values %$vlans) ? $TRUE : $FALSE; } =item getMode - get the mode From 201cefefd7837b1b4758286ffb84a9c259a0d32f Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Mon, 16 Sep 2013 14:28:05 -0400 Subject: [PATCH 043/369] Improve condition in pf::is_max_reg_nodes_reached $category or $category_id must not only be defined, but must also not be 0 or an empty string. --- lib/pf/node.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pf/node.pm b/lib/pf/node.pm index d85590ebf93e..97a1b8bfbbc6 100644 --- a/lib/pf/node.pm +++ b/lib/pf/node.pm @@ -1087,7 +1087,7 @@ sub is_max_reg_nodes_reached { return $FALSE if ($pid eq $default_pid); # per-category max node per pid limit - if ( defined($category) || defined($category_id) ) { + if ( $category || $category_id ) { my $category_info; my $nb_nodes; my $max_for_category; From caea89b2838ca1d09ff2ebb77494195ca11583b3 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Mon, 16 Sep 2013 14:32:37 -0400 Subject: [PATCH 044/369] Base::Controller::_list_items: respect order by We now perform the SQL query with the default order that we show in the Web interface. --- .../lib/pfappserver/Base/Controller.pm | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/html/pfappserver/lib/pfappserver/Base/Controller.pm b/html/pfappserver/lib/pfappserver/Base/Controller.pm index 4b5121e89337..b89d69270736 100644 --- a/html/pfappserver/lib/pfappserver/Base/Controller.pm +++ b/html/pfappserver/lib/pfappserver/Base/Controller.pm @@ -125,18 +125,19 @@ sub _list_items { $params{'where'} = { type => 'any', like => $filter }; $c->stash->{filter} = $filter; } - if ( exists( $c->stash->{'by'} ) ) { - $orderby = $c->stash->{'by'}; - if ( grep { $_ eq $orderby } (@$field_names) ) { - $orderdirection = $c->stash->{'direction'}; - unless ( defined $orderdirection && grep { $_ eq $orderdirection } ( 'asc', 'desc' ) ) { - $orderdirection = 'asc'; - } - $params{'orderby'} = "ORDER BY $orderby $orderdirection"; - $c->stash->{by} = $orderby; - $c->stash->{direction} = $orderdirection; - } + + $orderby = $c->stash->{'by'}; + unless ( $orderby && grep { $_ eq $orderby } (@$field_names) ) { + $orderby = $field_names->[0]; } + $orderdirection = $c->stash->{'direction'}; + unless ( $orderdirection && grep { $_ eq $orderdirection } ( 'asc', 'desc' ) ) { + $orderdirection = 'asc'; + } + $params{'orderby'} = "ORDER BY $orderby $orderdirection"; + $c->stash->{by} = $orderby; + $c->stash->{direction} = $orderdirection; + my $count; ( $status, $result ) = $model->search(%params); if ( is_success($status) ) { @@ -148,7 +149,7 @@ sub _list_items { $c->stash->{count} = $count; $c->stash->{page_num} = $page_num; $c->stash->{per_page} = $per_page; - $c->stash->{by} = $orderby || $field_names->[0]; + $c->stash->{by} = $orderby; $c->stash->{direction} = $orderdirection || 'asc'; $c->stash->{items} = $items_ref; $c->stash->{field_names} = $field_names; From 59d4734f5bf044c8bb260a0edd31e7b20f6ff115 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Mon, 16 Sep 2013 14:59:30 -0400 Subject: [PATCH 045/369] Add the possibility to show nodes regdate --- html/pfappserver/lib/pfappserver/Model/Node.pm | 4 +++- html/pfappserver/lib/pfappserver/Model/Search/Node.pm | 3 ++- lib/pf/node.pm | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/html/pfappserver/lib/pfappserver/Model/Node.pm b/html/pfappserver/lib/pfappserver/Model/Node.pm index ed869fde3467..92149aadc15e 100644 --- a/html/pfappserver/lib/pfappserver/Model/Node.pm +++ b/html/pfappserver/lib/pfappserver/Model/Node.pm @@ -67,10 +67,12 @@ sub exists { =head2 field_names +Field names to be displayed. The first one is the default sort field. + =cut sub field_names { - return [qw(mac computername pid last_ip status dhcp_fingerprint)]; + return [qw(mac regdate computername pid last_ip status dhcp_fingerprint)]; } =head2 countAll diff --git a/html/pfappserver/lib/pfappserver/Model/Search/Node.pm b/html/pfappserver/lib/pfappserver/Model/Search/Node.pm index 5e81d87b251b..926b17c306f3 100644 --- a/html/pfappserver/lib/pfappserver/Model/Search/Node.pm +++ b/html/pfappserver/lib/pfappserver/Model/Search/Node.pm @@ -86,9 +86,10 @@ sub make_builder { return pf::SearchBuilder->new ->select(qw( mac pid voip bypass_vlan status category_id - detect_date regdate unregdate lastskip + detect_date unregdate lastskip user_agent computername last_arp last_dhcp notes), + L_("IF(regdate = '0000-00-00 00:00:00', '', regdate)", 'regdate'), L_('iplog.ip', 'last_ip'), L_("IF(ISNULL(node_category.name), '', node_category.name)", 'category'), L_("IFNULL(os_type.description, ' ')", 'dhcp_fingerprint') diff --git a/lib/pf/node.pm b/lib/pf/node.pm index 97a1b8bfbbc6..138eaa537417 100644 --- a/lib/pf/node.pm +++ b/lib/pf/node.pm @@ -228,7 +228,7 @@ sub node_db_prepare { $node_statements->{'node_view_all_sql'} = qq[ SELECT node.mac, node.pid, node.voip, node.bypass_vlan, node.status, IF(ISNULL(node_category.name), '', node_category.name) as category, - node.detect_date, node.regdate, node.unregdate, node.lastskip, + node.detect_date, IF(node.regdate = '0000-00-00 00:00:00', '', node.regdate) as regdate, node.unregdate, node.lastskip, node.user_agent, node.computername, IFNULL(os_type.description, ' ') as dhcp_fingerprint, node.last_arp, node.last_dhcp, locationlog.switch as last_switch, locationlog.port as last_port, locationlog.vlan as last_vlan, From a16f0b072a094885dcbe0519d421dbc4f532549c Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Mon, 16 Sep 2013 15:09:08 -0400 Subject: [PATCH 046/369] Cleanup of Search models --- html/pfappserver/lib/pfappserver/Model/Search/Node.pm | 11 +++++------ html/pfappserver/lib/pfappserver/Model/Search/User.pm | 9 ++++----- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/html/pfappserver/lib/pfappserver/Model/Search/Node.pm b/html/pfappserver/lib/pfappserver/Model/Search/Node.pm index 926b17c306f3..baf1cb817cab 100644 --- a/html/pfappserver/lib/pfappserver/Model/Search/Node.pm +++ b/html/pfappserver/lib/pfappserver/Model/Search/Node.pm @@ -49,10 +49,9 @@ sub do_query { my ($self, $builder, $params) = @_; my %results = %$params; my $sql = $builder->sql; - my ($per_page, $page_num, $by, $direction) = @{$params}{qw(per_page page_num by direction)}; + my ($per_page, $page_num) = @{$params}{qw(per_page page_num)}; $per_page ||= 25; $page_num ||= 1; - $direction ||= 'ASC'; my $itemsKey = $self->itemsKey; $results{$itemsKey} = [node_custom_search($sql)]; my $sql_count = $builder->sql_count; @@ -166,10 +165,10 @@ sub make_builder { } sub add_order_by { - my ($self,$builder,$params) = @_; - my ($by,$direction) = @$params{qw(by direction)}; - if($by && $direction) { - $builder->order_by($by,$direction); + my ($self, $builder, $params) = @_; + my ($by, $direction) = @$params{qw(by direction)}; + if ($by && $direction) { + $builder->order_by($by, $direction); } } diff --git a/html/pfappserver/lib/pfappserver/Model/Search/User.pm b/html/pfappserver/lib/pfappserver/Model/Search/User.pm index ec2c8cf0d7c2..d2e4238273cf 100644 --- a/html/pfappserver/lib/pfappserver/Model/Search/User.pm +++ b/html/pfappserver/lib/pfappserver/Model/Search/User.pm @@ -124,10 +124,9 @@ sub do_query { my $logger = Log::Log4perl::get_logger(__PACKAGE__); my %results = %$params; my $sql = $builder->sql; - my ($per_page,$page_num,$by,$direction) = @{$params}{qw(per_page page_num by direction)}; + my ($per_page, $page_num) = @{$params}{qw(per_page page_num)}; $per_page ||= 25; $page_num ||= 1; - $direction ||= 'asc'; my $itemsKey = $self->itemsKey; $results{$itemsKey} = [person_custom_search($sql)]; my $sql_count = $builder->sql_count; @@ -158,10 +157,10 @@ sub add_searches { } sub add_order_by { - my ($self,$builder,$params) = @_; - my ($by,$direction) = @$params{qw(by direction)}; + my ($self, $builder, $params) = @_; + my ($by, $direction) = @$params{qw(by direction)}; if($by && $direction) { - $builder->order_by($by,$direction); + $builder->order_by($by, $direction); } } From e73126df6ce5322c8fe9b9131ac54b5caeb3d099 Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Tue, 17 Sep 2013 09:44:30 -0400 Subject: [PATCH 047/369] Fix debian packaging --- debian/packetfence.conffiles | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/packetfence.conffiles b/debian/packetfence.conffiles index 80d2db84f20e..080f3f0acbd4 100644 --- a/debian/packetfence.conffiles +++ b/debian/packetfence.conffiles @@ -161,4 +161,5 @@ /usr/local/pf/raddb/sites-available/soh /usr/local/pf/raddb/sites-available/status /usr/local/pf/raddb/sites-available/virtual.example.com -/usr/local/pf/raddb/sites-available/vmps \ No newline at end of file +/usr/local/pf/raddb/sites-available/vmps + From 35ec662c9ad7bab7ae1c7450feff35eca66b6956 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Tue, 17 Sep 2013 10:49:06 -0400 Subject: [PATCH 048/369] Improve success msg in test method of LDAPSource --- .../lib/pfappserver/Controller/Authentication/Source.pm | 2 +- lib/pf/Authentication/Source/LDAPSource.pm | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/html/pfappserver/lib/pfappserver/Controller/Authentication/Source.pm b/html/pfappserver/lib/pfappserver/Controller/Authentication/Source.pm index c8e104913178..79023e5534c6 100644 --- a/html/pfappserver/lib/pfappserver/Controller/Authentication/Source.pm +++ b/html/pfappserver/lib/pfappserver/Controller/Authentication/Source.pm @@ -218,7 +218,7 @@ sub test :Local :Args(1) { } $c->response->status($status); - $c->stash->{status_msg} = $c->loc($message); + $c->stash->{status_msg} = $message; # TODO: localize status message $c->stash->{current_view} = 'JSON'; } diff --git a/lib/pf/Authentication/Source/LDAPSource.pm b/lib/pf/Authentication/Source/LDAPSource.pm index f8bab5ed5a4d..15ec1fefc2fc 100644 --- a/lib/pf/Authentication/Source/LDAPSource.pm +++ b/lib/pf/Authentication/Source/LDAPSource.pm @@ -274,7 +274,7 @@ sub test { my $result = $self->bind_with_credentials($connection); if ($result->is_error) { $logger->warn("Unable to bind with $self->{'binddn'} on $LDAPServer:$LDAPServerPort"); - return ($FALSE, "Unable to bind to $LDAPServer with these settings"); + return ($FALSE, ["Unable to bind to [_1] with these settings", $LDAPServer]); } # Search @@ -292,7 +292,7 @@ sub test { return ($FALSE, 'Wrong base DN or username attribute'); } - return ($TRUE, 'Success'); + return ($TRUE, 'LDAP connect, bind and search successful'); } =head2 ldap_filter_for_conditions From ff1f1cf69a5cee7b2b582a459b24370b8bb10c11 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Tue, 17 Sep 2013 11:00:29 -0400 Subject: [PATCH 049/369] Fix match in HtpasswdSource Fixes #1714 --- lib/pf/Authentication/Source/HtpasswdSource.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pf/Authentication/Source/HtpasswdSource.pm b/lib/pf/Authentication/Source/HtpasswdSource.pm index f11264bdec23..c6a576bbf6e5 100644 --- a/lib/pf/Authentication/Source/HtpasswdSource.pm +++ b/lib/pf/Authentication/Source/HtpasswdSource.pm @@ -72,7 +72,7 @@ sub match_in_subclass { my $password_file = $self->{'path'}; if (-r $password_file) { my $htpasswd = new Apache::Htpasswd({ passwdFile => $password_file, ReadOnly => 1}); - if ( defined($htpasswd->fetchPass($params->{'username'})) ) { + if ( $htpasswd->fetchPass($params->{'username'}) ) { # Username is defined in the htpasswd file # Let's match the htpasswd conditions alltogether. # We should only have conditions based on the username attribute. From 42d6440ab76de384f73ef39a60a036afb55d5223 Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Tue, 17 Sep 2013 11:49:30 -0400 Subject: [PATCH 050/369] Added CoA for Xirrus --- lib/pf/SNMP/Xirrus.pm | 106 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/lib/pf/SNMP/Xirrus.pm b/lib/pf/SNMP/Xirrus.pm index 44f167821283..8e648fd914c2 100644 --- a/lib/pf/SNMP/Xirrus.pm +++ b/lib/pf/SNMP/Xirrus.pm @@ -31,6 +31,8 @@ use base ('pf::SNMP'); use pf::config; use pf::SNMP::constants; use pf::util; +use pf::util::radius qw(perform_disconnect); +use Try::Tiny; sub description { 'Xirrus WiFi Arrays' } @@ -128,6 +130,108 @@ sub deauthenticateMacDefault { } +=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 = Log::Log4perl::get_logger( ref($self) ); + + 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"); + # TODO push Login-User => 1 (RFC2865) in pf::radius::constants if someone ever reads this + # (not done because it doesn't exist in current branch) + 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 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 = Log::Log4perl::get_logger( ref($self) ); + + # initialize + $add_attributes_ref = {} if (!defined($add_attributes_ref)); + + if (!defined($self->{'_radiusSecret'})) { + $logger->warn( + "Unable to perform RADIUS CoA-Request on $self->{'_ip'}: RADIUS Shared Secret not configured" + ); + return; + } + + $logger->info("deauthenticating $mac"); + + # Where should we send the RADIUS CoA-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 = { + nas_ip => $send_disconnect_to, + secret => $self->{'_radiusSecret'}, + LocalAddr => $management_network->tag('vip'), + }; + + # transforming MAC to the expected format 00-11-22-33-CA-FE + $mac = uc($mac); + $mac =~ s/:/-/g; + + # Standard Attributes + my $attributes_ref = { + }; + + # merging additional attributes provided by caller to the standard attributes + $attributes_ref = { %$attributes_ref, %$add_attributes_ref }; + + $response = perform_disconnect( $connection_info, + { + 'Calling-Station-Id' => $mac, + }, + ); + } catch { + chomp; + $logger->warn("Unable to perform RADIUS CoA-Request: $_"); + $logger->error("Wrong RADIUS secret or unreachable network device...") if ($_ =~ /^Timeout/); + }; + return if (!defined($response)); + + return $TRUE if ($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 deauthTechniques Return the reference to the deauth technique or the default deauth technique. @@ -140,6 +244,7 @@ sub deauthTechniques { my $default = $SNMP::SNMP; my %tech = ( $SNMP::SNMP => \&deauthenticateMacDefault, + $SNMP::RADIUS => \&deauthenticateMacRadius, ); if (!defined($method) || !defined($tech{$method})) { @@ -183,3 +288,4 @@ USA. # vim: set shiftwidth=4: # vim: set expandtab: # vim: set backspace=indent,eol,start: + From 481fb1c6492f5592d7c585a2f0f9af8c42779875 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 18 Sep 2013 13:33:44 -0400 Subject: [PATCH 051/369] Untaint parameters to sprintf --- lib/pf/services.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pf/services.pm b/lib/pf/services.pm index 6a355ac25c02..f34675e783f6 100644 --- a/lib/pf/services.pm +++ b/lib/pf/services.pm @@ -372,6 +372,7 @@ sub getPidFromFile { sub launchService { my ($daemon,@launcher_args) = @_; my $launcher = $service_launchers{$daemon}; + @launcher_args = map { /^(.+)$/;$1 } @launcher_args; if ($launcher) { my $logger = Log::Log4perl::get_logger('pf::services'); my $cmd_line = sprintf($launcher, @launcher_args); From 96555613480842d106544d5cc1669d52d8a96772 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 18 Sep 2013 14:03:19 -0400 Subject: [PATCH 052/369] Created a script to extract logs from a date to now --- addons/getlogs.sh | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100755 addons/getlogs.sh diff --git a/addons/getlogs.sh b/addons/getlogs.sh new file mode 100755 index 000000000000..88e9a78b6fe6 --- /dev/null +++ b/addons/getlogs.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +#Get the log for the current day + +DATE=now + +if [ -n "$1" ]; then + DATE=$1 +fi + +PATTERN1="$(date --date="$DATE" +'%b %d').*" + +PATTERN2="$(date --date="$DATE" +'\[%a %b %d').*" + +PATTERN3=".*?$(date --date="$DATE" +'\[%d/%b/%Y').*" + +PATTERN4="$(date --date="$DATE" +'%a %b %d').*" + +LOGDIR=/usr/local/pf/logs + +TEMPDIR=$(mktemp -d) + +TEMPLOGDIRNAME="logs-$(date +'%Y%m%d%H%M%S')" + +TEMPLOGDIR=$TEMPDIR/$TEMPLOGDIRNAME +mkdir $TEMPLOGDIR + +extract_log() { + PATTERN=$1 + shift + while [ "$#" != "0" ];do + LOGNAME="$1" + LOG="$LOGDIR/$LOGNAME" + grep -P -A"$(wc -l $LOG | cut -d' ' -f1)" "$PATTERN1" "$LOG" > "$TEMPLOGDIR/$LOGNAME" + shift + done +} + + +extract_log "$PATTERN1" catalyst.log packetfence.log +extract_log "$PATTERN2" admin_error_log portal_error_log webservices_error_log +extract_log "$PATTERN3" admin_access_log portal_access_log webservices_access_log +extract_log "$PATTERN4" radius.log + +#for log in catalyst.log packetfence.log;do +# LOG="$LOGDIR/$log" +# grep -P -A"$(wc -l $LOG | cut -d' ' -f1)" "$PATTERN1" "$LOG" > "$TEMPLOGDIR/$log" +#done + +#for log in admin_error_log portal_error_log webservices_error_log +#do +# LOG="$LOGDIR/$log" +# grep -P -A"$(wc -l $LOG | cut -d' ' -f1)" "$PATTERN2" "$LOG" > "$TEMPLOGDIR/$log" +#done + +#for log in admin_access_log portal_access_log webservices_access_log +#do +# LOG="$LOGDIR/$log" +# grep -P -A"$(wc -l $LOG | cut -d' ' -f1)" "$PATTERN3" "$LOG" > "$TEMPLOGDIR/$log" +#done + +#for log in radius.log;do +# LOG="$LOGDIR/$log" +# grep -P -A"$(wc -l $LOG | cut -d' ' -f1)" "$PATTERN4" "$LOG" > "$TEMPLOGDIR/$log" +#done + + +tar -C"$TEMPDIR" -zcf $TEMPLOGDIRNAME.tar.gz $TEMPLOGDIRNAME + +rm -rf $TEMPDIR From 073cb54f9ba08867a3cca04809849376472adef0 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 18 Sep 2013 14:27:07 -0400 Subject: [PATCH 053/369] Perform Sanity check on SwitchConfig coming from the cache --- lib/pf/SwitchFactory.pm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/pf/SwitchFactory.pm b/lib/pf/SwitchFactory.pm index c0d1c76b6a0e..38be8cd99728 100644 --- a/lib/pf/SwitchFactory.pm +++ b/lib/pf/SwitchFactory.pm @@ -70,7 +70,13 @@ $switches_cached_config = pf::config::cached->new( -oncachereload => [ on_cache_switches_reload => sub { my ($config, $name) = @_; - %SwitchConfig = %{$config->fromCacheUntainted("SwitchConfig")}; + my $data = $config->fromCacheUntainted("SwitchConfig"); + if($data) { + %SwitchConfig = %$data; + } else { + #if not found then call the onfilereload callback + $config->doCallbacks(1,0); + } }, ] ); From 79bf2b6fa9ed728b388c6029413e888acba2796d Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 18 Sep 2013 19:37:30 -0400 Subject: [PATCH 054/369] Untaint the launcher --- lib/pf/services.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/pf/services.pm b/lib/pf/services.pm index f34675e783f6..ad7d4db450bd 100644 --- a/lib/pf/services.pm +++ b/lib/pf/services.pm @@ -374,6 +374,8 @@ sub launchService { my $launcher = $service_launchers{$daemon}; @launcher_args = map { /^(.+)$/;$1 } @launcher_args; if ($launcher) { + $launcher =~ /^(.*)$/; + $launcher = $1; my $logger = Log::Log4perl::get_logger('pf::services'); my $cmd_line = sprintf($launcher, @launcher_args); $logger->info("Starting $daemon with '$cmd_line'"); From 6630a852c2df105968ee2349a36b273696499c8b Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 19 Sep 2013 10:58:11 -0400 Subject: [PATCH 055/369] If saved computed data was not in the cache then rerun the onfilereload callbacks --- lib/pf/authentication.pm | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/pf/authentication.pm b/lib/pf/authentication.pm index ed5a0e109d7c..4254be72d58e 100644 --- a/lib/pf/authentication.pm +++ b/lib/pf/authentication.pm @@ -38,6 +38,7 @@ use pf::Authentication::Source::GoogleSource; use pf::Authentication::Source::GithubSource; use List::Util qw(first); use List::MoreUtils qw(none any); +use pf::util; # The results... # @@ -213,8 +214,14 @@ sub readAuthenticationConfigFile { -oncachereload => [ on_cache_authentication_reload => sub { my ($config, $name) = @_; - %authentication_lookup = %{$config->fromCacheUntainted("authentication_lookup")}; - @authentication_sources = @{$config->fromCacheUntainted("authentication_sources")}; + my $authentication_lookup_ref = $config->fromCacheUntainted("authentication_lookup"); + my $authentication_sources_ref = $config->fromCacheUntainted("authentication_sources"); + if( all_defined($authentication_sources_ref, $authentication_lookup_ref)) { + %authentication_lookup = %$authentication_lookup_ref; + @authentication_sources = @$authentication_sources_ref; + } else { + $config->doCallbacks(1,0); + } }, ], -onpostreload => [ From cd5aedeb3feac054323e506cbfcd61534ec4ffd4 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 19 Sep 2013 10:59:30 -0400 Subject: [PATCH 056/369] Created all defined method --- lib/pf/util.pm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/pf/util.pm b/lib/pf/util.pm index 1c6365d45dbd..cd83c26aab52 100644 --- a/lib/pf/util.pm +++ b/lib/pf/util.pm @@ -26,6 +26,7 @@ use Net::SMTP; use POSIX(); use File::Spec::Functions; use File::Slurp qw(read_dir); +use List::MoreUtils qw(all); our ( %local_mac ); @@ -53,7 +54,7 @@ BEGIN { pf_run pfmailer generate_id load_oui download_oui trim_path format_bytes log_of ordinal_suffix - untaint_chain read_dir_recursive + untaint_chain read_dir_recursive all_defined ); } @@ -1137,6 +1138,10 @@ sub read_dir_recursive { return @files; } +sub all_defined { + all { defined $_ } @_; +} + =back =head1 AUTHOR From 3b6f17dc6a94466e8c5a224ed4dd7de3c6064dc2 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 19 Sep 2013 11:11:31 -0400 Subject: [PATCH 057/369] Removed commented code Allow date range to be enter free form ./addons/getlogs.sh 2 days ago instead of ./addons/getlogs.sh "2 days ago" --- addons/getlogs.sh | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/addons/getlogs.sh b/addons/getlogs.sh index 88e9a78b6fe6..ac2ab8249e15 100755 --- a/addons/getlogs.sh +++ b/addons/getlogs.sh @@ -4,8 +4,8 @@ DATE=now -if [ -n "$1" ]; then - DATE=$1 +if [ "$#" != "0" ]; then + DATE="$@" fi PATTERN1="$(date --date="$DATE" +'%b %d').*" @@ -36,35 +36,11 @@ extract_log() { done } - extract_log "$PATTERN1" catalyst.log packetfence.log extract_log "$PATTERN2" admin_error_log portal_error_log webservices_error_log extract_log "$PATTERN3" admin_access_log portal_access_log webservices_access_log extract_log "$PATTERN4" radius.log -#for log in catalyst.log packetfence.log;do -# LOG="$LOGDIR/$log" -# grep -P -A"$(wc -l $LOG | cut -d' ' -f1)" "$PATTERN1" "$LOG" > "$TEMPLOGDIR/$log" -#done - -#for log in admin_error_log portal_error_log webservices_error_log -#do -# LOG="$LOGDIR/$log" -# grep -P -A"$(wc -l $LOG | cut -d' ' -f1)" "$PATTERN2" "$LOG" > "$TEMPLOGDIR/$log" -#done - -#for log in admin_access_log portal_access_log webservices_access_log -#do -# LOG="$LOGDIR/$log" -# grep -P -A"$(wc -l $LOG | cut -d' ' -f1)" "$PATTERN3" "$LOG" > "$TEMPLOGDIR/$log" -#done - -#for log in radius.log;do -# LOG="$LOGDIR/$log" -# grep -P -A"$(wc -l $LOG | cut -d' ' -f1)" "$PATTERN4" "$LOG" > "$TEMPLOGDIR/$log" -#done - - tar -C"$TEMPDIR" -zcf $TEMPLOGDIRNAME.tar.gz $TEMPLOGDIRNAME rm -rf $TEMPDIR From 952c654508b9bfea4b22e822fd006d1cf80f73a5 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 25 Sep 2013 14:00:51 -0400 Subject: [PATCH 058/369] Remove Minor parts from the COPYRIGHT section --- html/pfappserver/lib/pfappserver/Form/Field/DynamicTable.pm | 1 - .../lib/pfappserver/Form/Widget/Field/DynamicTable.pm | 1 - .../lib/pfappserver/Form/Widget/Wrapper/DynamicTableRow.pm | 1 - lib/pf/CHI.pm | 1 - lib/pf/ConfigStore/Authentication.pm | 1 - lib/pf/ConfigStore/Role/ValidGenericID.pm | 1 - lib/pf/ConfigStore/Violations.pm | 1 - lib/pf/IniFiles.pm | 1 - lib/pf/WebAPI/AuthenHandler.pm | 1 - lib/pf/WebAPI/InitHandler.pm | 1 - lib/pf/cmd.pm | 1 - lib/pf/cmd/help.pm | 1 - lib/pf/cmd/roles/show_help.pm | 1 - lib/pf/cmd/roles/show_parent_help.pm | 1 - lib/pf/cmd/subcmd.pm | 1 - lib/pf/file_paths.pm | 1 - lib/pf/log.pm | 1 - lib/pf/pftest.pm | 1 - lib/pf/pftest/authentication.pm | 1 - lib/pf/pftest/help.pm | 1 - lib/pf/pftest/mysql.pm | 1 - lib/pf/radius/soapclient.pm | 1 - lib/pf/violation_config.pm | 1 - t/PfFilePaths.pm | 1 - 24 files changed, 24 deletions(-) diff --git a/html/pfappserver/lib/pfappserver/Form/Field/DynamicTable.pm b/html/pfappserver/lib/pfappserver/Form/Field/DynamicTable.pm index ce1f76a58edc..e6b137deb61a 100644 --- a/html/pfappserver/lib/pfappserver/Form/Field/DynamicTable.pm +++ b/html/pfappserver/lib/pfappserver/Form/Field/DynamicTable.pm @@ -40,7 +40,6 @@ sub BUILD { Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/html/pfappserver/lib/pfappserver/Form/Widget/Field/DynamicTable.pm b/html/pfappserver/lib/pfappserver/Form/Widget/Field/DynamicTable.pm index 70824a532d65..1934ce92d8e1 100644 --- a/html/pfappserver/lib/pfappserver/Form/Widget/Field/DynamicTable.pm +++ b/html/pfappserver/lib/pfappserver/Form/Widget/Field/DynamicTable.pm @@ -52,7 +52,6 @@ use namespace::autoclean; Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/html/pfappserver/lib/pfappserver/Form/Widget/Wrapper/DynamicTableRow.pm b/html/pfappserver/lib/pfappserver/Form/Widget/Wrapper/DynamicTableRow.pm index 753c1e5e61a3..c29648cf1027 100644 --- a/html/pfappserver/lib/pfappserver/Form/Widget/Wrapper/DynamicTableRow.pm +++ b/html/pfappserver/lib/pfappserver/Form/Widget/Wrapper/DynamicTableRow.pm @@ -33,7 +33,6 @@ use namespace::autoclean; Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/CHI.pm b/lib/pf/CHI.pm index a4e41c594361..45a9339ea1fd 100644 --- a/lib/pf/CHI.pm +++ b/lib/pf/CHI.pm @@ -59,7 +59,6 @@ __PACKAGE__->config(chiConfigFromIniFile()); Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/ConfigStore/Authentication.pm b/lib/pf/ConfigStore/Authentication.pm index a793a279d490..1b7ea785ec57 100644 --- a/lib/pf/ConfigStore/Authentication.pm +++ b/lib/pf/ConfigStore/Authentication.pm @@ -38,7 +38,6 @@ __PACKAGE__->meta->make_immutable; Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/ConfigStore/Role/ValidGenericID.pm b/lib/pf/ConfigStore/Role/ValidGenericID.pm index 754b4038cafc..124e599e6174 100644 --- a/lib/pf/ConfigStore/Role/ValidGenericID.pm +++ b/lib/pf/ConfigStore/Role/ValidGenericID.pm @@ -22,7 +22,6 @@ sub validId { $_[1] =~ /[a-zA-Z0-9_-]+/; } Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/ConfigStore/Violations.pm b/lib/pf/ConfigStore/Violations.pm index 854db900637d..30921b7a5475 100644 --- a/lib/pf/ConfigStore/Violations.pm +++ b/lib/pf/ConfigStore/Violations.pm @@ -151,7 +151,6 @@ sub cleanupBeforeCommit { Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/IniFiles.pm b/lib/pf/IniFiles.pm index 39894c6a7247..a385e8c72c4f 100644 --- a/lib/pf/IniFiles.pm +++ b/lib/pf/IniFiles.pm @@ -200,7 +200,6 @@ sub GetCurrentModTimestamp { Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/WebAPI/AuthenHandler.pm b/lib/pf/WebAPI/AuthenHandler.pm index 1dce0a9c3352..d46d2abb7fe5 100644 --- a/lib/pf/WebAPI/AuthenHandler.pm +++ b/lib/pf/WebAPI/AuthenHandler.pm @@ -60,7 +60,6 @@ sub handler { Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/WebAPI/InitHandler.pm b/lib/pf/WebAPI/InitHandler.pm index 1fbf026ed03d..1cb2eca4311c 100644 --- a/lib/pf/WebAPI/InitHandler.pm +++ b/lib/pf/WebAPI/InitHandler.pm @@ -29,7 +29,6 @@ sub handler { Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/cmd.pm b/lib/pf/cmd.pm index c43360acabd6..c09075ac5477 100644 --- a/lib/pf/cmd.pm +++ b/lib/pf/cmd.pm @@ -44,7 +44,6 @@ sub args { Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/cmd/help.pm b/lib/pf/cmd/help.pm index c1aca46501db..a521c347ea29 100644 --- a/lib/pf/cmd/help.pm +++ b/lib/pf/cmd/help.pm @@ -39,7 +39,6 @@ sub run { Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/cmd/roles/show_help.pm b/lib/pf/cmd/roles/show_help.pm index 8c115d4e426c..90162b45d404 100644 --- a/lib/pf/cmd/roles/show_help.pm +++ b/lib/pf/cmd/roles/show_help.pm @@ -34,7 +34,6 @@ sub showHelp { Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/cmd/roles/show_parent_help.pm b/lib/pf/cmd/roles/show_parent_help.pm index 2627b114081c..9f78e648d111 100644 --- a/lib/pf/cmd/roles/show_parent_help.pm +++ b/lib/pf/cmd/roles/show_parent_help.pm @@ -24,7 +24,6 @@ sub showHelp { Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/cmd/subcmd.pm b/lib/pf/cmd/subcmd.pm index e08188e36692..5d8a35381fd7 100644 --- a/lib/pf/cmd/subcmd.pm +++ b/lib/pf/cmd/subcmd.pm @@ -91,7 +91,6 @@ sub unknownActionCmd { Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/file_paths.pm b/lib/pf/file_paths.pm index 0fc0e6de8323..d56bcf6bc219 100644 --- a/lib/pf/file_paths.pm +++ b/lib/pf/file_paths.pm @@ -125,7 +125,6 @@ $dhcp_fingerprints_url = 'http://www.packetfence.org/dhcp_fingerprints.conf Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/log.pm b/lib/pf/log.pm index 59a3416793ff..737a9e247e8b 100644 --- a/lib/pf/log.pm +++ b/lib/pf/log.pm @@ -34,7 +34,6 @@ sub get_logger { Log::Log4perl->get_logger(@_); } Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/pftest.pm b/lib/pf/pftest.pm index b8b76ce4da65..cf7f1d6289ea 100644 --- a/lib/pf/pftest.pm +++ b/lib/pf/pftest.pm @@ -31,7 +31,6 @@ sub helpActionCmd { "pf::pftest::help" } Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/pftest/authentication.pm b/lib/pf/pftest/authentication.pm index 55d8089c0b11..622d752e06f7 100644 --- a/lib/pf/pftest/authentication.pm +++ b/lib/pf/pftest/authentication.pm @@ -78,7 +78,6 @@ sub colors_supported { return is_interactive() } Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/pftest/help.pm b/lib/pf/pftest/help.pm index 05ed96887a09..a271495f4cc5 100644 --- a/lib/pf/pftest/help.pm +++ b/lib/pf/pftest/help.pm @@ -19,7 +19,6 @@ use base qw(pf::cmd::help); Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/pftest/mysql.pm b/lib/pf/pftest/mysql.pm index dfff00fcd7a5..7c2718a3175e 100644 --- a/lib/pf/pftest/mysql.pm +++ b/lib/pf/pftest/mysql.pm @@ -21,7 +21,6 @@ use base qw(pf::cmd::subcmd); Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/radius/soapclient.pm b/lib/pf/radius/soapclient.pm index 8516767041c9..1ee22eddce49 100644 --- a/lib/pf/radius/soapclient.pm +++ b/lib/pf/radius/soapclient.pm @@ -139,7 +139,6 @@ sub build_soap_string { Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/violation_config.pm b/lib/pf/violation_config.pm index b1fc55436542..e640451b5d1f 100644 --- a/lib/pf/violation_config.pm +++ b/lib/pf/violation_config.pm @@ -118,7 +118,6 @@ sub readViolationConfigFile { Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/t/PfFilePaths.pm b/t/PfFilePaths.pm index 8ad9d733760e..d8ab4bcea171 100644 --- a/t/PfFilePaths.pm +++ b/t/PfFilePaths.pm @@ -28,7 +28,6 @@ BEGIN { Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT From 467d3a89775fd0f81f73ea083033653bb8940a5b Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 25 Sep 2013 14:17:17 -0400 Subject: [PATCH 059/369] Added new Auth Source Null --- .../Form/Authentication/Source/Null.pm | 54 ++++++++++++++++++ .../root/authentication/source/type/Null.tt | 1 + lib/pf/Authentication/Source/NullSource.pm | 57 +++++++++++++++++++ lib/pf/authentication.pm | 4 +- 4 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 html/pfappserver/lib/pfappserver/Form/Authentication/Source/Null.pm create mode 100644 html/pfappserver/root/authentication/source/type/Null.tt create mode 100644 lib/pf/Authentication/Source/NullSource.pm diff --git a/html/pfappserver/lib/pfappserver/Form/Authentication/Source/Null.pm b/html/pfappserver/lib/pfappserver/Form/Authentication/Source/Null.pm new file mode 100644 index 000000000000..031c5eb98ac5 --- /dev/null +++ b/html/pfappserver/lib/pfappserver/Form/Authentication/Source/Null.pm @@ -0,0 +1,54 @@ +package pfappserver::Form::Authentication::Source::Null; +=head1 NAME + +pfappserver::Form::Authentication::Source::Null add documentation + +=cut + +=head1 DESCRIPTION + +pfappserver::Form::Authentication::Source::Null + +=cut + +use strict; +use warnings; +use HTML::FormHandler::Moose; +extends 'pfappserver::Form::Authentication::Source'; + +# Form fields +has_field 'email_required' => + ( + type => 'Toggle', + widget => 'Switch', + ); + +=head1 AUTHOR + +Inverse inc. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + diff --git a/html/pfappserver/root/authentication/source/type/Null.tt b/html/pfappserver/root/authentication/source/type/Null.tt new file mode 100644 index 000000000000..b14ec2fea631 --- /dev/null +++ b/html/pfappserver/root/authentication/source/type/Null.tt @@ -0,0 +1 @@ +[% form.field('email_required').render %] diff --git a/lib/pf/Authentication/Source/NullSource.pm b/lib/pf/Authentication/Source/NullSource.pm new file mode 100644 index 000000000000..57f600dd872b --- /dev/null +++ b/lib/pf/Authentication/Source/NullSource.pm @@ -0,0 +1,57 @@ +package pf::Authentication::Source::NullSource; +=head1 NAME + +pf::Authentication::Source::NullSource add documentation + +=cut + +=head1 DESCRIPTION + +pf::Authentication::Source::NullSource + +=cut + +use strict; +use warnings; +use Moose; + +extends 'pf::Authentication::Source'; + +has '+type' => (default => 'Null'); +has '+unique' => (default => 1); +has 'email_required' => ( is=> 'rw', default => 0); + +sub match_in_subclass { + my ($self, $params, $rule, $own_conditions, $matching_conditions) = @_; + return $params->{'username'}; +} + +=head1 AUTHOR + +Inverse inc. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + diff --git a/lib/pf/authentication.pm b/lib/pf/authentication.pm index 4254be72d58e..015bc05f4c12 100644 --- a/lib/pf/authentication.pm +++ b/lib/pf/authentication.pm @@ -36,6 +36,7 @@ use pf::Authentication::Source::SQLSource; use pf::Authentication::Source::FacebookSource; use pf::Authentication::Source::GoogleSource; use pf::Authentication::Source::GithubSource; +use pf::Authentication::Source::NullSource; use List::Util qw(first); use List::MoreUtils qw(none any); use pf::util; @@ -91,7 +92,8 @@ our %TYPE_TO_SOURCE = ( 'sms' => pf::Authentication::Source::SMSSource->meta->name, 'facebook' => pf::Authentication::Source::FacebookSource->meta->name, 'google' => pf::Authentication::Source::GoogleSource->meta->name, - 'github' => pf::Authentication::Source::GithubSource->meta->name + 'github' => pf::Authentication::Source::GithubSource->meta->name, + 'null' => pf::Authentication::Source::NullSource->meta->name ); our $logger = get_logger(); From 3206b0cd1a9de7d6862e87f1130c32bf93244bfb Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 25 Sep 2013 16:23:25 -0400 Subject: [PATCH 060/369] Will only allow one Null Authentication Source --- .../lib/pfappserver/Form/Portal/Common.pm | 2 +- .../static/admin/configuration/portal_profile.js | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/html/pfappserver/lib/pfappserver/Form/Portal/Common.pm b/html/pfappserver/lib/pfappserver/Form/Portal/Common.pm index 356a3c8ce98f..b7de32f1cc67 100644 --- a/html/pfappserver/lib/pfappserver/Form/Portal/Common.pm +++ b/html/pfappserver/lib/pfappserver/Form/Portal/Common.pm @@ -23,7 +23,7 @@ use pf::authentication; =cut sub options_sources { - return map { { value => $_->id, label => $_->id } } @{getAllAuthenticationSources()}; + return map { { value => $_->id, label => $_->id, attributes => { 'data-source-type' => $_->type } } } @{getAllAuthenticationSources()}; } =head2 validate diff --git a/html/pfappserver/root/static/admin/configuration/portal_profile.js b/html/pfappserver/root/static/admin/configuration/portal_profile.js index 81411229f4d8..3e7c37088060 100644 --- a/html/pfappserver/root/static/admin/configuration/portal_profile.js +++ b/html/pfappserver/root/static/admin/configuration/portal_profile.js @@ -238,7 +238,9 @@ function initReadPage(element) { var rows = tbody.children(':not(.hidden)'); var row = rows.first(); var options = row.find("select option"); - if( rows.length < options.length){ + if (row.find('select').val() == 'null' ) { + row.find('[href="#add"]').addClass('hidden'); + } else if( rows.length < options.length ) { rows.find('[href="#add"]').removeClass('hidden'); } }); @@ -247,6 +249,16 @@ function initReadPage(element) { $('#sourcesEmpty').addClass('hidden'); return false; }); + $('#sources').on('change','select', function(event) { + var that = $(this); + var tr = that.closest('tr'); + if(that.find(':selected').attr('data-source-type') == 'Null') { + tr.siblings(':not(.hidden)').find('[href="#delete"]').click(); + tr.find('[href="#add"]').addClass('hidden'); + } else { + tr.find('[href="#add"]').removeClass('hidden'); + } + }); } function initTemplatesPage(element) { From e7fee889cb143c4689ab6c4f543cf1992f1439a0 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 25 Sep 2013 16:33:30 -0400 Subject: [PATCH 061/369] Will always return true when trying to authenticate --- lib/pf/Authentication/Source/NullSource.pm | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/pf/Authentication/Source/NullSource.pm b/lib/pf/Authentication/Source/NullSource.pm index 57f600dd872b..730efbc62e03 100644 --- a/lib/pf/Authentication/Source/NullSource.pm +++ b/lib/pf/Authentication/Source/NullSource.pm @@ -14,6 +14,7 @@ pf::Authentication::Source::NullSource use strict; use warnings; use Moose; +use pf::config qw($TRUE); extends 'pf::Authentication::Source'; @@ -26,6 +27,15 @@ sub match_in_subclass { return $params->{'username'}; } +=head2 authenticate + +=cut + +sub authenticate { + my ($self, $username, $password) = @_; + return ($TRUE, 'Successful authentication using null source.'); +} + =head1 AUTHOR Inverse inc. From 11a018cd6ab8aa5c6517cea2ee573e0b854428d0 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 26 Sep 2013 11:48:38 -0400 Subject: [PATCH 062/369] Make NullSource class exclusive --- lib/pf/Authentication/Source/NullSource.pm | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/pf/Authentication/Source/NullSource.pm b/lib/pf/Authentication/Source/NullSource.pm index 730efbc62e03..0f6d2aeacf68 100644 --- a/lib/pf/Authentication/Source/NullSource.pm +++ b/lib/pf/Authentication/Source/NullSource.pm @@ -14,10 +14,12 @@ pf::Authentication::Source::NullSource use strict; use warnings; use Moose; -use pf::config qw($TRUE); +use pf::config qw($FALSE $TRUE); +use Email::Valid; extends 'pf::Authentication::Source'; +has '+class' => (default => 'exclusive'); has '+type' => (default => 'Null'); has '+unique' => (default => 1); has 'email_required' => ( is=> 'rw', default => 0); @@ -33,7 +35,10 @@ sub match_in_subclass { sub authenticate { my ($self, $username, $password) = @_; - return ($TRUE, 'Successful authentication using null source.'); + if (!$self->email_required || Email::Valid->address($username) ) { + return ($TRUE, 'Successful authentication using null source.'); + } + return ($FALSE, 'Successful authentication using null source.'); } =head1 AUTHOR From 729cde94537ca5ef7419f6d690d2fe13def3cad9 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 26 Sep 2013 11:58:02 -0400 Subject: [PATCH 063/369] Added new class type exclusive --- .../pfappserver/Controller/Authentication.pm | 14 +++++---- .../lib/pfappserver/Form/Portal/Common.pm | 2 +- .../root/configuration/authentication.tt | 31 +++++++++++++++++++ .../admin/configuration/portal_profile.js | 4 +-- 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/html/pfappserver/lib/pfappserver/Controller/Authentication.pm b/html/pfappserver/lib/pfappserver/Controller/Authentication.pm index 5d6753930688..70480629088d 100644 --- a/html/pfappserver/lib/pfappserver/Controller/Authentication.pm +++ b/html/pfappserver/lib/pfappserver/Controller/Authentication.pm @@ -37,18 +37,20 @@ Show list of authentication sources. Allow user to order the list. sub index :Path :Args(0) { my ($self, $c) = @_; - my ($sources, $internal_types, $external_types, $form); + my ($sources); (undef, $sources) = $c->model('Config::Authentication')->readAll(); - $internal_types = availableAuthenticationSourceTypes('internal'); - $external_types = availableAuthenticationSourceTypes('external'); - $form = pfappserver::Form::Authentication->new(ctx => $c, + my $internal_types = availableAuthenticationSourceTypes('internal'); + my $external_types = availableAuthenticationSourceTypes('external'); + my $exclusive_types = availableAuthenticationSourceTypes('exclusive'); + my $form = pfappserver::Form::Authentication->new(ctx => $c, init_object => {sources => $sources}); $form->process(); $c->stash( - internal_types => $internal_types, - external_types => $external_types, + internal_types => $internal_types, + external_types => $external_types, + exclusive_types => $exclusive_types, form => $form, template => 'configuration/authentication.tt' ); diff --git a/html/pfappserver/lib/pfappserver/Form/Portal/Common.pm b/html/pfappserver/lib/pfappserver/Form/Portal/Common.pm index b7de32f1cc67..0c45a4009347 100644 --- a/html/pfappserver/lib/pfappserver/Form/Portal/Common.pm +++ b/html/pfappserver/lib/pfappserver/Form/Portal/Common.pm @@ -23,7 +23,7 @@ use pf::authentication; =cut sub options_sources { - return map { { value => $_->id, label => $_->id, attributes => { 'data-source-type' => $_->type } } } @{getAllAuthenticationSources()}; + return map { { value => $_->id, label => $_->id, attributes => { 'data-source-class' => $_->class } } } @{getAllAuthenticationSources()}; } =head2 validate diff --git a/html/pfappserver/root/configuration/authentication.tt b/html/pfappserver/root/configuration/authentication.tt index 861a4956bfb3..1c58f25d85c2 100644 --- a/html/pfappserver/root/configuration/authentication.tt +++ b/html/pfappserver/root/configuration/authentication.tt @@ -83,6 +83,32 @@ +

    [% l('Exclusive Sources') %]

    + + + + + + + + + + + + [% FOREACH source IN form.field('sources').fields %] + [% IF source.field('class').value == 'exclusive' %] + + + + + + + + [% END -%] + [% END -%] + +
    [% l('Name') %][% l('Description') %][% l('Type') %]
    [% source.field('id').render_element %][% source.field('id').value %][% source.field('description').value %][% l(source.field('type').value) %][% l('Delete') %]
    + [% END -%]
    @@ -102,6 +128,11 @@ [% FOREACH type IN external_types.sort -%]
  • [% l(type) %]
  • [% END -%] +
  • + + [% FOREACH type IN exclusive_types.sort -%] +
  • [% l(type) %]
  • + [% END -%]
    diff --git a/html/pfappserver/root/static/admin/configuration/portal_profile.js b/html/pfappserver/root/static/admin/configuration/portal_profile.js index 3e7c37088060..9665a3ab1ed7 100644 --- a/html/pfappserver/root/static/admin/configuration/portal_profile.js +++ b/html/pfappserver/root/static/admin/configuration/portal_profile.js @@ -238,7 +238,7 @@ function initReadPage(element) { var rows = tbody.children(':not(.hidden)'); var row = rows.first(); var options = row.find("select option"); - if (row.find('select').val() == 'null' ) { + if (options.filter(':selected').attr('data-source-class') == 'exclusive') { row.find('[href="#add"]').addClass('hidden'); } else if( rows.length < options.length ) { rows.find('[href="#add"]').removeClass('hidden'); @@ -252,7 +252,7 @@ function initReadPage(element) { $('#sources').on('change','select', function(event) { var that = $(this); var tr = that.closest('tr'); - if(that.find(':selected').attr('data-source-type') == 'Null') { + if(that.find(':selected').attr('data-source-class') == 'exclusive') { tr.siblings(':not(.hidden)').find('[href="#delete"]').click(); tr.find('[href="#add"]').addClass('hidden'); } else { From 637c5c09981a457e70cd503237228434a14eb6c1 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 26 Sep 2013 14:28:02 -0400 Subject: [PATCH 064/369] Added the Null Source type to the documentation --- docs/PacketFence_Administration_Guide.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/PacketFence_Administration_Guide.asciidoc b/docs/PacketFence_Administration_Guide.asciidoc index 82e5f99e0aa4..4aaf9bfd3438 100644 --- a/docs/PacketFence_Administration_Guide.asciidoc +++ b/docs/PacketFence_Administration_Guide.asciidoc @@ -422,6 +422,7 @@ PacketFence can authenticate users that register devices via the captive portal * Google (OAuth 2) * Kerberos * LDAP +* Null * RADIUS * SMS * Sponsored Email From 859b2320685cc57c4f1ec09fa069daa68bbcb407 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 26 Sep 2013 14:29:03 -0400 Subject: [PATCH 065/369] Added method getExclusiveSources --- lib/pf/Portal/Profile.pm | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/pf/Portal/Profile.pm b/lib/pf/Portal/Profile.pm index 213a8f55ae68..845e29a0c605 100644 --- a/lib/pf/Portal/Profile.pm +++ b/lib/pf/Portal/Profile.pm @@ -175,6 +175,17 @@ sub getExternalSources { return grep { $_->{'class'} eq 'external' } $self->getSourcesAsObjects(); } +=item getExclusiveSources + +Returns the exclusive authentication sources objects for the current captive portal profile. + +=cut + +sub getExclusiveSources { + my ($self) = @_; + return grep { $_->{'class'} eq 'exclusive' } $self->getSourcesAsObjects(); +} + =item getSourceByType Returns the first source object for the requested source type for the current captive portal profile. From feabd4ac31cdf9d33db72233b01f7ecf2e59ffa7 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 26 Sep 2013 14:30:03 -0400 Subject: [PATCH 066/369] Added self registration mode null --- lib/pf/config.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pf/config.pm b/lib/pf/config.pm index 3774b971f414..c01780a7440a 100644 --- a/lib/pf/config.pm +++ b/lib/pf/config.pm @@ -96,7 +96,7 @@ BEGIN { %connection_group %connection_group_to_str $RADIUS_API_LEVEL $VLAN_API_LEVEL $INLINE_API_LEVEL $AUTHENTICATION_API_LEVEL $SOH_API_LEVEL $BILLING_API_LEVEL $ROLE_API_LEVEL - $SELFREG_MODE_EMAIL $SELFREG_MODE_SMS $SELFREG_MODE_SPONSOR $SELFREG_MODE_GOOGLE $SELFREG_MODE_FACEBOOK $SELFREG_MODE_GITHUB + $SELFREG_MODE_EMAIL $SELFREG_MODE_SMS $SELFREG_MODE_SPONSOR $SELFREG_MODE_GOOGLE $SELFREG_MODE_FACEBOOK $SELFREG_MODE_GITHUB $SELFREG_MODE_NULL %CAPTIVE_PORTAL $HTTP $HTTPS normalize_time $TIME_MODIFIER_RE $ACCT_TIME_MODIFIER_RE @@ -289,6 +289,7 @@ Readonly our $SELFREG_MODE_SPONSOR => 'sponsoremail'; Readonly our $SELFREG_MODE_GOOGLE => 'google'; Readonly our $SELFREG_MODE_FACEBOOK => 'facebook'; Readonly our $SELFREG_MODE_GITHUB => 'github'; +Readonly our $SELFREG_MODE_NULL => 'null'; # SoH filters Readonly our $SOH_ACTION_ACCEPT => 'accept'; From a7c4e2c747f521d92f06cebe2ec66821af99511d Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 26 Sep 2013 14:41:43 -0400 Subject: [PATCH 067/369] Created drop down menus for each class type --- .../root/configuration/authentication.tt | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/html/pfappserver/root/configuration/authentication.tt b/html/pfappserver/root/configuration/authentication.tt index 1c58f25d85c2..dd2120dd17a2 100644 --- a/html/pfappserver/root/configuration/authentication.tt +++ b/html/pfappserver/root/configuration/authentication.tt @@ -119,20 +119,32 @@
    [% l('Add source') %]
    From 9b33906b588cacd7467da4425af1e15fec558ab7 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 26 Sep 2013 14:42:34 -0400 Subject: [PATCH 068/369] Fixed issue with authentication and email required --- lib/pf/Authentication/Source/NullSource.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pf/Authentication/Source/NullSource.pm b/lib/pf/Authentication/Source/NullSource.pm index 0f6d2aeacf68..9f262de1daaf 100644 --- a/lib/pf/Authentication/Source/NullSource.pm +++ b/lib/pf/Authentication/Source/NullSource.pm @@ -16,6 +16,7 @@ use warnings; use Moose; use pf::config qw($FALSE $TRUE); use Email::Valid; +use pf::util; extends 'pf::Authentication::Source'; @@ -35,7 +36,7 @@ sub match_in_subclass { sub authenticate { my ($self, $username, $password) = @_; - if (!$self->email_required || Email::Valid->address($username) ) { + if (isdisabled($self->email_required) || Email::Valid->address($username) ) { return ($TRUE, 'Successful authentication using null source.'); } return ($FALSE, 'Successful authentication using null source.'); From f98f319f50549fefa80c24239736a4308255f3fc Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 26 Sep 2013 14:45:56 -0400 Subject: [PATCH 069/369] Added the exclusive type to guest mode --- lib/pf/Portal/ProfileFactory.pm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/pf/Portal/ProfileFactory.pm b/lib/pf/Portal/ProfileFactory.pm index dda980d22c2e..297aaf3c790c 100644 --- a/lib/pf/Portal/ProfileFactory.pm +++ b/lib/pf/Portal/ProfileFactory.pm @@ -95,10 +95,14 @@ sub _custom_profile { sub _guest_modes_from_sources { my ($sources) = @_; $sources ||= []; + my %modeClasses = ( + external => undef, + exclusive => undef, + ); my %is_in = map { $_ => undef } @$sources; my @guest_modes = map { lc($_->type) } - grep { exists $is_in{$_->id} && $_->class eq 'external' } + grep { exists $is_in{$_->id} && exists $modeClasses{$_->class} } @authentication_sources; return \@guest_modes; From 92ef8ac41a085cb8474a0c3696216d762c78679b Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 26 Sep 2013 15:11:19 -0400 Subject: [PATCH 070/369] Added new type null --- conf/authentication.conf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/conf/authentication.conf b/conf/authentication.conf index b290e8cda9d4..ba70dcfc2c6e 100644 --- a/conf/authentication.conf +++ b/conf/authentication.conf @@ -44,3 +44,8 @@ description= match=all action0=set_role=guest action1=set_access_duration=1D + +[null] +description=Null Source +type=Null +email_required=disabled From 4dfdafe22a8650de8da6590a3f5a95847728fab0 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 26 Sep 2013 16:08:06 -0400 Subject: [PATCH 071/369] Added support for a null authentication source --- lib/pf/web.pm | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/pf/web.pm b/lib/pf/web.pm index 7cc2c9730784..5b1151c7eeba 100644 --- a/lib/pf/web.pm +++ b/lib/pf/web.pm @@ -36,6 +36,7 @@ use Log::Log4perl; use Readonly; use Template; use URI::Escape qw(uri_escape uri_unescape); +use List::MoreUtils qw(any); BEGIN { use Exporter (); @@ -297,10 +298,20 @@ sub generate_login_page { = is_in_list($SELFREG_MODE_FACEBOOK, $portalSession->getProfile->getGuestModes); $portalSession->stash->{'oauth2_github'} = is_in_list($SELFREG_MODE_GITHUB, $portalSession->getProfile->getGuestModes); + $portalSession->stash->{'null_source'} + = is_in_list($SELFREG_MODE_NULL, $portalSession->getProfile->getGuestModes); + $portalSession->stash->{'no_username'} = _no_username($portalSession); render_template($portalSession, $LOGIN_TEMPLATE); } +sub _no_username { + my ($portalSession) = @_; + return any {$_->type eq 'Null' && isdisabled($_->email_required) } + map { getAuthenticationSource($_) } + @{$portalSession->getProfile->getSources}; +} + sub generate_enabler_page { my ( $portalSession, $violation_id, $enable_text ) = @_; @@ -555,7 +566,10 @@ sub validate_form { $logger->trace("form validation attempt"); my $cgi = $portalSession->getCgi(); - if ( $cgi->param("username") && $cgi->param("password") ) { + my $no_password_needed = any {$_ eq 'null' } @{$portalSession->getProfile->getGuestModes}; + my $no_username_needed = _no_username($portalSession); + + if ( ($cgi->param("username") || $no_username_needed ) && ( $cgi->param("password") || $no_password_needed ) ) { # acceptable use pocliy accepted? if (!defined($cgi->param("aup_signed")) || !$cgi->param("aup_signed")) { return ( 0 , 'You need to accept the terms before proceeding any further.' ); @@ -579,11 +593,12 @@ sub web_user_authenticate { $logger->trace("authentication attempt"); my $session = $portalSession->getSession(); + my @sources = ($portalSession->getProfile->getInternalSources, $portalSession->getProfile->getExclusiveSources); + my $username = $portalSession->cgi->param("username"); + my $password = $portalSession->cgi->param("password"); # validate login and password - my ($return, $message, $source_id) = &pf::authentication::authenticate($portalSession->cgi->param("username"), - $portalSession->cgi->param("password"), - $portalSession->getProfile->getInternalSources); + my ($return, $message, $source_id) = pf::authentication::authenticate($username, $password, @sources); if (defined($return) && $return == 1) { # save login into session From 83b29f2196d2e35b5e2115d8279d646c4dbb6f2e Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 26 Sep 2013 16:09:02 -0400 Subject: [PATCH 072/369] Changed the default for email_required to disabled --- lib/pf/Authentication/Source/NullSource.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pf/Authentication/Source/NullSource.pm b/lib/pf/Authentication/Source/NullSource.pm index 9f262de1daaf..1afb1a41cd14 100644 --- a/lib/pf/Authentication/Source/NullSource.pm +++ b/lib/pf/Authentication/Source/NullSource.pm @@ -23,7 +23,7 @@ extends 'pf::Authentication::Source'; has '+class' => (default => 'exclusive'); has '+type' => (default => 'Null'); has '+unique' => (default => 1); -has 'email_required' => ( is=> 'rw', default => 0); +has 'email_required' => ( is=> 'rw', default => 'disabled'); sub match_in_subclass { my ($self, $params, $rule, $own_conditions, $matching_conditions) = @_; From b5e202eca0ef06cebf87f873adb07c34d3c01816 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 26 Sep 2013 16:10:29 -0400 Subject: [PATCH 073/369] Added values for the checkbox --- .../lib/pfappserver/Form/Authentication/Source/Null.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/html/pfappserver/lib/pfappserver/Form/Authentication/Source/Null.pm b/html/pfappserver/lib/pfappserver/Form/Authentication/Source/Null.pm index 031c5eb98ac5..ceb1358c9efe 100644 --- a/html/pfappserver/lib/pfappserver/Form/Authentication/Source/Null.pm +++ b/html/pfappserver/lib/pfappserver/Form/Authentication/Source/Null.pm @@ -21,6 +21,8 @@ has_field 'email_required' => ( type => 'Toggle', widget => 'Switch', + checkbox_value => 'enabled', + unchecked_value => 'disabled', ); =head1 AUTHOR From 1ccfc576d6b141bdb308d8338f725d38dc223b01 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 26 Sep 2013 16:13:01 -0400 Subject: [PATCH 074/369] Added support for the null authentication source --- html/captive-portal/templates/login.html | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/html/captive-portal/templates/login.html b/html/captive-portal/templates/login.html index fb09441bdb14..35c4e3ceacb9 100644 --- a/html/captive-portal/templates/login.html +++ b/html/captive-portal/templates/login.html @@ -60,13 +60,17 @@
    [%# User / Pass %] + [% UNLESS no_username %]
    - [% i18n("Username") %] + [% IF null_source %][% i18n("Email") %] [% ELSE %] [% i18n("Username") %][% END %]
    + [% END %] + [% UNLESS null_source %]
    [% i18n("Password") %]
    + [% END %] [%# submit %]
    @@ -90,7 +94,7 @@
    [% END %] - [% IF guest_allowed -%] + [% IF guest_allowed && !null_source -%]
    or
    [% i18n("Sign up") %] From aff72d60f99f147b9d49de6c43a8c3198578cb08 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 26 Sep 2013 16:13:16 -0400 Subject: [PATCH 075/369] Added support for the null authentication source --- html/captive-portal/register.cgi | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/html/captive-portal/register.cgi b/html/captive-portal/register.cgi index 1fe0aa5cf336..5b2fbccdc81b 100755 --- a/html/captive-portal/register.cgi +++ b/html/captive-portal/register.cgi @@ -2,7 +2,7 @@ =head1 NAME -register.cgi +register.cgi =head1 SYNOPSYS @@ -31,6 +31,7 @@ use pf::web::custom; # called last to allow redefinitions use pf::authentication; use pf::Authentication::constants; +use List::MoreUtils qw(any); Log::Log4perl->init("$conf_dir/log.conf"); my $logger = Log::Log4perl->get_logger('register.cgi'); @@ -58,8 +59,11 @@ $info{'pid'} = $cgi->remote_user || "admin"; # Pull browser user-agent string $info{'user_agent'} = $cgi->user_agent; -if (defined($cgi->param('username')) && $cgi->param('username') ne '') { - +my $no_password_needed = any {$_ eq 'null' } @{$portalSession->getProfile->getGuestModes}; +my $no_username_needed = pf::web::_no_username($portalSession); + +if ( (defined($cgi->param('username') ) || $no_username_needed ) && ($cgi->param('username') ne '' || $no_password_needed )) { + my ($form_return, $err) = pf::web::validate_form($portalSession); if ($form_return != 1) { $logger->trace("form validation failed or first time for " . $portalSession->getClientMac()); @@ -176,20 +180,20 @@ Inverse inc. Copyright (C) 2005-2013 Inverse inc. =head1 LICENSE - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -USA. - +USA. + =cut From 04913925f0bdf474201875702b3aa0a7034e47d3 Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Thu, 6 Jun 2013 16:13:50 -0400 Subject: [PATCH 076/369] Rewrite of feature proxy interception fir packetfence 4 Conflicts: lib/pf/iptables.pm --- conf/documentation.conf | 5 + conf/httpd.conf.d/httpd.proxy | 214 +++++++++++++++++++++++++++ conf/iptables.conf | 6 + conf/pf.conf.defaults | 6 + lib/pf/Portal/Session.pm | 8 +- lib/pf/iptables.pm | 88 +++++++++--- lib/pf/web/interceptproxy.pm | 263 ++++++++++++++++++++++++++++++++++ lib/pf/web/util.pm | 50 +++++++ 8 files changed, 617 insertions(+), 23 deletions(-) create mode 100644 conf/httpd.conf.d/httpd.proxy create mode 100644 lib/pf/web/interceptproxy.pm diff --git a/conf/documentation.conf b/conf/documentation.conf index af3bf151646a..05f49f13ddee 100644 --- a/conf/documentation.conf +++ b/conf/documentation.conf @@ -870,3 +870,8 @@ description=< + + LoadModule perl_module /usr/lib/apache2/modules/mod_perl.so + + + LoadModule log_config_module /usr/lib/apache2/modules/mod_log_config.so + + + LoadModule ssl_module /usr/lib/apache2/modules/mod_ssl.so + + + LoadModule headers_module /usr/lib/apache2/modules/mod_headers.so + + + LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so + + + LoadModule authz_host_module /usr/lib/apache2/modules/mod_authz_host.so + + + LoadModule setenvif_module /usr/lib/apache2/modules/mod_setenvif.so + + + LoadModule rewrite_module /usr/lib/apache2/modules/mod_rewrite.so + + + LoadModule alias_module /usr/lib/apache2/modules/mod_alias.so + + + LoadModule mime_module /usr/lib/apache2/modules/mod_mime.so + + + LoadModule apreq_module /usr/lib/apache2/modules/mod_apreq2.so + + + LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so + + + LoadModule proxy_connect_module /usr/lib/apache2/modules/mod_proxy_connect.so + + + +#RHEL specific + + + LoadModule perl_module modules/mod_perl.so + + + LoadModule log_config_module modules/mod_log_config.so + + + LoadModule ssl_module modules/mod_ssl.so + + + LoadModule headers_module modules/mod_headers.so + + + LoadModule proxy_module modules/mod_proxy.so + + + LoadModule authz_host_module modules/mod_authz_host.so + + + LoadModule setenvif_module modules/mod_setenvif.so + + + LoadModule rewrite_module modules/mod_rewrite.so + + + LoadModule alias_module modules/mod_alias.so + + + LoadModule mime_module modules/mod_mime.so + + + LoadModule apreq_module modules/mod_apreq2.so + + + LoadModule proxy_http_module modules/mod_proxy_http.so + + + LoadModule proxy_connect_module modules/mod_proxy_connect.so + + + +PerlSwitches -I/usr/local/pf/lib +#AddHandler perl-script .cgi +#Options +ExecCGI +#PerlHandler ModPerl::PerlRun + +# Prevent Browsers (Chrome and Firefox) to cache DNS while under the captive portal +Header always set X-DNS-Prefetch-Control off + + + Order deny,allow + Allow from all + + + + SSLOptions +StdEnvVars + + +SetEnvIf User-Agent ".*MSIE.*" \ + nokeepalive ssl-unclean-shutdown \ + downgrade-1.0 force-response-1.0 + +TypesConfig /etc/mime.types + + +use pf::config qw(); +use Tie::DxHash; +use pf::services::apache; + +sub gen_conf { + my %conf; + tie %conf, 'Tie::DxHash'; + + %conf = @_; + return \%conf; +} + +my $PfConfig = \%pf::config::Config; +my $management_network = $pf::config::management_network; +my $install_dir = $pf::config::install_dir; +my $var_dir = $pf::config::var_dir; +my @internal_nets = @pf::config::internal_nets; +my $host; + +$PidFile = $install_dir.'/var/run/httpd.proxy.pid'; + +$Include = $install_dir.'/conf/httpd.conf.d/log.conf'; + +$User = "pf"; +$Group = "pf"; + +$PerlOptions = "+GlobalRequest"; +$ProxyRequests = "Off"; + +if (defined($PfConfig->{'alerting'}{'fromaddr'}) && $PfConfig->{'alerting'}{'fromaddr'} ne '') { + $ServerAdmin = $PfConfig->{'alerting'}{'fromaddr'}; +} else { + $ServerAdmin = "root\@".$PfConfig->{'general'}{'hostname'}.".".$PfConfig->{'general'}{'domain'}; +} + +$ServerTokens = "Prod"; +$ServerSignature = "Off"; +$UseCanonicalName = "Off"; +$Timeout = "50"; +$KeepAliveTimeout = "10"; + +$MaxClients = pf::services::apache::calculate_max_clients(pf::services::apache::get_total_system_memory()); +$StartServers = pf::services::apache::calculate_start_servers($MaxClients); +$MinSpareServers = pf::services::apache::calculate_min_spare_servers($MaxClients); + +$HostnameLookups = "off"; +$MaxRequestsPerChild = "1000"; +$PerlInitHandler = "pf::WebAPI::InitHandler"; + + +$SSLPassPhraseDialog = "builtin"; +$SSLSessionCache = "dbm:".$install_dir."/var/ssl_scache"; +$SSLSessionCacheTimeout = "300"; +$SSLMutex = "file:".$install_dir."/var/ssl_mutex"; +$SSLRandomSeed = "startup builtin"; +$SSLRandomSeed = "connect builtin"; +$SSLCipherSuite = "ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL"; + +$ErrorLog = $install_dir.'/logs/proxy_error_log'; + +foreach my $port (split(',',$PfConfig->{'interception_proxy'}{'port'})) { + push (@NameVirtualHost,"*:".$port); +} + +push (@NameVirtualHost,"*:444"); + +foreach my $interface (@internal_nets) { + foreach my $port (split(',',$PfConfig->{'interception_proxy'}{'port'})) { + push (@Listen,$interface->{'Tip'}.":".$port); + push @{ $VirtualHost{$interface->{'Tip'}.":".$port} }, gen_conf( + ServerName => $PfConfig->{'general'}{'hostname'}.".".$PfConfig->{'general'}{'domain'}.":".$port, + PerlOptions => '+GlobalRequest', + PerlModule => 'pf::web::interceptproxy', + PerlTransHandler => '+pf::web::interceptproxy::translate', + ProxyRequests => 'On', + ProxyPreserveHost => 'On', + AllowCONNECT => '444 443', + ProxyVia => 'full', + ErrorLog => $install_dir.'/logs/proxy_error_log', + CustomLog => $install_dir.'/logs/proxy_access_log combined', + ); + } +} + +push (@Listen,"127.0.0.1:444"); + +push @{ VirtualHost{'127.0.0.1:444'} }, gen_conf( + ServerName => $PfConfig->{'general'}{'hostname'}.".".$PfConfig->{'general'}{'domain'}.":444", + PerlOptions => '+GlobalRequest', + PerlModule => 'pf::web::interceptproxy', + PerlTransHandler => '+pf::web::interceptproxy::reverse', + ProxyRequests => 'Off', + ProxyPreserveHost => 'On', + ProxyVia => 'Off', + ErrorLog => $install_dir.'/logs/reverse_reproxy_error_log', + CustomLog => $install_dir.'/logs/reverse_proxy_access_log combined', + SSLEngine => 'on', + SSLProxyEngine => 'on', + Include => $var_dir.'/conf/ssl-certificates.conf', +); + + diff --git a/conf/iptables.conf b/conf/iptables.conf index 7bf5cd551913..3af8013fb075 100644 --- a/conf/iptables.conf +++ b/conf/iptables.conf @@ -44,6 +44,7 @@ # HTTP (captive-portal) -A input-internal-vlan-if --protocol tcp --match tcp --dport 80 --jump ACCEPT -A input-internal-vlan-if --protocol tcp --match tcp --dport 443 --jump ACCEPT +%%input_inter_vlan_if%% :input-internal-inline-if - [0:0] # DHCP @@ -64,6 +65,7 @@ # allow everyone else behind inline interface (not registered, isolated, etc.) -A input-internal-inline-if --protocol tcp --match tcp --dport 80 --jump ACCEPT -A input-internal-inline-if --protocol tcp --match tcp --dport 443 --jump ACCEPT +%%input_inter_inline_rules%% :input-highavailability-if - [0:0] #SSH @@ -104,6 +106,9 @@ COMMIT :PREROUTING ACCEPT [0:0] :prerouting-int-inline-if - [0:0] %%nat_prerouting_inline%% +:prerouting-int-vlan-if - [0:0] +%%nat_prerouting_vlan%% + :POSTROUTING ACCEPT [0:0] # # NAT out (PAT actually) @@ -128,3 +133,4 @@ COMMIT # These will redirect to the proper chains based on conf/pf.conf's configuration %%nat_if_src_to_chain%% COMMIT + diff --git a/conf/pf.conf.defaults b/conf/pf.conf.defaults index a4aa09dd0d17..643395d98fd1 100644 --- a/conf/pf.conf.defaults +++ b/conf/pf.conf.defaults @@ -684,3 +684,9 @@ voip=no user = pass = +[interception_proxy] +# +# intercept_proxy.port +# +# Define the proxy port to intercept in vlan and in inline enforcement +port= diff --git a/lib/pf/Portal/Session.pm b/lib/pf/Portal/Session.pm index e0a9562ed992..ce3de982a851 100644 --- a/lib/pf/Portal/Session.pm +++ b/lib/pf/Portal/Session.pm @@ -174,18 +174,18 @@ sub _resolveIp { $proxied_lookup{$management_network->tag('vip')} = 1 if ($management_network && $management_network->tag('vip')); # if this is NOT from one of the expected proxy IPs return the IP - if (!$proxied_lookup{$directly_connected_ip}) { + if ( (!$proxied_lookup{$directly_connected_ip}) && !($directly_connected_ip ne '127.0.0.1') ) { return $directly_connected_ip; } # behind a proxy? if (defined($ENV{'HTTP_X_FORWARDED_FOR'})) { - my $proxied_ip = $ENV{'HTTP_X_FORWARDED_FOR'}; + my @proxied_ip = split(',',$ENV{'HTTP_X_FORWARDED_FOR'}); $logger->debug( "Remote Address is $directly_connected_ip. Client is behind proxy? " - . "Returning: $proxied_ip according to HTTP Headers" + . "Returning: $proxied_ip[0] according to HTTP Headers" ); - return $proxied_ip; + return $proxied_ip[0]; } $logger->debug("Remote Address is $directly_connected_ip but no further hints of client IP in HTTP Headers"); diff --git a/lib/pf/iptables.pm b/lib/pf/iptables.pm index e704bc54b6bb..a475b2464e2a 100644 --- a/lib/pf/iptables.pm +++ b/lib/pf/iptables.pm @@ -53,6 +53,7 @@ Readonly my $FW_FILTER_FORWARD_INT_VLAN => 'forward-internal-vlan-if'; Readonly my $FW_PREROUTING_INT_INLINE => 'prerouting-int-inline-if'; Readonly my $FW_POSTROUTING_INT_INLINE => 'postrouting-int-inline-if'; Readonly my $FW_POSTROUTING_INT_INLINE_ROUTED => 'postrouting-inline-routed'; +Readonly my $FW_PREROUTING_INT_VLAN => 'prerouting-int-vlan-if'; =head1 SUBROUTINES @@ -86,6 +87,7 @@ sub iptables_generate { 'mangle_if_src_to_chain' => '', 'mangle_prerouting_inline' => '', 'nat_if_src_to_chain' => '', 'nat_prerouting_inline' => '', 'nat_postrouting_vlan' => '', 'nat_postrouting_inline' => '', + 'input_inter_inline_rules' => '', 'nat_prerouting_vlan' => '', 'routed_postrouting_inline' => '', ); @@ -99,7 +101,7 @@ sub iptables_generate { if (is_inline_enforcement_enabled()) { # Note: I'm giving references to this guy here so he can directly mess with the tables $self->generate_inline_rules( - \$tags{'filter_forward_inline'}, \$tags{'nat_prerouting_inline'}, \$tags{'nat_postrouting_inline'},\$tags{'routed_postrouting_inline'} + \$tags{'filter_forward_inline'}, \$tags{'nat_prerouting_inline'}, \$tags{'nat_postrouting_inline'},\$tags{'routed_postrouting_inline'},\$tags{'input_inter_inline_rules'} ); # MANGLE @@ -111,7 +113,10 @@ sub iptables_generate { $tags{'nat_prerouting_inline'} .= $self->generate_nat_redirect_rules(); } - # OAuth and passthrough + #NAT Intercept Proxy + $self->generate_interception_rules(\$tags{'nat_if_src_to_chain'},\$tags{'nat_prerouting_vlan'},\$tags{'input_inter_vlan_if'} ); + + # OAuth my $google_enabled = $guest_self_registration{$SELFREG_MODE_GOOGLE}; my $facebook_enabled = $guest_self_registration{$SELFREG_MODE_FACEBOOK}; my $github_enabled = $guest_self_registration{$SELFREG_MODE_GITHUB}; @@ -161,7 +166,7 @@ sub generate_filter_if_src_to_chain { my $google_enabled = $guest_self_registration{$SELFREG_MODE_GOOGLE}; my $facebook_enabled = $guest_self_registration{$SELFREG_MODE_FACEBOOK}; my $github_enabled = $guest_self_registration{$SELFREG_MODE_GITHUB}; - my $passthrough_enabled = isenabled($Config{'trapping'}{'passthrough'}); + my $passthrough = isenabled($Config{'trapping'}{'passthrough'}); # internal interfaces handling foreach my $interface (@internal_nets) { @@ -176,7 +181,7 @@ sub generate_filter_if_src_to_chain { } $rules .= "-A INPUT --in-interface $dev -d $ip --jump $FW_FILTER_INPUT_INT_VLAN\n"; $rules .= "-A INPUT --in-interface $dev -d 255.255.255.255 --jump $FW_FILTER_INPUT_INT_VLAN\n"; - if ($google_enabled || $facebook_enabled || $github_enabled || $passthrough_enabled ) { + if ($google_enabled || $facebook_enabled || $github_enabled || $passthrough) { $rules .= "-A FORWARD --in-interface $dev --jump $FW_FILTER_FORWARD_INT_VLAN\n"; $rules .= "-A FORWARD --out-interface $dev --jump $FW_FILTER_FORWARD_INT_VLAN\n"; } @@ -232,21 +237,35 @@ Handling both FILTER and NAT tables at the same time. =cut sub generate_inline_rules { - my ($self,$filter_rules_ref, $nat_prerouting_ref, $nat_postrouting_ref, $routed_postrouting_inline) = @_; + my ($self,$filter_rules_ref, $nat_prerouting_ref, $nat_postrouting_ref, $routed_postrouting_inline, $input_filtering_ref) = @_; my $logger = Log::Log4perl::get_logger('pf::iptables'); $logger->info("Adding DNS DNAT rules for unregistered and isolated inline clients."); - foreach my $network ( keys %ConfigNetworks ) { - # skip non-inline interfaces - next if ( !pf::config::is_network_type_inline($network) ); - - my $rule = "--protocol udp --destination-port 53"; - $$nat_prerouting_ref .= "-A $FW_PREROUTING_INT_INLINE $rule --match mark --mark 0x$IPTABLES_MARK_UNREG " - . "--jump REDIRECT\n"; - $$nat_prerouting_ref .= "-A $FW_PREROUTING_INT_INLINE $rule --match mark --mark 0x$IPTABLES_MARK_ISOLATION " - . "--jump REDIRECT\n"; - last; - } + + my $rule = "--protocol udp --destination-port 53"; + $$nat_prerouting_ref .= "-A $FW_PREROUTING_INT_INLINE $rule --match mark --mark 0x$IPTABLES_MARK_UNREG " + . "--jump REDIRECT\n"; + $$nat_prerouting_ref .= "-A $FW_PREROUTING_INT_INLINE $rule --match mark --mark 0x$IPTABLES_MARK_ISOLATION " + . "--jump REDIRECT\n"; + + if (defined($Config{'interception_proxy'}{'port'})) { + $logger->info("Adding Proxy interception rules"); + foreach my $intercept_port ( split(',', $Config{'interception_proxy'}{'port'} ) ) { + my $rule = "--protocol tcp --destination-port $intercept_port"; + $$nat_prerouting_ref .= "-A $FW_PREROUTING_INT_INLINE $rule --match mark --mark 0x$IPTABLES_MARK_UNREG " + . "--jump REDIRECT\n"; + $$nat_prerouting_ref .= "-A $FW_PREROUTING_INT_INLINE $rule --match mark --mark 0x$IPTABLES_MARK_ISOLATION " + . "--jump REDIRECT\n"; + $$input_filtering_ref .= "-A $FW_FILTER_INPUT_INT_INLINE --protocol tcp --match tcp --dport $intercept_port " + . " --match mark --mark 0x$IPTABLES_MARK_UNREG --jump ACCEPT\n"; + $$input_filtering_ref .= "-A $FW_FILTER_INPUT_INT_INLINE --protocol tcp --match tcp --dport $intercept_port " + . " --match mark --mark 0x$IPTABLES_MARK_UNREG --jump ACCEPT\n"; + $$input_filtering_ref .= "-A $FW_FILTER_INPUT_INT_INLINE --protocol tcp --match tcp --dport $intercept_port " + . " --match mark --mark 0x$IPTABLES_MARK_REG --jump DROP\n"; + } + } + + $logger->info("Adding NAT Masquarade statement (PAT)"); $$nat_postrouting_ref .= "-A $FW_POSTROUTING_INT_INLINE --jump MASQUERADE\n"; @@ -258,7 +277,7 @@ sub generate_inline_rules { my $google_enabled = $guest_self_registration{$SELFREG_MODE_GOOGLE}; my $facebook_enabled = $guest_self_registration{$SELFREG_MODE_FACEBOOK}; my $github_enabled = $guest_self_registration{$SELFREG_MODE_GITHUB}; - my $passthrough_enabled = isenabled($Config{'trapping'}{'passthrough'}); + my $passthrough = isenabled($Config{'trapping'}{'passthrough'}); # Allow remote conformity scan server to reach unregistered devices in inline mode if ( defined($Config{'scan'}{'host'}) && $Config{'scan'}{'host'} ne "127.0.0.1" ) { @@ -433,9 +452,9 @@ sub generate_nat_redirect_rules { my $google_enabled = $guest_self_registration{$SELFREG_MODE_GOOGLE}; my $facebook_enabled = $guest_self_registration{$SELFREG_MODE_FACEBOOK}; my $github_enabled = $guest_self_registration{$SELFREG_MODE_GITHUB}; - my $passthrough_enabled = isenabled($Config{'trapping'}{'passthrough'}); + my $passthrough = isenabled($Config{'trapping'}{'passthrough'}); - if ($google_enabled||$facebook_enabled||$github_enabled||$passthrough_enabled) { + if ($google_enabled||$facebook_enabled||$github_enabled||$passthrough) { $rules .= "-A $FW_PREROUTING_INT_INLINE -m set --match-set pfsession_passthrough dst,dst ". "--match mark --mark 0x$IPTABLES_MARK_UNREG --jump ACCEPT\n"; } @@ -635,6 +654,37 @@ sub get_snat_interface { } } +=item generate_interception_rules + +Creating porper source interface matches to jump to the right chains for vlan enforcement method. + +=cut +sub generate_interception_rules { + my ($self, $nat_if_src_to_chain,$nat_prerouting_vlan, $input_inter_vlan_if) = @_; + my $logger = Log::Log4perl::get_logger('pf::iptables'); + + # internal interfaces handling + foreach my $interface (@internal_nets) { + my $dev = $interface->tag("int"); + my $enforcement_type = $Config{"interface $dev"}{'enforcement'}; + + # vlan enforcement + if ($enforcement_type eq $IF_ENFORCEMENT_VLAN) { + # send everything from vlan interfaces to the vlan chain + $$nat_if_src_to_chain .= "-A PREROUTING --in-interface $dev --jump $FW_PREROUTING_INT_VLAN\n"; + } + } + if (defined($Config{'interception_proxy'}{'port'})) { + foreach my $intercept_port ( split( ',', $Config{'interception_proxy'}{'port'} ) ) { + my $rule = "--protocol tcp --destination-port $intercept_port"; + $logger->warn($rule); + $$nat_prerouting_vlan .= "-A $FW_PREROUTING_INT_VLAN $rule --jump REDIRECT\n"; + $$input_inter_vlan_if .= "-A $FW_FILTER_INPUT_INT_VLAN $rule --jump ACCEPT\n"; + } + } + +} + =back diff --git a/lib/pf/web/interceptproxy.pm b/lib/pf/web/interceptproxy.pm new file mode 100644 index 000000000000..8a58e2940f6c --- /dev/null +++ b/lib/pf/web/interceptproxy.pm @@ -0,0 +1,263 @@ +package pf::web::interceptproxy; + +=head1 NAME + +interceptproxy.pm + +=cut + +use strict; +use warnings; + +use Apache2::Const -compile => qw(OK DECLINED HTTP_MOVED_TEMPORARILY); +use Apache2::RequestRec (); +use Apache2::RequestUtil; +use Apache2::Connection; +use Apache2::URI; + +use APR::URI; +use Log::Log4perl; +use URI::Escape qw(uri_escape); + +use pf::config; +use pf::util; +use pf::web::util; +#use pf::web::constants; + +use constant BUFF_LEN => 1024; + +=head1 SUBROUTINES + +=over + +=item translate + +Intercept proxy requests to forward them to the captive portal. + +=cut +sub translate { + my ($r) = shift; + my $logger = Log::Log4perl->get_logger(__PACKAGE__); + $logger->warn("hitting interceptor with URL: " . $r->uri); + #Fetch the captive portal URL + my $proto = isenabled($Config{'captive_portal'}{'secure_redirect'}) ? $HTTPS : $HTTP; + my $url = "$proto://".$Config{'general'}{'hostname'}.".".$Config{'general'}{'domain'}; + + my $parsed_portal = APR::URI->parse($r->pool, $url); + my $parsed_request = APR::URI->parse($r->pool, $r->uri); + + #in case of a Get request to another site than the captive portal, we redirect the request to the captive portal + if ( $parsed_request->scheme eq 'http' ) { + if ($parsed_portal->hostname ne $parsed_request->hostname) { + $logger->info("HTTP request redirect"); + $r->err_headers_out->set('Location' => $parsed_portal->unparse); + $r->content_type('text/html'); + $r->no_cache(1); + return Apache2::Const::HTTP_MOVED_TEMPORARILY; + } + } + + #in case of a CONNECT request we redirect the request to the reverse proxy + elsif ( $parsed_portal->hostname ne $parsed_request->scheme ) { + $logger->info("CONNECT request to reverseproxy"); + $r->parsed_uri->hostname('127.0.0.1'); + $r->parsed_uri->port('444'); + $r->uri('127.0.0.1:444'); + $r->pnotes( 'url_to_mod_proxy' => $r->uri ); + $r->handler('modperl'); + #Def FixupHandler + $r->set_handlers(PerlFixupHandler => \&fixup); + return Apache2::Const::OK; + } + + #The request match with the captive portal URL + + + #If it is an http request -> Forward to the captive portal + + if ( $parsed_request->scheme eq 'http' ) { + my $session_cook = pf::web::util::getcookie($r->headers_in->{Cookie}); + #If there is a session cookie then push the remote ip in the session and redirect to the captive portal + if ($session_cook) { + my (%session_id); + pf::web::util::session(\%session_id,$session_cook); + $session_id{remote_ip} = $r->connection->remote_ip; + my $uri = $parsed_portal->unparse; + $logger->info("http request redirect to captive portal"); + $r->err_headers_out->set('Location' => $uri); + $r->content_type('text/html'); + $r->no_cache(1); + return Apache2::Const::HTTP_MOVED_TEMPORARILY; + } + #if there is no cookie then proxy to captive portal + else { + $logger->warn($r->uri); + $parsed_portal->scheme(undef); + $parsed_portal->scheme('http'); + $logger->warn("DEBUG: ".$parsed_portal->unparse.$parsed_request->rpath); + $r->pnotes( 'url_to_mod_proxy' => $parsed_portal->unparse.$parsed_request->rpath ); + } + } else { + + #If it is a connect request -> forward to the reverse proxy + $r->parsed_uri->hostname('127.0.0.1'); + $r->parsed_uri->port('444'); + my $url = "127.0.0.1:444"; + $r->uri($url); + $r->pnotes( 'url_to_mod_proxy' => $r->uri ); + } + #Forward to mod_proxy + $r->handler('modperl'); + $r->set_handlers(PerlFixupHandler => \&fixup); + return Apache2::Const::OK; +} + +=item rewrite + +Rewrite Location header to Packetfence captive portal. + +=cut + +sub rewrite { + my $f = shift; + my $r = $f->r; + my $logger = Log::Log4perl->get_logger(__PACKAGE__); + if ($r->content_type =~ /text\/html(.*)/) { + unless ($f->ctx) { + my @valhead = $r->headers_out->get('Location'); + my $value = $Config{'general'}{'hostname'}.".".$Config{'general'}{'domain'}; + my $replacementheader = $r->hostname; + my $headval; + foreach $headval (@valhead) { + if ($headval && $headval =~ /$value/x) { + $headval =~ s/$value/$replacementheader/ig; + $r->headers_out->unset('Location'); + $r->headers_out->set('Location' => $headval); + } + } + } + my $ctx = $f->ctx; + while ($f->read(my $buffer, BUFF_LEN)) { + $ctx->{data} .= $buffer; + $ctx->{keepalives} = $f->c->keepalives; + $f->ctx($ctx); + } + # Thing we do at end + if ($f->seen_eos) { + # Dump datas out + $f->print($f->ctx->{data}); + } + return Apache2::Const::OK; + } else { + return Apache2::Const::DECLINED; + } +} + + +=item fixup + +Last Handler and last chance to do something in the request + +=cut + +sub fixup { + my $r = shift; + my $logger = Log::Log4perl->get_logger(__PACKAGE__); + if($r->pnotes('url_to_mod_proxy')){ + return proxy_redirect($r, $r->pnotes('url_to_mod_proxy')); + } +} + +=item proxy_redirect + +Mod_proxy redirect + +=cut + +sub proxy_redirect { + my ($r, $url) = @_; + my $logger = Log::Log4perl->get_logger(__PACKAGE__); + $r->set_handlers(PerlResponseHandler => []); + $r->filename("proxy:".$url); + $r->proxyreq(2); + $r->handler('proxy-server'); + return Apache2::Const::OK; +} + + +=item + +Reverse proxy TransHandler + +=cut +sub reverse { + my $r = shift; + my $logger = Log::Log4perl->get_logger(__PACKAGE__); + + my $parsed_request = APR::URI->parse($r->pool, $r->uri); + my $proto = isenabled($Config{'captive_portal'}{'secure_redirect'}) ? $HTTPS : $HTTP; + my $url = "$proto://".$Config{'general'}{'hostname'}.".".$Config{'general'}{'domain'}; + my $parsed_portal = APR::URI->parse($r->pool, $url); + $parsed_portal->scheme(undef); + $parsed_portal->scheme('http'); + my $session_cook = pf::web::util::getcookie($r->headers_in->{Cookie}); + + #If session cookie exist then we can set X-Forwarded-For and proxy to the captive portal + if ($session_cook) { + my (%session_id); + pf::web::util::session(\%session_id,$session_cook); + if ($session_id{remote_ip}) { + $r->headers_in->set('X-Forwarded-For' => $session_id{remote_ip}); + $r->headers_in->set('Host' => $Config{'general'}{'hostname'}); + my $url = "$proto://".$Config{'general'}{'hostname'}.".".$Config{'general'}{'domain'}; + $parsed_portal->scheme('https'); + my $url_proxy = $parsed_portal->unparse.$r->uri; + return proxy_redirect($r, $url_proxy); + } + #Cookie is invalid delete it + else { + $r->err_headers_out->add('Set-Cookie' => "packetfence=".$session_id{_session_id}."; expires=Thu, 01-Jan-70 00:00:01 GMT; domain=".$parsed_portal->hostname."; path=/"); + $r->err_headers_out->set('Location' => $parsed_portal->unparse); + $r->content_type('text/html'); + $r->no_cache(1); + return Apache2::Const::HTTP_MOVED_TEMPORARILY; + } + + } + #No session, create one and redirect to http portal to catch the remote ip + else { + my (%session_id); + pf::web::util::session(\%session_id); + $r->err_headers_out->add('Set-Cookie' => "packetfence=".$session_id{_session_id}."; domain=".$parsed_portal->hostname."; path=/"); + $r->err_headers_out->set('Location' => $parsed_portal->unparse); + $r->content_type('text/html'); + $r->no_cache(1); + return Apache2::Const::HTTP_MOVED_TEMPORARILY; + } +} + +=back + +=head1 AUTHOR + +Fabrice Durand + +=head1 COPYRIGHT +Copyright (C) 2012 Inverse inc. + +=head1 LICENSE +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. +=cut +1; + diff --git a/lib/pf/web/util.pm b/lib/pf/web/util.pm index fcb1032208d4..be476376f893 100644 --- a/lib/pf/web/util.pm +++ b/lib/pf/web/util.pm @@ -21,6 +21,8 @@ use warnings; use pf::config; use pf::util; use pf::web; +use Apache::Session::Generate::MD5; +use Apache::Session::Flex; use Cache::Memcached; BEGIN { @@ -274,6 +276,54 @@ sub del_memcached { $memd->delete($key); } +=item + +generate or retreive an apache session + +=cut + +sub session { + my ($session, $id) = @_; + eval { + tie %{$session}, 'Apache::Session::Flex', $id, { + Store => 'Memcached', + Lock => 'Null', + Generate => 'MD5', + Serialize => 'Storable', + Servers => get_memcached_conf(), + }; + } or session($session, undef); + + return $session; +} + +=item + +retreive packetfence cookie + +=cut + +sub getcookie { + my ($cookies) =@_; + my $logger = Log::Log4perl->get_logger(__PACKAGE__); + my $cleaned_cookies = ''; + if ( defined($cookies) ) { + foreach (split(';', $cookies)) { + if (/([^,; ]+)=([^,; ]+)/) { + if ($1 eq 'packetfence'){ + $cleaned_cookies .= $2; + } + } + } + if ($cleaned_cookies ne '') { + return $cleaned_cookies; + } + } + else { + return $FALSE; + } +} + =back =head1 AUTHOR From 4517340abe6d43945b4f42a97d23b69cda9ac299 Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Fri, 7 Jun 2013 14:29:20 -0400 Subject: [PATCH 077/369] Manage httpd.proxy service Apache configuration file in perl Packaging RPM/DEB Conflicts: debian/control lib/pf/services.pm --- addons/packages/packetfence.spec | 3 ++ conf/httpd.conf.d/httpd.proxy | 59 ++++++++++---------------------- debian/control | 3 +- lib/pf/services.pm | 9 +++-- lib/pf/web/interceptproxy.pm | 20 ++++++----- 5 files changed, 42 insertions(+), 52 deletions(-) diff --git a/addons/packages/packetfence.spec b/addons/packages/packetfence.spec index 84f80130084a..bf89935889b0 100644 --- a/addons/packages/packetfence.spec +++ b/addons/packages/packetfence.spec @@ -104,6 +104,8 @@ Requires: %{real_name}-pfcmd-suid Requires: perl(Bit::Vector) Requires: perl(CGI::Session), perl(CGI::Session::Driver::memcached), perl(JSON), perl(PHP::Session) Requires: perl(Apache2::Request) +Requires: perl(Apache::Session) +Requires: perl(Apache::Session::Memcached) Requires: perl(Class::Accessor) Requires: perl(Class::Accessor::Fast::Contained) Requires: perl(Class::Data::Inheritable) @@ -712,6 +714,7 @@ fi %config /usr/local/pf/conf/httpd.conf.d/captive-portal-common.conf %config /usr/local/pf/conf/httpd.conf.d/httpd.admin %config /usr/local/pf/conf/httpd.conf.d/httpd.portal +%config /usr/local/pf/conf/httpd.conf.d/httpd.proxy %config /usr/local/pf/conf/httpd.conf.d/httpd.webservices %config /usr/local/pf/conf/httpd.conf.d/log.conf %config(noreplace) /usr/local/pf/conf/httpd.conf.d/ssl-certificates.conf diff --git a/conf/httpd.conf.d/httpd.proxy b/conf/httpd.conf.d/httpd.proxy index 11ab2b26232a..35c8e86136a6 100644 --- a/conf/httpd.conf.d/httpd.proxy +++ b/conf/httpd.conf.d/httpd.proxy @@ -87,21 +87,11 @@ PerlSwitches -I/usr/local/pf/lib -#AddHandler perl-script .cgi -#Options +ExecCGI -#PerlHandler ModPerl::PerlRun +PerlModule APR::Table # Prevent Browsers (Chrome and Firefox) to cache DNS while under the captive portal Header always set X-DNS-Prefetch-Control off - - Order deny,allow - Allow from all - - - - SSLOptions +StdEnvVars - SetEnvIf User-Agent ".*MSIE.*" \ nokeepalive ssl-unclean-shutdown \ @@ -136,9 +126,6 @@ $Include = $install_dir.'/conf/httpd.conf.d/log.conf'; $User = "pf"; $Group = "pf"; -$PerlOptions = "+GlobalRequest"; -$ProxyRequests = "Off"; - if (defined($PfConfig->{'alerting'}{'fromaddr'}) && $PfConfig->{'alerting'}{'fromaddr'} ne '') { $ServerAdmin = $PfConfig->{'alerting'}{'fromaddr'}; } else { @@ -157,24 +144,33 @@ $MinSpareServers = pf::services::apache::calculate_min_spare_servers($MaxClients $HostnameLookups = "off"; $MaxRequestsPerChild = "1000"; -$PerlInitHandler = "pf::WebAPI::InitHandler"; -$SSLPassPhraseDialog = "builtin"; -$SSLSessionCache = "dbm:".$install_dir."/var/ssl_scache"; -$SSLSessionCacheTimeout = "300"; -$SSLMutex = "file:".$install_dir."/var/ssl_mutex"; -$SSLRandomSeed = "startup builtin"; -$SSLRandomSeed = "connect builtin"; -$SSLCipherSuite = "ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL"; - $ErrorLog = $install_dir.'/logs/proxy_error_log'; +$CustomLog = $install_dir.'/logs/proxy_access_log combined'; foreach my $port (split(',',$PfConfig->{'interception_proxy'}{'port'})) { push (@NameVirtualHost,"*:".$port); } push (@NameVirtualHost,"*:444"); +push (@Listen,"127.0.0.1:444"); +push @{ $VirtualHost{'*:444'} }, gen_conf( + ServerName => $PfConfig->{'general'}{'hostname'}.".".$PfConfig->{'general'}{'domain'}.":444", + PerlOptions => '+GlobalRequest', + SSLEngine => 'on', + SSLProxyEngine => 'on', + Include => $var_dir.'/conf/ssl-certificates.conf', + PerlModule => 'pf::web::interceptproxy', + PerlTransHandler => '+pf::web::interceptproxy::reverse', + ProxyRequests => 'off', + ProxyPreserveHost => 'on', + ProxyVia => 'off', + LogLevel => 'debug', + ErrorLog => $install_dir.'/logs/reverse_reproxy_error_log', + CustomLog => $install_dir.'/logs/reverse_proxy_access_log combined', +); + foreach my $interface (@internal_nets) { foreach my $port (split(',',$PfConfig->{'interception_proxy'}{'port'})) { @@ -194,21 +190,4 @@ foreach my $interface (@internal_nets) { } } -push (@Listen,"127.0.0.1:444"); - -push @{ VirtualHost{'127.0.0.1:444'} }, gen_conf( - ServerName => $PfConfig->{'general'}{'hostname'}.".".$PfConfig->{'general'}{'domain'}.":444", - PerlOptions => '+GlobalRequest', - PerlModule => 'pf::web::interceptproxy', - PerlTransHandler => '+pf::web::interceptproxy::reverse', - ProxyRequests => 'Off', - ProxyPreserveHost => 'On', - ProxyVia => 'Off', - ErrorLog => $install_dir.'/logs/reverse_reproxy_error_log', - CustomLog => $install_dir.'/logs/reverse_proxy_access_log combined', - SSLEngine => 'on', - SSLProxyEngine => 'on', - Include => $var_dir.'/conf/ssl-certificates.conf', -); - diff --git a/debian/control b/debian/control index 30fccefda8a5..bcaa56e8675d 100644 --- a/debian/control +++ b/debian/control @@ -20,7 +20,8 @@ Depends: ${misc:Depends}, vlan, make, # apache related apache2, apache2.2-common, apache2-utils, libapache2-mod-proxy-html, apache2-mpm-prefork, libapache2-mod-apreq2, libapache2-mod-perl2, - libapache2-request-perl, libtie-dxhash-perl, libapache-ssllookup-perl, + libapache2-request-perl, libtie-dxhash-perl, libapache-session-perl, + libapache-session-memcached-perl, libapache-ssllookup-perl, make, iproute, ipset, diff --git a/lib/pf/services.pm b/lib/pf/services.pm index ad7d4db450bd..6a545ab5446b 100644 --- a/lib/pf/services.pm +++ b/lib/pf/services.pm @@ -49,7 +49,7 @@ use pf::violation_config; use File::Slurp qw(read_file); Readonly our @APACHE_SERVICES => ( - 'httpd.admin', 'httpd.webservices', 'httpd.portal' + 'httpd.admin', 'httpd.webservices', 'httpd.portal', 'httpd.proxy' ); Readonly our @ALL_SERVICES => ( @@ -82,6 +82,7 @@ $service_launchers{'httpd'} = "%1\$s -f $conf_dir/httpd.conf"; $service_launchers{'httpd.webservices'} = "%1\$s -f $conf_dir/httpd.conf.d/httpd.webservices -D$OS"; $service_launchers{'httpd.admin'} = "%1\$s -f $conf_dir/httpd.conf.d/httpd.admin -D$OS"; $service_launchers{'httpd.portal'} = "%1\$s -f $conf_dir/httpd.conf.d/httpd.portal -D$OS"; +$service_launchers{'httpd.proxy'} = "%1\$s -f $conf_dir/httpd.conf.d/httpd.proxy -D$OS"; $service_launchers{'pfdetect'} = "%1\$s -d -p $install_dir/var/alert &"; $service_launchers{'pfmon'} = '%1$s -d &'; @@ -153,6 +154,7 @@ sub service_ctl { 'httpd' => \&generate_httpd_conf, 'httpd.webservices' => \&generate_httpd_conf, 'httpd.portal' => \&generate_httpd_conf, + 'httpd.proxy' => \&generate_httpd_conf, 'httpd.admin' => \&generate_httpd_conf, 'radiusd' => \&generate_radiusd_conf, 'snmptrapd' => \&generate_snmptrapd_conf @@ -167,7 +169,7 @@ sub service_ctl { # valid daemon and flags are set if (grep({ $daemon eq $_ } @ALL_SERVICES) && defined($service_launchers{$daemon})) { - if ( !( ($daemon eq 'pfdhcplistener' ) || ($daemon eq 'httpd') || ($daemon eq 'httpd.webservices') || ($daemon eq 'httpd.admin') || ($daemon eq 'httpd.portal') ) ) { + if ( !( ($daemon eq 'pfdhcplistener' ) || ($daemon eq 'httpd') || ($daemon eq 'httpd.webservices') || ($daemon eq 'httpd.admin') || ($daemon eq 'httpd.portal') || ($daemon eq 'httpd.proxy') ) ) { if ( $daemon eq 'dhcpd' ) { # create var/dhcpd/dhcpd.leases if it doesn't exist @@ -302,6 +304,9 @@ sub service_list { push @finalServiceList, $service if ( (is_inline_enforcement_enabled() || is_vlan_enforcement_enabled()) && isenabled($Config{'services'}{'pfdns'}) ); + } elsif ( $service eq "httpd.proxy" ) { + push @finalServiceList, $service + if ( defined($Config{'interception_proxy'}{'port'}) ); } elsif ( $service eq 'pfdhcplistener' ) { push @finalServiceList, $service if ( isenabled($Config{'network'}{'dhcpdetector'}) ); diff --git a/lib/pf/web/interceptproxy.pm b/lib/pf/web/interceptproxy.pm index 8a58e2940f6c..ad8ffbb45c3f 100644 --- a/lib/pf/web/interceptproxy.pm +++ b/lib/pf/web/interceptproxy.pm @@ -9,6 +9,8 @@ interceptproxy.pm use strict; use warnings; +use Apache2::Reload; + use Apache2::Const -compile => qw(OK DECLINED HTTP_MOVED_TEMPORARILY); use Apache2::RequestRec (); use Apache2::RequestUtil; @@ -49,7 +51,7 @@ sub translate { #in case of a Get request to another site than the captive portal, we redirect the request to the captive portal if ( $parsed_request->scheme eq 'http' ) { if ($parsed_portal->hostname ne $parsed_request->hostname) { - $logger->info("HTTP request redirect"); + $logger->trace("HTTP request redirect to captive portal"); $r->err_headers_out->set('Location' => $parsed_portal->unparse); $r->content_type('text/html'); $r->no_cache(1); @@ -59,7 +61,7 @@ sub translate { #in case of a CONNECT request we redirect the request to the reverse proxy elsif ( $parsed_portal->hostname ne $parsed_request->scheme ) { - $logger->info("CONNECT request to reverseproxy"); + $logger->trace("CONNECT request to reverseproxy"); $r->parsed_uri->hostname('127.0.0.1'); $r->parsed_uri->port('444'); $r->uri('127.0.0.1:444'); @@ -83,7 +85,7 @@ sub translate { pf::web::util::session(\%session_id,$session_cook); $session_id{remote_ip} = $r->connection->remote_ip; my $uri = $parsed_portal->unparse; - $logger->info("http request redirect to captive portal"); + $logger->trace("http request redirect to captive portal, we have the cookie"); $r->err_headers_out->set('Location' => $uri); $r->content_type('text/html'); $r->no_cache(1); @@ -91,19 +93,20 @@ sub translate { } #if there is no cookie then proxy to captive portal else { - $logger->warn($r->uri); + $logger->trace("No cookie then proxy to the captive portal"); $parsed_portal->scheme(undef); $parsed_portal->scheme('http'); $logger->warn("DEBUG: ".$parsed_portal->unparse.$parsed_request->rpath); $r->pnotes( 'url_to_mod_proxy' => $parsed_portal->unparse.$parsed_request->rpath ); } } else { - - #If it is a connect request -> forward to the reverse proxy + #If it is a connect request -> forward to the reverse proxy + $logger->trace("CONNECT request to the captive portal :".$r->uri); $r->parsed_uri->hostname('127.0.0.1'); $r->parsed_uri->port('444'); my $url = "127.0.0.1:444"; $r->uri($url); + $logger->warn("CONNECT request to the captive portal :".$r->uri); $r->pnotes( 'url_to_mod_proxy' => $r->uri ); } #Forward to mod_proxy @@ -193,7 +196,7 @@ Reverse proxy TransHandler sub reverse { my $r = shift; my $logger = Log::Log4perl->get_logger(__PACKAGE__); - + $logger->trace("Reverse proxy :".$r->uri); my $parsed_request = APR::URI->parse($r->pool, $r->uri); my $proto = isenabled($Config{'captive_portal'}{'secure_redirect'}) ? $HTTPS : $HTTP; my $url = "$proto://".$Config{'general'}{'hostname'}.".".$Config{'general'}{'domain'}; @@ -208,7 +211,7 @@ sub reverse { pf::web::util::session(\%session_id,$session_cook); if ($session_id{remote_ip}) { $r->headers_in->set('X-Forwarded-For' => $session_id{remote_ip}); - $r->headers_in->set('Host' => $Config{'general'}{'hostname'}); + $r->headers_in->set('Host' => $Config{'general'}{'hostname'}.".".$Config{'general'}{'domain'}); my $url = "$proto://".$Config{'general'}{'hostname'}.".".$Config{'general'}{'domain'}; $parsed_portal->scheme('https'); my $url_proxy = $parsed_portal->unparse.$r->uri; @@ -260,4 +263,3 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. =cut 1; - From 80e1bfebd403315849f45f9eb0c6d7ec69e5d746 Mon Sep 17 00:00:00 2001 From: Fabrice Durand Date: Sun, 30 Jun 2013 15:23:53 -0400 Subject: [PATCH 078/369] Fix pfcmd help and remove rebase stuff Conflicts: lib/pf/services.pm --- lib/pf/pfcmd/help.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pf/pfcmd/help.pm b/lib/pf/pfcmd/help.pm index e4b6649f3ad1..2567f8ee5b17 100644 --- a/lib/pf/pfcmd/help.pm +++ b/lib/pf/pfcmd/help.pm @@ -117,10 +117,11 @@ Services managed by PacketFence: httpd.webservices| Apache Webservices httpd.admin | Apache Web admin httpd.portal | Apache Captive Portal - pfdns | DNS daemon + httpd.proxy | Apache Proxy Interception pf | all services that should be running based on your config pfdetect | PF snort alert parser pfdhcplistener | PF DHCP monitoring daemon + pfdns | DNS daemon pfmon | PF ARP monitoring daemon pfsetvlan | PF VLAN isolation daemon radiusd | FreeRADIUS daemon From e559a4e50cca23fc8686a1c55069cd92819808fa Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Fri, 19 Jul 2013 09:25:47 -0400 Subject: [PATCH 079/369] Fix for test --- lib/pf/web/interceptproxy.pm | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/pf/web/interceptproxy.pm b/lib/pf/web/interceptproxy.pm index ad8ffbb45c3f..79bf89a37600 100644 --- a/lib/pf/web/interceptproxy.pm +++ b/lib/pf/web/interceptproxy.pm @@ -9,8 +9,6 @@ interceptproxy.pm use strict; use warnings; -use Apache2::Reload; - use Apache2::Const -compile => qw(OK DECLINED HTTP_MOVED_TEMPORARILY); use Apache2::RequestRec (); use Apache2::RequestUtil; @@ -24,7 +22,6 @@ use URI::Escape qw(uri_escape); use pf::config; use pf::util; use pf::web::util; -#use pf::web::constants; use constant BUFF_LEN => 1024; @@ -243,7 +240,7 @@ sub reverse { =head1 AUTHOR -Fabrice Durand +Inverse inc. =head1 COPYRIGHT Copyright (C) 2012 Inverse inc. From 9d7643600e5d47eb85d63f2f3b4f51dd53beb95e Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Tue, 17 Sep 2013 16:23:27 -0400 Subject: [PATCH 080/369] Passthrough fix --- lib/pf/iptables.pm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/pf/iptables.pm b/lib/pf/iptables.pm index a475b2464e2a..6e02e3fa31fb 100644 --- a/lib/pf/iptables.pm +++ b/lib/pf/iptables.pm @@ -166,7 +166,7 @@ sub generate_filter_if_src_to_chain { my $google_enabled = $guest_self_registration{$SELFREG_MODE_GOOGLE}; my $facebook_enabled = $guest_self_registration{$SELFREG_MODE_FACEBOOK}; my $github_enabled = $guest_self_registration{$SELFREG_MODE_GITHUB}; - my $passthrough = isenabled($Config{'trapping'}{'passthrough'}); + my $passthrough_enabled = isenabled($Config{'trapping'}{'passthrough'}); # internal interfaces handling foreach my $interface (@internal_nets) { @@ -181,7 +181,7 @@ sub generate_filter_if_src_to_chain { } $rules .= "-A INPUT --in-interface $dev -d $ip --jump $FW_FILTER_INPUT_INT_VLAN\n"; $rules .= "-A INPUT --in-interface $dev -d 255.255.255.255 --jump $FW_FILTER_INPUT_INT_VLAN\n"; - if ($google_enabled || $facebook_enabled || $github_enabled || $passthrough) { + if ($google_enabled || $facebook_enabled || $github_enabled || $passthrough_enabled) { $rules .= "-A FORWARD --in-interface $dev --jump $FW_FILTER_FORWARD_INT_VLAN\n"; $rules .= "-A FORWARD --out-interface $dev --jump $FW_FILTER_FORWARD_INT_VLAN\n"; } @@ -277,7 +277,7 @@ sub generate_inline_rules { my $google_enabled = $guest_self_registration{$SELFREG_MODE_GOOGLE}; my $facebook_enabled = $guest_self_registration{$SELFREG_MODE_FACEBOOK}; my $github_enabled = $guest_self_registration{$SELFREG_MODE_GITHUB}; - my $passthrough = isenabled($Config{'trapping'}{'passthrough'}); + my $passthrough_enabled = isenabled($Config{'trapping'}{'passthrough'}); # Allow remote conformity scan server to reach unregistered devices in inline mode if ( defined($Config{'scan'}{'host'}) && $Config{'scan'}{'host'} ne "127.0.0.1" ) { @@ -452,9 +452,9 @@ sub generate_nat_redirect_rules { my $google_enabled = $guest_self_registration{$SELFREG_MODE_GOOGLE}; my $facebook_enabled = $guest_self_registration{$SELFREG_MODE_FACEBOOK}; my $github_enabled = $guest_self_registration{$SELFREG_MODE_GITHUB}; - my $passthrough = isenabled($Config{'trapping'}{'passthrough'}); + my $passthrough_enabled = isenabled($Config{'trapping'}{'passthrough'}); - if ($google_enabled||$facebook_enabled||$github_enabled||$passthrough) { + if ($google_enabled||$facebook_enabled||$github_enabled||$passthrough_enabled) { $rules .= "-A $FW_PREROUTING_INT_INLINE -m set --match-set pfsession_passthrough dst,dst ". "--match mark --mark 0x$IPTABLES_MARK_UNREG --jump ACCEPT\n"; } From 1e4064d689fcb02703e09a75bc0a343edb6fc4bc Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Thu, 19 Sep 2013 11:27:30 -0400 Subject: [PATCH 081/369] Move proxy interception in trapping section --- conf/documentation.conf | 27 +++++++++++++++++---- conf/httpd.conf.d/httpd.proxy | 4 +-- conf/pf.conf.defaults | 17 ++++++++----- html/pfappserver/lib/pfappserver/I18N/en.po | 8 ++++++ lib/pf/iptables.pm | 10 ++++---- lib/pf/services.pm | 2 +- 6 files changed, 49 insertions(+), 19 deletions(-) diff --git a/conf/documentation.conf b/conf/documentation.conf index 05f49f13ddee..a63cf273b5c9 100644 --- a/conf/documentation.conf +++ b/conf/documentation.conf @@ -295,6 +295,28 @@ The configuration parameter "passthrough" must be enabled for passthroughs to be effective. EOT +[trapping.proxy_passthroughs] +type=list +description=<{'interception_proxy'}{'port'})) { +foreach my $port (split(',',$PfConfig->{'trapping'}{'interception_proxy_port'})) { push (@NameVirtualHost,"*:".$port); } @@ -173,7 +173,7 @@ push @{ $VirtualHost{'*:444'} }, gen_conf( foreach my $interface (@internal_nets) { - foreach my $port (split(',',$PfConfig->{'interception_proxy'}{'port'})) { + foreach my $port (split(',',$PfConfig->{'trapping'}{'interception_proxy_port'})) { push (@Listen,$interface->{'Tip'}.":".$port); push @{ $VirtualHost{$interface->{'Tip'}.":".$port} }, gen_conf( ServerName => $PfConfig->{'general'}{'hostname'}.".".$PfConfig->{'general'}{'domain'}.":".$port, diff --git a/conf/pf.conf.defaults b/conf/pf.conf.defaults index 643395d98fd1..182fc5aa3c80 100644 --- a/conf/pf.conf.defaults +++ b/conf/pf.conf.defaults @@ -162,6 +162,17 @@ passthroughs= # # Comma-delimited list of domains to be use for apache passthrough proxy_passthroughs= +# +# trapping.interception_proxy +# +# When enabled, packetfence will intercept proxy request to somes specified port +interception_proxy=disabled +# +# trapping.interception_proxy_port +# +# Comma-delimited list of port used to intercept proxy traffic +interception_proxy_port=8080,3128 + [registration] # @@ -684,9 +695,3 @@ voip=no user = pass = -[interception_proxy] -# -# intercept_proxy.port -# -# Define the proxy port to intercept in vlan and in inline enforcement -port= diff --git a/html/pfappserver/lib/pfappserver/I18N/en.po b/html/pfappserver/lib/pfappserver/I18N/en.po index e4ae665f9c5c..886f6f04b24f 100644 --- a/html/pfappserver/lib/pfappserver/I18N/en.po +++ b/html/pfappserver/lib/pfappserver/I18N/en.po @@ -3709,6 +3709,14 @@ msgstr "Passthroughs" msgid "trapping.proxy_passthroughs" msgstr "Proxy Passthroughs" +# conf/documentation.conf +msgid "trapping.interception_proxy" +msgstr "Proxy Interception" + +# conf/documentation.conf +msgid "trapping.interception_proxy_port" +msgstr "Proxy Interception Port" + # conf/documentation.conf msgid "trapping.range" msgstr "Addresses ranges" diff --git a/lib/pf/iptables.pm b/lib/pf/iptables.pm index 6e02e3fa31fb..007a32ffa77c 100644 --- a/lib/pf/iptables.pm +++ b/lib/pf/iptables.pm @@ -88,7 +88,7 @@ sub iptables_generate { 'nat_if_src_to_chain' => '', 'nat_prerouting_inline' => '', 'nat_postrouting_vlan' => '', 'nat_postrouting_inline' => '', 'input_inter_inline_rules' => '', 'nat_prerouting_vlan' => '', - 'routed_postrouting_inline' => '', + 'routed_postrouting_inline' => '','input_inter_vlan_if' => '', ); # global substitution variables @@ -248,9 +248,9 @@ sub generate_inline_rules { $$nat_prerouting_ref .= "-A $FW_PREROUTING_INT_INLINE $rule --match mark --mark 0x$IPTABLES_MARK_ISOLATION " . "--jump REDIRECT\n"; - if (defined($Config{'interception_proxy'}{'port'})) { + if (defined($Config{'trapping'}{'interception_proxy_port'}) && isenabled($Config{'trapping'}{'interception_proxy'})) { $logger->info("Adding Proxy interception rules"); - foreach my $intercept_port ( split(',', $Config{'interception_proxy'}{'port'} ) ) { + foreach my $intercept_port ( split(',', $Config{'trapping'}{'interception_proxy_port'} ) ) { my $rule = "--protocol tcp --destination-port $intercept_port"; $$nat_prerouting_ref .= "-A $FW_PREROUTING_INT_INLINE $rule --match mark --mark 0x$IPTABLES_MARK_UNREG " . "--jump REDIRECT\n"; @@ -674,8 +674,8 @@ sub generate_interception_rules { $$nat_if_src_to_chain .= "-A PREROUTING --in-interface $dev --jump $FW_PREROUTING_INT_VLAN\n"; } } - if (defined($Config{'interception_proxy'}{'port'})) { - foreach my $intercept_port ( split( ',', $Config{'interception_proxy'}{'port'} ) ) { + if (defined($Config{'trapping'}{'interception_proxy_port'}) && isenabled($Config{'trapping'}{'interception_proxy'})) { + foreach my $intercept_port ( split( ',', $Config{'trapping'}{'interception_proxy_port'} ) ) { my $rule = "--protocol tcp --destination-port $intercept_port"; $logger->warn($rule); $$nat_prerouting_vlan .= "-A $FW_PREROUTING_INT_VLAN $rule --jump REDIRECT\n"; diff --git a/lib/pf/services.pm b/lib/pf/services.pm index 6a545ab5446b..e92a7315e5cd 100644 --- a/lib/pf/services.pm +++ b/lib/pf/services.pm @@ -306,7 +306,7 @@ sub service_list { && isenabled($Config{'services'}{'pfdns'}) ); } elsif ( $service eq "httpd.proxy" ) { push @finalServiceList, $service - if ( defined($Config{'interception_proxy'}{'port'}) ); + if ( isenabled($Config{'trapping'}{'interception_proxy'}) ); } elsif ( $service eq 'pfdhcplistener' ) { push @finalServiceList, $service if ( isenabled($Config{'network'}{'dhcpdetector'}) ); From d786b0d9562fab6dd0338c792a6563632cbe951f Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Fri, 27 Sep 2013 10:14:35 -0400 Subject: [PATCH 082/369] Update doc --- NEWS.asciidoc | 1 + docs/PacketFence_Administration_Guide.asciidoc | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/NEWS.asciidoc b/NEWS.asciidoc index 6e2f839571f6..106719b6781b 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -18,6 +18,7 @@ New Features ++++++++++++ * Profiles can be filter by switches +* Proxy interception Enhancements ++++++++++++ diff --git a/docs/PacketFence_Administration_Guide.asciidoc b/docs/PacketFence_Administration_Guide.asciidoc index 4aaf9bfd3438..e3b3bb9761bb 100644 --- a/docs/PacketFence_Administration_Guide.asciidoc +++ b/docs/PacketFence_Administration_Guide.asciidoc @@ -1140,13 +1140,24 @@ There are two solutions for passthroughs - one using DNS resolution and iptables When enabled, PacketFence will use pfdns if you defined *Passthroughs*, or Apache mod-proxy if you defined *Proxy Passthroughs* to allow trapped devices to reach web sites. *DNS passthrough: -Add a new FQDN (should be a wildcard domain like *.google.com) in the *Passthroughs* section. When PacketFence receives a DNS request for this domain, it will answer the real IP address and punch a hole in the firewall (using iptables) to allow access. With this method, PacketFence must be the default gateway of your device. +Add a new FQDN (should be a wildcard domain like *.google.com) in the Passthroughs section. When PacketFence receives a DNS request for this domain, it will answer the real IP address and punch a hole in the firewall (using iptables) to allow access. With this method, PacketFence must be the default gateway of your device. *mod_proxy passthrough: Add a new FQDN (should be a wildcard domain like *.google.com) in the Proxy Passthroughs section. For this FQDN, PacketFence will answer the IP address of the captive portal and when a device hits the captive portal, PacketFence will detect that this FQDN has a passthrough configuration and will forward the traffic to mod_proxy. These two methods can be used together but DNS-based passthroughs have higher priority. +Proxy Interception +~~~~~~~~~~~~~~~~~~ + +In PacketFence you are now able to intercept proxy request and forward them to the captive portal. It only work in layer 2 network because packetfence must be the default gateway of your device. +In order to use the Proxy Interception feature, you need to enable it from the GUI in +*Configuration -> Trapping* and check *Proxy Interception*. + +Add the port you want to intercept, like 8080 3128 and add a new entry in the /etc/hosts file to resolv the fqdn of the captive portal to 127.0.0.1. +The modification of the hosts file is really important because apache try to resolv the fqdn of the captive portal and it must be 127.0.0.1. + + Configuration by example ------------------------ From 5f97ebfdcf41a2c145547fdccd2e786dc78e2de0 Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Fri, 27 Sep 2013 10:21:34 -0400 Subject: [PATCH 083/369] Update News file --- NEWS.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.asciidoc b/NEWS.asciidoc index 6e2f839571f6..6c59acc7d0ca 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -27,6 +27,7 @@ Enhancements * Search by MAC address for nodes and users now accepts any MAC format * Improved starting delay when using inline mode * Added memcached as a managed service +* Added CoA support for Xirrus access point Bug Fixes +++++++++ From 0fb83052ee0a437eb144ba0756c78bb540a63164 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Fri, 27 Sep 2013 12:13:38 -0400 Subject: [PATCH 084/369] untaint values before storing them in the hash --- lib/pf/config/cached.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pf/config/cached.pm b/lib/pf/config/cached.pm index e743163973fd..07455f5e0f77 100644 --- a/lib/pf/config/cached.pm +++ b/lib/pf/config/cached.pm @@ -906,8 +906,8 @@ sub toHash { } foreach my $section ($self->Sections()) { my %data; - foreach my $param (uniq $self->Parameters($section),@default_parms) { - $data{$param} = untaint_value ($self->val($section,$param)); + foreach my $param ( map { untaint_value($_) } uniq $self->Parameters($section),@default_parms) { + $data{$param} = untaint ($self->val($section,$param)); } $hash->{$section} = \%data; } From 95fdca11abaa67293ff1798472fd69c407182479 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Fri, 27 Sep 2013 16:44:34 -0400 Subject: [PATCH 085/369] Syntax & logging cleanup --- html/pfappserver/lib/pfappserver/Base/Controller/Crud.pm | 4 ++-- .../lib/pfappserver/Base/Controller/Crud/Clone.pm | 7 +++---- html/pfappserver/lib/pfappserver/Model/MacAddress.pm | 2 -- html/pfappserver/root/node/violations.tt | 2 +- lib/pf/temporary_password.pm | 2 +- 5 files changed, 7 insertions(+), 10 deletions(-) diff --git a/html/pfappserver/lib/pfappserver/Base/Controller/Crud.pm b/html/pfappserver/lib/pfappserver/Base/Controller/Crud.pm index b830f8e9c58c..bbfe7bfb263b 100644 --- a/html/pfappserver/lib/pfappserver/Base/Controller/Crud.pm +++ b/html/pfappserver/lib/pfappserver/Base/Controller/Crud.pm @@ -21,8 +21,8 @@ use namespace::autoclean; =cut -sub create : Local: Args(0) { - my ($self,$c) = @_; +sub create :Local :Args(0) { + my ($self, $c) = @_; if ($c->request->method eq 'POST') { $self->_processCreatePost($c); # check if exists diff --git a/html/pfappserver/lib/pfappserver/Base/Controller/Crud/Clone.pm b/html/pfappserver/lib/pfappserver/Base/Controller/Crud/Clone.pm index 59349eccab62..42ce0a07f620 100644 --- a/html/pfappserver/lib/pfappserver/Base/Controller/Crud/Clone.pm +++ b/html/pfappserver/lib/pfappserver/Base/Controller/Crud/Clone.pm @@ -27,7 +27,8 @@ sub clone :Chained('object') :PathPart('clone') :Args(0) { my ( $self, $c, $to ) = @_; if ($c->request->method eq 'POST') { $self->_processCreatePost($c); - } else { + } + else { my $model = $self->getModel($c); my $itemKey = $model->itemKey; my $idKey = $model->idKey; @@ -35,9 +36,7 @@ sub clone :Chained('object') :PathPart('clone') :Args(0) { delete $item->{$idKey}; my $form = $self->getForm($c); $form->process(init_object => $item); - $c->stash( - form => $form, - ); + $c->stash(form => $form); } } diff --git a/html/pfappserver/lib/pfappserver/Model/MacAddress.pm b/html/pfappserver/lib/pfappserver/Model/MacAddress.pm index 88c30ac82741..27e8c7138da3 100644 --- a/html/pfappserver/lib/pfappserver/Model/MacAddress.pm +++ b/html/pfappserver/lib/pfappserver/Model/MacAddress.pm @@ -93,10 +93,8 @@ sub search { if ( exists $params{orderby} ) { - my ( $field, $order ) = $params{orderby} =~ /ORDER BY\s+(.*)\s+(.*)/; - $logger->info("$field, $order"); if ( $order eq 'desc' ) { $sorter = sub {$b->{$field} cmp $a->{$field} }; } diff --git a/html/pfappserver/root/node/violations.tt b/html/pfappserver/root/node/violations.tt index 29815ceb806e..9ed859e64b13 100644 --- a/html/pfappserver/root/node/violations.tt +++ b/html/pfappserver/root/node/violations.tt @@ -21,7 +21,7 @@ [% ELSE %]
    -

    [% l('No violation history') %]

    +

    [% l('No violation found') %]

    [% END %]
    diff --git a/lib/pf/temporary_password.pm b/lib/pf/temporary_password.pm index 00940087265d..51eb81192bf6 100644 --- a/lib/pf/temporary_password.pm +++ b/lib/pf/temporary_password.pm @@ -372,7 +372,7 @@ sub modify_actions { @{$temporary_password}{@ACTION_FIELDS}, $pid ); my $rows = $query->rows; - $logger->info("temporarypassword $pid modified") if $rows ; + $logger->info("pid $pid modified") if $rows ; return ($rows); } From 5567418dd53afd30e985b44782e6a53c2464a944 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Mon, 30 Sep 2013 08:57:57 -0400 Subject: [PATCH 086/369] Bump release to 4.0.7 --- NEWS.asciidoc | 11 +++++++++++ conf/pf-release | 2 +- debian/changelog | 4 ++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/NEWS.asciidoc b/NEWS.asciidoc index 1168d3e10bf7..79bc54749b04 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -35,6 +35,17 @@ Bug Fixes * +Version 4.0.6-2 released on 2013-09-13 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Bug Fixes ++++++++++ + +* Fixed dependancy in debian/ubuntu package (#1705) +* Fixed 802.1X error in RADIUS authorize (#1709) +* Fixed pfcmd not stopping services (#1710) +* Fixed caching issue on Web admin interface (#1711) + Version 4.0.6 released on 2013-09-05 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/conf/pf-release b/conf/pf-release index b9c2facad682..b0bf22650ccd 100644 --- a/conf/pf-release +++ b/conf/pf-release @@ -1 +1 @@ -PacketFence 4.0.6 +PacketFence 4.0.7 diff --git a/debian/changelog b/debian/changelog index a8d1e4b0cbf2..e36c7a519844 100644 --- a/debian/changelog +++ b/debian/changelog @@ -32,13 +32,13 @@ packetfence (4.0.0) unstable; urgency=low * Version 4.0.0 - -- Francis Lachapelle Wed, 8 May 2013 12:00:00 -0400 + -- Francis Lachapelle Wed, 8 May 2013 12:00:00 -0400 packetfence (3.6.1) unstable; urgency=low * Version 3.6.1 - -- Derek Wuelfrath Thu, 10 Oct 2012 17:12:00 -0400 + -- Derek Wuelfrath Thu, 10 Oct 2012 17:12:00 -0400 packetfence (3.6.0) unstable; urgency=low From 6cfb44a084ba1b93bb823c70c391e3182f5e7195 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Mon, 30 Sep 2013 08:58:42 -0400 Subject: [PATCH 087/369] Remove seperators from sources pulldown --- html/pfappserver/root/configuration/authentication.tt | 2 -- 1 file changed, 2 deletions(-) diff --git a/html/pfappserver/root/configuration/authentication.tt b/html/pfappserver/root/configuration/authentication.tt index dd2120dd17a2..f9619fa7ae3e 100644 --- a/html/pfappserver/root/configuration/authentication.tt +++ b/html/pfappserver/root/configuration/authentication.tt @@ -127,7 +127,6 @@ [% END -%] -
  • -
  • + [% ELSE %] + [% END %] [% UNLESS null_source %]
    From 679fb8ff61fb1ef774bc94079c8253a2469b1881 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 30 Sep 2013 17:37:35 -0400 Subject: [PATCH 097/369] Added help for new command fixpermissions --- lib/pf/pfcmd/help.pm | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/pf/pfcmd/help.pm b/lib/pf/pfcmd/help.pm index b5c7979382a5..0bbf707361d9 100644 --- a/lib/pf/pfcmd/help.pm +++ b/lib/pf/pfcmd/help.pm @@ -647,6 +647,16 @@ EOT return 1; } +sub help_fixpermissions { + print STDERR << "EOT"; +Usage: pfcmd fixpermissions + +Fix the permissions of the files and directories of packetfence + +EOT + return 1; +} + =back =head1 AUTHOR From 4a05b223b3e4eb05e99be2a2033f72ec5d7ab6f6 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Tue, 1 Oct 2013 10:24:55 -0400 Subject: [PATCH 098/369] Nodes will be registered with the admin user when when email is not required --- html/captive-portal/register.cgi | 1 + lib/pf/Authentication/Source/NullSource.pm | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/html/captive-portal/register.cgi b/html/captive-portal/register.cgi index 5b2fbccdc81b..b2bd8779fcdf 100755 --- a/html/captive-portal/register.cgi +++ b/html/captive-portal/register.cgi @@ -79,6 +79,7 @@ if ( (defined($cgi->param('username') ) || $no_username_needed ) && ($cgi->param } my $pid = $portalSession->getSession->param("username"); + $pid = $default_pid if $no_username_needed; my $params = { username => $pid }; # TODO : add current_time and computer_name my $locationlog_entry = locationlog_view_open_mac($mac); diff --git a/lib/pf/Authentication/Source/NullSource.pm b/lib/pf/Authentication/Source/NullSource.pm index 1afb1a41cd14..1d73c95a81bc 100644 --- a/lib/pf/Authentication/Source/NullSource.pm +++ b/lib/pf/Authentication/Source/NullSource.pm @@ -14,7 +14,7 @@ pf::Authentication::Source::NullSource use strict; use warnings; use Moose; -use pf::config qw($FALSE $TRUE); +use pf::config qw($FALSE $TRUE $default_pid); use Email::Valid; use pf::util; @@ -25,9 +25,13 @@ has '+type' => (default => 'Null'); has '+unique' => (default => 1); has 'email_required' => ( is=> 'rw', default => 'disabled'); +=head2 match_in_subclass + +=cut + sub match_in_subclass { my ($self, $params, $rule, $own_conditions, $matching_conditions) = @_; - return $params->{'username'}; + return $self->email_required ? $params->{'username'} : $default_pid; } =head2 authenticate From e3ca9c9fe3703b0ef7b8ab5541f2a1c3682504bf Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Wed, 2 Oct 2013 11:12:10 -0400 Subject: [PATCH 099/369] Fix templates of portal profiles section --- html/pfappserver/root/portal/profile/edit.tt | 90 +++++++++---------- html/pfappserver/root/portal/profile/files.tt | 58 ++++++------ html/pfappserver/root/portal/profile/view.tt | 90 +++++++++---------- 3 files changed, 117 insertions(+), 121 deletions(-) diff --git a/html/pfappserver/root/portal/profile/edit.tt b/html/pfappserver/root/portal/profile/edit.tt index 2ff47c46b4bb..6e5864a78dbb 100644 --- a/html/pfappserver/root/portal/profile/edit.tt +++ b/html/pfappserver/root/portal/profile/edit.tt @@ -59,50 +59,50 @@ [% l('Rename File') %]
    -
    - -
    - -

    [% directory %][% file_name %]

    - - - -
    -
    - -
    - -
    -
    [% l('Available Variables') %]
    -
      - [% FOREACH var IN ['logo', 'username', 'user_agent', 'dhcp_fingerprint', 'last_switch', 'last_port', 'last_vlan', 'last_connection_type', 'last_ssid'] %] - [% variable_entry(var) %] - [% END %] -
    -
    -
    [%file_content | html%]
    - -
    -
    + + +
    +
    +

    [% directory %][% file_name %]

    + + +
    +
    + +
    + +
    +
    [% l('Available Variables') %]
    +
      + [% FOREACH var IN ['logo', 'username', 'user_agent', 'dhcp_fingerprint', 'last_switch', 'last_port', 'last_vlan', 'last_connection_type', 'last_ssid'] %] + [% variable_entry(var) %] + [% END %] +
    +
    +
    [%file_content | html%]
    + +
    +
    +
    diff --git a/html/pfappserver/root/portal/profile/files.tt b/html/pfappserver/root/portal/profile/files.tt index 3f0529146553..f25a8461841a 100644 --- a/html/pfappserver/root/portal/profile/files.tt +++ b/html/pfappserver/root/portal/profile/files.tt @@ -174,37 +174,35 @@ td a.btn { margin-left: 5px; } -
    -
    diff --git a/html/pfappserver/root/portal/profile/view.tt b/html/pfappserver/root/portal/profile/view.tt index cd2f04bee789..5f17f1561594 100644 --- a/html/pfappserver/root/portal/profile/view.tt +++ b/html/pfappserver/root/portal/profile/view.tt @@ -13,58 +13,56 @@ -
    -
    +[%- END %] From 4947a262da25b30854f5d33e604a1d92c15952b6 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Fri, 20 Sep 2013 09:43:54 -0400 Subject: [PATCH 243/369] Add access rights to SoH filters management --- html/pfappserver/lib/pfappserver/Controller/SoH.pm | 10 +++++----- html/pfappserver/root/soh/index.tt | 8 +++++++- html/pfappserver/root/soh/read.tt | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/html/pfappserver/lib/pfappserver/Controller/SoH.pm b/html/pfappserver/lib/pfappserver/Controller/SoH.pm index d652b0b2e533..fa10c5b35949 100644 --- a/html/pfappserver/lib/pfappserver/Controller/SoH.pm +++ b/html/pfappserver/lib/pfappserver/Controller/SoH.pm @@ -28,7 +28,7 @@ BEGIN { extends 'pfappserver::Base::Controller'; } =cut -sub index :Path :Args(0) { +sub index :Path :Args(0) :AdminRole('SOH_READ') { my ($self, $c) = @_; my ($status, $result) = $c->model('SoH')->filters(); @@ -44,7 +44,7 @@ sub index :Path :Args(0) { =cut -sub create :Local { +sub create :Local :AdminRole('SOH_CREATE') { my ($self, $c) = @_; my ($status, $result, $form); @@ -113,7 +113,7 @@ sub object :Chained('/') :PathPart('soh') :CaptureArgs(1) { =cut -sub read :Chained('object') :PathPart('read') :Args(0) { +sub read :Chained('object') :PathPart('read') :Args(0) :AdminRole('SOH_READ') { my ($self, $c) = @_; my ($status, $result, $form); @@ -146,7 +146,7 @@ sub read :Chained('object') :PathPart('read') :Args(0) { =cut -sub update :Chained('object') :PathPart('update') :Args(0) { +sub update :Chained('object') :PathPart('update') :Args(0) :AdminRole('SOH_UPDATE') { my ($self, $c) = @_; my ($status, $result, $form); @@ -181,7 +181,7 @@ sub update :Chained('object') :PathPart('update') :Args(0) { =cut -sub delete :Chained('object') :PathPart('delete') :Args(0) { +sub delete :Chained('object') :PathPart('delete') :Args(0) :AdminRole('SOH_DELETE') { my ($self, $c) = @_; my $configViolationsModel = $c->model('Config::Violations'); diff --git a/html/pfappserver/root/soh/index.tt b/html/pfappserver/root/soh/index.tt index bc607b24e049..e1289edbea48 100644 --- a/html/pfappserver/root/soh/index.tt +++ b/html/pfappserver/root/soh/index.tt @@ -38,7 +38,11 @@ [% filter.filter_id %] [% filter.name %] [% l(filter.action) %] - [% l('Delete') %] + + [%- IF can_access("SOH_DELETE") %] + [% l('Delete') %] + [%- END %] + [% END -%] @@ -49,6 +53,8 @@

    [% l('No filter defined') %]

    + [%- IF can_access("SOH_CREATE") %] + [%- END %] diff --git a/html/pfappserver/root/soh/read.tt b/html/pfappserver/root/soh/read.tt index ddb390e60c17..d1842cabd699 100644 --- a/html/pfappserver/root/soh/read.tt +++ b/html/pfappserver/root/soh/read.tt @@ -50,7 +50,7 @@ From 2033aa97658cf41f4a1825b66c616777fb4122d7 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Fri, 20 Sep 2013 09:54:10 -0400 Subject: [PATCH 244/369] Add access rights to fingerprints management --- .../pfappserver/Controller/Configuration/Fingerprints.pm | 8 ++++---- .../root/configuration/fingerprints/simple_search.tt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/html/pfappserver/lib/pfappserver/Controller/Configuration/Fingerprints.pm b/html/pfappserver/lib/pfappserver/Controller/Configuration/Fingerprints.pm index 73d861874bb5..c5d627ca153f 100644 --- a/html/pfappserver/lib/pfappserver/Controller/Configuration/Fingerprints.pm +++ b/html/pfappserver/lib/pfappserver/Controller/Configuration/Fingerprints.pm @@ -43,14 +43,14 @@ sub index :Path :Args(0) { =cut -sub simple_search :Local :Args() : SimpleSearch('OS') { } +sub simple_search :Local :Args() :SimpleSearch('OS') :AdminRole('FINGERPRINTS_READ') { } =head2 update =cut -sub update :Local :Args(0) { +sub update :Local :Args(0) :AdminRole('FINGERPRINTS_UPDATE') { my ( $self, $c ) = @_; $c->stash->{current_view} = 'JSON'; my ( $status, $version_msg, $total ) = update_dhcp_fingerprints_conf(); @@ -65,7 +65,7 @@ sub update :Local :Args(0) { =cut -sub upload :Local :Args(0) { +sub upload :Local :Args(0) :AdminRole('FINGERPRINTS_READ') { my ( $self, $c ) = @_; $c->stash->{current_view} = 'JSON'; @@ -113,7 +113,7 @@ sub upload :Local :Args(0) { =head1 COPYRIGHT -Copyright (C) 2012 Inverse inc. +Copyright (C) 2012-2013 Inverse inc. =head1 LICENSE diff --git a/html/pfappserver/root/configuration/fingerprints/simple_search.tt b/html/pfappserver/root/configuration/fingerprints/simple_search.tt index 3d2759ff08b9..ab49165baa8b 100644 --- a/html/pfappserver/root/configuration/fingerprints/simple_search.tt +++ b/html/pfappserver/root/configuration/fingerprints/simple_search.tt @@ -1,7 +1,7 @@

    [% l('Fingerprints') %]

    [%- INCLUDE 'configuration/listing.inc' titles = { From dd664b90e1fde04e4828d83c4c7c72ff18b6587a Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Fri, 20 Sep 2013 09:54:51 -0400 Subject: [PATCH 245/369] Add access rights to useragents management --- .../lib/pfappserver/Controller/Configuration/UserAgents.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/html/pfappserver/lib/pfappserver/Controller/Configuration/UserAgents.pm b/html/pfappserver/lib/pfappserver/Controller/Configuration/UserAgents.pm index add4b6e6f70c..d2df1daacbd7 100644 --- a/html/pfappserver/lib/pfappserver/Controller/Configuration/UserAgents.pm +++ b/html/pfappserver/lib/pfappserver/Controller/Configuration/UserAgents.pm @@ -33,13 +33,13 @@ sub index :Path { =cut -sub simple_search :Local :Args() : SimpleSearch('UserAgent') {} +sub simple_search :Local :Args() :SimpleSearch('UserAgent') :AdminRole('USERAGENTS_READ') {} =head2 upload =cut -sub upload :Local :Args(0) { +sub upload :Local :Args(0) :AdminRole('USERAGENTS_READ') { my ( $self, $c ) = @_; $c->stash->{current_view} = 'JSON'; @@ -97,7 +97,7 @@ sub upload :Local :Args(0) { =head1 COPYRIGHT -Copyright (C) 2012 Inverse inc. +Copyright (C) 2012-2013 Inverse inc. =head1 LICENSE From 6c83152fbc7872b7267a9fb0437bec34635f63bd Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Fri, 20 Sep 2013 09:55:34 -0400 Subject: [PATCH 246/369] Add access rights to MAC addresses management --- .../lib/pfappserver/Controller/Configuration/MacAddress.pm | 4 ++-- .../root/configuration/macaddress/simple_search.tt | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/html/pfappserver/lib/pfappserver/Controller/Configuration/MacAddress.pm b/html/pfappserver/lib/pfappserver/Controller/Configuration/MacAddress.pm index 7db876f206f0..850418521106 100644 --- a/html/pfappserver/lib/pfappserver/Controller/Configuration/MacAddress.pm +++ b/html/pfappserver/lib/pfappserver/Controller/Configuration/MacAddress.pm @@ -34,13 +34,13 @@ sub index :Path { =cut -sub simple_search :Local :Args(): SimpleSearch('MacAddress') { } +sub simple_search :Local :Args() :SimpleSearch('MacAddress') :AdminRole('MAC_READ') { } =head2 update =cut -sub update : Local : Args(0) { +sub update :Local :Args(0) :AdminRole('MAC_UPDATE') { my ( $self, $c ) = @_; $c->stash->{current_view} = 'JSON'; my ($status, $status_msg) = download_oui(); diff --git a/html/pfappserver/root/configuration/macaddress/simple_search.tt b/html/pfappserver/root/configuration/macaddress/simple_search.tt index 06c4369cd472..63911234ab98 100644 --- a/html/pfappserver/root/configuration/macaddress/simple_search.tt +++ b/html/pfappserver/root/configuration/macaddress/simple_search.tt @@ -1,7 +1,9 @@

    [% l('MAC Addresses') %]

    + [%- IF can_access("MAC_UPDATE") %] + [%- END %] [%- INCLUDE 'configuration/listing.inc' titles = { oui =>{ title => 'OUI' }, vendor_info => { title => 'Vendor' }, From 7c91ce42c7b4675c8102e2e48dd54468e30db6c3 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Fri, 20 Sep 2013 12:44:24 -0400 Subject: [PATCH 247/369] Group admin roles actions in pulldown menus --- .../lib/pfappserver/Form/Config/AdminRoles.pm | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/html/pfappserver/lib/pfappserver/Form/Config/AdminRoles.pm b/html/pfappserver/lib/pfappserver/Form/Config/AdminRoles.pm index 1142c2c84289..18b22c400f55 100644 --- a/html/pfappserver/lib/pfappserver/Form/Config/AdminRoles.pm +++ b/html/pfappserver/lib/pfappserver/Form/Config/AdminRoles.pm @@ -43,11 +43,26 @@ has_field 'actions.contains' => options_method => \&options_actions, widget_wrapper => 'DynamicTableRow', ); -sub build_do_form_wrapper{ 0 } +sub build_do_form_wrapper{ 0 } sub options_actions { - return map { {label => $_, value => $_} } @ADMIN_ACTIONS; + my $self = shift; + + my %groups; + my @options; + + map { + m/^(.+?)(_(READ|CREATE|UPDATE|DELETE))?$/; + $groups{$1} = [] unless $groups{$1}; + push(@{$groups{$1}}, { value => $_, label => $self->_localize($_) }) + } @ADMIN_ACTIONS; + + @options = map { + { group => $self->_localize($_), options => $groups{$_} } + } sort keys %groups; + + return \@options; }; =head1 COPYRIGHT From b1d75e6162129a52e77218f564445244a3f0fc77 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Fri, 20 Sep 2013 12:46:08 -0400 Subject: [PATCH 248/369] Sort actions when viewing an admin role --- .../Controller/Configuration/AdminRoles.pm | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/html/pfappserver/lib/pfappserver/Controller/Configuration/AdminRoles.pm b/html/pfappserver/lib/pfappserver/Controller/Configuration/AdminRoles.pm index c1671da9a980..72acc4f733cd 100644 --- a/html/pfappserver/lib/pfappserver/Controller/Configuration/AdminRoles.pm +++ b/html/pfappserver/lib/pfappserver/Controller/Configuration/AdminRoles.pm @@ -89,6 +89,24 @@ after view => sub { } }; +=head2 after _setup_object + +Sort the actions of the admin role. + +This subroutine is defined in pfappserver::Base::Controller::Crud. + +=cut + +after _setup_object => sub { + my ($self, $c) = @_; + + # Sort actions + if (is_success($c->response->status)) { + my @actions = sort @{$c->stash->{'item'}->{'actions'}}; + $c->stash->{'item'}->{'actions'} = \@actions; + } +}; + =head2 index Usage: /configuration/adminroles/ From a00fefb5f70fa5681ca24f00fb25ce634d4d1b5b Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Fri, 20 Sep 2013 14:19:17 -0400 Subject: [PATCH 249/369] Localization --- html/pfappserver/lib/pfappserver/I18N/en.po | 338 +++++++++++++++++++- 1 file changed, 334 insertions(+), 4 deletions(-) diff --git a/html/pfappserver/lib/pfappserver/I18N/en.po b/html/pfappserver/lib/pfappserver/I18N/en.po index 45ca351f995a..58b11d759a76 100644 --- a/html/pfappserver/lib/pfappserver/I18N/en.po +++ b/html/pfappserver/lib/pfappserver/I18N/en.po @@ -48,6 +48,26 @@ msgstr "" msgid "A manual start from the command line will be required. Are you sure you want to continue?" msgstr "" +# pf::admin_roles (Groups) +msgid "ADMIN_ROLES" +msgstr "Admin Roles" + +# pf::admin_roles (Actions) +msgid "ADMIN_ROLES_CREATE" +msgstr "Admin Roles - Create" + +# pf::admin_roles (Actions) +msgid "ADMIN_ROLES_DELETE" +msgstr "Admin Roles - Delete" + +# pf::admin_roles (Actions) +msgid "ADMIN_ROLES_READ" +msgstr "Admin Roles - Read" + +# pf::admin_roles (Actions) +msgid "ADMIN_ROLES_UPDATE" +msgstr "Admin Roles - Update" + # html/pfappserver/lib/pfappserver/Form/Authentication/Source/Github.pm # html/pfappserver/lib/pfappserver/Form/Authentication/Source/Google.pm msgid "API Authorize Path" @@ -110,8 +130,11 @@ msgid "" "specified." msgstr "" +# html/pfappserver/lib/pfappserver/Form/Config/AdminRoles.pm # html/pfappserver/lib/pfappserver/Form/Violation.pm # html/pfappserver/root/user/create.tt +# html/pfappserver/root/configuration/adminroles/view.tt +# html/pfappserver/root/configuration/users.tt # html/pfappserver/root/user/view.tt # html/pfappserver/root/violation/list.tt msgid "Actions" @@ -139,6 +162,10 @@ msgstr "" msgid "Add a source." msgstr "" +# html/pfappserver/root/configuration/adminroles/index.tt +msgid "Add admin role" +msgstr "" + # html/pfappserver/root/soh/index.tt msgid "Add filter" msgstr "" @@ -208,6 +235,14 @@ msgstr "" msgid "Admin Login" msgstr "" +# html/pfappserver/root/configuration/adminroles/view.tt +msgid "Admin Role" +msgstr "" + +# html/pfappserver/root/configuration/adminroles/index.tt +msgid "Admin Roles" +msgstr "" + # html/pfappserver/root/admin/nodes.tt # html/pfappserver/root/admin/users.tt msgid "Advanced" @@ -346,10 +381,23 @@ msgid "CLI" msgstr "" # html/pfappserver/lib/pfappserver/Form/Node/Create/Import.pm +# pf::admin_roles (Groups) +msgid "CONFIGURATION_MAIN" +msgstr "Main Configuration" + +# pf::admin_roles (Actions) +msgid "CONFIGURATION_MAIN_READ" +msgstr "Main Configuration - Read" + +# pf::admin_roles (Actions) +msgid "CONFIGURATION_MAIN_UPDATE" +msgstr "Main Configuration - Update" + # html/pfappserver/lib/pfappserver/Form/User/Create/Import.pm msgid "CSV File" msgstr "" +# html/pfappserver/root/configuration/adminroles/index.tt # html/pfappserver/root/configuration/authentication.tt # html/pfappserver/root/configuration/floatingdevice/index.tt # html/pfappserver/root/configuration/switch/index.tt @@ -386,6 +434,7 @@ msgstr "" msgid "Clear Violation" msgstr "" +# html/pfappserver/root/configuration/adminroles/list.tt # html/pfappserver/root/configuration/floatingdevice/list.tt # html/pfappserver/root/configuration/switch/list.tt # html/pfappserver/root/violation/list.tt @@ -396,6 +445,7 @@ msgstr "" # html/pfappserver/root/admin/users.tt # html/pfappserver/root/authentication/source/rule_read.tt # html/pfappserver/root/config/networks/view.tt +# html/pfappserver/root/configuration/adminroles/view.tt # html/pfappserver/root/configuration/floatingdevice/view.tt # html/pfappserver/root/configuration/switch/view.tt # html/pfappserver/root/interface/view.tt @@ -646,6 +696,10 @@ msgstr "" msgid "Default pid value to assign to imported nodes." msgstr "" +# html/pfappserver/root/configuration/adminroles/index.tt +msgid "Define roles with specific access rights to the Web administration interface." +msgstr "" + # html/pfappserver/root/configuration/authentication.tt msgid "Define the authentication sources to let users access the captive portal or the admin Web interface." msgstr "" @@ -670,6 +724,8 @@ msgid "" msgstr "" # html/pfappserver/root/config/networks/view.tt +# html/pfappserver/root/configuration/adminroles/index.tt +# html/pfappserver/root/configuration/adminroles/list.tt # html/pfappserver/root/configuration/authentication.tt # html/pfappserver/root/configuration/floatingdevice/index.tt # html/pfappserver/root/configuration/floatingdevice/list.tt @@ -686,6 +742,10 @@ msgstr "" msgid "Delete" msgstr "" +# html/pfappserver/root/configuration/adminroles/index.tt +msgid "Delete Admin Role" +msgstr "" + # html/pfappserver/root/portal/profile/files.tt msgid "Delete File" msgstr "" @@ -754,6 +814,7 @@ msgstr "" # html/pfappserver/lib/pfappserver/Form/Role.pm # html/pfappserver/lib/pfappserver/Form/Violation.pm # html/pfappserver/root/authentication/source/rules_read.tt +# html/pfappserver/root/configuration/adminroles/list.tt # html/pfappserver/root/configuration/authentication.tt # html/pfappserver/root/configuration/switch/list.tt # html/pfappserver/root/node/violations.tt @@ -927,6 +988,38 @@ msgstr "" msgid "External Sources" msgstr "" +# pf::admin_roles (Groups) +msgid "FINGERPRINTS" +msgstr "Fingerprints" + +# pf::admin_roles (Actions) +msgid "FINGERPRINTS_READ" +msgstr "Fingerprints - Read" + +# pf::admin_roles (Actions) +msgid "FINGERPRINTS_UPDATE" +msgstr "Fingerprints - Update" + +# pf::admin_roles (Groups) +msgid "FLOATING_DEVICES" +msgstr "Floating Devices" + +# pf::admin_roles (Actions) +msgid "FLOATING_DEVICES_CREATE" +msgstr "Floating Devices - Create" + +# pf::admin_roles (Actions) +msgid "FLOATING_DEVICES_DELETE" +msgstr "Floating Devices - Delete" + +# pf::admin_roles (Actions) +msgid "FLOATING_DEVICES_READ" +msgstr "Floating Devices - Read" + +# pf::admin_roles (Actions) +msgid "FLOATING_DEVICES_UPDATE" +msgstr "Floating Devices - Update" + # conf/documentation.conf (guests_self_registration.mandatory_fields) msgid "" "Fields required to be filled in the self-registration form. Valid values are:" @@ -1043,6 +1136,26 @@ msgstr "" msgid "ID of the scanning configuration on the OpenVAS server" msgstr "" +# pf::admin_roles (Groups) +msgid "INTERFACES" +msgstr "Interfaces" + +# pf::admin_roles (Actions) +msgid "INTERFACES_CREATE" +msgstr "Interfaces - Create" + +# pf::admin_roles (Actions) +msgid "INTERFACES_DELETE" +msgstr "Interfaces - Delete" + +# pf::admin_roles (Actions) +msgid "INTERFACES_READ" +msgstr "Interfaces - Read" + +# pf::admin_roles (Actions) +msgid "INTERFACES_UPDATE" +msgstr "Interfaces - Update" + # html/pfappserver/root/node/view.tt msgid "IP" msgstr "" @@ -1302,6 +1415,7 @@ msgstr "" # html/pfappserver/root/configuration/floatingdevice/list.tt # html/pfappserver/root/user/view.tt # html/pfappserver/root/user/violations.tt +# pf::admin_roles (Groups) msgid "MAC" msgstr "" @@ -1322,6 +1436,14 @@ msgstr "" msgid "MAC address" msgstr "" +# pf::admin_roles (Actions) +msgid "MAC_READ" +msgstr "MAC Addresses - Read" + +# pf::admin_roles (Actions) +msgid "MAC_UPDATE" +msgstr "MAC Addresses - Update" + # html/pfappserver/root/admin/configuration.tt msgid "Main" msgstr "" @@ -1362,6 +1484,26 @@ msgstr "" msgid "Multiple" msgstr "" +# pf::admin_roles (Groups) +msgid "NODES" +msgstr "Nodes" + +# pf::admin_roles (Actions) +msgid "NODES_CREATE" +msgstr "Nodes - Create" + +# pf::admin_roles (Actions) +msgid "NODES_DELETE" +msgstr "Nodes - Delete" + +# pf::admin_roles (Actions) +msgid "NODES_READ" +msgstr "Nodes - Read" + +# pf::admin_roles (Actions) +msgid "NODES_UPDATE" +msgstr "Nodes - Update" + # html/pfappserver/lib/pfappserver/Form/Authentication/Rule.pm # html/pfappserver/lib/pfappserver/Form/Authentication/Source.pm # html/pfappserver/lib/pfappserver/Form/Node.pm @@ -1425,6 +1567,10 @@ msgstr "" msgid "New" msgstr "" +# html/pfappserver/root/configuration/adminroles/view.tt +msgid "New Admin Role" +msgstr "" + # html/pfappserver/root/portal/profile/files.tt msgid "New File" msgstr "" @@ -1494,6 +1640,7 @@ msgstr "" msgid "No node found" msgstr "" +# html/pfappserver/root/configuration/adminroles/index.tt # html/pfappserver/root/roles/index.tt msgid "No role defined" msgstr "" @@ -1515,15 +1662,12 @@ msgstr "" msgid "No useragent found" msgstr "" -# html/pfappserver/root/user/violations.tt -msgid "No violation" -msgstr "" - # html/pfappserver/root/violation/list.tt msgid "No violation defined" msgstr "" # html/pfappserver/root/node/violations.tt +# html/pfappserver/root/user/violations.tt msgid "No violation found" msgstr "" @@ -1592,6 +1736,26 @@ msgstr "" msgid "Owner" msgstr "" +# pf::admin_roles (Groups) +msgid "PORTAL_PROFILES" +msgstr "Portal Profiles" + +# pf::admin_roles (Actions) +msgid "PORTAL_PROFILES_CREATE" +msgstr "Portal Profiles - Create" + +# pf::admin_roles (Actions) +msgid "PORTAL_PROFILES_DELETE" +msgstr "Portal Profiles - Delete" + +# pf::admin_roles (Actions) +msgid "PORTAL_PROFILES_READ" +msgstr "Portal Profiles - Read" + +# pf::admin_roles (Actions) +msgid "PORTAL_PROFILES_UPDATE" +msgstr "Portal Profiles - Update" + # html/pfappserver/lib/pfappserver/Form/Authentication/Source/LDAP.pm # html/pfappserver/lib/pfappserver/Form/Config/Switch.pm # html/pfappserver/lib/pfappserver/Form/User/Create/Import.pm @@ -1683,6 +1847,10 @@ msgstr "" msgid "Please specify the default DHCP lease time." msgstr "" +# html/pfappserver/lib/pfappserver/Form/Config/AdminRoles.pm +msgid "Please specify the description of the admin role." +msgstr "" + # html/pfappserver/lib/pfappserver/Form/User.pm msgid "Please specify the end date of the registration window." msgstr "" @@ -1699,6 +1867,10 @@ msgstr "" msgid "Please specify the maximum DHCP lease time." msgstr "" +# html/pfappserver/lib/pfappserver/Form/Config/AdminRoles.pm +msgid "Please specify the name of the admin role." +msgstr "" + # html/pfappserver/lib/pfappserver/Form/Config/Network/Routed.pm msgid "Please specify the netmask." msgstr "" @@ -1831,6 +2003,15 @@ msgstr "" msgid "RADIUS" msgstr "" +# pf::admin_roles (Actions) +# pf::admin_roles (Groups) +msgid "REPORTS" +msgstr "Reports" + +# html/pfappserver/root/configuration/adminroles/index.tt +msgid "Really delete this admin role?" +msgstr "" + # html/pfappserver/root/portal/profile/files.tt msgid "Really delete this file?" msgstr "" @@ -1911,6 +2092,7 @@ msgid "Release" msgstr "" # html/pfappserver/root/node/violations.tt +# html/pfappserver/root/user/violations.tt msgid "Release Date" msgstr "" @@ -1999,6 +2181,11 @@ msgstr "" msgid "Role" msgstr "" +# html/pfappserver/lib/pfappserver/Form/Config/AdminRoles.pm +# html/pfappserver/root/configuration/adminroles/list.tt +msgid "Role Name" +msgstr "" + # html/pfappserver/root/configuration/switch/view.tt msgid "Role mapping by VLAN" msgstr "" @@ -2031,6 +2218,11 @@ msgstr "" msgid "Rules" msgstr "" +# pf::admin_roles (Actions) +# pf::admin_roles (Groups) +msgid "SERVICES" +msgstr "Services" + # html/pfappserver/lib/pfappserver/Form/Authentication/Source/SMS.pm msgid "SMS Carriers" msgstr "" @@ -2039,6 +2231,26 @@ msgstr "" msgid "SNMP" msgstr "" +# pf::admin_roles (Groups) +msgid "SOH" +msgstr "SoH Filters" + +# pf::admin_roles (Actions) +msgid "SOH_CREATE" +msgstr "SoH Filters - Create" + +# pf::admin_roles (Actions) +msgid "SOH_DELETE" +msgstr "SoH Filters - Delete" + +# pf::admin_roles (Actions) +msgid "SOH_READ" +msgstr "SoH Filters - Read" + +# pf::admin_roles (Actions) +msgid "SOH_UPDATE" +msgstr "SoH Filters - Update" + # html/pfappserver/lib/pfappserver/Form/Field/ProfileFilter.pm # pf::Authentication::Source (common_attributes) msgid "SSID" @@ -2052,11 +2264,32 @@ msgstr "" msgid "SWITCH" msgstr "" +# pf::admin_roles (Groups) +msgid "SWITCHES" +msgstr "Switches" + +# pf::admin_roles (Actions) +msgid "SWITCHES_CREATE" +msgstr "Switches - Create" + +# pf::admin_roles (Actions) +msgid "SWITCHES_DELETE" +msgstr "Switches - Delete" + +# pf::admin_roles (Actions) +msgid "SWITCHES_READ" +msgstr "Switches - Read" + +# pf::admin_roles (Actions) +msgid "SWITCHES_UPDATE" +msgstr "Switches - Update" + # html/pfappserver/root/admin/nodes.tt # html/pfappserver/root/admin/users.tt # html/pfappserver/root/authentication/source/read.tt # html/pfappserver/root/authentication/source/rule_read.tt # html/pfappserver/root/config/networks/view.tt +# html/pfappserver/root/configuration/adminroles/view.tt # html/pfappserver/root/configuration/floatingdevice/view.tt # html/pfappserver/root/configuration/section.tt # html/pfappserver/root/configuration/switch/view.tt @@ -2100,6 +2333,7 @@ msgstr "" # html/pfappserver/root/authentication/source/read.tt # html/pfappserver/root/authentication/source/rule_read.tt # html/pfappserver/root/config/networks/view.tt +# html/pfappserver/root/configuration/adminroles/view.tt # html/pfappserver/root/configuration/floatingdevice/view.tt # html/pfappserver/root/configuration/switch/view.tt # html/pfappserver/root/interface/view.tt @@ -2312,6 +2546,7 @@ msgstr "" # html/pfappserver/root/admin/wrapper.tt # html/pfappserver/root/configurator/services.tt # html/pfappserver/root/service/status.tt +# html/pfappserver/root/user/view.tt msgid "Status" msgstr "" @@ -2569,6 +2804,81 @@ msgstr "" msgid "Type" msgstr "" +# pf::admin_roles (Groups) +msgid "USERAGENTS" +msgstr "Useragents" + +# pf::admin_roles (Actions) +msgid "USERAGENTS_READ" +msgstr "Useragents - Read" + +# pf::admin_roles (Groups) +msgid "USERS" +msgstr "Users" + +# pf::admin_roles (Actions) +msgid "USERS_CREATE" +msgstr "Users - Create" + +# pf::admin_roles (Actions) +msgid "USERS_DELETE" +msgstr "Users - Delete" + +# pf::admin_roles (Actions) +msgid "USERS_READ" +msgstr "Users - Read" + +# pf::admin_roles (Groups) +msgid "USERS_ROLES" +msgstr "Users Roles" + +# pf::admin_roles (Actions) +msgid "USERS_ROLES_CREATE" +msgstr "Users Roles - Create" + +# pf::admin_roles (Actions) +msgid "USERS_ROLES_DELETE" +msgstr "Users Roles - Delete" + +# pf::admin_roles (Actions) +msgid "USERS_ROLES_READ" +msgstr "Users Roles - Read" + +# pf::admin_roles (Actions) +msgid "USERS_ROLES_UPDATE" +msgstr "Users Roles - Update" + +# pf::admin_roles (Groups) +msgid "USERS_SOURCES" +msgstr "Users Sources" + +# pf::admin_roles (Actions) +msgid "USERS_SOURCES_CREATE" +msgstr "Users Sources - Create" + +# pf::admin_roles (Actions) +msgid "USERS_SOURCES_DELETE" +msgstr "Users Sources - Delete" + +# pf::admin_roles (Actions) +msgid "USERS_SOURCES_READ" +msgstr "Users Sources - Read" + +# pf::admin_roles (Actions) +msgid "USERS_SOURCES_UPDATE" +msgstr "Users Sources - Update" + +# pf::admin_roles (Actions) +msgid "USERS_UPDATE" +msgstr "Users - Update" + +# conf/documentation.conf (trapping.always_use_redirecturl) +msgid "" + "Under most circumstances we can redirect the user to the URL he originally " + "intended to visit. When enabled, always_use_redirecturl forces the captive " + "portal to redirect the user to the URL defined in trapping.redirecturl instead." +msgstr "" + # html/pfappserver/lib/pfappserver/Form/Node.pm msgid "Unregistration" msgstr "" @@ -2673,6 +2983,26 @@ msgstr "" msgid "Users" msgstr "" +# pf::admin_roles (Groups) +msgid "VIOLATIONS" +msgstr "Violations" + +# pf::admin_roles (Actions) +msgid "VIOLATIONS_CREATE" +msgstr "Violations - Create" + +# pf::admin_roles (Actions) +msgid "VIOLATIONS_DELETE" +msgstr "Violations - Delete" + +# pf::admin_roles (Actions) +msgid "VIOLATIONS_READ" +msgstr "Violations - Read" + +# pf::admin_roles (Actions) +msgid "VIOLATIONS_UPDATE" +msgstr "Violations - Update" + # html/pfappserver/lib/pfappserver/Form/Field/ProfileFilter.pm # html/pfappserver/lib/pfappserver/Form/Violation.pm msgid "VLAN" From fe3a73ffe476697a189ef90120004a05f9539b58 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 23 Sep 2013 00:43:35 -0400 Subject: [PATCH 250/369] Remove the delete link from the single action of a role --- html/pfappserver/root/static/admin/configuration/adminroles.js | 1 + 1 file changed, 1 insertion(+) diff --git a/html/pfappserver/root/static/admin/configuration/adminroles.js b/html/pfappserver/root/static/admin/configuration/adminroles.js index 5a8224930b96..4b786b529bf0 100644 --- a/html/pfappserver/root/static/admin/configuration/adminroles.js +++ b/html/pfappserver/root/static/admin/configuration/adminroles.js @@ -78,6 +78,7 @@ AdminRolesView.prototype.readAdminRoles = function(e) { modal.append(data); modal.one('shown', function() { modal.find(':input:visible').first().focus(); + updateDynamicRowsAfterRemove(modal.find('#actions')); }); modal.modal({ shown: true }); }, From 6bc7077a6bfadfeec1661361ddf4d253daba026c Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 23 Sep 2013 11:13:14 -0400 Subject: [PATCH 251/369] Redo the onfilereload when there is no extra data in the cache --- lib/pf/admin_roles.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pf/admin_roles.pm b/lib/pf/admin_roles.pm index 2493a07b566d..6af3a7150d5f 100644 --- a/lib/pf/admin_roles.pm +++ b/lib/pf/admin_roles.pm @@ -117,7 +117,7 @@ our $cached_adminroles_config = pf::config::cached->new( if ($data) { %ADMIN_ROLES = %$data; } else { - reloadConfig($config,$name); + $config->doCallbacks(1,0); } } ], From e21d726982ed7bc9236d160cdf73528d7ce62706 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Mon, 23 Sep 2013 11:30:55 -0400 Subject: [PATCH 252/369] Add missing ADMIN_ROLES_CREATE admin role action --- lib/pf/admin_roles.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pf/admin_roles.pm b/lib/pf/admin_roles.pm index 6af3a7150d5f..7f2e42a677df 100644 --- a/lib/pf/admin_roles.pm +++ b/lib/pf/admin_roles.pm @@ -40,6 +40,7 @@ our @ADMIN_ACTIONS = qw( PORTAL_PROFILES_UPDATE PORTAL_PROFILES_DELETE ADMIN_ROLES_READ + ADMIN_ROLES_CREATE ADMIN_ROLES_UPDATE ADMIN_ROLES_DELETE INTERFACES_READ From e4e7284062a39f72bc9fbce3bbcbdad7fb965820 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Mon, 23 Sep 2013 14:03:37 -0400 Subject: [PATCH 253/369] Fix typo --- html/pfappserver/root/configuration/adminroles/list.tt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/html/pfappserver/root/configuration/adminroles/list.tt b/html/pfappserver/root/configuration/adminroles/list.tt index be733f7f7695..4f3793d16ec4 100644 --- a/html/pfappserver/root/configuration/adminroles/list.tt +++ b/html/pfappserver/root/configuration/adminroles/list.tt @@ -12,7 +12,7 @@ [% adminrole.id %] [% adminrole.description | html%] - [% IF can_access("ADMIN_ROLES_CREATE ") %][% l('Clone') %][% END %] + [% IF can_access("ADMIN_ROLES_CREATE") %][% l('Clone') %][% END %] [% IF can_access("ADMIN_ROLES_DELETE") %][% l('Delete') %][% END %] From b67c42bfe33ef0b62440dfca084098db00388f97 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 2 Oct 2013 10:40:13 -0400 Subject: [PATCH 254/369] Adding a new realm for the configurator --- html/pfappserver/lib/pfappserver.pm | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/html/pfappserver/lib/pfappserver.pm b/html/pfappserver/lib/pfappserver.pm index 3ae7c58720b4..a67f4569f728 100644 --- a/html/pfappserver/lib/pfappserver.pm +++ b/html/pfappserver/lib/pfappserver.pm @@ -100,6 +100,20 @@ __PACKAGE__->config( store => { class => '+pfappserver::Authentication::Store::PacketFence', } + }, + configurator => { + credential => { + class => 'Password', + password_type => 'none' + }, + store => { + class => 'Minimal', + users => { + _PF_CONFIGURATOR => { + roles => [qw/ALL/], + } + } + } } } }, From c8ea16564139c884480b2ca263c014d588aacd39 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 2 Oct 2013 11:00:13 -0400 Subject: [PATCH 255/369] Check if user is in admin realm instead just existence --- .../lib/pfappserver/Base/Controller.pm | 2 +- .../lib/pfappserver/Controller/Admin.pm | 4 ++-- .../lib/pfappserver/Controller/Graph.pm | 20 ------------------- html/pfappserver/root/admin/wrapper.tt | 2 +- 4 files changed, 4 insertions(+), 24 deletions(-) diff --git a/html/pfappserver/lib/pfappserver/Base/Controller.pm b/html/pfappserver/lib/pfappserver/Base/Controller.pm index d24e06effde4..fdd5eca645af 100644 --- a/html/pfappserver/lib/pfappserver/Base/Controller.pm +++ b/html/pfappserver/lib/pfappserver/Base/Controller.pm @@ -66,7 +66,7 @@ sub auto :Private { # This fixes a problem when "en" is not in the browsers languages. $c->languages( ['en'] ); - unless ($c->user_exists()) { + unless ($c->user_in_realm('admin')) { $c->response->status(HTTP_UNAUTHORIZED); $c->response->location($c->req->referer); $c->stash->{template} = 'admin/unauthorized.tt'; diff --git a/html/pfappserver/lib/pfappserver/Controller/Admin.pm b/html/pfappserver/lib/pfappserver/Controller/Admin.pm index 8079234acedd..357c9aa1c1a0 100644 --- a/html/pfappserver/lib/pfappserver/Controller/Admin.pm +++ b/html/pfappserver/lib/pfappserver/Controller/Admin.pm @@ -34,7 +34,7 @@ sub auto :Private { # Make sure the 'enforcements' session variable doesn't exist as it affects the Interface controller delete $c->session->{'enforcements'}; - unless ($c->action->name eq 'login' || $c->action->name eq 'logout' || $c->user_exists()) { + unless ($c->action->name eq 'login' || $c->action->name eq 'logout' || $c->user_in_realm('admin')) { $c->stash->{'template'} = 'admin/login.tt'; unless ($c->action->name eq 'index') { $c->stash->{status_msg} = 'Your session has expired.'; @@ -88,7 +88,7 @@ sub login :Local :Args(0) { } $c->stash->{current_view} = 'JSON'; } - elsif ($c->user_exists()) { + elsif ($c->user_in_realm( 'admin' )) { $c->response->redirect($c->uri_for($c->controller('Admin')->action_for('status'))); $c->detach(); } diff --git a/html/pfappserver/lib/pfappserver/Controller/Graph.pm b/html/pfappserver/lib/pfappserver/Controller/Graph.pm index c2ff6412798f..c3c187ab9d60 100644 --- a/html/pfappserver/lib/pfappserver/Controller/Graph.pm +++ b/html/pfappserver/lib/pfappserver/Controller/Graph.pm @@ -25,26 +25,6 @@ Readonly::Scalar our $REPORTS => 'reports'; =head1 METHODS -=head2 auto - -Allow only authenticated users - -=cut - -sub auto :Private { - my ($self, $c) = @_; - - unless ($c->user_exists()) { - $c->response->status(HTTP_UNAUTHORIZED); - $c->response->location($c->req->referer); - $c->stash->{template} = 'admin/unauthorized.tt'; - $c->detach(); - return 0; - } - - return 1; -} - =head2 begin Set the default view to pfappserver::View::JSON. diff --git a/html/pfappserver/root/admin/wrapper.tt b/html/pfappserver/root/admin/wrapper.tt index 058eb4cd09dd..8f992d9b0ca4 100644 --- a/html/pfappserver/root/admin/wrapper.tt +++ b/html/pfappserver/root/admin/wrapper.tt @@ -51,7 +51,7 @@ - [%- IF c.user_exists %] + [%- IF c.user_in_realm( 'admin' ) %] diff --git a/html/pfappserver/root/interface/index.tt b/html/pfappserver/root/interface/index.tt index 80b21139e0d2..84cfa487ca58 100644 --- a/html/pfappserver/root/interface/index.tt +++ b/html/pfappserver/root/interface/index.tt @@ -2,6 +2,8 @@ [% INCLUDE interface/list.tt %] +[%- IF can_access("INTERFACES_CREATE") %] +[%- END %] diff --git a/html/pfappserver/root/interface/list.tt b/html/pfappserver/root/interface/list.tt index e1dafd94a857..94c91685f6fa 100644 --- a/html/pfappserver/root/interface/list.tt +++ b/html/pfappserver/root/interface/list.tt @@ -21,9 +21,9 @@ [% l(interfaces.$i.type) %] [% IF interfaces.$i.vlan -%] - [% l('Delete') %] + [% IF can_access("INTERFACES_DELETE") %][% l('Delete') %][% END %] [% ELSE -%] - [% l('Add VLAN') %] + [% IF can_access("INTERFACES_CREATE") %][% l('Add VLAN') %][% END %] [% END -%] diff --git a/html/pfappserver/root/interface/view.tt b/html/pfappserver/root/interface/view.tt index bd644b4ecf51..6b049b5c0008 100644 --- a/html/pfappserver/root/interface/view.tt +++ b/html/pfappserver/root/interface/view.tt @@ -12,6 +12,6 @@ From d50f7b26390a1ded8b18e83b2fab54761acdb509 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Mon, 4 Nov 2013 10:01:03 -0500 Subject: [PATCH 269/369] Change type of access_level column We no longer use a bit string but simply a string that refers to one or many roles from conf/adminroles.conf --- db/upgrade-4.0.0-4.1.0.sql | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/db/upgrade-4.0.0-4.1.0.sql b/db/upgrade-4.0.0-4.1.0.sql index 50d532aaaebb..38642e1e7658 100644 --- a/db/upgrade-4.0.0-4.1.0.sql +++ b/db/upgrade-4.0.0-4.1.0.sql @@ -1,5 +1,13 @@ -- --- category of temporary password is not mandatory +-- category of temporary_password is not mandatory -- -ALTER TABLE `temporary_password` MODIFY category int DEFAULT NULL; \ No newline at end of file +ALTER TABLE `temporary_password` MODIFY category int DEFAULT NULL; + +-- +-- access_level of temporary_password is now a string instead of a bit string +-- + +ALTER TABLE temporary_password CHANGE access_level access_level varchar(255) DEFAULT 'NONE'; +UPDATE temporary_password SET access_level = 'ALL' WHERE access_level = '4294967295'; +UPDATE temporary_password SET access_level = 'NONE' WHERE access_level = '0'; From 442c6e0c8721f891fa05fcd36d458d73a345871f Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Thu, 21 Nov 2013 16:40:40 -0500 Subject: [PATCH 270/369] Switch editor: Remove 'disabled' class of Save btn --- html/pfappserver/root/configuration/switch/view.tt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/html/pfappserver/root/configuration/switch/view.tt b/html/pfappserver/root/configuration/switch/view.tt index d84969ba557e..b247096fb3f0 100644 --- a/html/pfappserver/root/configuration/switch/view.tt +++ b/html/pfappserver/root/configuration/switch/view.tt @@ -90,7 +90,7 @@ From 486c29face67376b375270d64f7309cd587ba838 Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Fri, 11 Oct 2013 16:18:15 -0400 Subject: [PATCH 271/369] Added wiredeauthTechniques method like deauthTechniques for the wireless Added ArubaSwitch switch module (mac auth and 802.1x and CoA support) Added Dell Force10 switch module Added CoA deauth support for Cisco Switch --- lib/pf/SNMP.pm | 37 +++- lib/pf/SNMP/ArubaSwitch.pm | 249 +++++++++++++++++++++++++++ lib/pf/SNMP/Brocade.pm | 2 +- lib/pf/SNMP/Cisco/Catalyst_2950.pm | 29 +++- lib/pf/SNMP/Cisco/Catalyst_2960.pm | 134 +++++++++++++- lib/pf/SNMP/Dell/Force10.pm | 157 +++++++++++++++++ lib/pf/SNMP/Juniper.pm | 2 +- lib/pf/SNMP/MockedSwitch.pm | 20 ++- lib/pf/SNMP/PacketFence.pm | 34 ++-- lib/pf/SNMP/ThreeCom/Switch_4200G.pm | 2 +- lib/pf/enforcement.pm | 6 +- sbin/pfsetvlan | 16 +- 12 files changed, 655 insertions(+), 33 deletions(-) create mode 100644 lib/pf/SNMP/ArubaSwitch.pm create mode 100644 lib/pf/SNMP/Dell/Force10.pm diff --git a/lib/pf/SNMP.pm b/lib/pf/SNMP.pm index 49e239b75c46..02786dab3e38 100644 --- a/lib/pf/SNMP.pm +++ b/lib/pf/SNMP.pm @@ -2413,7 +2413,7 @@ ifIndex - ifIndex to force re-authentication on =cut sub dot1xPortReauthenticate { - my ($this, $ifIndex) = @_; + my ($this, $ifIndex, $mac) = @_; return $this->_dot1xPortReauthenticate($ifIndex); } @@ -2475,7 +2475,7 @@ Default behavior is to bounce the port =cut sub handleReAssignVlanTrapForWiredMacAuth { - my ($this, $ifIndex) = @_; + my ($this, $ifIndex, $mac) = @_; my $logger = Log::Log4perl::get_logger(ref($this)); # TODO extract that behavior in a method call in pf::vlan so it can be overridden easily @@ -2814,6 +2814,39 @@ sub getIfIndexByNasPortId { return $FALSE; } +=item wiredeauthTechniques + +Return the reference to the deauth technique or the default deauth technique. + +=cut + +sub wiredeauthTechniques { + my ($this, $method, $connection_type) = @_; + my $logger = Log::Log4perl::get_logger( ref($this) ); + if ($connection_type == $WIRED_802_1X) { + my $default = $SNMP::SNMP; + my %tech = ( + $SNMP::SNMP => \&dot1xPortReauthenticate, + ); + + if (!defined($method) || !defined($tech{$method})) { + $method = $default; + } + return $method,$tech{$method}; + } + if ($connection_type == $WIRED_MAC_AUTH) { + my $default = $SNMP::SNMP; + my %tech = ( + $SNMP::SNMP => \&handleReAssignVlanTrapForWiredMacAuth, + ); + + if (!defined($method) || !defined($tech{$method})) { + $method = $default; + } + return $method,$tech{$method}; + } +} + =back =head1 AUTHOR diff --git a/lib/pf/SNMP/ArubaSwitch.pm b/lib/pf/SNMP/ArubaSwitch.pm new file mode 100644 index 000000000000..97a4731c6cd8 --- /dev/null +++ b/lib/pf/SNMP/ArubaSwitch.pm @@ -0,0 +1,249 @@ +package pf::SNMP::ArubaSwitch; + +=head1 NAME + +pf::SNMP::ArubaSwitch - Object oriented module to access SNMP enabled Aruba Switches + +=head1 SYNOPSIS + +The pf::SNMP::ArubaSwitch module implements an object oriented interface +to access SNMP enabled Aruba switches. + +=head1 STATUS + +=over + +=item Supports + +=over + +=item 802.1X and MAC-Authentication with and without VoIP + +=back + +Stacked switch support has not been tested. + +=back + + +=head1 BUGS AND LIMITATIONS + +=over + +=back + +=head1 CONFIGURATION AND ENVIRONMENT + +F + +=cut + +use strict; +use warnings; +use Log::Log4perl; +use Net::SNMP; +use base ('pf::SNMP'); + +sub description { 'Aruba Switches' } + +# importing switch constants +use pf::SNMP::constants; +use pf::util; +use pf::config; + +=head1 SUBROUTINES + +=over + +=cut +# CAPABILITIES +# access technology supported +sub supportsRoleBasedEnforcement { return $TRUE; } +sub supportsWiredMacAuth { return $TRUE; } +sub supportsWiredDot1x { return $TRUE; } +sub supportsRadiusDynamicVlanAssignment { return $TRUE; } +# sub supportsRadiusVoip { return $TRUE; } +# inline capabilities +sub inlineCapabilities { return ($MAC,$PORT); } + + +=item getVersion + +=cut + +sub getVersion { + my ($this) = @_; + my $oid_sysDescr = '1.3.6.1.2.1.1.1.0'; + my $logger = Log::Log4perl::get_logger( ref($this) ); + if ( !$this->connectRead() ) { + return ''; + } + $logger->trace("SNMP get_request for sysDescr: $oid_sysDescr"); + my $result = $this->{_sessionRead}->get_request( -varbindlist => [$oid_sysDescr] ); + my $sysDescr = ( $result->{$oid_sysDescr} || '' ); + if ( $sysDescr =~ m/V(\d{1}\.\d{2}\.\d{2})/ ) { + return $1; + } elsif ( $sysDescr =~ m/Version (\d+\.\d+\([^)]+\)[^,\s]*)(,|\s)+/ ) { + return $1; + } else { + return $sysDescr; + } +} + +=item _dot1xPortReauthenticate + +Actual implementation. + +Allows callers to refer to this implementation even though someone along the way override the above call. + +=cut + +sub dot1xPortReauthenticate { + my ($this, $ifIndex) = @_; + my $logger = Log::Log4perl::get_logger(ref($this)); + + return; +} + + +=item parseTrap + +All traps ignored + +=cut + +sub parseTrap { + my ( $this, $trapString ) = @_; + my $trapHashRef; + my $logger = Log::Log4perl::get_logger( ref($this) ); + + $logger->debug("trap ignored, not useful for switch"); + $trapHashRef->{'trapType'} = 'unknown'; + + return $trapHashRef; +} + +=head2 getIfIndexByNasPortId + +Fetch the ifindex on the switch by NAS-Port-Id radius attribute + +=cut + + +sub getIfIndexByNasPortId { + my ($this, $ifDesc_param) = @_; + + if ( !$this->connectRead() ) { + return 0; + } + + my @ifDescTemp = split(':',$ifDesc_param); + my $OID_ifDesc = '1.3.6.1.2.1.2.2.1.2'; + my $ifDescHashRef; + my $result = $this->{_sessionRead}->get_table( -baseoid => $OID_ifDesc ); + foreach my $key ( keys %{$result} ) { + my $ifDesc = $result->{$key}; + if ( $ifDesc =~ /$ifDescTemp[1]$/i ) { + $key =~ /^$OID_ifDesc\.(\d+)$/; + return $1; + } + } +} + +=item deauthenticateMacRadius + +Method to deauth a wired node with CoA. + +=cut +sub deauthenticateMacRadius { + my ($this, $ifIndex,$mac) = @_; + my $logger = Log::Log4perl::get_logger(ref($this)); + + + # perform CoA + $this->radiusDisconnect($mac); +} + +=item returnRoleAttribute + +What RADIUS Attribute (usually VSA) should the role returned into. + +=cut + +sub returnRoleAttribute { + my ($this) = @_; + + return 'Aruba-User-Role'; +} + +=item wiredeauthTechniques + +Return the reference to the deauth technique or the default deauth technique. + +=cut + +sub wiredeauthTechniques { + my ($this, $method, $connection_type) = @_; + my $logger = Log::Log4perl::get_logger( ref($this) ); + if ($connection_type == $WIRED_802_1X) { + my $default = $SNMP::SNMP; + my %tech = ( + $SNMP::SNMP => \&dot1xPortReauthenticate, + $SNMP::RADIUS => \&deauthenticateMacRadius, + ); + + if (!defined($method) || !defined($tech{$method})) { + $method = $default; + } + return $method,$tech{$method}; + } + if ($connection_type == $WIRED_MAC_AUTH) { + my $default = $SNMP::SNMP; + my %tech = ( + $SNMP::SNMP => \&handleReAssignVlanTrapForWiredMacAuth, + $SNMP::RADIUS => \&deauthenticateMacRadius, + ); + + if (!defined($method) || !defined($tech{$method})) { + $method = $default; + } + return $method,$tech{$method}; + } +} + + +=back + +=head1 AUTHOR + +Inverse inc. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + +# vim: set shiftwidth=4: +# vim: set expandtab: +# vim: set backspace=indent,eol,start: + diff --git a/lib/pf/SNMP/Brocade.pm b/lib/pf/SNMP/Brocade.pm index 2247c9400293..e273c7a8398e 100644 --- a/lib/pf/SNMP/Brocade.pm +++ b/lib/pf/SNMP/Brocade.pm @@ -122,7 +122,7 @@ Allows callers to refer to this implementation even though someone along the way =cut sub dot1xPortReauthenticate { - my ($this, $ifIndex) = @_; + my ($this, $ifIndex, $mac) = @_; my $logger = Log::Log4perl::get_logger(ref($this)); diff --git a/lib/pf/SNMP/Cisco/Catalyst_2950.pm b/lib/pf/SNMP/Cisco/Catalyst_2950.pm index b82b98f2d30d..17374aee24a9 100644 --- a/lib/pf/SNMP/Cisco/Catalyst_2950.pm +++ b/lib/pf/SNMP/Cisco/Catalyst_2950.pm @@ -976,7 +976,7 @@ or set the VLAN and log if there is a VoIP device. =cut sub dot1xPortReauthenticate { - my ($this, $ifIndex) = @_; + my ($this, $ifIndex, $mac) = @_; my $logger = Log::Log4perl::get_logger(ref($this)); $logger->info( @@ -1016,7 +1016,7 @@ sub dot1xPortReauthenticate { "Changing VLAN and leaving everything as it is." ); - my $mac = $locationlog[0]->{'mac'}; + $mac = $locationlog[0]->{'mac'}; my $vlan_obj = new pf::vlan::custom(); my ($vlan,$wasInline) = $vlan_obj->fetchVlanForNode($mac, $this, $ifIndex, $WIRED_802_1X); @@ -1160,6 +1160,31 @@ sub ifIndexToLldpLocalPort { return; } +=item getIfIndexByNasPortId + +Fetch the ifindex on the switch by NAS-Port-Id radius attribute + +=cut + +sub getIfIndexiByNasPortId { + my ($this, $ifDesc_param) = @_; + + if ( !$this->connectRead() ) { + return 0; + } + + my $OID_ifDesc = '1.3.6.1.2.1.2.2.1.2'; + my $ifDescHashRef; + my $result = $this->{_sessionRead}->get_table( -baseoid => $OID_ifDesc ); + foreach my $key ( keys %{$result} ) { + my $ifDesc = $result->{$key}; + if ( $ifDesc =~ /$ifDesc_param$/i ) { + $key =~ /^$OID_ifDesc\.(\d+)$/; + return $1; + } + } +} + =back =head1 AUTHOR diff --git a/lib/pf/SNMP/Cisco/Catalyst_2960.pm b/lib/pf/SNMP/Cisco/Catalyst_2960.pm index 844406acc094..d1761490dc3c 100644 --- a/lib/pf/SNMP/Cisco/Catalyst_2960.pm +++ b/lib/pf/SNMP/Cisco/Catalyst_2960.pm @@ -136,6 +136,10 @@ use base ('pf::SNMP::Cisco::Catalyst_2950'); use pf::config; use pf::SNMP::constants; use pf::util; +use pf::accounting qw(node_accounting_current_sessionid); +use pf::node qw(node_attributes); +use pf::util::radius qw(perform_coa perform_disconnect); + sub description { 'Cisco Catalyst 2960' } @@ -328,7 +332,7 @@ Points to pf::SNMP implementation bypassing Catalyst_2950's overridden behavior. =cut sub dot1xPortReauthenticate { - my ($this, $ifIndex) = @_; + my ($this, $ifIndex, $mac) = @_; return $this->_dot1xPortReauthenticate($ifIndex); } @@ -366,6 +370,134 @@ sub getVoipVsa { return ('Cisco-AVPair' => "device-traffic-class=voice"); } +=item deauthenticateMacRadius + +Method to deauth a wired node with CoA. + +=cut +sub deauthenticateMacRadius { + my ($this, $ifIndex,$mac) = @_; + my $logger = Log::Log4perl::get_logger(ref($this)); + + + # perform CoA + my $acctsessionid = node_accounting_current_sessionid($mac); + $this->radiusDisconnect($mac ,{ 'Acct-Terminate-Cause' => 'Admin-Reset'}); +} + +=item radiusDisconnect + +Send a CoA to disconnect a mac + +=cut +sub radiusDisconnect { + my ($self, $mac, $add_attributes_ref) = @_; + my $logger = Log::Log4perl::get_logger( ref($self) ); + + # initialize + $add_attributes_ref = {} if (!defined($add_attributes_ref)); + + if (!defined($self->{'_radiusSecret'})) { + $logger->warn( + "Unable to perform RADIUS CoA-Request on $self->{'_ip'}: RADIUS Shared Secret not configured" + ); + return; + } + + $logger->info("deauthenticating $mac"); + + # Where should we send the RADIUS CoA-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 = { + nas_ip => $send_disconnect_to, + secret => $self->{'_radiusSecret'}, + LocalAddr => $management_network->tag('vip'), + }; + + $logger->debug("network device supports roles. Evaluating role to be returned"); + my $roleResolver = pf::roles::custom->instance(); + my $role = $roleResolver->getRoleForNode($mac, $self); + + my $node_info = node_attributes($mac); + # 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, + 'NAS-IP-Address' => $send_disconnect_to, + }; + + # merging additional attributes provided by caller to the standard attributes + $attributes_ref = { %$attributes_ref, %$add_attributes_ref }; + + $response = perform_coa($connection_info, $attributes_ref, [{ 'vendor' => 'Cisco', 'attribute' => 'Cisco-AVPair', 'value' => 'subscriber:command=reauthenticate' }]); + + } catch { + chomp; + $logger->warn("Unable to perform RADIUS CoA-Request: $_"); + $logger->error("Wrong RADIUS secret or unreachable network device...") if ($_ =~ /^Timeout/); + }; + return if (!defined($response)); + + return $TRUE if ($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 wiredeauthTechniques + +Return the reference to the deauth technique or the default deauth technique. + +=cut + +sub wiredeauthTechniques { + my ($this, $method, $connection_type) = @_; + my $logger = Log::Log4perl::get_logger( ref($this) ); + if ($connection_type == $WIRED_802_1X) { + my $default = $SNMP::SNMP; + my %tech = ( + $SNMP::SNMP => \&dot1xPortReauthenticate, + $SNMP::RADIUS => \&deauthenticateMacRadius, + ); + + if (!defined($method) || !defined($tech{$method})) { + $method = $default; + } + return $method,$tech{$method}; + } + if ($connection_type == $WIRED_MAC_AUTH) { + my $default = $SNMP::SNMP; + my %tech = ( + $SNMP::SNMP => \&handleReAssignVlanTrapForWiredMacAuth, + $SNMP::RADIUS => \&deauthenticateMacRadius, + ); + + if (!defined($method) || !defined($tech{$method})) { + $method = $default; + } + return $method,$tech{$method}; + } +} + =back =head1 AUTHOR diff --git a/lib/pf/SNMP/Dell/Force10.pm b/lib/pf/SNMP/Dell/Force10.pm new file mode 100644 index 000000000000..d144f43e82fc --- /dev/null +++ b/lib/pf/SNMP/Dell/Force10.pm @@ -0,0 +1,157 @@ +package pf::SNMP::Dell::Force10; + +=head1 NAME + +pf::SNMP::Dell::Force10 - Object oriented module to access SNMP enabled Dell Force10 switches + +=head1 SYNOPSIS + +The pf::SNMP::Dell::Force10 module implements an object oriented interface to access SNMP enabled Dell:Force10 switches. + +The minimum required firmware version is ... + +=head1 CONFIGURATION AND ENVIRONMENT + +F + +=cut + +use strict; +use warnings; +use Log::Log4perl; +use pf::config; +use base ('pf::SNMP::Dell'); + +sub description { 'Dell Force 10' } + +# CAPABILITIES +# access technology supported +sub supportsWiredMacAuth { return $TRUE; } +sub supportsWiredDot1x { return $TRUE; } +# VoIP technology supported +sub supportsRadiusVoip { return $TRUE; } +# override 2950's FALSE +sub supportsRadiusDynamicVlanAssignment { return $TRUE; } + +sub getMinOSVersion { + my ($this) = @_; + my $logger = Log::Log4perl::get_logger( ref($this) ); + return '112'; +} + +=item * _identifyConnectionType + +Identify the connection type based information provided by RADIUS call + +Returns the constants $WIRED or $WIRELESS. Undef if unable to identify. + +=cut + +sub _identifyConnectionType { + my ($this, $nas_port_type, $eap_type, $mac, $user_name) = @_; + my $logger = Log::Log4perl::get_logger(ref($this)); + + $eap_type = 0 if (not defined($eap_type)); + if (defined($nas_port_type)) { + + if ($nas_port_type =~ /^Wireless-802\.11/) { + + if ($eap_type) { + return $WIRELESS_802_1X; + } else { + return $WIRELESS_MAC_AUTH; + } + + } elsif ($nas_port_type =~ /^Ethernet/ ) { + + if ($eap_type) { + + # some vendor do EAP-based Wired MAC Authentication, as far as PacketFence is concerned + # this is still MAC Authentication so we need to cheat a little bit here + # TODO: consider moving this logic later once the switch is initialized so we can ask it + # (supportsEAPMacAuth?) + $mac =~ s/[^[:xdigit:]]//g; + if (lc $mac eq lc $user_name) { + return $WIRED_MAC_AUTH; + } else { + return $WIRED_802_1X; + } + + } else { + return $WIRED_MAC_AUTH; + } + + } else { + # we didn't recognize request_type, this is a problem + $logger->warn("Unknown connection_type. NAS-Port-Type: $nas_port_type, EAP-Type: $eap_type."); + return; + } + } else { + + #$logger->warn("Request type was not set. There is a problem with the NAS, your radius config " + # ."or rlm_perl packetfence.pm FreeRADIUS module."); + return $WIRED_MAC_AUTH; + } +} + +=item getIfIndexByNasPortId + +Fetch the ifindex on the switch by NAS-Port-Id radius attribute + +=cut + +sub getIfIndexByNasPortId { + my ($this, $ifDesc_param) = @_; + my $logger = Log::Log4perl::get_logger(ref($this)); + if ( !$this->connectRead() ) { + return 0; + } + my @ifDesc_val = split('/',$ifDesc_param); + my $OID_ifDesc = '1.3.6.1.2.1.17.1.4.1.2.'.$ifDesc_param; + $logger->warn($OID_ifDesc); + my $ifDescHashRef; + my $result = $this->{_sessionRead}->get_request( -varbindlist => [ "$OID_ifDesc" ] ); + return $result->{"$OID_ifDesc"}; + foreach my $key ( keys %{$result} ) { + my $ifDesc = $result->{$key}; + if ( $ifDesc =~ /$ifDesc_val[1]$/i ) { + $key =~ /^$OID_ifDesc\.(\d+)$/; + return $1; + } + } +} + + +=head1 AUTHOR + +Inverse inc. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + +# vim: set shiftwidth=4: +# vim: set expandtab: +# vim: set backspace=indent,eol,start: + diff --git a/lib/pf/SNMP/Juniper.pm b/lib/pf/SNMP/Juniper.pm index ae7b7ee9e78b..66a6aeae89d0 100644 --- a/lib/pf/SNMP/Juniper.pm +++ b/lib/pf/SNMP/Juniper.pm @@ -183,7 +183,7 @@ Called when a ReAssignVlan trap is received for a switch-port in Wired MAC Authe =cut sub handleReAssignVlanTrapForWiredMacAuth { - my ($this, $ifIndex) = @_; + my ($this, $ifIndex, $mac) = @_; my $logger = Log::Log4perl::get_logger(ref($this)); my $switch_ip = $this->{_ip}; diff --git a/lib/pf/SNMP/MockedSwitch.pm b/lib/pf/SNMP/MockedSwitch.pm index 33648bf73d3f..4801041e8b09 100644 --- a/lib/pf/SNMP/MockedSwitch.pm +++ b/lib/pf/SNMP/MockedSwitch.pm @@ -2535,7 +2535,7 @@ ifIndex - ifIndex to force re-authentication on =cut sub dot1xPortReauthenticate { - my ($this, $ifIndex) = @_; + my ($this, $ifIndex, $mac) = @_; return $this->_dot1xPortReauthenticate($ifIndex); } @@ -2768,7 +2768,7 @@ sub NasPortToIfIndex { =cut sub handleReAssignVlanTrapForWiredMacAuth { - my ($this, $ifIndex) = @_; + my ($this, $ifIndex, $mac) = @_; my $logger = Log::Log4perl::get_logger(ref($this)); my $switch_ip = $this->{'_ip'}; @@ -2778,7 +2778,9 @@ sub handleReAssignVlanTrapForWiredMacAuth { return; } - my $mac = $locationlog[0]->{'mac'}; + if (!defined($mac)) { + $mac = $locationlog[0]->{'mac'}; + } my $hasPhone = $this->hasPhoneAtIfIndex($ifIndex); # TODO extract that behavior in a method call in pf::vlan so it can be overridden easily @@ -2889,6 +2891,18 @@ sub getIfIndexByNasPortId { return $FALSE; } +=item wiredeauthTechniques + +Return the reference to the deauth technique or the default deauth technique. + +=cut + +sub wiredeauthTechniques { + my ($this, $method, $connection_type) = @_; + my $logger = Log::Log4perl::get_logger( ref($this) ); + return $TRUE; +} + =back =head1 AUTHOR diff --git a/lib/pf/SNMP/PacketFence.pm b/lib/pf/SNMP/PacketFence.pm index 87e552c03ff5..1ce8da0753b2 100644 --- a/lib/pf/SNMP/PacketFence.pm +++ b/lib/pf/SNMP/PacketFence.pm @@ -48,20 +48,34 @@ sub connectWrite { } sub sendLocalReAssignVlanTrap { - my ($this, $switch_ip, $ifIndex, $connection_type) = @_; + my ($this, $switch_ip, $ifIndex, $connection_type, $mac) = @_; my $logger = Log::Log4perl::get_logger( ref($this) ); if ( !$this->connectWrite() ) { return 0; } - my $result = $this->{_sessionWrite}->trap( - -genericTrap => Net::SNMP::ENTERPRISE_SPECIFIC, - -agentaddr => $switch_ip, - -varbindlist => [ - '1.3.6.1.6.3.1.1.4.1.0', Net::SNMP::OBJECT_IDENTIFIER, '1.3.6.1.4.1.29464.1.1', - "1.3.6.1.2.1.2.2.1.1.$ifIndex", Net::SNMP::INTEGER, $ifIndex, - "1.3.6.1.2.1.2.2.1.1.$ifIndex", Net::SNMP::INTEGER, $connection_type, - ] - ); + my $result; + if (defined($mac)) { + $result = $this->{_sessionWrite}->trap( + -genericTrap => Net::SNMP::ENTERPRISE_SPECIFIC, + -agentaddr => $switch_ip, + -varbindlist => [ + '1.3.6.1.6.3.1.1.4.1.0', Net::SNMP::OBJECT_IDENTIFIER, '1.3.6.1.4.1.29464.1.1', + "1.3.6.1.2.1.2.2.1.1.$ifIndex", Net::SNMP::INTEGER, $ifIndex, + "1.3.6.1.2.1.2.2.1.1.$ifIndex", Net::SNMP::INTEGER, $connection_type, + "1.3.6.1.4.1.29464.1.3", Net::SNMP::OCTET_STRING, $mac, + ] + ); + } else { + $result = $this->{_sessionWrite}->trap( + -genericTrap => Net::SNMP::ENTERPRISE_SPECIFIC, + -agentaddr => $switch_ip, + -varbindlist => [ + '1.3.6.1.6.3.1.1.4.1.0', Net::SNMP::OBJECT_IDENTIFIER, '1.3.6.1.4.1.29464.1.1', + "1.3.6.1.2.1.2.2.1.1.$ifIndex", Net::SNMP::INTEGER, $ifIndex, + "1.3.6.1.2.1.2.2.1.1.$ifIndex", Net::SNMP::INTEGER, $connection_type, + ] + ); + } if ( !$result ) { $logger->error( "error sending SNMP trap: " . $this->{_sessionWrite}->error() ); diff --git a/lib/pf/SNMP/ThreeCom/Switch_4200G.pm b/lib/pf/SNMP/ThreeCom/Switch_4200G.pm index 08e5af420e48..9ea82472579b 100644 --- a/lib/pf/SNMP/ThreeCom/Switch_4200G.pm +++ b/lib/pf/SNMP/ThreeCom/Switch_4200G.pm @@ -140,7 +140,7 @@ See in L. =cut sub dot1xPortReauthenticate { - my ($this, $ifIndex) = @_; + my ($this, $ifIndex, $mac) = @_; my $logger = Log::Log4perl::get_logger(ref($this)); $logger->warn( diff --git a/lib/pf/enforcement.pm b/lib/pf/enforcement.pm index cbcd2417311f..0a0e25b6e592 100644 --- a/lib/pf/enforcement.pm +++ b/lib/pf/enforcement.pm @@ -131,7 +131,7 @@ sub _vlan_reevaluation { } elsif ($conn_type == $WIRED_SNMP_TRAPS) { $logger->debug("sending a local reAssignVlan trap to force VLAN change"); - $trapSender->sendLocalReAssignVlanTrap($switch_ip, $ifIndex, $conn_type); + $trapSender->sendLocalReAssignVlanTrap($switch_ip, $ifIndex, $conn_type, $mac); } elsif ($conn_type == $WIRELESS_MAC_AUTH) { $logger->debug("sending a local desAssociate trap to force deassociation " @@ -150,11 +150,11 @@ sub _vlan_reevaluation { } elsif ($conn_type == $WIRED_802_1X) { $logger->debug("sending a local reAssignVlan trap to force VLAN change"); - $trapSender->sendLocalReAssignVlanTrap($switch_ip, $ifIndex, $conn_type); + $trapSender->sendLocalReAssignVlanTrap($switch_ip, $ifIndex, $conn_type, $mac); } elsif ($conn_type == $WIRED_MAC_AUTH) { $logger->debug("sending a local reAssignVlan trap to force VLAN change"); - $trapSender->sendLocalReAssignVlanTrap($switch_ip, $ifIndex, $conn_type); + $trapSender->sendLocalReAssignVlanTrap($switch_ip, $ifIndex, $conn_type, $mac); } } else { $logger->error("Can't instantiate switch 127.0.0.1! Check your configuration!"); diff --git a/sbin/pfsetvlan b/sbin/pfsetvlan index 521f48014baf..3ff8769a172e 100755 --- a/sbin/pfsetvlan +++ b/sbin/pfsetvlan @@ -594,17 +594,20 @@ sub parseTrap { \.1\.3\.6\.1\.6\.3\.1\.1\.4\.1\.0\ =\ OID:\ \.1\.3\.6\.1\.4\.1\.29464\.1\.1 # metadata \|\.1\.3\.6\.1\.2\.1\.2\.2\.1\.1\.(\d+)\ =\ INTEGER:\ \d+ # ifIndex \|\.1\.3\.6\.1\.2\.1\.2\.2\.1\.1\.\d+\ =\ INTEGER:\ (\d+) # connection type + \|\.1\.3\.6\.1\.4\.1\.29464\.1\.3\ =\ STRING:\ \"(.+)\" # mac /x) { # WARNING: using trap operation for something it is not meant to $trapHashRef = { 'trapType' => 'reAssignVlan', 'trapIfIndex' => $1, 'trapOperation' => $2, + 'trapMac' => $3, }; } elsif ($trapLine =~ /BEGIN VARIABLEBINDINGS \.1\.3\.6\.1\.6\.3\.1\.1\.4\.1\.0 = OID: \.1\.3\.6\.1\.4\.1\.29464\.1\.1\|\.1\.3\.6\.1\.2\.1\.2\.2\.1\.1\.(\d+) = INTEGER:/) { $trapHashRef = { 'trapType' => 'reAssignVlan', 'trapIfIndex' => $1, + 'trapMac' => $3, }; } elsif ($trapLine =~ /BEGIN\ VARIABLEBINDINGS\ # metadata @@ -711,6 +714,7 @@ sub parseTrap { } elsif ($trapType eq 'reAssignVlan') { $trapOperation = $trapHashRef->{'trapOperation'}; + $trapMac = $trapHashRef->{'trapMac'}; } elsif ($trapType eq 'roaming') { $trapMac = $trapHashRef->{'trapMac'}; $trapMac =~ s/ /:/g; @@ -1609,15 +1613,9 @@ sub handleTrap { my $connection_type = $trapOperation; # WARNING: I used trapOperation to carry the connection type $logger->info("$trapType trap received on $switch_ip ifIndex $switch_port"); - if (defined($connection_type) && $connection_type == $WIRED_802_1X) { - # we spawn a shell to workaround a thread safety bug in Net::Appliance::Session when using SSH transport - # http://www.cpanforum.com/threads/6909 - $logger->info("Forcing 802.1x re-authentication on $switch_ip:$switch_port. A new VLAN will be assigned."); - pf_run("/usr/local/pf/bin/pfcmd_vlan -deauthenticateDot1x -switch $switch_ip -ifIndex $switch_port"); - - } elsif (defined($connection_type) && $connection_type == $WIRED_MAC_AUTH) { - $switch->handleReAssignVlanTrapForWiredMacAuth($switch_port); - + if (defined($connection_type) && ($connection_type == $WIRED_802_1X || $connection_type == $WIRED_MAC_AUTH) ) { + my ($switchdeauthMethod, $deauthTechniques) = $switch->wiredeauthTechniques($switch->{_deauthMethod},$connection_type); + $deauthTechniques->($switch_port,$trapMac); } else { my @locationlog = locationlog_view_open_switchport_no_VoIP( $switch_ip, $switch_port ); From 25f1f5d7e7acd97801afd7e17dcd50cc1f57aa6b Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Fri, 11 Oct 2013 16:49:38 -0400 Subject: [PATCH 272/369] Update doc Added radius attribute --- ...twork_Devices_Configuration_Guide.asciidoc | 46 +++++++++++++++++++ lib/pf/radius.pm | 2 +- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/docs/PacketFence_Network_Devices_Configuration_Guide.asciidoc b/docs/PacketFence_Network_Devices_Configuration_Guide.asciidoc index 16163d14ff51..37d768cac4e9 100644 --- a/docs/PacketFence_Network_Devices_Configuration_Guide.asciidoc +++ b/docs/PacketFence_Network_Devices_Configuration_Guide.asciidoc @@ -108,6 +108,7 @@ PacketFence supports the following devices: | |DWL Access-Points |Dlink::DWL | |DWS 3026 |Dlink::DWS_3026 |Dell |PowerConnect 3424 |Dell::PowerConnect3424 +| |Force 10 |Dell::Force10 |Edge-corE |3526XA |Accton::ES3536XA | |3528M |Accton::ES3528M |Enterasys |Matrix N3 |Enterasys::Matrix_N3 @@ -860,6 +861,12 @@ Radius server configuration: radius-server host 192.168.1.5 auth-port 1812 acct-port 1813 timeout 2 key useStrongerSecret radius-server vsa send authentication +CoA configuration + + aaa server radius dynamic-author + client 192.168.1.5 server-key useStrongerSecret + port 3799 + 802.1x with MAC Authentication bypass (Multi­Host) ++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -896,6 +903,12 @@ Radius server configuration radius-server host 10.10.10.10 auth-port 1812 acct-port 1813 timeout 2 key useStrongerSecret radius-server vsa send authentication +CoA configuration + + aaa server radius dynamic-author + client 192.168.1.5 server-key useStrongerSecret + port 3799 + MAC Authentication bypass only ++++++++++++++++++++++++++++++ @@ -932,6 +945,12 @@ Radius server configuration radius-server host 192.168.1.5 auth-port 1812 acct-port 1813 timeout 2 key useStrongerSecret radius-server vsa send authentication +CoA configuration + + aaa server radius dynamic-author + client 192.168.1.5 server-key useStrongerSecret + port 3799 + Port-­Security ++++++++++++++ @@ -1108,6 +1127,33 @@ On each interface: Dell ~~~~ +Force 10 +^^^^^^^^ + +PacketFence supports this switch using radiusi mac-auth and 802.1x + +Global config settings + + radius-server host 192.168.1.5 key s3cr3t auth-port 1812 + +MAB interface configuration: + + interface GigabitEthernet 0/1 + no ip address + switchport + dot1x authentication + dot1x mac-auth-bypass + dot1x auth-type mab-only + no shutdown + +802.1x interface configuration: + + interface GigabitEthernet 0/1 + no ip address + switchport + dot1x authentication + no shutdown + PowerConnect 3424 ^^^^^^^^^^^^^^^^^ diff --git a/lib/pf/radius.pm b/lib/pf/radius.pm index ed77497fbe3d..04b30d99b347 100644 --- a/lib/pf/radius.pm +++ b/lib/pf/radius.pm @@ -234,7 +234,7 @@ sub _parseRequest { $eap_type = $radius_request->{'EAP-Type'}; } - my $nas_port_id_key = first { exists $radius_request->{$_} && defined $radius_request->{$_} } qw(Cisco-NAS-Port NAS-Port-Id); + my $nas_port_id_key = first { exists $radius_request->{$_} && defined $radius_request->{$_} } qw(Aruba-Port-Identifier Cisco-NAS-Port NAS-Port-Id); my $nas_port_id; if ($nas_port_id_key) { $nas_port_id = $radius_request->{$nas_port_id_key}; From 690509843c60da78ba86fc9a9c835535f91f83e0 Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Tue, 15 Oct 2013 11:08:27 -0400 Subject: [PATCH 273/369] Added custom radius answer for aruba switch (remove vlan id if we have a role) --- lib/pf/SNMP/ArubaSwitch.pm | 56 +++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/lib/pf/SNMP/ArubaSwitch.pm b/lib/pf/SNMP/ArubaSwitch.pm index 97a4731c6cd8..6ed5a8a183cb 100644 --- a/lib/pf/SNMP/ArubaSwitch.pm +++ b/lib/pf/SNMP/ArubaSwitch.pm @@ -42,6 +42,7 @@ use strict; use warnings; use Log::Log4perl; use Net::SNMP; +use Try::Tiny; use base ('pf::SNMP'); sub description { 'Aruba Switches' } @@ -139,7 +140,6 @@ sub getIfIndexByNasPortId { my @ifDescTemp = split(':',$ifDesc_param); my $OID_ifDesc = '1.3.6.1.2.1.2.2.1.2'; - my $ifDescHashRef; my $result = $this->{_sessionRead}->get_table( -baseoid => $OID_ifDesc ); foreach my $key ( keys %{$result} ) { my $ifDesc = $result->{$key}; @@ -211,6 +211,60 @@ sub wiredeauthTechniques { } } +=item returnRadiusAccessAccept + +Prepares the RADIUS Access-Accept reponse for the network device. + +Default implementation. + +=cut + +sub returnRadiusAccessAccept { + my ($self, $vlan, $mac, $port, $connection_type, $user_name, $ssid, $wasInline, $user_role) = @_; + my $logger = Log::Log4perl::get_logger( ref($self) ); + + # Inline Vs. VLAN enforcement + my $radius_reply_ref = {}; + + if (!$wasInline || ($wasInline && $vlan != 0)) { + $radius_reply_ref = { + 'Tunnel-Medium-Type' => $RADIUS::ETHERNET, + 'Tunnel-Type' => $RADIUS::VLAN, + 'Tunnel-Private-Group-ID' => $vlan, + }; + } + + # TODO this is experimental + try { + if ($self->supportsRoleBasedEnforcement()) { + $logger->debug("network device supports roles. Evaluating role to be returned"); + my $role = ""; + if ( defined($user_role) && $user_role ne "" ) { + $role = $self->getRoleByName($user_role); + } + if ( defined($role) && $role ne "" ) { + $radius_reply_ref = {}; + $radius_reply_ref->{$self->returnRoleAttribute()} = $role; + $logger->info( + "Added role $role to the returned RADIUS Access-Accept under attribute " . $self->returnRoleAttribute() + ); + } + else { + $logger->debug("received undefined role. No Role added to RADIUS Access-Accept"); + } + } + } + catch { + chomp($_); + $logger->debug( + "Exception when trying to resolve a Role for the node. No Role added to RADIUS Access-Accept. " + . "Exception: $_" + ); + }; + + $logger->info("Returning ACCEPT with VLAN: $vlan"); + return [$RADIUS::RLM_MODULE_OK, %$radius_reply_ref]; +} =back From 374f66f8a66035beeca3899485aca06d150e48f8 Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Wed, 30 Oct 2013 11:05:56 -0400 Subject: [PATCH 274/369] Added HP Standalone access point module --- lib/pf/SNMP/HP/MSM.pm | 138 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 lib/pf/SNMP/HP/MSM.pm diff --git a/lib/pf/SNMP/HP/MSM.pm b/lib/pf/SNMP/HP/MSM.pm new file mode 100644 index 000000000000..fe7c7f88c970 --- /dev/null +++ b/lib/pf/SNMP/HP/MSM.pm @@ -0,0 +1,138 @@ +package pf::SNMP::HP::MSM; + +=head1 NAME + +pf::SNMP::HP::MSM + +=head1 SYNOPSIS + +The pf::SNMP::HP::MSM module manages access to HP Procurve access point MSM + +=head1 STATUS + +Should work on all HP Wireless Access Point + +=cut + +use strict; +use warnings; + +use Log::Log4perl; +use POSIX; + +use base ('pf::SNMP::HP::Controller_MSM710'); + +use pf::config; +sub description { 'HP ProCurve MSM Access Point' } + +# importing switch constants +use pf::SNMP::constants; +use pf::util; +use Net::Appliance::Session; + +=head1 SUBROUTINES + +=over + +=cut + +=item _deauthenticateMacWithSSH + +Method to deauthenticate a node with SSH + +=cut + +sub _deauthenticateMacWithSSH { + my ( $this, $mac ) = @_; + my $logger = Log::Log4perl::get_logger( ref($this) ); + my $session; + my @addition_ops; + if (defined $this->{_controllerPort} && $this->{_cliTransport} eq 'SSH' ) { + @addition_ops = ( + connect_options => { + ops => [ '-p' => $this->{_controllerPort} ] + } + ); + } + eval { + $session = Net::Appliance::Session->new( + Host => $this->{_ip}, + Timeout => 20, + Transport => $this->{_cliTransport}, + Platform => 'HP', + Source => $lib_dir.'/pf/SNMP/HP/nas-pb.yml', + @addition_ops + ); + $session->connect( + Name => $this->{_cliUser}, + Password => $this->{_cliPwd} + ); + }; + + if ($@) { + $logger->error( "ERROR: Can not connect to controller $this->{'_ip'} using " + . $this->{_cliTransport} ); + return 1; + } + $session->cmd("enable"); + $session->cmd("disassociate wireless client $mac"); + $session->close(); + + return 1; +} + +=item deauthTechniques + +Return the reference to the deauth technique or the default deauth technique. + +=cut + +sub deauthTechniques { + my ($this, $method) = @_; + my $logger = Log::Log4perl::get_logger( ref($this) ); + my $default = $SNMP::SSH; + my %tech = ( + $SNMP::SSH => \&_deauthenticateMacWithSSH, + ); + + if (!defined($method) || !defined($tech{$method})) { + $method = $default; + } + return $method,$tech{$method}; +} + + +=back + +=head1 AUTHOR + +Inverse inc. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + +# vim: set shiftwidth=4: +# vim: set expandtab: +# vim: set backspace=indent,eol,start: From 2c984adff6bb4a0c67c0e6349169c31caa38e64b Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Wed, 20 Nov 2013 13:01:05 -0500 Subject: [PATCH 275/369] Missing $switch param --- sbin/pfsetvlan | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbin/pfsetvlan b/sbin/pfsetvlan index 3ff8769a172e..cbfb259d8edb 100755 --- a/sbin/pfsetvlan +++ b/sbin/pfsetvlan @@ -1615,7 +1615,7 @@ sub handleTrap { if (defined($connection_type) && ($connection_type == $WIRED_802_1X || $connection_type == $WIRED_MAC_AUTH) ) { my ($switchdeauthMethod, $deauthTechniques) = $switch->wiredeauthTechniques($switch->{_deauthMethod},$connection_type); - $deauthTechniques->($switch_port,$trapMac); + $deauthTechniques->($switch,$switch_port,$trapMac); } else { my @locationlog = locationlog_view_open_switchport_no_VoIP( $switch_ip, $switch_port ); From 0aace286ff06c7eafda1fe046fdfe6acc231e809 Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Wed, 20 Nov 2013 17:08:28 -0500 Subject: [PATCH 276/369] Missing lib --- lib/pf/SNMP/Cisco/Catalyst_2960.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pf/SNMP/Cisco/Catalyst_2960.pm b/lib/pf/SNMP/Cisco/Catalyst_2960.pm index d1761490dc3c..beae24700124 100644 --- a/lib/pf/SNMP/Cisco/Catalyst_2960.pm +++ b/lib/pf/SNMP/Cisco/Catalyst_2960.pm @@ -131,6 +131,7 @@ use strict; use warnings; use Log::Log4perl; use Net::SNMP; +use Try::Tiny; use base ('pf::SNMP::Cisco::Catalyst_2950'); use pf::config; From 235f2f8cb48dcae0c33af88aaef4813785c3c33e Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Tue, 24 Sep 2013 19:15:41 -0400 Subject: [PATCH 277/369] Added new files for the services refactor --- lib/pf/services/manager.pm | 395 ++++++++++++++++++ lib/pf/services/manager/dhcpd.pm | 101 +++++ lib/pf/services/manager/httpd.pm | 64 +++ lib/pf/services/manager/httpd_admin.pm | 52 +++ lib/pf/services/manager/httpd_portal.pm | 52 +++ lib/pf/services/manager/httpd_webservices.pm | 52 +++ lib/pf/services/manager/memcached.pm | 56 +++ lib/pf/services/manager/pfdetect.pm | 59 +++ lib/pf/services/manager/pfdhcplistener.pm | 74 ++++ lib/pf/services/manager/pfdns.pm | 54 +++ lib/pf/services/manager/pfmon.pm | 54 +++ lib/pf/services/manager/pfsetvlan.pm | 53 +++ lib/pf/services/manager/radiusd.pm | 69 +++ .../manager/roles/pf_conf_service_managed.pm | 55 +++ .../manager/roles/pf_conf_trapping_engine.pm | 69 +++ lib/pf/services/manager/snmptrapd.pm | 59 +++ lib/pf/services/manager/snort.pm | 62 +++ lib/pf/services/manager/submanager.pm | 118 ++++++ lib/pf/services/manager/suricata.pm | 66 +++ 19 files changed, 1564 insertions(+) create mode 100644 lib/pf/services/manager.pm create mode 100644 lib/pf/services/manager/dhcpd.pm create mode 100644 lib/pf/services/manager/httpd.pm create mode 100644 lib/pf/services/manager/httpd_admin.pm create mode 100644 lib/pf/services/manager/httpd_portal.pm create mode 100644 lib/pf/services/manager/httpd_webservices.pm create mode 100644 lib/pf/services/manager/memcached.pm create mode 100644 lib/pf/services/manager/pfdetect.pm create mode 100644 lib/pf/services/manager/pfdhcplistener.pm create mode 100644 lib/pf/services/manager/pfdns.pm create mode 100644 lib/pf/services/manager/pfmon.pm create mode 100644 lib/pf/services/manager/pfsetvlan.pm create mode 100644 lib/pf/services/manager/radiusd.pm create mode 100644 lib/pf/services/manager/roles/pf_conf_service_managed.pm create mode 100644 lib/pf/services/manager/roles/pf_conf_trapping_engine.pm create mode 100644 lib/pf/services/manager/snmptrapd.pm create mode 100644 lib/pf/services/manager/snort.pm create mode 100644 lib/pf/services/manager/submanager.pm create mode 100644 lib/pf/services/manager/suricata.pm diff --git a/lib/pf/services/manager.pm b/lib/pf/services/manager.pm new file mode 100644 index 000000000000..92944f2b5796 --- /dev/null +++ b/lib/pf/services/manager.pm @@ -0,0 +1,395 @@ +package pf::services::manager; +=head1 NAME + +pf::services::manager + +=cut + +=head1 DESCRIPTION + +pf::services::manager + +This module encapsulates the service actions/commands for pfcmd tool + + +=cut + +use strict; + +use pf::file_paths; +use pf::log; +use pf::config; +use Moo; +use File::Slurp qw(read_file); +use Proc::ProcessTable; +use List::Util qw(first); +use Linux::Inotify2; + +=head1 Attributes + +=head2 name + +name of service + +=cut + +has name => ( is => 'rw'); + +=head2 launcher + +sprintf-formatted string that control how the services should be started + %1$s: is the service executable + %2$s: optional parameters + +=cut + +has launcher => ( is => 'rw', lazy => 1); + +=head2 dependsOnServices + +services that this service needs in order to start + +=cut + +has dependsOnServices => (is => 'ro', default => sub { [qw(memcached httpd.admin)] } ); + +=head2 executable + +executable of service + +=cut + +has executable => (is => 'rw', builder => 1, lazy => 1 ); + +=head1 Methods + +=head2 start + + start the service + +=cut + +sub start { + my ($self,$quick) = @_; + my $result = 0; + unless ($self->pid) { + if( $self->preStartSetup($quick)) { + if($self->startService($quick)) { + $result = $self->postStartCleanup($quick); + } + } + } + return $result; +} + +=head2 preStartSetup + + setup work for starting a servicw + +=cut + +sub preStartSetup { + my ($self,$quick) = @_; + $self->removeStalePid; + $self->generateConfig($quick) unless $quick; + return 1; +} + +=head2 startService + + Starts the service + +=cut + +sub startService { + my ($self,$quick) = @_; + return $self->launchService($self->executable); +} + +=head2 postStartCleanup + + Cleanup work after the starting the service + +=cut + +sub postStartCleanup { + my ($self,$quick) = @_; + my $run_dir = "$var_dir/run"; + my $pidFile = $self->pidFile; + my $result = 0; + unless (-e $pidFile) { + my $inotify = Linux::Inotify2->new; + $inotify->watch ($run_dir, IN_CREATE, sub { + my $e = shift; + my $name = $e->fullname; + if($pidFile eq $name) { + $e->w->cancel; + } + }); + my $timedout; + eval { + local $SIG{ALRM} = sub { die "alarm clock restart" }; + alarm 60; + eval { + 1 while !-e $pidFile && $inotify->poll; + }; + alarm 0; + $timedout = 1 if $@ && $@ =~ /^alarm clock restart/; + }; + my $logger = get_logger; + $logger->warn($self->name . " timed out trying to start" ) if $timedout; + alarm 0; + } + return -e $pidFile; +} + +=head2 _build_executable + +the builder the executable attribute + +=cut + +sub _build_executable { + my ($self) = @_; + my $name = $self->name; + my $service = ( $Config{'services'}{"${name}_binary"} || "$install_dir/sbin/$name" ); + return $service; +} + +=head2 restart + +restart the service + +=cut + +sub restart { + my ($self,$quick) = @_; + $self->stop($quick); + return $self->start($quick); +} + +=head2 status + +returns the pid or list of pids for the servie(s) + +=cut + +sub status { + my ($self,$quick) = @_; + $self->removeStalePid; + my $pid = $self->pid; + return $pid ? $pid : "0"; +} + +=head2 pid + +Returns the pid of the service + +=cut + +sub pid { + my ($self) = @_; + return $self->pidFromFile; +} + +=head2 stop + +Stop the service waitinf for it to shutdown + +=cut + +sub stop { + my ($self,$quick) = @_; + my $pid = $self->pid; + my $name = $self->name; + my $logger = get_logger; + if ($pid) { + $logger->info("Sending TERM signal to $name with pid $pid"); + my $count = kill 'TERM',$pid; + unless ($count) { + $logger->logcroak("Can't a TERM signal to $name with pid $pid "); + return; + } + my $pid_file = $self->pidFile; + if ( $self->waitToShutdown($pid) && -e $pid_file) { + $logger->info("Removing $pid_file"); + unlink($pid_file); + } + return !-e $pid_file; + } + return; +} + +=head2 watch + +If the service is stopped start the service + +=cut + +sub watch { + my ($self) = @_; + $self->removeStalePid; + unless($self->pid) { + return $self->start(1); + } + return; +} + +=head2 generateConfig + +generates the configuration files for the service + +=cut + +sub generateConfig { 1 } + +=head2 launchService + +launch the service using the launcher and arguements passed + +=cut + +sub launchService { + my ($self,@launcher_args) = @_; + my $launcher = $self->launcher; + if ($launcher) { + my $name = $self->name; + my $logger = get_logger; + my $cmd_line = sprintf($launcher, map { /^(.*)$/;$1 } @launcher_args); + $logger->info("Starting $name with '$cmd_line'"); + if ($cmd_line =~ /^(.+)$/) { + $cmd_line = $1; + my $t0 = Time::HiRes::time(); + my $return_value = system($cmd_line); + my $elapsed = Time::HiRes::time() - $t0; + $logger->info(sprintf("Daemon %s took %.3f seconds to start.", $name, $elapsed)); + return $return_value == 0; + } + } + return; +} + +=head2 pidFile + +return the pid file of the service + +=cut + +sub pidFile { + my ($self) = @_; + my $name = $self->name; + return "$var_dir/run/$name.pid"; +} + +=head2 pidFromFile + +get the pid from the pid file + +=cut + +sub pidFromFile { + my ($self) = @_; + my $name = $self->name; + my $logger = Log::Log4perl::get_logger('pf::services'); + my $pid; + my $pid_file = $self->pidFile; + if (-e $pid_file) { + eval {chomp( $pid = read_file($pid_file) );}; + } + $pid = 0 unless $pid; + if($pid) { + $logger->info("pidof -x $name returned $pid"); + if($pid =~ /^\s*(\d*)\s*$/) { + $pid = $1; + } + } + return $pid; +} + +=head2 removeStalePid + +removes the stale PID file + +=cut + +sub removeStalePid { + my ($self) = @_; + my $logger = get_logger; + my $pid = $self->pidFromFile; + my $pid_file = $self->pidFile; + if($pid && $pid =~ /^(.*)$/) { + $pid = $1; + unless (kill( 0,$pid)) { + $pid = 0; + $logger->info("removing stale pid file $pid_file"); + unlink $pid_file; + } + } +} + +=head2 waitToShutdown + +Waits for the pid of the service to shutdown + +=cut + +sub waitToShutdown { + my ($self, $pid) = @_; + my $name = $self->name; + my $logger = Log::Log4perl::get_logger('pf::services'); + my $maxWait = 10; + my $curWait = 0; + my $ppt; + my $proc = 0; + while ( ( ( $curWait < $maxWait ) + && ( $self->status ne "0" ) ) && defined($proc) ) + { + $ppt = new Proc::ProcessTable; + $proc = first { defined $_ && $_->pid == $pid } @{ $ppt->table }; + $logger->info("Waiting for $name to stop "); + sleep(2); + $curWait++; + } + return !defined $proc; +} + +=head2 isManaged + +return true is the service is currently managed by packetfence + +=cut + +sub isManaged { 1 } + + +=head1 AUTHOR + +Inverse inc. + +Minor parts of this file may have been contributed. See CREDITS. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + diff --git a/lib/pf/services/manager/dhcpd.pm b/lib/pf/services/manager/dhcpd.pm new file mode 100644 index 000000000000..e3c4aff089b6 --- /dev/null +++ b/lib/pf/services/manager/dhcpd.pm @@ -0,0 +1,101 @@ +package pf::services::manager::dhcpd; +=head1 NAME + +pf::services::manager::dhcpd add documentation + +=cut + +=head1 DESCRIPTION + +pf::services::manager::dhcpd + +=cut + +use strict; +use warnings; +use Moo; +use pf::file_paths; +use pf::config; +use pf::log; +use pf::services::dhcpd qw(generate_dhcpd_conf); +use File::Touch; + +extends 'pf::services::manager'; +with 'pf::services::manager::roles::pf_conf_service_managed'; + +has '+name' => (default => sub { 'dhcpd' } ); + +has '+launcher' => (default => sub { "sudo %1\$s -lf $var_dir/dhcpd/dhcpd.leases -cf $generated_conf_dir/dhcpd.conf -pf $var_dir/run/dhcpd.pid " . join(" ", @listen_ints) } ); + + +sub generateConfig { + generate_dhcpd_conf(); +} + +sub preStartSetup { + my ($self,$quick) = @_; + $self->SUPER::preStartSetup($quick); + my $leases_file = "$var_dir/dhcpd/dhcpd.leases"; + touch ($leases_file) unless -f $leases_file; + manageStaticRoute(1); + return 1; +} + +sub stop { + my ($self,$quick) = @_; + $self->SUPER::stop($quick); + manageStaticRoute(); +} + +sub manageStaticRoute { + my $add_Route = @_; + my $logger = get_logger; + + foreach my $network ( keys %ConfigNetworks ) { + # shorter, more convenient local accessor + my %net = %{$ConfigNetworks{$network}}; + + + if ( defined($net{'next_hop'}) && ($net{'next_hop'} =~ /^(?:\d{1,3}\.){3}\d{1,3}$/) ) { + my $add_del = $add_Route ? 'add' : 'del'; + my $full_path = can_run('route') + or $logger->error("route is not installed! Can't add static routes to routed VLANs."); + + my $cmd = "sudo $full_path $add_del -net $network netmask " . $net{'netmask'} . " gw " . $net{'next_hop'}; + $cmd = untaint_chain($cmd); + my @out = pf_run($cmd); + } + } +} + +=head1 AUTHOR + +Inverse inc. + +Minor parts of this file may have been contributed. See CREDITS. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + diff --git a/lib/pf/services/manager/httpd.pm b/lib/pf/services/manager/httpd.pm new file mode 100644 index 000000000000..b540a51667ed --- /dev/null +++ b/lib/pf/services/manager/httpd.pm @@ -0,0 +1,64 @@ +package pf::services::manager::httpd; +=head1 NAME + +pf::services::manager::httpd add documentation + +=cut + +=head1 DESCRIPTION + +pf::services::manager::httpd + +=cut + +use strict; +use warnings; +use pf::config; +use Moo; +extends 'pf::services::manager'; + +has '+launcher' => ( builder => 1, lazy => 1 ); + +sub executable { + my ($self) = @_; + my $service = ( $Config{'services'}{"httpd_binary"} || "$install_dir/sbin/httpd" ); + return $service; +} + +sub _build_launcher { + my ($self) = @_; + my $name = $self->name; + return "%1\$s -f $conf_dir/httpd.conf.d/$name -D$OS" +} + +=head1 AUTHOR + +Inverse inc. + +Minor parts of this file may have been contributed. See CREDITS. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + diff --git a/lib/pf/services/manager/httpd_admin.pm b/lib/pf/services/manager/httpd_admin.pm new file mode 100644 index 000000000000..6e87f87d7079 --- /dev/null +++ b/lib/pf/services/manager/httpd_admin.pm @@ -0,0 +1,52 @@ +package pf::services::manager::httpd_admin; +=head1 NAME + +pf::services::manager::httpd_admin add documentation + +=cut + +=head1 DESCRIPTION + +pf::services::manager::httpd_admin + +=cut + +use strict; +use warnings; +use Moo; + +extends 'pf::services::manager::httpd'; + +has '+name' => (default => sub { 'httpd.admin' } ); + +=head1 AUTHOR + +Inverse inc. + +Minor parts of this file may have been contributed. See CREDITS. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + diff --git a/lib/pf/services/manager/httpd_portal.pm b/lib/pf/services/manager/httpd_portal.pm new file mode 100644 index 000000000000..73b65ebfbb59 --- /dev/null +++ b/lib/pf/services/manager/httpd_portal.pm @@ -0,0 +1,52 @@ +package pf::services::manager::httpd_portal; +=head1 NAME + +pf::services::manager::httpd_portal add documentation + +=cut + +=head1 DESCRIPTION + +pf::services::manager::httpd_portal + +=cut + +use strict; +use warnings; +use Moo; + +extends 'pf::services::manager::httpd'; + +has '+name' => (default => sub { 'httpd.portal' } ); + +=head1 AUTHOR + +Inverse inc. + +Minor parts of this file may have been contributed. See CREDITS. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + diff --git a/lib/pf/services/manager/httpd_webservices.pm b/lib/pf/services/manager/httpd_webservices.pm new file mode 100644 index 000000000000..bfecbd0a0856 --- /dev/null +++ b/lib/pf/services/manager/httpd_webservices.pm @@ -0,0 +1,52 @@ +package pf::services::manager::httpd_webservices; +=head1 NAME + +pf::services::manager::httpd_webservices add documentation + +=cut + +=head1 DESCRIPTION + +pf::services::manager::httpd_webservices + +=cut + +use strict; +use warnings; +use Moo; + +extends 'pf::services::manager::httpd'; + +has '+name' => (default => sub { 'httpd.webservices' } ); + +=head1 AUTHOR + +Inverse inc. + +Minor parts of this file may have been contributed. See CREDITS. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + diff --git a/lib/pf/services/manager/memcached.pm b/lib/pf/services/manager/memcached.pm new file mode 100644 index 000000000000..ef911f3c947a --- /dev/null +++ b/lib/pf/services/manager/memcached.pm @@ -0,0 +1,56 @@ +package pf::services::manager::memcached; +=head1 NAME + +pf::services::manager::memcached add documentation + +=cut + +=head1 DESCRIPTION + +pf::services::manager::memcached + +=cut + +use strict; +use warnings; +use Moo; +use pf::file_paths; + +extends 'pf::services::manager'; +with 'pf::services::manager::roles::pf_conf_service_managed'; + +has '+name' => (default => sub { 'memcached' } ); + +has '+launcher' => (default => sub { "%1\$s -d -p 11211 -u pf -m 64 -c 1024 -P $install_dir/var/run/memcached.pid"}); + +=head1 AUTHOR + +Inverse inc. + +Minor parts of this file may have been contributed. See CREDITS. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + diff --git a/lib/pf/services/manager/pfdetect.pm b/lib/pf/services/manager/pfdetect.pm new file mode 100644 index 000000000000..12f1d1573f0a --- /dev/null +++ b/lib/pf/services/manager/pfdetect.pm @@ -0,0 +1,59 @@ +package pf::services::manager::pfdetect; +=head1 NAME + +pf::services::manager::pfdetect add documentation + +=cut + +=head1 DESCRIPTION + +pf::services::manager::pfdetect + +=cut + +use strict; +use warnings; +use Moo; +use pf::file_paths; +use pf::config; +use pf::util; +extends 'pf::services::manager'; + +has '+name' => (default => sub { 'pfdetect' }); + +has '+launcher' => (default => sub {"%1\$s -d -p $install_dir/var/alert &"}); + +sub isManaged { return isenabled( $Config{'trapping'}{'detection'} ); } + + +=head1 AUTHOR + +Inverse inc. + +Minor parts of this file may have been contributed. See CREDITS. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + diff --git a/lib/pf/services/manager/pfdhcplistener.pm b/lib/pf/services/manager/pfdhcplistener.pm new file mode 100644 index 000000000000..d647c7b84a5a --- /dev/null +++ b/lib/pf/services/manager/pfdhcplistener.pm @@ -0,0 +1,74 @@ +package pf::services::manager::pfdhcplistener; +=head1 NAME + +pf::services::manager::pfdhcplistener add documentation + +=cut + +=head1 DESCRIPTION + +pf::services::manager::pfdhcplistener + +=cut + +use strict; +use warnings; +use Moo; +use pf::config; + +extends 'pf::services::manager::submanager'; + +has pfdhcplistenerManagers => (is => 'rw', builder => 1 ); + + +has '+name' => (default => sub { 'pfdhcplistener'} ); + +sub _build_pfdhcplistenerManagers { + my ($self) = @_; + my @managers = map { + pf::services::manager->new ({ + executable => $self->executable, + name => "pfdhcplistener_$_", + launcher => "sudo %1\$s -i '$_' -d &" + }) + } @listen_ints, @dhcplistener_ints; + return \@managers; +} + + +sub managers { + my ($self) = @_; + return @{$self->pfdhcplistenerManagers}; +} + +=head1 AUTHOR + +Inverse inc. + +Minor parts of this file may have been contributed. See CREDITS. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + diff --git a/lib/pf/services/manager/pfdns.pm b/lib/pf/services/manager/pfdns.pm new file mode 100644 index 000000000000..87a8501bbe51 --- /dev/null +++ b/lib/pf/services/manager/pfdns.pm @@ -0,0 +1,54 @@ +package pf::services::manager::pfdns; +=head1 NAME + +pf::services::manager::pfdns add documentation + +=cut + +=head1 DESCRIPTION + +pf::services::manager::pfdns + +=cut + +use strict; +use warnings; +use Moo; +extends 'pf::services::manager'; +with 'pf::services::manager::roles::pf_conf_service_managed'; + +has '+name' => (default => sub { 'pfdns' } ); + +has '+launcher' => (default => sub { '%1$s -d &' } ); + +=head1 AUTHOR + +Inverse inc. + +Minor parts of this file may have been contributed. See CREDITS. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + diff --git a/lib/pf/services/manager/pfmon.pm b/lib/pf/services/manager/pfmon.pm new file mode 100644 index 000000000000..83fbeba00264 --- /dev/null +++ b/lib/pf/services/manager/pfmon.pm @@ -0,0 +1,54 @@ +package pf::services::manager::pfmon; +=head1 NAME + +pf::services::manager::pfmon add documentation + +=cut + +=head1 DESCRIPTION + +pf::services::manager::pfmon + +=cut + +use strict; +use warnings; +use Moo; + +extends 'pf::services::manager'; + +has '+name' => ( default => sub { 'pfmon' } ); + +has '+launcher' => (default => sub { '%1$s -d' } ); + +=head1 AUTHOR + +Inverse inc. + +Minor parts of this file may have been contributed. See CREDITS. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + diff --git a/lib/pf/services/manager/pfsetvlan.pm b/lib/pf/services/manager/pfsetvlan.pm new file mode 100644 index 000000000000..e8c7256c53a6 --- /dev/null +++ b/lib/pf/services/manager/pfsetvlan.pm @@ -0,0 +1,53 @@ +package pf::services::manager::pfsetvlan; +=head1 NAME + +pf::services::manager::pfsetvlan add documentation + +=cut + +=head1 DESCRIPTION + +pf::services::manager::pfsetvlan + +=cut + +use strict; +use warnings; +use Moo; +extends 'pf::services::manager'; + +has '+name' => (default => sub { 'pfsetvlan' } ); + +has '+launcher' => (default => sub { '%1$s -d ' } ); + +=head1 AUTHOR + +Inverse inc. + +Minor parts of this file may have been contributed. See CREDITS. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + diff --git a/lib/pf/services/manager/radiusd.pm b/lib/pf/services/manager/radiusd.pm new file mode 100644 index 000000000000..79bab2ead2fc --- /dev/null +++ b/lib/pf/services/manager/radiusd.pm @@ -0,0 +1,69 @@ +package pf::services::manager::radiusd; +=head1 NAME + +pf::services::manager::radiusd add documentation + +=cut + +=head1 DESCRIPTION + +pf::services::manager::radiusd + +=cut + +use strict; +use warnings; +use pf::services::radiusd qw(generate_radiusd_conf); +use pf::file_paths; +use Moo; + +extends 'pf::services::manager'; +with 'pf::services::manager::roles::pf_conf_service_managed'; + +has '+name' => ( default => sub { 'radiusd' } ); + +has '+launcher' => ( default => sub { "sudo %1\$s -d $install_dir/raddb/"} ); + +sub preStartSetup { + my ($self,$quick) = @_; + require pf::freeradius; + pf::freeradius::freeradius_populate_nas_config(); + $self->SUPER::preStartSetup($quick); +} + +sub generateConfig { + my ($self,$quick) = @_; + generate_radiusd_conf(); +} + +=head1 AUTHOR + +Inverse inc. + +Minor parts of this file may have been contributed. See CREDITS. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + diff --git a/lib/pf/services/manager/roles/pf_conf_service_managed.pm b/lib/pf/services/manager/roles/pf_conf_service_managed.pm new file mode 100644 index 000000000000..5273ab4b1804 --- /dev/null +++ b/lib/pf/services/manager/roles/pf_conf_service_managed.pm @@ -0,0 +1,55 @@ +package pf::services::manager::roles::pf_conf_service_managed; +=head1 NAME + +pf::services::manager::roles::pf_conf_service_managed add documentation + +=cut + +=head1 DESCRIPTION + +pf::services::manager::roles::pf_conf_service_managed + +=cut + +use strict; +use warnings; +use Moo::Role; +use pf::config; +use pf::util; + +sub isManaged { + my ($self) = @_; + isenabled($Config{'services'}{$self->name}) +} + +=head1 AUTHOR + +Inverse inc. + +Minor parts of this file may have been contributed. See CREDITS. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + diff --git a/lib/pf/services/manager/roles/pf_conf_trapping_engine.pm b/lib/pf/services/manager/roles/pf_conf_trapping_engine.pm new file mode 100644 index 000000000000..f9b41aa4cf35 --- /dev/null +++ b/lib/pf/services/manager/roles/pf_conf_trapping_engine.pm @@ -0,0 +1,69 @@ +package pf::services::manager::roles::pf_conf_trapping_engine; +=head1 NAME + +pf::services::manager::roles::pf_conf_trapping_engine add documentation + +=cut + +=head1 DESCRIPTION + +pf::services::manager::roles::pf_conf_trapping_engine + +=cut + +use strict; +use warnings; +use Moo::Role; +use pf::config; +use pf::util; + +=head2 isManaged + +Verify if the trapping engine + +=cut + +sub isManaged { + my ($self) = @_; + return isenabled($Config{'trapping'}{'detection'}) && $Config{'trapping'}{'detection_engine'} eq $self->name; +} + +=head2 dependsOnServices + +services that the trapping engine depends on + +=cut + +has dependsOnServices => (default => sub { [qw(memcached httpd.admin pfdetect)] } ); + +=head1 AUTHOR + +Inverse inc. + +Minor parts of this file may have been contributed. See CREDITS. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + diff --git a/lib/pf/services/manager/snmptrapd.pm b/lib/pf/services/manager/snmptrapd.pm new file mode 100644 index 000000000000..1388b5d0e656 --- /dev/null +++ b/lib/pf/services/manager/snmptrapd.pm @@ -0,0 +1,59 @@ +package pf::services::manager::snmptrapd; +=head1 NAME + +pf::services::manager::snmptrapd add documentation + +=cut + +=head1 DESCRIPTION + +pf::services::manager::snmptrapd + +=cut + +use strict; +use warnings; +use Moo; +use pf::file_paths; +use pf::services::snmptrapd qw(generate_snmptrapd_conf); +extends 'pf::services::manager'; + +has '+name' => (default => sub { 'snmptrapd' } ); + +has '+launcher' => (default => sub { "%1\$s -n -c $generated_conf_dir/snmptrapd.conf -C -A -Lf $install_dir/logs/snmptrapd.log -p $install_dir/var/run/snmptrapd.pid -On" } ); + +sub generateConfig { + generate_snmptrapd_conf(); +} + +=head1 AUTHOR + +Inverse inc. + +Minor parts of this file may have been contributed. See CREDITS. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + diff --git a/lib/pf/services/manager/snort.pm b/lib/pf/services/manager/snort.pm new file mode 100644 index 000000000000..1c4096e03d24 --- /dev/null +++ b/lib/pf/services/manager/snort.pm @@ -0,0 +1,62 @@ +package pf::services::manager::snort; +=head1 NAME + +pf::services::manager::snort add documentation + +=cut + +=head1 DESCRIPTION + +pf::services::manager::snort + +=cut + +use strict; +use warnings; +use Moo; +extends 'pf::services::manager'; +with 'pf::services::manager::roles::pf_conf_service_managed'; +use pf::file_paths; +use pf::config; + +has '+name' => ( default => sub { 'snort' } ); + +has '+launcher' => ( + default => sub { + "%1\$s -u pf -c $generated_conf_dir/snort.conf -i $monitor_int " . + "-N -D -l $install_dir/var --pid-path $install_dir/var/run" + }, + lazy => 1 +); + +=head1 AUTHOR + +Inverse inc. + +Minor parts of this file may have been contributed. See CREDITS. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + diff --git a/lib/pf/services/manager/submanager.pm b/lib/pf/services/manager/submanager.pm new file mode 100644 index 000000000000..e75fd0eb24b4 --- /dev/null +++ b/lib/pf/services/manager/submanager.pm @@ -0,0 +1,118 @@ +package pf::services::manager::submanager; +=head1 NAME + +pf::services::manager::submanager add documentation + +=cut + +=head1 DESCRIPTION + +pf::services::manager::submanager + +a subclass for handling a service the has multple sub services + +=cut + +use strict; +use warnings; +use Moo; +use List::MoreUtils qw(true any); + +extends 'pf::services::manager'; + +=head2 managers + +The list of sub managers + +=cut + +sub managers { + my ($self) = @_; + return (); +} + +=head2 start + +start all the sub managers + +=cut + +sub start { + my ($self,$quick) = @_; + my $count; + my $pass = true {$count++; $_->start($quick) } $self->managers; + return $pass == $count; +} + +=head2 stop + +stop all the sub managers + +=cut + +sub stop { + my ($self,$quick) = @_; + my $count; + my $pass = true {$count++; $_->stop($quick) } $self->managers; + return $pass == $count; +} + +=head2 watch + +watch all the sub managers + +=cut + +sub watch { + my ($self,$quick) = @_; + my $count; + my $pass = true {$count++; $_->watch($quick) } $self->managers; + return $pass == $count; +} + +=head2 status + +returns all the pids of the submanagers + +=cut + +sub status { + my ($self,$quick) = @_; + my @results = map {$_->status } $self->managers; + if (@results == 0 || (!$quick && any { !defined($_) || $_ eq "0" } @results )) { + @results = ("0"); + } + return join(" ",@results); +} + +=head1 AUTHOR + +Inverse inc. + +Minor parts of this file may have been contributed. See CREDITS. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + diff --git a/lib/pf/services/manager/suricata.pm b/lib/pf/services/manager/suricata.pm new file mode 100644 index 000000000000..082c07ef338d --- /dev/null +++ b/lib/pf/services/manager/suricata.pm @@ -0,0 +1,66 @@ +package pf::services::manager::suricata; +=head1 NAME + +pf::services::manager::suricata add documentation + +=cut + +=head1 DESCRIPTION + +pf::services::manager::suricata + +=cut + +use strict; +use warnings; +use pf::file_paths; +use pf::config; +use Moo; +use pf::services::suricata qw(generate_suricata_conf); +extends 'pf::services::manager'; +with 'pf::services::manager::roles::pf_conf_service_managed'; + +has '+name' => ( default => sub { 'suricata' } ); + +has '+launcher' => ( + default => sub { + "%1\$s -D -c $install_dir/var/conf/suricata.yaml -i $monitor_int " . + "-l $install_dir/var --pidfile $install_dir/var/run/suricata.pid" + }, +); + +sub generateConfig { + generate_suricata_conf(); +} + +=head1 AUTHOR + +Inverse inc. + +Minor parts of this file may have been contributed. See CREDITS. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + From e27c1a02d8d3cf5f71d568ece5a72e910f098dd3 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Tue, 24 Sep 2013 19:17:59 -0400 Subject: [PATCH 278/369] Use the new pf::services::manager framework for the pfcmd service command --- bin/pfcmd.pl | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) diff --git a/bin/pfcmd.pl b/bin/pfcmd.pl index 21caa5de0c89..053c9447b9d7 100755 --- a/bin/pfcmd.pl +++ b/bin/pfcmd.pl @@ -78,6 +78,7 @@ =head1 SYNOPSIS use pf::pfcmd; use pf::util; use HTTP::Status qw(is_success); +use List::MoreUtils qw(all true); # Perl taint mode setup (see: perlsec) delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; @@ -96,6 +97,13 @@ =head1 SYNOPSIS Readonly my $delimiter => '|'; use vars qw/%cmd $grammar/; my $command; +our %ACTION_MAP = ( + status => \&statusOfService, + start => \&startService, + stop => \&stopService, + watch => \&watchService, + restart => \&restartService, +); my $count = $ENV{PER_PAGE}; my $offset = $ENV{PAGE_NUM}; @@ -1145,7 +1153,24 @@ sub traplog { # stop/start pf services # return service status # + sub service { + my $service = $cmd{command}[1]; + my $action = $cmd{command}[2]; + require pf::services; + import pf::services; + my $actionHandler; + $action =~ /^(.*)$/; + $action = $1; + if(exists $ACTION_MAP{$action} && defined ($actionHandler = $ACTION_MAP{$action})) { + $service =~ /^(.*)$/; + $service = $1; + return $actionHandler->($service); + } + return $FALSE; +} + +sub service_ { my $service = $cmd{command}[1]; my $command = $cmd{command}[2]; require pf::services; @@ -1335,6 +1360,182 @@ sub service { return 0; } +sub startService { + my ($service) = @_; + my @managers = getStartServiceManagers($service); + print "service|command\n"; + my $count = 0; + if(isIptableManaged($service)) { + my $technique; + if(all { $_->status eq '0' } @managers) { + $technique = getIptablesTechnique(); + $technique->iptables_save( $install_dir . '/var/iptables.bak' ); + } + $technique ||= getIptablesTechnique(); + $technique->iptables_generate(); + } + foreach my $manager (@managers) { + my $command; + if($manager->status ne '0') { + $command = 'already started'; + } else { + $manager->start; + $command = 'start'; + } + print join('|',$manager->name,$command),"\n"; + } + return 0; +} + +sub saveIptables { + $logger->info("saving current iptables to var/iptables.bak"); +} + +sub getIptablesTechnique { + require pf::inline::custom; + my $iptables = pf::inline::custom->new(); + return $iptables->{_technique}; +} + +sub getStartServiceManagers { + my ($service) = @_; + my @services; + if($service eq 'pf') { + @services = @pf::services::ALL_SERVICES; + } else { + @services = ($service); + } + return grep { $_->isManaged } _getStartServiceManagers(@services); +} + +sub _getStartServiceManagers { + my %seen; + my @serviceManagers = + grep { (!exists $seen{$_->name}) && ($seen{$_->name} = 1) } + map { + my $m = $_; + my @managers = map { getServiceManager($_) } @{$m->dependsOnServices}; + push @managers,$m; + @managers + } + grep { defined $_ } + map { getServiceManager($_) } @_; + return @serviceManagers; +} + +sub stopService { + my ($service) = @_; + my @managers = getStopServiceManagers($service); + print "service|command\n"; + foreach my $manager (@managers) { + my $command; + if($manager->status eq '0') { + $command = 'already stopped'; + } else { + $manager->stop; + $command = 'stop'; + } + print join('|',$manager->name,$command),"\n"; + } + if(isIptableManaged($service)) { + my $count = true { $_->status eq '0' } @managers; + if( $count ) { + getIptablesTechnique->iptables_restore( $install_dir . '/var/iptables.bak' ); + } else { + $logger->error( + "Even though 'service pf stop' was called, there are still $count services running. " + . "Can't restore iptables from var/iptables.bak" + ); + } + } + return 0; +} + +sub isIptableManaged { + return $_[0] eq 'pf' && isenabled($Config{services}{iptables}) +} + +sub getStopServiceManagers { + my ($service) = @_; + my @services; + if($service eq 'pf') { + @services = grep { $_ ne 'memcached' } @pf::services::ALL_SERVICES; + push @services,'memcached'; + } else { + @services = ($service); + } + return _getStopServiceManagers(@services); +} + +sub _getStopServiceManagers { + my %seen; + my @serviceManagers = + grep { defined ($_) && (!exists $seen{$_->name}) && ($seen{$_->name} = 1) } + map { getServiceManager($_) } @_; + return @serviceManagers; +} + + +sub restartService { + my ($service) = @_; + stopService($service); + startService($service); +} + +sub watchService { + my ($service) = @_; + my @stoppedServiceManagers = + grep { $_->isManaged && $_->status eq '0' } + getStartServiceManagers($service); + if(@stoppedServiceManagers) { + my @stoppedServices = map { $_->name } @stoppedServiceManagers; + $logger->info("watch found incorrectly stopped services: " . join(", ", @stoppedServices)); + print "The following processes are not running:\n" . " - " + . join( "\n - ", @stoppedServices ) . "\n"; + if ( isenabled( $Config{'servicewatch'}{'email'} ) ) { + my %message; + $message{'subject'} = "PF WATCHER ALERT"; + $message{'message'} + = "The following processes are not running:\n" . " - " + . join( "\n - ", @stoppedServices ) . "\n"; + pfmailer(%message); + } + if ( isenabled( $Config{'servicewatch'}{'restart'} ) ) { + print "service|command\n"; + foreach my $manager (@stoppedServiceManagers) { + $manager->watch; + print join('|',$manager->name,"watch"),"\n"; + } + return 0; + } + } + return 1; +} + +sub statusOfService { + my ($service) = @_; + my @managers = getStopServiceManagers($service); + print "service|shouldBeStarted|pid\n"; + my $notStarted = 0; + foreach my $manager (@managers) { + my $isManaged = $manager->isManaged; + my $status = $manager->status; + print join('|',$manager->name,$isManaged,$status),"\n"; + $notStarted++ if $status eq '0' && $isManaged; + } + return ( $notStarted ? 3 : 0); +} + +sub getServiceManager { + my ($service) = @_; + my $module = "pf::services::manager::${service}"; + $module =~ /^(.*)$/; + $module = $1; + $module =~ s/\./_/; + eval "use $module;"; + return $module->new; +} + sub class { my ( $function, $id ); require pf::class; From 01e0c4ae46b19d20c4f0ad22319f6fba21208bf4 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 25 Sep 2013 10:15:43 -0400 Subject: [PATCH 279/369] Remove Minor parts from the COPYRIGHT section --- lib/pf/services/manager.pm | 1 - lib/pf/services/manager/httpd.pm | 1 - lib/pf/services/manager/httpd_admin.pm | 1 - lib/pf/services/manager/httpd_portal.pm | 1 - lib/pf/services/manager/httpd_webservices.pm | 1 - lib/pf/services/manager/memcached.pm | 1 - lib/pf/services/manager/pfdetect.pm | 1 - lib/pf/services/manager/pfdns.pm | 1 - lib/pf/services/manager/pfmon.pm | 1 - lib/pf/services/manager/pfsetvlan.pm | 1 - lib/pf/services/manager/radiusd.pm | 1 - lib/pf/services/manager/roles/pf_conf_service_managed.pm | 1 - lib/pf/services/manager/snmptrapd.pm | 1 - lib/pf/services/manager/snort.pm | 1 - lib/pf/services/manager/submanager.pm | 1 - lib/pf/services/manager/suricata.pm | 1 - 16 files changed, 16 deletions(-) diff --git a/lib/pf/services/manager.pm b/lib/pf/services/manager.pm index 92944f2b5796..211b9b887a03 100644 --- a/lib/pf/services/manager.pm +++ b/lib/pf/services/manager.pm @@ -366,7 +366,6 @@ sub isManaged { 1 } Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/services/manager/httpd.pm b/lib/pf/services/manager/httpd.pm index b540a51667ed..baf3fa66f92f 100644 --- a/lib/pf/services/manager/httpd.pm +++ b/lib/pf/services/manager/httpd.pm @@ -35,7 +35,6 @@ sub _build_launcher { Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/services/manager/httpd_admin.pm b/lib/pf/services/manager/httpd_admin.pm index 6e87f87d7079..037049aa6366 100644 --- a/lib/pf/services/manager/httpd_admin.pm +++ b/lib/pf/services/manager/httpd_admin.pm @@ -23,7 +23,6 @@ has '+name' => (default => sub { 'httpd.admin' } ); Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/services/manager/httpd_portal.pm b/lib/pf/services/manager/httpd_portal.pm index 73b65ebfbb59..8b5d8a222414 100644 --- a/lib/pf/services/manager/httpd_portal.pm +++ b/lib/pf/services/manager/httpd_portal.pm @@ -23,7 +23,6 @@ has '+name' => (default => sub { 'httpd.portal' } ); Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/services/manager/httpd_webservices.pm b/lib/pf/services/manager/httpd_webservices.pm index bfecbd0a0856..c644e970daa4 100644 --- a/lib/pf/services/manager/httpd_webservices.pm +++ b/lib/pf/services/manager/httpd_webservices.pm @@ -23,7 +23,6 @@ has '+name' => (default => sub { 'httpd.webservices' } ); Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/services/manager/memcached.pm b/lib/pf/services/manager/memcached.pm index ef911f3c947a..75b4225b9938 100644 --- a/lib/pf/services/manager/memcached.pm +++ b/lib/pf/services/manager/memcached.pm @@ -27,7 +27,6 @@ has '+launcher' => (default => sub { "%1\$s -d -p 11211 -u pf -m 64 -c 1024 -P $ Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/services/manager/pfdetect.pm b/lib/pf/services/manager/pfdetect.pm index 12f1d1573f0a..679ce61b9b7d 100644 --- a/lib/pf/services/manager/pfdetect.pm +++ b/lib/pf/services/manager/pfdetect.pm @@ -30,7 +30,6 @@ sub isManaged { return isenabled( $Config{'trapping'}{'detection'} ); } Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/services/manager/pfdns.pm b/lib/pf/services/manager/pfdns.pm index 87a8501bbe51..6c23d29e965d 100644 --- a/lib/pf/services/manager/pfdns.pm +++ b/lib/pf/services/manager/pfdns.pm @@ -25,7 +25,6 @@ has '+launcher' => (default => sub { '%1$s -d &' } ); Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/services/manager/pfmon.pm b/lib/pf/services/manager/pfmon.pm index 83fbeba00264..d1cd31518885 100644 --- a/lib/pf/services/manager/pfmon.pm +++ b/lib/pf/services/manager/pfmon.pm @@ -25,7 +25,6 @@ has '+launcher' => (default => sub { '%1$s -d' } ); Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/services/manager/pfsetvlan.pm b/lib/pf/services/manager/pfsetvlan.pm index e8c7256c53a6..51a5226aaf41 100644 --- a/lib/pf/services/manager/pfsetvlan.pm +++ b/lib/pf/services/manager/pfsetvlan.pm @@ -24,7 +24,6 @@ has '+launcher' => (default => sub { '%1$s -d ' } ); Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/services/manager/radiusd.pm b/lib/pf/services/manager/radiusd.pm index 79bab2ead2fc..69b1c5115882 100644 --- a/lib/pf/services/manager/radiusd.pm +++ b/lib/pf/services/manager/radiusd.pm @@ -40,7 +40,6 @@ sub generateConfig { Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/services/manager/roles/pf_conf_service_managed.pm b/lib/pf/services/manager/roles/pf_conf_service_managed.pm index 5273ab4b1804..b7c0ee817b36 100644 --- a/lib/pf/services/manager/roles/pf_conf_service_managed.pm +++ b/lib/pf/services/manager/roles/pf_conf_service_managed.pm @@ -26,7 +26,6 @@ sub isManaged { Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/services/manager/snmptrapd.pm b/lib/pf/services/manager/snmptrapd.pm index 1388b5d0e656..7a4c6b854d84 100644 --- a/lib/pf/services/manager/snmptrapd.pm +++ b/lib/pf/services/manager/snmptrapd.pm @@ -30,7 +30,6 @@ sub generateConfig { Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/services/manager/snort.pm b/lib/pf/services/manager/snort.pm index 1c4096e03d24..972d3b757254 100644 --- a/lib/pf/services/manager/snort.pm +++ b/lib/pf/services/manager/snort.pm @@ -33,7 +33,6 @@ has '+launcher' => ( Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/services/manager/submanager.pm b/lib/pf/services/manager/submanager.pm index e75fd0eb24b4..512292edb012 100644 --- a/lib/pf/services/manager/submanager.pm +++ b/lib/pf/services/manager/submanager.pm @@ -89,7 +89,6 @@ sub status { Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT diff --git a/lib/pf/services/manager/suricata.pm b/lib/pf/services/manager/suricata.pm index 082c07ef338d..02e28638ac14 100644 --- a/lib/pf/services/manager/suricata.pm +++ b/lib/pf/services/manager/suricata.pm @@ -37,7 +37,6 @@ sub generateConfig { Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. =head1 COPYRIGHT From 0d744e5985e24df0fc2956d23a8f04b63a8fbd02 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 25 Sep 2013 11:15:10 -0400 Subject: [PATCH 280/369] Added missed isManaged --- lib/pf/services/manager/pfdhcplistener.pm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/pf/services/manager/pfdhcplistener.pm b/lib/pf/services/manager/pfdhcplistener.pm index d647c7b84a5a..062ad61eee41 100644 --- a/lib/pf/services/manager/pfdhcplistener.pm +++ b/lib/pf/services/manager/pfdhcplistener.pm @@ -20,7 +20,6 @@ extends 'pf::services::manager::submanager'; has pfdhcplistenerManagers => (is => 'rw', builder => 1 ); - has '+name' => (default => sub { 'pfdhcplistener'} ); sub _build_pfdhcplistenerManagers { @@ -41,12 +40,14 @@ sub managers { return @{$self->pfdhcplistenerManagers}; } +sub isManaged { + isenabled($Config{'network'}{'dhcpdetector'}) +} + =head1 AUTHOR Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. - =head1 COPYRIGHT Copyright (C) 2005-2013 Inverse inc. From e0252f8b10677db6c994c387b4fdff6021f2e9f9 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 25 Sep 2013 11:17:06 -0400 Subject: [PATCH 281/369] Fixed issue with t/pf.t --- lib/pf/services/manager/roles/pf_conf_trapping_engine.pm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/pf/services/manager/roles/pf_conf_trapping_engine.pm b/lib/pf/services/manager/roles/pf_conf_trapping_engine.pm index f9b41aa4cf35..547f4b768cf3 100644 --- a/lib/pf/services/manager/roles/pf_conf_trapping_engine.pm +++ b/lib/pf/services/manager/roles/pf_conf_trapping_engine.pm @@ -34,14 +34,12 @@ services that the trapping engine depends on =cut -has dependsOnServices => (default => sub { [qw(memcached httpd.admin pfdetect)] } ); +has '+dependsOnServices' => ( is => 'rw', default => sub { [qw(memcached httpd.admin pfdetect)] } ); =head1 AUTHOR Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. - =head1 COPYRIGHT Copyright (C) 2005-2013 Inverse inc. From 34503dfc1ff644753d0a7d8467c417975e00584d Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 25 Sep 2013 11:34:55 -0400 Subject: [PATCH 282/369] Added vlan/inline enforcement check for is managed --- lib/pf/services/manager/dhcpd.pm | 4 +- lib/pf/services/manager/pfdns.pm | 1 + .../is_managed_vlan_inline_enforcement.pm | 53 +++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 lib/pf/services/manager/roles/is_managed_vlan_inline_enforcement.pm diff --git a/lib/pf/services/manager/dhcpd.pm b/lib/pf/services/manager/dhcpd.pm index e3c4aff089b6..bbc032b62725 100644 --- a/lib/pf/services/manager/dhcpd.pm +++ b/lib/pf/services/manager/dhcpd.pm @@ -19,9 +19,11 @@ use pf::config; use pf::log; use pf::services::dhcpd qw(generate_dhcpd_conf); use File::Touch; +use IPC::Cmd qw[can_run run]; extends 'pf::services::manager'; with 'pf::services::manager::roles::pf_conf_service_managed'; +with 'pf::services::manager::roles::is_managed_vlan_inline_enforcement'; has '+name' => (default => sub { 'dhcpd' } ); @@ -72,7 +74,7 @@ sub manageStaticRoute { Inverse inc. -Minor parts of this file may have been contributed. See CREDITS. + =head1 COPYRIGHT diff --git a/lib/pf/services/manager/pfdns.pm b/lib/pf/services/manager/pfdns.pm index 6c23d29e965d..30bf11e928d0 100644 --- a/lib/pf/services/manager/pfdns.pm +++ b/lib/pf/services/manager/pfdns.pm @@ -16,6 +16,7 @@ use warnings; use Moo; extends 'pf::services::manager'; with 'pf::services::manager::roles::pf_conf_service_managed'; +with 'pf::services::manager::roles::is_managed_vlan_inline_enforcement'; has '+name' => (default => sub { 'pfdns' } ); diff --git a/lib/pf/services/manager/roles/is_managed_vlan_inline_enforcement.pm b/lib/pf/services/manager/roles/is_managed_vlan_inline_enforcement.pm new file mode 100644 index 000000000000..968d09ae213b --- /dev/null +++ b/lib/pf/services/manager/roles/is_managed_vlan_inline_enforcement.pm @@ -0,0 +1,53 @@ +package pf::services::manager::roles::is_managed_vlan_inline_enforcement; +=head1 NAME + +pf::services::manager::roles::is_managed_vlan_inline_enforcement add documentation + +=cut + +=head1 DESCRIPTION + +pf::services::manager::roles::is_managed_vlan_inline_enforcement + +=cut + +use strict; +use warnings; +use pf::config; + +use Moo::Role; + +around isManaged => sub { + my $orig = shift; + return (is_inline_enforcement_enabled() || is_vlan_enforcement_enabled()) && $orig->(@_); +}; + +=head1 AUTHOR + +Inverse inc. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + From c75b6c9d7119bc99b5c5f6f8b3331bed9f9d952d Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 25 Sep 2013 12:22:38 -0400 Subject: [PATCH 283/369] Added missing module --- lib/pf/services/manager/pfdhcplistener.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pf/services/manager/pfdhcplistener.pm b/lib/pf/services/manager/pfdhcplistener.pm index 062ad61eee41..230f9d3b5564 100644 --- a/lib/pf/services/manager/pfdhcplistener.pm +++ b/lib/pf/services/manager/pfdhcplistener.pm @@ -15,6 +15,7 @@ use strict; use warnings; use Moo; use pf::config; +use pf::util; extends 'pf::services::manager::submanager'; From 15c6714b2e1096c4d00b4f5e3a353891fe1bcd53 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 25 Sep 2013 13:05:39 -0400 Subject: [PATCH 284/369] Removed all old code from lib/pf/services.pm Refactored service_list & service_ctl in terms of pf::services::manager moved function getServiceManager from bin/pfcmd.pl to pf::services::get_service_manager Removed all code from bin/pfcmd.pl Refactor getServiceManager to pf::services::get_service_manager added checkup before starting services --- bin/pfcmd.pl | 227 ++--------------------- lib/pf/services.pm | 439 +++++++-------------------------------------- 2 files changed, 79 insertions(+), 587 deletions(-) diff --git a/bin/pfcmd.pl b/bin/pfcmd.pl index 053c9447b9d7..1961d799cd34 100755 --- a/bin/pfcmd.pl +++ b/bin/pfcmd.pl @@ -1170,202 +1170,13 @@ sub service { return $FALSE; } -sub service_ { - my $service = $cmd{command}[1]; - my $command = $cmd{command}[2]; - require pf::services; - import pf::services; - - $logger->info("Executing pfcmd service $service $command"); - - if ( lc($command) eq 'status' ) { - my (@services, %diff); - if ( $service eq 'pf' ) { - @services = @pf::services::ALL_SERVICES; - } else { - push( @services, $service ); - } - my @incorrectly_stopped_services = (); - my @services_which_should_be_started = pf::services::service_list(@services); - print "service|shouldBeStarted|pid\n"; - foreach my $tmp (@services) { - my $should_be_started = ( - ( grep( { $_ eq $tmp } @services_which_should_be_started ) - > 0 - ) ? 1 : 0 - ); - my $pid = pf::services::service_ctl( $tmp, 'status' ); - if ( ($should_be_started) && ( !$pid ) ) { - push @incorrectly_stopped_services, $tmp; - } - print "$tmp|$should_be_started|$pid\n"; - } - return ( ( scalar(@incorrectly_stopped_services) > 0 ) ? 3 : 0 ); - } - - if ( lc($command) eq 'watch' ) { - my (@services, %diff); - if ( $service eq "pf" ) { - @services = @pf::services::ALL_SERVICES; - } else { - push( @services, $service ); - } - my @services_which_should_be_started = pf::services::service_list(@services); - my @incorrectly_stopped_services = (); - foreach my $tmp (@services) { - my $should_be_started = (grep( { $_ eq $tmp } @services_which_should_be_started ) > 0); - my $pid = pf::services::service_ctl( $tmp, 'status' ); - if ( ($should_be_started) && ( !$pid ) ) { - push @incorrectly_stopped_services, $tmp; - } - } - if (@incorrectly_stopped_services) { - $logger->info("watch found incorrectly stopped services: " . join(", ", @incorrectly_stopped_services)); - print "The following processes are not running:\n" . " - " - . join( "\n - ", @incorrectly_stopped_services ) . "\n"; - if ( isenabled( $Config{'servicewatch'}{'email'} ) ) { - my %message; - $message{'subject'} = "PF WATCHER ALERT"; - $message{'message'} - = "The following processes are not running:\n" . " - " - . join( "\n - ", @incorrectly_stopped_services ) . "\n"; - pfmailer(%message); - } - if ( isenabled( $Config{'servicewatch'}{'restart'} ) ) { - $command = 'restart'; - } else { - return 1; - } - } else { - return 1; - } - } - - if ( lc($command) eq 'restart' ) { - if ( lc($service) eq 'pf' ) { - $logger->info( - "packetfence restart ... executing stop followed by start"); - local $cmd{command}[2] = "stop"; - service(); - local $cmd{command}[2] = "start"; - service(); - return 1; - } else { - if ( !pf::services::service_ctl( $service, "status" ) ) { - $command = "restart"; - } - } - } - - my (@services, %diff); - if ( $service ne 'pf' ) { - # make sure that snort is not started without pfdetect - if ($service eq 'snort') { - if ( !pf::services::service_ctl( 'pfdetect', 'status' ) ) { - $logger->info('addind pfdetect to list of services so that snort can be started'); - push @services, 'pfdetect'; - } - } - push @services, $service; - } else { - @services = @pf::services::ALL_SERVICES; - } - - my @alreadyRunningServices = (); - if ( lc($command) eq 'start' ) { - require pf::pfcmd::checkup; - import pf::pfcmd::checkup; - #Start httpd.admin anyway for the configurator - my $nb_running_services = 0; - if ( pf::services::service_ctl( "httpd.admin", "status" ) ) { - $nb_running_services++; - push @alreadyRunningServices, "httpd.admin"; - } - if ( grep( { $_ eq "httpd.admin" } @alreadyRunningServices ) == 1 ) - { - print "httpd.admin|already running\n"; - } else { - pf::services::service_ctl( "httpd.admin", $command ); - print "httpd.admin|$command\n"; - } - checkup(@services); - foreach my $tmp (@pf::services::ALL_SERVICES) { - if ( pf::services::service_ctl( $tmp, "status" ) ) { - $nb_running_services++; - push @alreadyRunningServices, $tmp; - } - } - if ( $nb_running_services == 0 ) { - if(isenabled($Config{services}{iptables}) && $service eq 'pf') { - $logger->info("saving current iptables to var/iptables.bak"); - require pf::inline::custom; - my $iptables = pf::inline::custom->new(); - my $technique = $iptables->{_technique}; - $technique->iptables_save( $install_dir . '/var/iptables.bak' ); - } - } - } - - print "service|command\n"; - if ( $command ne 'stop' ) { - print "config files|$command\n"; - require pf::os; - pf::os::import_dhcp_fingerprints(); - pf::services::read_violations_conf(); - if(isenabled($Config{services}{iptables}) && $service eq 'pf') { - print "iptables|$command\n"; - require pf::inline::custom; - my $iptables = pf::inline::custom->new(); - my $technique = $iptables->{_technique}; - $technique->iptables_generate(); - } - } - - foreach my $srv (@services) { - next if ( ($srv eq 'httpd.admin') && ($command eq 'start' ) ); - if ( ( $command eq 'start' ) - && ( grep( { $_ eq $srv } @alreadyRunningServices ) == 1 ) ) - { - print "$srv|already running\n"; - } else { - pf::services::service_ctl( $srv, $command ); - print "$srv|$command\n"; - } - } - - if ( lc($command) eq 'stop' ) { - my $nb_running_services = 0; - foreach my $tmp (@pf::services::ALL_SERVICES) { - if ( pf::services::service_ctl( $tmp, "status" ) ) { - $nb_running_services++; - } - } - if ( $nb_running_services == 0 ) { - if(isenabled($Config{services}{iptables}) && $service eq 'pf') { - print "iptables|$command\n"; - require pf::inline::custom; - my $iptables = pf::inline::custom->new(); - my $technique = $iptables->{_technique}; - $technique->iptables_restore( $install_dir . '/var/iptables.bak' ); - } - } else { - if ( lc($service) eq 'pf' ) { - $logger->error( - "Even though 'service pf stop' was called, there are still $nb_running_services services running. " - . "Can't restore iptables from var/iptables.bak" - ); - } - } - } - return 0; -} - sub startService { my ($service) = @_; my @managers = getStartServiceManagers($service); print "service|command\n"; my $count = 0; - if(isIptableManaged($service)) { + if(isIptablesManaged($service)) { + $logger->info("saving current iptables to var/iptables.bak"); my $technique; if(all { $_->status eq '0' } @managers) { $technique = getIptablesTechnique(); @@ -1374,6 +1185,10 @@ sub startService { $technique ||= getIptablesTechnique(); $technique->iptables_generate(); } + require pf::pfcmd::checkup; + import pf::pfcmd::checkup; + checkup( map {$_->name} @managers); + foreach my $manager (@managers) { my $command; if($manager->status ne '0') { @@ -1387,10 +1202,6 @@ sub startService { return 0; } -sub saveIptables { - $logger->info("saving current iptables to var/iptables.bak"); -} - sub getIptablesTechnique { require pf::inline::custom; my $iptables = pf::inline::custom->new(); @@ -1401,11 +1212,11 @@ sub getStartServiceManagers { my ($service) = @_; my @services; if($service eq 'pf') { - @services = @pf::services::ALL_SERVICES; + @services = pf::services::service_list(@pf::services::ALL_SERVICES); } else { @services = ($service); } - return grep { $_->isManaged } _getStartServiceManagers(@services); + return _getStartServiceManagers(@services); } sub _getStartServiceManagers { @@ -1414,12 +1225,12 @@ sub _getStartServiceManagers { grep { (!exists $seen{$_->name}) && ($seen{$_->name} = 1) } map { my $m = $_; - my @managers = map { getServiceManager($_) } @{$m->dependsOnServices}; + my @managers = map { pf::services::get_service_manager($_) } @{$m->dependsOnServices}; push @managers,$m; @managers } grep { defined $_ } - map { getServiceManager($_) } @_; + map { pf::services::get_service_manager($_) } @_; return @serviceManagers; } @@ -1437,7 +1248,7 @@ sub stopService { } print join('|',$manager->name,$command),"\n"; } - if(isIptableManaged($service)) { + if(isIptablesManaged($service)) { my $count = true { $_->status eq '0' } @managers; if( $count ) { getIptablesTechnique->iptables_restore( $install_dir . '/var/iptables.bak' ); @@ -1451,7 +1262,7 @@ sub stopService { return 0; } -sub isIptableManaged { +sub isIptablesManaged { return $_[0] eq 'pf' && isenabled($Config{services}{iptables}) } @@ -1471,7 +1282,7 @@ sub _getStopServiceManagers { my %seen; my @serviceManagers = grep { defined ($_) && (!exists $seen{$_->name}) && ($seen{$_->name} = 1) } - map { getServiceManager($_) } @_; + map { pf::services::get_service_manager($_) } @_; return @serviceManagers; } @@ -1485,7 +1296,7 @@ sub restartService { sub watchService { my ($service) = @_; my @stoppedServiceManagers = - grep { $_->isManaged && $_->status eq '0' } + grep { $_->status eq '0' } getStartServiceManagers($service); if(@stoppedServiceManagers) { my @stoppedServices = map { $_->name } @stoppedServiceManagers; @@ -1526,16 +1337,6 @@ sub statusOfService { return ( $notStarted ? 3 : 0); } -sub getServiceManager { - my ($service) = @_; - my $module = "pf::services::manager::${service}"; - $module =~ /^(.*)$/; - $module = $1; - $module =~ s/\./_/; - eval "use $module;"; - return $module->new; -} - sub class { my ( $function, $id ); require pf::class; diff --git a/lib/pf/services.pm b/lib/pf/services.pm index e92a7315e5cd..b6400ed38131 100644 --- a/lib/pf/services.pm +++ b/lib/pf/services.pm @@ -23,431 +23,122 @@ F, F, F. use strict; use warnings; -use File::Basename; -use IPC::Cmd qw[can_run run]; -use Log::Log4perl; -use Readonly; -use Time::HiRes; -use Try::Tiny; -use UNIVERSAL::require; -use Proc::ProcessTable; -use List::Util qw(first); - use pf::config; -use pf::util; -use pf::node qw(nodes_registered_not_violators); -use pf::trigger qw(trigger_delete_all parse_triggers); -use pf::class qw(class_view_all class_merge); -use pf::services::apache; -use pf::services::dhcpd qw(generate_dhcpd_conf); -use pf::services::radiusd qw(generate_radiusd_conf); -use pf::services::snmptrapd qw(generate_snmptrapd_conf); -use pf::services::snort qw(generate_snort_conf); -use pf::services::suricata qw(generate_suricata_conf); -use pf::SwitchFactory; -use pf::violation_config; -use File::Slurp qw(read_file); - -Readonly our @APACHE_SERVICES => ( - 'httpd.admin', 'httpd.webservices', 'httpd.portal', 'httpd.proxy' +use pf::services::manager::memcached; +use pf::services::manager::httpd_admin; +use pf::services::manager::httpd_webservices; +use pf::services::manager::httpd_portal; +use pf::services::manager::pfdns; +use pf::services::manager::dhcpd; +use pf::services::manager::pfdetect; +use pf::services::manager::snort; +use pf::services::manager::suricata; +use pf::services::manager::radiusd; +use pf::services::manager::snmptrapd; +use pf::services::manager::pfsetvlan; +use pf::services::manager::pfdhcplistener; +use pf::services::manager::pfmon; +use Module::Loaded qw(is_loaded); + +our @APACHE_SERVICES = ( + 'httpd.admin', 'httpd.webservices', 'httpd.portal' ); -Readonly our @ALL_SERVICES => ( +our @ALL_SERVICES = ( 'memcached', @APACHE_SERVICES, 'pfdns', 'dhcpd', 'pfdetect', 'snort', 'suricata', 'radiusd', 'snmptrapd', 'pfsetvlan', 'pfdhcplistener', 'pfmon' ); my $services = join("|", @ALL_SERVICES); -Readonly our $ALL_BINARIES_RE => qr/$services +our $ALL_BINARIES_RE => qr/$services |apache2 # httpd on debian |freeradius # radiusd on debian |httpd.worker # mpm_worker apache version |httpd $/x; -=head1 Globals - -=over - -=item service_launchers - -sprintf-formatted strings that control how the services should be started. - %1$s: is the binary (w/ full path) - %2$s: optional parameters - -=cut - -my %service_launchers; -$service_launchers{'httpd'} = "%1\$s -f $conf_dir/httpd.conf"; -$service_launchers{'httpd.webservices'} = "%1\$s -f $conf_dir/httpd.conf.d/httpd.webservices -D$OS"; -$service_launchers{'httpd.admin'} = "%1\$s -f $conf_dir/httpd.conf.d/httpd.admin -D$OS"; -$service_launchers{'httpd.portal'} = "%1\$s -f $conf_dir/httpd.conf.d/httpd.portal -D$OS"; -$service_launchers{'httpd.proxy'} = "%1\$s -f $conf_dir/httpd.conf.d/httpd.proxy -D$OS"; - -$service_launchers{'pfdetect'} = "%1\$s -d -p $install_dir/var/alert &"; -$service_launchers{'pfmon'} = '%1$s -d &'; -$service_launchers{'pfdhcplistener'} = 'sudo %1$s -i %2$s -d &'; -$service_launchers{'pfsetvlan'} = '%1$s -d &'; -# TODO the following join on @listen_ints will cause problems with dynamic config reloading -$service_launchers{'dhcpd'} = "sudo %1\$s -lf $var_dir/dhcpd/dhcpd.leases -cf $generated_conf_dir/dhcpd.conf -pf $var_dir/run/dhcpd.pid " . join(" ", @listen_ints); -$service_launchers{'pfdns'} = '%1$s -d &'; -$service_launchers{'snmptrapd'} = "%1\$s -n -c $generated_conf_dir/snmptrapd.conf -C -A -Lf $install_dir/logs/snmptrapd.log -p $install_dir/var/run/snmptrapd.pid -On"; -$service_launchers{'radiusd'} = "sudo %1\$s -d $install_dir/raddb/"; -$service_launchers{'memcached'} = "%1\$s -d -p 11211 -u pf -m 64 -c 1024 -P $install_dir/var/run/memcached.pid"; - -# TODO $monitor_int will cause problems with dynamic config reloading -if ( isenabled( $Config{'trapping'}{'detection'} ) && $monitor_int && $Config{'trapping'}{'detection_engine'} eq 'snort' ) { - $service_launchers{'snort'} = - "%1\$s -u pf -c $generated_conf_dir/snort.conf -i $monitor_int " . - "-N -D -l $install_dir/var --pid-path $install_dir/var/run"; -} elsif ( isenabled( $Config{'trapping'}{'detection'} ) && $monitor_int && $Config{'trapping'}{'detection_engine'} eq 'suricata' ) { - $service_launchers{'suricata'} = - "%1\$s -D -c $install_dir/var/conf/suricata.yaml -i $monitor_int " . - "-l $install_dir/var --pidfile $install_dir/var/run/suricata.pid"; -} - -=back +our %ALLOWED_ACTIONS = ( + stop => undef, + start => undef, + watch => undef, + status => undef, + restart => undef, +); =head1 SUBROUTINES -=over - -=item * service_ctl +=head2 service_ctl =cut -#FIXME this is ridiculously complex and unfocused for such a simple task.. what is all that duplication? sub service_ctl { - my ( $daemon, $action, $quick ) = @_; - my $logger = Log::Log4perl::get_logger('pf::services'); - my $service = ( $Config{'services'}{"${daemon}_binary"} || "$install_dir/sbin/$daemon" ); - if ($daemon =~ /httpd\.(.*)/) { - $service = ( $Config{'services'}{"httpd_binary"} || "$install_dir/sbin/$daemon" ); - } - my $binary = basename($service); - - #Untaint Daemon - $daemon =~ /^(.*)$/; - $daemon = $1; - - $logger->info("$daemon $service $action"); - if ( $binary =~ /^($ALL_BINARIES_RE)$/ ) { - $binary = $1; - CASE: { - $action eq "start" && do { - - # if we shouldn't be running that daemon based on current configuration, skip it - if (!scalar grep({ $daemon eq $_ } service_list(@ALL_SERVICES))) { - $logger->info("$daemon ($service) not started because it's not required based on configuration"); - return $FALSE; - } - - if ( $daemon =~ /(dhcpd|snort|suricata|httpd|snmptrapd|radiusd)/ && !$quick ) - { - my $confname = "generate_" . $daemon . "_conf"; - $logger->info( - "Generating configuration file for $binary ($confname)"); - my %serviceHash = ( - 'dhcpd' => \&generate_dhcpd_conf, - 'snort' => \&generate_snort_conf, - 'suricata' => \&generate_suricata_conf, - 'httpd' => \&generate_httpd_conf, - 'httpd.webservices' => \&generate_httpd_conf, - 'httpd.portal' => \&generate_httpd_conf, - 'httpd.proxy' => \&generate_httpd_conf, - 'httpd.admin' => \&generate_httpd_conf, - 'radiusd' => \&generate_radiusd_conf, - 'snmptrapd' => \&generate_snmptrapd_conf - ); - if ( $serviceHash{$daemon} ) { - $serviceHash{$daemon}->(); - } else { - print "No such sub: $confname\n"; - } - } - - # valid daemon and flags are set - if (grep({ $daemon eq $_ } @ALL_SERVICES) && defined($service_launchers{$daemon})) { - - if ( !( ($daemon eq 'pfdhcplistener' ) || ($daemon eq 'httpd') || ($daemon eq 'httpd.webservices') || ($daemon eq 'httpd.admin') || ($daemon eq 'httpd.portal') || ($daemon eq 'httpd.proxy') ) ) { - if ( $daemon eq 'dhcpd' ) { - - # create var/dhcpd/dhcpd.leases if it doesn't exist - pf_run("touch $var_dir/dhcpd/dhcpd.leases") if (!-f $var_dir . '/dhcpd/dhcpd.leases'); - - manage_Static_Route(1); - - } elsif ( $daemon eq 'radiusd' ) { - my $pid = service_ctl( $daemon, "status" ); - # TODO: push all these per-daemon initialization into pf::services::... - require pf::freeradius; - pf::freeradius::freeradius_populate_nas_config(); - - } - return launchService($daemon,$service); - } elsif ($daemon eq 'pfdhcplistener') { - if ( isenabled( $Config{'network'}{'dhcpdetector'} ) ) { - # putting interfaces to run listener on in hash so that - # only one listener per interface will ever run - my %interfaces = map { $_ => $TRUE } @listen_ints, @dhcplistener_ints; - foreach my $dev (keys %interfaces) { - launchService($daemon,$service, $dev); - } - return 1; - } - } elsif ($daemon eq 'httpd') { - foreach my $serv (@APACHE_SERVICES) { - next if ($serv eq "httpd.admin"); - service_ctl($serv,"start"); - } - } elsif ($daemon =~ /httpd\.(.*)/) { - launchService($daemon,$service); - } - } - last CASE; - }; - $action eq "stop" && do { - if ($daemon eq 'httpd') { - foreach my $serv (@APACHE_SERVICES) { - stopService($serv,$binary); - } - } else { - stopService($daemon,$binary); - } - last CASE; - }; - $action eq "restart" && do { - service_ctl( "pfdetect", "stop" ) if ( $daemon eq "snort" || $daemon eq "suricata" ); - service_ctl( $daemon, "stop" ); - - service_ctl( "pfdetect", "start" ) if ( $daemon eq "snort" || $daemon eq "suricata" ); - service_ctl( $daemon, "start" ); - last CASE; - }; - $action eq "status" && do { - my $pid; - # -x: this causes the program to also return process id's of shells running the named scripts. - if (!( ($binary eq "pfdhcplistener") || ($daemon eq "httpd") || ($daemon eq "snort") ) ) { - return getPidFromFile($daemon,$binary); - } - # Handle the pfdhcplistener case. Grab exact interfaces where pfdhcplistner should run, - # explicitly check process names per interface then return 0 to force a restart if one is missing. - elsif ($binary eq "pfdhcplistener") { - my %int_to_pid; - my $dead_flag; - foreach my $interface ( @listen_ints, @dhcplistener_ints ) { - my $pid = getPidFromFile("pfdhcplistener_${interface}",$binary); - $int_to_pid{$interface} = $pid; - $dead_flag = $TRUE unless $pid; - } - - # outputs: a list of interface => pid, ... helpful for sysadmin and forensics - $logger->info( - sprintf( "$binary pids %s", join(", ", map { "$_ => $int_to_pid{$_}" } keys %int_to_pid) ) - ); - - # return 0 if one is not working - # REWORK: if there only one interface without a pfdhcplistener then the pid is 0 - # result, you can have more than one pfdhcplistener per interface ?! - # return 0 if ($dead_flag); - $pid = join(" ", values %int_to_pid); - if ( $quick || !$dead_flag) { - return ($pid); - } else { - return (0); - } - } - elsif ($daemon =~ "snort") { - $pid = 0; - if (defined $monitor_int) { - $pid = getPidFromFile("${daemon}_${monitor_int}.pid",$binary); - } - return ($pid); - } - - } + my ($service, $action, $quick) = @_; + if(exists $ALLOWED_ACTIONS{$action}) { + my $sm = get_service_manager($service); + if(defined $sm && ($action ne 'start' || $sm->isManaged )) { + return $sm->$action($quick); } } - else { - $logger->logcroak("unknown service $binary (daemon: $daemon)!"); - return $FALSE; - } - return $TRUE; + return 0; } -=item * service_list +=head2 get_service_manager -return an array of enabled services +Get service manager my service name =cut -sub service_list { - my @services = @_; - my @finalServiceList = (); - my @add_last; - foreach my $service (@services) { - if ( $service eq 'snort' || $service eq 'suricata' ) { - # add suricata or snort to services to add last if enabled - push @add_last, $service - if (isenabled($Config{'trapping'}{'detection'}) && $Config{'trapping'}{'detection_engine'} eq $service); - } elsif ( $service eq "radiusd" ) { - push @finalServiceList, $service - if ( isenabled($Config{'services'}{'radiusd'}) ); - } elsif ( $service eq "pfdetect" ) { - push @finalServiceList, $service - if ( isenabled( $Config{'trapping'}{'detection'} ) ); - } elsif ( $service eq "dhcpd" ) { - push @finalServiceList, $service - if ( (is_inline_enforcement_enabled() || is_vlan_enforcement_enabled()) - && isenabled($Config{'services'}{'dhcpd'}) ); - } elsif ( $service eq "pfdns" ) { - push @finalServiceList, $service - if ( (is_inline_enforcement_enabled() || is_vlan_enforcement_enabled()) - && isenabled($Config{'services'}{'pfdns'}) ); - } elsif ( $service eq "httpd.proxy" ) { - push @finalServiceList, $service - if ( isenabled($Config{'trapping'}{'interception_proxy'}) ); - } - elsif ( $service eq 'pfdhcplistener' ) { - push @finalServiceList, $service if ( isenabled($Config{'network'}{'dhcpdetector'}) ); - } - # other services are added as-is - else { - push @finalServiceList, $service; - } +sub get_service_manager { + my ($service) = @_; + my $sm; + my $module = _make_service_manager_module_name($service); + if(is_loaded($module)) { + $sm = $module->new; } - - push @finalServiceList, @add_last; - return @finalServiceList; + return $sm; } -# Adding or removing static routes for Registration and Isolation VLANs -sub manage_Static_Route { - my $add_Route = @_; - my $logger = Log::Log4perl::get_logger('pf::services'); - - foreach my $network ( keys %ConfigNetworks ) { - # shorter, more convenient local accessor - my %net = %{$ConfigNetworks{$network}}; - +=head2 read_violations_conf - if ( defined($net{'next_hop'}) && ($net{'next_hop'} =~ /^(?:\d{1,3}\.){3}\d{1,3}$/) ) { - my $add_del = $add_Route ? 'add' : 'del'; - my $full_path = can_run('route') - or $logger->error("route is not installed! Can't add static routes to routed VLANs."); - - my $cmd = "sudo $full_path $add_del -net $network netmask " . $net{'netmask'} . " gw " . $net{'next_hop'}; - $cmd = untaint_chain($cmd); - my @out = pf_run($cmd); - } - } -} - -=item * read_violations_conf +reload the violation config =cut sub read_violations_conf { + require pf::violation_config; pf::violation_config::readViolationConfigFile(); return 1; } -sub getPidFromFile { - my ($daemon,$binary) = @_; - my $logger = Log::Log4perl::get_logger('pf::services'); - my $pid = 0; - my $pid_file = "$install_dir/var/run/$daemon.pid"; - if (-e $pid_file) { - eval {chomp( $pid = read_file($pid_file) );}; - } - $pid = 0 unless $pid; - $logger->info("pidof -x $binary returned $pid"); - if($pid && $pid =~ /^(.*)$/) { - $pid = $1; - unless (kill( 0,$pid)) { - $pid = 0; - $logger->info("removing stale pid file $pid_file"); - unlink $pid_file; - } - } +=head2 _make_service_manager_module_name - return ($pid); -} +make the service manager module name -sub launchService { - my ($daemon,@launcher_args) = @_; - my $launcher = $service_launchers{$daemon}; - @launcher_args = map { /^(.+)$/;$1 } @launcher_args; - if ($launcher) { - $launcher =~ /^(.*)$/; - $launcher = $1; - my $logger = Log::Log4perl::get_logger('pf::services'); - my $cmd_line = sprintf($launcher, @launcher_args); - $logger->info("Starting $daemon with '$cmd_line'"); - if ($cmd_line =~ /^(.+)$/) { - $cmd_line = $1; - my $t0 = Time::HiRes::time(); - my $return_value = system($cmd_line); - my $elapsed = Time::HiRes::time() - $t0; - $logger->info(sprintf("Daemon %s took %.3f seconds to start.", $daemon, $elapsed)); - return $return_value; - } - } - return; +=cut + +sub _make_service_manager_module_name { + my ($service) = @_; + my $module = "pf::services::manager::${service}"; + $module =~ /^(.*)$/; + $module = $1; + $module =~ s/\./_/; + return $module; } +=head2 service_list -sub stopService { - my ($service,$binary) = @_; - my $pids = service_ctl( $service, "status", 1 ); - my $logger = Log::Log4perl::get_logger('pf::services'); - $pids =~ /^(.*)$/; - $pids = $1; - my @pid = split(' ', $pids); - foreach my $pid (@pid) { - if ($pid) { - $logger->info("Sending TERM signal to $service with pid $pid"); - my $count = kill 'TERM',$pid; - unless ($count) { - $logger->logcroak("Can't a TERM signal to $service with pid $pid "); - return; - } - - if ( $service =~ /(dhcpd)/) { - manage_Static_Route(); - } - my $pid_file = "$install_dir/var/run/$binary.pid"; - if ( waitToShutdown($service, $pid) && -e $pid_file) { - $logger->info("Removing $pid_file"); - unlink($pid_file); - } - } - } +Return the list of services that are allowed to be managed -} +=cut -sub waitToShutdown { - my ($service, $pid) = @_; - my $logger = Log::Log4perl::get_logger('pf::services'); - my $maxWait = 10; - my $curWait = 0; - my $ppt; - my $proc = 0; - while ( ( ( $curWait < $maxWait ) - && ( service_ctl( $service, "status" ) ne "0" ) ) && defined($proc) ) - { - $ppt = new Proc::ProcessTable; - $proc = first { $_->pid == $pid } @{ $ppt->table }; - $logger->info("Waiting for $service to stop "); - sleep(2); - $curWait++; - } - return defined $proc; +sub service_list { + return grep { + my $module = _make_service_manager_module_name($_); + is_loaded($module) && $module->new->isManaged + } @_; } -=back - =head1 AUTHOR Inverse inc. From cacc253250919fbc4ee21a27417ef36845af95cb Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 26 Sep 2013 00:59:18 -0400 Subject: [PATCH 285/369] Refactored pf status in terms of the service manager model --- .../lib/pfappserver/Model/Services.pm | 35 +++---------------- 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/html/pfappserver/lib/pfappserver/Model/Services.pm b/html/pfappserver/lib/pfappserver/Model/Services.pm index 420c5082c318..e74948b87654 100644 --- a/html/pfappserver/lib/pfappserver/Model/Services.pm +++ b/html/pfappserver/lib/pfappserver/Model/Services.pm @@ -97,28 +97,8 @@ sub status { my ($self) = @_; my $logger = get_logger(); - my $cmd = "$PFCMD service pf status 2>&1"; - $logger->info("Requesting services status with: $cmd"); - - my @services_status = $self->_run_pfcmd_service("pf","status"); - $logger->debug( - "Service status output: " - . ( (@services_status) ? join('', @services_status) : 'NONE' ) - ); - - # TODO extract service\|shouldBeStarted\|pid into constant and use constant both here and when we report on CLI - if (!@services_status || $services_status[0] !~ /^service\|shouldBeStarted\|pid$/) { - return ( $STATUS::INTERNAL_SERVER_ERROR, join('', @services_status) ); - } - - my $services_ref = {}; - shift @services_status; # throw out first line - foreach my $service_status (@services_status) { - chomp($service_status); - my ($service_name, $should_be_started, $pids) = split(/\|/, $service_status); - $services_ref->{$service_name} = ($pids) if ($should_be_started); - } - return ($STATUS::OK, { services => $services_ref}) if ( %$services_ref ); + my %services_ref = map { $_->name => $_->status } grep { $_->isManaged } map { pf::services::get_service_manager($_) } @pf::services::ALL_SERVICES; + return ($STATUS::OK, { services => \%services_ref}) if ( keys %services_ref ); return ($STATUS::INTERNAL_SERVER_ERROR, "Unidentified error see server side logs for details."); } @@ -129,15 +109,10 @@ sub status { sub service_status { my ($self,$service) = @_; - my @services = @pf::services::ALL_SERVICES; - my @services_which_should_be_started = pf::services::service_list(@services); + my $sm = pf::services::get_service_manager($service); my %status = ( - pid => pf::services::service_ctl($service, 'status' ), - shouldBeStarted => ( - ( grep( { $_ eq $service } @services_which_should_be_started ) - > 0 - ) ? 1 : 0 - ) + pid => $sm->status, + shouldBeStarted => $sm->isManaged ); return ($STATUS::OK,\%status); } From ff296c1fd8af9650b2a6f333d8ebe6ebceaa994b Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Fri, 27 Sep 2013 15:17:47 -0400 Subject: [PATCH 286/369] Refactored stop where if the process did not stop in 60 seconds kill -9 the process --- lib/pf/services/manager.pm | 144 +++++++++++++++++++++++++------------ 1 file changed, 97 insertions(+), 47 deletions(-) diff --git a/lib/pf/services/manager.pm b/lib/pf/services/manager.pm index 211b9b887a03..896b6841120c 100644 --- a/lib/pf/services/manager.pm +++ b/lib/pf/services/manager.pm @@ -11,7 +11,6 @@ pf::services::manager This module encapsulates the service actions/commands for pfcmd tool - =cut use strict; @@ -24,6 +23,8 @@ use File::Slurp qw(read_file); use Proc::ProcessTable; use List::Util qw(first); use Linux::Inotify2; +use Errno qw(EINTR EAGAIN); +use Time::HiRes qw (alarm sleep); =head1 Attributes @@ -61,11 +62,37 @@ executable of service has executable => (is => 'rw', builder => 1, lazy => 1 ); +=head2 lastPid + +The last pid retrived from the pidFile + +=cut + +has lastPid => (is => 'rw'); + +=head2 inotify + +The inotify object used to watch for pidfile + +=cut + +has inotify => (is => 'rw', builder => 1, lazy => 1 ); + =head1 Methods +=head2 _build_inotify + +builds the inotify object + +=cut + +sub _build_inotify { + return Linux::Inotify2->new; +} + =head2 start - start the service +start the service =cut @@ -84,7 +111,7 @@ sub start { =head2 preStartSetup - setup work for starting a servicw +work for starting a servicw =cut @@ -97,7 +124,7 @@ sub preStartSetup { =head2 startService - Starts the service +Starts the service =cut @@ -108,7 +135,7 @@ sub startService { =head2 postStartCleanup - Cleanup work after the starting the service +Cleanup work after the starting the service =cut @@ -118,7 +145,7 @@ sub postStartCleanup { my $pidFile = $self->pidFile; my $result = 0; unless (-e $pidFile) { - my $inotify = Linux::Inotify2->new; + my $inotify = $self->inotify; $inotify->watch ($run_dir, IN_CREATE, sub { my $e = shift; my $name = $e->fullname; @@ -189,7 +216,8 @@ Returns the pid of the service sub pid { my ($self) = @_; - return $self->pidFromFile; + $self->lastPid($self->pidFromFile); + return $self->lastPid; } =head2 stop @@ -201,25 +229,73 @@ Stop the service waitinf for it to shutdown sub stop { my ($self,$quick) = @_; my $pid = $self->pid; - my $name = $self->name; - my $logger = get_logger; if ($pid) { - $logger->info("Sending TERM signal to $name with pid $pid"); - my $count = kill 'TERM',$pid; - unless ($count) { - $logger->logcroak("Can't a TERM signal to $name with pid $pid "); - return; - } - my $pid_file = $self->pidFile; - if ( $self->waitToShutdown($pid) && -e $pid_file) { - $logger->info("Removing $pid_file"); - unlink($pid_file); - } - return !-e $pid_file; + $self->preStopSetup(); + $self->stopService(); + $self->postStopCleanup(); + return 1; } return; } + +=head2 preStopSetup + +the pre stop setup + +=cut + +sub preStopSetup { + my ($self) = @_; + $self->inotify->watch($self->pidFile, IN_DELETE_SELF); +} + +sub postStopCleanup { + my ($self) = @_; + my $logger = get_logger(); + my $name = $self->name; + my $pid = $self->lastPid; + my $inotify = $self->inotify; + my $pidFile = $self->pidFile; + my $timedout; + #give the kill a little time + sleep(0.1); + $inotify->blocking(0); + $self->removeStalePid; + eval { + local $SIG{ALRM} = sub { die "alarm clock restart" }; + alarm 60; + eval { + until($inotify->read) { + die $! if defined $! && $! != EINTR && $! != EAGAIN; + $self->removeStalePid; + #give it some time + select(undef, undef, undef, 0.1); + } + }; + alarm 0; + $timedout = 1 if $@ && $@ =~ /^alarm clock restart/; + $logger->error("Error: $@") if $@; + }; + alarm 0; + $logger->info("Timed out waiting for process $name to stop") if $timedout; + $self->removeStalePid; + my $still_alive = kill 0 , $pid; + if ( $still_alive ) { + my $count = kill 'KILL',$pid; + $self->removeStalePid; + } +} + +sub stopService { + my ($self) = @_; + my $name = $self->name; + my $logger = get_logger(); + my $pid = $self->lastPid; + $logger->info("Sending TERM signal to $name with pid $pid"); + my $count = kill 'TERM',$pid; +} + =head2 watch If the service is stopped start the service @@ -327,32 +403,6 @@ sub removeStalePid { } } -=head2 waitToShutdown - -Waits for the pid of the service to shutdown - -=cut - -sub waitToShutdown { - my ($self, $pid) = @_; - my $name = $self->name; - my $logger = Log::Log4perl::get_logger('pf::services'); - my $maxWait = 10; - my $curWait = 0; - my $ppt; - my $proc = 0; - while ( ( ( $curWait < $maxWait ) - && ( $self->status ne "0" ) ) && defined($proc) ) - { - $ppt = new Proc::ProcessTable; - $proc = first { defined $_ && $_->pid == $pid } @{ $ppt->table }; - $logger->info("Waiting for $name to stop "); - sleep(2); - $curWait++; - } - return !defined $proc; -} - =head2 isManaged return true is the service is currently managed by packetfence From 18baee876e763153d2ecb0460b257abc90e2ea7d Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 30 Sep 2013 08:02:22 -0400 Subject: [PATCH 287/369] Code cleanp better logging --- lib/pf/services/manager.pm | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/pf/services/manager.pm b/lib/pf/services/manager.pm index 896b6841120c..b7985ee65eeb 100644 --- a/lib/pf/services/manager.pm +++ b/lib/pf/services/manager.pm @@ -392,13 +392,14 @@ sub removeStalePid { my ($self) = @_; my $logger = get_logger; my $pid = $self->pidFromFile; - my $pid_file = $self->pidFile; + my $pidFile = $self->pidFile; if($pid && $pid =~ /^(.*)$/) { $pid = $1; - unless (kill( 0,$pid)) { - $pid = 0; - $logger->info("removing stale pid file $pid_file"); - unlink $pid_file; + $logger->info("verifying process $pid"); + my $result = kill(0, $pid); + unless ($result) { + $logger->info("removing stale pid file $pidFile"); + unlink $pidFile; } } } From e6ac306d680ad8b8d930114b2f8ec972ec27759c Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 30 Sep 2013 09:48:07 -0400 Subject: [PATCH 288/369] Created test and dummy daemon for testing pf::services::manager --- t/daemon.t | 128 +++++++++++++++++++++++++++++++++++++++++++++++ t/services/dummy | 24 +++++++++ 2 files changed, 152 insertions(+) create mode 100755 t/daemon.t create mode 100755 t/services/dummy diff --git a/t/daemon.t b/t/daemon.t new file mode 100755 index 000000000000..c05cdfb1ff58 --- /dev/null +++ b/t/daemon.t @@ -0,0 +1,128 @@ +#!/usr/bin/perl +=head1 NAME + +daemon + +=cut + +=head1 DESCRIPTION + +daemon + +=cut + +use strict; +use warnings; +use Time::HiRes qw(sleep); +use lib '/usr/local/pf/lib'; + +use Test::More tests => 14; # last test to print + +use Test::NoWarnings; + +use_ok('pf::services::manager'); + +my $sm = pf::services::manager->new( + executable => '/usr/local/pf/t/services/dummy', + launcher => '%1$s', + name => 'dummy' +); + +isa_ok($sm,"pf::services::manager"); + +$sm->start; + +my $pid = $sm->pid; + +ok($pid,"Pid return $pid"); + +ok(isAlive($pid), "Process is running"); + +kill 9, $pid; +#Give it a little time +waitForPid($pid); + +ok(-e $sm->pidFile,"Pidfile there after force kill of process"); + +$sm->removeStalePid; + +ok(!(-e $sm->pidFile),"The stale pid removed"); + +$sm->watch; + +sleep(0.1); + +#Give it a little time +$pid = $sm->pid; + +ok($pid,"Pid return $pid after watch"); + +ok(isAlive($pid), "Process is running after watch"); + +$sm->stop; + +ok(!isAlive($pid),"Process is stopped"); + +ok(!-e $sm->pidFile,"Pidfile is removed after stopping"); + +$sm->start; + +$pid = $sm->pid; + +ok($pid,"Pid return $pid"); + +ok(isAlive($pid), "Process is running"); + +$sm->restart; + +my $newpid = $sm->pid; + +ok($pid != $newpid && isAlive($newpid),"Restart is successful"); + +sub isAlive { + my ($pid) = @_; + return kill 0, $pid; +} + +sub waitForPid { + my ($pid) = @_; + my $count = 0; + while(isAlive($pid) && $count < 4 ) { + sleep(0.1); + $count++; + } +} + + +=head1 AUTHOR + +Inverse inc. + +Minor parts of this file may have been contributed. See CREDITS. + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + + diff --git a/t/services/dummy b/t/services/dummy new file mode 100755 index 000000000000..8def8c4fc2c3 --- /dev/null +++ b/t/services/dummy @@ -0,0 +1,24 @@ +#!/usr/bin/perl +use strict; +use POSIX qw(pause setsid); +use Getopt::Std; + +BEGIN { + use lib qw(/usr/local/pf/lib /usr/local/pf/t); + use pf::util; + use PfFilePaths; +} + +my %args; +getopts( 'n:', \%args ); +my $name = 'dummy'; +$name = $args{n} if exists $args{n}; + +exit(0) if fork; +setsid; +exit(0) if fork; + +createpid($name); +$SIG{TERM} = sub {}; +pause; +deletepid($name); From 1eb1d3bfcf0befad454d14002689a6aeca2e1787 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 30 Sep 2013 17:18:45 -0400 Subject: [PATCH 289/369] renamed pf::services::manager::roles::pf_conf_service_managed to pf::services::manager::roles::is_managed_by_pf_conf --- lib/pf/services/manager/dhcpd.pm | 2 +- lib/pf/services/manager/memcached.pm | 2 +- lib/pf/services/manager/pfdns.pm | 2 +- lib/pf/services/manager/radiusd.pm | 2 +- ...{pf_conf_service_managed.pm => is_managed_by_pf_conf.pm} | 6 +++--- lib/pf/services/manager/snort.pm | 2 +- lib/pf/services/manager/suricata.pm | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) rename lib/pf/services/manager/roles/{pf_conf_service_managed.pm => is_managed_by_pf_conf.pm} (84%) diff --git a/lib/pf/services/manager/dhcpd.pm b/lib/pf/services/manager/dhcpd.pm index bbc032b62725..6c33a748a903 100644 --- a/lib/pf/services/manager/dhcpd.pm +++ b/lib/pf/services/manager/dhcpd.pm @@ -22,7 +22,7 @@ use File::Touch; use IPC::Cmd qw[can_run run]; extends 'pf::services::manager'; -with 'pf::services::manager::roles::pf_conf_service_managed'; +with 'pf::services::manager::roles::is_managed_by_pf_conf'; with 'pf::services::manager::roles::is_managed_vlan_inline_enforcement'; has '+name' => (default => sub { 'dhcpd' } ); diff --git a/lib/pf/services/manager/memcached.pm b/lib/pf/services/manager/memcached.pm index 75b4225b9938..7f065ddf5899 100644 --- a/lib/pf/services/manager/memcached.pm +++ b/lib/pf/services/manager/memcached.pm @@ -17,7 +17,7 @@ use Moo; use pf::file_paths; extends 'pf::services::manager'; -with 'pf::services::manager::roles::pf_conf_service_managed'; +with 'pf::services::manager::roles::is_managed_by_pf_conf'; has '+name' => (default => sub { 'memcached' } ); diff --git a/lib/pf/services/manager/pfdns.pm b/lib/pf/services/manager/pfdns.pm index 30bf11e928d0..19f2fd7f6355 100644 --- a/lib/pf/services/manager/pfdns.pm +++ b/lib/pf/services/manager/pfdns.pm @@ -15,7 +15,7 @@ use strict; use warnings; use Moo; extends 'pf::services::manager'; -with 'pf::services::manager::roles::pf_conf_service_managed'; +with 'pf::services::manager::roles::is_managed_by_pf_conf'; with 'pf::services::manager::roles::is_managed_vlan_inline_enforcement'; has '+name' => (default => sub { 'pfdns' } ); diff --git a/lib/pf/services/manager/radiusd.pm b/lib/pf/services/manager/radiusd.pm index 69b1c5115882..4b7a12b4afcf 100644 --- a/lib/pf/services/manager/radiusd.pm +++ b/lib/pf/services/manager/radiusd.pm @@ -18,7 +18,7 @@ use pf::file_paths; use Moo; extends 'pf::services::manager'; -with 'pf::services::manager::roles::pf_conf_service_managed'; +with 'pf::services::manager::roles::is_managed_by_pf_conf'; has '+name' => ( default => sub { 'radiusd' } ); diff --git a/lib/pf/services/manager/roles/pf_conf_service_managed.pm b/lib/pf/services/manager/roles/is_managed_by_pf_conf.pm similarity index 84% rename from lib/pf/services/manager/roles/pf_conf_service_managed.pm rename to lib/pf/services/manager/roles/is_managed_by_pf_conf.pm index b7c0ee817b36..3d6b6d4d0a56 100644 --- a/lib/pf/services/manager/roles/pf_conf_service_managed.pm +++ b/lib/pf/services/manager/roles/is_managed_by_pf_conf.pm @@ -1,13 +1,13 @@ -package pf::services::manager::roles::pf_conf_service_managed; +package pf::services::manager::roles::is_managed_by_pf_conf; =head1 NAME -pf::services::manager::roles::pf_conf_service_managed add documentation +pf::services::manager::roles::is_managed_by_pf_conf add documentation =cut =head1 DESCRIPTION -pf::services::manager::roles::pf_conf_service_managed +pf::services::manager::roles::is_managed_by_pf_conf =cut diff --git a/lib/pf/services/manager/snort.pm b/lib/pf/services/manager/snort.pm index 972d3b757254..ea8ba3b0d79b 100644 --- a/lib/pf/services/manager/snort.pm +++ b/lib/pf/services/manager/snort.pm @@ -15,7 +15,7 @@ use strict; use warnings; use Moo; extends 'pf::services::manager'; -with 'pf::services::manager::roles::pf_conf_service_managed'; +with 'pf::services::manager::roles::is_managed_by_pf_conf'; use pf::file_paths; use pf::config; diff --git a/lib/pf/services/manager/suricata.pm b/lib/pf/services/manager/suricata.pm index 02e28638ac14..46635467aec5 100644 --- a/lib/pf/services/manager/suricata.pm +++ b/lib/pf/services/manager/suricata.pm @@ -18,7 +18,7 @@ use pf::config; use Moo; use pf::services::suricata qw(generate_suricata_conf); extends 'pf::services::manager'; -with 'pf::services::manager::roles::pf_conf_service_managed'; +with 'pf::services::manager::roles::is_managed_by_pf_conf'; has '+name' => ( default => sub { 'suricata' } ); From 2aa3ec33d436135fe8f4cb607f3ab4eeef528558 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Tue, 1 Oct 2013 06:29:18 -0400 Subject: [PATCH 290/369] Add httpd.proxy to service list --- lib/pf/pfcmd.pm | 2 +- lib/pf/services.pm | 3 +- lib/pf/services/manager/httpd_proxy.pm | 57 ++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 lib/pf/services/manager/httpd_proxy.pm diff --git a/lib/pf/pfcmd.pm b/lib/pf/pfcmd.pm index 4eb64d079a1a..c33d52871f2b 100644 --- a/lib/pf/pfcmd.pm +++ b/lib/pf/pfcmd.pm @@ -312,7 +312,7 @@ sub parseCommandLine { 'service' => qr{ ^ ( dhcpd | httpd | pfdns | pfdetect | pf | pfdhcplistener | pfmon | pfsetvlan | radiusd | snmptrapd - | snort | suricata | httpd\.webservices | httpd\.admin | httpd\.portal | memcached) + | snort | suricata | httpd\.webservices | httpd\.admin | httpd\.portal | httpd\.proxy | memcached) \s+ ( restart | start | status | stop | watch ) diff --git a/lib/pf/services.pm b/lib/pf/services.pm index b6400ed38131..90f28491a643 100644 --- a/lib/pf/services.pm +++ b/lib/pf/services.pm @@ -28,6 +28,7 @@ use pf::services::manager::memcached; use pf::services::manager::httpd_admin; use pf::services::manager::httpd_webservices; use pf::services::manager::httpd_portal; +use pf::services::manager::httpd_proxy; use pf::services::manager::pfdns; use pf::services::manager::dhcpd; use pf::services::manager::pfdetect; @@ -41,7 +42,7 @@ use pf::services::manager::pfmon; use Module::Loaded qw(is_loaded); our @APACHE_SERVICES = ( - 'httpd.admin', 'httpd.webservices', 'httpd.portal' + 'httpd.admin', 'httpd.webservices', 'httpd.portal', 'httpd.proxy' ); our @ALL_SERVICES = ( diff --git a/lib/pf/services/manager/httpd_proxy.pm b/lib/pf/services/manager/httpd_proxy.pm new file mode 100644 index 000000000000..1f92d69aa934 --- /dev/null +++ b/lib/pf/services/manager/httpd_proxy.pm @@ -0,0 +1,57 @@ +package pf::services::manager::httpd_proxy; +=head1 NAME + +pf::services::manager::httpd_proxy add documentation + +=cut + +=head1 DESCRIPTION + +pf::services::manager::httpd_proxy + +=cut + +use strict; +use warnings; +use Moo; +use pf::config; +use pf::util; + +extends 'pf::services::manager::httpd'; + +has '+name' => (default => sub { 'httpd.proxy' } ); + +sub isManaged { + return isenabled($Config{'trapping'}{'interception_proxy'}); +} + +=head1 AUTHOR + +Inverse inc. + + +=head1 COPYRIGHT + +Copyright (C) 2005-2013 Inverse inc. + +=head1 LICENSE + +This program is free software; you can redistribute it and::or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +USA. + +=cut + +1; + From bea183a92377f9c0665cf4dc231e8f580dd738b1 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Tue, 1 Oct 2013 14:31:49 -0400 Subject: [PATCH 291/369] Avoid printing double headers on restart --- bin/pfcmd.pl | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/bin/pfcmd.pl b/bin/pfcmd.pl index 1961d799cd34..15388ffa1820 100755 --- a/bin/pfcmd.pl +++ b/bin/pfcmd.pl @@ -79,6 +79,8 @@ =head1 SYNOPSIS use pf::util; use HTTP::Status qw(is_success); use List::MoreUtils qw(all true); +use Term::ANSIColor; +use IO::Interactive qw(is_interactive); # Perl taint mode setup (see: perlsec) delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; @@ -105,6 +107,10 @@ =head1 SYNOPSIS restart => \&restartService, ); +our $SERVICE_HEADER ="service|command\n"; + +our $IS_INTERACTIVE = is_interactive(); + my $count = $ENV{PER_PAGE}; my $offset = $ENV{PAGE_NUM}; @@ -1173,7 +1179,7 @@ sub service { sub startService { my ($service) = @_; my @managers = getStartServiceManagers($service); - print "service|command\n"; + print $SERVICE_HEADER; my $count = 0; if(isIptablesManaged($service)) { $logger->info("saving current iptables to var/iptables.bak"); @@ -1237,7 +1243,7 @@ sub _getStartServiceManagers { sub stopService { my ($service) = @_; my @managers = getStopServiceManagers($service); - print "service|command\n"; + print $SERVICE_HEADER; foreach my $manager (@managers) { my $command; if($manager->status eq '0') { @@ -1290,6 +1296,7 @@ sub _getStopServiceManagers { sub restartService { my ($service) = @_; stopService($service); + local $SERVICE_HEADER = ''; startService($service); } @@ -1312,7 +1319,7 @@ sub watchService { pfmailer(%message); } if ( isenabled( $Config{'servicewatch'}{'restart'} ) ) { - print "service|command\n"; + print $SERVICE_HEADER; foreach my $manager (@stoppedServiceManagers) { $manager->watch; print join('|',$manager->name,"watch"),"\n"; From 0e15324af0f258f0f7ba30557ccdc90ed29b5c4a Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Tue, 1 Oct 2013 15:14:35 -0400 Subject: [PATCH 292/369] Removed unused variables --- lib/pf/services.pm | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lib/pf/services.pm b/lib/pf/services.pm index 90f28491a643..5d2279c16827 100644 --- a/lib/pf/services.pm +++ b/lib/pf/services.pm @@ -50,14 +50,6 @@ our @ALL_SERVICES = ( 'snmptrapd', 'pfsetvlan', 'pfdhcplistener', 'pfmon' ); -my $services = join("|", @ALL_SERVICES); -our $ALL_BINARIES_RE => qr/$services - |apache2 # httpd on debian - |freeradius # radiusd on debian - |httpd.worker # mpm_worker apache version - |httpd -$/x; - our %ALLOWED_ACTIONS = ( stop => undef, start => undef, From ac0e21faa2f9f06712adfddba398581fe56ff308 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 3 Oct 2013 18:01:05 -0400 Subject: [PATCH 293/369] refactor the creation of the cmdline to a seperate function --- lib/pf/services/manager.pm | 54 +++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/lib/pf/services/manager.pm b/lib/pf/services/manager.pm index b7985ee65eeb..d7456437f091 100644 --- a/lib/pf/services/manager.pm +++ b/lib/pf/services/manager.pm @@ -130,7 +130,7 @@ Starts the service sub startService { my ($self,$quick) = @_; - return $self->launchService($self->executable); + return $self->launchService; } =head2 postStartCleanup @@ -326,25 +326,47 @@ launch the service using the launcher and arguements passed =cut sub launchService { - my ($self,@launcher_args) = @_; - my $launcher = $self->launcher; - if ($launcher) { - my $name = $self->name; - my $logger = get_logger; - my $cmd_line = sprintf($launcher, map { /^(.*)$/;$1 } @launcher_args); - $logger->info("Starting $name with '$cmd_line'"); - if ($cmd_line =~ /^(.+)$/) { - $cmd_line = $1; - my $t0 = Time::HiRes::time(); - my $return_value = system($cmd_line); - my $elapsed = Time::HiRes::time() - $t0; - $logger->info(sprintf("Daemon %s took %.3f seconds to start.", $name, $elapsed)); - return $return_value == 0; - } + my ($self) = @_; + my $cmdLine = $self->_cmdLine; + if ($cmdLine =~ /^(.+)$/) { + $cmdLine = $1; + my $logger = get_logger(); + my $t0 = Time::HiRes::time(); + my $return_value = system($cmdLine); + my $elapsed = Time::HiRes::time() - $t0; + $logger->info(sprintf("Daemon %s took %.3f seconds to start.", $self->name, $elapsed)); + return $return_value == 0; } return; } +=head2 _cmdLine + +TODO: documention + +=cut + +sub _cmdLine { + my ($self) = @_; + my $launcher = $self->launcher; + my @cmdLineArgs = $self->_cmdLineArgs; + my $cmdLine = sprintf($launcher, map { /^(.*)$/;$1 } @cmdLineArgs); + return $cmdLine; +} + + +=head2 _cmdLineArgs + +TODO: documention + +=cut + +sub _cmdLineArgs { + my ($self) = @_; + return ($self->executable); +} + + =head2 pidFile return the pid file of the service From 7035b857e7dd3145349a8145b610b4aa22c168bf Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 3 Oct 2013 20:08:26 -0400 Subject: [PATCH 294/369] Refactor stop watch generateConfig startService postStartCleanup to a generalized around modifier Overloaded removeStalePid to call removeStalePid on submanagers --- lib/pf/services/manager/submanager.pm | 37 ++++++++------------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/lib/pf/services/manager/submanager.pm b/lib/pf/services/manager/submanager.pm index 512292edb012..04a5d9114cb6 100644 --- a/lib/pf/services/manager/submanager.pm +++ b/lib/pf/services/manager/submanager.pm @@ -31,43 +31,28 @@ sub managers { return (); } -=head2 start +=head2 generateConfig startService postStartCleanup stop watch -start all the sub managers +Delegating generateConfig startService postStartCleanup stop watch to sub managers =cut -sub start { - my ($self,$quick) = @_; +around [qw(generateConfig startService postStartCleanup watch stop)] => sub { + my ($orig,$self,$quick) = @_; my $count; - my $pass = true {$count++; $_->start($quick) } $self->managers; + my $pass = true {$count++; $_->$orig($quick) } $self->managers; return $pass == $count; -} +}; -=head2 stop +=head2 removeStalePid -stop all the sub managers +Delegating removeStalePid to sub managers =cut -sub stop { - my ($self,$quick) = @_; - my $count; - my $pass = true {$count++; $_->stop($quick) } $self->managers; - return $pass == $count; -} - -=head2 watch - -watch all the sub managers - -=cut - -sub watch { - my ($self,$quick) = @_; - my $count; - my $pass = true {$count++; $_->watch($quick) } $self->managers; - return $pass == $count; +sub removeStalePid { + my ($self) = @_; + $_->removeStalePid foreach $self->managers; } =head2 status From 8256bd6cad292889fb33f631fcb0d992a7f1c260 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Fri, 4 Oct 2013 12:46:42 -0400 Subject: [PATCH 295/369] pfcmd service now has color --- bin/pfcmd.pl | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/bin/pfcmd.pl b/bin/pfcmd.pl index 15388ffa1820..2086046500fa 100755 --- a/bin/pfcmd.pl +++ b/bin/pfcmd.pl @@ -1197,14 +1197,23 @@ sub startService { foreach my $manager (@managers) { my $command; + my $color = ''; if($manager->status ne '0') { + $color = color 'yellow' if $IS_INTERACTIVE; $command = 'already started'; } else { - $manager->start; - $command = 'start'; + if($manager->start) { + $command = 'start'; + $color = color 'green' if $IS_INTERACTIVE; + } else { + $command = 'not started'; + $color = color 'red' if $IS_INTERACTIVE; + } } - print join('|',$manager->name,$command),"\n"; + print $manager->name,"|${color}$command\n"; + print color 'reset' if $IS_INTERACTIVE; } + print color 'reset' if $IS_INTERACTIVE; return 0; } @@ -1246,13 +1255,20 @@ sub stopService { print $SERVICE_HEADER; foreach my $manager (@managers) { my $command; + my $color = ''; if($manager->status eq '0') { $command = 'already stopped'; + $color = color 'yellow' if $IS_INTERACTIVE; } else { - $manager->stop; - $command = 'stop'; + if($manager->stop) { + $color = color 'green' if $IS_INTERACTIVE; + $command = 'stop'; + } else { + $color = color 'red' if $IS_INTERACTIVE; + } } - print join('|',$manager->name,$command),"\n"; + print $manager->name,"|${color}$command\n"; + print color 'reset' if $IS_INTERACTIVE; } if(isIptablesManaged($service)) { my $count = true { $_->status eq '0' } @managers; @@ -1336,10 +1352,21 @@ sub statusOfService { print "service|shouldBeStarted|pid\n"; my $notStarted = 0; foreach my $manager (@managers) { + my $color = ''; my $isManaged = $manager->isManaged; my $status = $manager->status; - print join('|',$manager->name,$isManaged,$status),"\n"; - $notStarted++ if $status eq '0' && $isManaged; + if($status eq '0' ) { + if ($isManaged) { + $color = color 'red' if $IS_INTERACTIVE; + $notStarted++; + } else { + $color = color 'yellow' if $IS_INTERACTIVE; + } + } else { + $color = color 'green' if $IS_INTERACTIVE; + } + print $manager->name,"|${color}$isManaged|$status\n"; + print color 'reset' if $IS_INTERACTIVE; } return ( $notStarted ? 3 : 0); } From ecb706a659955d04f1d1a43b5ea1a2cb7b8ce7b9 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Fri, 4 Oct 2013 14:36:45 -0400 Subject: [PATCH 296/369] Added new perl modules --- addons/packages/packetfence.spec | 2 ++ debian/control | 1 + 2 files changed, 3 insertions(+) diff --git a/addons/packages/packetfence.spec b/addons/packages/packetfence.spec index b01926904354..fc0de1a345c3 100644 --- a/addons/packages/packetfence.spec +++ b/addons/packages/packetfence.spec @@ -224,6 +224,8 @@ Requires: perl(Moo) >= 1.0 Requires: perl(Term::ANSIColor) Requires: perl(IO::Interactive) Requires: perl(Module::Loaded) +Requires: perl(Linux::FD) +Requires: perl(File::Touch) # configuration-wizard Requires: iproute, vconfig # diff --git a/debian/control b/debian/control index cb5bac368984..ee0ae82bab43 100644 --- a/debian/control +++ b/debian/control @@ -53,6 +53,7 @@ Depends: ${misc:Depends}, vlan, make, libiptables-libiptc-perl, libload-perl, libmime-lite-tt-perl, libmime-lite-perl, libconfig-general-perl, libproc-processtable-perl, libfile-flock-perl, libperl-version-perl, perl-modules, + liblinux-fd-perl, libfile-touch-perl # hard-coded to specific version because v3 broke the API and we haven't ported to it yet # see #1313: Port our Net-Appliance-Session to the version 3 API # http://packetfence.org/bugs/view.php?id=1313 From bf51c3cbdb088e96adf8979e8e8d5110c95c16e2 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Tue, 15 Oct 2013 14:30:35 -0400 Subject: [PATCH 297/369] Moved to use timerfd for timeouts --- lib/pf/services/manager.pm | 100 +++++++++++++++++++++++++------------ 1 file changed, 69 insertions(+), 31 deletions(-) diff --git a/lib/pf/services/manager.pm b/lib/pf/services/manager.pm index d7456437f091..0df6df4af3c7 100644 --- a/lib/pf/services/manager.pm +++ b/lib/pf/services/manager.pm @@ -24,7 +24,8 @@ use Proc::ProcessTable; use List::Util qw(first); use Linux::Inotify2; use Errno qw(EINTR EAGAIN); -use Time::HiRes qw (alarm sleep); +use Time::HiRes qw (alarm); +use Linux::FD::Timer; =head1 Attributes @@ -99,7 +100,7 @@ start the service sub start { my ($self,$quick) = @_; my $result = 0; - unless ($self->pid) { + unless ($self->status) { if( $self->preStartSetup($quick)) { if($self->startService($quick)) { $result = $self->postStartCleanup($quick); @@ -119,6 +120,7 @@ sub preStartSetup { my ($self,$quick) = @_; $self->removeStalePid; $self->generateConfig($quick) unless $quick; + $self->_setupWatchForPidCreate; return 1; } @@ -141,35 +143,48 @@ Cleanup work after the starting the service sub postStartCleanup { my ($self,$quick) = @_; - my $run_dir = "$var_dir/run"; my $pidFile = $self->pidFile; my $result = 0; + my $inotify = $self->inotify; unless (-e $pidFile) { - my $inotify = $self->inotify; - $inotify->watch ($run_dir, IN_CREATE, sub { - my $e = shift; - my $name = $e->fullname; - if($pidFile eq $name) { - $e->w->cancel; - } - }); my $timedout; eval { local $SIG{ALRM} = sub { die "alarm clock restart" }; alarm 60; eval { - 1 while !-e $pidFile && $inotify->poll; + 1 while $inotify->poll && !-e $pidFile; }; alarm 0; $timedout = 1 if $@ && $@ =~ /^alarm clock restart/; }; + alarm 0; my $logger = get_logger; $logger->warn($self->name . " timed out trying to start" ) if $timedout; - alarm 0; } return -e $pidFile; } + +=head2 _setupWatchForPidCreate + +This setups a watch on the run directory to wait for the pid to + +=cut + +sub _setupWatchForPidCreate { + my ($self) = @_; + my $inotify = $self->inotify; + my $pidFile = $self->pidFile; + my $run_dir = "$var_dir/run"; + $inotify->watch ($run_dir, IN_CREATE, sub { + my $e = shift; + my $name = $e->fullname; + if($pidFile eq $name) { + $e->w->cancel; + } + }); +} + =head2 _build_executable the builder the executable attribute @@ -250,6 +265,23 @@ sub preStopSetup { $self->inotify->watch($self->pidFile, IN_DELETE_SELF); } +=head2 stopService + +=cut + +sub stopService { + my ($self) = @_; + my $name = $self->name; + my $logger = get_logger(); + my $pid = $self->lastPid; + $logger->info("Sending TERM signal to $name with pid $pid"); + my $count = kill 'TERM',$pid; +} + +=head2 postStopCleanup + +=cut + sub postStopCleanup { my ($self) = @_; my $logger = get_logger(); @@ -259,9 +291,11 @@ sub postStopCleanup { my $pidFile = $self->pidFile; my $timedout; #give the kill a little time - sleep(0.1); $inotify->blocking(0); $self->removeStalePid; + my $timer = Linux::FD::Timer->new('monotonic'); + $timer->set_timeout(0.1,0.1); + $timer->receive; eval { local $SIG{ALRM} = sub { die "alarm clock restart" }; alarm 60; @@ -270,7 +304,7 @@ sub postStopCleanup { die $! if defined $! && $! != EINTR && $! != EAGAIN; $self->removeStalePid; #give it some time - select(undef, undef, undef, 0.1); + $timer->receive; } }; alarm 0; @@ -279,21 +313,10 @@ sub postStopCleanup { }; alarm 0; $logger->info("Timed out waiting for process $name to stop") if $timedout; - $self->removeStalePid; - my $still_alive = kill 0 , $pid; - if ( $still_alive ) { - my $count = kill 'KILL',$pid; - $self->removeStalePid; + if ($self->isAlive($pid)) { + kill 'KILL',$pid; } -} - -sub stopService { - my ($self) = @_; - my $name = $self->name; - my $logger = get_logger(); - my $pid = $self->lastPid; - $logger->info("Sending TERM signal to $name with pid $pid"); - my $count = kill 'TERM',$pid; + $self->removeStalePid; } =head2 watch @@ -418,14 +441,29 @@ sub removeStalePid { if($pid && $pid =~ /^(.*)$/) { $pid = $1; $logger->info("verifying process $pid"); - my $result = kill(0, $pid); + my $result = $self->isAlive; unless ($result) { $logger->info("removing stale pid file $pidFile"); - unlink $pidFile; + unlink $pidFile if -e $pidFile; } } } +=head2 isAlive + +checks if process is alive + +=cut + +sub isAlive { + my ($self,$pid) = @_; + my $result; + $pid = $self->pid unless defined $pid; + $result = kill 0 , $pid if $pid; + return $result; +} + + =head2 isManaged return true is the service is currently managed by packetfence From c9e9140e218a09bf66a694b9a5b91494c0e63115 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Tue, 15 Oct 2013 14:32:47 -0400 Subject: [PATCH 298/369] Group the sub pfhcplistener pidfiles in one inotify object --- lib/pf/services/manager/pfdhcplistener.pm | 51 ++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/lib/pf/services/manager/pfdhcplistener.pm b/lib/pf/services/manager/pfdhcplistener.pm index 230f9d3b5564..5ddd73c4bd5a 100644 --- a/lib/pf/services/manager/pfdhcplistener.pm +++ b/lib/pf/services/manager/pfdhcplistener.pm @@ -16,10 +16,15 @@ use warnings; use Moo; use pf::config; use pf::util; +use List::MoreUtils qw(any all); +use Linux::Inotify2; +use pf::log; extends 'pf::services::manager::submanager'; -has pfdhcplistenerManagers => (is => 'rw', builder => 1 ); +has pfdhcplistenerManagers => (is => 'rw', builder => 1, lazy => 1); + +has _pidFiles => (is => 'rw', default => sub { {} } ); has '+name' => (default => sub { 'pfdhcplistener'} ); @@ -35,6 +40,50 @@ sub _build_pfdhcplistenerManagers { return \@managers; } +=head2 _setupWatchForPidCreate + +Setting up inotify to watch for the creation of pidFiles for each pfdhcplistener instance + +=cut + +sub _setupWatchForPidCreate { + my ($self) = @_; + my $inotify = $self->inotify; + my @pidFiles = map { $_->pidFile } $self->managers; + my $run_dir = "$var_dir/run"; + $inotify->watch ($run_dir, IN_CREATE, sub { + my $e = shift; + if(all { -e $_ } @pidFiles) { + my $name = $e->fullname; + @pidFiles = grep { $_ ne $name } @pidFiles; + $e->w->cancel unless @pidFiles; + } + }); +} + +sub postStartCleanup { + my ($self,$quick) = @_; + my $pidFile = $self->pidFile; + my $result = 0; + my $inotify = $self->inotify; + my @pidFiles = map { $_->pidFile } $self->managers; + my $logger = get_logger; + unless (-e $pidFile) { + my $timedout; + eval { + local $SIG{ALRM} = sub { die "alarm clock restart" }; + alarm 60; + eval { + 1 while $inotify->poll; + }; + alarm 0; + $timedout = 1 if $@ && $@ =~ /^alarm clock restart/; + }; + alarm 0; + $logger->warn($self->name . " timed out trying to start" ) if $timedout; + } + return all { -e $_ } @pidFiles; +} sub managers { my ($self) = @_; From ddbeadff8812299796fd63e068552e8194a71e52 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Fri, 18 Oct 2013 11:51:39 -0400 Subject: [PATCH 299/369] Refactor get(Stop|Start)ServiceManagers to getManagers --- bin/pfcmd.pl | 103 ++++++++++++++++++++++++--------------------------- 1 file changed, 48 insertions(+), 55 deletions(-) diff --git a/bin/pfcmd.pl b/bin/pfcmd.pl index 2086046500fa..62d342b5be4c 100755 --- a/bin/pfcmd.pl +++ b/bin/pfcmd.pl @@ -69,7 +69,11 @@ =head1 SYNOPSIS use Log::Log4perl; use Try::Tiny; -use constant INSTALL_DIR => '/usr/local/pf'; +use constant { + INSTALL_DIR => '/usr/local/pf', + JUST_MANAGED => 1, + INCLUDE_DEPENDS_ON => 2, +}; use lib INSTALL_DIR . "/lib"; @@ -79,6 +83,7 @@ =head1 SYNOPSIS use pf::util; use HTTP::Status qw(is_success); use List::MoreUtils qw(all true); +use List::Util qw(first); use Term::ANSIColor; use IO::Interactive qw(is_interactive); @@ -1171,14 +1176,20 @@ sub service { if(exists $ACTION_MAP{$action} && defined ($actionHandler = $ACTION_MAP{$action})) { $service =~ /^(.*)$/; $service = $1; - return $actionHandler->($service); + my @services; + if($service eq 'pf') { + @services = @pf::services::ALL_SERVICES; + } else { + @services = ($service); + } + return $actionHandler->($service,@services); } return $FALSE; } sub startService { - my ($service) = @_; - my @managers = getStartServiceManagers($service); + my ($service,@services) = @_; + my @managers = getManagers(\@services,INCLUDE_DEPENDS_ON | JUST_MANAGED); print $SERVICE_HEADER; my $count = 0; if(isIptablesManaged($service)) { @@ -1217,41 +1228,45 @@ sub startService { return 0; } -sub getIptablesTechnique { - require pf::inline::custom; - my $iptables = pf::inline::custom->new(); - return $iptables->{_technique}; -} - -sub getStartServiceManagers { - my ($service) = @_; - my @services; - if($service eq 'pf') { - @services = pf::services::service_list(@pf::services::ALL_SERVICES); - } else { - @services = ($service); - } - return _getStartServiceManagers(@services); -} - -sub _getStartServiceManagers { +sub getManagers { + my ($services,$flags) = @_; + $flags = 0 unless defined $flags; my %seen; + my $includeDependsOn = $flags & INCLUDE_DEPENDS_ON; + my $justManaged = $flags & JUST_MANAGED; my @serviceManagers = - grep { (!exists $seen{$_->name}) && ($seen{$_->name} = 1) } + grep { (!exists $seen{$_->name}) && ($seen{$_->name} = 1) && ( !$justManaged || $_->isManaged ) } map { my $m = $_; - my @managers = map { pf::services::get_service_manager($_) } @{$m->dependsOnServices}; + my @managers = + grep { defined $_ } + map { pf::services::get_service_manager($_) } + @{$m->dependsOnServices} + if $includeDependsOn; push @managers,$m; @managers } grep { defined $_ } - map { pf::services::get_service_manager($_) } @_; + map { pf::services::get_service_manager($_) } @$services; return @serviceManagers; } +sub getIptablesTechnique { + require pf::inline::custom; + my $iptables = pf::inline::custom->new(); + return $iptables->{_technique}; +} + sub stopService { - my ($service) = @_; - my @managers = getStopServiceManagers($service); + my ($service,@services) = @_; + my @managers = getManagers(\@services); + #push memcached to back of the list + my $manager = first { $_->name eq 'memcached' } @managers; + if($manager) { + @managers = grep { $_->name ne 'memcached' } @managers; + push @managers, $manager; + } + print $SERVICE_HEADER; foreach my $manager (@managers) { my $command; @@ -1288,39 +1303,17 @@ sub isIptablesManaged { return $_[0] eq 'pf' && isenabled($Config{services}{iptables}) } -sub getStopServiceManagers { - my ($service) = @_; - my @services; - if($service eq 'pf') { - @services = grep { $_ ne 'memcached' } @pf::services::ALL_SERVICES; - push @services,'memcached'; - } else { - @services = ($service); - } - return _getStopServiceManagers(@services); -} - -sub _getStopServiceManagers { - my %seen; - my @serviceManagers = - grep { defined ($_) && (!exists $seen{$_->name}) && ($seen{$_->name} = 1) } - map { pf::services::get_service_manager($_) } @_; - return @serviceManagers; -} - - sub restartService { - my ($service) = @_; - stopService($service); + stopService(@_); local $SERVICE_HEADER = ''; - startService($service); + startService(@_); } sub watchService { - my ($service) = @_; + my ($service,@services) = @_; my @stoppedServiceManagers = grep { $_->status eq '0' } - getStartServiceManagers($service); + getManagers(\@services, JUST_MANAGED | INCLUDE_DEPENDS_ON); if(@stoppedServiceManagers) { my @stoppedServices = map { $_->name } @stoppedServiceManagers; $logger->info("watch found incorrectly stopped services: " . join(", ", @stoppedServices)); @@ -1347,8 +1340,8 @@ sub watchService { } sub statusOfService { - my ($service) = @_; - my @managers = getStopServiceManagers($service); + my ($service,@services) = @_; + my @managers = getManagers(\@services); print "service|shouldBeStarted|pid\n"; my $notStarted = 0; foreach my $manager (@managers) { From 4e5e385bd1f083cba886b7f83e37bb85e53df8fa Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Mon, 18 Nov 2013 13:32:36 -0500 Subject: [PATCH 300/369] Add dependency to Linux::Inotify2 --- addons/packages/packetfence.spec | 1 + debian/control | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/packages/packetfence.spec b/addons/packages/packetfence.spec index fc0de1a345c3..2d6e844b9cd2 100644 --- a/addons/packages/packetfence.spec +++ b/addons/packages/packetfence.spec @@ -225,6 +225,7 @@ Requires: perl(Term::ANSIColor) Requires: perl(IO::Interactive) Requires: perl(Module::Loaded) Requires: perl(Linux::FD) +Requires: perl(Linux::Inotify2) Requires: perl(File::Touch) # configuration-wizard Requires: iproute, vconfig diff --git a/debian/control b/debian/control index ee0ae82bab43..406ae1aa3936 100644 --- a/debian/control +++ b/debian/control @@ -53,7 +53,7 @@ Depends: ${misc:Depends}, vlan, make, libiptables-libiptc-perl, libload-perl, libmime-lite-tt-perl, libmime-lite-perl, libconfig-general-perl, libproc-processtable-perl, libfile-flock-perl, libperl-version-perl, perl-modules, - liblinux-fd-perl, libfile-touch-perl + liblinux-fd-perl, liblinux-inotify2-perl, libfile-touch-perl, # hard-coded to specific version because v3 broke the API and we haven't ported to it yet # see #1313: Port our Net-Appliance-Session to the version 3 API # http://packetfence.org/bugs/view.php?id=1313 From 2d42b20f64c0621390e4e3b23ae3e3e6a66f32c6 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 20 Nov 2013 12:43:24 -0500 Subject: [PATCH 301/369] Fixed configuration generation for httpd based services --- lib/pf/services/manager/httpd.pm | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/lib/pf/services/manager/httpd.pm b/lib/pf/services/manager/httpd.pm index baf3fa66f92f..a6f4b57c04e3 100644 --- a/lib/pf/services/manager/httpd.pm +++ b/lib/pf/services/manager/httpd.pm @@ -15,6 +15,7 @@ use strict; use warnings; use pf::config; use Moo; +use pf::services::apache; extends 'pf::services::manager'; has '+launcher' => ( builder => 1, lazy => 1 ); @@ -31,6 +32,22 @@ sub _build_launcher { return "%1\$s -f $conf_dir/httpd.conf.d/$name -D$OS" } +=head2 generateConfig + +TODO: documention + +=cut + +our $WAS_GENERATED; + +sub generateConfig { + my ($self) = @_; + return 1 if $WAS_GENERATED; + pf::services::apache::generate_httpd_conf(); + $WAS_GENERATED = 1; + return 1; +} + =head1 AUTHOR Inverse inc. From a50db5ac614c083bbb12bb7bc23d647eb0a57e4b Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 27 Nov 2013 11:49:15 -0500 Subject: [PATCH 302/369] Untaint launcher before passing it to sprintf --- lib/pf/services/manager.pm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/pf/services/manager.pm b/lib/pf/services/manager.pm index 0df6df4af3c7..41b0e51fd9ce 100644 --- a/lib/pf/services/manager.pm +++ b/lib/pf/services/manager.pm @@ -372,7 +372,9 @@ TODO: documention sub _cmdLine { my ($self) = @_; my $launcher = $self->launcher; - my @cmdLineArgs = $self->_cmdLineArgs; + $launcher =~ /^(.*)$/; + $launcher = $1; + my @cmdLineArgs = map { /^(.*)$/;$1 } $self->_cmdLineArgs; my $cmdLine = sprintf($launcher, map { /^(.*)$/;$1 } @cmdLineArgs); return $cmdLine; } From 0c4e5119222189bbc70786285dd2dca6824f6e07 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 27 Nov 2013 12:03:07 -0500 Subject: [PATCH 303/369] Refactor reset --- bin/pfcmd.pl | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/bin/pfcmd.pl b/bin/pfcmd.pl index 62d342b5be4c..348f0665ca3e 100755 --- a/bin/pfcmd.pl +++ b/bin/pfcmd.pl @@ -116,6 +116,8 @@ =head1 SYNOPSIS our $IS_INTERACTIVE = is_interactive(); +our $RESET_COLOR = $IS_INTERACTIVE ? color 'reset' : ''; + my $count = $ENV{PER_PAGE}; my $offset = $ENV{PAGE_NUM}; @@ -1221,10 +1223,8 @@ sub startService { $color = color 'red' if $IS_INTERACTIVE; } } - print $manager->name,"|${color}$command\n"; - print color 'reset' if $IS_INTERACTIVE; + print $manager->name,"|${color}${command}${RESET_COLOR}\n"; } - print color 'reset' if $IS_INTERACTIVE; return 0; } @@ -1282,8 +1282,7 @@ sub stopService { $color = color 'red' if $IS_INTERACTIVE; } } - print $manager->name,"|${color}$command\n"; - print color 'reset' if $IS_INTERACTIVE; + print $manager->name,"|${color}${command}${RESET_COLOR}\n"; } if(isIptablesManaged($service)) { my $count = true { $_->status eq '0' } @managers; @@ -1358,8 +1357,7 @@ sub statusOfService { } else { $color = color 'green' if $IS_INTERACTIVE; } - print $manager->name,"|${color}$isManaged|$status\n"; - print color 'reset' if $IS_INTERACTIVE; + print $manager->name,"|${color}$isManaged|$status${RESET_COLOR}\n"; } return ( $notStarted ? 3 : 0); } From 74032b9b3b5fc943d436ff25714791fc52621feb Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 27 Nov 2013 12:03:18 -0500 Subject: [PATCH 304/369] Display better message when a service was not stopped --- bin/pfcmd.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/pfcmd.pl b/bin/pfcmd.pl index 348f0665ca3e..25440caa03eb 100755 --- a/bin/pfcmd.pl +++ b/bin/pfcmd.pl @@ -1280,6 +1280,7 @@ sub stopService { $command = 'stop'; } else { $color = color 'red' if $IS_INTERACTIVE; + $command = 'not stopped'; } } print $manager->name,"|${color}${command}${RESET_COLOR}\n"; From 18ce0dcfd6ce4d30fad6994f2949cd45163f178b Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 27 Nov 2013 12:04:16 -0500 Subject: [PATCH 305/369] Return value of the parent stop command --- lib/pf/services/manager/dhcpd.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pf/services/manager/dhcpd.pm b/lib/pf/services/manager/dhcpd.pm index 6c33a748a903..1ede91e7bcc8 100644 --- a/lib/pf/services/manager/dhcpd.pm +++ b/lib/pf/services/manager/dhcpd.pm @@ -24,7 +24,6 @@ use IPC::Cmd qw[can_run run]; extends 'pf::services::manager'; with 'pf::services::manager::roles::is_managed_by_pf_conf'; with 'pf::services::manager::roles::is_managed_vlan_inline_enforcement'; - has '+name' => (default => sub { 'dhcpd' } ); has '+launcher' => (default => sub { "sudo %1\$s -lf $var_dir/dhcpd/dhcpd.leases -cf $generated_conf_dir/dhcpd.conf -pf $var_dir/run/dhcpd.pid " . join(" ", @listen_ints) } ); @@ -45,8 +44,9 @@ sub preStartSetup { sub stop { my ($self,$quick) = @_; - $self->SUPER::stop($quick); + my $result = $self->SUPER::stop($quick); manageStaticRoute(); + return $result; } sub manageStaticRoute { From d9ebfb6a1fd03e571b7c899a6a430c5a54f8e5bf Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 28 Nov 2013 13:18:53 -0500 Subject: [PATCH 306/369] Added new attribute shouldCheckup --- lib/pf/services/manager.pm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/pf/services/manager.pm b/lib/pf/services/manager.pm index 41b0e51fd9ce..c38da2dfbd9f 100644 --- a/lib/pf/services/manager.pm +++ b/lib/pf/services/manager.pm @@ -37,6 +37,14 @@ name of service has name => ( is => 'rw'); +=head2 shouldCheckup + +if service requires checkup + +=cut + +has shouldCheckup => ( is => 'rw', default => sub { 1 } ); + =head2 launcher sprintf-formatted string that control how the services should be started From 0d425e475c0bcb91cebf0db968c451a88fbb6ca7 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 28 Nov 2013 13:19:35 -0500 Subject: [PATCH 307/369] Setup attribute shouldCheckup to 0 --- lib/pf/services/manager/httpd_admin.pm | 2 ++ lib/pf/services/manager/memcached.pm | 2 ++ 2 files changed, 4 insertions(+) diff --git a/lib/pf/services/manager/httpd_admin.pm b/lib/pf/services/manager/httpd_admin.pm index 037049aa6366..fd12cf774c40 100644 --- a/lib/pf/services/manager/httpd_admin.pm +++ b/lib/pf/services/manager/httpd_admin.pm @@ -19,6 +19,8 @@ extends 'pf::services::manager::httpd'; has '+name' => (default => sub { 'httpd.admin' } ); +has '+shouldCheckup' => ( default => sub { 0 } ); + =head1 AUTHOR Inverse inc. diff --git a/lib/pf/services/manager/memcached.pm b/lib/pf/services/manager/memcached.pm index 7f065ddf5899..a10e7cd601a6 100644 --- a/lib/pf/services/manager/memcached.pm +++ b/lib/pf/services/manager/memcached.pm @@ -23,6 +23,8 @@ has '+name' => (default => sub { 'memcached' } ); has '+launcher' => (default => sub { "%1\$s -d -p 11211 -u pf -m 64 -c 1024 -P $install_dir/var/run/memcached.pid"}); +has '+shouldCheckup' => ( default => sub { 0 } ); + =head1 AUTHOR Inverse inc. From 7fce2e5e5bead1614f8982d723067bccb9bb643a Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 28 Nov 2013 13:21:23 -0500 Subject: [PATCH 308/369] Start service that require no checkup before service that require checkup --- bin/pfcmd.pl | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/bin/pfcmd.pl b/bin/pfcmd.pl index 25440caa03eb..126202726e5c 100755 --- a/bin/pfcmd.pl +++ b/bin/pfcmd.pl @@ -68,6 +68,7 @@ =head1 SYNOPSIS use File::Basename qw(basename); use Log::Log4perl; use Try::Tiny; +use List::MoreUtils qw(part); use constant { INSTALL_DIR => '/usr/local/pf', @@ -1204,30 +1205,42 @@ sub startService { $technique ||= getIptablesTechnique(); $technique->iptables_generate(); } + require pf::pfcmd::checkup; import pf::pfcmd::checkup; - checkup( map {$_->name} @managers); + my ($noCheckupManagers,$checkupManagers) = part { $_->shouldCheckup} @managers; + foreach my $manager (@$noCheckupManagers) { + _doStart($manager); + } + if(@$checkupManagers) { + checkup( map {$_->name} @$checkupManagers); - foreach my $manager (@managers) { - my $command; - my $color = ''; - if($manager->status ne '0') { - $color = color 'yellow' if $IS_INTERACTIVE; - $command = 'already started'; - } else { - if($manager->start) { - $command = 'start'; - $color = color 'green' if $IS_INTERACTIVE; - } else { - $command = 'not started'; - $color = color 'red' if $IS_INTERACTIVE; - } + foreach my $manager (@$checkupManagers) { + _doStart($manager); } - print $manager->name,"|${color}${command}${RESET_COLOR}\n"; } return 0; } +sub _doStart { + my ($manager) = @_; + my $command; + my $color = ''; + if($manager->status ne '0') { + $color = color 'yellow' if $IS_INTERACTIVE; + $command = 'already started'; + } else { + if($manager->start) { + $command = 'start'; + $color = color 'green' if $IS_INTERACTIVE; + } else { + $command = 'not started'; + $color = color 'red' if $IS_INTERACTIVE; + } + } + print $manager->name,"|${color}${command}${RESET_COLOR}\n"; +} + sub getManagers { my ($services,$flags) = @_; $flags = 0 unless defined $flags; From ba94b86e0f6e080b523b087b6289288bf463cf23 Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Thu, 28 Nov 2013 16:23:21 -0500 Subject: [PATCH 309/369] Fixed AeroHive trap --- lib/pf/SNMP/AeroHIVE.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pf/SNMP/AeroHIVE.pm b/lib/pf/SNMP/AeroHIVE.pm index dced9439df63..4143ea539fd3 100644 --- a/lib/pf/SNMP/AeroHIVE.pm +++ b/lib/pf/SNMP/AeroHIVE.pm @@ -111,6 +111,7 @@ sub parseTrap { $valeurs{$oid} = $value; } $trapHashRef->{'trapSSID'} = $valeurs{$AEROHIVE::ahSSID}; + $trapHashRef->{'trapSSID'} =~ s/"//g; $trapHashRef->{'trapIfIndex'} = $valeurs{$AEROHIVE::ahIfIndex}; $trapHashRef->{'trapVlan'} = $valeurs{$AEROHIVE::ahClientVLAN}; $trapHashRef->{'trapMac'} = $valeurs{$AEROHIVE::ahRemoteId}; From 7a575d768d20d94b2d307142862e085689c151f0 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Fri, 29 Nov 2013 09:20:05 -0500 Subject: [PATCH 310/369] Use prototype Delay method to respect seconds We were using the standard setTimeout function which expects miliseconds, not seconds. --- html/common/pf.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/html/common/pf.js b/html/common/pf.js index e450ead2dec6..6672db13941b 100644 --- a/html/common/pf.js +++ b/html/common/pf.js @@ -62,7 +62,7 @@ function networkAccessCallback(destination_url, redirect_url) { } // Chrome 10 / Safari 5 / IE9 (sometimes) flawless - top.location.replace(destination_url.unescapeHTML()); + performRedirect(destination_url); } /** @@ -96,9 +96,9 @@ Date.now = Date.now || function() { return +new Date; }; function detectNetworkAccess(retry_delay, destination_url, redirect_url, external_ip) { "use strict"; - var errorDetected; - var loaded; - var netdetect = $('netdetect'); + var errorDetected, loaded, netdetect, checker, initNetDetect; + + netdetect = $('netdetect'); netdetect.onerror = function() { errorDetected = true; loaded = false; @@ -107,22 +107,21 @@ function detectNetworkAccess(retry_delay, destination_url, redirect_url, externa errorDetected = false; loaded = true; }; - var checker; - var initNetDetect = function() { + initNetDetect = function() { errorDetected = loaded = undefined; var netdetect = $('netdetect'); netdetect.src = "http://" + external_ip + "/common/network-access-detection.gif?r=" + Date.now(); - setTimeout(checker,1000); + checker.delay(retry_delay); }; checker = function() { var netdetect = $('netdetect'); - if(errorDetected === true) { + if (errorDetected === true) { initNetDetect(); } else if (loaded === true) { networkAccessCallback(destination_url, redirect_url); } else { - //Check the width or height of the image since we do not know if it is loaded - if(netdetect.width || netdetect.height) { + // Check the width or height of the image since we do not know if it is loaded + if (netdetect.width || netdetect.height) { networkAccessCallback(destination_url, redirect_url); } else { initNetDetect(); From d8224a425ffb45261f6596e30de68b66ab0b7679 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Tue, 15 Oct 2013 14:19:50 -0400 Subject: [PATCH 311/369] Allow switch to be read dynamically by radius --- lib/pf/SwitchFactory.pm | 2 + lib/pf/freeradius.pm | 40 ++---------- raddb/policy.conf | 4 ++ raddb/sites-available/dynamic-clients | 91 +++++++++------------------ 4 files changed, 40 insertions(+), 97 deletions(-) diff --git a/lib/pf/SwitchFactory.pm b/lib/pf/SwitchFactory.pm index 38be8cd99728..cf0c95b96dab 100644 --- a/lib/pf/SwitchFactory.pm +++ b/lib/pf/SwitchFactory.pm @@ -23,6 +23,7 @@ use Log::Log4perl qw(get_logger); use pf::config; use pf::config::cached; use pf::util; +use pf::freeradius; our ($singleton, %SwitchConfig, $switches_cached_config); @@ -64,6 +65,7 @@ $switches_cached_config = pf::config::cached->new( } } $SwitchConfig{'127.0.0.1'} = { %{$SwitchConfig{default}}, type => 'PacketFence', mode => 'production', uplink => ['dynamic'], SNMPVersionTrap => '1', SNMPCommunityTrap => 'public'}; + freeradius_populate_nas_config(\%SwitchConfig); $config->cache->set("SwitchConfig",\%SwitchConfig); }, ], diff --git a/lib/pf/freeradius.pm b/lib/pf/freeradius.pm index aa540f81861d..a2839a6e9b0f 100644 --- a/lib/pf/freeradius.pm +++ b/lib/pf/freeradius.pm @@ -121,55 +121,27 @@ Populates the radius_nas table with switches in switches.conf. # First, we aim at reduced complexity. I prefer to dump and reload than to deal with merging config vs db changes. sub freeradius_populate_nas_config { my $logger = Log::Log4perl::get_logger('pf::freeradius'); + my ($switch_config) = @_; if (!_delete_all_nas()) { $logger->info("Problem emptying FreeRADIUS nas clients table."); } - # load switches.conf - my %SwitchConfig; - if (!-e $conf_dir.SWITCHES_CONF) { - croak "Config file " . $conf_dir.SWITCHES_CONF . " cannot be read\n"; - } - - tie %SwitchConfig, 'pf::config::cached', (-file => $conf_dir.SWITCHES_CONF); - - my @errors = @Config::IniFiles::errors; - if ( scalar(@errors) ) { - croak "Error reading config file: " . join( "\n", @errors ) . "\n"; - } - - $logger->debug("Starting to insert switches in radius_nas table for FreeRADIUS"); - foreach my $switch (sort keys %SwitchConfig) { + foreach my $switch (keys %$switch_config) { # we skip the 'default' entry or the local switch if ($switch eq 'default' || $switch eq '127.0.0.1') { next; } - # valid if switch's radiusSecret exists and is not all whitespace - my $valid_sw_radiussecret = ( - defined($SwitchConfig{$switch}{'radiusSecret'}) - && $SwitchConfig{$switch}{'radiusSecret'} =~ /\S/ - ); - - # valid if default radiusSecret exists and is not all whitespace - my $valid_df_radiussecret = ( - defined($SwitchConfig{'default'}{'radiusSecret'}) - && $SwitchConfig{'default'}{'radiusSecret'} =~ /\S/ - ); + my $sw_radiussecret = $switch_config->{$switch}{'radiusSecret'}; - # we are looking for the opposite of a valid switch statement or a valid radius statement - if (!($valid_sw_radiussecret || $valid_df_radiussecret)) { + # skipping unless switch's radiusSecret exists and is not all whitespace + unless (defined $sw_radiussecret && $sw_radiussecret =~ /\S/ ) { $logger->debug("No RADIUS secret for switch: $switch FreeRADIUS configuration skipped"); next; } # insert NAS - _insert_nas( - $switch, - $switch, - $SwitchConfig{$switch}{'radiusSecret'} || $SwitchConfig{'default'}{'radiusSecret'}, - $switch . " (" . ($SwitchConfig{$switch}{'type'} || $SwitchConfig{'default'}{'type'}) .")", - ); + _insert_nas( $switch, $switch, $sw_radiussecret, $switch . " (" . $switch_config->{$switch}{'type'} .")"); } } diff --git a/raddb/policy.conf b/raddb/policy.conf index 31ce6bad125c..325cced75b5d 100644 --- a/raddb/policy.conf +++ b/raddb/policy.conf @@ -155,6 +155,10 @@ policy { } } + + # The dynamic client/controller time to live / lifetime + dynamic_controller_ttl = 600 + # # Normalize the MAC Addresses in the Calling/Called-Station-Id # diff --git a/raddb/sites-available/dynamic-clients b/raddb/sites-available/dynamic-clients index f8c3cc4ddd4a..69705c2346a8 100644 --- a/raddb/sites-available/dynamic-clients +++ b/raddb/sites-available/dynamic-clients @@ -33,13 +33,7 @@ # # Define a network where clients may be dynamically defined. -client dynamic { - ipaddr = 192.168.0.0 - - # - # You MUST specify a netmask! - # IPv4 /32 or IPv6 /128 are NOT allowed! - netmask = 16 +client 0.0.0.0/0 { # # Any other configuration normally found in a "client" @@ -71,7 +65,7 @@ client dynamic { # If the lifetime is "0", then the dynamic client is never # deleted. The only way to delete the client is to re-start # the server. - lifetime = 3600 + lifetime = ${policy.dynamic_controller_ttl} } # @@ -80,6 +74,7 @@ server dynamic_client_server { # # The only contents of the virtual server is the "authorize" section. + # authorize { # @@ -106,38 +101,6 @@ server dynamic_client_server { # useless, but it documents the attributes # you need. # - update control { - - # - # Echo the IP address of the client. - FreeRADIUS-Client-IP-Address = "%{Packet-Src-IP-Address}" - - # require_message_authenticator - FreeRADIUS-Client-Require-MA = no - - # secret - FreeRADIUS-Client-Secret = "testing123" - - # shortname - FreeRADIUS-Client-Shortname = "%{Packet-Src-IP-Address}" - - # nastype - FreeRADIUS-Client-NAS-Type = "other" - - # virtual_server - # - # This can ONLY be used if the network client - # definition (e.g. "client dynamic" above) has - # NO virtual_server defined. - # - # If the network client definition does have a - # virtual_server defined, then that is used, - # and there is no need to define this attribute. - # - FreeRADIUS-Client-Virtual-Server = "something" - - } - # # Example 2: Read the clients from "clients" files # in a directory. @@ -155,25 +118,27 @@ server dynamic_client_server { # Example 3: Look the clients up in SQL. # # This requires the SQL module to be configured, of course. - if ("%{sql: SELECT nasname FROM nas WHERE nasname = '%{Packet-Src-IP-Address}'}") { - update control { - # - # Echo the IP. - FreeRADIUS-Client-IP-Address = "%{Packet-Src-IP-Address}" - - # - # Do multiple SELECT statements to grab - # the various definitions. - FreeRADIUS-Client-Shortname = "%{sql: SELECT shortname FROM nas WHERE nasname = '%{Packet-Src-IP-Address}'}" + update control { + Tmp-String-8 = "%{sql: SELECT nasname FROM radius_nas WHERE nasname '%{Packet-Src-IP-Address}'}" + } + if ("%{control:Tmp-String-8}") { + update control { + # + # Echo the IP. + FreeRADIUS-Client-IP-Address = "%{Packet-Src-IP-Address}" - FreeRADIUS-Client-Secret = "%{sql: SELECT secret FROM nas WHERE nasname = '%{Packet-Src-IP-Address}'}" + # + # Do multiple SELECT statements to grab + # the various definitions. + FreeRADIUS-Client-Shortname = "%{sql: SELECT shortname FROM radius_nas WHERE nasname = '%{control:Tmp-String-8}'}" - FreeRADIUS-Client-NAS-Type = "%{sql: SELECT type FROM nas WHERE nasname = '%{Packet-Src-IP-Address}'}" + FreeRADIUS-Client-Secret = "%{sql: SELECT secret FROM radius_nas WHERE nasname = '%{control:Tmp-String-8}'}" - FreeRADIUS-Client-Virtual-Server = "%{sql: SELECT server FROM nas WHERE nasname = '%{Packet-Src-IP-Address}'}" - } + FreeRADIUS-Client-NAS-Type = "%{sql: SELECT type FROM radius_nas WHERE nasname = '%{control:Tmp-String-8}'}" - } + } + ok + } # Do an LDAP lookup in the elements OU, check to see if # the Packet-Src-IP-Address object has a "ou" @@ -198,27 +163,27 @@ server dynamic_client_server { # # And with a "ou" value of the shared secret password # for the NAS element. ie "password" - if ("%{ldap:ldap:///OU=Elements,OU=Radius,DC=ACME,DC=COM?ou?sub?cn=%{Packet-Src-IP-Address}}") { - update control { - FreeRADIUS-Client-IP-Address = "%{Packet-Src-IP-Address}" +# if ("%{ldap:ldap:///OU=Elements,OU=Radius,DC=ACME,DC=COM?ou?sub?cn=%{Packet-Src-IP-Address}}") { +# update control { +# FreeRADIUS-Client-IP-Address = "%{Packet-Src-IP-Address}" # Set the Client-Shortname to be the Location # "l" just like in the Huntgroups, but this # time to the shortname. - FreeRADIUS-Client-Shortname = "%{ldap:ldap:///OU=Elements,OU=Radius,DC=ACME,DC=COM?l?sub?cn=%{Packet-Src-IP-Address}}" +# FreeRADIUS-Client-Shortname = "%{ldap:ldap:///OU=Elements,OU=Radius,DC=ACME,DC=COM?l?sub?cn=%{Packet-Src-IP-Address}}" # Lookup and set the Shared Secret based on # the "ou" attribute. - FreeRADIUS-Client-Secret = "%{ldap:ldap:///OU=Elements,OU=Radius,DC=ACME,DC=COM?ou?sub?cn=%{Packet-Src-IP-Address}}" - } - } +# FreeRADIUS-Client-Secret = "%{ldap:ldap:///OU=Elements,OU=Radius,DC=ACME,DC=COM?ou?sub?cn=%{Packet-Src-IP-Address}}" +# } +# ok +# } # # Tell the caller that the client was defined properly. # # If the authorize section does NOT return "ok", then # the new client is ignored. - ok } } From 144e93976639937bed2f6f80b01b5cde9434c97a Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 21 Nov 2013 11:40:21 -0500 Subject: [PATCH 312/369] Will not truncate radius_nas table on restart --- lib/pf/services.pm | 3 ++- lib/pf/services/radiusd.pm | 13 +++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/pf/services.pm b/lib/pf/services.pm index e92a7315e5cd..73fbde28d941 100644 --- a/lib/pf/services.pm +++ b/lib/pf/services.pm @@ -181,7 +181,8 @@ sub service_ctl { my $pid = service_ctl( $daemon, "status" ); # TODO: push all these per-daemon initialization into pf::services::... require pf::freeradius; - pf::freeradius::freeradius_populate_nas_config(); + require pf::SwitchFactory; + pf::freeradius::freeradius_populate_nas_config(\%pf::SwitchFactory::SwitchConfig); } return launchService($daemon,$service); diff --git a/lib/pf/services/radiusd.pm b/lib/pf/services/radiusd.pm index 1be834656554..87a8bf2cc90b 100644 --- a/lib/pf/services/radiusd.pm +++ b/lib/pf/services/radiusd.pm @@ -11,12 +11,12 @@ according to what PacketFence needs to accomplish. =head1 CONFIGURATION AND ENVIRONMENT -Read the following configuration files: +Read the following configuration files: F F F -Generates the following configuration files: +Generates the following configuration files: F F F @@ -60,9 +60,10 @@ sub generate_radiusd_conf { generate_radiusd_eapconf(); generate_radiusd_sqlconf(); - #Build the nas table for RADIUS + #Build the nas table for RADIUS require pf::freeradius; - pf::freeradius::freeradius_populate_nas_config(); + require pf::SwitchFactory; + pf::freeradius::freeradius_populate_nas_config(\%pf::SwitchFactory::SwitchConfig); return 1; } @@ -80,8 +81,8 @@ sub generate_radiusd_mainconf { $tags{'install_dir'} = $install_dir; $tags{'management_ip'} = defined($management_network->tag('vip')) ? $management_network->tag('vip') : $management_network->tag('ip'); $tags{'arch'} = `uname -m` eq "x86_64" ? "64" : ""; - - parse_template( \%tags, "$conf_dir/radiusd/radiusd.conf", "$install_dir/raddb/radiusd.conf" ); + + parse_template( \%tags, "$conf_dir/radiusd/radiusd.conf", "$install_dir/raddb/radiusd.conf" ); } =item * generate_radiusd_eapconf From 13db4dc40a013804f897c00241af7fe30cfb61e0 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Thu, 21 Nov 2013 11:40:42 -0500 Subject: [PATCH 313/369] Updated NEWS files --- NEWS.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.asciidoc b/NEWS.asciidoc index fa2dd806381e..38b2251e2b75 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -24,6 +24,7 @@ New Features * Displayed columns of nodes are now customizable * Create a single node or import multiple nodes from a CSV file from the Web admin * LDAP authentication sources can now filter by group membership using a second LDAP query +* Radius does not need to be restarted after adding a switch Enhancements ++++++++++++ From f5ea594eafcd750135c3b15be732349a9da822c9 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Fri, 29 Nov 2013 10:29:39 -0500 Subject: [PATCH 314/369] Fix condition to avoid warning --- lib/pf/vlan.pm | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/lib/pf/vlan.pm b/lib/pf/vlan.pm index ba9e3d8e656b..7f78fac340f9 100644 --- a/lib/pf/vlan.pm +++ b/lib/pf/vlan.pm @@ -73,7 +73,7 @@ sub fetchVlanForNode { $logger->info("Inline trigger match, the node is in inline mode"); my $inline = $this->getInlineVlan($switch, $ifIndex, $mac, $node_info, $connection_type, $user_name, $ssid); $logger->info("MAC: $mac, PID: " .$node_info->{pid}. ", Status: " .$node_info->{status}. ". Returned VLAN: $inline"); - return ( $inline , 1 ); + return ( $inline, 1 ); } # violation handling @@ -87,20 +87,14 @@ sub fetchVlanForNode { # there were no violation, now onto registration handling my $registration = $this->getRegistrationVlan($switch, $ifIndex, $mac, $node_info, $connection_type, $user_name, $ssid); if (defined($registration) && $registration != 0) { - - if ( ($connection_type & $WIRELESS_MAC_AUTH) == $WIRELESS_MAC_AUTH ) { - - + if ($connection_type && ($connection_type & $WIRELESS_MAC_AUTH) == $WIRELESS_MAC_AUTH) { my $notes = $node_info->{'notes'}; if ($notes eq 'AUTO-REGISTERED') { $logger->info("Connection type is WIRELESS_MAC_AUTH and the device was comming from a secure SSID with auto registration" ); - my %info = ( - 'notes' => '', - ); - node_modify($mac,%info); + node_modify($mac, ('notes' => '')); } } - return ( $registration , 0, "registration"); + return ( $registration, 0, "registration" ); } # no violation, not unregistered, we are now handling a normal vlan From d682450c9e488d3d3007e1f668975c5a949f30ce Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Fri, 29 Nov 2013 15:16:31 -0500 Subject: [PATCH 315/369] Fix the error "dispatcher.pm line 70", missing test on the Referer --- lib/pf/web/dispatcher.pm | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/pf/web/dispatcher.pm b/lib/pf/web/dispatcher.pm index 5189234ba475..920480b6052f 100755 --- a/lib/pf/web/dispatcher.pm +++ b/lib/pf/web/dispatcher.pm @@ -66,13 +66,19 @@ sub translate { my $s = $r->server(); my $proto = isenabled($Config{'captive_portal'}{'secure_redirect'}) ? $HTTPS : $HTTP; #Because of chrome captiv portal detection we have to test if the request come from http request - my $parsed = APR::URI->parse($r->pool,$r->headers_in->{'Referer'}); - if ($s->port eq '80' && $proto eq 'https' && $r->uri !~ /$WEB::ALLOWED_RESOURCES/o && $parsed->path !~ /$WEB::ALLOWED_RESOURCES/o) { - #Generate a page with a refresh tag - $r->handler('modperl'); - $r->set_handlers( PerlResponseHandler => \&html_redirect ); - return Apache2::Const::OK; - } else { + if (defined($r->headers_in->{'Referer'})) { + my $parsed = APR::URI->parse($r->pool,$r->headers_in->{'Referer'}); + if ($s->port eq '80' && $proto eq 'https' && $r->uri !~ /$WEB::ALLOWED_RESOURCES/o && $parsed->path !~ /$WEB::ALLOWED_RESOURCES/o) { + #Generate a page with a refresh tag + $r->handler('modperl'); + $r->set_handlers( PerlResponseHandler => \&html_redirect ); + return Apache2::Const::OK; + } else { + # DECLINED tells Apache to continue further mod_rewrite / alias processing + return Apache2::Const::DECLINED; + } + } + else { # DECLINED tells Apache to continue further mod_rewrite / alias processing return Apache2::Const::DECLINED; } From aaefe69579e9dc0b5e03afd62698e8190aae28bd Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Fri, 29 Nov 2013 21:40:14 -0500 Subject: [PATCH 316/369] Check the role for dot1x autoregistration from the authentication sources defined in the captiv portal associated to the connection instead of all the authentication sources. --- lib/pf/vlan.pm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/pf/vlan.pm b/lib/pf/vlan.pm index ba9e3d8e656b..c672f2dd2c03 100644 --- a/lib/pf/vlan.pm +++ b/lib/pf/vlan.pm @@ -26,6 +26,7 @@ use pf::violation qw(violation_count_trap violation_exist_open violation_view_to use pf::authentication; use pf::Authentication::constants; +use pf::Portal::ProfileFactory; our $VERSION = 1.04; @@ -367,13 +368,15 @@ sub getNormalVlan { # FIRST HIT MATCH elsif ( defined $user_name && (($connection_type & $EAP) == $EAP) ) { $logger->debug("EAP connection with a username. Trying to match rules from authentication sources."); + my $profile = pf::Portal::ProfileFactory->instantiate($mac); + my @sources = ($profile->getInternalSources); my $params = { username => $user_name, connection_type => connection_type_to_str($connection_type), SSID => $ssid, }; - $role = &pf::authentication::match(&pf::authentication::getInternalAuthenticationSources(), $params, $Actions::SET_ROLE); - } + $role = &pf::authentication::match([@sources], $params, $Actions::SET_ROLE); + } # If a user based role has been found by matching authentication sources rules, we return it if ( defined($role) && $role ne '' ) { From 19cc2d6a484b162d45cf3622a02fbabfe04ae9ed Mon Sep 17 00:00:00 2001 From: Louis Munro Date: Mon, 2 Dec 2013 09:52:08 -0500 Subject: [PATCH 317/369] Modified logrotate to use copytrucate instead of restarting services. --- addons/logrotate | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/addons/logrotate b/addons/logrotate index 43e3e1e202be..58665313a583 100644 --- a/addons/logrotate +++ b/addons/logrotate @@ -6,13 +6,6 @@ missingok compress delaycompress - sharedscripts - create 644 pf pf su pf pf - postrotate - # uncomment the crm statements if you are running packetfence in a corosync cluster - #/usr/sbin/crm resource unmanage PacketFence - /etc/init.d/packetfence condrestart >/dev/null 2>&1 || true - #/usr/sbin/crm resource manage PacketFence - endscript + copytruncate } From 1cb1414637c3ab64328ba1d37b34947f0001d8d7 Mon Sep 17 00:00:00 2001 From: Louis Munro Date: Mon, 2 Dec 2013 09:56:10 -0500 Subject: [PATCH 318/369] Updated NEWS.asciidoc to reflect logrotate changes. --- NEWS.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.asciidoc b/NEWS.asciidoc index fa2dd806381e..1d76a05216da 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -43,6 +43,7 @@ Enhancements * Validate file path when saving an Htpasswd authentication source * Improved validation of a sponsor's email address * Allow actions depending on authentication source type +* Modified logrotate so it uses copytruncate instead of restarting the services. Bug Fixes +++++++++ From e8166606c4fa25112536de9abc6d88b446f62734 Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Mon, 2 Dec 2013 10:03:27 -0500 Subject: [PATCH 319/369] Added proxy log files in logrotate --- addons/logrotate | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/logrotate b/addons/logrotate index 58665313a583..2ed39016329c 100644 --- a/addons/logrotate +++ b/addons/logrotate @@ -1,6 +1,6 @@ # logrotate file for packetfence -/usr/local/pf/logs/access_log /usr/local/pf/logs/admin_access_log /usr/local/pf/logs/admin_error_log /usr/local/pf/logs/error_log /usr/local/pf/logs/packetfence.log /usr/local/pf/logs/pfdetect /usr/local/pf/logs/pfmon /usr/local/pf/logs/snmptrapd.log /usr/local/pf/logs/radius.log /usr/local/pf/logs/portal_access_log /usr/local/pf/logs/portal_error_log /usr/local/pf/logs/webservices_access_log /usr/local/pf/logs/webservices_error_log /usr/local/pf/logs/catalyst.log { +/usr/local/pf/logs/access_log /usr/local/pf/logs/admin_access_log /usr/local/pf/logs/admin_error_log /usr/local/pf/logs/error_log /usr/local/pf/logs/packetfence.log /usr/local/pf/logs/pfdetect /usr/local/pf/logs/pfmon /usr/local/pf/logs/snmptrapd.log /usr/local/pf/logs/radius.log /usr/local/pf/logs/portal_access_log /usr/local/pf/logs/portal_error_log /usr/local/pf/logs/portal_error_log /usr/local/pf/logs/proxy_access_log /usr/local/pf/logs/webservices_access_log /usr/local/pf/logs/webservices_error_log /usr/local/pf/logs/catalyst.log { weekly rotate 52 missingok From b1dcd5cf60b480c87e296303af9e57d41209d15b Mon Sep 17 00:00:00 2001 From: Louis Munro Date: Mon, 2 Dec 2013 11:06:42 -0500 Subject: [PATCH 320/369] Added a barnyard2 init script. --- NEWS.asciidoc | 1 + addons/barnyard2.sh | 116 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100755 addons/barnyard2.sh diff --git a/NEWS.asciidoc b/NEWS.asciidoc index 1d76a05216da..01ee1b76519e 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -44,6 +44,7 @@ Enhancements * Improved validation of a sponsor's email address * Allow actions depending on authentication source type * Modified logrotate so it uses copytruncate instead of restarting the services. +* Now comes with a corosync compatible barnyard2 init script in addons. Bug Fixes +++++++++ diff --git a/addons/barnyard2.sh b/addons/barnyard2.sh new file mode 100755 index 000000000000..09a5b91d9f13 --- /dev/null +++ b/addons/barnyard2.sh @@ -0,0 +1,116 @@ +#!/bin/bash +# lmunro@inverse.ca 20130508 +# License: GNU General Public License 2 (GPL2) +# +# This script is called from heartbeat (or corosync) to manage +# the Barnyard2 resource. +# It is loosely based on the barnyard2 init script. + +# Source function library +. /etc/rc.d/init.d/functions + +# program name +BASE=barnyard2 + +# program options +CONF="/usr/local/$BASE/etc/barnyard2.conf" +GEN_MAP="/usr/local/pf/conf/snort/gen-msg.map" +SID_MAP="/usr/local/pf/conf/snort/sid-msg.map" +LOG_DIR="/var/log/snort" +SPOOL_DIR="/var/log/snort" +LOG_FILE="merged.log" +WALDO_FILE="/var/log/snort/barnyard2.waldo" +DAEMON="-D" + +# Check that $BASE exists. +[ -f /usr/local/bin/$BASE ] || exit 0 + +# source ocf functions +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat} +. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs + + +RETVAL=0 + + +_get_meta_data() { + cat < + + +1.0 + + +The Barnyard resource agent manages the barnyard2 service. + + + +Barnyard + + + + + + + + + + + + +END + + return $OCF_SUCCESS +} + + + +_start () { + if [ -n "`/sbin/pidof $BASE`" ]; then + echo -n $"$BASE: already running" + echo "" + exit $OCF_SUCCESS + fi + echo -n "Starting Barnyard: " + /usr/local/bin/$BASE -c $CONF -G $GEN_MAP -S $SID_MAP -d $SPOOL_DIR -l $LOG_DIR -f $LOG_FILE -w $WALDO_FILE $DAEMON + sleep 1 + action "" /sbin/pidof $BASE + RETVAL=$? + [ $RETVAL -eq 0 ] && touch /var/lock/subsys/barnyard2 +} + +_stop () { + echo -n "Shutting down Barnyard: " + killproc /usr/local/bin/$BASE + RETVAL=$? + echo + [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/barnyard2 +} + +_monitor () { + status $BASE || RETVAL=7 +} + +_usage () { + echo "Usage: barnyard {start|stop|monitor|meta_data}" +} + +case $__OCF_ACTION in + meta-data) + _get_meta_data + exit $OCF_SUCCESS + ;; + start) _start + exit $RETVAL + ;; + stop) _stop + ;; + monitor) _monitor + exit $RETVAL + ;; + *) _usage + exit $OCF_ERR_UNIMPLEMENTED + ;; +esac + +exit $? From b84ae2ebb2fa5e920c6e3aa00d58d8a90028d4ec Mon Sep 17 00:00:00 2001 From: lzammit Date: Mon, 2 Dec 2013 13:35:21 -0500 Subject: [PATCH 321/369] Update PacketFence_Administration_Guide.asciidoc Disable resolvconf --- docs/PacketFence_Administration_Guide.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/PacketFence_Administration_Guide.asciidoc b/docs/PacketFence_Administration_Guide.asciidoc index 4c0d28150515..fa1385c6cd12 100644 --- a/docs/PacketFence_Administration_Guide.asciidoc +++ b/docs/PacketFence_Administration_Guide.asciidoc @@ -199,6 +199,7 @@ Install your distribution with minimal installation and no additional packages. * Disable Firewall * Disable SELinux * Disable AppArmor +* Disable resolvconf Make sure your system is up to date and your yum or apt-get database is updated. On a RHEL-based system, do: From 3e5827caecfbcc48741a489f30bba02554e9a019 Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Mon, 2 Dec 2013 14:04:45 -0500 Subject: [PATCH 322/369] Synchronise locationlog before trying to match source in portal profile (Autoreg 802.1x) --- lib/pf/radius.pm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/pf/radius.pm b/lib/pf/radius.pm index ed77497fbe3d..e3ebd8b2e482 100644 --- a/lib/pf/radius.pm +++ b/lib/pf/radius.pm @@ -138,6 +138,9 @@ sub authorize { if (!node_register($mac, $autoreg_node_defaults{'pid'}, %autoreg_node_defaults)) { $logger->error("auto-registration of node $mac failed"); } + locationlog_synchronize($switch_ip, $port, undef, $mac, + $isPhone ? $VOIP : $NO_VOIP, $connection_type, $user_name, $ssid + ); } # if it's an IP Phone, let _authorizeVoip decide (extension point) From 3dea4202097adc6651596a2a7519ce33f17ecee0 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Mon, 2 Dec 2013 15:41:31 -0500 Subject: [PATCH 323/369] Update NEWS and UPGRADE files --- NEWS.asciidoc | 1 + UPGRADE.asciidoc | 10 +++++++++- conf/admin_roles.conf | 0 3 files changed, 10 insertions(+), 1 deletion(-) delete mode 100644 conf/admin_roles.conf diff --git a/NEWS.asciidoc b/NEWS.asciidoc index 69ab13137ac6..db3aebb39ee8 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -26,6 +26,7 @@ New Features * LDAP authentication sources can now filter by group membership using a second LDAP query * Extended definition of access durations * FreeRADIUS does not need to be restarted after adding a switch +* New customizable ACLs for Web admin interface Enhancements ++++++++++++ diff --git a/UPGRADE.asciidoc b/UPGRADE.asciidoc index eedb7308e656..dbf9fc418a88 100644 --- a/UPGRADE.asciidoc +++ b/UPGRADE.asciidoc @@ -12,6 +12,9 @@ Database schema update ^^^^^^^^^^^^^^^^^^^^^^ The category column in the temporary_password should not be mandatory. + +Also, the access_level of the temporary_password table is now a string instead of a bit string. + Make sure you run the following to update your schema: mysql -u root -p pf -v < db/upgrade-4.0.0-4.1.0.sql @@ -20,7 +23,12 @@ Configuration changes ^^^^^^^^^^^^^^^^^^^^^ The parameters `trapping.redirecturl` and `trapping.always_use_redirecturl` from `pf.conf` (or `pf.conf.defaults`) -were moved to the default portal profile in `profiles.conf`. Adjust your configuration accordingly. +were moved to the default portal profile in `profiles.conf`. + +The action `set_access_level` of authentication sources in `authentication.pf` must now match one of the admin roles +defined in `adminroles.conf`. The previous level `4294967295` must be replaced by *ALL* and the level `0` by *NONE*. + +Adjust your configuration files accordingly. Upgrading from a version prior to 4.0.6 --------------------------------------- diff --git a/conf/admin_roles.conf b/conf/admin_roles.conf deleted file mode 100644 index e69de29bb2d1..000000000000 From 413a6db801187d8f288e5ac4df112c6d8b85196f Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 2 Dec 2013 09:50:15 -0500 Subject: [PATCH 324/369] Will only attempt repopulation of switches if there switches need to be changed --- lib/pf/freeradius.pm | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/lib/pf/freeradius.pm b/lib/pf/freeradius.pm index a2839a6e9b0f..fcc6c5e53d43 100644 --- a/lib/pf/freeradius.pm +++ b/lib/pf/freeradius.pm @@ -122,24 +122,21 @@ Populates the radius_nas table with switches in switches.conf. sub freeradius_populate_nas_config { my $logger = Log::Log4perl::get_logger('pf::freeradius'); my ($switch_config) = @_; + my %skip = (default => undef, '127.0.0.1' => undef ); + my $radiusSecret; + my @switches = grep { + !exists $skip{$_} + && defined( $radiusSecret = $switch_config->{$_}{radiusSecret} ) + && $radiusSecret =~ /\S/ + } keys %$switch_config; + return unless @switches; if (!_delete_all_nas()) { $logger->info("Problem emptying FreeRADIUS nas clients table."); } - foreach my $switch (keys %$switch_config) { - - # we skip the 'default' entry or the local switch - if ($switch eq 'default' || $switch eq '127.0.0.1') { next; } - + foreach my $switch (@switches) { my $sw_radiussecret = $switch_config->{$switch}{'radiusSecret'}; - - # skipping unless switch's radiusSecret exists and is not all whitespace - unless (defined $sw_radiussecret && $sw_radiussecret =~ /\S/ ) { - $logger->debug("No RADIUS secret for switch: $switch FreeRADIUS configuration skipped"); - next; - } - # insert NAS _insert_nas( $switch, $switch, $sw_radiussecret, $switch . " (" . $switch_config->{$switch}{'type'} .")"); } From dd4fada0f5e07ab89b86b607e62e5b510df2a5b9 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Fri, 29 Nov 2013 17:28:53 -0500 Subject: [PATCH 325/369] Validate startup array references --- bin/pfcmd.pl | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/bin/pfcmd.pl b/bin/pfcmd.pl index 126202726e5c..a73945440f72 100755 --- a/bin/pfcmd.pl +++ b/bin/pfcmd.pl @@ -1206,13 +1206,15 @@ sub startService { $technique->iptables_generate(); } - require pf::pfcmd::checkup; - import pf::pfcmd::checkup; my ($noCheckupManagers,$checkupManagers) = part { $_->shouldCheckup} @managers; - foreach my $manager (@$noCheckupManagers) { - _doStart($manager); + if($noCheckupManagers && @$noCheckupManagers) { + foreach my $manager (@$noCheckupManagers) { + _doStart($manager); + } } - if(@$checkupManagers) { + if($checkupManagers && @$checkupManagers) { + require pf::pfcmd::checkup; + import pf::pfcmd::checkup; checkup( map {$_->name} @$checkupManagers); foreach my $manager (@$checkupManagers) { From 8e489db30e9f345448ba1e56b7d6e24c558c4de9 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 2 Dec 2013 11:56:12 -0500 Subject: [PATCH 326/369] Add db_ping function --- lib/pf/db.pm | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/pf/db.pm b/lib/pf/db.pm index 4feff690ca45..17320d0bea87 100644 --- a/lib/pf/db.pm +++ b/lib/pf/db.pm @@ -40,7 +40,7 @@ BEGIN { use Exporter (); our ( @ISA, @EXPORT ); @ISA = qw(Exporter); - @EXPORT = qw(%dbh db_data db_connect db_disconnect get_db_handle db_query_execute); + @EXPORT = qw(%dbh db_data db_connect db_disconnect get_db_handle db_query_execute db_ping); } @@ -118,6 +118,21 @@ sub db_connect { } } +=item * db_ping + +checks if database is connected + +=cut + +sub db_ping { + my ($dbh,$result); + eval { + my $dbh = db_connect; + $result = $dbh->ping; + }; + return $result; +} + =item * db_disconnect =cut From 26865a9cee896baec98acc126131c75f30fc569f Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 2 Dec 2013 12:00:29 -0500 Subject: [PATCH 327/369] Check if the database is alive before loading into database --- lib/pf/violation_config.pm | 91 ++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/lib/pf/violation_config.pm b/lib/pf/violation_config.pm index e640451b5d1f..491c53ec3fb0 100644 --- a/lib/pf/violation_config.pm +++ b/lib/pf/violation_config.pm @@ -20,6 +20,7 @@ use Try::Tiny; use pf::config; use pf::trigger qw(trigger_delete_all parse_triggers); use pf::class qw(class_merge); +use pf::db; our (%Violation_Config, $cached_violations_config); @@ -37,51 +38,53 @@ sub fileReloadViolationConfig { $logger->info("called $name"); $config->toHash(\%Violation_Config); $config->cleanupWhitespace(\%Violation_Config); - trigger_delete_all(); - while(my ($violation,$data) = each %Violation_Config) { - # parse triggers if they exist - my $triggers_ref = []; - if ( defined $data->{'trigger'} ) { - try { - $triggers_ref = parse_triggers($data->{'trigger'}); - } catch { - $logger->warn("Violation $violation is ignored: $_"); - $triggers_ref = []; - }; + if(db_ping) { + trigger_delete_all(); + while(my ($violation,$data) = each %Violation_Config) { + # parse triggers if they exist + my $triggers_ref = []; + if ( defined $data->{'trigger'} ) { + try { + $triggers_ref = parse_triggers($data->{'trigger'}); + } catch { + $logger->warn("Violation $violation is ignored: $_"); + $triggers_ref = []; + }; + } + + # parse grace, try to understand trailing signs, and convert back to seconds + if ( defined $data->{'grace'} ) { + $data->{'grace'} = normalize_time($data->{'grace'}); + } + + if ( defined $data->{'window'} && $data->{'window'} ne "dynamic" ) { + $data->{'window'} = normalize_time($data->{'window'}); + } + + # be careful of the way parameters are passed, whitelists, actions and triggers are expected at the end + class_merge( + $violation, + $data->{'desc'} || '', + $data->{'auto_enable'}, + $data->{'max_enable'}, + $data->{'grace'}, + $data->{'window'}, + $data->{'vclose'}, + $data->{'priority'}, + $data->{'template'}, + $data->{'max_enable_url'}, + $data->{'redirect_url'}, + $data->{'button_text'}, + $data->{'enabled'}, + $data->{'vlan'}, + $data->{'target_category'}, + $data->{'whitelisted_categories'} || '', + $data->{'actions'}, + $triggers_ref + ); } - - # parse grace, try to understand trailing signs, and convert back to seconds - if ( defined $data->{'grace'} ) { - $data->{'grace'} = normalize_time($data->{'grace'}); - } - - if ( defined $data->{'window'} && $data->{'window'} ne "dynamic" ) { - $data->{'window'} = normalize_time($data->{'window'}); - } - - # be careful of the way parameters are passed, whitelists, actions and triggers are expected at the end - class_merge( - $violation, - $data->{'desc'} || '', - $data->{'auto_enable'}, - $data->{'max_enable'}, - $data->{'grace'}, - $data->{'window'}, - $data->{'vclose'}, - $data->{'priority'}, - $data->{'template'}, - $data->{'max_enable_url'}, - $data->{'redirect_url'}, - $data->{'button_text'}, - $data->{'enabled'}, - $data->{'vlan'}, - $data->{'target_category'}, - $data->{'whitelisted_categories'} || '', - $data->{'actions'}, - $triggers_ref - ); + $config->cache->set("Violation_Config",\%Violation_Config); } - $config->cache->set("Violation_Config",\%Violation_Config); } sub readViolationConfigFile { @@ -98,7 +101,7 @@ sub readViolationConfigFile { if($data) { %Violation_Config = %$data; } else { - fileReloadViolationConfig($config,$name); + $config->doCallbacks(1,0); } } ], From 3e137256d747ea5dad7e7614da385585441a0652 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 2 Dec 2013 12:04:13 -0500 Subject: [PATCH 328/369] Refactor color usage on the command --- bin/pfcmd.pl | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/bin/pfcmd.pl b/bin/pfcmd.pl index a73945440f72..ac6db1a01c5d 100755 --- a/bin/pfcmd.pl +++ b/bin/pfcmd.pl @@ -113,11 +113,8 @@ =head1 SYNOPSIS restart => \&restartService, ); -our $SERVICE_HEADER ="service|command\n"; - -our $IS_INTERACTIVE = is_interactive(); - -our $RESET_COLOR = $IS_INTERACTIVE ? color 'reset' : ''; +our ($SERVICE_HEADER, $IS_INTERACTIVE); +our ($RESET_COLOR, $WARNING_COLOR, $ERROR_COLOR, $SUCCESS_COLOR); my $count = $ENV{PER_PAGE}; my $offset = $ENV{PAGE_NUM}; @@ -1173,6 +1170,13 @@ sub service { my $action = $cmd{command}[2]; require pf::services; import pf::services; + $SERVICE_HEADER ="service|command\n"; + $IS_INTERACTIVE = is_interactive(); + $RESET_COLOR = $IS_INTERACTIVE ? color 'reset' : ''; + $WARNING_COLOR = $IS_INTERACTIVE ? color 'yellow' : ''; + $ERROR_COLOR = $IS_INTERACTIVE ? color 'red' : ''; + $SUCCESS_COLOR = $IS_INTERACTIVE ? color 'green' : ''; + my $actionHandler; $action =~ /^(.*)$/; $action = $1; @@ -1207,16 +1211,14 @@ sub startService { } my ($noCheckupManagers,$checkupManagers) = part { $_->shouldCheckup} @managers; + if($noCheckupManagers && @$noCheckupManagers) { foreach my $manager (@$noCheckupManagers) { _doStart($manager); } } if($checkupManagers && @$checkupManagers) { - require pf::pfcmd::checkup; - import pf::pfcmd::checkup; checkup( map {$_->name} @$checkupManagers); - foreach my $manager (@$checkupManagers) { _doStart($manager); } @@ -1229,15 +1231,15 @@ sub _doStart { my $command; my $color = ''; if($manager->status ne '0') { - $color = color 'yellow' if $IS_INTERACTIVE; + $color = $WARNING_COLOR; $command = 'already started'; } else { if($manager->start) { $command = 'start'; - $color = color 'green' if $IS_INTERACTIVE; + $color = $SUCCESS_COLOR; } else { $command = 'not started'; - $color = color 'red' if $IS_INTERACTIVE; + $color = $ERROR_COLOR; } } print $manager->name,"|${color}${command}${RESET_COLOR}\n"; @@ -1288,13 +1290,13 @@ sub stopService { my $color = ''; if($manager->status eq '0') { $command = 'already stopped'; - $color = color 'yellow' if $IS_INTERACTIVE; + $color = $WARNING_COLOR; } else { if($manager->stop) { - $color = color 'green' if $IS_INTERACTIVE; + $color = $SUCCESS_COLOR; $command = 'stop'; } else { - $color = color 'red' if $IS_INTERACTIVE; + $color = $ERROR_COLOR; $command = 'not stopped'; } } @@ -1365,13 +1367,13 @@ sub statusOfService { my $status = $manager->status; if($status eq '0' ) { if ($isManaged) { - $color = color 'red' if $IS_INTERACTIVE; + $color = $ERROR_COLOR; $notStarted++; } else { - $color = color 'yellow' if $IS_INTERACTIVE; + $color = $WARNING_COLOR; } } else { - $color = color 'green' if $IS_INTERACTIVE; + $color = $SUCCESS_COLOR; } print $manager->name,"|${color}$isManaged|$status${RESET_COLOR}\n"; } @@ -1395,8 +1397,14 @@ sub checkup { require pf::services; require pf::pfcmd::checkup; no warnings "once"; #avoids only used once warnings generated by the access of pf::pfcmd::checkup namespace + my @services; + if(@_) { + @services = @_; + } else { + @services = @pf::services::ALL_SERVICES; + } - my @problems = pf::pfcmd::checkup::sanity_check(pf::services::service_list(@pf::services::ALL_SERVICES)); + my @problems = pf::pfcmd::checkup::sanity_check(pf::services::service_list(@services)); foreach my $entry (@problems) { chomp $entry->{$pf::pfcmd::checkup::MESSAGE}; print $entry->{$pf::pfcmd::checkup::SEVERITY} . " - " . $entry->{$pf::pfcmd::checkup::MESSAGE} . "\n"; From 91d10b766bad7e98e83859997295dc646add6b63 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 2 Dec 2013 16:33:11 -0500 Subject: [PATCH 329/369] Will not attempt to repopulate db if if database is down --- lib/pf/freeradius.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pf/freeradius.pm b/lib/pf/freeradius.pm index fcc6c5e53d43..db00ee8b5e4f 100644 --- a/lib/pf/freeradius.pm +++ b/lib/pf/freeradius.pm @@ -121,6 +121,7 @@ Populates the radius_nas table with switches in switches.conf. # First, we aim at reduced complexity. I prefer to dump and reload than to deal with merging config vs db changes. sub freeradius_populate_nas_config { my $logger = Log::Log4perl::get_logger('pf::freeradius'); + return unless db_ping; my ($switch_config) = @_; my %skip = (default => undef, '127.0.0.1' => undef ); my $radiusSecret; From e4d21cdb79186ad4445dc8ec4c663629afdb3267 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 2 Dec 2013 18:43:52 -0500 Subject: [PATCH 330/369] New schema for 4.1.0 release --- db/pf-schema-4.1.0.sql | 807 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 807 insertions(+) create mode 100644 db/pf-schema-4.1.0.sql diff --git a/db/pf-schema-4.1.0.sql b/db/pf-schema-4.1.0.sql new file mode 100644 index 000000000000..84118f8ec43c --- /dev/null +++ b/db/pf-schema-4.1.0.sql @@ -0,0 +1,807 @@ +-- +-- Table structure for table `class` +-- + +CREATE TABLE class ( + vid int(11) NOT NULL, + description varchar(255) NOT NULL default "none", + auto_enable char(1) NOT NULL default "Y", + max_enables int(11) NOT NULL default 0, + grace_period int(11) NOT NULL, + window varchar(255) NOT NULL default 0, + vclose int(11), + priority int(11) NOT NULL, + template varchar(255), + max_enable_url varchar(255), + redirect_url varchar(255), + button_text varchar(255), + enabled char(1) NOT NULL default "N", + vlan varchar(255), + target_category varchar(255), + PRIMARY KEY (vid) +) ENGINE=InnoDB; + +-- +-- Table structure for table `trigger` +-- +CREATE TABLE `trigger` ( + vid int(11) default NULL, + tid_start varchar(255) NOT NULL, + tid_end varchar(255) NOT NULL, + type varchar(255) default NULL, + whitelisted_categories varchar(255) NOT NULL default '', + PRIMARY KEY (vid,tid_start,tid_end,type), + KEY `trigger` (tid_start,tid_end,type), + CONSTRAINT `0_64` FOREIGN KEY (`vid`) REFERENCES `class` (`vid`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB; + +-- +-- Table structure for table `person` +-- + +CREATE TABLE person ( + pid varchar(255) NOT NULL, + `firstname` varchar(255) default NULL, + `lastname` varchar(255) default NULL, + `email` varchar(255) default NULL, + `telephone` varchar(255) default NULL, + `company` varchar(255) default NULL, + `address` varchar(255) default NULL, + notes varchar(255), + sponsor varchar(255) default NULL, + PRIMARY KEY (pid) +) ENGINE=InnoDB; + + +-- +-- Table structure for table `node_category` +-- + +CREATE TABLE `node_category` ( + `category_id` int NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `max_nodes_per_pid` int default 0, + `notes` varchar(255) default NULL, + PRIMARY KEY (`category_id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +-- +-- Insert 'default' category +-- + +INSERT INTO `node_category` (category_id,name,notes) VALUES ("1","default","Placeholder role/category, feel free to edit"); + +-- +-- Insert 'guest' category +-- + +INSERT INTO `node_category` (category_id,name,notes) VALUES ("2","guest","Guests"); + +-- +-- Insert 'gaming' category +-- + +INSERT INTO `node_category` (category_id,name,notes) VALUES ("3","gaming","Gaming devices"); + +-- +-- Table structure for table `node` +-- + +CREATE TABLE node ( + mac varchar(17) NOT NULL, + pid varchar(255) NOT NULL default "admin", + category_id int default NULL, + detect_date datetime NOT NULL default "0000-00-00 00:00:00", + regdate datetime NOT NULL default "0000-00-00 00:00:00", + unregdate datetime NOT NULL default "0000-00-00 00:00:00", + lastskip datetime NOT NULL default "0000-00-00 00:00:00", + status varchar(15) NOT NULL default "unreg", + user_agent varchar(255) default NULL, + computername varchar(255) default NULL, + notes varchar(255) default NULL, + last_arp datetime NOT NULL default "0000-00-00 00:00:00", + last_dhcp datetime NOT NULL default "0000-00-00 00:00:00", + dhcp_fingerprint varchar(255) default NULL, + `bypass_vlan` varchar(50) default NULL, + `voip` enum('no','yes') NOT NULL DEFAULT 'no', + PRIMARY KEY (mac), + KEY pid (pid), + KEY category_id (category_id), + KEY `node_status` (`status`, `unregdate`), + KEY `node_dhcpfingerprint` (`dhcp_fingerprint`), + CONSTRAINT `0_57` FOREIGN KEY (`pid`) REFERENCES `person` (`pid`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `node_category_key` FOREIGN KEY (`category_id`) REFERENCES `node_category` (`category_id`) +) ENGINE=InnoDB; + +-- +-- Table structure for table `node_useragent` +-- + +CREATE TABLE `node_useragent` ( + mac varchar(17) NOT NULL, + os varchar(255) DEFAULT NULL, + browser varchar(255) DEFAULT NULL, + device enum('no','yes') NOT NULL DEFAULT 'no', + device_name varchar(255) DEFAULT NULL, + mobile enum('no','yes') NOT NULL DEFAULT 'no', + PRIMARY KEY (mac) +) ENGINE=InnoDB; + +-- +-- Trigger to delete the node_useragent associated with a mac when deleting this mac from the node table +-- + +DROP TRIGGER IF EXISTS node_useragent_delete_trigger; +DELIMITER / +CREATE TRIGGER node_useragent_delete_trigger AFTER DELETE ON node +FOR EACH ROW +BEGIN + DELETE FROM node_useragent WHERE mac = OLD.mac; +END / +DELIMITER ; + +-- +-- Table structure for table `action` +-- + +CREATE TABLE action ( + vid int(11) NOT NULL, + action varchar(255) NOT NULL, + PRIMARY KEY (vid,action), + CONSTRAINT `FOREIGN` FOREIGN KEY (`vid`) REFERENCES `class` (`vid`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB; + +-- +-- Table structure for table `violation` +-- + +CREATE TABLE violation ( + id int NOT NULL AUTO_INCREMENT, + mac varchar(17) NOT NULL, + vid int(11) NOT NULL, + start_date datetime NOT NULL, + release_date datetime default "0000-00-00 00:00:00", + status varchar(10) default "open", + ticket_ref varchar(255) default NULL, + notes text, + KEY mac (mac), + KEY vid (vid), + KEY status (status), + KEY ind1 (mac,status,vid), + CONSTRAINT `0_60` FOREIGN KEY (`mac`) REFERENCES `node` (`mac`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `0_61` FOREIGN KEY (`vid`) REFERENCES `class` (`vid`) ON DELETE CASCADE ON UPDATE CASCADE, + PRIMARY KEY (id) +) ENGINE=InnoDB; + +-- +-- Table structure for table `iplog` +-- + +CREATE TABLE iplog ( + mac varchar(17) NOT NULL, + ip varchar(15) NOT NULL, + start_time datetime NOT NULL, + end_time datetime default "0000-00-00 00:00:00", + KEY mac (mac), + KEY `ip_view_open` (`ip`, `end_time`), + KEY `mac_view_open` (`mac`, `end_time`), + CONSTRAINT `0_63` FOREIGN KEY (`mac`) REFERENCES `node` (`mac`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB; + +CREATE TABLE os_type ( + os_id int(11) NOT NULL, + description varchar(255) NOT NULL, + PRIMARY KEY os_id (os_id) +) ENGINE=InnoDB; + +CREATE TABLE dhcp_fingerprint ( + fingerprint varchar(255) NOT NULL, + os_id int(11) NOT NULL, + PRIMARY KEY fingerprint (fingerprint), + KEY os_id_key (os_id), + CONSTRAINT `0_65` FOREIGN KEY (`os_id`) REFERENCES `os_type` (`os_id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB; + +CREATE TABLE os_class ( + class_id int(11) NOT NULL, + description varchar(255) NOT NULL, + PRIMARY KEY class_id (class_id) +) ENGINE=InnoDB; + +CREATE TABLE os_mapping ( + os_type int(11) NOT NULL, + os_class int(11) NOT NULL, + PRIMARY KEY (os_type,os_class), + KEY os_type_key (os_type), + KEY os_class_key (os_class), + CONSTRAINT `0_66` FOREIGN KEY (`os_type`) REFERENCES `os_type` (`os_id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `0_67` FOREIGN KEY (`os_class`) REFERENCES `os_class` (`class_id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB; + +CREATE TABLE `locationlog` ( + `mac` varchar(17) default NULL, + `switch` varchar(17) NOT NULL default '', + `port` varchar(8) NOT NULL default '', + `vlan` varchar(50) default NULL, + `connection_type` varchar(50) NOT NULL default '', + `dot1x_username` varchar(255) NOT NULL default '', + `ssid` varchar(32) NOT NULL default '', + `start_time` datetime NOT NULL default '0000-00-00 00:00:00', + `end_time` datetime default NULL, + KEY `locationlog_view_mac` (`mac`, `end_time`), + KEY `locationlog_view_switchport` (`switch`,`port`,`end_time`,`vlan`) +) ENGINE=InnoDB; + +CREATE TABLE `locationlog_history` ( + `mac` varchar(17) default NULL, + `switch` varchar(17) NOT NULL default '', + `port` varchar(8) NOT NULL default '', + `vlan` varchar(50) default NULL, + `connection_type` varchar(50) NOT NULL default '', + `dot1x_username` varchar(255) NOT NULL default '', + `ssid` varchar(32) NOT NULL default '', + `start_time` datetime NOT NULL default '0000-00-00 00:00:00', + `end_time` datetime default NULL, + KEY `locationlog_history_view_mac` (`mac`, `end_time`) +) ENGINE=InnoDB; + +CREATE TABLE `userlog` ( + `mac` varchar(17) NOT NULL default '', + `pid` varchar(255) default NULL, + `start_time` datetime NOT NULL default '0000-00-00 00:00:00', + `end_time` datetime default NULL, + PRIMARY KEY (`mac`,`start_time`), + KEY `pid` (`pid`), + CONSTRAINT `userlog_ibfk_1` FOREIGN KEY (`mac`) REFERENCES `node` (`mac`) ON DELETE CASCADE +) ENGINE=InnoDB; + +CREATE TABLE `ifoctetslog` ( + `switch` varchar(17) NOT NULL default '', + `port` varchar(8) NOT NULL default '', + `read_time` datetime NOT NULL default '0000-00-00 00:00:00', + `mac` varchar(17) default NULL, + `ifInOctets` bigint(20) unsigned NOT NULL default '0', + `ifOutOctets` bigint(20) unsigned NOT NULL default '0', + PRIMARY KEY (`switch`,`port`,`read_time`) +) ENGINE=InnoDB; + +CREATE TABLE `switchlocation` ( + `switch` varchar(17) NOT NULL default '', + `port` varchar(8) NOT NULL default '', + `start_time` datetime NOT NULL default '0000-00-00 00:00:00', + `end_time` datetime default NULL, + `location` varchar(50) default NULL, + `description` varchar(50) default NULL, + PRIMARY KEY (`switch`,`port`,`start_time`) +) ENGINE=InnoDB; + +CREATE TABLE `traplog` ( + `switch` varchar(30) NOT NULL default '', + `ifIndex` smallint(6) NOT NULL default '0', + `parseTime` datetime NOT NULL default '0000-00-00 00:00:00', + `type` varchar(30) NOT NULL default '', + KEY `switch` (`switch`,`ifIndex`), + KEY `parseTime` (`parseTime`) +) ENGINE=InnoDB; + +CREATE TABLE `configfile` ( + `filename` varchar(255) NOT NULL, + `filecontent` text NOT NULL, + `lastmodified` datetime NOT NULL +) ENGINE=InnoDB default CHARSET=latin1; + +-- +-- Table structure for table `email_activation` +-- + +CREATE TABLE email_activation ( + `code_id` int NOT NULL AUTO_INCREMENT, + `pid` varchar(255) default NULL, + `mac` varchar(17) default NULL, + `email` varchar(255) NOT NULL, -- email were approbation request is sent + `activation_code` varchar(255) NOT NULL, + `expiration` datetime NOT NULL, + `status` varchar(60) default NULL, + `type` varchar(60) default NULL, + PRIMARY KEY (code_id), + KEY `identifier` (pid, mac), + KEY `activation` (activation_code, status) +) ENGINE=InnoDB; + +-- +-- Table structure for table `temporary_password` +-- + +CREATE TABLE temporary_password ( + `pid` varchar(255) NOT NULL, + `password` varchar(255) NOT NULL, + `valid_from` datetime default NULL, + `expiration` datetime NOT NULL, + `access_duration` varchar(255) default NULL, + `access_level` varchar(255) DEFAULT 'NONE', + `category` int DEFAULT NULL, + `sponsor` tinyint(1) NOT NULL default 0, + `unregdate` datetime NOT NULL default "0000-00-00 00:00:00", + PRIMARY KEY (pid) +) ENGINE=InnoDB; + +-- +-- Insert 'default' admin user +-- + +INSERT INTO `person` (pid,notes) VALUES ("admin","Default Admin User - do not delete"); +INSERT INTO temporary_password (pid, password, valid_from, expiration, access_duration, access_level, category) VALUES ('admin', 'admin', NOW(), '2038-01-01', '9999D', 'ALL', 1); + +-- +-- Trigger to delete the temp password from 'temporary_password' when deleting the pid associated with +-- + +DROP TRIGGER IF EXISTS temporary_password_delete_trigger; +DELIMITER / +CREATE TRIGGER temporary_password_delete_trigger AFTER DELETE ON person +FOR EACH ROW +BEGIN + DELETE FROM temporary_password WHERE pid = OLD.pid; +END / +DELIMITER ; + +-- +-- Table structure for table `sms_activation` +-- + +CREATE TABLE sms_activation ( + `code_id` int NOT NULL AUTO_INCREMENT, + `mac` varchar(17) default NULL, + `phone_number` varchar(255) NOT NULL, -- phone number where sms is sent + `carrier_id` int(11) NOT NULL, + `activation_code` varchar(255) NOT NULL, + `expiration` datetime NOT NULL, + `status` varchar(60) default NULL, + PRIMARY KEY (code_id), + KEY `identifier` (mac), + KEY `activation` (activation_code, status) +) ENGINE=InnoDB; + +-- +-- Table structure for table `sms_carrier` +-- +-- Source: StatusNet +-- Schema fetched on 2010-10-15 from: +-- http://gitorious.org/statusnet/mainline/blobs/raw/master/db/statusnet.sql +-- + +CREATE TABLE sms_carrier ( + id integer primary key comment 'primary key for SMS carrier', + name varchar(64) unique key comment 'name of the carrier', + email_pattern varchar(255) not null comment 'sprintf pattern for making an email address from a phone number', + created datetime not null comment 'date this record was created', + modified timestamp comment 'date this record was modified' +) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin; + +-- +-- Insert data for table `sms_carrier` +-- +-- Source: StatusNet +-- Data fetched on 2011-07-20 from: +-- http://gitorious.org/statusnet/mainline/blobs/raw/master/db/sms_carrier.sql +-- + +INSERT INTO sms_carrier + (id, name, email_pattern, created) +VALUES + (100056, '3 River Wireless', '%s@sms.3rivers.net', now()), + (100057, '7-11 Speakout', '%s@cingularme.com', now()), + (100058, 'Airtel (Karnataka, India)', '%s@airtelkk.com', now()), + (100059, 'Alaska Communications Systems', '%s@msg.acsalaska.com', now()), + (100060, 'Alltel Wireless', '%s@message.alltel.com', now()), + (100061, 'AT&T Wireless', '%s@txt.att.net', now()), + (100062, 'Bell Mobility (Canada)', '%s@txt.bell.ca', now()), + (100063, 'Boost Mobile', '%s@myboostmobile.com', now()), + (100064, 'Cellular One (Dobson)', '%s@mobile.celloneusa.com', now()), + (100065, 'Cingular (Postpaid)', '%s@cingularme.com', now()), + (100066, 'Centennial Wireless', '%s@cwemail.com', now()), + (100067, 'Cingular (GoPhone prepaid)', '%s@cingularme.com', now()), + (100068, 'Claro (Nicaragua)', '%s@ideasclaro-ca.com', now()), + (100069, 'Comcel', '%s@comcel.com.co', now()), + (100070, 'Cricket', '%s@sms.mycricket.com', now()), + (100071, 'CTI', '%s@sms.ctimovil.com.ar', now()), + (100072, 'Emtel (Mauritius)', '%s@emtelworld.net', now()), + (100073, 'Fido (Canada)', '%s@fido.ca', now()), + (100074, 'General Communications Inc.', '%s@msg.gci.net', now()), + (100075, 'Globalstar', '%s@msg.globalstarusa.com', now()), + (100076, 'Helio', '%s@myhelio.com', now()), + (100077, 'Illinois Valley Cellular', '%s@ivctext.com', now()), + (100078, 'i wireless', '%s.iws@iwspcs.net', now()), + (100079, 'Meteor (Ireland)', '%s@sms.mymeteor.ie', now()), + (100080, 'Mero Mobile (Nepal)', '%s@sms.spicenepal.com', now()), + (100081, 'MetroPCS', '%s@mymetropcs.com', now()), + (100082, 'Movicom', '%s@movimensaje.com.ar', now()), + (100083, 'Mobitel (Sri Lanka)', '%s@sms.mobitel.lk', now()), + (100084, 'Movistar (Colombia)', '%s@movistar.com.co', now()), + (100085, 'MTN (South Africa)', '%s@sms.co.za', now()), + (100086, 'MTS (Canada)', '%s@text.mtsmobility.com', now()), + (100087, 'Nextel (Argentina)', '%s@nextel.net.ar', now()), + (100088, 'Orange (Poland)', '%s@orange.pl', now()), + (100089, 'Personal (Argentina)', '%s@personal-net.com.ar', now()), + (100090, 'Plus GSM (Poland)', '%s@text.plusgsm.pl', now()), + (100091, 'President\'s Choice (Canada)', '%s@txt.bell.ca', now()), + (100092, 'Qwest', '%s@qwestmp.com', now()), + (100093, 'Rogers (Canada)', '%s@pcs.rogers.com', now()), + (100094, 'Sasktel (Canada)', '%s@sms.sasktel.com', now()), + (100095, 'Setar Mobile email (Aruba)', '%s@mas.aw', now()), + (100096, 'Solo Mobile', '%s@txt.bell.ca', now()), + (100097, 'Sprint (PCS)', '%s@messaging.sprintpcs.com', now()), + (100098, 'Sprint (Nextel)', '%s@page.nextel.com', now()), + (100099, 'Suncom', '%s@tms.suncom.com', now()), + (100100, 'T-Mobile', '%s@tmomail.net', now()), + (100101, 'T-Mobile (Austria)', '%s@sms.t-mobile.at', now()), + (100102, 'Telus Mobility (Canada)', '%s@msg.telus.com', now()), + (100103, 'Thumb Cellular', '%s@sms.thumbcellular.com', now()), + (100104, 'Tigo (Formerly Ola)', '%s@sms.tigo.com.co', now()), + (100105, 'Unicel', '%s@utext.com', now()), + (100106, 'US Cellular', '%s@email.uscc.net', now()), + (100107, 'Verizon', '%s@vtext.com', now()), + (100108, 'Virgin Mobile (Canada)', '%s@vmobile.ca', now()), + (100109, 'Virgin Mobile (USA)', '%s@vmobl.com', now()), + (100110, 'YCC', '%s@sms.ycc.ru', now()), + (100111, 'Orange (UK)', '%s@orange.net', now()), + (100112, 'Cincinnati Bell Wireless', '%s@gocbw.com', now()), + (100113, 'T-Mobile Germany', '%s@t-mobile-sms.de', now()), + (100114, 'Vodafone Germany', '%s@vodafone-sms.de', now()), + (100115, 'E-Plus', '%s@smsmail.eplus.de', now()), + (100116, 'Cellular South', '%s@csouth1.com', now()), + (100117, 'ChinaMobile (139)', '%s@139.com', now()), + (100118, 'Dialog Axiata', '%s@dialog.lk', now()); + +-- Adding RADIUS nas client table + +CREATE TABLE radius_nas ( + id int(10) NOT NULL AUTO_INCREMENT, + nasname varchar(128) NOT NULL, + shortname varchar(32), + type varchar(30) default 'other', + ports int(5), + secret varchar(60) default 'secret' NOT NULL, + community varchar(50), + description varchar(200) default 'RADIUS Client', + PRIMARY KEY (id), + KEY nasname (nasname) +) ENGINE=InnoDB; + +-- Adding RADIUS accounting table + +CREATE TABLE radacct ( + radacctid bigint(21) NOT NULL AUTO_INCREMENT, + acctsessionid varchar(64) NOT NULL default '', + acctuniqueid varchar(32) NOT NULL default '', + username varchar(64) NOT NULL default '', + groupname varchar(64) NOT NULL default '', + realm varchar(64) default '', + nasipaddress varchar(15) NOT NULL default '', + nasportid varchar(15) default NULL, + nasporttype varchar(32) default NULL, + acctstarttime datetime NULL default NULL, + acctstoptime datetime NULL default NULL, + acctsessiontime int(12) default NULL, + acctauthentic varchar(32) default NULL, + connectinfo_start varchar(50) default NULL, + connectinfo_stop varchar(50) default NULL, + acctinputoctets bigint(20) default NULL, + acctoutputoctets bigint(20) default NULL, + calledstationid varchar(50) NOT NULL default '', + callingstationid varchar(50) NOT NULL default '', + acctterminatecause varchar(32) NOT NULL default '', + servicetype varchar(32) default NULL, + framedprotocol varchar(32) default NULL, + framedipaddress varchar(15) NOT NULL default '', + acctstartdelay int(12) default NULL, + acctstopdelay int(12) default NULL, + xascendsessionsvrkey varchar(10) default NULL, + PRIMARY KEY (radacctid), + KEY username (username), + KEY framedipaddress (framedipaddress), + KEY acctsessionid (acctsessionid), + KEY acctsessiontime (acctsessiontime), + KEY acctuniqueid (acctuniqueid), + KEY acctstarttime (acctstarttime), + KEY acctstoptime (acctstoptime), + KEY nasipaddress (nasipaddress), + KEY callingstationid (callingstationid) +) ENGINE=InnoDB; + +-- Adding RADIUS update log table + +CREATE TABLE radacct_log ( + acctsessionid varchar(64) NOT NULL default '', + username varchar(64) NOT NULL default '', + nasipaddress varchar(15) NOT NULL default '', + acctstatustype varchar(25) NOT NULL default '', + timestamp datetime NULL default NULL, + acctinputoctets bigint(20) default NULL, + acctoutputoctets bigint(20) default NULL, + acctsessiontime int(12) default NULL, + KEY acctsessionid (acctsessionid), + KEY username (username), + KEY nasipaddress (nasipaddress), + KEY timestamp (timestamp) +) ENGINE=InnoDB; + +-- Adding RADIUS Updates Stored Procedure + +DROP PROCEDURE IF EXISTS acct_update; +DELIMITER / +CREATE PROCEDURE acct_update( + IN p_timestamp datetime, + IN p_acctsessiontime int(12), + IN p_acctinputoctets bigint(20), + IN p_acctoutputoctets bigint(20), + IN p_acctsessionid varchar(64), + IN p_username varchar(64), + IN p_nasipaddress varchar(15), + IN p_framedipaddress varchar(15), + IN p_acctstatustype varchar(25) +) +BEGIN + DECLARE Previous_Input_Octets bigint(20); + DECLARE Previous_Output_Octets bigint(20); + DECLARE Previous_Session_Time int(12); + + # Collect traffic previous values in the update table + SELECT SUM(acctinputoctets), SUM(acctoutputoctets), SUM(acctsessiontime) + INTO Previous_Input_Octets, Previous_Output_Octets, Previous_Session_Time + FROM radacct_log + WHERE acctsessionid = p_acctsessionid + AND username = p_username + AND nasipaddress = p_nasipaddress; + + # Set values to 0 when no previous records + IF (Previous_Session_Time IS NULL) THEN + SET Previous_Session_Time = 0; + SET Previous_Input_Octets = 0; + SET Previous_Output_Octets = 0; + END IF; + + # Update record with new traffic + UPDATE radacct SET + framedipaddress = p_framedipaddress, + acctsessiontime = p_acctsessiontime, + acctinputoctets = p_acctinputoctets, + acctoutputoctets = p_acctoutputoctets + WHERE acctsessionid = p_acctsessionid + AND username = p_username + AND nasipaddress = p_nasipaddress + AND (acctstoptime IS NULL OR acctstoptime = 0); + + # Create new record in the log table + INSERT INTO radacct_log + (acctsessionid, username, nasipaddress, + timestamp, acctstatustype, acctinputoctets, acctoutputoctets, acctsessiontime) + VALUES + (p_acctsessionid, p_username, p_nasipaddress, + p_timestamp, p_acctstatustype, (p_acctinputoctets - Previous_Input_Octets), (p_acctoutputoctets - Previous_Output_Octets), + (p_acctsessiontime - Previous_Session_Time)); +END / +DELIMITER ; + +-- Adding RADIUS Start Stored Procedure + +DROP PROCEDURE IF EXISTS acct_start; +DELIMITER / +CREATE PROCEDURE acct_start ( + IN p_acctsessionid varchar(64), + IN p_acctuniqueid varchar(32), + IN p_username varchar(64), + IN p_realm varchar(64), + IN p_nasipaddress varchar(15), + IN p_nasportid varchar(15), + IN p_nasporttype varchar(32), + IN p_acctstarttime datetime, + IN p_acctstoptime datetime, + IN p_acctsessiontime int(12), + IN p_acctauthentic varchar(32), + IN p_connectioninfo_start varchar(50), + IN p_connectioninfo_stop varchar(50), + IN p_acctinputoctets bigint(20), + IN p_acctoutputoctets bigint(20), + IN p_calledstationid varchar(50), + IN p_callingstationid varchar(50), + IN p_acctterminatecause varchar(32), + IN p_servicetype varchar(32), + IN p_framedprotocol varchar(32), + IN p_framedipaddress varchar(15), + IN p_acctstartdelay varchar(12), + IN p_acctstopdelay varchar(12), + IN p_xascendsessionsvrkey varchar(10), + IN p_acctstatustype varchar(25) +) +BEGIN + # Insert new record with new traffic + INSERT INTO radacct + (acctsessionid, acctuniqueid, username, + realm, nasipaddress, nasportid, + nasporttype, acctstarttime, acctstoptime, + acctsessiontime, acctauthentic, connectinfo_start, + connectinfo_stop, acctinputoctets, acctoutputoctets, + calledstationid, callingstationid, acctterminatecause, + servicetype, framedprotocol, framedipaddress, + acctstartdelay, acctstopdelay, xascendsessionsvrkey) + VALUES + (p_acctsessionid, p_acctuniqueid, p_username, + p_realm, p_nasipaddress, p_nasportid, + p_nasporttype, p_acctstarttime, p_acctstoptime, + p_acctsessiontime, p_acctauthentic, p_connectioninfo_start, + p_connectioninfo_stop, p_acctinputoctets, p_acctoutputoctets, + p_calledstationid, p_callingstationid, p_acctterminatecause, + p_servicetype, p_framedprotocol, p_framedipaddress, + p_acctstartdelay, p_acctstopdelay, p_xascendsessionsvrkey); + + # Create new record in the log table + INSERT INTO radacct_log + (acctsessionid, username, nasipaddress, + timestamp, acctstatustype, acctinputoctets, acctoutputoctets, acctsessiontime) + VALUES + (p_acctsessionid, p_username, p_nasipaddress, + p_acctstarttime, p_acctstatustype,p_acctinputoctets,p_acctoutputoctets,p_acctsessiontime); +END / +DELIMITER ; + +-- Adding RADIUS Stop Stored Procedure + +DROP PROCEDURE IF EXISTS acct_stop; +DELIMITER / +CREATE PROCEDURE acct_stop( + IN p_timestamp datetime, + IN p_acctsessiontime int(12), + IN p_acctinputoctets bigint(20), + IN p_acctoutputoctets bigint(20), + IN p_acctterminatecause varchar(12), + IN p_acctdelaystop varchar(32), + IN p_connectinfo_stop varchar(50), + IN p_acctsessionid varchar(64), + IN p_username varchar(64), + IN p_nasipaddress varchar(15), + IN p_acctstatustype varchar(25) +) +BEGIN + DECLARE Previous_Input_Octets bigint(20); + DECLARE Previous_Output_Octets bigint(20); + DECLARE Previous_Session_Time int(12); + + # Collect traffic previous values in the update table + SELECT SUM(acctinputoctets), SUM(acctoutputoctets), SUM(acctsessiontime) + INTO Previous_Input_Octets, Previous_Output_Octets, Previous_Session_Time + FROM radacct_log + WHERE acctsessionid = p_acctsessionid + AND username = p_username + AND nasipaddress = p_nasipaddress; + + # Set values to 0 when no previous records + IF (Previous_Session_Time IS NULL) THEN + SET Previous_Session_Time = 0; + SET Previous_Input_Octets = 0; + SET Previous_Output_Octets = 0; + END IF; + + # Update record with new traffic + UPDATE radacct SET + acctstoptime = p_timestamp, + acctsessiontime = p_acctsessiontime, + acctinputoctets = p_acctinputoctets, + acctoutputoctets = p_acctoutputoctets, + acctterminatecause = p_acctterminatecause, + connectinfo_stop = p_connectinfo_stop + WHERE acctsessionid = p_acctsessionid + AND username = p_username + AND nasipaddress = p_nasipaddress + AND (acctstoptime IS NULL OR acctstoptime = 0); + + # Create new record in the log table + INSERT INTO radacct_log + (acctsessionid, username, nasipaddress, + timestamp, acctstatustype, acctinputoctets, acctoutputoctets, acctsessiontime) + VALUES + (p_acctsessionid, p_username, p_nasipaddress, + p_timestamp, p_acctstatustype, (p_acctinputoctets - Previous_Input_Octets), (p_acctoutputoctets - Previous_Output_Octets), + (p_acctsessiontime - Previous_Session_Time)); +END / +DELIMITER ; + +-- +-- Statement of Health (SoH) related +-- +-- The web interface allows you to create any number of named filters, +-- which are a collection of rules. A rule is a specific condition that +-- must be satisfied by the statement of health, e.g. "anti-virus is not +-- installed". The rules in a filter are ANDed together to determine if +-- the specified action is to be executed. + +-- +-- One entry per filter. +-- + +CREATE TABLE soh_filters ( + filter_id int NOT NULL PRIMARY KEY AUTO_INCREMENT, + name varchar(32) NOT NULL UNIQUE, + + -- If action is null, this filter won't do anything. Otherwise this + -- column may have any value; "accept" and "violation" are currently + -- recognised and acted upon. + action varchar(32), + + -- If action = 'violation', then this column contains the vid of a + -- violation to trigger. (I wish I could write a constraint to + -- express this.) + vid int +) ENGINE=InnoDB; + +INSERT INTO soh_filters (name) VALUES ('Default'); + +-- +-- One entry for each rule in a filter. +-- + +CREATE TABLE soh_filter_rules ( + rule_id int NOT NULL PRIMARY KEY AUTO_INCREMENT, + + filter_id int NOT NULL, + FOREIGN KEY (filter_id) REFERENCES soh_filters (filter_id) + ON DELETE CASCADE, + + -- Any valid health class, e.g. "antivirus" + class varchar(32) NOT NULL, + + -- Must be 'is' or 'is not' + op varchar(16) NOT NULL, + + -- May be 'ok', 'installed', 'enabled', 'disabled', 'uptodate', + -- 'microsoft' for now; more values may be used in future. + status varchar(16) NOT NULL +) ENGINE=InnoDB; + +-- +-- Table structure for table `scan` +-- + +CREATE TABLE scan ( + id varchar(20) NOT NULL, + ip varchar(255) NOT NULL, + mac varchar(17) NOT NULL, + type varchar(255) NOT NULL, + start_date datetime NOT NULL, + update_date timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP, + status varchar(255) NOT NULL, + report_id varchar(255) NOT NULL, + PRIMARY KEY (id) +) ENGINE=InnoDB; + +-- +-- Table structure for table `billing` +-- + +CREATE TABLE billing ( + id varchar(20) NOT NULL, + ip varchar(255) NOT NULL, + mac varchar(17) NOT NULL, + type varchar(255) NOT NULL, + start_date datetime NOT NULL, + update_date timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP, + status varchar(255) NOT NULL, + item varchar(255) NOT NULL, + price varchar(255) NOT NULL, + person varchar(255) NOT NULL, + PRIMARY KEY (id) +) ENGINE=InnoDB; + +-- +-- Table structure for table `savedsearch` +-- + +CREATE TABLE savedsearch ( + id int NOT NULL AUTO_INCREMENT, + pid varchar(255) NOT NULL, + namespace varchar(255) NOT NULL, + name varchar(255) NOT NULL, + query text, + in_dashboard tinyint, + PRIMARY KEY (id) +) ENGINE=InnoDB; From 7e8eea8cd15b3b0a687036c5b4938195340ae7f9 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Mon, 2 Dec 2013 22:28:21 -0500 Subject: [PATCH 331/369] Fix reordering of conf sections and groups Fixes #1749 --- NEWS.asciidoc | 1 + lib/pf/IniFiles.pm | 16 ++++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/NEWS.asciidoc b/NEWS.asciidoc index db3aebb39ee8..c01473b7811d 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -67,6 +67,7 @@ Bug Fixes * Fixed self-registration of multiple unverified devices * Fixed duplicate entries in advanced search of nodes * Fixed advanced search by node category +* Fixed reordering of conf sections and groups (#1749) Version 4.0.6-2 released on 2013-09-13 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/lib/pf/IniFiles.pm b/lib/pf/IniFiles.pm index a385e8c72c4f..53835e9fe324 100644 --- a/lib/pf/IniFiles.pm +++ b/lib/pf/IniFiles.pm @@ -130,18 +130,18 @@ sub ResortSections { sub ReorderByGroup { my ($self) = @_; my @sections = $self->Sections; - if(@sections) { - #Finding all non group sections + if (@sections) { + # Finding all non group sections my @non_group = grep { !/ / } @sections; - if(scalar @sections != scalar @non_group) { - my @new_sections; + if (scalar @sections != scalar @non_group) { + my @new_sections; my @groups = grep { / / } @sections; foreach my $section (@non_group) { - push @new_sections,$section, grep { /^\Q$section \E/ } @groups; - @groups = grep { !/^\Q$section\E/ } @groups; + push @new_sections, $section, grep { /^\Q$section \E/ } @groups; + @groups = grep { !/^\Q$section \E/ } @groups; } - #Push any remaining group sections - push @new_sections,@groups; + # Push any remaining group sections + push @new_sections, @groups; $self->{sects} = \@new_sections; } } From fd482e1e60264fa994eff38472bf2f54ffdb15e3 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Tue, 3 Dec 2013 09:17:46 -0500 Subject: [PATCH 332/369] Fix packaging --- addons/packages/packetfence.spec | 1 - debian/packetfence.conffiles | 1 - 2 files changed, 2 deletions(-) diff --git a/addons/packages/packetfence.spec b/addons/packages/packetfence.spec index 5427d9c9f613..7daa42a7e9d3 100644 --- a/addons/packages/packetfence.spec +++ b/addons/packages/packetfence.spec @@ -650,7 +650,6 @@ fi %attr(0755, pf, pf) /usr/local/pf/bin/pftest %doc /usr/local/pf/ChangeLog %dir /usr/local/pf/conf -%config(noreplace) /usr/local/pf/conf/admin_roles.conf %config(noreplace) /usr/local/pf/conf/adminroles.conf %config(noreplace) /usr/local/pf/conf/authentication.conf %config /usr/local/pf/conf/chi.conf diff --git a/debian/packetfence.conffiles b/debian/packetfence.conffiles index 11b4923708a0..9bf2afb77b89 100644 --- a/debian/packetfence.conffiles +++ b/debian/packetfence.conffiles @@ -1,4 +1,3 @@ -/usr/local/pf/conf/admin_roles.conf /usr/local/pf/conf/adminroles.conf /usr/local/pf/conf/authentication.conf /usr/local/pf/conf/profiles.conf From f75306001e54a512998225352ecd86941b316566 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Tue, 3 Dec 2013 09:40:00 -0500 Subject: [PATCH 333/369] Fix warning in condition in pf::vlan --- lib/pf/vlan.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pf/vlan.pm b/lib/pf/vlan.pm index c672f2dd2c03..986ca7665396 100644 --- a/lib/pf/vlan.pm +++ b/lib/pf/vlan.pm @@ -366,7 +366,7 @@ sub getNormalVlan { # If it's an EAP connection with a username, we try to match that username with authentication sources to calculate # the role based on the rules defined in the different authentication sources. # FIRST HIT MATCH - elsif ( defined $user_name && (($connection_type & $EAP) == $EAP) ) { + elsif ( defined $user_name && $connection_type && ($connection_type & $EAP) == $EAP ) { $logger->debug("EAP connection with a username. Trying to match rules from authentication sources."); my $profile = pf::Portal::ProfileFactory->instantiate($mac); my @sources = ($profile->getInternalSources); From 3cf7ab61232404437ad7d4c74f22313b8d88e47a Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Tue, 3 Dec 2013 09:46:54 -0500 Subject: [PATCH 334/369] Update HTTP/BrowserDetect.pm --- lib/HTTP/BrowserDetect.pm | 777 ++++++++++++++++++++++++-------------- 1 file changed, 486 insertions(+), 291 deletions(-) diff --git a/lib/HTTP/BrowserDetect.pm b/lib/HTTP/BrowserDetect.pm index 9bd4f4d3994b..89ba9cac42a5 100644 --- a/lib/HTTP/BrowserDetect.pm +++ b/lib/HTTP/BrowserDetect.pm @@ -3,18 +3,14 @@ use warnings; package HTTP::BrowserDetect; -use vars qw(@ISA @EXPORT @EXPORT_OK @ALL_TESTS); -require Exporter; - -@ISA = qw(Exporter); -@EXPORT = qw(); -@EXPORT_OK = qw(); +use vars qw(@ALL_TESTS); # Operating Systems our @OS_TESTS = qw( windows mac os2 unix linux vms bsd amiga firefoxos + rimtabletos ); # More precise Windows @@ -23,9 +19,9 @@ our @WINDOWS_TESTS = qw( win95 win98 winnt winme win32 win2k winxp win2k3 winvista - win7 win8 wince - winphone winphone7 winphone7_5 - winphone8 + win7 win8 win8_0 + win8_1 wince winphone + winphone7 winphone7_5 winphone8 ); # More precise Mac @@ -90,6 +86,7 @@ our @IE_TESTS = qw( ie5 ie5up ie55 ie55up ie6 ie7 ie8 ie9 ie10 + ie11 ); our @OPERA_TESTS = qw( @@ -118,31 +115,73 @@ our @ENGINE_TESTS = qw( gecko trident ); +# https://support.google.com/webmasters/answer/1061943?hl=en + +my %ROBOTS = ( + altavista => 'AltaVista', + askjeeves => 'AskJeeves', + baidu => 'Baidu Spider', + curl => 'curl', + facebook => 'Facebook', + getright => 'GetRight', + google => 'Google', + googleadsbot => 'Google AdsBot', + googleadsense => 'Google AdSense', + googlebotimage => 'Googlebot Images', + googlebotnews => 'Googlebot News', + googlebotvideo => 'Googlebot Video', + googlemobile => 'Google Mobile', + icab => 'iCab', + infoseek => 'InfoSeek', + linkchecker => 'LinkChecker', + linkexchange => 'LinkExchange', + lotusnotes => 'Lotus Notes', + lwp => 'LWP::UserAgent', + lycos => 'Lycos', + msn => 'MSN', + msnmobile => 'MSN Mobile', + puf => 'puf', + robot => 'robot', + slurp => 'Yahoo! Slurp', + specialarchiver => 'archive.org_bot', + staroffice => 'StarOffice', + webcrawler => 'WebCrawler', + webtv => 'WebTV', + wget => 'wget', + yahoo => 'Yahoo', + yandeximages => 'YandexImages', +); + our @ROBOT_TESTS = qw( puf curl wget - getright robot yahoo + getright robot slurp + yahoo altavista lycos infoseek lwp webcrawler linkexchange - slurp webtv staroffice - lotusnotes icab google - googlemobile msn msnmobile + webtv staroffice + lotusnotes icab googlemobile + msn msnmobile facebook baidu googleadsbot - askjeeves + askjeeves googleadsense googlebotvideo + googlebotnews googlebotimage google + linkchecker yandeximages specialarchiver ); our @MISC_TESTS = qw( mobile dotnet x11 - java tablet + java tablet ); push @ALL_TESTS, ( - @OS_TESTS, @WINDOWS_TESTS, @MAC_TESTS, - @UNIX_TESTS, @BSD_TESTS, @GAMING_TESTS, - ( sort ( keys %DEVICE_TESTS ) ), @BROWSER_TESTS, @IE_TESTS, - @OPERA_TESTS, @AOL_TESTS, @NETSCAPE_TESTS, - @FIREFOX_TESTS, @ENGINE_TESTS, @ROBOT_TESTS, - @MISC_TESTS, + @OS_TESTS, @WINDOWS_TESTS, + @MAC_TESTS, @UNIX_TESTS, + @BSD_TESTS, @GAMING_TESTS, + ( sort ( keys %DEVICE_TESTS ) ), @BROWSER_TESTS, + @IE_TESTS, @OPERA_TESTS, + @AOL_TESTS, @NETSCAPE_TESTS, + @FIREFOX_TESTS, @ENGINE_TESTS, + @ROBOT_TESTS, @MISC_TESTS, ); # Safari build -> version map for versions prior to 3.0 @@ -229,19 +268,24 @@ sub _test { $self->{tests} = {}; my $tests = $self->{tests}; + $self->_os_tests; + $self->_robot_tests; my @ff = ( 'firefox', @FIREFOX_TESTS ); my $ff = join "|", @ff; my $ua = lc $self->{user_agent}; + # Trident Engine (detect early for sniffing out IE) + $tests->{TRIDENT} = ( index( $ua, "trident/" ) != -1 ); + # Browser version my ( $major, $minor, $beta ) = ( $ua =~ m{ \S+ # Greedly catch anything leading up to forward slash. \/ # Version starts with a slash [A-Za-z]* # Eat any letters before the major version - ( [^.]* ) # Major version number is everything before the first dot + ( [0-9A-Za-z]* ) # Major version number is everything before the first dot \. # The first dot ( [\d]* ) # Minor version number is every digit after the first dot [\d.]* # Throw away remaining numbers and dots @@ -266,32 +310,61 @@ sub _test { } - # IE (and many others ) version - if ($ua =~ m{ - compatible; - \s* - \w* - [\s|\/] - [A-Za-z\-\/]* # Eat any letters before the major version - ( [0-9a-zA-Z\.]* ) # Grab everything else and split it later - ; - }x + # IE (and others) version + if ( $ua =~ m{\b msie \s ( [0-9\.]+ ) (?: [a-z]+ [a-z0-9]* )? ;}x ) { + + # Internet Explorer + ( $major, $minor, $beta ) = split /\./, $1; + } + elsif ( $ua + =~ m{\b compatible; \s* [\w\-]* / ( [0-9\.]* ) (?: [a-z]+ [a-z0-9\.]* )? ;}x ) { - my $match = $1; - $match =~ s{[a-zA-Z].*}{}g; # toss the beta version for now - ( $major, $minor, $beta ) = split /\./, $match; + # Generic "compatible" formats + ( $major, $minor, $beta ) = split /\./, $1; } + elsif ($tests->{TRIDENT} && $ua =~ m{\b rv: ( [0-9\.]+ ) \b}x ) { + # MSIE masking as Gecko really well ;) + ( $major, $minor, $beta ) = split /\./, $1; + } + + # Opera browsers + + $tests->{OPERA} + = ( index( $ua, "opera" ) != -1 + || index( $ua, "opr/" ) != -1 ); + $tests->{OPERA3} + = ( index( $ua, "opera 3" ) != -1 + || index( $ua, "opera/3" ) != -1 ); + $tests->{OPERA4} + = ( index( $ua, "opera 4" ) != -1 ) + || ( index( $ua, "opera/4" ) != -1 + && ( index( $ua, "nintendo dsi" ) == -1 ) ); + $tests->{OPERA5} + = ( index( $ua, "opera 5" ) != -1 ) + || ( index( $ua, "opera/5" ) != -1 ); + $tests->{OPERA6} + = ( index( $ua, "opera 6" ) != -1 ) + || ( index( $ua, "opera/6" ) != -1 ); + $tests->{OPERA7} + = ( index( $ua, "opera 7" ) != -1 ) + || ( index( $ua, "opera/7" ) != -1 ); # Opera needs to be dealt with specifically # http://dev.opera.com/articles/view/opera-ua-string-changes/ + # http://my.opera.com/community/openweb/idopera/ # Opera/9.80 (S60; SymbOS; Opera Mobi/320; U; sv) Presto/2.4.15 Version/10.00 + # Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.52 Safari/537.36 OPR/15.0.1147.100 if ( $ua =~ m{\AOpera.*\sVersion/(\d*)\.(\d*)\z}i ) { $major = $1; $minor = $2; } + elsif ( $ua =~ m{\bOPR/(\d+)\.(\d+)}i ) { + $major = $1; + $minor = $2; + } elsif ( $ua =~ m{NetFront/(\d*)\.(\d*) Kindle}i ) { $major = $1; $minor = $2; @@ -309,7 +382,9 @@ sub _test { $tests->{GECKO} = ( index( $ua, "gecko" ) != -1 ) && ( index( $ua, "like gecko" ) == -1 ); - $tests->{CHROME} = ( index( $ua, "chrome/" ) != -1 ); + $tests->{CHROME} + = ( !$tests->{OPERA} + && index( $ua, "chrome/" ) != -1 ); $tests->{SAFARI} = ( ( index( $ua, "safari" ) != -1 ) || ( index( $ua, "applewebkit" ) != -1 ) ) @@ -358,10 +433,12 @@ sub _test { = ( !$tests->{FIREFOX} && !$tests->{SAFARI} && !$tests->{CHROME} + && !$tests->{OPERA} + && !$tests->{TRIDENT} && index( $ua, "mozilla" ) != -1 + && index( $ua, "msie" ) == -1 && index( $ua, "spoofer" ) == -1 && index( $ua, "compatible" ) == -1 - && index( $ua, "opera" ) == -1 && index( $ua, "webtv" ) == -1 && index( $ua, "hotjava" ) == -1 && index( $ua, "nintendo" ) == -1 @@ -401,7 +478,8 @@ sub _test { # Internet Explorer browsers - $tests->{IE} = ( index( $ua, "msie" ) != -1 + $tests->{IE} = ( $tests->{TRIDENT} + || index( $ua, "msie" ) != -1 || index( $ua, 'microsoft internet explorer' ) != -1 ); $tests->{IE3} = ( $tests->{IE} && $major == 3 ); $tests->{IE4} = ( $tests->{IE} && $major == 4 ); @@ -416,6 +494,7 @@ sub _test { $tests->{IE8} = ( $tests->{IE} && $major == 8 ); $tests->{IE9} = ( $tests->{IE} && $major == 9 ); $tests->{IE10} = ( $tests->{IE} && $major == 10 ); + $tests->{IE11} = ( $tests->{IE} && $major == 11 ); # Neoplanet browsers @@ -435,24 +514,8 @@ sub _test { $tests->{AOLTV} = ( index( $ua, "navio" ) != -1 ) || ( index( $ua, "navio_aoltv" ) != -1 ); - # Opera browsers - - $tests->{OPERA} = ( index( $ua, "opera" ) != -1 ); - $tests->{OPERA3} = ( index( $ua, "opera 3" ) != -1 ) - || ( index( $ua, "opera/3" ) != -1 ); - $tests->{OPERA4} = ( index( $ua, "opera 4" ) != -1 ) - || ( index( $ua, "opera/4" ) != -1 - && ( index( $ua, "nintendo dsi" ) == -1 ) ); - $tests->{OPERA5} = ( index( $ua, "opera 5" ) != -1 ) - || ( index( $ua, "opera/5" ) != -1 ); - $tests->{OPERA6} = ( index( $ua, "opera 6" ) != -1 ) - || ( index( $ua, "opera/6" ) != -1 ); - $tests->{OPERA7} = ( index( $ua, "opera 7" ) != -1 ) - || ( index( $ua, "opera/7" ) != -1 ); - # Other browsers - $tests->{CURL} = ( index( $ua, "libcurl" ) != -1 ); $tests->{STAROFFICE} = ( index( $ua, "staroffice" ) != -1 ); $tests->{ICAB} = ( index( $ua, "icab" ) != -1 ); $tests->{LOTUSNOTES} = ( index( $ua, "lotus-notes" ) != -1 ); @@ -462,74 +525,11 @@ sub _test { $tests->{ELINKS} = ( index( $ua, "elinks" ) != -1 ); $tests->{WEBTV} = ( index( $ua, "webtv" ) != -1 ); $tests->{MOSAIC} = ( index( $ua, "mosaic" ) != -1 ); - $tests->{PUF} = ( index( $ua, "puf/" ) != -1 ); - $tests->{WGET} = ( index( $ua, "wget" ) != -1 ); - $tests->{GETRIGHT} = ( index( $ua, "getright" ) != -1 ); - $tests->{LWP} - = ( index( $ua, "libwww-perl" ) != -1 || index( $ua, "lwp-" ) != -1 ); - $tests->{YAHOO} = ( index( $ua, "yahoo" ) != -1 ) - && ( index( $ua, 'jp.co.yahoo.android' ) == -1 ); - $tests->{GOOGLE} = ( index( $ua, "googlebot" ) != -1 ); - $tests->{GOOGLEMOBILE} = ( index( $ua, "googlebot-mobile" ) != -1 ); - $tests->{MSN} = ( - ( index( $ua, "msnbot" ) != -1 || index( $ua, "bingbot" ) ) != -1 ); - $tests->{MSNMOBILE} = ( - ( index( $ua, "msnbot-mobile" ) != -1 - || index( $ua, "bingbot-mobile" ) - ) != -1 - ); $tests->{JAVA} = ( index( $ua, "java" ) != -1 || index( $ua, "jdk" ) != -1 || index( $ua, "jakarta commons-httpclient" ) != -1 ); - $tests->{ALTAVISTA} = ( index( $ua, "altavista" ) != -1 ); - $tests->{SCOOTER} = ( index( $ua, "scooter" ) != -1 ); - $tests->{LYCOS} = ( index( $ua, "lycos" ) != -1 ); - $tests->{INFOSEEK} = ( index( $ua, "infoseek" ) != -1 ); - $tests->{WEBCRAWLER} = ( index( $ua, "webcrawler" ) != -1 ); - $tests->{LINKEXCHANGE} = ( index( $ua, "lecodechecker" ) != -1 ); - $tests->{SLURP} = ( index( $ua, "slurp" ) != -1 ); - $tests->{FACEBOOK} = ( index( $ua, "facebookexternalhit" ) != -1 ); - $tests->{BAIDU} = ( index( $ua, "baiduspider" ) != -1 ); - $tests->{GOOGLEADSBOT} = ( index( $ua, "adsbot-google" ) != -1 ); - $tests->{ASKJEEVES} = ( index( $ua, "ask jeeves/teoma" ) != -1 ); - $tests->{ROBOT} = ( - ( $tests->{WGET} - || $tests->{PUF} - || $tests->{GETRIGHT} - || $tests->{LWP} - || $tests->{YAHOO} - || $tests->{ALTAVISTA} - || $tests->{LYCOS} - || $tests->{INFOSEEK} - || $tests->{WEBCRAWLER} - || $tests->{LINKEXCHANGE} - || $tests->{SLURP} - || $tests->{GOOGLE} - || $tests->{GOOGLEMOBILE} - || $tests->{MSN} - || $tests->{MSNMOBILE} - || $tests->{FACEBOOK} - || $tests->{JAVA} - || $tests->{BAIDU} - || $tests->{GOOGLEADSBOT} - || $tests->{ASKJEEVES} - ) - || index( $ua, "bot" ) != -1 - || index( $ua, "spider" ) != -1 - || index( $ua, "crawl" ) != -1 - || index( $ua, "agent" ) != -1 - || $ua =~ /seek (?! mo (?: toolbar )? \s+ \d+\.\d+ )/x - || $ua =~ /search (?! [\w\s]* toolbar \b | bar \b )/x - || index( $ua, "reap" ) != -1 - || index( $ua, "worm" ) != -1 - || index( $ua, "find" ) != -1 - || index( $ua, "index" ) != -1 - || index( $ua, "copy" ) != -1 - || index( $ua, "fetch" ) != -1 - || index( $ua, "ia_archive" ) != -1 - || index( $ua, "zyborg" ) != -1 - ); + $tests->{NETFRONT} = ( index( $ua, "playstation 3" ) != -1 || index( $ua, "playstation portable" ) != -1 @@ -537,21 +537,22 @@ sub _test { # Devices - $tests->{BLACKBERRY} = ( index( $ua, "blackberry" ) != -1 ); - $tests->{IPHONE} = ( index( $ua, "iphone" ) != -1 ); - $tests->{WINCE} = ( index( $ua, "windows ce" ) != -1 ); - $tests->{WINPHONE} = ( index( $ua, "windows phone" ) != -1 ); - $tests->{WEBOS} = ( index( $ua, "webos" ) != -1 ); - $tests->{IPOD} = ( index( $ua, "ipod" ) != -1 ); - $tests->{IPAD} = ( index( $ua, "ipad" ) != -1 ); - $tests->{KINDLE} = ( index( $ua, "kindle" ) != -1 ); - $tests->{AUDREY} = ( index( $ua, "audrey" ) != -1 ); - $tests->{IOPENER} = ( index( $ua, "i-opener" ) != -1 ); - $tests->{AVANTGO} = ( index( $ua, "avantgo" ) != -1 ); - $tests->{PALM} = ( $tests->{AVANTGO} || index( $ua, "palmos" ) != -1 ); - $tests->{OBIGO} = ( index( $ua, "obigo/" ) != -1 ); - $tests->{WAP} = ( - $tests->{OBIGO} + $tests->{BLACKBERRY} = ( index( $ua, "blackberry" ) != -1 + || index( $ua, "rim tablet os" ) != -1 ); + $tests->{IPHONE} = ( index( $ua, "iphone" ) != -1 ); + $tests->{WINCE} = ( index( $ua, "windows ce" ) != -1 ); + $tests->{WINPHONE} = ( index( $ua, "windows phone" ) != -1 ); + $tests->{WEBOS} = ( index( $ua, "webos" ) != -1 ); + $tests->{IPOD} = ( index( $ua, "ipod" ) != -1 ); + $tests->{IPAD} = ( index( $ua, "ipad" ) != -1 ); + $tests->{KINDLE} = ( index( $ua, "kindle" ) != -1 ); + $tests->{AUDREY} = ( index( $ua, "audrey" ) != -1 ); + $tests->{IOPENER} = ( index( $ua, "i-opener" ) != -1 ); + $tests->{AVANTGO} = ( index( $ua, "avantgo" ) != -1 ); + $tests->{PALM} = ( $tests->{AVANTGO} || index( $ua, "palmos" ) != -1 ); + $tests->{OBIGO} = ( index( $ua, "obigo/" ) != -1 ); + $tests->{WAP} + = ( $tests->{OBIGO} || index( $ua, "up.browser" ) != -1 || ( index( $ua, "nokia" ) != -1 && !$tests->{WINPHONE} ) || index( $ua, "alcatel" ) != -1 @@ -571,9 +572,11 @@ sub _test { $tests->{DSI} = ( index( $ua, "nintendo dsi" ) != -1 ); $tests->{'N3DS'} = ( index( $ua, "nintendo 3ds" ) != -1 ); - $tests->{MOBILE} = ( - ( $tests->{FIREFOX} && index( $ua, "mobile" ) != -1 ) + ( $tests->{FIREFOX} && index( $ua, "mobile" ) != -1 ) + || ( $tests->{IE} + && !$tests->{WINPHONE} + && index( $ua, "arm" ) != -1 ) || index( $ua, "up.browser" ) != -1 || index( $ua, "nokia" ) != -1 || index( $ua, "alcatel" ) != -1 @@ -596,8 +599,10 @@ sub _test { || index( $ua, "iphone" ) != -1 || index( $ua, "ipod" ) != -1 || index( $ua, "ipad" ) != -1 - || (index( $ua, "opera mini" ) != -1 && index( $ua, "tablet" ) == -1 ) - || (index( $ua, "android" ) != -1 && index( $ua, "mobile" ) != -1 ) + || ( index( $ua, "opera mini" ) != -1 + && index( $ua, "tablet" ) == -1 ) + || ( index( $ua, "android" ) != -1 + && index( $ua, "mobile" ) != -1 ) || index( $ua, "htc_" ) != -1 || index( $ua, "symbian" ) != -1 || index( $ua, "webos" ) != -1 @@ -609,17 +614,22 @@ sub _test { || index( $ua, "opera mobi" ) != -1 || index( $ua, "fennec" ) != -1 || index( $ua, "opera tablet" ) != -1 + || index( $ua, "rim tablet" ) != -1 || $tests->{PSP} || $tests->{DSI} || $tests->{'N3DS'} || $tests->{GOOGLEMOBILE} || $tests->{MSNMOBILE} ); - - + $tests->{TABLET} = ( - index( $ua, "ipad" ) != -1 - || (index( $ua, "android" ) != -1 && index( $ua, "mobile" ) == -1 && index( $ua, "opera" ) == -1 ) + index( $ua, "ipad" ) != -1 + || ( $tests->{IE} + && !$tests->{WINPHONE} + && index( $ua, "arm" ) != -1 ) + || ( index( $ua, "android" ) != -1 + && index( $ua, "mobile" ) == -1 + && index( $ua, "opera" ) == -1 ) || index( $ua, "kindle" ) != -1 || index( $ua, "xoom" ) != -1 || index( $ua, "flyer" ) != -1 @@ -639,13 +649,188 @@ sub _test { || index( $ua, "an10bg3" ) != -1 || index( $ua, "an10bg3dt" ) != -1 || index( $ua, "opera tablet" ) != -1 - || index( $ua, "hp-tablet" ) != -1 - - + || index( $ua, "rim tablet" ) != -1 + || index( $ua, "hp-tablet" ) + != -1 + ); # Operating System + # A final try at browser version, if we haven't gotten it so far + if ( !defined( $major ) || $major eq '' ) { + if ( $ua =~ /[A-Za-z]+\/(\d+)\;/ ) { + $major = $1; + $minor = 0; + } + + } + + # Gecko version + $self->{gecko_version} = undef; + if ( $tests->{GECKO} ) { + if ( $ua =~ /\([^)]*rv:([\w.\d]*)/ ) { + $self->{gecko_version} = $1; + } + } + + # Engines + + $self->{engine_version} = $self->{gecko_version}; + + if ( $ua =~ /trident\/([\w\.\d]*)/ ) { + $self->{engine_version} = $1; + } + + # RealPlayer + $tests->{REALPLAYER} + = ( index( $ua, "(r1 " ) != -1 || index( $ua, "realplayer" ) != -1 ); + + $self->{realplayer_version} = undef; + if ( $tests->{REALPLAYER} ) { + if ( $ua =~ /realplayer\/([\d+\.]+)/ ) { + $self->{realplayer_version} = $1; + my @version = split( /\./, $self->{realplayer_version} ); + $major = shift @version; + $minor = shift @version; + } + elsif ( $ua =~ /realplayer\s(\w+)/ ) { + $self->{realplayer_version} = $1; + } + } + + # Device from UA + + $self->{device_name} = undef; + + if ( $tests->{OBIGO} && $ua =~ /^(mot-\S+)/ ) { + $self->{device_name} = substr $self->{user_agent}, 0, length $1; + $self->{device_name} =~ s/^MOT-/Motorola /i; + } + elsif ( + $ua =~ /windows phone os [^\)]+ iemobile\/[^;]+; ([^;]+; [^;\)]+)/g ) + { + $self->{device_name} = substr $self->{user_agent}, + pos( $ua ) - length $1, length $1; + $self->{device_name} =~ s/; / /; + } + elsif ( $ua + =~ /windows phone [^\)]+ iemobile\/[^;]+; arm; touch; ([^;]+; [^;\)]+)/g + ) + { + $self->{device_name} = substr $self->{user_agent}, + pos( $ua ) - length $1, length $1; + $self->{device_name} =~ s/; / /; + } + + $self->{major} = $major; + $self->{minor} = $minor; + $self->{beta} = $beta; + + $self->_os_tests; + $self->_robot_tests; + + return undef unless $self->robot; + +} + +sub _robot_tests { + my $self = shift; + my $ua = lc $self->{user_agent}; + my $tests = $self->{tests}; + + $tests->{LWP} + = ( index( $ua, "libwww-perl" ) != -1 || index( $ua, "lwp-" ) != -1 ); + $tests->{YAHOO} = ( index( $ua, "yahoo" ) != -1 ) + && ( index( $ua, 'jp.co.yahoo.android' ) == -1 ); + $tests->{MSN} = ( + ( index( $ua, "msnbot" ) != -1 || index( $ua, "bingbot" ) ) != -1 ); + $tests->{MSNMOBILE} = ( + ( index( $ua, "msnbot-mobile" ) != -1 + || index( $ua, "bingbot-mobile" ) + ) != -1 + ); + + $tests->{ALTAVISTA} = ( index( $ua, "altavista" ) != -1 ); + $tests->{ASKJEEVES} = ( index( $ua, "ask jeeves/teoma" ) != -1 ); + $tests->{BAIDU} = ( index( $ua, "baiduspider" ) != -1 ); + $tests->{CURL} = ( index( $ua, "libcurl" ) != -1 ); + $tests->{FACEBOOK} = ( index( $ua, "facebookexternalhit" ) != -1 ); + $tests->{GETRIGHT} = ( index( $ua, "getright" ) != -1 ); + $tests->{GOOGLEADSBOT} = ( index( $ua, "adsbot-google" ) != -1 ); + $tests->{GOOGLEADSENSE} = ( index( $ua, "mediapartners-google" ) != -1 ); + $tests->{GOOGLEBOTIMAGE} = ( index( $ua, "googlebot-image" ) != -1 ); + $tests->{GOOGLEBOTNEWS} = ( index( $ua, "googlebot-news" ) != -1 ); + $tests->{GOOGLEBOTVIDEO} = ( index( $ua, "googlebot-video" ) != -1 ); + $tests->{GOOGLEMOBILE} = ( index( $ua, "googlebot-mobile" ) != -1 ); + $tests->{GOOGLE} = ( index( $ua, "googlebot" ) != -1 ); + $tests->{INFOSEEK} = ( index( $ua, "infoseek" ) != -1 ); + $tests->{LINKEXCHANGE} = ( index( $ua, "lecodechecker" ) != -1 ); + $tests->{LINKCHECKER} = ( index( $ua, "linkchecker" ) != -1 ); + $tests->{LYCOS} = ( index( $ua, "lycos" ) != -1 ); + $tests->{PUF} = ( index( $ua, "puf/" ) != -1 ); + $tests->{SCOOTER} = ( index( $ua, "scooter" ) != -1 ); + $tests->{SLURP} = ( index( $ua, "slurp" ) != -1 ); + $tests->{SPECIALARCHIVER} = ( index( $ua, "special_archiver" ) != -1 ); + $tests->{WEBCRAWLER} = ( index( $ua, "webcrawler" ) != -1 ); + $tests->{WGET} = ( index( $ua, "wget" ) != -1 ); + $tests->{YANDEXIMAGES} = ( index( $ua, "yandeximages" ) != -1 ); + + $tests->{ROBOT} + = ( $tests->{ALTAVISTA} + || $tests->{ASKJEEVES} + || $tests->{BAIDU} + || $tests->{FACEBOOK} + || $tests->{GETRIGHT} + || $tests->{GOOGLEADSBOT} + || $tests->{GOOGLEADSENSE} + || $tests->{GOOGLEMOBILE} + || $tests->{GOOGLEBOTNEWS} + || $tests->{GOOGLEBOTIMAGE} + || $tests->{GOOGLEBOTVIDEO} + || $tests->{GOOGLE} + || $tests->{INFOSEEK} + || $tests->{JAVA} + || $tests->{LINKEXCHANGE} + || $tests->{LINKCHECKER} + || $tests->{LWP} + || $tests->{LYCOS} + || $tests->{MSNMOBILE} + || $tests->{MSN} + || $tests->{PUF} + || $tests->{SLURP} + || $tests->{SPECIALARCHIVER} + || $tests->{WEBCRAWLER} + || $tests->{WGET} + || $tests->{YAHOO} + || $tests->{YANDEXIMAGES} ) + || index( $ua, "agent" ) != -1 + || index( $ua, "bot" ) != -1 + || index( $ua, "copy" ) != -1 + || index( $ua, "crawl" ) != -1 + || index( $ua, "fetch" ) != -1 + || index( $ua, "find" ) != -1 + || index( $ua, "ia_archive" ) != -1 + || index( $ua, "index" ) != -1 + || index( $ua, "reap" ) != -1 + || index( $ua, "spider" ) != -1 + || index( $ua, "worm" ) != -1 + || index( $ua, "zyborg" ) != -1 + || $ua =~ /seek (?! mo (?: toolbar )? \s+ \d+\.\d+ )/x + || $ua =~ /search (?! [\w\s]* toolbar \b | bar \b )/x; + + # Yahoo Slurp! hack this should apply to most browsers, but there's a case + # where GoogleBot masquerades as Safari on iOS. not sure how to handle + # that. + + delete $tests->{FIREFOX} if $self->robot; +} + +sub _os_tests { + my $self = shift; + my $tests = $self->{tests}; + my $ua = lc $self->{user_agent}; + $tests->{WIN16} = ( index( $ua, "win16" ) != -1 || index( $ua, "16bit" ) != -1 @@ -674,7 +859,9 @@ sub _test { $tests->{WIN2K3} = ( index( $ua, "nt 5.2" ) != -1 ); $tests->{WINVISTA} = ( index( $ua, "nt 6.0" ) != -1 ); $tests->{WIN7} = ( index( $ua, "nt 6.1" ) != -1 ); - $tests->{WIN8} = ( index( $ua, "nt 6.2" ) != -1 ); + $tests->{WIN8_0} = ( index( $ua, "nt 6.2" ) != -1 ); + $tests->{WIN8_1} = ( index( $ua, "nt 6.3" ) != -1 ); + $tests->{WIN8} = ( $tests->{WIN8_0} || $tests->{WIN8_1} ); $tests->{DOTNET} = ( index( $ua, ".net clr" ) != -1 ); $tests->{WINME} = ( index( $ua, "win 9x 4.90" ) != -1 ); # whatever @@ -756,8 +943,8 @@ sub _test { $tests->{AIX3} = ( index( $ua, "aix 3" ) != -1 ); $tests->{AIX4} = ( index( $ua, "aix 4" ) != -1 ); - $tests->{LINUX} = ( index( $ua, "inux" ) != -1 ); - $tests->{SCO} = $ua =~ m{(?:SCO|unix_sv)}; + $tests->{LINUX} = ( index( $ua, "inux" ) != -1 ); + $tests->{SCO} = $ua =~ m{(?:SCO|unix_sv)}; $tests->{UNIXWARE} = ( index( $ua, "unix_system_v" ) != -1 ); $tests->{MPRAS} = ( index( $ua, "ncr" ) != -1 ); $tests->{RELIANT} = ( index( $ua, "reliantunix" ) != -1 ); @@ -798,138 +985,117 @@ sub _test { && !$tests->{ANDROID} && index( $ua, "fennec" ) == -1 ); + $tests->{RIMTABLETOS} = ( index( $ua, "rim tablet os" ) != -1 ); + $tests->{PS3GAMEOS} = $tests->{PS3} && $tests->{NETFRONT}; $tests->{PSPGAMEOS} = $tests->{PSP} && $tests->{NETFRONT}; +} - # A final try at browser version, if we haven't gotten it so far - if ( !defined( $major ) || $major eq '' ) { - if ( $ua =~ /[A-Za-z]+\/(\d+)\;/ ) { - $major = $1; - $minor = 0; - } +# undocumented, experimental, volatile. not bothering with major/minor here as +# that's flawed for 3 point versions the plan is to move this parsing into the +# UeberAgent parser - } +sub os_version { + my $self = shift; - # Gecko version - $self->{gecko_version} = undef; - if ( $tests->{GECKO} ) { - if ( $ua =~ /\([^)]*rv:([\w.\d]*)/ ) { - $self->{gecko_version} = $1; - } + if ( $self->ios && $self->{user_agent} =~ m{OS (\d*_\d*|\d*_\d*_\d*) like Mac} ) { + my $version = $1; + $version =~ s{_}{.}g; + return $version; } - # Engines - - $tests->{TRIDENT} = ( index( $ua, "trident/" ) != -1 ); - - $self->{engine_version} = $self->{gecko_version}; - - if ( $ua =~ /trident\/([\w\.\d]*)/ ) { - $self->{engine_version} = $1; + if ( $self->mac && $self->{user_agent} =~ m{ X \s (\d\d)_(\d)_(\d)}x ) { + return join '.', $1, $2, $3; } - # RealPlayer - $tests->{REALPLAYER} - = ( index( $ua, "(r1 " ) != -1 || index( $ua, "realplayer" ) != -1 ); - - $self->{realplayer_version} = undef; - if ( $tests->{REALPLAYER} ) { - if ( $ua =~ /realplayer\/([\d+\.]+)/ ) { - $self->{realplayer_version} = $1; - my @version = split( /\./, $self->{realplayer_version} ); - $major = shift @version; - $minor = shift @version; - } - elsif ( $ua =~ /realplayer\s(\w+)/ ) { - $self->{realplayer_version} = $1; - } + # firefox in mac + # "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:25.0) Gecko/20100101 Firefox/25.0" + if ( $self->mac && $self->{user_agent} =~ m{ X \s (\d\d\.\d)}x ) { + return $1; } - # Device from UA - - $self->{device_name} = undef; - - if ( $tests->{OBIGO} && $ua =~ /^(mot-\S+)/ ) - { - $self->{device_name} = substr $self->{user_agent}, 0, length $1; - $self->{device_name} =~ s/^MOT-/Motorola /i; - } - elsif ( $ua =~ /windows phone os [^\)]+ iemobile\/[^;]+; ([^;]+; [^;\)]+)/g ) + if ( $self->winphone + && $self->{user_agent} =~ m{Windows \s Phone \s \w{0,2} \s{0,1} (\d+\.\d+);}x ) { - $self->{device_name} = substr $self->{user_agent}, - pos( $ua ) - length $1, length $1; - $self->{device_name} =~ s/; / /; + return $1; } - elsif ( $ua =~ /windows phone [^\)]+ iemobile\/[^;]+; arm; touch; ([^;]+; [^;\)]+)/g ) - { - $self->{device_name} = substr $self->{user_agent}, - pos( $ua ) - length $1, length $1; - $self->{device_name} =~ s/; / /; + + if ( $self->android && $self->{user_agent} =~ m{Android ([\d\.\w-]*)} ) { + return $1; } - $self->{major} = $major; - $self->{minor} = $minor; - $self->{beta} = $beta; + if ( $self->firefoxos && $self->{user_agent} =~ m{Firefox/([\d\.]*)} ) { + return $1; + } } +# because the internals are the way they are, these tests have to happen in a +# certain order. hopefully we can change this once we have lazily loaded +# attributes. in the meantime, a pile of returns will do the job. if we +# changed this to use a hash, we'd still need a carefully ordered array of keys +# in order to get something useful back. so, as it is, this actually wouldn't +# be that much less verbose and the order of operations is quite clear. it +# still feels dirty, though. it does highlight the fact that way too many +# methods can return true for some UA strings, which means there are probably a +# lot of false positives we haven't checked for. + sub browser_string { - my ( $self ) = _self_or_default( @_ ); - my $browser_string = undef; - my $user_agent = $self->user_agent; - if ( defined $user_agent ) { - $browser_string = 'Netscape' if $self->netscape; - $browser_string = 'Firefox' if $self->firefox; - $browser_string = 'Safari' if $self->safari; - $browser_string = 'Chrome' if $self->chrome; - $browser_string = 'MSIE' if $self->ie; - $browser_string = 'WebTV' if $self->webtv; - $browser_string = 'AOL Browser' if $self->aol; - $browser_string = 'Obigo' if $self->obigo; - $browser_string = 'Opera' if $self->opera; - $browser_string = 'Mosaic' if $self->mosaic; - $browser_string = 'Lynx' if $self->lynx; - $browser_string = 'Links' if $self->links; - $browser_string = 'RealPlayer' if $self->realplayer_browser; - $browser_string = 'IceWeasel' if $self->iceweasel; - $browser_string = 'curl' if $self->curl; - $browser_string = 'puf' if $self->puf; - $browser_string = 'NetFront' if $self->netfront; - $browser_string = 'Mobile Safari' if $self->mobile_safari; - $browser_string = 'ELinks' if $self->elinks; - $browser_string = 'BlackBerry' if $self->blackberry; - $browser_string = 'Nintendo 3DS' if $self->n3ds; - $browser_string = 'Nintendo DSi' if $self->dsi; - } - return $browser_string; + my ( $self ) = _self_or_default( @_ ); + return undef unless defined $self->{user_agent}; + + return 'Netscape' if $self->netscape; + return 'IceWeasel' if $self->iceweasel; + return 'Firefox' if $self->firefox; + return 'BlackBerry' if $self->blackberry; + return 'Mobile Safari' if $self->mobile_safari; + return 'RealPlayer' if $self->realplayer_browser; + return 'Safari' if $self->safari; + return 'Chrome' if $self->chrome; + return 'AOL Browser' if $self->aol; + return 'MSIE' if $self->ie; + return 'WebTV' if $self->webtv; + return 'Obigo' if $self->obigo; + return 'Nintendo DSi' if $self->dsi; + return 'Opera' if $self->opera; + return 'Mosaic' if $self->mosaic; + return 'Lynx' if $self->lynx; + return 'ELinks' if $self->elinks; + return 'Links' if $self->links; + return 'curl' if $self->curl; + return 'puf' if $self->puf; + return 'NetFront' if $self->netfront; + return 'Nintendo 3DS' if $self->n3ds; + return undef; } sub os_string { - my ( $self ) = _self_or_default( @_ ); - my $os_string = undef; - my $user_agent = $self->user_agent; - if ( defined $user_agent ) { - $os_string = 'Win95' if $self->win95; - $os_string = 'Win98' if $self->win98; - $os_string = 'WinNT' if $self->winnt; - $os_string = 'Win2k' if $self->win2k; - $os_string = 'WinXP' if $self->winxp; - $os_string = 'Win2k3' if $self->win2k3; - $os_string = 'WinVista' if $self->winvista; - $os_string = 'Win7' if $self->win7; - $os_string = 'Win8' if $self->win8; - $os_string = 'Windows Phone' if $self->winphone; - $os_string = 'Mac' if $self->mac; - $os_string = 'Mac OS X' if $self->macosx; - $os_string = 'Win3x' if $self->win3x; - $os_string = 'OS2' if $self->os2; - $os_string = 'Unix' if $self->unix && !$self->linux; - $os_string = 'Linux' if $self->linux; - $os_string = 'Firefox OS' if $self->firefoxos; - $os_string = 'Playstation 3 GameOS' if $self->ps3gameos; - $os_string = 'Playstation Portable GameOS' if $self->pspgameos; - $os_string = 'iOS' if $self->iphone || $self->ipod || $self->ipad; - } - return $os_string; + my ( $self ) = _self_or_default( @_ ); + return undef unless defined $self->{user_agent}; + + return 'Win95' if $self->win95; + return 'Win98' if $self->win98; + return 'Win2k' if $self->win2k; + return 'WinXP' if $self->winxp; + return 'Win2k3' if $self->win2k3; + return 'WinVista' if $self->winvista; + return 'Win7' if $self->win7; + return 'Win8' if $self->win8_0; + return 'Win8.1' if $self->win8_1; + return 'WinNT' if $self->winnt; + return 'Windows Phone' if $self->winphone; + return 'Win3x' if $self->win3x; + return 'Android' if $self->android; + return 'Linux' if $self->linux; + return 'Unix' if $self->unix; + return 'Firefox OS' if $self->firefoxos; + return 'RIM Tablet OS' if $self->rimtabletos; + return 'Playstation 3 GameOS' if $self->ps3gameos; + return 'Playstation Portable GameOS' if $self->pspgameos; + return 'iOS' if $self->iphone || $self->ipod || $self->ipad; + return 'Mac OS X' if $self->macosx; + return 'Mac' if $self->mac; + return 'OS2' if $self->os2; + return undef; } sub realplayer { @@ -942,7 +1108,9 @@ sub realplayer { sub _realplayer_version { my ( $self, $check ) = _self_or_default( @_ ); - if ( exists $self->{realplayer_version} && $self->{realplayer_version} ) { + if ( exists $self->{realplayer_version} + && $self->{realplayer_version} ) + { my @version = split( /\./, $self->{realplayer_version} ); $self->{major} = shift @version; $self->{minor} = $self->_format_minor( shift @version ); @@ -1040,7 +1208,7 @@ sub _public { # Return Public version of Safari. See RT #48727. if ( $self->safari ) { - my $ua = lc $self->user_agent; + my $ua = lc $self->{user_agent}; # Safari starting with version 3.0 provides its own public version if ($ua =~ m{ @@ -1065,12 +1233,12 @@ sub _public { # lower build for my $maybe_build ( - sort { $b <=> $a } + sort { $self->_cmp_versions( $b, $a ) } keys %safari_build_to_version ) { $version = $safari_build_to_version{$maybe_build}, last - if $build >= $maybe_build; + if $self->_cmp_versions( $build, $maybe_build ) >= 0; } } my ( $major, $minor ) = split /\./, $version; @@ -1084,11 +1252,27 @@ sub _public { return ( $self->major, $self->minor, $self->beta( $check ) ); } +sub _cmp_versions { + my ( $self, $a, $b ) = @_; + + my @a = split /\./, $a; + my @b = split /\./, $b; + + while ( @b ) { + return -1 if @a == 0 || $a[0] < $b[0]; + return 1 if @b == 0 || $b[0] < $a[0]; + shift @a; + shift @b; + } + + return @a <=> @b; +} + sub engine_string { my ( $self, $check ) = _self_or_default( @_ ); - if ( $self->user_agent =~ m{\bKHTML\b} ) { + if ( $self->{user_agent} =~ m{\bKHTML\b} ) { return 'KHTML'; } @@ -1214,28 +1398,30 @@ sub _language_country { if ( $self->safari ) { if ( $self->major == 1 - && $self->user_agent =~ m/\s ( [a-z]{2} ) \)/xms ) + && $self->{user_agent} =~ m/\s ( [a-z]{2} ) \)/xms ) { return { language => uc $1 }; } - if ( $self->user_agent =~ m/\s ([a-z]{2})-([A-Za-z]{2})/xms ) { + if ( $self->{user_agent} =~ m/\s ([a-z]{2})-([A-Za-z]{2})/xms ) { return { language => uc $1, country => uc $2 }; } } - if ( $self->aol && $self->user_agent =~ m/;([A-Z]{2})_([A-Z]{2})\)/ ) { + if ( $self->aol + && $self->{user_agent} =~ m/;([A-Z]{2})_([A-Z]{2})\)/ ) + { return { language => $1, country => $2 }; } - if ( $self->user_agent =~ m/\b([a-z]{2})-([A-Za-z]{2})\b/xms ) { + if ( $self->{user_agent} =~ m/\b([a-z]{2})-([A-Za-z]{2})\b/xms ) { return { language => uc $1, country => uc $2 }; } - if ( $self->user_agent =~ m/\[([a-z]{2})\]/xms ) { + if ( $self->{user_agent} =~ m/\[([a-z]{2})\]/xms ) { return { language => uc $1 }; } - if ( $self->user_agent =~ m/\(([^)]+)\)/xms ) { + if ( $self->{user_agent} =~ m/\(([^)]+)\)/xms ) { my @parts = split( /;/, $1 ); foreach my $part ( @parts ) { if ( $part =~ /^\s*([a-z]{2})\s*$/ ) { @@ -1272,6 +1458,17 @@ sub browser_properties { return @browser_properties; } + +sub robot_name { + my $self = shift; + foreach my $name ( @ROBOT_TESTS ) { + next if $name eq 'robot'; + if ( $self->$name ) { + return $ROBOTS{$name}; + } + } +} + 1; # ABSTRACT: Determine Web browser, version, and platform from an HTTP user agent string @@ -1303,11 +1500,6 @@ __END__ ...; } - # Process a different user agent string - $browser->user_agent($another_user_agent_string); - - - =head1 DESCRIPTION The HTTP::BrowserDetect object does a number of tests on an HTTP user agent @@ -1332,12 +1524,12 @@ HTTP::BrowserDetect object that is created behind the scenes. =head1 SUBROUTINES/METHODS -=head2 user_agent($user_agent_string) +=head2 user_agent() + +Returns the value of the user agent string. -Returns the value of the user agent string. When called with a parameter, it -resets the user agent and reperforms all tests on the string. This way you can -process a series of user agent strings (from a log file, perhaps) without -creating a new HTTP::BrowserDetect object each time. +Calling this method with a parameter has now been deprecated and this feature +will be removed in an upcoming release. =head2 country() @@ -1480,7 +1672,9 @@ winnt, which is a type of win32) win32 winme win95 win98 winnt - win2k winxp win2k3 winvista win7 win8 + win2k winxp win2k3 winvista win7 + win8 + win8_0 win8_1 wince winphone winphone7 winphone7_5 winphone8 @@ -1495,6 +1689,8 @@ mac68k macppc macosx ios =head2 os2() +=head2 rimtabletos() + =head2 unix() sun sun4 sun5 suni86 irix irix5 irix6 hpux hpux9 hpux10 @@ -1519,8 +1715,9 @@ Returns one of the following strings, or undef. This method exists solely for compatibility with the L module. Win95, Win98, WinNT, Win2K, WinXP, Win2k3, WinVista, Win7, Win8, - Windows Phone, Mac, Mac OS X, iOS, Win3x, OS2, Unix, Linux, - Firefox OS, Playstation 3 GameOS, Playstation Portable GameOS + Win8.1, Windows Phone, Mac, Mac OS X, iOS, Win3x, OS2, Unix, Linux, + Firefox OS, Playstation 3 GameOS, Playstation Portable GameOS, + RIM Tablet OS =head1 Detecting Browser Vendor @@ -1542,7 +1739,7 @@ version separately. =head3 icab -=head3 ie ie3 ie4 ie4up ie5 ie55 ie6 ie7 ie8 ie9 ie10 +=head3 ie ie3 ie4 ie4up ie5 ie55 ie6 ie7 ie8 ie9 ie10 ie11 =head3 java @@ -1593,7 +1790,7 @@ Returns undef on failure. Otherwise returns one of the following: Netscape, Firefox, Safari, Chrome, MSIE, WebTV, AOL Browser, Opera, Mosaic, Lynx, Links, ELinks, RealPlayer, IceWeasel, curl, puf, NetFront, Mobile Safari, -BlackBerry +BlackBerry. =head2 gecko_version() @@ -1671,6 +1868,8 @@ value. This is by no means a complete list of robots that exist on the Web. =head3 googleadsbot +=head3 googleadsense + =head3 googlemobile =head3 infoseek @@ -1780,6 +1979,8 @@ Aran Deltac yeahoffline +David Ihnen + =head1 TO DO The C<_engine()> method currently only handles Gecko and Trident. It needs to @@ -1789,15 +1990,9 @@ POD coverage is also not 100%. =head1 SEE ALSO -"The Ultimate JavaScript Client Sniffer, Version 3.0", L - "Browser ID (User-Agent) Strings", L -Safari "Historical User Agent strings", L (now gone, retrieved 2007-06-20) - -"Safari Agent Strings", L - -perl(1), L, L. +L. =head1 From 12015d45f33ef03365684797a54c68059ace9ada Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Tue, 3 Dec 2013 09:49:32 -0500 Subject: [PATCH 335/369] Bump release to 4.1.0 --- conf/pf-release | 2 +- docs/docinfo.xml | 6 +++--- docs/includes/global-attributes.asciidoc | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/conf/pf-release b/conf/pf-release index b0bf22650ccd..98dc8065b659 100644 --- a/conf/pf-release +++ b/conf/pf-release @@ -1 +1 @@ -PacketFence 4.0.7 +PacketFence 4.1.0 diff --git a/docs/docinfo.xml b/docs/docinfo.xml index bbd7e47e1324..c4824483c4bd 100644 --- a/docs/docinfo.xml +++ b/docs/docinfo.xml @@ -1,7 +1,7 @@ -Version 4.0.6 - September 2013 -for version 4.0.6 -2013-09-05 +Version 4.1.0 - December 2013 +for version 4.1.0 +2013-12-05 Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License". diff --git a/docs/includes/global-attributes.asciidoc b/docs/includes/global-attributes.asciidoc index f78a04693a8c..ba7e8ff6c068 100644 --- a/docs/includes/global-attributes.asciidoc +++ b/docs/includes/global-attributes.asciidoc @@ -13,6 +13,6 @@ // TODO have the build system take care of this -:release_version: 4.0.6 +:release_version: 4.1.0 // vim: set syntax=asciidoc tabstop=2 shiftwidth=2 expandtab: From 8dd8caae28794cdf97d9ac45e5c918a8f9440f59 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Tue, 3 Dec 2013 10:06:24 -0500 Subject: [PATCH 336/369] Fix warning in condition in pf::vlan --- lib/pf/vlan.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pf/vlan.pm b/lib/pf/vlan.pm index 986ca7665396..eb6bdaa1e7bb 100644 --- a/lib/pf/vlan.pm +++ b/lib/pf/vlan.pm @@ -89,7 +89,7 @@ sub fetchVlanForNode { my $registration = $this->getRegistrationVlan($switch, $ifIndex, $mac, $node_info, $connection_type, $user_name, $ssid); if (defined($registration) && $registration != 0) { - if ( ($connection_type & $WIRELESS_MAC_AUTH) == $WIRELESS_MAC_AUTH ) { + if ( $connection_type && ($connection_type & $WIRELESS_MAC_AUTH) == $WIRELESS_MAC_AUTH ) { my $notes = $node_info->{'notes'}; @@ -344,10 +344,10 @@ sub getNormalVlan { my $role = ""; # Try MAC_AUTH, then other EAP methods and finally anything else. - if ( ($connection_type & $WIRED_MAC_AUTH) == $WIRED_MAC_AUTH ) { + if ( $connection_type && ($connection_type & $WIRED_MAC_AUTH) == $WIRED_MAC_AUTH ) { $logger->info("Connection type is WIRED_MAC_AUTH. Getting role from node_info" ); $role = $node_info->{'category'}; - } elsif ( ($connection_type & $WIRELESS_MAC_AUTH) == $WIRELESS_MAC_AUTH ) { + } elsif ( $connection_type && ($connection_type & $WIRELESS_MAC_AUTH) == $WIRELESS_MAC_AUTH ) { $logger->info("Connection type is WIRELESS_MAC_AUTH. Getting role from node_info" ); $role = $node_info->{'category'}; From 850c83c6e43d52e6b0579b6bf8353b3a2a7e2c47 Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Tue, 3 Dec 2013 14:33:48 -0500 Subject: [PATCH 337/369] added a new column in node table to detect if the node has been auto registered --- NEWS.asciidoc | 1 + db/pf-schema-4.1.0.sql | 1 + db/upgrade-4.0.0-4.1.0.sql | 6 ++++++ lib/pf/node.pm | 18 ++++++++++-------- lib/pf/vlan.pm | 13 ++++++------- 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/NEWS.asciidoc b/NEWS.asciidoc index c01473b7811d..94b6faa72982 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -48,6 +48,7 @@ Enhancements * Allow actions depending on authentication source type * Modified logrotate so it uses copytruncate instead of restarting the services. * Now comes with a corosync compatible barnyard2 init script in addons. +* Unreg the node when you come from a secure connection to an open connection Bug Fixes +++++++++ diff --git a/db/pf-schema-4.1.0.sql b/db/pf-schema-4.1.0.sql index 84118f8ec43c..d7c2917ec956 100644 --- a/db/pf-schema-4.1.0.sql +++ b/db/pf-schema-4.1.0.sql @@ -104,6 +104,7 @@ CREATE TABLE node ( dhcp_fingerprint varchar(255) default NULL, `bypass_vlan` varchar(50) default NULL, `voip` enum('no','yes') NOT NULL DEFAULT 'no', + `autoreg` enum('no','yes') NOT NULL DEFAULT 'no', PRIMARY KEY (mac), KEY pid (pid), KEY category_id (category_id), diff --git a/db/upgrade-4.0.0-4.1.0.sql b/db/upgrade-4.0.0-4.1.0.sql index 38642e1e7658..a5f5bc04a452 100644 --- a/db/upgrade-4.0.0-4.1.0.sql +++ b/db/upgrade-4.0.0-4.1.0.sql @@ -11,3 +11,9 @@ ALTER TABLE `temporary_password` MODIFY category int DEFAULT NULL; ALTER TABLE temporary_password CHANGE access_level access_level varchar(255) DEFAULT 'NONE'; UPDATE temporary_password SET access_level = 'ALL' WHERE access_level = '4294967295'; UPDATE temporary_password SET access_level = 'NONE' WHERE access_level = '0'; + +-- +-- Added a new column to set if the node has been registered by auto registration +-- + +ALTER TABLE `node` ADD `autoreg` enum('no','yes') NOT NULL DEFAULT 'no' AFTER voip; diff --git a/lib/pf/node.pm b/lib/pf/node.pm index c1da483abf8c..558dc9ba5896 100644 --- a/lib/pf/node.pm +++ b/lib/pf/node.pm @@ -126,7 +126,7 @@ sub node_db_prepare { detect_date=?, regdate=?, unregdate=?, lastskip=?, user_agent=?, computername=?, dhcp_fingerprint=?, last_arp=?, last_dhcp=?, - notes=? + notes=?, autoreg=? WHERE mac=? ]); @@ -136,7 +136,7 @@ sub node_db_prepare { detect_date, regdate, unregdate, lastskip, user_agent, computername, dhcp_fingerprint, last_arp, last_dhcp, - node.notes + node.notes, autoreg FROM node LEFT JOIN node_category USING (category_id) WHERE mac = ? @@ -148,7 +148,7 @@ sub node_db_prepare { detect_date, regdate, unregdate, lastskip, user_agent, computername, IFNULL(os_class.description, ' ') as dhcp_fingerprint, last_arp, last_dhcp, - node.notes + node.notes, autoreg FROM node LEFT JOIN node_category USING (category_id) LEFT JOIN dhcp_fingerprint ON node.dhcp_fingerprint=dhcp_fingerprint.fingerprint @@ -183,7 +183,7 @@ sub node_db_prepare { node.detect_date, node.regdate, node.unregdate, node.lastskip, node.user_agent, node.computername, node.dhcp_fingerprint, node.last_arp, node.last_dhcp, - node.notes, + node.notes, autoreg, UNIX_TIMESTAMP(node.regdate) AS regdate_timestamp, UNIX_TIMESTAMP(node.unregdate) AS unregdate_timestamp FROM node @@ -402,7 +402,7 @@ sub node_add { 'detect_date', 'regdate', 'unregdate', 'lastskip', 'user_agent', 'computername', 'dhcp_fingerprint', 'last_arp', 'last_dhcp', - 'notes' + 'notes', 'autoreg' ) { $data{$field} = "" if ( !defined $data{$field} ); } @@ -422,7 +422,7 @@ sub node_add { $data{detect_date}, $data{regdate}, $data{unregdate}, $data{lastskip}, $data{user_agent}, $data{computername}, $data{dhcp_fingerprint}, $data{last_arp}, $data{last_dhcp}, - $data{notes} + $data{notes}, $data{autoreg} ) || return (0); return (1); } @@ -441,7 +441,8 @@ sub node_add_simple { 'last_skip' => 0, 'status' => 'unreg', 'last_dhcp' => 0, - 'voip' => 'no' + 'voip' => 'no', + 'autoreg' => 'no' ); if ( !node_add( $mac, %tmp ) ) { return (0); @@ -772,7 +773,7 @@ sub node_modify { $existing->{detect_date}, $existing->{regdate}, $existing->{unregdate}, $existing->{lastskip}, $existing->{user_agent}, $existing->{computername}, $existing->{dhcp_fingerprint}, $existing->{last_arp}, $existing->{last_dhcp}, - $existing->{notes}, + $existing->{notes},$existing->{autoreg}, $mac ); return ($sth->rows); @@ -1169,3 +1170,4 @@ USA. =cut 1; + diff --git a/lib/pf/vlan.pm b/lib/pf/vlan.pm index eb6bdaa1e7bb..9ff1f0ab8e64 100644 --- a/lib/pf/vlan.pm +++ b/lib/pf/vlan.pm @@ -92,11 +92,10 @@ sub fetchVlanForNode { if ( $connection_type && ($connection_type & $WIRELESS_MAC_AUTH) == $WIRELESS_MAC_AUTH ) { - my $notes = $node_info->{'notes'}; - if ($notes eq 'AUTO-REGISTERED') { - $logger->info("Connection type is WIRELESS_MAC_AUTH and the device was comming from a secure SSID with auto registration" ); + if (isenabled($notes->{'autoreg'})) { + $logger->info("Connection type is WIRELESS_MAC_AUTH and the device was coming from a secure SSID with auto registration" ); my %info = ( - 'notes' => '', + 'autoreg' => 'no', ); node_modify($mac,%info); } @@ -351,13 +350,12 @@ sub getNormalVlan { $logger->info("Connection type is WIRELESS_MAC_AUTH. Getting role from node_info" ); $role = $node_info->{'category'}; - my $notes = $node_info->{'notes'}; - if ($notes eq 'AUTO-REGISTERED') { + if (isenabled($notes->{'äutoreg'})) { $logger->info("Device is comming from a secure connection and has been auto registered, we unreg it and forward it to the portal" ); $role = 'registration'; my %info = ( 'status' => 'unreg', - 'notes' => '', + 'autoreg' => 'no', ); node_modify($mac,%info); } @@ -449,6 +447,7 @@ sub getNodeInfoForAutoReg { notes => 'AUTO-REGISTERED', status => 'reg', auto_registered => 1, # tells node_register to autoreg + autoreg => 'yes', ); # if we are called from a violation with action=autoreg, say so From c8db7ae8bf9650c11e598d18f490dbda15871567 Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Tue, 3 Dec 2013 14:43:05 -0500 Subject: [PATCH 338/369] Fix syntax --- lib/pf/vlan.pm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/pf/vlan.pm b/lib/pf/vlan.pm index 9ff1f0ab8e64..b2a7da4880f4 100644 --- a/lib/pf/vlan.pm +++ b/lib/pf/vlan.pm @@ -91,8 +91,7 @@ sub fetchVlanForNode { if ( $connection_type && ($connection_type & $WIRELESS_MAC_AUTH) == $WIRELESS_MAC_AUTH ) { - - if (isenabled($notes->{'autoreg'})) { + if (isenabled($node_info->{'autoreg'})) { $logger->info("Connection type is WIRELESS_MAC_AUTH and the device was coming from a secure SSID with auto registration" ); my %info = ( 'autoreg' => 'no', @@ -350,7 +349,7 @@ sub getNormalVlan { $logger->info("Connection type is WIRELESS_MAC_AUTH. Getting role from node_info" ); $role = $node_info->{'category'}; - if (isenabled($notes->{'äutoreg'})) { + if (isenabled($node_info->{'autoreg'})) { $logger->info("Device is comming from a secure connection and has been auto registered, we unreg it and forward it to the portal" ); $role = 'registration'; my %info = ( From 6b6073b9e868299ab5b38c090c65fc4812c44bd7 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Tue, 3 Dec 2013 14:45:18 -0500 Subject: [PATCH 339/369] Change the default admin level --- conf/authentication.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/authentication.conf b/conf/authentication.conf index ba70dcfc2c6e..88a10aefe54e 100644 --- a/conf/authentication.conf +++ b/conf/authentication.conf @@ -10,7 +10,7 @@ type=Htpasswd [file1 rule admins] description=All admins match=all -action0=set_access_level=4294967295 +action0=set_access_level=ALL [sms] description=SMS-based registration From 9b006cf3ce431fdd85ef87ee5c239dd76f5efbea Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Wed, 4 Dec 2013 09:26:41 -0500 Subject: [PATCH 340/369] Missing autoreg in node_add sql and test if pf.conf exist before trying to manage iptables --- bin/pfcmd.pl | 2 +- lib/pf/node.pm | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/pfcmd.pl b/bin/pfcmd.pl index ac6db1a01c5d..6e206a0392bc 100755 --- a/bin/pfcmd.pl +++ b/bin/pfcmd.pl @@ -1199,7 +1199,7 @@ sub startService { my @managers = getManagers(\@services,INCLUDE_DEPENDS_ON | JUST_MANAGED); print $SERVICE_HEADER; my $count = 0; - if(isIptablesManaged($service)) { + if(isIptablesManaged($service) && -e $pf_config_file) { $logger->info("saving current iptables to var/iptables.bak"); my $technique; if(all { $_->status eq '0' } @managers) { diff --git a/lib/pf/node.pm b/lib/pf/node.pm index 558dc9ba5896..d88fa7e0d95f 100644 --- a/lib/pf/node.pm +++ b/lib/pf/node.pm @@ -112,9 +112,9 @@ sub node_db_prepare { detect_date, regdate, unregdate, lastskip, user_agent, computername, dhcp_fingerprint, last_arp, last_dhcp, - notes + notes, autoreg ) VALUES ( - ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? + ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) ]); From 0a791b092e41a9a72b9ded4c15e2cd240e72c783 Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Wed, 4 Dec 2013 10:25:55 -0500 Subject: [PATCH 341/369] Update doc for dynamic radius client and fix sql syntax --- .../PacketFence_Administration_Guide.asciidoc | 24 +++++++++++++++---- raddb/sites-available/dynamic-clients | 2 +- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/docs/PacketFence_Administration_Guide.asciidoc b/docs/PacketFence_Administration_Guide.asciidoc index 2151e2c58468..094fe00970f5 100644 --- a/docs/PacketFence_Administration_Guide.asciidoc +++ b/docs/PacketFence_Administration_Guide.asciidoc @@ -879,9 +879,25 @@ attempting to attack each other. FreeRADIUS Configuration ~~~~~~~~~~~~~~~~~~~~~~~~ -This section presents the FreeRADIUS configuration steps. In some occasions, a RADIUS server is mandatory in order to give access to the network. For example, the usage of WPA2-Enterprise (Wireless 802.1X), MAC authentication and Wired 802.1X all requires a RADIUS server to authenticate the users and the devices, and then to push the proper VLAN to the network equipment. We strongly recommend that you install FreeRADIUS even if you plan not to use the feature now. +This section presents the FreeRADIUS configuration steps. In some occasions, a RADIUS server is mandatory in order to give access to the network. For example, the usage of WPA2-Enterprise (Wireless 802.1X), MAC authentication and Wired 802.1X all requires a RADIUS server to authenticate the users and the devices, and then to push the proper VLAN to the network equipment. -Option 1: Authentication against Active Directory (AD) +Option 1: Dynamic switch configuration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Since PacketFence version 4.1 you are now be able to enable dynamic clients. +It mean that when you add a new switch configuration in PacketFence´s administration interface you don´t have to restart radiusd service. + +To enable this feature make a symlink in `/usr/local/pf/raddb/site-enabled` directory: + + ln -s ../sites-available/dynamic-clients dynamic-clients + +and of course restart radiusd: + + /usr/local/pf/bin/pfcmd service radiusd restart + + + +Option 2: Authentication against Active Directory (AD) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Replace `/usr/local/pf/raddb/modules/mschap` with the following configuration: @@ -1054,14 +1070,14 @@ For Debian and Ubuntu: rad_recv: Access-Accept packet from host 127.0.0.1 port 18120, id=108, length=20 -Option 2: Local Authentication +Option 3: Local Authentication ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Add your user's entries at the end of the `/usr/local/pf/raddb/users` file with the following format: username Cleartext-Password := "password" -Option 3: Authentication against OpenLDAP +Option 4: Authentication against OpenLDAP ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ To be contributed... diff --git a/raddb/sites-available/dynamic-clients b/raddb/sites-available/dynamic-clients index 69705c2346a8..b230fcbf28c8 100644 --- a/raddb/sites-available/dynamic-clients +++ b/raddb/sites-available/dynamic-clients @@ -119,7 +119,7 @@ server dynamic_client_server { # # This requires the SQL module to be configured, of course. update control { - Tmp-String-8 = "%{sql: SELECT nasname FROM radius_nas WHERE nasname '%{Packet-Src-IP-Address}'}" + Tmp-String-8 = "%{sql: SELECT nasname FROM radius_nas WHERE nasname = '%{Packet-Src-IP-Address}'}" } if ("%{control:Tmp-String-8}") { update control { From b3191cbb2aa5cb2a033f6fd72e21ed0b693a3948 Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Wed, 4 Dec 2013 13:16:48 -0500 Subject: [PATCH 342/369] Added autoreg default value in node_modify --- lib/pf/node.pm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/pf/node.pm b/lib/pf/node.pm index d88fa7e0d95f..7683fcf50d28 100644 --- a/lib/pf/node.pm +++ b/lib/pf/node.pm @@ -750,6 +750,11 @@ sub node_modify { delete $existing->{'category'} if defined($existing->{'category'}); } + # Autoregistration handling + if (!defined($data{'autoreg'})) { + $existing->{autoreg} = 'no'; + } + my $new_mac = lc( $existing->{'mac'} ); my $new_status = $existing->{'status'}; From db4b7ce341b4f3cb9cbad8f7f4d13619124a6e31 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Wed, 4 Dec 2013 14:34:44 -0500 Subject: [PATCH 343/369] Will pass orginal url to captive portal as the destination_url --- lib/pf/web/dispatcher.pm | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/pf/web/dispatcher.pm b/lib/pf/web/dispatcher.pm index 920480b6052f..b09b36284b35 100755 --- a/lib/pf/web/dispatcher.pm +++ b/lib/pf/web/dispatcher.pm @@ -14,6 +14,8 @@ use Apache2::RequestRec (); use Apache2::Response (); use Apache2::RequestUtil (); use Apache2::ServerRec; +use Apache2::URI (); +use Apache2::Util (); use APR::Table; use APR::URI; @@ -35,7 +37,7 @@ use pf::proxypassthrough::constants; Implementation of PerlTransHandler. Rewrite all URLs except those explicitly allowed by the Captive portal. -For simplicity and performance this doesn't consume and leverage +For simplicity and performance this doesn't consume and leverage L. Reference: http://perl.apache.org/docs/2.0/user/handlers/http.html#PerlTransHandler @@ -99,7 +101,7 @@ sub translate { =item handler -For simplicity and performance this doesn't consume and leverage +For simplicity and performance this doesn't consume and leverage L. =cut @@ -108,7 +110,8 @@ sub handler { my ($r) = @_; my $logger = Log::Log4perl->get_logger(__PACKAGE__); $logger->trace('hitting redirector'); - + my $url = $r->construct_url; + my $orginal_url = Apache2::Util::escape_path($url,$r->pool); my $proto; # Google chrome hack redirect in http if ($r->uri =~ /\/generate_204/) { @@ -118,7 +121,7 @@ sub handler { } my $stash = { - 'login_url' => "$proto://".$Config{'general'}{'hostname'}.".".$Config{'general'}{'domain'}."/captive-portal", + 'login_url' => "$proto://".$Config{'general'}{'hostname'}.".".$Config{'general'}{'domain'}."/captive-portal?destination_url=$orginal_url", 'login_url_wispr' => "$proto://".$Config{'general'}{'hostname'}.".".$Config{'general'}{'domain'}."/wispr", }; @@ -194,22 +197,22 @@ Inverse inc. Copyright (C) 2005-2013 Inverse inc. =head1 LICENSE - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -USA. - +USA. + =cut 1; From aeeb54f2d3c435a68fd52c85a683b2b778c89a75 Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Thu, 5 Dec 2013 10:04:54 -0500 Subject: [PATCH 344/369] Fix redirect_url --- lib/pf/web.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pf/web.pm b/lib/pf/web.pm index 8562467a72a2..1384c17eec3a 100644 --- a/lib/pf/web.pm +++ b/lib/pf/web.pm @@ -170,7 +170,7 @@ sub generate_release_page { $portalSession->stash({ timer => $Config{'trapping'}{'redirtimer'}, - redirect_url => $portalSession->getProfile->getRedirectURL, + redirect_url => $portalSession->getDestinationUrl(), initial_delay => $CAPTIVE_PORTAL{'NET_DETECT_INITIAL_DELAY'}, retry_delay => $CAPTIVE_PORTAL{'NET_DETECT_RETRY_DELAY'}, external_ip => $Config{'captive_portal'}{'network_detection_ip'}, @@ -179,7 +179,7 @@ sub generate_release_page { # override destination_url if we enabled the always_use_redirecturl option if (isenabled($portalSession->getProfile->forceRedirectURL)) { - $portalSession->stash->{'destination_url'} = $portalSession->getProfile->getRedirectURL; + $portalSession->stash->{'redirect_url'} = $portalSession->getProfile->getRedirectURL; } render_template($portalSession, 'release.html', $r); From 5c04de6f2e8e9bbaad7ee49caff574758a41bf4e Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Thu, 5 Dec 2013 14:40:30 -0500 Subject: [PATCH 345/369] Fixed pid of SMS-registered devices --- NEWS.asciidoc | 1 + html/captive-portal/mobile-confirmation.cgi | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/NEWS.asciidoc b/NEWS.asciidoc index 94b6faa72982..6726072e40c6 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -69,6 +69,7 @@ Bug Fixes * Fixed duplicate entries in advanced search of nodes * Fixed advanced search by node category * Fixed reordering of conf sections and groups (#1749) +* Fixed pid of SMS-registered devices (was "admin" in certain circumstances) Version 4.0.6-2 released on 2013-09-13 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/html/captive-portal/mobile-confirmation.cgi b/html/captive-portal/mobile-confirmation.cgi index baaa4cc93ed4..f127e28c0b09 100755 --- a/html/captive-portal/mobile-confirmation.cgi +++ b/html/captive-portal/mobile-confirmation.cgi @@ -66,7 +66,8 @@ if ( $portalSession->getCgi->param("pin") ) { $logger->info("Valid PIN -- Registering user"); - my $pid = $portalSession->getSession->param("guest_pid") || "admin"; + my $node_info = node_attributes($portalSession->getClientMac()); + my $pid = $node_info->{'pid'} || 'admin'; my $sms_type = pf::Authentication::Source::SMSSource->meta->get_attribute('type')->default; my $source = $portalSession->getProfile->getSourceByType($sms_type); my $auth_params = { 'username' => $pid }; @@ -86,9 +87,6 @@ if ( $portalSession->getCgi->param("pin") ) { pf::web::web_node_register($portalSession, $pid, %info); - # clear state that redirects to the Enter PIN page - $portalSession->getSession->clear(["guest_pid"]); - pf::web::end_portal_session($portalSession); } else { From 8ad273092bbc8ca61c355b0c882a10494ed560c4 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Thu, 5 Dec 2013 16:47:09 -0500 Subject: [PATCH 346/369] Initial destination URL is now respected with FF --- NEWS.asciidoc | 1 + html/captive-portal/templates/pending.html | 2 +- html/captive-portal/templates/release.html | 2 +- .../captive-portal/templates/scan-in-progress.html | 2 +- html/common/pf.js | 12 ++++++------ lib/pf/Portal/Session.pm | 5 +++-- lib/pf/web.pm | 14 ++------------ 7 files changed, 15 insertions(+), 23 deletions(-) diff --git a/NEWS.asciidoc b/NEWS.asciidoc index 6726072e40c6..3c8924707b68 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -40,6 +40,7 @@ Enhancements * Improved validation of VLAN management * Updated FontAwesome to version 3.2.1 * Each portal profile can now have a different redirection URL +* Initial destination URL is now respected with Firefox * An Htpasswd source can now define sponsors * Improved display of pie charts (limit of legend labels and highlight of table rows) * Creation of users is now performed from the users page (was on the configuration page) diff --git a/html/captive-portal/templates/pending.html b/html/captive-portal/templates/pending.html index 199755e9987b..dbe84d801010 100644 --- a/html/captive-portal/templates/pending.html +++ b/html/captive-portal/templates/pending.html @@ -11,7 +11,7 @@ } detectNetworkAccess.delay([% initial_delay %], - [% retry_delay %], "[% destination_url %]", "[% redirect_url %]", "[% external_ip %]" + [% retry_delay %], "[% destination_url %]", "[% external_ip %]" ); }); diff --git a/html/captive-portal/templates/release.html b/html/captive-portal/templates/release.html index afbd768c3950..81abf144a2e5 100644 --- a/html/captive-portal/templates/release.html +++ b/html/captive-portal/templates/release.html @@ -21,7 +21,7 @@ } detectNetworkAccess.delay([% initial_delay %], - [% retry_delay %], "[% destination_url %]", "[% redirect_url %]", "[% external_ip %]" + [% retry_delay %], "[% destination_url %]", "[% external_ip %]" ); [% END %] }); diff --git a/html/captive-portal/templates/scan-in-progress.html b/html/captive-portal/templates/scan-in-progress.html index 6fc6aebc02b8..664b95829d1b 100644 --- a/html/captive-portal/templates/scan-in-progress.html +++ b/html/captive-portal/templates/scan-in-progress.html @@ -17,7 +17,7 @@ } detectNetworkAccess.delay([% refresh_timer %], - [% refresh_timer %], "[% destination_url %]", "[% redirect_url %]", "[% external_ip %]" + [% refresh_timer %], "[% destination_url %]", "[% external_ip %]" ); }); diff --git a/html/common/pf.js b/html/common/pf.js index 6672db13941b..258166d0ad70 100644 --- a/html/common/pf.js +++ b/html/common/pf.js @@ -43,14 +43,14 @@ function fetchNodeStatus() { Called when access to the network outside registration or quarantine works */ var network_redirected = false; -function networkAccessCallback(destination_url, redirect_url) { +function networkAccessCallback(destination_url) { network_redirected = true; // browser redirect // Firefox 3/4 needs a new forced destination and a little delay if (Prototype.Browser.Gecko) { - performRedirect.delay(5, redirect_url); + performRedirect.delay(5, destination_url); return; } @@ -61,7 +61,7 @@ function networkAccessCallback(destination_url, redirect_url) { return; } - // Chrome 10 / Safari 5 / IE9 (sometimes) flawless + // Other browsers, try a direct redirection performRedirect(destination_url); } @@ -94,7 +94,7 @@ function performRedirect(destination_url) { Date.now = Date.now || function() { return +new Date; }; -function detectNetworkAccess(retry_delay, destination_url, redirect_url, external_ip) { +function detectNetworkAccess(retry_delay, destination_url, external_ip) { "use strict"; var errorDetected, loaded, netdetect, checker, initNetDetect; @@ -118,11 +118,11 @@ function detectNetworkAccess(retry_delay, destination_url, redirect_url, externa if (errorDetected === true) { initNetDetect(); } else if (loaded === true) { - networkAccessCallback(destination_url, redirect_url); + networkAccessCallback(destination_url); } else { // Check the width or height of the image since we do not know if it is loaded if (netdetect.width || netdetect.height) { - networkAccessCallback(destination_url, redirect_url); + networkAccessCallback(destination_url); } else { initNetDetect(); } diff --git a/lib/pf/Portal/Session.pm b/lib/pf/Portal/Session.pm index eafe435be413..90e310de11fe 100644 --- a/lib/pf/Portal/Session.pm +++ b/lib/pf/Portal/Session.pm @@ -153,11 +153,12 @@ Returns destination_url properly parsed, defended against XSS and with configure sub _getDestinationUrl { my ($self) = @_; - # Set default if destination_url not set - unless (defined($self->cgi->param("destination_url"))) { + # Return portal profile's redirection URL if destination_url is not set or if redirection URL is forced + if (!defined($self->cgi->param("destination_url")) || $self->getProfile->forceRedirectURL) { return $self->getProfile->getRedirectURL; } + # Respect the user's initial destination URL return decode_entities(uri_unescape($self->cgi->param("destination_url"))); } diff --git a/lib/pf/web.pm b/lib/pf/web.pm index 1384c17eec3a..d1f2ca62c2e0 100644 --- a/lib/pf/web.pm +++ b/lib/pf/web.pm @@ -170,18 +170,13 @@ sub generate_release_page { $portalSession->stash({ timer => $Config{'trapping'}{'redirtimer'}, - redirect_url => $portalSession->getDestinationUrl(), + destination_url => $portalSession->getDestinationUrl(), initial_delay => $CAPTIVE_PORTAL{'NET_DETECT_INITIAL_DELAY'}, retry_delay => $CAPTIVE_PORTAL{'NET_DETECT_RETRY_DELAY'}, external_ip => $Config{'captive_portal'}{'network_detection_ip'}, auto_redirect => $Config{'captive_portal'}{'network_detection'}, }); - # override destination_url if we enabled the always_use_redirecturl option - if (isenabled($portalSession->getProfile->forceRedirectURL)) { - $portalSession->stash->{'redirect_url'} = $portalSession->getProfile->getRedirectURL; - } - render_template($portalSession, 'release.html', $r); } @@ -653,17 +648,12 @@ sub generate_pending_page { my ( $portalSession ) = @_; $portalSession->stash({ - redirect_url => $portalSession->getProfile->getRedirectURL, + destination_url => $portalSession->getDestinationUrl(), initial_delay => $CAPTIVE_PORTAL{'NET_DETECT_PENDING_INITIAL_DELAY'}, retry_delay => $CAPTIVE_PORTAL{'NET_DETECT_PENDING_RETRY_DELAY'}, external_ip => $Config{'captive_portal'}{'network_detection_ip'}, }); - # override destination_url if we enabled the always_use_redirecturl option - if (isenabled($portalSession->getProfile->forceRedirectURL)) { - $portalSession->stash->{'destination_url'} = $portalSession->getProfile->getRedirectURL; - } - render_template($portalSession, 'pending.html'); } From e96e1f2070fe32b0020a0d61fdfd588f8cf56703 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Thu, 5 Dec 2013 16:48:58 -0500 Subject: [PATCH 347/369] New link on SMS confirmation page to cancel Instead of automatically changing the node status to unreg when visiting the captive portal, we now keep the node in pending mode but allow the user to go back to the registration page that will unregister the node and display the login/registration page. --- NEWS.asciidoc | 1 + html/captive-portal/redir.cgi | 9 +++++++-- .../captive-portal/templates/guest/sms_confirmation.html | 4 ++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/NEWS.asciidoc b/NEWS.asciidoc index 3c8924707b68..503006b5e90a 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -50,6 +50,7 @@ Enhancements * Modified logrotate so it uses copytruncate instead of restarting the services. * Now comes with a corosync compatible barnyard2 init script in addons. * Unreg the node when you come from a secure connection to an open connection +* Allow a self-registered node by SMS to go back to the registration page Bug Fixes +++++++++ diff --git a/html/captive-portal/redir.cgi b/html/captive-portal/redir.cgi index 050d4900d811..73e3c986a7cb 100755 --- a/html/captive-portal/redir.cgi +++ b/html/captive-portal/redir.cgi @@ -100,7 +100,13 @@ if ($violation) { #check to see if node needs to be registered # -my $unreg = node_unregistered($mac); +my $unreg; +if ($portalSession->getCgi->param('unreg')) { + $logger->info("Unregister node $mac"); + $unreg = node_deregister($mac); # set node status to 'unreg' +} else { + $unreg = node_unregistered($mac); # check if node status is 'unreg' +} if ($unreg && isenabled($Config{'trapping'}{'registration'})){ # Redirect to the billing engine if enabled if ( isenabled($portalSession->getProfile->getBillingEngine) ) { @@ -130,7 +136,6 @@ if ($unreg && isenabled($Config{'trapping'}{'registration'})){ my $node_info = node_view($mac); if (defined($node_info) && $node_info->{'status'} eq $pf::node::STATUS_PENDING) { if (pf::sms_activation::sms_activation_has_entry($mac)) { - node_deregister($mac); pf::web::guest::generate_sms_confirmation_page($portalSession, "/activate/sms"); } elsif ($portalSession->getCgi->https()) { diff --git a/html/captive-portal/templates/guest/sms_confirmation.html b/html/captive-portal/templates/guest/sms_confirmation.html index 74e4b2dda3fd..dd2d82805a5f 100644 --- a/html/captive-portal/templates/guest/sms_confirmation.html +++ b/html/captive-portal/templates/guest/sms_confirmation.html @@ -28,4 +28,8 @@

    [% title %]

    + + [% INCLUDE footer.html %] From 59ae1ac51e4af794eba4df8221c7b1b536b30946 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Fri, 6 Dec 2013 11:09:58 -0500 Subject: [PATCH 348/369] Fix saving allow_localdomain in email source When the checkbox was unchecked, the option was not saved and was enabled by default. --- NEWS.asciidoc | 1 + .../lib/pfappserver/Form/Authentication/Source/Email.pm | 4 +++- lib/pf/Authentication/Source/EmailSource.pm | 3 +-- lib/pf/Authentication/Source/NullSource.pm | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/NEWS.asciidoc b/NEWS.asciidoc index 503006b5e90a..957c1e867211 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -72,6 +72,7 @@ Bug Fixes * Fixed advanced search by node category * Fixed reordering of conf sections and groups (#1749) * Fixed pid of SMS-registered devices (was "admin" in certain circumstances) +* Fixed saving of 'allow local domain' option when disabled in an email authentication source Version 4.0.6-2 released on 2013-09-13 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/html/pfappserver/lib/pfappserver/Form/Authentication/Source/Email.pm b/html/pfappserver/lib/pfappserver/Form/Authentication/Source/Email.pm index e351b8651b3c..0d5b6d20234b 100644 --- a/html/pfappserver/lib/pfappserver/Form/Authentication/Source/Email.pm +++ b/html/pfappserver/lib/pfappserver/Form/Authentication/Source/Email.pm @@ -29,7 +29,9 @@ has_field 'email_activation_timeout' => ); has_field 'allow_localdomain' => ( - type => 'Checkbox', + type => 'Toggle', + checkbox_value => 'yes', + unchecked_value => 'no', label => 'Allow Local Domain', default => pf::Authentication::Source::EmailSource->meta->get_attribute('allow_localdomain')->default, tags => { after_element => \&help, diff --git a/lib/pf/Authentication/Source/EmailSource.pm b/lib/pf/Authentication/Source/EmailSource.pm index dd0d34c7a5eb..a9db048f4fb9 100644 --- a/lib/pf/Authentication/Source/EmailSource.pm +++ b/lib/pf/Authentication/Source/EmailSource.pm @@ -8,7 +8,6 @@ pf::Authentication::Source::EmailSource =cut -use pf::config qw($TRUE $FALSE); use pf::Authentication::constants; use Moose; @@ -17,8 +16,8 @@ extends 'pf::Authentication::Source'; has '+class' => (default => 'external'); has '+type' => (default => 'Email'); has '+unique' => (default => 1); +has 'allow_localdomain' => (isa => 'Str', is => 'rw', default => 'yes'); has 'email_activation_timeout' => (isa => 'Str', is => 'rw', default => '10m'); -has 'allow_localdomain' => (isa => 'Bool', is => 'rw', default => 1); =head2 available_attributes diff --git a/lib/pf/Authentication/Source/NullSource.pm b/lib/pf/Authentication/Source/NullSource.pm index 72221ae216ce..0b649327f630 100644 --- a/lib/pf/Authentication/Source/NullSource.pm +++ b/lib/pf/Authentication/Source/NullSource.pm @@ -23,7 +23,7 @@ extends 'pf::Authentication::Source'; has '+class' => (default => 'exclusive'); has '+type' => (default => 'Null'); has '+unique' => (default => 1); -has 'email_required' => ( is=> 'rw', default => 'disabled'); +has 'email_required' => (isa => 'Str', is => 'rw', default => 'no'); =head2 available_actions From 4509bfece03bd493658871122bcf0f8b78ec9621 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Fri, 6 Dec 2013 11:17:47 -0500 Subject: [PATCH 349/369] Add allow_localdomain option to the sponsor source --- NEWS.asciidoc | 4 +++- conf/authentication.conf | 2 +- .../pfappserver/Form/Authentication/Source/Null.pm | 5 +++-- .../Form/Authentication/Source/SponsorEmail.pm | 12 ++++++++++++ .../authentication/source/type/SponsorEmail.tt | 2 +- lib/pf/Authentication/Source/SponsorEmailSource.pm | 1 + lib/pf/web/guest.pm | 14 +++++++++++--- 7 files changed, 32 insertions(+), 8 deletions(-) diff --git a/NEWS.asciidoc b/NEWS.asciidoc index 957c1e867211..2e440707cf65 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -11,7 +11,7 @@ This is a list of noteworthy changes across releases. For more details and developer visible changes see the ChangeLog file. For a list of compatibility related changes see the UPGRADE.asciidoc file. -Version 4.x.y released on 2013-MM-DD +Version 4.1.0 released on 2013-MM-DD ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ New Features @@ -51,6 +51,7 @@ Enhancements * Now comes with a corosync compatible barnyard2 init script in addons. * Unreg the node when you come from a secure connection to an open connection * Allow a self-registered node by SMS to go back to the registration page +* Sponsor email authentication source can refuse email addresses of the local domain (as the email source) Bug Fixes +++++++++ @@ -73,6 +74,7 @@ Bug Fixes * Fixed reordering of conf sections and groups (#1749) * Fixed pid of SMS-registered devices (was "admin" in certain circumstances) * Fixed saving of 'allow local domain' option when disabled in an email authentication source +* The 'allow local domain' option of the email source will now only affect the user who registers by email Version 4.0.6-2 released on 2013-09-13 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/conf/authentication.conf b/conf/authentication.conf index 88a10aefe54e..9f973a4b10e0 100644 --- a/conf/authentication.conf +++ b/conf/authentication.conf @@ -27,7 +27,7 @@ action1=set_access_duration=1D description=Email-based registration email_activation_timeout=10m type=Email -allow_localdomain=1 +allow_localdomain=yes [email rule catchall] description= diff --git a/html/pfappserver/lib/pfappserver/Form/Authentication/Source/Null.pm b/html/pfappserver/lib/pfappserver/Form/Authentication/Source/Null.pm index e76ca2171cf4..6c6a7f00d25c 100644 --- a/html/pfappserver/lib/pfappserver/Form/Authentication/Source/Null.pm +++ b/html/pfappserver/lib/pfappserver/Form/Authentication/Source/Null.pm @@ -1,4 +1,5 @@ package pfappserver::Form::Authentication::Source::Null; + =head1 NAME pfappserver::Form::Authentication::Source::Null add documentation @@ -20,8 +21,8 @@ extends 'pfappserver::Form::Authentication::Source'; has_field 'email_required' => ( type => 'Toggle', - checkbox_value => 'enabled', - unchecked_value => 'disabled', + checkbox_value => 'yes', + unchecked_value => 'no', ); =head1 AUTHOR diff --git a/html/pfappserver/lib/pfappserver/Form/Authentication/Source/SponsorEmail.pm b/html/pfappserver/lib/pfappserver/Form/Authentication/Source/SponsorEmail.pm index 877d31cefa0b..d0b21de63ade 100644 --- a/html/pfappserver/lib/pfappserver/Form/Authentication/Source/SponsorEmail.pm +++ b/html/pfappserver/lib/pfappserver/Form/Authentication/Source/SponsorEmail.pm @@ -16,6 +16,18 @@ with 'pfappserver::Base::Form::Role::Help'; use pf::Authentication::Source::SponsorEmailSource; +# Form fields +has_field 'allow_localdomain' => + ( + type => 'Toggle', + checkbox_value => 'yes', + unchecked_value => 'no', + label => 'Allow Local Domain', + default => pf::Authentication::Source::EmailSource->meta->get_attribute('allow_localdomain')->default, + tags => { after_element => \&help, + help => 'Accept self-registration with email address from the local domain' }, + ); + =head1 COPYRIGHT Copyright (C) 2013 Inverse inc. diff --git a/html/pfappserver/root/authentication/source/type/SponsorEmail.tt b/html/pfappserver/root/authentication/source/type/SponsorEmail.tt index 8b137891791f..2f0dcc239332 100644 --- a/html/pfappserver/root/authentication/source/type/SponsorEmail.tt +++ b/html/pfappserver/root/authentication/source/type/SponsorEmail.tt @@ -1 +1 @@ - +[% form.field('allow_localdomain').render %] diff --git a/lib/pf/Authentication/Source/SponsorEmailSource.pm b/lib/pf/Authentication/Source/SponsorEmailSource.pm index 067cf2b66900..d3548c2c61e3 100644 --- a/lib/pf/Authentication/Source/SponsorEmailSource.pm +++ b/lib/pf/Authentication/Source/SponsorEmailSource.pm @@ -16,6 +16,7 @@ extends 'pf::Authentication::Source'; has '+class' => (default => 'external'); has '+type' => (default => 'SponsorEmail'); has '+unique' => (default => 1); +has 'allow_localdomain' => (isa => 'Str', is => 'rw', default => 'yes'); =head2 available_attributes diff --git a/lib/pf/web/guest.pm b/lib/pf/web/guest.pm index 12587b8878ff..a1ee44f2f2ba 100644 --- a/lib/pf/web/guest.pm +++ b/lib/pf/web/guest.pm @@ -182,13 +182,21 @@ sub validate_selfregistration { return ($FALSE, $GUEST::ERROR_AUP_NOT_ACCEPTED); } - my $email_type = pf::Authentication::Source::EmailSource->meta->get_attribute('type')->default; - my $source = $portalSession->getProfile->getSourceByType($email_type); + # check if email with local domain is allowed for email and sponsor sources + my $source; + if (defined($cgi->param('by_email'))) { + my $email_type = pf::Authentication::Source::EmailSource->meta->get_attribute('type')->default; + $source = $portalSession->getProfile->getSourceByType($email_type); + } + elsif (defined($cgi->param('by_sponsor'))) { + my $sponsor_type = pf::Authentication::Source::SponsorEmailSource->meta->get_attribute('type')->default; + $source = $portalSession->getProfile->getSourceByType($sponsor_type); + } if ($source) { unless (isenabled($source->{allow_localdomain})) { # You should not register as a guest if you are part of the local network my $localdomain = $Config{'general'}{'domain'}; - if ($cgi->param('email') =~ /[@.]$localdomain$/i) { + if ($cgi->param('email') =~ /[@\.]$localdomain$/i) { return ($FALSE, $GUEST::ERROR_EMAIL_UNAUTHORIZED_AS_GUEST, [ $localdomain ]); } } From 0011712941e21f74e6343f56843077ed76897e06 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Fri, 6 Dec 2013 14:24:16 -0500 Subject: [PATCH 350/369] Will not removestaleFile if the quick argument is true --- lib/pf/services/manager.pm | 17 +++++++++-------- lib/pf/services/manager/submanager.pm | 6 +++--- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/pf/services/manager.pm b/lib/pf/services/manager.pm index c38da2dfbd9f..20cf22bc8f62 100644 --- a/lib/pf/services/manager.pm +++ b/lib/pf/services/manager.pm @@ -126,7 +126,7 @@ work for starting a servicw sub preStartSetup { my ($self,$quick) = @_; - $self->removeStalePid; + $self->removeStalePid($quick); $self->generateConfig($quick) unless $quick; $self->_setupWatchForPidCreate; return 1; @@ -226,7 +226,7 @@ returns the pid or list of pids for the servie(s) sub status { my ($self,$quick) = @_; - $self->removeStalePid; + $self->removeStalePid($quick); my $pid = $self->pid; return $pid ? $pid : "0"; } @@ -253,9 +253,9 @@ sub stop { my ($self,$quick) = @_; my $pid = $self->pid; if ($pid) { - $self->preStopSetup(); - $self->stopService(); - $self->postStopCleanup(); + $self->preStopSetup($quick); + $self->stopService($quick); + $self->postStopCleanup($quick); return 1; } return; @@ -291,7 +291,7 @@ sub stopService { =cut sub postStopCleanup { - my ($self) = @_; + my ($self,$quick) = @_; my $logger = get_logger(); my $name = $self->name; my $pid = $self->lastPid; @@ -300,7 +300,7 @@ sub postStopCleanup { my $timedout; #give the kill a little time $inotify->blocking(0); - $self->removeStalePid; + $self->removeStalePid($quick); my $timer = Linux::FD::Timer->new('monotonic'); $timer->set_timeout(0.1,0.1); $timer->receive; @@ -444,7 +444,8 @@ removes the stale PID file =cut sub removeStalePid { - my ($self) = @_; + my ($self,$quick) = @_; + return if $quick; my $logger = get_logger; my $pid = $self->pidFromFile; my $pidFile = $self->pidFile; diff --git a/lib/pf/services/manager/submanager.pm b/lib/pf/services/manager/submanager.pm index 04a5d9114cb6..5ccf5c227d59 100644 --- a/lib/pf/services/manager/submanager.pm +++ b/lib/pf/services/manager/submanager.pm @@ -51,8 +51,8 @@ Delegating removeStalePid to sub managers =cut sub removeStalePid { - my ($self) = @_; - $_->removeStalePid foreach $self->managers; + my ($self,$quick) = @_; + $_->removeStalePid($quick) foreach $self->managers; } =head2 status @@ -63,7 +63,7 @@ returns all the pids of the submanagers sub status { my ($self,$quick) = @_; - my @results = map {$_->status } $self->managers; + my @results = map { $_->status($quick) } $self->managers; if (@results == 0 || (!$quick && any { !defined($_) || $_ eq "0" } @results )) { @results = ("0"); } From 5185a250e832cf89a87c631614ac2f4c52f1f4bf Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Fri, 6 Dec 2013 14:25:32 -0500 Subject: [PATCH 351/369] Service status is called with quick parameter --- html/pfappserver/lib/pfappserver/Model/Services.pm | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/html/pfappserver/lib/pfappserver/Model/Services.pm b/html/pfappserver/lib/pfappserver/Model/Services.pm index e74948b87654..60bdab464910 100644 --- a/html/pfappserver/lib/pfappserver/Model/Services.pm +++ b/html/pfappserver/lib/pfappserver/Model/Services.pm @@ -97,7 +97,7 @@ sub status { my ($self) = @_; my $logger = get_logger(); - my %services_ref = map { $_->name => $_->status } grep { $_->isManaged } map { pf::services::get_service_manager($_) } @pf::services::ALL_SERVICES; + my %services_ref = map { $_->name => $_->status(1) } grep { $_->isManaged } map { pf::services::get_service_manager($_) } @pf::services::ALL_SERVICES; return ($STATUS::OK, { services => \%services_ref}) if ( keys %services_ref ); return ($STATUS::INTERNAL_SERVER_ERROR, "Unidentified error see server side logs for details."); @@ -163,7 +163,13 @@ sub service_start { =cut sub service_cmd { - my ($self,$service) = @_; + my ($self,@args) = @_; + my $logger = get_logger(); + my $result = $self->_run_pfcmd_service(@args); + $logger->debug("pfcmd service output: " . $result); + return ($STATUS::OK, {result => $result}) if ( defined($result) ); + + return ($STATUS::INTERNAL_SERVER_ERROR, "Unidentified error see server side logs for details."); } =item service_cmd_background From 0493a64e8ec18641a5f347dab47772b5840a7e41 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Fri, 6 Dec 2013 14:37:08 -0500 Subject: [PATCH 352/369] Start/Stop/Restart will now call the pfcmd and wait for it's completion before return --- html/pfappserver/lib/pfappserver/Controller/Service.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/html/pfappserver/lib/pfappserver/Controller/Service.pm b/html/pfappserver/lib/pfappserver/Controller/Service.pm index 5948f631038e..64a90600441a 100644 --- a/html/pfappserver/lib/pfappserver/Controller/Service.pm +++ b/html/pfappserver/lib/pfappserver/Controller/Service.pm @@ -62,7 +62,7 @@ sub status :Chained('service') :PathPart('') :Args(0) :AdminRole('SERVICES') { sub start :Chained('service') :PathPart :Args(0) :AdminRole('SERVICES') { my ($self, $c) = @_; - $self->_process_model_results_as_json( $c, $c->stash->{model}->service_ctl($c->stash->{service}, "start") ); + $self->_process_model_results_as_json( $c, $c->stash->{model}->service_cmd($c->stash->{service}, "start") ); } =head2 stop @@ -71,7 +71,7 @@ sub start :Chained('service') :PathPart :Args(0) :AdminRole('SERVICES') { sub stop :Chained('service') :PathPart :Args(0) :AdminRole('SERVICES') { my ($self, $c) = @_; - $self->_process_model_results_as_json( $c, $c->stash->{model}->service_ctl($c->stash->{service}, "stop") ); + $self->_process_model_results_as_json( $c, $c->stash->{model}->service_cmd($c->stash->{service}, "stop") ); } =head2 restart @@ -80,7 +80,7 @@ sub stop :Chained('service') :PathPart :Args(0) :AdminRole('SERVICES') { sub restart :Chained('service') :PathPart :Args(0) :AdminRole('SERVICES') { my ($self, $c) = @_; - $self->_process_model_results_as_json( $c, $c->stash->{model}->service_ctl($c->stash->{service}, "restart") ); + $self->_process_model_results_as_json( $c, $c->stash->{model}->service_cmd($c->stash->{service}, "restart") ); } =head2 pf_start From 95db68e4f8ea6afbeaa5d9a9e732a423ef40716b Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Fri, 6 Dec 2013 15:02:52 -0500 Subject: [PATCH 353/369] Clearing network information when reloading pf.conf --- lib/pf/config.pm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/pf/config.pm b/lib/pf/config.pm index 4563b0372832..832adb061e68 100644 --- a/lib/pf/config.pm +++ b/lib/pf/config.pm @@ -477,6 +477,11 @@ sub readPfConfigFiles { my ($config) = @_; $config->toHash(\%Config); $config->cleanupWhitespace(\%Config); + #clearing older interfaces infor + $monitor_int = $management_network = undef; + @listen_ints = @dhcplistener_ints = @ha_ints = + @internal_nets = @external_nets = + @inline_enforcement_nets = @vlan_enforcement_nets = (); my @time_values = grep { my $t = $Doc_Config{$_}{type}; defined $t && $t eq 'time' } keys %Doc_Config; @@ -619,6 +624,7 @@ sub readNetworkConfigFile { my ($config) = @_; $config->toHash(\%ConfigNetworks); $config->cleanupWhitespace(\%ConfigNetworks); + @routed_isolation_nets = @routed_registration_nets = @inline_nets = (); foreach my $network ( $config->Sections ) { # populate routed nets variables From bcc51e64b47e1ea6885c4f0020104e203672e340 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 15 Jul 2013 11:28:12 -0400 Subject: [PATCH 354/369] Use the correct prepared statement when there are no dates defined --- lib/pf/ifoctetslog.pm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/pf/ifoctetslog.pm b/lib/pf/ifoctetslog.pm index 2ae2ced7ed2a..2cf95b35664d 100644 --- a/lib/pf/ifoctetslog.pm +++ b/lib/pf/ifoctetslog.pm @@ -8,7 +8,7 @@ pf::ifoctetslog - module for SNMP counters. =head1 DESCRIPTION -pf::ifoctetslog contains the functions related to the SNMP counters: +pf::ifoctetslog contains the functions related to the SNMP counters: inbound and outbound octets counters included in the ifTable. =head1 CONFIGURATION AND ENVIRONMENT @@ -128,7 +128,7 @@ sub ifoctetslog_history_user { @raw_data = db_data(IFOCTETSLOG, $ifoctetslog_statements, 'ifoctetslog_history_user_start_end_sql', $user, $params{'start_time'}, $params{'end_time'}); } else { - @raw_data = db_data(IFOCTETSLOG, $ifoctetslog_statements, 'ifoctetslog_history_user_start_end_sql', $user); + @raw_data = db_data(IFOCTETSLOG, $ifoctetslog_statements, 'ifoctetslog_history_user_sql', $user); } my $previousLine; @@ -186,10 +186,10 @@ sub ifoctetslog_history_switchport { my @raw_data; my @data; if ( exists( $params{'start_time'} ) && exists( $params{'end_time'} ) ) { - @raw_data = db_data(IFOCTETSLOG, $ifoctetslog_statements, 'ifoctetslog_history_switchport_start_end_sql', + @raw_data = db_data(IFOCTETSLOG, $ifoctetslog_statements, 'ifoctetslog_history_switchport_start_end_sql', $switch, $params{'ifIndex'}, $params{'start_time'}, $params{'end_time'}); } else { - @raw_data = db_data(IFOCTETSLOG, $ifoctetslog_statements, 'ifoctetslog_history_switchport_sql', + @raw_data = db_data(IFOCTETSLOG, $ifoctetslog_statements, 'ifoctetslog_history_switchport_sql', $switch, $params{'ifIndex'}); } my $previousLine; @@ -215,7 +215,7 @@ sub ifoctetslog_history_switchport { sub ifoctetslog_insert { my ( $switch, $ifIndex, $mac, $ifInOctets, $ifOutOctets ) = @_; - db_query_execute(IFOCTETSLOG, $ifoctetslog_statements, 'ifoctetslog_insert_sql', + db_query_execute(IFOCTETSLOG, $ifoctetslog_statements, 'ifoctetslog_insert_sql', $switch, $ifIndex, $mac, $ifInOctets, $ifOutOctets) || return (0); return (1); From 4f9252398c13932663824d1fe7c2711e6c9ada0d Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Fri, 6 Dec 2013 16:11:58 -0500 Subject: [PATCH 355/369] Updated news file --- NEWS.asciidoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS.asciidoc b/NEWS.asciidoc index 2e440707cf65..2f70155db780 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -75,6 +75,8 @@ Bug Fixes * Fixed pid of SMS-registered devices (was "admin" in certain circumstances) * Fixed saving of 'allow local domain' option when disabled in an email authentication source * The 'allow local domain' option of the email source will now only affect the user who registers by email +* Fixed ifoctetshistoryuser command to use the correct query when just a user is given +* Fixed network-detection for IE 8 Version 4.0.6-2 released on 2013-09-13 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 01eae41b6192ec5e3fe663caf7a8a5f20750b3d0 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 9 Dec 2013 12:46:27 -0500 Subject: [PATCH 356/369] Use isenabled for forceRedirectURL --- lib/pf/Portal/Session.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pf/Portal/Session.pm b/lib/pf/Portal/Session.pm index 90e310de11fe..58ca9c7ad080 100644 --- a/lib/pf/Portal/Session.pm +++ b/lib/pf/Portal/Session.pm @@ -154,7 +154,7 @@ sub _getDestinationUrl { my ($self) = @_; # Return portal profile's redirection URL if destination_url is not set or if redirection URL is forced - if (!defined($self->cgi->param("destination_url")) || $self->getProfile->forceRedirectURL) { + if (!defined($self->cgi->param("destination_url")) || isenabled($self->getProfile->forceRedirectURL)) { return $self->getProfile->getRedirectURL; } From 858f8267fb45a018118ce2199b4aa0652eca9e3d Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Mon, 9 Dec 2013 13:07:17 -0500 Subject: [PATCH 357/369] Will not set destination_url if the url matches the captive portal --- lib/pf/web/dispatcher.pm | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/pf/web/dispatcher.pm b/lib/pf/web/dispatcher.pm index b09b36284b35..dbc8934638c4 100755 --- a/lib/pf/web/dispatcher.pm +++ b/lib/pf/web/dispatcher.pm @@ -110,8 +110,12 @@ sub handler { my ($r) = @_; my $logger = Log::Log4perl->get_logger(__PACKAGE__); $logger->trace('hitting redirector'); + my $captivePortalDomain = $Config{'general'}{'hostname'}.".".$Config{'general'}{'domain'}; + my $destination_url = ''; my $url = $r->construct_url; - my $orginal_url = Apache2::Util::escape_path($url,$r->pool); + if ($url !~ m#://\Q$captivePortalDomain\E/#) { + $destination_url = Apache2::Util::escape_path($url,$r->pool); + } my $proto; # Google chrome hack redirect in http if ($r->uri =~ /\/generate_204/) { @@ -121,8 +125,8 @@ sub handler { } my $stash = { - 'login_url' => "$proto://".$Config{'general'}{'hostname'}.".".$Config{'general'}{'domain'}."/captive-portal?destination_url=$orginal_url", - 'login_url_wispr' => "$proto://".$Config{'general'}{'hostname'}.".".$Config{'general'}{'domain'}."/wispr", + 'login_url' => "${proto}://${captivePortalDomain}/captive-portal?destination_url=$destination_url", + 'login_url_wispr' => "${proto}://${captivePortalDomain}/wispr" }; # prepare custom REDIRECT response From 4c73805b7de7d73d1ebec0e6690782f6426fc290 Mon Sep 17 00:00:00 2001 From: Durand Fabrice Date: Tue, 10 Dec 2013 09:26:03 -0500 Subject: [PATCH 358/369] Removed support for the httpd service --- lib/pf/pfcmd.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pf/pfcmd.pm b/lib/pf/pfcmd.pm index c33d52871f2b..b167e28511f6 100644 --- a/lib/pf/pfcmd.pm +++ b/lib/pf/pfcmd.pm @@ -309,7 +309,7 @@ sub parseCommandLine { ( \d+ ) ) $ }xms, - 'service' => qr{ ^ ( dhcpd | httpd | pfdns | pfdetect + 'service' => qr{ ^ ( dhcpd | pfdns | pfdetect | pf | pfdhcplistener | pfmon | pfsetvlan | radiusd | snmptrapd | snort | suricata | httpd\.webservices | httpd\.admin | httpd\.portal | httpd\.proxy | memcached) From 6bdccd9845ff5e457188d55cea3bfba189a2ed46 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Tue, 10 Dec 2013 14:46:48 -0500 Subject: [PATCH 359/369] Improve SSID report on web admin --- NEWS.asciidoc | 1 + lib/pf/pfcmd/report.pm | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/NEWS.asciidoc b/NEWS.asciidoc index 2f70155db780..7d6a12be30f6 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -77,6 +77,7 @@ Bug Fixes * The 'allow local domain' option of the email source will now only affect the user who registers by email * Fixed ifoctetshistoryuser command to use the correct query when just a user is given * Fixed network-detection for IE 8 +* Fixed SQL query of SSID report in Web admin Version 4.0.6-2 released on 2013-09-13 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/lib/pf/pfcmd/report.pm b/lib/pf/pfcmd/report.pm index 4ef107f55a71..41045406474a 100644 --- a/lib/pf/pfcmd/report.pm +++ b/lib/pf/pfcmd/report.pm @@ -256,13 +256,13 @@ sub report_db_prepare { ]); $report_statements->{'report_ssid_sql'} = get_db_handle()->prepare(qq [ - SELECT ssid,count(*) AS nodes, ROUND(COUNT(*)/ - (SELECT COUNT(*) + SELECT ssid, COUNT(DISTINCT locationlog.mac) AS nodes, ROUND(COUNT(DISTINCT locationlog.mac)/ + (SELECT COUNT(DISTINCT locationlog.mac) FROM locationlog INNER JOIN node ON node.mac = locationlog.mac AND locationlog.end_time IS NULL INNER JOIN iplog ON node.mac = iplog.mac WHERE ssid != "" AND iplog.start_time BETWEEN ? AND ? - )*100,1) as percent + )*100,1) AS percent FROM locationlog INNER JOIN node ON node.mac = locationlog.mac AND locationlog.end_time IS NULL INNER JOIN iplog ON node.mac = iplog.mac From c96192b7d6b9a6e4f0415853205165c097f36494 Mon Sep 17 00:00:00 2001 From: Jean Raby Date: Wed, 11 Dec 2013 10:48:40 -0500 Subject: [PATCH 360/369] fix invalid regex (^ was escaped by the shell) --- addons/watchdog/freeradius-watchdog.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/watchdog/freeradius-watchdog.sh b/addons/watchdog/freeradius-watchdog.sh index d35b7c696610..012ca5f7ccd6 100644 --- a/addons/watchdog/freeradius-watchdog.sh +++ b/addons/watchdog/freeradius-watchdog.sh @@ -33,10 +33,10 @@ function radius_test () { WORKING=0 for OUTPUT in `radtest testuser testpass $SERVER_IP 12 testing123 2>&1` do - if [[ "$OUTPUT" =~ "^radclient: no response from server for" ]]; then + if [[ "$OUTPUT" =~ ^"radclient: no response from server for" ]]; then WORKING=0 break - elif [[ "$OUTPUT" =~ "^rad_recv: Access-Accept packet from host" ]]; then + elif [[ "$OUTPUT" =~ ^"rad_recv: Access-Accept packet from host" ]]; then WORKING=1 fi done From d34f7441c1fd3ab492e8a0c62ff52649b04c6743 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Wed, 11 Dec 2013 11:50:26 -0500 Subject: [PATCH 361/369] Simple search of nodes: respect spaces We must respect the space characters when the search string doesn't match a MAC address. --- lib/pf/node.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pf/node.pm b/lib/pf/node.pm index 7683fcf50d28..dcc40af8df86 100644 --- a/lib/pf/node.pm +++ b/lib/pf/node.pm @@ -658,7 +658,7 @@ sub node_view_all { $node_view_all_sql .= " HAVING node.mac = $mac"; } else { - my $like = get_db_handle->quote("\%$like\%"); + $like = get_db_handle->quote('%' . $params{'where'}{'like'} . '%'); $node_view_all_sql .= " HAVING node.mac LIKE $like" . " OR node.computername LIKE $like" . " OR node.pid LIKE $like" From 108a7a854fec544750b15f5f155d4eaad9e4fb96 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Wed, 11 Dec 2013 12:05:00 -0500 Subject: [PATCH 362/369] Cleanup bundled values of authentication.conf --- conf/authentication.conf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/conf/authentication.conf b/conf/authentication.conf index 9f973a4b10e0..2d03bec04509 100644 --- a/conf/authentication.conf +++ b/conf/authentication.conf @@ -38,6 +38,7 @@ action1=set_access_duration=1D [sponsor] description=Sponsor-based registration type=SponsorEmail +allow_localdomain=yes [sponsor rule catchall] description= @@ -48,4 +49,4 @@ action1=set_access_duration=1D [null] description=Null Source type=Null -email_required=disabled +email_required=no From 3e67e39c24d1444254d4bf9e8429f3b6e6d69ddd Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Wed, 11 Dec 2013 12:05:37 -0500 Subject: [PATCH 363/369] Improve error message in Null auth source --- lib/pf/Authentication/Source/NullSource.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pf/Authentication/Source/NullSource.pm b/lib/pf/Authentication/Source/NullSource.pm index 0b649327f630..e7c092eab7df 100644 --- a/lib/pf/Authentication/Source/NullSource.pm +++ b/lib/pf/Authentication/Source/NullSource.pm @@ -57,7 +57,7 @@ sub authenticate { if (isdisabled($self->email_required) || Email::Valid->address($username) ) { return ($TRUE, 'Successful authentication using null source.'); } - return ($FALSE, 'Successful authentication using null source.'); + return ($FALSE, 'Invalid email address provided.'); } =head1 AUTHOR From 044e706cad15ac9b5620e5bf8bf785435da60ba0 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Wed, 11 Dec 2013 12:26:14 -0500 Subject: [PATCH 364/369] Improve help on Web admin interface --- html/pfappserver/root/configuration/adminroles/index.tt | 2 +- html/pfappserver/root/portal/profile/view.tt | 2 +- lib/pf/pfcmd/help.pm | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/html/pfappserver/root/configuration/adminroles/index.tt b/html/pfappserver/root/configuration/adminroles/index.tt index 2ae17f8e6810..4980766f44d2 100644 --- a/html/pfappserver/root/configuration/adminroles/index.tt +++ b/html/pfappserver/root/configuration/adminroles/index.tt @@ -17,7 +17,7 @@

    [% l('Admin Roles') %]

    -

    [% l('Define roles with specific access rights to the Web administration interface.') %]

    +

    [% l('Define roles with specific access rights to the Web administration interface. Roles are assigned to users depending on their authentication source.') %]

    [% INCLUDE configuration/adminroles/list.tt %] diff --git a/html/pfappserver/root/portal/profile/view.tt b/html/pfappserver/root/portal/profile/view.tt index 7a77662db4cb..4285eee5d0e4 100644 --- a/html/pfappserver/root/portal/profile/view.tt +++ b/html/pfappserver/root/portal/profile/view.tt @@ -51,7 +51,7 @@

    [%- IF form.isa('pfappserver::Form::Portal::Profile::Default') -%] - [% l('With no source specified, all internal sources will be used.') %] + [% l('With no source specified, all internal and external sources will be used.') %] [%- ELSE -%] [% l('With no source specified, the sources of the default profile will be used.') %] [%- END -%]
    diff --git a/lib/pf/pfcmd/help.pm b/lib/pf/pfcmd/help.pm index 0bbf707361d9..7ce39afb4cc2 100644 --- a/lib/pf/pfcmd/help.pm +++ b/lib/pf/pfcmd/help.pm @@ -651,7 +651,7 @@ sub help_fixpermissions { print STDERR << "EOT"; Usage: pfcmd fixpermissions -Fix the permissions of the files and directories of packetfence +Fix the permissions of the files and directories of PacketFence EOT return 1; From 29d5553ea30e1649a4e0aec38511fa57ed3a2475 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Wed, 11 Dec 2013 13:45:00 -0500 Subject: [PATCH 365/369] Update German translation --- NEWS.asciidoc | 2 + conf/locale/de/LC_MESSAGES/packetfence.po | 471 ++++++++++++---------- 2 files changed, 254 insertions(+), 219 deletions(-) diff --git a/NEWS.asciidoc b/NEWS.asciidoc index 7d6a12be30f6..be91d0e08974 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -52,10 +52,12 @@ Enhancements * Unreg the node when you come from a secure connection to an open connection * Allow a self-registered node by SMS to go back to the registration page * Sponsor email authentication source can refuse email addresses of the local domain (as the email source) +* Updated German (de) translation Bug Fixes +++++++++ +* RADIUS configuration files are no longer replaced when updating packages * Fixed match of Htpasswd authentication source (#1714) * Fixed creation of users without a role (#1721) * Fixed expiration date of registration to the end of the day (#1722) diff --git a/conf/locale/de/LC_MESSAGES/packetfence.po b/conf/locale/de/LC_MESSAGES/packetfence.po index 20ae69f6f53b..69beec017346 100644 --- a/conf/locale/de/LC_MESSAGES/packetfence.po +++ b/conf/locale/de/LC_MESSAGES/packetfence.po @@ -1,16 +1,14 @@ -# Copyright (C) 2006-2012 Inverse inc. +# Copyright (C) 2006-2013 Inverse inc. # This file is distributed under the same license as the PacketFence project. -# -# Translators: -# Tino Matysiak , 2011. # +# Translators: +# erSitzt , 2013 +# Tino Matysiak , 2011 msgid "" msgstr "" "Project-Id-Version: PacketFence\n" -"Report-Msgid-Bugs-To: http://www.packetfence.org/bugs/\n" -"PO-Revision-Date: 2012-04-26 17:23+0000\n" -"Last-Translator: inverse \n" -"Language-Team: PacketFence support \n" +"PO-Revision-Date: 2013-12-02 22:10+0000\n" +"Language-Team: German (http://www.transifex.com/projects/p/packetfence/language/de/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -35,6 +33,9 @@ msgstr "Italiano" msgid "nl_NL" msgstr "Dutch" +msgid "pl_PL" +msgstr "Polski" + msgid "pt_BR" msgstr "Português" @@ -74,7 +75,7 @@ msgid "Unable to validate credentials at the moment" msgstr "Die Anmeldeinformationen können im Moment nicht überprüft werden" msgid "error: something went wrong creating the guest" -msgstr "" +msgstr "Es gab ein Problem beim Erstellen des Gast-Accounts" msgid "help: provide info" msgstr "Wenn Sie Fragen zu dieser Seite haben, wenden Sie sich an Ihren Systemadministrator für Unterstützung. Bitte stellen Sie folgende Informationen zur Verfügung:" @@ -89,13 +90,16 @@ msgid "register: to complete" msgstr "Um den Registrierungsprozess abzuschließen, müssen Sie sich mit Ihrem Benutzernamen und Ihrem Passwort authentifizieren." msgid "Authentication" -msgstr "" +msgstr "Authentifizierung" + +msgid "Wrong username or password." +msgstr "Falscher Benutzername oder Passwort" msgid "or" -msgstr "" +msgstr "oder" msgid "Sign up" -msgstr "" +msgstr "Registrieren" msgid "register: skip registration" msgstr "Registrierung überspringen" @@ -158,46 +162,46 @@ msgid "PacketFence Registration System" msgstr "PacketFence Registrierungs-System" msgid "Guest Registration" -msgstr "" +msgstr "Gast Registrierung" msgid "guest network disclaimer" -msgstr "" +msgstr "Dieses Gast-Netzwerk wird exklusiv zum Nutzen der Gäste und Besucher bereitgestellt. Der Zugriff schliesst keine Garantie für Zuverlässigkeit, Geschwindigkeit oder Privatssphäre ein; Dieses Netzwerk wird für den ausdrücklichen Zweck zur Erleichterung der einfachen Internet-Kommunikation bereitgestellt" msgid "" "In the fields below please enter your name, phone number and a valid email " "address." -msgstr "" +msgstr "Bitte geben sie in den folgenden Feldern ihren Namen, Telefonnummer und eine gültige Emailadresse ein." msgid "" "If you choose to receive your access code by email, you " "will have to click on an activation link sent to your email address. After " "clicking on the link you will receive guest credentials to use on-site by " "email" -msgstr "" +msgstr "Wenn sie wählen ihren Zugangscode per Email zu erhalten, müssen Sie auf einen Aktivierungslink, der an Ihre Emailadresse geschickt wurde, klicken. Nachdem Sie auf den Link geklickt haben, erhalten Sie per Email Gast-Zugangsdaten, die Sie vor Ort nutzen können." msgid "" "If you choose to receive your access code by email, you " "will be given temporary network access for 10 minutes during that time:" -msgstr "" +msgstr "Wenn sie sich entscheiden ihren Zugangscode per Email zu erhalten, bekommen sie temporären Netzwerkzugriff für 10 Minuten in dieser Zeit:" msgid "Login to the email account you referenced and;" -msgstr "" +msgstr "Melden sie sich in dem Email-Account an, den sie angegeben haben und;" msgid "" "Click on the link emailed to you to validate network access for the next 24 " "hours." -msgstr "" +msgstr "Klicken sie auf den Link der ihnen zugemailt wurde um den Netzwerkzugriff für die nächsten 24 Stunden zu bestätigen." msgid "Register by Email" -msgstr "" +msgstr "Per Email registrieren" msgid "" "If you choose to receive your access code by SMS, you will " "be able to enter it on the next page." -msgstr "" +msgstr "Wenn sie sich entscheiden ihren Zugangscode per SMS zu erhalten, haben sie auf der nächsten Seite die Möglichkeit ihn einzugeben." msgid "Register by SMS" -msgstr "" +msgstr "Per SMS registrieren" msgid "Password" msgstr "Passwort" @@ -267,7 +271,7 @@ msgstr "Es wurde erkannt, dass Ihr Gerät Daten zu einem unbekannten Netzwerk ve msgid "" "Your system has been detected sending traffic to a network known to be " "unused (darknet). This is often indicative of a worm/virus infection." -msgstr "" +msgstr "Es wurde festgestellt dass ihr System Traffic in ein nicht verwendetes Netzwerk (darknet) sendet. Dies ist oft ein Anzeichen für eine Wurm/Virus - Infektion." msgid "" "Your system will likely need to be rebuilt. Please contact your local " @@ -277,7 +281,7 @@ msgstr "Das Betriebssystem muss wahrscheinlich neu installiert werden. Bitte wen msgid "" "Your system will likely need to be rebuilt. Please contact your support " "staff for more information." -msgstr "" +msgstr "Ihr System muss vermutlich neuinstalliert werden. Bitte wenden sie sich an ihren Support für weitere Informationen." msgid "Windows patches are not up to date" msgstr "Windows-Updates sind nicht auf dem neuesten Stand" @@ -339,315 +343,317 @@ msgid "" msgstr "Ihr System muss womöglich neu installiert werden. Bitte wenden Sie sich an Ihren Systemadministrator für weitere Informationen." msgid "guest management" -msgstr "" +msgstr "Gästeverwaltung" msgid "guest registration form" -msgstr "" +msgstr "Gast Registrierungsformular" msgid "guest registration instructions" -msgstr "" +msgstr "Bitte füllen sie alle untenstehenden Felder zum Erstellen eines Gastzugangs aus. Gäste können sich nicht vor ihrem Ankunftsdatum oder nach ihrem Ankunftsdatum zuzüglich einer Zeitspanne mit einem Toleranzfenster von einem Tag registrieren. Der Zugriffszeitraum startet wenn sich der Gast im Abfang-Portal (Captive-Portal) angemeldet hat" msgid "Firstname" -msgstr "" +msgstr "Vorname" msgid "firstname" -msgstr "" +msgstr "Vorname" msgid "Lastname" -msgstr "" +msgstr "Nachname" msgid "lastname" -msgstr "" +msgstr "Nachname" msgid "Company" -msgstr "" +msgstr "Firma" msgid "Company / Organization" -msgstr "" +msgstr "Firma / Organisation" msgid "organization" -msgstr "" +msgstr "Firma / Organisation" msgid "Phone number" -msgstr "" +msgstr "Telefonnummer" msgid "phone" -msgstr "" +msgstr "Telefon" msgid "Phone Provider" -msgstr "" +msgstr "Telefonanbieter" msgid "Select your provider" -msgstr "" +msgstr "Anbieter auswählen" msgid "Email" -msgstr "" +msgstr "Email" msgid "email" -msgstr "" +msgstr "Email" msgid "Sponsor's email" -msgstr "" +msgstr "Email des Sponsors" msgid "sponsor_email" -msgstr "" +msgstr "Email des Sponsors" msgid "Address" -msgstr "" +msgstr "Adresse" msgid "Arrival Date" -msgstr "" +msgstr "Ankunftsdatum" msgid "End Date" -msgstr "" +msgstr "Enddatum" msgid "Access Duration" -msgstr "" +msgstr "Zugangsdauer" msgid "Notes" -msgstr "" +msgstr "Notizen" msgid "Send access code by email" -msgstr "" +msgstr "Zugangscode per Mail schicken" msgid "Print access code" -msgstr "" +msgstr "Zugangscode drucken" msgid "Print" -msgstr "" +msgstr "Drucken" msgid "Back" -msgstr "" +msgstr "Zurück" msgid "second" msgid_plural "seconds" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Sekunde" +msgstr[1] "Sekunden" msgid "minute" msgid_plural "minutes" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Minute" +msgstr[1] "Minuten" msgid "hour" msgid_plural "hours" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Stunde" +msgstr[1] "Stunden" msgid "day" msgid_plural "days" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Tag" +msgstr[1] "Tage" msgid "week" msgid_plural "weeks" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Woche" +msgstr[1] "Wochen" msgid "month" msgid_plural "months" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Monat" +msgstr[1] "Monate" msgid "year" msgid_plural "years" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Jahr" +msgstr[1] "Jahre" msgid "Invalid access duration provided" -msgstr "" +msgstr "Ungültige Zugangsdauer angegeben" msgid "Expected on %s" -msgstr "" +msgstr "Erwartet am %s" msgid "Missing mandatory parameter or malformed entry." -msgstr "" +msgstr "Zwingender Parameter fehlt oder fehlerhafter Eintrag." msgid "Usernames must only contain alphanumeric characters." -msgstr "" +msgstr "Benutzernamen dürfen nur alphanumerische Zeichen enthalten." msgid "Access duration is not of an allowed value." -msgstr "" +msgstr "Zugriffszeitraum hat keinen gültigen Wert." msgid "Arrival date is not of expected format." -msgstr "" +msgstr "Ankunftsdatum ist nicht im erwarteten Format." msgid "" "You can't register as a guest with a %s email address. Please register as a " "regular user using your email address instead." -msgstr "" +msgstr "Sie können sich nicht als Gast mit einer %s Emailadresse anmelden. Bitte registrieren sie sich stattdessen als normaler Benutzer mit ihrer Emailadresse." msgid "An error occured while sending the confirmation email." -msgstr "" +msgstr "Beim Versenden der Besätigungsemail ist ein Fehler aufgetreten." msgid "An error occured while sending the PIN by SMS." -msgstr "" +msgstr "Beim Versenden der PIN per SMS ist ein Fehler aufgetreten." msgid "The uploaded file was corrupted. Please try again." -msgstr "" +msgstr "Die hochgeladene Datei ist korrupt. Bitte erneut versuchen." msgid "Can't open uploaded file." -msgstr "" +msgstr "Die hochgeladene Datei kann nicht geöffnet werden." msgid "Confirm Mobile Phone Number" -msgstr "" +msgstr "Handynummer bestätigen." msgid "" "Please enter the PIN code received on your mobile phone in order to gain " "access to the network." -msgstr "" +msgstr "Bitte geben sie den PIN-Code ein, den sie auf ihr Mobiltelefon erhalten haben um Netzwerkzugriff zu erhalten." msgid "PIN" -msgstr "" +msgstr "PIN" msgid "Confirm" -msgstr "" +msgstr "Bestätigen" msgid "Cancel" -msgstr "" +msgstr "Abbrechen" msgid "Guest Access Code" -msgstr "" +msgstr "Gast-Zugangscode" msgid "This username and password will be valid starting %s." -msgstr "" +msgstr "Dieser Benutzername und Password wird ab %s gültig sein." msgid "Once authenticated the access will be valid for %d %s." -msgstr "" +msgstr "Sobald sie authentifiziert wurden ist der Zugang gültig für %d %s." msgid "" "Guest successfully registered. An email with the username and password has " "been sent." -msgstr "" +msgstr "Gast erfolgreich registriert. Eine Email mit Benutzername und Password wurde verschickt." msgid "Import completed: %i guest(s) created, %i line(s) skipped." -msgstr "" +msgstr "Import abgeschlossen: %i Gäste angelegt, %i Zeilen übersprungen." msgid "Single guest creation" -msgstr "" +msgstr "Einzelnen Gast erstellen" msgid "Multiple guest accounts creation" -msgstr "" +msgstr "Mehrere Gäste erstellen" msgid "CSV file" -msgstr "" +msgstr "CSV-Datei" msgid "CSV file import" -msgstr "" +msgstr "CSV-Datei Import" msgid "You are logged in as" -msgstr "" +msgstr "Sind sind eingeloggt als" msgid "Sponsored by" -msgstr "" +msgstr "Gesponsort von" msgid "Guest Network Access Information" -msgstr "" +msgstr "Gast-Netzwerk Zugangsinformation" msgid "" "If you have scripting turned off, you will not be automatically redirected. " "Please enable scripting or open a new browser window from time to time to " "see if your access was enabled." -msgstr "" +msgstr "Wenn sie Scripting deaktiviert haben, werden sie nicht automatisch weitergeleitet. Bitte aktivieren sie Scripting oder öffnen sie immer mal ein neues Browserfenster um zu sehen ob ihr Zugriff aktiviert wurde." -msgid "Unable to detect network connectivity. Try restarting your web browser or opening a new tab to see if your access has been succesfully enabled." -msgstr "" +msgid "" +"Unable to detect network connectivity. Try restarting your web browser or " +"opening a new tab to see if your access has been succesfully enabled." +msgstr "Kann keine Netzwerkverbindung feststellen. Versuchen Sie Ihren Browser neuzustarten oder einen neuen Tab zu öffnen um zu sehen ob der Zugang erfolgreich aktiviert wurde." msgid "" "Your network access should be available. Close your current browser, and " "open a new one to start browsing." -msgstr "" +msgstr "Ihr Netzwerkzugang sollte jetzt verfügbar sein. Schliessen Sie Ihren aktuellen Browser und öffnen Sie einen Neuen" msgid "Registration pending" -msgstr "" +msgstr "Registrierung steht noch aus" msgid "" "There are known issues with the automatic redirection on Opera browsers. " "Please open a new browser window from time to time to see if your access was" " enabled." -msgstr "" +msgstr "Es gibt bekannte Probleme mit der automatischen Weiterleitung in Opera-Browsern. Bitte öffnen sie immer mal ein neues Browserfenster um zu sehen ob ihr Zugriff aktiviert wurde." msgid "" "Some versions of Internet Explorer may take a while before redirection " "occur." -msgstr "" +msgstr "Einige Versionen des Internet Explorer brauchen evtl. einen Moment bevor die Weiterleitung stattfindet." msgid "I accept the terms" -msgstr "" +msgstr "Ich akzeptiere die Bedingungen" msgid "I have read and accept the terms" -msgstr "" +msgstr "Ich habe die Bedingungen gelesen und akzeptiere sie" msgid "You need to accept the terms before proceeding any further." -msgstr "" +msgstr "Sie müssen die Bedingungen akzeptieren bevor sie fortsetzen." msgid "" "Your registration is pending approval. Once approved you will be " "automatically redirected." -msgstr "" +msgstr "Ihre Registrierung wartet auf Genehmigung. Sobald sie genehmigt wurde, werden sie weitergeleitet." msgid "Next page" -msgstr "" +msgstr "Nächste Seite" msgid "" "The activation code provided is invalid. Reasons could be: it never existed," " it was already used or has expired." -msgstr "" +msgstr "Der angegebene Aktivierungscode ist ungültig. Dies kann folgende Gründe haben: es gab ihn nie, er wurde schon benutzt oder er ist abgelaufen." msgid "" "You have been detected using a device that has been explicitly disallowed by" " your network administrator." -msgstr "" +msgstr "Es wurde festgestellt dass sie ein Gerät benutzen, welches explizit vom Administrator verboten wurde." msgid "NAT Device Detected" -msgstr "" +msgstr "NAT Gerät erkannt" msgid "" "You have been detected using a device that performs network address " "translation (NAT). These devices, typically wireless access points or " "'routers' are not permitted on the network. Please unplug this device and " "connect your computer directly to the network for access." -msgstr "" +msgstr "Es wurde festgestellt dass sie ein Gerät einsetzen welches Network Address Translation (NAT) verwendet. Diese Geräte, typischerweise AccessPoints oder Router sind in diesem Netzwerk nicht erlaubt. Bitte trennen Sie dieses Gerät vom Netzwerk und verbinden Sie ihren Rechner direkt mit dem Netzwerk um Zugriff zu erhalten." msgid "Rogue DHCP server" -msgstr "" +msgstr "Unauthorisierter DHCP Server" msgid "You have been detected running a rogue DHCP server. Please disable it." -msgstr "" +msgstr "Es wurde festgestellt dass sie einen unauthorisierten DHCP Server betreiben. Bitte deaktivieren sie ihn." msgid "Vulnerability Scanning" -msgstr "" +msgstr "Schwachstellen Scan" msgid "" "Your system will be scanned for vulnerabilities before you are allowed to " "enter the network. Please click on the button below, this can take anywhere " "from a few seconds to a couple of minutes." -msgstr "" +msgstr "Ihr System wird auf Schwachstellen geprüft bevor sie Zugang zum Netzwerk erhalten. Bitte klicken sie unten auf den Button, dies kann ein paar Sekunden bis zu mehreren Minuten dauern." msgid "Malware found!" -msgstr "" +msgstr "Schadsoftware gefunden!" msgid "" "Your system has been found to be infected with malware. Due to the threat " "this infection poses for other systems on the network, network connectivity " "has been disabled until corrective action is taken." -msgstr "" +msgstr "Es wurde festgestellt dass ihr System mit Schadsoftware infiziert ist. Aufgrund der Bedrohung die diese Infektion für andere Systeme im Netzwerk darstellt, wurde ihre Netzwerkverbindung deaktiviert bis sie das Problem behoben haben." msgid "Malware Removal" -msgstr "" +msgstr "Schadsoftware Entfernung" msgid "LSASS Worm" -msgstr "" +msgstr "LSASS Wurm" msgid "" "Your system has been found to be infected with An LSASS-based worm. Due to " "the threat this infection poses for other systems on the network, network " "connectivity has been disabled until corrective action is taken. " "Instructions for disinfection are below:" -msgstr "" +msgstr "Es wurde festgestellt dass ihr System mit einem LSASS-basierten Wurm infiziert ist. Aufgrund der Bedrohung die diese Infektion für andere Systeme im Netzwerk darstellt, wurde ihre Netzwerkverbindung deaktiviert bis sie das Problem behoben haben.\nAnweisungen zur Entfernung finden sie unten:" msgid "Worm Removal" -msgstr "" +msgstr "Wurmentfernung" msgid "" "Make sure your antivirus is working. You might want to perform a full system" @@ -655,338 +661,365 @@ msgid "" "network access. Make sure that you followed the instructions to correct the " "issue. Failure to do so will result in network access being disabled again. " "Repeated failures will result in access being disabled permanently." -msgstr "" +msgstr "Stellen sie sicher dass ihre Antiviren-Lösung funktioniert. Führen sie evtl. einen vollen System-Scan durch. Wenn sie auf den 'Netzwerk aktivieren'-Button klicken wird ihr Netzwerk wieder aktiviert. Stellen sie sicher dass sie den Angaben zum Beheben des Problems gefolgt sind. Wenn dies nicht der Fall ist, wird der Netzwerkzugriff wieder deaktiviert. Wiederholte Fehler führen zu einer permanenten Deaktivierung." msgid "Trojan Infection" -msgstr "" +msgstr "Trojaner" msgid "Unauthorized device" -msgstr "" +msgstr "Unauthorisiertes Gerät" msgid "" "Your system has been found to be infected with a Trojan IRC bot and is " "scanning other systems. Due to the threat this infection poses for other " "systems on the network, network connectivity has been disabled until " "corrective action is taken." -msgstr "" +msgstr "Es wurde festgestellt dass ihr System mit einem Trojaner IRC Bot infiziert ist und andere Systeme scannt. Aufgrund der Bedrohung die diese Infektion für andere Systeme im Netzwerk darstellt, wurde ihre Netzwerkverbindung deaktiviert bis sie das Problem behoben haben." msgid "Zotob Infection" -msgstr "" +msgstr "Zotob Infektion" msgid "" "Your system has been found to be infected with a Zotob worm and is scanning " "other systems. Due to the threat this infection poses for other systems on " "the network, network connectivity has been disabled until corrective action " "is taken." -msgstr "" +msgstr "Es wurde festgestellt dass ihr System mit einem Zotob-Wurm infiziert ist. Aufgrund der Bedrohung die diese Infektion für andere Systeme im Netzwerk darstellt, wurde ihre Netzwerkverbindung deaktiviert bis sie das Problem behoben haben." msgid "" "Your network access is currently being enabled. Once network connectivity is" " established you will be automatically redirected." -msgstr "" +msgstr "Ihr Netzwerkzugang wird gerade aktiviert. Sobald die Netzwerkverbindung hergestellt wurde, werden sie automatisch weitergeleitet." msgid "Your network access is currently being enabled. Please wait..." -msgstr "" +msgstr "Ihr Netzwerkzugang wird gerade aktiviert. Bitte warten..." msgid "You must be authenticated to manage guests." -msgstr "" +msgstr "Sie müssen authentifiziert sein um Gäste verwalten zu können." msgid "This account is expired." -msgstr "" +msgstr "Dieser Zugang ist abgelaufen." msgid "This account is not yet activated." -msgstr "" +msgstr "Dieser Zugang ist noch nicht aktiviert." msgid "" "Your network should be enabled within a minute or two. If it is not reboot " "your computer." -msgstr "" +msgstr "Ihr Netzwerk sollte in den nächsten ein bis zwei Minuten aktiviert werden. Wenn nicht, starten sie bitte ihren Rechner neu." msgid "Invalid PIN" -msgstr "" +msgstr "Ungültige PIN" msgid "Username Prefix" -msgstr "" +msgstr "Benutzername Prefix" msgid "Quantity" -msgstr "" +msgstr "Anzahl" msgid "Print access codes" -msgstr "" +msgstr "Zugriffscode drucken" msgid "Logout" -msgstr "" +msgstr "Ausloggen" msgid "Required columns: username, password." -msgstr "" +msgstr "Benötigte Spalten: Benutzername, Passwort" msgid "Column Delimiter" -msgstr "" +msgstr "Spaltenbegrenzer" msgid "Columns Order" -msgstr "" +msgstr "Spaltenreihenfolge" msgid "comma (,)" -msgstr "" +msgstr "komma(,)" msgid "semicolon (;)" -msgstr "" +msgstr "semikolon(;)" msgid "tab" -msgstr "" +msgstr "tab" msgid "Format is: yyyy-mm-dd" -msgstr "" +msgstr "Das Format ist: jjjj-mm-dd" msgid "Import file" -msgstr "" +msgstr "Importdatei" msgid "Access to the guest network has been granted until %s." -msgstr "" +msgstr "Zugriff auf das Gast-Netzwerk wurde bis zum %s gestattet" msgid "Access to the guest network has been granted." -msgstr "" +msgstr "Zugriff auf das Gast-Netzwerk wurde gewährt." msgid "Access to the guest network granted" -msgstr "" +msgstr "Zugriff auf das Gast-Netzwerk wurde gestattet" msgid "" "Your XML configuration have been generated and is now ready to download. " "Follow the link below in order to get access to the secure SSID." -msgstr "" +msgstr "Ihre XML-Konfiguration wurde generiert und steht nun zum Download bereit.\nFolgen Sie dem Link unten um Zugriff auf die sichere SSID zu bekommen." msgid "Click to install your generated wireless profile." -msgstr "" +msgstr "Klicken um das generierte Wireless-Profil zu installieren." msgid "Internet Access Package" -msgstr "" +msgstr "Internetzugriffspaket" msgid "Credit Card Number" -msgstr "" +msgstr "Kreditkartennummer" msgid "Credit Card Expiration Date" -msgstr "" +msgstr "Kreditkartenablaufdatum" msgid "MMYY" -msgstr "" +msgstr "MMJJ" msgid "Credit Card Verification Number" -msgstr "" +msgstr "Kreditkarten Prüfnummer" msgid "Continue" -msgstr "" +msgstr "Fortsetzen" msgid "" "An error occured while processing your payment. Incorrect credit card " "informations provided." -msgstr "" +msgstr "Bei der Bearbeitung ihrer Bezahlung ist ein Fehler aufgetreten. Es wurden ungültige Kreditkarteninformationen angegeben" msgid "" "An error occured while processing you payment. Your credit card has not been" " charged." -msgstr "" +msgstr "Bei der Bearbeitung ihrer Bezahlung ist ein Fehler aufgetreten. Ihre Kreditkarte wurde nicht belastet." msgid "The scan report code provided is invalid or expired." -msgstr "" +msgstr "Der Scan-Report Code ist ungültig oder abgelaufen." # SoH filters msgid "Filters" -msgstr "" +msgstr "Filter" msgid "" "Define the filters which will apply to all NAP-capable clients that produce " "a statement of health (SoH)." -msgstr "" +msgstr "Definieren sie die Filter, welche auf alle NAP-fähigen Clients, welche einen Statement of Health(SoH) liefern, angewandt werden." msgid "Delete this filter" -msgstr "" +msgstr "Diesen Filter löschen" msgid "Do nothing" -msgstr "" +msgstr "Nichts tun" msgid "Accept" -msgstr "" +msgstr "Akzeptieren" msgid "Reject" -msgstr "" +msgstr "Abweisen" msgid "Trigger violation" -msgstr "" +msgstr "Verstoß auslösen" msgid "Conditions:" -msgstr "" +msgstr "Bedingungen:" msgid "(None yet)" -msgstr "" +msgstr "(bisher keine)" msgid "Add a condition" -msgstr "" +msgstr "Bedingung hinzufügen" msgid "Delete this condition" -msgstr "" +msgstr "Diese Bedingung löschen" msgid "Firewall" -msgstr "" +msgstr "Firewall" msgid "Anti-virus" -msgstr "" +msgstr "Antivirus" msgid "Anti-spyware" -msgstr "" +msgstr "Anti-Spyware" msgid "Auto-updates" -msgstr "" +msgstr "Auto-Updates" msgid "Security updates" -msgstr "" +msgstr "Sicherheitsupdates" msgid "is" -msgstr "" +msgstr "ist" msgid "is not" -msgstr "" +msgstr "ist nicht" msgid "ok" -msgstr "" +msgstr "Ok" msgid "installed" -msgstr "" +msgstr "installiert" msgid "enabled" -msgstr "" +msgstr "aktiviert" msgid "disabled" -msgstr "" +msgstr "deaktiviert" msgid "up-to-date" -msgstr "" +msgstr "aktuell" msgid "from Microsoft" -msgstr "" +msgstr "von Microsoft" msgid "Action:" -msgstr "" +msgstr "Aktion:" msgid "Add a filter" -msgstr "" +msgstr "Filter hinzufügen" msgid "Save filters" -msgstr "" +msgstr "Filter speichern" msgid "Invalid response" -msgstr "" +msgstr "Ungültige Antwort" msgid "Request failed" -msgstr "" +msgstr "Anfrage fehlgeschlagen" msgid "Are you sure you want to delete this filter?" -msgstr "" +msgstr "Diesen Filter wirklich löschen ?" msgid "Enter new filter name" -msgstr "" +msgstr "Neuen Filternamen eingeben" msgid "Guest Sponsor Login" -msgstr "" +msgstr "Gast Sponsor Login" msgid "Before we proceed with guest activation, we need you to authenticate." -msgstr "" +msgstr "Bevor wir mit der Gast-Aktivierung fortfahren, müssen Sie sich authentifizieren." msgid "" "You have reached the maximum number of devices you are able to register with" " this username." -msgstr "" +msgstr "Sie haben die maximale Anzahl an Geräten erreicht, die Sie mit diesem Benutzer registrieren können." msgid "" "An email has been sent to your email address. Click on the activation link " "to confirm your email address. Once confirmed you will receive a username " "and password by email for you to use once on-site." -msgstr "" +msgstr "Eine Email wurde an Ihre Emailadresse geschickt. Klicken Sie auf den Aktivierungslink um Ihre Emailadresse zu bestätigen. Sobald diese bestätigt ist, erhalten Sie per Email einen Benutzernamen und ein Passwort zur Verwendung vor Ort." msgid "" "An access request was sent to the sponsor's email. You will receive an email" " with a username and password once your access has been approved." -msgstr "" +msgstr "Eine Zugriffsanfrage wurde an die Email des Sponsors geschickt. Sie erhalten eine Email mit Benutzernamen und Passwort sobald Ihr Zugriff bestätigt wurde." msgid "Registration in advance by SMS is not supported." -msgstr "" +msgstr "Vorabregistrierung per SMS wird nicht unterstützt." msgid "%s: Guest Network Access Information" -msgstr "" +msgstr "%s: Gast-Netzwerk Zugangsinformation" msgid "%s: Guest access confirmed!" -msgstr "" +msgstr "%s: Gast Zugang bestätigt!" msgid "%s: Guest network access enabled" -msgstr "" +msgstr "%s: Gastnetzwerk-Zugriff aktiviert" msgid "" "There was a problem trying to find the computer to register. The problem has" " been logged." -msgstr "" +msgstr "Es gab ein Problem beim Versuch den zu registrierenden Computer zu finden. Das Problem wurde geloggt." msgid "" "The device with MAC address %s has already been authorized to your network." -msgstr "" +msgstr "Das Gerät mit der MAC-Adresse %s wurde bereits für Ihr Netzwerk autorisiert." msgid "%s: Guest access request" -msgstr "" +msgstr "%s: Gastzugangsanfrage" msgid "%s: Guest access request accepted" -msgstr "" +msgstr "%s: Gastzugangsanfrage angenommen" msgid "Guest pre-registration is not allowed by policy" -msgstr "" +msgstr "Gast Vorabregistrierung ist per Richtlinie nicht erlaubt" msgid "" "If you choose to have your access sponsored, we will send " "an email to the Sponsor email you provided with an activation link. The " "sponsor will need to click on that link and authenticate in order to approve" " you in." -msgstr "" +msgstr "Wenn sie sich entscheiden ihren Zugangs per Sponsor zu erhalten, werden wir einen Aktivierungslink per Email an die Emailadresse des Sponsors, den Sie angegeben haben schicken. Der Sponsor muss dann auf diesen Link klicken und sich authentifizieren um Sie zu bestätigen." msgid "You will receive guest credentials by email once approved." -msgstr "" +msgstr "Sie erhalten Gastzugangsdaten per Email sobald Ihr Zugang bestätigt wurden." msgid "You will be in a waiting area until approved." -msgstr "" +msgstr "Sie werden sich in einem Wartebereich befinden bis Ihr Zugang bestätigt wurde." msgid "Register through a Sponsor" -msgstr "" +msgstr "Per Sponsor registrieren" msgid "Network Access Requested" -msgstr "" +msgstr "Netzwerkzugang beantragt" msgid "Access to the guest network confirmed" -msgstr "" +msgstr "Zugang zum Gastnetzwerk bestätigt" msgid "" "Access to the guest network has been successfully confirmed. You should " "receive credentials for on-site guest access by email shortly." -msgstr "" +msgstr "Zugang zum Gastnetzwerk wurde erfolgreich bestätigt. Sie sollten die Zugangsdaten für den Gastzugang vor Ort in Kürze per Email erhalten." msgid "%s: Email activation required" -msgstr "" +msgstr "%s: Emailaktivierung erforderlich" msgid "Missing mandatory parameter or malformed entry" -msgstr "" +msgstr "Zwingender Parameter fehlt oder fehlerhafter Eintrag." msgid "Missing mandatory parameter(s): %s" -msgstr "" +msgstr "Fehlende(r) zwingende(r) Parameter: %s" msgid "Illegal email address provided" -msgstr "" +msgstr "Ungültige Emailadresse angegeben" msgid "Illegal phone number provided" -msgstr "" +msgstr "Ungültige Telefonnummer angegeben" msgid "Acceptable Use Policy (AUP) was not accepted" -msgstr "" +msgstr "Nutzungsvereinbarung wurde nicht akzeptiert" msgid "Your access can only be sponsored by a %s email address" -msgstr "" +msgstr "Ihr Zugang kann nur von einer %s Emailadresse gesponsort werden" msgid "Unable to validate your sponsor at the moment" -msgstr "" +msgstr "Ihr Sponsor kann im Moment nicht überprüft werden" msgid "Email %s is not allowed to sponsor guest access" -msgstr "" +msgstr "Die Email %s darf keinen Gastzugang sponsoren" + +msgid "You need to be authenticated to access this page." +msgstr "Sie müssen sich authentifizieren um auf diese Seite zuzugreifen." + +msgid "OAuth2 Error: Failed to get the token" +msgstr "OAuth2 Fehler: Kein Token erhalten" + +msgid "OAuth2 Error: Failed to validate the token, please retry" +msgstr "OAuth2 Fehler: Token konnte nicht validiert werden, bitte erneut versuchen" + +msgid "Registration canceled please try again" +msgstr "Registrierung abgebrochen, bitte erneut versuchen" + +msgid "Please verify MAC address provided" +msgstr "Bitte angegebene MAC-Adresse verifizieren" + +msgid "You are not authorized" +msgstr "Sie sind nicht berechtigt" + +msgid "The MAC address %s has been successfully registered." +msgstr "Die MAC-Adresse %s wurde erfolgreich registriert." + +msgid "The MAC address %s provided is invalid please try again" +msgstr "Die MAC-Adresse %s ist ungültig, bitte nochmal versuchen" + +msgid "This module is not enabled" +msgstr "Dieses Modul ist nicht aktiviert" From 126d4870b217c13936ec344ed4393c55082ac3b9 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Wed, 11 Dec 2013 13:48:20 -0500 Subject: [PATCH 366/369] Prepare release 4.1.0 --- NEWS.asciidoc | 4 ++-- debian/changelog | 6 ++++++ ...PacketFence_Network_Devices_Configuration_Guide.asciidoc | 4 ++-- docs/docinfo.xml | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/NEWS.asciidoc b/NEWS.asciidoc index be91d0e08974..b9e94f3cf2de 100644 --- a/NEWS.asciidoc +++ b/NEWS.asciidoc @@ -11,7 +11,7 @@ This is a list of noteworthy changes across releases. For more details and developer visible changes see the ChangeLog file. For a list of compatibility related changes see the UPGRADE.asciidoc file. -Version 4.1.0 released on 2013-MM-DD +Version 4.1.0 released on 2013-12-11 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ New Features @@ -20,7 +20,7 @@ New Features * Portal profiles can be filtered by switches * Proxy interception * New pfcmd command fixpermissions -* Added a Null Authenication Source +* Added a "Null" authenication source * Displayed columns of nodes are now customizable * Create a single node or import multiple nodes from a CSV file from the Web admin * LDAP authentication sources can now filter by group membership using a second LDAP query diff --git a/debian/changelog b/debian/changelog index e36c7a519844..e45bd5236159 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +packetfence (4.1.0) unstable; urgency=low + + * Version 4.1.0 + + -- Francis Lachapelle Wed, 11 Dec 2013 12:00:00 -0400 + packetfence (4.0.6) unstable; urgency=low * Version 4.0.6 diff --git a/docs/PacketFence_Network_Devices_Configuration_Guide.asciidoc b/docs/PacketFence_Network_Devices_Configuration_Guide.asciidoc index 37d768cac4e9..e998dd6a9ee8 100644 --- a/docs/PacketFence_Network_Devices_Configuration_Guide.asciidoc +++ b/docs/PacketFence_Network_Devices_Configuration_Guide.asciidoc @@ -47,7 +47,7 @@ Note on Inline enforcement support ---------------------------------- There is no need to follow the instructions in this guide if you plan on deploying in inline -enforcement, except radius inline. In this case all you need to do is to have a flat layer 2 network up to +enforcement, except RADIUS inline. In this case all you need to do is to have a flat layer 2 network up to PacketFence's inline interface with no other gateway available for devices to reach out to the Internet. @@ -1130,7 +1130,7 @@ Dell Force 10 ^^^^^^^^ -PacketFence supports this switch using radiusi mac-auth and 802.1x +PacketFence supports this switch using RADIUS, MAC-Authentication and 802.1x. Global config settings diff --git a/docs/docinfo.xml b/docs/docinfo.xml index c4824483c4bd..7ef185ee3153 100644 --- a/docs/docinfo.xml +++ b/docs/docinfo.xml @@ -1,7 +1,7 @@ Version 4.1.0 - December 2013 for version 4.1.0 -2013-12-05 +2013-12-11 Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License". From a0d35eb98e6f495ea606e75e652ed9dda51bd2d8 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Wed, 11 Dec 2013 14:03:39 -0500 Subject: [PATCH 367/369] Prepare release 4.1.0 --- addons/packages/packetfence.spec | 3 +++ 1 file changed, 3 insertions(+) diff --git a/addons/packages/packetfence.spec b/addons/packages/packetfence.spec index 7daa42a7e9d3..ccd1f42509b6 100644 --- a/addons/packages/packetfence.spec +++ b/addons/packages/packetfence.spec @@ -870,6 +870,9 @@ fi %attr(6755, root, root) /usr/local/pf/bin/pfcmd %changelog +* Wed Dec 11 2013 Francis Lachapelle - 4.1.0-1 +- New release 4.1.0 + * Thu Sep 5 2013 Francis Lachapelle - 4.0.6-1 - New release 4.0.6 From 53bd99cb11bb531d489552d3480a7ac2fda9d5d5 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Wed, 11 Dec 2013 14:20:03 -0500 Subject: [PATCH 368/369] Update ChangeLog --- ChangeLog | 3572 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 3572 insertions(+) diff --git a/ChangeLog b/ChangeLog index fe6b25077484..a05ab8f956e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,3575 @@ +commit a0d35eb98e6f495ea606e75e652ed9dda51bd2d8 +Author: Francis Lachapelle +Date: Wed Dec 11 14:03:39 2013 -0500 + + Prepare release 4.1.0 + +M addons/packages/packetfence.spec + +commit 126d4870b217c13936ec344ed4393c55082ac3b9 +Author: Francis Lachapelle +Date: Wed Dec 11 13:48:20 2013 -0500 + + Prepare release 4.1.0 + +M NEWS.asciidoc +M debian/changelog +M docs/PacketFence_Network_Devices_Configuration_Guide.asciidoc +M docs/docinfo.xml + +commit 29d5553ea30e1649a4e0aec38511fa57ed3a2475 +Author: Francis Lachapelle +Date: Wed Dec 11 13:45:00 2013 -0500 + + Update German translation + +M NEWS.asciidoc +M conf/locale/de/LC_MESSAGES/packetfence.po + +commit 044e706cad15ac9b5620e5bf8bf785435da60ba0 +Author: Francis Lachapelle +Date: Wed Dec 11 12:26:14 2013 -0500 + + Improve help on Web admin interface + +M html/pfappserver/root/configuration/adminroles/index.tt +M html/pfappserver/root/portal/profile/view.tt +M lib/pf/pfcmd/help.pm + +commit 3e67e39c24d1444254d4bf9e8429f3b6e6d69ddd +Author: Francis Lachapelle +Date: Wed Dec 11 12:05:37 2013 -0500 + + Improve error message in Null auth source + +M lib/pf/Authentication/Source/NullSource.pm + +commit 108a7a854fec544750b15f5f155d4eaad9e4fb96 +Author: Francis Lachapelle +Date: Wed Dec 11 12:05:00 2013 -0500 + + Cleanup bundled values of authentication.conf + +M conf/authentication.conf + +commit d34f7441c1fd3ab492e8a0c62ff52649b04c6743 +Author: Francis Lachapelle +Date: Wed Dec 11 11:50:26 2013 -0500 + + Simple search of nodes: respect spaces + + We must respect the space characters when the search string doesn't + match a MAC address. + +M lib/pf/node.pm + +commit c96192b7d6b9a6e4f0415853205165c097f36494 +Author: Jean Raby +Date: Wed Dec 11 10:48:40 2013 -0500 + + fix invalid regex (^ was escaped by the shell) + +M addons/watchdog/freeradius-watchdog.sh + +commit 6bdccd9845ff5e457188d55cea3bfba189a2ed46 +Author: Francis Lachapelle +Date: Tue Dec 10 14:46:48 2013 -0500 + + Improve SSID report on web admin + +M NEWS.asciidoc +M lib/pf/pfcmd/report.pm + +commit 4c73805b7de7d73d1ebec0e6690782f6426fc290 +Author: Durand Fabrice +Date: Tue Dec 10 09:26:03 2013 -0500 + + Removed support for the httpd service + +M lib/pf/pfcmd.pm + +commit 858f8267fb45a018118ce2199b4aa0652eca9e3d +Author: James Rouzier +Date: Mon Dec 9 13:07:17 2013 -0500 + + Will not set destination_url if the url matches the captive portal + +M lib/pf/web/dispatcher.pm + +commit 01eae41b6192ec5e3fe663caf7a8a5f20750b3d0 +Author: James Rouzier +Date: Mon Dec 9 12:46:27 2013 -0500 + + Use isenabled for forceRedirectURL + +M lib/pf/Portal/Session.pm + +commit 4f9252398c13932663824d1fe7c2711e6c9ada0d +Author: James Rouzier +Date: Fri Dec 6 16:11:58 2013 -0500 + + Updated news file + +M NEWS.asciidoc + +commit bcc51e64b47e1ea6885c4f0020104e203672e340 +Author: James Rouzier +Date: Mon Jul 15 11:28:12 2013 -0400 + + Use the correct prepared statement when there are no dates defined + +M lib/pf/ifoctetslog.pm + +commit 95db68e4f8ea6afbeaa5d9a9e732a423ef40716b +Author: James Rouzier +Date: Fri Dec 6 15:02:52 2013 -0500 + + Clearing network information when reloading pf.conf + +M lib/pf/config.pm + +commit 0493a64e8ec18641a5f347dab47772b5840a7e41 +Author: James Rouzier +Date: Fri Dec 6 14:37:08 2013 -0500 + + Start/Stop/Restart will now call the pfcmd and wait for it's completion before return + +M html/pfappserver/lib/pfappserver/Controller/Service.pm + +commit 5185a250e832cf89a87c631614ac2f4c52f1f4bf +Author: James Rouzier +Date: Fri Dec 6 14:25:32 2013 -0500 + + Service status is called with quick parameter + +M html/pfappserver/lib/pfappserver/Model/Services.pm + +commit 0011712941e21f74e6343f56843077ed76897e06 +Author: James Rouzier +Date: Fri Dec 6 14:24:16 2013 -0500 + + Will not removestaleFile if the quick argument is true + +M lib/pf/services/manager.pm +M lib/pf/services/manager/submanager.pm + +commit 4509bfece03bd493658871122bcf0f8b78ec9621 +Author: Francis Lachapelle +Date: Fri Dec 6 11:17:47 2013 -0500 + + Add allow_localdomain option to the sponsor source + +M NEWS.asciidoc +M conf/authentication.conf +M html/pfappserver/lib/pfappserver/Form/Authentication/Source/Null.pm +M html/pfappserver/lib/pfappserver/Form/Authentication/Source/SponsorEmail.pm +M html/pfappserver/root/authentication/source/type/SponsorEmail.tt +M lib/pf/Authentication/Source/SponsorEmailSource.pm +M lib/pf/web/guest.pm + +commit 59ae1ac51e4af794eba4df8221c7b1b536b30946 +Author: Francis Lachapelle +Date: Fri Dec 6 11:09:58 2013 -0500 + + Fix saving allow_localdomain in email source + + When the checkbox was unchecked, the option was not saved and was + enabled by default. + +M NEWS.asciidoc +M html/pfappserver/lib/pfappserver/Form/Authentication/Source/Email.pm +M lib/pf/Authentication/Source/EmailSource.pm +M lib/pf/Authentication/Source/NullSource.pm + +commit e96e1f2070fe32b0020a0d61fdfd588f8cf56703 +Author: Francis Lachapelle +Date: Thu Dec 5 16:48:58 2013 -0500 + + New link on SMS confirmation page to cancel + + Instead of automatically changing the node status to unreg when visiting + the captive portal, we now keep the node in pending mode but allow the + user to go back to the registration page that will unregister the node + and display the login/registration page. + +M NEWS.asciidoc +M html/captive-portal/redir.cgi +M html/captive-portal/templates/guest/sms_confirmation.html + +commit 8ad273092bbc8ca61c355b0c882a10494ed560c4 +Author: Francis Lachapelle +Date: Thu Dec 5 16:47:09 2013 -0500 + + Initial destination URL is now respected with FF + +M NEWS.asciidoc +M html/captive-portal/templates/pending.html +M html/captive-portal/templates/release.html +M html/captive-portal/templates/scan-in-progress.html +M html/common/pf.js +M lib/pf/Portal/Session.pm +M lib/pf/web.pm + +commit 5c04de6f2e8e9bbaad7ee49caff574758a41bf4e +Author: Francis Lachapelle +Date: Thu Dec 5 14:40:30 2013 -0500 + + Fixed pid of SMS-registered devices + +M NEWS.asciidoc +M html/captive-portal/mobile-confirmation.cgi + +commit aeeb54f2d3c435a68fd52c85a683b2b778c89a75 +Author: Durand Fabrice +Date: Thu Dec 5 10:04:54 2013 -0500 + + Fix redirect_url + +M lib/pf/web.pm + +commit db4b7ce341b4f3cb9cbad8f7f4d13619124a6e31 +Author: James Rouzier +Date: Wed Dec 4 14:34:44 2013 -0500 + + Will pass orginal url to captive portal as the destination_url + +M lib/pf/web/dispatcher.pm + +commit b3191cbb2aa5cb2a033f6fd72e21ed0b693a3948 +Author: Durand Fabrice +Date: Wed Dec 4 13:16:48 2013 -0500 + + Added autoreg default value in node_modify + +M lib/pf/node.pm + +commit 0a791b092e41a9a72b9ded4c15e2cd240e72c783 +Author: Durand Fabrice +Date: Wed Dec 4 10:25:55 2013 -0500 + + Update doc for dynamic radius client and fix sql syntax + +M docs/PacketFence_Administration_Guide.asciidoc +M raddb/sites-available/dynamic-clients + +commit 9b006cf3ce431fdd85ef87ee5c239dd76f5efbea +Author: Durand Fabrice +Date: Wed Dec 4 09:26:41 2013 -0500 + + Missing autoreg in node_add sql and test if pf.conf exist before trying to manage iptables + +M bin/pfcmd.pl +M lib/pf/node.pm + +commit 6b6073b9e868299ab5b38c090c65fc4812c44bd7 +Author: James Rouzier +Date: Tue Dec 3 14:45:18 2013 -0500 + + Change the default admin level + +M conf/authentication.conf + +commit c8db7ae8bf9650c11e598d18f490dbda15871567 +Author: Durand Fabrice +Date: Tue Dec 3 14:43:05 2013 -0500 + + Fix syntax + +M lib/pf/vlan.pm + +commit 850c83c6e43d52e6b0579b6bf8353b3a2a7e2c47 +Author: Durand Fabrice +Date: Tue Dec 3 14:33:48 2013 -0500 + + added a new column in node table to detect if the node has been auto registered + +M NEWS.asciidoc +M db/pf-schema-4.1.0.sql +M db/upgrade-4.0.0-4.1.0.sql +M lib/pf/node.pm +M lib/pf/vlan.pm + +commit 8dd8caae28794cdf97d9ac45e5c918a8f9440f59 +Author: Francis Lachapelle +Date: Tue Dec 3 10:06:24 2013 -0500 + + Fix warning in condition in pf::vlan + +M lib/pf/vlan.pm + +commit 12015d45f33ef03365684797a54c68059ace9ada +Author: Francis Lachapelle +Date: Tue Dec 3 09:49:32 2013 -0500 + + Bump release to 4.1.0 + +M conf/pf-release +M docs/docinfo.xml +M docs/includes/global-attributes.asciidoc + +commit 3cf7ab61232404437ad7d4c74f22313b8d88e47a +Author: Francis Lachapelle +Date: Tue Dec 3 09:46:54 2013 -0500 + + Update HTTP/BrowserDetect.pm + +M lib/HTTP/BrowserDetect.pm + +commit f75306001e54a512998225352ecd86941b316566 +Author: Francis Lachapelle +Date: Tue Dec 3 09:40:00 2013 -0500 + + Fix warning in condition in pf::vlan + +M lib/pf/vlan.pm + +commit fd482e1e60264fa994eff38472bf2f54ffdb15e3 +Author: Francis Lachapelle +Date: Tue Dec 3 09:17:46 2013 -0500 + + Fix packaging + +M addons/packages/packetfence.spec +M debian/packetfence.conffiles + +commit 7e8eea8cd15b3b0a687036c5b4938195340ae7f9 +Author: Francis Lachapelle +Date: Mon Dec 2 22:28:21 2013 -0500 + + Fix reordering of conf sections and groups + + Fixes #1749 + +M NEWS.asciidoc +M lib/pf/IniFiles.pm + +commit e4d21cdb79186ad4445dc8ec4c663629afdb3267 +Author: James Rouzier +Date: Mon Dec 2 18:43:52 2013 -0500 + + New schema for 4.1.0 release + +A db/pf-schema-4.1.0.sql + +commit 91d10b766bad7e98e83859997295dc646add6b63 +Author: James Rouzier +Date: Mon Dec 2 16:33:11 2013 -0500 + + Will not attempt to repopulate db if if database is down + +M lib/pf/freeradius.pm + +commit 3e137256d747ea5dad7e7614da385585441a0652 +Author: James Rouzier +Date: Mon Dec 2 12:04:13 2013 -0500 + + Refactor color usage on the command + +M bin/pfcmd.pl + +commit 26865a9cee896baec98acc126131c75f30fc569f +Author: James Rouzier +Date: Mon Dec 2 12:00:29 2013 -0500 + + Check if the database is alive before loading into database + +M lib/pf/violation_config.pm + +commit 8e489db30e9f345448ba1e56b7d6e24c558c4de9 +Author: James Rouzier +Date: Mon Dec 2 11:56:12 2013 -0500 + + Add db_ping function + +M lib/pf/db.pm + +commit dd4fada0f5e07ab89b86b607e62e5b510df2a5b9 +Author: James Rouzier +Date: Fri Nov 29 17:28:53 2013 -0500 + + Validate startup array references + +M bin/pfcmd.pl + +commit 413a6db801187d8f288e5ac4df112c6d8b85196f +Author: James Rouzier +Date: Mon Dec 2 09:50:15 2013 -0500 + + Will only attempt repopulation of switches if there switches need to be changed + +M lib/pf/freeradius.pm + +commit 3dea4202097adc6651596a2a7519ce33f17ecee0 +Author: Francis Lachapelle +Date: Mon Dec 2 15:41:31 2013 -0500 + + Update NEWS and UPGRADE files + +M NEWS.asciidoc +M UPGRADE.asciidoc +D conf/admin_roles.conf + +commit 3e5827caecfbcc48741a489f30bba02554e9a019 +Author: Durand Fabrice +Date: Mon Dec 2 14:04:45 2013 -0500 + + Synchronise locationlog before trying to match source in portal profile (Autoreg 802.1x) + +M lib/pf/radius.pm + +commit b84ae2ebb2fa5e920c6e3aa00d58d8a90028d4ec +Author: lzammit +Date: Mon Dec 2 13:35:21 2013 -0500 + + Update PacketFence_Administration_Guide.asciidoc + + Disable resolvconf + +M docs/PacketFence_Administration_Guide.asciidoc + +commit b1dcd5cf60b480c87e296303af9e57d41209d15b +Author: Louis Munro +Date: Mon Dec 2 11:06:42 2013 -0500 + + Added a barnyard2 init script. + +M NEWS.asciidoc +A addons/barnyard2.sh + +commit e8166606c4fa25112536de9abc6d88b446f62734 +Author: Durand Fabrice +Date: Mon Dec 2 10:03:27 2013 -0500 + + Added proxy log files in logrotate + +M addons/logrotate + +commit 1cb1414637c3ab64328ba1d37b34947f0001d8d7 +Author: Louis Munro +Date: Mon Dec 2 09:56:10 2013 -0500 + + Updated NEWS.asciidoc to reflect logrotate changes. + +M NEWS.asciidoc + +commit 19cc2d6a484b162d45cf3622a02fbabfe04ae9ed +Author: Louis Munro +Date: Mon Dec 2 09:52:08 2013 -0500 + + Modified logrotate to use copytrucate instead of restarting services. + +M addons/logrotate + +commit aaefe69579e9dc0b5e03afd62698e8190aae28bd +Author: Durand Fabrice +Date: Fri Nov 29 21:40:14 2013 -0500 + + Check the role for dot1x autoregistration from the authentication sources defined + in the captiv portal associated to the connection instead of all the authentication sources. + +M lib/pf/vlan.pm + +commit d682450c9e488d3d3007e1f668975c5a949f30ce +Author: Durand Fabrice +Date: Fri Nov 29 15:16:31 2013 -0500 + + Fix the error "dispatcher.pm line 70", missing test on the Referer + +M lib/pf/web/dispatcher.pm + +commit f5ea594eafcd750135c3b15be732349a9da822c9 +Author: Francis Lachapelle +Date: Fri Nov 29 10:29:39 2013 -0500 + + Fix condition to avoid warning + +M lib/pf/vlan.pm + +commit 13db4dc40a013804f897c00241af7fe30cfb61e0 +Author: James Rouzier +Date: Thu Nov 21 11:40:42 2013 -0500 + + Updated NEWS files + +M NEWS.asciidoc + +commit 144e93976639937bed2f6f80b01b5cde9434c97a +Author: James Rouzier +Date: Thu Nov 21 11:40:21 2013 -0500 + + Will not truncate radius_nas table on restart + +M lib/pf/services.pm +M lib/pf/services/radiusd.pm + +commit d8224a425ffb45261f6596e30de68b66ab0b7679 +Author: James Rouzier +Date: Tue Oct 15 14:19:50 2013 -0400 + + Allow switch to be read dynamically by radius + +M lib/pf/SwitchFactory.pm +M lib/pf/freeradius.pm +M raddb/policy.conf +M raddb/sites-available/dynamic-clients + +commit 7a575d768d20d94b2d307142862e085689c151f0 +Author: Francis Lachapelle +Date: Fri Nov 29 09:20:05 2013 -0500 + + Use prototype Delay method to respect seconds + + We were using the standard setTimeout function which expects + miliseconds, not seconds. + +M html/common/pf.js + +commit ba94b86e0f6e080b523b087b6289288bf463cf23 +Author: Durand Fabrice +Date: Thu Nov 28 16:23:21 2013 -0500 + + Fixed AeroHive trap + +M lib/pf/SNMP/AeroHIVE.pm + +commit 7fce2e5e5bead1614f8982d723067bccb9bb643a +Author: James Rouzier +Date: Thu Nov 28 13:21:23 2013 -0500 + + Start service that require no checkup before service that require checkup + +M bin/pfcmd.pl + +commit 0d425e475c0bcb91cebf0db968c451a88fbb6ca7 +Author: James Rouzier +Date: Thu Nov 28 13:19:35 2013 -0500 + + Setup attribute shouldCheckup to 0 + +M lib/pf/services/manager/httpd_admin.pm +M lib/pf/services/manager/memcached.pm + +commit d9ebfb6a1fd03e571b7c899a6a430c5a54f8e5bf +Author: James Rouzier +Date: Thu Nov 28 13:18:53 2013 -0500 + + Added new attribute shouldCheckup + +M lib/pf/services/manager.pm + +commit 18ce0dcfd6ce4d30fad6994f2949cd45163f178b +Author: James Rouzier +Date: Wed Nov 27 12:04:16 2013 -0500 + + Return value of the parent stop command + +M lib/pf/services/manager/dhcpd.pm + +commit 74032b9b3b5fc943d436ff25714791fc52621feb +Author: James Rouzier +Date: Wed Nov 27 12:03:18 2013 -0500 + + Display better message when a service was not stopped + +M bin/pfcmd.pl + +commit 0c4e5119222189bbc70786285dd2dca6824f6e07 +Author: James Rouzier +Date: Wed Nov 27 12:03:07 2013 -0500 + + Refactor reset + +M bin/pfcmd.pl + +commit a50db5ac614c083bbb12bb7bc23d647eb0a57e4b +Author: James Rouzier +Date: Wed Nov 27 11:49:15 2013 -0500 + + Untaint launcher before passing it to sprintf + +M lib/pf/services/manager.pm + +commit 2d42b20f64c0621390e4e3b23ae3e3e6a66f32c6 +Author: James Rouzier +Date: Wed Nov 20 12:43:24 2013 -0500 + + Fixed configuration generation for httpd based services + +M lib/pf/services/manager/httpd.pm + +commit 4e5e385bd1f083cba886b7f83e37bb85e53df8fa +Author: Francis Lachapelle +Date: Mon Nov 18 13:32:36 2013 -0500 + + Add dependency to Linux::Inotify2 + +M addons/packages/packetfence.spec +M debian/control + +commit ddbeadff8812299796fd63e068552e8194a71e52 +Author: James Rouzier +Date: Fri Oct 18 11:51:39 2013 -0400 + + Refactor get(Stop|Start)ServiceManagers to getManagers + +M bin/pfcmd.pl + +commit c9e9140e218a09bf66a694b9a5b91494c0e63115 +Author: James Rouzier +Date: Tue Oct 15 14:32:47 2013 -0400 + + Group the sub pfhcplistener pidfiles in one inotify object + +M lib/pf/services/manager/pfdhcplistener.pm + +commit bf51c3cbdb088e96adf8979e8e8d5110c95c16e2 +Author: James Rouzier +Date: Tue Oct 15 14:30:35 2013 -0400 + + Moved to use timerfd for timeouts + +M lib/pf/services/manager.pm + +commit ecb706a659955d04f1d1a43b5ea1a2cb7b8ce7b9 +Author: James Rouzier +Date: Fri Oct 4 14:36:45 2013 -0400 + + Added new perl modules + +M addons/packages/packetfence.spec +M debian/control + +commit 8256bd6cad292889fb33f631fcb0d992a7f1c260 +Author: James Rouzier +Date: Fri Oct 4 12:46:42 2013 -0400 + + pfcmd service now has color + +M bin/pfcmd.pl + +commit 7035b857e7dd3145349a8145b610b4aa22c168bf +Author: James Rouzier +Date: Thu Oct 3 20:08:26 2013 -0400 + + Refactor stop watch generateConfig startService postStartCleanup to a generalized around modifier + Overloaded removeStalePid to call removeStalePid on submanagers + +M lib/pf/services/manager/submanager.pm + +commit ac0e21faa2f9f06712adfddba398581fe56ff308 +Author: James Rouzier +Date: Thu Oct 3 18:01:05 2013 -0400 + + refactor the creation of the cmdline to a seperate function + +M lib/pf/services/manager.pm + +commit 0e15324af0f258f0f7ba30557ccdc90ed29b5c4a +Author: James Rouzier +Date: Tue Oct 1 15:14:35 2013 -0400 + + Removed unused variables + +M lib/pf/services.pm + +commit bea183a92377f9c0665cf4dc231e8f580dd738b1 +Author: James Rouzier +Date: Tue Oct 1 14:31:49 2013 -0400 + + Avoid printing double headers on restart + +M bin/pfcmd.pl + +commit 2aa3ec33d436135fe8f4cb607f3ab4eeef528558 +Author: James Rouzier +Date: Tue Oct 1 06:29:18 2013 -0400 + + Add httpd.proxy to service list + +M lib/pf/pfcmd.pm +M lib/pf/services.pm +A lib/pf/services/manager/httpd_proxy.pm + +commit 1eb1d3bfcf0befad454d14002689a6aeca2e1787 +Author: James Rouzier +Date: Mon Sep 30 17:18:45 2013 -0400 + + renamed pf::services::manager::roles::pf_conf_service_managed to pf::services::manager::roles::is_managed_by_pf_conf + +M lib/pf/services/manager/dhcpd.pm +M lib/pf/services/manager/memcached.pm +M lib/pf/services/manager/pfdns.pm +M lib/pf/services/manager/radiusd.pm +A lib/pf/services/manager/roles/is_managed_by_pf_conf.pm +D lib/pf/services/manager/roles/pf_conf_service_managed.pm +M lib/pf/services/manager/snort.pm +M lib/pf/services/manager/suricata.pm + +commit e6ac306d680ad8b8d930114b2f8ec972ec27759c +Author: James Rouzier +Date: Mon Sep 30 09:48:07 2013 -0400 + + Created test and dummy daemon for testing pf::services::manager + +A t/daemon.t +A t/services/dummy + +commit 18baee876e763153d2ecb0460b257abc90e2ea7d +Author: James Rouzier +Date: Mon Sep 30 08:02:22 2013 -0400 + + Code cleanp better logging + +M lib/pf/services/manager.pm + +commit ff296c1fd8af9650b2a6f333d8ebe6ebceaa994b +Author: James Rouzier +Date: Fri Sep 27 15:17:47 2013 -0400 + + Refactored stop where if the process did not stop in 60 seconds kill -9 the process + +M lib/pf/services/manager.pm + +commit cacc253250919fbc4ee21a27417ef36845af95cb +Author: James Rouzier +Date: Thu Sep 26 00:59:18 2013 -0400 + + Refactored pf status in terms of the service manager model + +M html/pfappserver/lib/pfappserver/Model/Services.pm + +commit 15c6714b2e1096c4d00b4f5e3a353891fe1bcd53 +Author: James Rouzier +Date: Wed Sep 25 13:05:39 2013 -0400 + + Removed all old code from lib/pf/services.pm + Refactored service_list & service_ctl in terms of pf::services::manager + moved function getServiceManager from bin/pfcmd.pl to pf::services::get_service_manager + + Removed all code from bin/pfcmd.pl + Refactor getServiceManager to pf::services::get_service_manager + added checkup before starting services + +M bin/pfcmd.pl +M lib/pf/services.pm + +commit c75b6c9d7119bc99b5c5f6f8b3331bed9f9d952d +Author: James Rouzier +Date: Wed Sep 25 12:22:38 2013 -0400 + + Added missing module + +M lib/pf/services/manager/pfdhcplistener.pm + +commit 34503dfc1ff644753d0a7d8467c417975e00584d +Author: James Rouzier +Date: Wed Sep 25 11:34:55 2013 -0400 + + Added vlan/inline enforcement check for is managed + +M lib/pf/services/manager/dhcpd.pm +M lib/pf/services/manager/pfdns.pm +A lib/pf/services/manager/roles/is_managed_vlan_inline_enforcement.pm + +commit e0252f8b10677db6c994c387b4fdff6021f2e9f9 +Author: James Rouzier +Date: Wed Sep 25 11:17:06 2013 -0400 + + Fixed issue with t/pf.t + +M lib/pf/services/manager/roles/pf_conf_trapping_engine.pm + +commit 0d744e5985e24df0fc2956d23a8f04b63a8fbd02 +Author: James Rouzier +Date: Wed Sep 25 11:15:10 2013 -0400 + + Added missed isManaged + +M lib/pf/services/manager/pfdhcplistener.pm + +commit 01e0c4ae46b19d20c4f0ad22319f6fba21208bf4 +Author: James Rouzier +Date: Wed Sep 25 10:15:43 2013 -0400 + + Remove Minor parts from the COPYRIGHT section + +M lib/pf/services/manager.pm +M lib/pf/services/manager/httpd.pm +M lib/pf/services/manager/httpd_admin.pm +M lib/pf/services/manager/httpd_portal.pm +M lib/pf/services/manager/httpd_webservices.pm +M lib/pf/services/manager/memcached.pm +M lib/pf/services/manager/pfdetect.pm +M lib/pf/services/manager/pfdns.pm +M lib/pf/services/manager/pfmon.pm +M lib/pf/services/manager/pfsetvlan.pm +M lib/pf/services/manager/radiusd.pm +M lib/pf/services/manager/roles/pf_conf_service_managed.pm +M lib/pf/services/manager/snmptrapd.pm +M lib/pf/services/manager/snort.pm +M lib/pf/services/manager/submanager.pm +M lib/pf/services/manager/suricata.pm + +commit e27c1a02d8d3cf5f71d568ece5a72e910f098dd3 +Author: James Rouzier +Date: Tue Sep 24 19:17:59 2013 -0400 + + Use the new pf::services::manager framework for the pfcmd service command + +M bin/pfcmd.pl + +commit 235f2f8cb48dcae0c33af88aaef4813785c3c33e +Author: James Rouzier +Date: Tue Sep 24 19:15:41 2013 -0400 + + Added new files for the services refactor + +A lib/pf/services/manager.pm +A lib/pf/services/manager/dhcpd.pm +A lib/pf/services/manager/httpd.pm +A lib/pf/services/manager/httpd_admin.pm +A lib/pf/services/manager/httpd_portal.pm +A lib/pf/services/manager/httpd_webservices.pm +A lib/pf/services/manager/memcached.pm +A lib/pf/services/manager/pfdetect.pm +A lib/pf/services/manager/pfdhcplistener.pm +A lib/pf/services/manager/pfdns.pm +A lib/pf/services/manager/pfmon.pm +A lib/pf/services/manager/pfsetvlan.pm +A lib/pf/services/manager/radiusd.pm +A lib/pf/services/manager/roles/pf_conf_service_managed.pm +A lib/pf/services/manager/roles/pf_conf_trapping_engine.pm +A lib/pf/services/manager/snmptrapd.pm +A lib/pf/services/manager/snort.pm +A lib/pf/services/manager/submanager.pm +A lib/pf/services/manager/suricata.pm + +commit 0aace286ff06c7eafda1fe046fdfe6acc231e809 +Author: Durand Fabrice +Date: Wed Nov 20 17:08:28 2013 -0500 + + Missing lib + +M lib/pf/SNMP/Cisco/Catalyst_2960.pm + +commit 2c984adff6bb4a0c67c0e6349169c31caa38e64b +Author: Durand Fabrice +Date: Wed Nov 20 13:01:05 2013 -0500 + + Missing $switch param + +M sbin/pfsetvlan + +commit 374f66f8a66035beeca3899485aca06d150e48f8 +Author: Durand Fabrice +Date: Wed Oct 30 11:05:56 2013 -0400 + + Added HP Standalone access point module + +A lib/pf/SNMP/HP/MSM.pm + +commit 690509843c60da78ba86fc9a9c835535f91f83e0 +Author: Durand Fabrice +Date: Tue Oct 15 11:08:27 2013 -0400 + + Added custom radius answer for aruba switch (remove vlan id if we have a role) + +M lib/pf/SNMP/ArubaSwitch.pm + +commit 25f1f5d7e7acd97801afd7e17dcd50cc1f57aa6b +Author: Durand Fabrice +Date: Fri Oct 11 16:49:38 2013 -0400 + + Update doc + Added radius attribute + +M docs/PacketFence_Network_Devices_Configuration_Guide.asciidoc +M lib/pf/radius.pm + +commit 486c29face67376b375270d64f7309cd587ba838 +Author: Durand Fabrice +Date: Fri Oct 11 16:18:15 2013 -0400 + + Added wiredeauthTechniques method like deauthTechniques for the wireless + Added ArubaSwitch switch module (mac auth and 802.1x and CoA support) + Added Dell Force10 switch module + Added CoA deauth support for Cisco Switch + +M lib/pf/SNMP.pm +A lib/pf/SNMP/ArubaSwitch.pm +M lib/pf/SNMP/Brocade.pm +M lib/pf/SNMP/Cisco/Catalyst_2950.pm +M lib/pf/SNMP/Cisco/Catalyst_2960.pm +A lib/pf/SNMP/Dell/Force10.pm +M lib/pf/SNMP/Juniper.pm +M lib/pf/SNMP/MockedSwitch.pm +M lib/pf/SNMP/PacketFence.pm +M lib/pf/SNMP/ThreeCom/Switch_4200G.pm +M lib/pf/enforcement.pm +M sbin/pfsetvlan + +commit 442c6e0c8721f891fa05fcd36d458d73a345871f +Author: Francis Lachapelle +Date: Thu Nov 21 16:40:40 2013 -0500 + + Switch editor: Remove 'disabled' class of Save btn + +M html/pfappserver/root/configuration/switch/view.tt + +commit d50f7b26390a1ded8b18e83b2fab54761acdb509 +Author: Francis Lachapelle +Date: Mon Nov 4 10:01:03 2013 -0500 + + Change type of access_level column + + We no longer use a bit string but simply a string that refers to one or + many roles from conf/adminroles.conf + +M db/upgrade-4.0.0-4.1.0.sql + +commit 9bc26205c6caec3a016d53ab96fb866c30186c91 +Author: Francis Lachapelle +Date: Mon Nov 4 09:52:35 2013 -0500 + + Add access rights to interfaces management + +M html/pfappserver/root/admin/configuration.tt +M html/pfappserver/root/config/networks/view.tt +M html/pfappserver/root/interface/index.tt +M html/pfappserver/root/interface/list.tt +M html/pfappserver/root/interface/view.tt + +commit 11a9f73fc704dec5127476a92bab8ac8e50e476a +Author: James Rouzier +Date: Mon Nov 4 08:14:46 2013 -0500 + + Pass roles as an array ref + +M html/pfappserver/lib/pfappserver/Authentication/Store/PacketFence/User.pm +M html/pfappserver/lib/pfappserver/Base/Action/AdminRole.pm +M html/pfappserver/lib/pfappserver/Controller/Admin.pm +M html/pfappserver/lib/pfappserver/View/HTML.pm + +commit a781bd20645153f6a3dc53bf1e475bd5e09eae6f +Author: Francis Lachapelle +Date: Fri Nov 1 16:31:44 2013 -0400 + + Fix access authorization of actions + +M html/pfappserver/lib/pfappserver/View/HTML.pm + +commit 6f8ebd8f2699dd0bc377071fe40ba7df98f79e9b +Author: James Rouzier +Date: Wed Oct 2 11:05:11 2013 -0400 + + pfappserver::Authentication::Store::PacketFence::User->roles returns an array ref instead of an array + +M html/pfappserver/lib/pfappserver/Authentication/Store/PacketFence/User.pm +M html/pfappserver/lib/pfappserver/Base/Action/AdminRole.pm +M html/pfappserver/lib/pfappserver/Controller/Admin.pm +M html/pfappserver/lib/pfappserver/View/HTML.pm + +commit bab9d0f7c899f8b483374e1f591b10f83a102538 +Author: James Rouzier +Date: Thu Oct 10 16:23:16 2013 -0400 + + Imported module pfappserver::Base::Action::AdminRole + Cleanup unused variable + +M html/pfappserver/lib/pfappserver/Controller/Interface.pm + +commit 3e772bd10922dda2a495a195e700286b496111e9 +Author: Francis Lachapelle +Date: Thu Oct 10 16:09:59 2013 -0400 + + Add access rights to interfaces management + +M html/pfappserver/lib/pfappserver/Controller/Interface.pm + +commit ab27b4c3d04742931483fd843419b6a0adf9fa53 +Author: James Rouzier +Date: Thu Oct 10 16:06:35 2013 -0400 + + Fix debug statement + +M html/pfappserver/lib/pfappserver/Base/Action/AdminRole.pm + +commit 5ed86e9fb55fde9fc182c1fd43d1a6ab0d694108 +Author: James Rouzier +Date: Thu Oct 10 16:02:53 2013 -0400 + + Fixed can_access_any function to expect roles to return an array + +M html/pfappserver/lib/pfappserver/View/HTML.pm + +commit b96244cb526fc72d0d4042f401488ece8f2dfe57 +Author: James Rouzier +Date: Wed Oct 2 11:16:19 2013 -0400 + + Added AdminRoles attribute to Controller + +M html/pfappserver/lib/pfappserver/Controller/Interface.pm + +commit f89bc251cbc91cdee78ce3e23289b17589922aa9 +Author: James Rouzier +Date: Wed Oct 2 11:14:22 2013 -0400 + + refactor to use can_access_any + +M html/pfappserver/root/admin/wrapper.tt + +commit e2307abdbc3079f20cea2c744caf2f76e5b8c80d +Author: James Rouzier +Date: Wed Oct 2 11:13:36 2013 -0400 + + Added new function can_access_any to be exposed to template + +M html/pfappserver/lib/pfappserver/View/HTML.pm + +commit 5241e12041286e73d17be0ef466c044b7eb42c94 +Author: James Rouzier +Date: Wed Oct 2 11:12:38 2013 -0400 + + Added new function pf::admin_roles::admin_can_do_any that would match if any action matches + +M lib/pf/admin_roles.pm + +commit e5ab2f6e8612f7411001036e71710aab72588a0a +Author: James Rouzier +Date: Wed Oct 2 11:10:49 2013 -0400 + + Configurator automatically login the _PF_CONFIGURATOR user + +M html/pfappserver/lib/pfappserver/Controller/Configurator.pm + +commit c8ea16564139c884480b2ca263c014d588aacd39 +Author: James Rouzier +Date: Wed Oct 2 11:00:13 2013 -0400 + + Check if user is in admin realm instead just existence + +M html/pfappserver/lib/pfappserver/Base/Controller.pm +M html/pfappserver/lib/pfappserver/Controller/Admin.pm +M html/pfappserver/lib/pfappserver/Controller/Graph.pm +M html/pfappserver/root/admin/wrapper.tt + +commit b67c42bfe33ef0b62440dfca084098db00388f97 +Author: James Rouzier +Date: Wed Oct 2 10:40:13 2013 -0400 + + Adding a new realm for the configurator + +M html/pfappserver/lib/pfappserver.pm + +commit e4e7284062a39f72bc9fbce3bbcbdad7fb965820 +Author: Francis Lachapelle +Date: Mon Sep 23 14:03:37 2013 -0400 + + Fix typo + +M html/pfappserver/root/configuration/adminroles/list.tt + +commit e21d726982ed7bc9236d160cdf73528d7ce62706 +Author: Francis Lachapelle +Date: Mon Sep 23 11:30:55 2013 -0400 + + Add missing ADMIN_ROLES_CREATE admin role action + +M lib/pf/admin_roles.pm + +commit 6bc7077a6bfadfeec1661361ddf4d253daba026c +Author: James Rouzier +Date: Mon Sep 23 11:13:14 2013 -0400 + + Redo the onfilereload when there is no extra data in the cache + +M lib/pf/admin_roles.pm + +commit fe3a73ffe476697a189ef90120004a05f9539b58 +Author: James Rouzier +Date: Mon Sep 23 00:43:35 2013 -0400 + + Remove the delete link from the single action of a role + +M html/pfappserver/root/static/admin/configuration/adminroles.js + +commit a00fefb5f70fa5681ca24f00fb25ce634d4d1b5b +Author: Francis Lachapelle +Date: Fri Sep 20 14:19:17 2013 -0400 + + Localization + +M html/pfappserver/lib/pfappserver/I18N/en.po + +commit b1d75e6162129a52e77218f564445244a3f0fc77 +Author: Francis Lachapelle +Date: Fri Sep 20 12:46:08 2013 -0400 + + Sort actions when viewing an admin role + +M html/pfappserver/lib/pfappserver/Controller/Configuration/AdminRoles.pm + +commit 7c91ce42c7b4675c8102e2e48dd54468e30db6c3 +Author: Francis Lachapelle +Date: Fri Sep 20 12:44:24 2013 -0400 + + Group admin roles actions in pulldown menus + +M html/pfappserver/lib/pfappserver/Form/Config/AdminRoles.pm + +commit 6c83152fbc7872b7267a9fb0437bec34635f63bd +Author: Francis Lachapelle +Date: Fri Sep 20 09:55:34 2013 -0400 + + Add access rights to MAC addresses management + +M html/pfappserver/lib/pfappserver/Controller/Configuration/MacAddress.pm +M html/pfappserver/root/configuration/macaddress/simple_search.tt + +commit dd664b90e1fde04e4828d83c4c7c72ff18b6587a +Author: Francis Lachapelle +Date: Fri Sep 20 09:54:51 2013 -0400 + + Add access rights to useragents management + +M html/pfappserver/lib/pfappserver/Controller/Configuration/UserAgents.pm + +commit 2033aa97658cf41f4a1825b66c616777fb4122d7 +Author: Francis Lachapelle +Date: Fri Sep 20 09:54:10 2013 -0400 + + Add access rights to fingerprints management + +M html/pfappserver/lib/pfappserver/Controller/Configuration/Fingerprints.pm +M html/pfappserver/root/configuration/fingerprints/simple_search.tt + +commit 4947a262da25b30854f5d33e604a1d92c15952b6 +Author: Francis Lachapelle +Date: Fri Sep 20 09:43:54 2013 -0400 + + Add access rights to SoH filters management + +M html/pfappserver/lib/pfappserver/Controller/SoH.pm +M html/pfappserver/root/soh/index.tt +M html/pfappserver/root/soh/read.tt + +commit 8ba398b14b38ce2e59d314e7adb7e2a6c4e12aa5 +Author: Francis Lachapelle +Date: Fri Sep 20 09:09:15 2013 -0400 + + Add access rights to users sources management + +M html/pfappserver/lib/pfappserver/Controller/Authentication.pm +M html/pfappserver/lib/pfappserver/Controller/Authentication/Source.pm +M html/pfappserver/root/authentication/source/read.tt +M html/pfappserver/root/authentication/source/rule_read.tt +M html/pfappserver/root/authentication/source/rules_read.tt +M html/pfappserver/root/configuration/authentication.tt + +commit 390d23be22e25c273d2581b33457d0e81315b975 +Author: Francis Lachapelle +Date: Fri Sep 20 09:03:25 2013 -0400 + + Add access rights to users roles management + +M html/pfappserver/lib/pfappserver/Controller/Roles.pm +M html/pfappserver/root/roles/index.tt +M html/pfappserver/root/roles/read.tt +M lib/pf/admin_roles.pm + +commit 05cedfb15b92a796175241cf11b65c9f0b706baa +Author: Francis Lachapelle +Date: Fri Sep 20 06:43:36 2013 -0400 + + Add access rights to violations management + +M html/pfappserver/lib/pfappserver/Controller/Violation.pm +M html/pfappserver/root/violation/list.tt +M html/pfappserver/root/violation/view.tt + +commit 866d5da2c02ad18f74ef5c12876b396106d1ad33 +Author: Francis Lachapelle +Date: Thu Sep 19 17:05:31 2013 -0400 + + Add access rights to reports + +M html/pfappserver/lib/pfappserver/Controller/Admin.pm +M html/pfappserver/lib/pfappserver/Controller/Graph.pm + +commit 9dcafcd04f8a7197338d53cb071c89eba9fd27e3 +Author: Francis Lachapelle +Date: Thu Sep 19 16:53:18 2013 -0400 + + Add access rights to main configuration section + +M html/pfappserver/root/configuration/section.tt + +commit 91d0ac7b5a598f36ff59dd45b0a515e09dd9afab +Author: Francis Lachapelle +Date: Thu Sep 19 16:52:15 2013 -0400 + + Add access rights to admin roles management + +M html/pfappserver/lib/pfappserver/Controller/Configuration/AdminRoles.pm +M html/pfappserver/root/configuration/adminroles/index.tt +M html/pfappserver/root/configuration/adminroles/list.tt +M html/pfappserver/root/configuration/adminroles/view.tt + +commit 2aeeb06f633bff4c82588b0e3ec4a6e52f0c5ad4 +Author: Francis Lachapelle +Date: Thu Sep 19 16:40:46 2013 -0400 + + Add access rights to portal profiles management + +M html/pfappserver/lib/pfappserver/Controller/Portal/Profile.pm +M html/pfappserver/lib/pfappserver/Controller/Portal/Profile/Default.pm +M html/pfappserver/root/admin/configuration.tt +M html/pfappserver/root/portal/profile/files.tt +M html/pfappserver/root/portal/profile/index.tt +M html/pfappserver/root/portal/profile/view.tt +M lib/pf/admin_roles.pm + +commit cb6ec06a6e9800363de0e53e108b153f9ebfbd49 +Author: Francis Lachapelle +Date: Thu Sep 19 15:28:16 2013 -0400 + + Add access rights to services + +M html/pfappserver/lib/pfappserver/Controller/Service.pm + +commit d6534fb3a8fd677d9f37f31296e3c1dcdc1d9fb1 +Author: Francis Lachapelle +Date: Thu Sep 19 15:24:48 2013 -0400 + + Add description to page of admin roles + +M html/pfappserver/root/configuration/adminroles/index.tt + +commit d994247fd0bd0b5e64f3c0c158018a651a4b12b1 +Author: Francis Lachapelle +Date: Thu Sep 19 15:24:20 2013 -0400 + + Improve logging of AdminRole action + +M html/pfappserver/lib/pfappserver/Base/Action/AdminRole.pm + +commit 8a4bf7a4e9e6d76df0ae8cd24e1957d86b8dbde9 +Author: Francis Lachapelle +Date: Thu Sep 19 15:14:29 2013 -0400 + + Add access rights to users management + +M html/pfappserver/lib/pfappserver/Controller/User.pm +M html/pfappserver/lib/pfappserver/Model/User.pm +M html/pfappserver/root/user/view.tt +M html/pfappserver/root/user/violations.tt + +commit 69d034fff4f6da5cf50f6dab012cb5b7eafd0cd2 +Author: Francis Lachapelle +Date: Thu Sep 19 14:59:55 2013 -0400 + + Add access rights to switches management + +M html/pfappserver/lib/pfappserver/Controller/Configuration/Switch.pm +M html/pfappserver/root/configuration/switch/index.tt +M html/pfappserver/root/configuration/switch/list.tt +M html/pfappserver/root/configuration/switch/view.tt + +commit f31d2eb13a84dec72798cc19c2ea83f34bc1a14c +Author: Francis Lachapelle +Date: Thu Sep 19 14:58:16 2013 -0400 + + Add access rights to floating devices management + +M html/pfappserver/lib/pfappserver/Controller/Configuration/FloatingDevice.pm +M html/pfappserver/root/configuration/floatingdevice/index.tt +M html/pfappserver/root/configuration/floatingdevice/list.tt +M html/pfappserver/root/configuration/floatingdevice/view.tt + +commit 7faf37c20f8ce811640a61297e35875f73013fc9 +Author: James Rouzier +Date: Wed Sep 18 17:10:01 2013 -0400 + + Added role FLOATING_DEVICES_READ to configuration/floatingdevice/read + +M html/pfappserver/lib/pfappserver/Controller/Configuration/FloatingDevice.pm + +commit 1d4ee33551794a38268def6efce273e9c4a05e7b +Author: James Rouzier +Date: Wed Sep 18 17:04:08 2013 -0400 + + Added role USERS_DELETE to user/delete + +M html/pfappserver/lib/pfappserver/Controller/User.pm + +commit 887aa7bccb3ed445fecd23d6e5a6af81d482db45 +Author: James Rouzier +Date: Wed Sep 18 17:03:14 2013 -0400 + + Added role SWITCHES_READ to configuration/switch/view + +M html/pfappserver/lib/pfappserver/Controller/Configuration/Switch.pm + +commit 52a48855375128ab8712a04ff25ee2c387225bb4 +Author: James Rouzier +Date: Wed Sep 18 17:01:43 2013 -0400 + + Changed SimpleSearch and AdminRole to be a role into of a class + +M html/pfappserver/lib/pfappserver/Base/Action/AdminRole.pm +M html/pfappserver/lib/pfappserver/Base/Action/SimpleSearch.pm +M html/pfappserver/lib/pfappserver/Base/Controller.pm + +commit ee1aeea1b07ef29a9256af0052e16797220d0c69 +Author: Francis Lachapelle +Date: Wed Sep 18 15:45:01 2013 -0400 + + Fix HTML of admin role editor + +M html/pfappserver/root/configuration/adminroles/view.tt + +commit 915f2d434e4a7ddee47e73d8a9d7ee2dcceb5e19 +Author: Francis Lachapelle +Date: Wed Sep 18 15:44:16 2013 -0400 + + Add more access rights "actions" + +M html/pfappserver/root/admin/configuration.tt +M lib/pf/admin_roles.pm + +commit 470f31f33998445e27b1116c6deadcbe518e4e7c +Author: Francis Lachapelle +Date: Wed Sep 18 15:39:00 2013 -0400 + + Add access rights to nodes management + +M html/pfappserver/lib/pfappserver/Controller/Admin.pm +M html/pfappserver/lib/pfappserver/Controller/Node.pm +M html/pfappserver/root/node/view.tt +M html/pfappserver/root/node/violations.tt + +commit fb06354498097e1ebcd8da20e214ebb97807bbd4 +Author: Francis Lachapelle +Date: Wed Sep 18 15:25:01 2013 -0400 + + Add new AdminRole action + + This action is used whenever the AdminRole action parameter is defined + in a controller. + +A html/pfappserver/lib/pfappserver/Base/Action/AdminRole.pm +M html/pfappserver/lib/pfappserver/Base/Controller.pm + +commit 3ddaef13aa482b7c90af95cb1576367e4938e68d +Author: Francis Lachapelle +Date: Fri Sep 6 09:52:38 2013 -0400 + + Fix condition to show configuration section + +M html/pfappserver/root/admin/wrapper.tt + +commit 59503ea4dea927287d25d7e8072ca39f12b002f1 +Author: Durand Fabrice +Date: Fri Aug 30 13:28:27 2013 -0400 + + Fix packaging + +M addons/packages/packetfence.spec +M debian/packetfence.conffiles + +commit 0279654c079a099a06d2cd367427a10d12d33249 +Author: Francis Lachapelle +Date: Tue Aug 13 10:13:11 2013 -0400 + + Fix configuration template wrt admin roles + +M html/pfappserver/root/admin/configuration.tt + +commit 81ac26cb13e4fd4b6d9e4b6d5a6ad904c95ba35c +Author: James Rouzier +Date: Mon Aug 12 18:20:42 2013 -0400 + + Have a default for onhashchange + +M html/pfappserver/root/static/admin/configuration.js + +commit 01c73ab3458b16d0e0867f690203af51dc2523c5 +Author: Francis Lachapelle +Date: Mon Aug 12 16:14:16 2013 -0400 + + Initial integration of access rights in templates + +M conf/adminroles.conf +M html/pfappserver/lib/pfappserver/Base/Form/Authentication/Action.pm +M html/pfappserver/root/admin/configuration.tt +M html/pfappserver/root/admin/status.tt +M html/pfappserver/root/admin/wrapper.tt +M html/pfappserver/root/node/advanced_search.tt +M html/pfappserver/root/node/simple_search.tt +M html/pfappserver/root/static/admin/common.css +M html/pfappserver/root/user/view.tt +M lib/pf/admin_roles.pm + +commit c711db9352e2bf3a2fa45e2f8b292bbfc2f12adb +Author: James Rouzier +Date: Mon Aug 12 15:49:48 2013 -0400 + + Pick the first link in the configuration nav link instead of hard coding it to general + +M html/pfappserver/root/static/admin/configuration.js + +commit 93c3ef983607252ea145fbd223fcd4e573699be4 +Author: James Rouzier +Date: Mon Aug 12 12:30:01 2013 -0400 + + Added upgrade and downgrade scripts for admin roles + +A db/pf-roles-downgrade.sql +A db/pf-roles-upgrade.sql + +commit dc38ab96966cf2f3e51c4390da3f233b44e4fd05 +Author: Francis Lachapelle +Date: Fri Aug 9 11:01:49 2013 -0400 + + Improve admin role editor + +M html/pfappserver/lib/pfappserver/Form/Config/AdminRoles.pm +M html/pfappserver/root/configuration/adminroles/view.tt + +commit e90122767d8433795a4681c24148495366e4e8c7 +Author: Francis Lachapelle +Date: Fri Aug 9 10:53:33 2013 -0400 + + Admin roles: return list when creating/updating + + When successfully creating or updating a role, we return the list of all + the roles to avoid an additional AJAX query. + +M html/pfappserver/lib/pfappserver/Controller/Configuration/AdminRoles.pm + +commit edbcbd9f120a2d6cd1755785250de66d2ca59cbb +Author: Francis Lachapelle +Date: Fri Aug 9 10:52:43 2013 -0400 + + Improve syntax + +M html/pfappserver/lib/pfappserver/Authentication/Store/PacketFence/User.pm +M html/pfappserver/lib/pfappserver/Controller/Configuration/AdminRoles.pm +M html/pfappserver/lib/pfappserver/Form/Config/AdminRoles.pm +M lib/pf/ConfigStore/AdminRoles.pm +M lib/pf/admin_roles.pm + +commit fd622eb4f72dc5be892a9eb600c9b1d92ece9387 +Author: Francis Lachapelle +Date: Fri Aug 9 10:49:50 2013 -0400 + + Improve JS and templates of admin roles + +M html/pfappserver/root/admin/configuration.tt +M html/pfappserver/root/configuration/adminroles/index.tt +M html/pfappserver/root/configuration/adminroles/list.tt +M html/pfappserver/root/static/admin/configuration/adminroles.js + +commit c55ea16a80d1a94fbc3854b050a978163db704d1 +Author: James Rouzier +Date: Thu Aug 8 14:05:16 2013 -0400 + + Fixed bug with NONE role not being check first Also allow multiple actions to be passed + +M lib/pf/admin_roles.pm + +commit cab7206f9f72dbcea8e6fead27c45830bfcdc3d0 +Author: James Rouzier +Date: Thu Aug 8 13:55:26 2013 -0400 + + changed access_level to a string + +M lib/pf/Authentication/Source/SQLSource.pm + +commit 6f59e592731952aa9ebfb7e507ba4f60dbb4f458 +Author: James Rouzier +Date: Thu Aug 8 13:53:43 2013 -0400 + + saving user roles to the session + +M html/pfappserver/lib/pfappserver/Controller/Admin.pm + +commit d7e2499ae18256d0877ba6a5ca1b4c548a95d160 +Author: James Rouzier +Date: Thu Aug 8 13:37:05 2013 -0400 + + Added _roles attribute and ensure that uses with the role of NONE are not allowed to check in + +M html/pfappserver/lib/pfappserver/Authentication/Store/PacketFence/User.pm + +commit c924098df6e407f81b950138af5dd33f6c1da004 +Author: James Rouzier +Date: Thu Aug 8 13:35:27 2013 -0400 + + retrived user roles from the session + +M html/pfappserver/lib/pfappserver/Authentication/Store/PacketFence.pm + +commit 0f7cd8b1675ec199d5f62d14c20865ef6df09b37 +Author: James Rouzier +Date: Thu Aug 8 13:33:59 2013 -0400 + + Verify if the user exists before retrivng roles + +M html/pfappserver/lib/pfappserver/View/HTML.pm + +commit 48efc3a27a4cbd91ce9fe87d439bfd7d17f69426 +Author: James Rouzier +Date: Thu Aug 8 13:30:43 2013 -0400 + + If action type allow mulitple values then convert the value to an array + +M html/pfappserver/root/static/admin/common.js + +commit 7800b3e505b55fa7ec65e558aa0588f1243174a4 +Author: James Rouzier +Date: Thu Aug 8 13:29:49 2013 -0400 + + Changed the name of the action to match the actions defined in pf::admin_roles + +M html/pfappserver/root/admin/wrapper.tt + +commit 5ada47aafbce43887f1403e3439ea7b7eacd10a8 +Author: James Rouzier +Date: Thu Aug 8 13:28:38 2013 -0400 + + Added the ability to choose multiple roles and pull roles from ADMIN ROLES + +M html/pfappserver/lib/pfappserver/Base/Form/Authentication/Action.pm + +commit 43e436e50bfb56e34010b564bd55b4e323b07227 +Author: James Rouzier +Date: Tue Aug 6 13:36:36 2013 -0400 + + function admin_can will always fail if has role of NONE + +M lib/pf/admin_roles.pm + +commit a965792866bc69241e9215f4270d188f32e0b448 +Author: James Rouzier +Date: Tue Aug 6 12:26:44 2013 -0400 + + default role is ALL + +M html/pfappserver/lib/pfappserver/Authentication/Store/PacketFence/User.pm + +commit 63bfc16a2143766b9988b3ab7ffaa5f6b1fb80fa +Author: James Rouzier +Date: Tue Aug 6 12:25:57 2013 -0400 + + Will use the roles from the defined user + +M html/pfappserver/lib/pfappserver/View/HTML.pm + +commit a310c50acfac5bf886a3dc7b1c1d39deef6125b8 +Author: James Rouzier +Date: Tue Aug 6 12:24:21 2013 -0400 + + Refactor + use the cached config from pf::admin_roles + +M lib/pf/ConfigStore/AdminRoles.pm + +commit 3a5be424b593ce9ddc8caafb89ecdcc1c53d5de8 +Author: James Rouzier +Date: Tue Aug 6 12:22:52 2013 -0400 + + implemented admin_can + Added hard coded roles NONE and ALL + move the load of the adminroles.conf to here + +M lib/pf/admin_roles.pm + +commit 0ac61d60cf3988ae7b386d00a3fceb2c64d3351b +Author: James Rouzier +Date: Tue Aug 6 12:21:16 2013 -0400 + + Added Description for admin role + +M html/pfappserver/lib/pfappserver/Form/Config/AdminRoles.pm +M html/pfappserver/root/configuration/adminroles/list.tt + +commit 1ac91c1006e2e3f66236e2a66e1642e830f6db75 +Author: James Rouzier +Date: Tue Aug 6 10:10:31 2013 -0400 + + renamed administration function + +M html/pfappserver/lib/pfappserver/View/HTML.pm + +commit ba8eb4c38c387bbefc04767492fae32e07210e71 +Author: James Rouzier +Date: Tue Aug 6 10:08:53 2013 -0400 + + New configuartion controller for adminroles + +A conf/admin_roles.conf +A conf/adminroles.conf +A html/pfappserver/lib/pfappserver/Controller/Configuration/AdminRoles.pm +M html/pfappserver/lib/pfappserver/Controller/User.pm +A html/pfappserver/lib/pfappserver/Form/Config/AdminRoles.pm +A html/pfappserver/lib/pfappserver/Model/Config/AdminRoles.pm +M html/pfappserver/root/admin/configuration.tt +A html/pfappserver/root/configuration/adminroles/index.tt +A html/pfappserver/root/configuration/adminroles/list.tt +A html/pfappserver/root/configuration/adminroles/view.tt +A html/pfappserver/root/static/admin/configuration/adminroles.js +A lib/pf/ConfigStore/AdminRoles.pm +M lib/pf/admin_roles.pm +M lib/pf/file_paths.pm + +commit 12fea5e471bc08b30681e06ea823573c12e75a42 +Author: James Rouzier +Date: Mon Aug 5 18:24:42 2013 -0400 + + renamed pf::user_roles to pf::admin_roles + +M html/pfappserver/lib/pfappserver/View/HTML.pm +A lib/pf/admin_roles.pm +D lib/pf/user_roles.pm + +commit 9bb1c8a11f19e27bc58d928fb64cd15f40aa6958 +Author: James Rouzier +Date: Wed Jul 31 22:49:02 2013 -0400 + + Example restriction for user role + +M html/pfappserver/lib/pfappserver/Controller/User.pm +M html/pfappserver/root/admin/wrapper.tt + +commit d4049b499df21c79c32cc662580dbd5f90209104 +Author: James Rouzier +Date: Wed Jul 31 22:00:27 2013 -0400 + + Add new module pf::user and exposed_method has_role to templates + +M html/pfappserver/lib/pfappserver/View/HTML.pm +A lib/pf/user_roles.pm + +commit 04906e4f793da80f59ee45af0cd98efad99b683e +Author: Francis Lachapelle +Date: Fri Nov 22 16:10:03 2013 -0500 + + Improve Administration Guide + +M docs/PacketFence_Administration_Guide.asciidoc + +commit 852a2a5f14010b8fcfb2f687e728dd19443ef777 +Author: Francis Lachapelle +Date: Fri Nov 22 15:49:36 2013 -0500 + + Remove useless call to get_abbr_time + +M html/pfappserver/lib/pfappserver/Base/Form/Authentication/Action.pm +M html/pfappserver/lib/pfappserver/Form/Field/Duration.pm +M html/pfappserver/lib/pfappserver/Form/User.pm + +commit 0400cc762fd1d981bbb6b0df8e8c620c74eb8b3a +Author: Francis Lachapelle +Date: Mon Nov 18 13:58:29 2013 -0500 + + Fix argument to pf::authentication::match + +M html/captive-portal/email_activation.cgi + +commit 36dd0b14c424d7d08d855f275e464f28662ef63e +Author: Francis Lachapelle +Date: Mon Nov 18 11:50:11 2013 -0500 + + Update NEWS and admin guide for extended duration + +M NEWS.asciidoc +M docs/PacketFence_Administration_Guide.asciidoc + +commit efe35c882de938c978358ebc4cad9a0244f4c5fa +Author: Francis Lachapelle +Date: Fri Nov 1 14:33:31 2013 -0400 + + Set default_access_duration as an extended_time + +M conf/documentation.conf +M html/pfappserver/lib/pfappserver/Form/Config/Pf.pm +M html/pfappserver/root/static/admin/common.js + +commit 37538797417d396b86a152d701b3c174d6ba1a6c +Author: Francis Lachapelle +Date: Fri Nov 1 14:30:30 2013 -0400 + + Improve formatting of extended duration + +M lib/pf/web/util.pm + +commit 7f1d9b279ce8fb0e081c02bdfbd04d4600f3e5af +Author: Francis Lachapelle +Date: Fri Nov 1 11:14:27 2013 -0400 + + New ExtendedDuration field and widget + +A html/pfappserver/lib/pfappserver/Form/Field/ExtendedDuration.pm +A html/pfappserver/lib/pfappserver/Form/Widget/Field/ExtendedDuration.pm +M html/pfappserver/root/static/admin/common.css +M lib/pf/config.pm +M lib/pf/util.pm + +commit 874d093d380d1ae54b1abee82a2ae74ad2460ba1 +Author: Francis Lachapelle +Date: Fri Nov 1 11:02:55 2013 -0400 + + Support hours/minutes/seconds in relative duration + +M lib/pf/config.pm + +commit 698b8380efe368125107eb3c3ce703f32a8bce10 +Author: Francis Lachapelle +Date: Fri Nov 1 10:59:54 2013 -0400 + + application.js: trigger change event on btn groups + +M html/pfappserver/root/static/app/application.js + +commit d8c036df50b614fdc5ecc7254ce741fa05215688 +Author: Francis Lachapelle +Date: Fri Nov 1 10:10:09 2013 -0400 + + C::Configuration: action to compute duration + +M html/pfappserver/lib/pfappserver/Controller/Configuration.pm + +commit a4864c864a43daf43c69d5f9d991eb2b1fa53023 +Author: Francis Lachapelle +Date: Fri Nov 1 10:05:34 2013 -0400 + + Support 'disabled' attribute in ButtonGroup + +M html/pfappserver/lib/pfappserver/Form/Widget/Field/ButtonGroup.pm + +commit 8fd328beef3be8fe1274bc42d019503147e56660 +Author: Francis Lachapelle +Date: Fri Nov 1 09:46:51 2013 -0400 + + Improve Form::Field::Duration + + Added attributes "with_operator" (show a select input with 'add' and + 'subtract' options) and "with_time" (optionally hide time units). + + Also added support to disable the entire widget. + +M html/pfappserver/lib/pfappserver/Form/Field/Duration.pm + +commit be449f2418b3b045952ad4bfc14ceaffa3532ade +Author: Francis Lachapelle +Date: Fri Nov 1 09:33:36 2013 -0400 + + Improve update of compound fields in Base::Form + +M html/pfappserver/lib/pfappserver/Base/Form.pm + +commit 55fea9b0d3bb112f9ab40228116ac6d91a095999 +Author: Francis Lachapelle +Date: Fri Nov 1 09:22:17 2013 -0400 + + Improve pf::web::util::get_translated_time_hash + +M html/pfappserver/lib/pfappserver/Base/Form/Authentication/Action.pm +M lib/pf/web/util.pm + +commit 4b0b1fb9b5856dac358a9e8fe532731e1c151c0f +Author: Francis Lachapelle +Date: Wed Oct 23 10:40:33 2013 -0400 + + Tests for pf::config::access_duration + +M t/config.t + +commit 34525526dba5651ca7d453ce84500086c8642bf6 +Author: Francis Lachapelle +Date: Wed Oct 23 10:34:08 2013 -0400 + + Fix calculation of duration for months and years + +M lib/pf/config.pm + +commit 266944d6d2a80fe0b5d4b5187cd93d97949471d7 +Author: Francis Lachapelle +Date: Tue Oct 22 16:10:05 2013 -0400 + + Handle advanced deadline in self-registration CGI + +M html/captive-portal/guest-selfregistration.cgi + +commit 96cbf1c70ced9aaa03956a279fecf67962f61989 +Author: Francis Lachapelle +Date: Tue Oct 22 14:00:50 2013 -0400 + + Fix oauth2.cgi + +M html/captive-portal/oauth2.cgi + +commit 21315589058765053e4110609792ac8188d62b1b +Author: Durand Fabrice +Date: Thu Jun 6 10:13:34 2013 -0400 + + Rewrite feature for packetfence 4, missing admin gui stuff + +M html/captive-portal/email_activation.cgi +M html/captive-portal/mobile-confirmation.cgi +M html/captive-portal/oauth2.cgi +M html/captive-portal/register.cgi +M lib/pf/config.pm +M lib/pf/web/wispr.pm + +commit 30256fb88720e15cd9af48677e076e49d7501a94 +Author: Francis Lachapelle +Date: Thu Nov 28 13:23:11 2013 -0500 + + Comments cleanup + +M sbin/pfdns + +commit ba78b0612112ffded5e70a8319a1ab4424f4665f +Author: Francis Lachapelle +Date: Thu Nov 28 12:39:09 2013 -0500 + + Allow actions depending on auth source type + +M NEWS.asciidoc +M html/pfappserver/lib/pfappserver/Base/Form/Authentication/Action.pm +M html/pfappserver/lib/pfappserver/Form/Authentication/Rule.pm +M html/pfappserver/root/authentication/source/rule_read.tt +M lib/pf/Authentication/Source/EmailSource.pm +M lib/pf/Authentication/Source/NullSource.pm +M lib/pf/Authentication/Source/SMSSource.pm +M lib/pf/Authentication/Source/SponsorEmailSource.pm + +commit 7b4a3a2b038d6211dfcf61033e9e08521946b412 +Author: Francis Lachapelle +Date: Thu Nov 28 09:52:49 2013 -0500 + + Improved validation of a sponsor's email address + + When validating a sponsor's email address, we used to only check the + first source that returns a username for the specified email address, + which would cause a problem when the email address was found in multiple + sources but the 'mark as sponsor' action was set only for one the + sources. With this commit, we let each source's "match" implementation + handles the possibility that an email address is specified instead of a + username. + +M NEWS.asciidoc +M lib/pf/Authentication/Source/HtpasswdSource.pm +M lib/pf/Authentication/Source/LDAPSource.pm +M lib/pf/Authentication/Source/SQLSource.pm +M lib/pf/authentication.pm +M lib/pf/temporary_password.pm +M lib/pf/web/guest.pm + +commit ae01ddd8a3013b90398038bb68c3b56352ccbd32 +Author: James Rouzier +Date: Wed Nov 27 10:27:08 2013 -0500 + + Added support for Date.now() for older browsers + +M html/common/pf.js + +commit 773559e7e82670f80798eec8841a5d6ce55ab106 +Author: James Rouzier +Date: Thu Oct 17 14:17:06 2013 -0400 + + Hardcoded the retry_delay + +M html/common/pf.js + +commit beabb866eccd90fe7c12c4701a7d74329003d7c0 +Author: James Rouzier +Date: Wed Jul 17 10:51:07 2013 -0400 + + Added additional event handler for dealing with the onload event not firing for some browsers + +M html/common/pf.js + +commit 29c9bcddfe7abeed15c403049a85e4cddff5bcf6 +Author: Francis Lachapelle +Date: Tue Nov 26 15:41:33 2013 -0500 + + Fix advanced search by node category + +M NEWS.asciidoc +M html/pfappserver/lib/pfappserver/Model/Node.pm +M html/pfappserver/root/admin/nodes.tt +M lib/pf/node.pm + +commit 339a17c0de1af5b8b9537d27878a7846e6adf11a +Author: Durand Fabrice +Date: Tue Nov 26 11:16:08 2013 -0500 + + Missing comma + +M lib/pf/vlan.pm + +commit acdbb803ba8f592dc45397cdecb5de1010192762 +Author: Durand Fabrice +Date: Tue Nov 26 10:44:27 2013 -0500 + + Unreg a node if it try to connect to a open SSID and was autoregistered on a secure ssid + +M lib/pf/vlan.pm + +commit fb9bd620c61997e561d6e345a4b4e8b36ccf490c +Author: Durand Fabrice +Date: Wed Nov 20 16:37:40 2013 -0500 + + Fixed WARNING - invalid parameter with profile + +M lib/pf/pfcmd/checkup.pm + +commit 9f0e78831878a85c8ec35aaedc0246f05f3cc8bb +Author: Durand Fabrice +Date: Wed Nov 20 13:02:10 2013 -0500 + + Remove duplicate entry + +M conf/documentation.conf + +commit 25781a0d142722ceef7403b83f2e90db3f388487 +Author: Francis Lachapelle +Date: Mon Nov 18 10:18:28 2013 -0500 + + Initialize JS widgets that are not visible + + This is required for multi-values chosen select widget. + +M html/pfappserver/root/static/admin/common.js +M html/pfappserver/root/static/js/user.js + +commit a29ba04aac2b642e09df1a475a4333fe272a3846 +Author: Francis Lachapelle +Date: Thu Nov 14 14:29:18 2013 -0500 + + Fix checkboxes of displayed columns (nodes/users) + +M html/pfappserver/root/node/create.tt +M html/pfappserver/root/node/simple_search.tt +M html/pfappserver/root/static/js/node.js +M html/pfappserver/root/static/js/user.js +M html/pfappserver/root/user/create.tt + +commit 76a0166260ce1788ab9720a5856bf01dfa9dcc0c +Author: Francis Lachapelle +Date: Thu Nov 14 14:15:53 2013 -0500 + + Validate file path when saving an Htpasswd source + +M NEWS.asciidoc +M html/pfappserver/lib/pfappserver/Form/Authentication/Source/Htpasswd.pm + +commit 7e609d080c19b4c3c9835b3c6dc34ee54d2b9a14 +Author: Francis Lachapelle +Date: Thu Nov 14 13:59:40 2013 -0500 + + Fix duplicate entries in advanced search of nodes + +M NEWS.asciidoc +M html/pfappserver/lib/pfappserver/Model/Search/Node.pm + +commit de27c133546ffdd10d2090380d6e4aca42761ca7 +Author: Francis Lachapelle +Date: Wed Nov 13 16:14:33 2013 -0500 + + Localization + +M html/pfappserver/lib/pfappserver/I18N/en.po +M html/pfappserver/root/user/list_password.tt +M html/pfappserver/root/user/view.tt + +commit d1dbad37f53a74177f34e72fba4dc4e6cd0d5982 +Author: Francis Lachapelle +Date: Wed Nov 13 16:10:54 2013 -0500 + + LDAP source: filter by group membership + +M NEWS.asciidoc +M html/pfappserver/lib/pfappserver/Form/Authentication/Rule.pm +M lib/pf/Authentication/Source/LDAPSource.pm +M lib/pf/Authentication/constants.pm + +commit 5d63ea12f5fc010bfa2f1ae76f732bcbf56bf355 +Author: Francis Lachapelle +Date: Tue Nov 12 16:25:40 2013 -0500 + + Users CSV importation: use only checked columns + +M html/pfappserver/lib/pfappserver/Model/User.pm + +commit dca5224926175b845cef9b0571382f35acb26571 +Author: Francis Lachapelle +Date: Tue Nov 12 16:24:53 2013 -0500 + + Create a node or import nodes from a CSV file + +M NEWS.asciidoc +M html/pfappserver/lib/pfappserver/Controller/Node.pm +M html/pfappserver/lib/pfappserver/Form/Node.pm +A html/pfappserver/lib/pfappserver/Form/Node/Create/Import.pm +M html/pfappserver/lib/pfappserver/Model/Node.pm +M html/pfappserver/root/admin/nodes.tt +A html/pfappserver/root/node/create.tt +M html/pfappserver/root/static/admin/common.js +M html/pfappserver/root/static/js/node.js +M html/pfappserver/root/user/create.tt +M lib/pf/node.pm + +commit dc3d9971f4d3065ea4434a7dc2e982de0300d1cd +Author: Francis Lachapelle +Date: Tue Nov 12 09:41:00 2013 -0500 + + Move users creation to users page + + Users creation was previously accessible from the configuration page. + +M NEWS.asciidoc +M html/pfappserver/lib/pfappserver/Controller/User.pm +M html/pfappserver/root/admin/configuration.tt +M html/pfappserver/root/admin/users.tt +D html/pfappserver/root/configuration/users.tt +M html/pfappserver/root/static/admin/configuration.js +M html/pfappserver/root/static/admin/configuration/authentication.js +D html/pfappserver/root/static/admin/configuration/users.js +M html/pfappserver/root/static/js/user.js +A html/pfappserver/root/user/create.tt +M html/pfappserver/root/user/view.tt + +commit bb2d386107c3db133e2a35490b437cef4f3124a9 +Author: Francis Lachapelle +Date: Fri Nov 8 13:43:35 2013 -0500 + + Highlight corresponding rows of pie chart segments + +M NEWS.asciidoc +M html/pfappserver/root/graph/pie.tt +M html/pfappserver/root/static/admin/common.css +M html/pfappserver/root/static/app/application.js +M html/pfappserver/root/static/app/graphs.js + +commit 1ca425d43814401d459cf7d817b97add246d02c8 +Author: Francis Lachapelle +Date: Fri Nov 8 12:03:38 2013 -0500 + + Limit pie charts to 10 lengend labels + +M html/pfappserver/root/static/app/graphs.js + +commit 32b5e9281d9c99468e28a2131e1f500f20a310af +Author: Francis Lachapelle +Date: Tue Nov 5 15:30:00 2013 -0500 + + Fix self-reg of multiple unverified devices + +M NEWS.asciidoc +M conf/templates/emails-guest_sponsor_preregistration.txt.tt +M html/captive-portal/email_activation.cgi +M lib/pf/email_activation.pm + +commit a93c41a42a034703e2cd39d724e3c9744c77afc6 +Author: Francis Lachapelle +Date: Mon Nov 4 16:24:23 2013 -0500 + + Improve saved search on users page + +M NEWS.asciidoc +M html/pfappserver/lib/pfappserver/Controller/Admin.pm +M html/pfappserver/lib/pfappserver/Controller/SavedSearch/Node.pm +M html/pfappserver/lib/pfappserver/Controller/SavedSearch/User.pm +M html/pfappserver/lib/pfappserver/Form/SavedSearch.pm +M html/pfappserver/lib/pfappserver/Model/SavedSearch/Node.pm +M html/pfappserver/lib/pfappserver/Model/SavedSearch/User.pm +M html/pfappserver/root/admin/users.tt +M html/pfappserver/root/static/admin/searches.js +M html/pfappserver/root/static/js/user.js +M lib/pf/savedsearch.pm + +commit f5424f979ab0d5b21ab451a62549b19fa5d2d89b +Author: James Rouzier +Date: Tue Nov 5 13:36:55 2013 -0500 + + Code cleanup + +M html/captive-portal/templates/login.html + +commit 8fc21fff21379d44a657078fc7833fa26a7db79a +Author: James Rouzier +Date: Tue Nov 5 10:41:50 2013 -0500 + + Added compression to chi for memcached + +M conf/chi.conf + +commit ac220c8bb9a2602c5d1d47f5c8a08701ead4d290 +Author: Francis Lachapelle +Date: Mon Nov 4 13:20:50 2013 -0500 + + Cleanup Form::User + +M html/pfappserver/lib/pfappserver/Form/User.pm + +commit 7daf8f821bb9a3b30f626475ff80e8086e799a5b +Author: Francis Lachapelle +Date: Tue Oct 29 15:19:16 2013 -0400 + + Allow Htpasswd sources to validatate sponsors + + A sponsor is validated by her/his email address and consequently, the + authentication source must implement the method "username_from_email". + +M NEWS.asciidoc +M lib/pf/Authentication/Source/HtpasswdSource.pm +M lib/pf/authentication.pm +M lib/pf/file_paths.pm +M t/authentication.t +A t/data/htpasswd.conf + +commit 76f0cb6f75788ebc98e655ff5e1e14717ffab5a8 +Author: Francis Lachapelle +Date: Thu Oct 24 16:25:03 2013 -0400 + + Fix display of profiles table + +M html/pfappserver/root/portal/profile/index.tt + +commit c8cbf13d89ee33240505cad2052d67d8ffb12357 +Author: James Rouzier +Date: Tue Oct 29 11:52:03 2013 -0400 + + Fix indent + +M packetfence.init + +commit 73d79d59eea1d33a7b252ae5b6d06c6cd59e42ff +Author: James Rouzier +Date: Fri Oct 25 18:15:08 2013 -0400 + + Flush ipset before starting packetfence + +M packetfence.init + +commit 523f11a7f9372740e521564f1e01b933df7a42f7 +Author: Durand Fabrice +Date: Thu Oct 24 19:46:16 2013 -0400 + + Fix wispr authentication (http://www.packetfence.org/bugs/view.php?id=1742) + +M lib/pf/web.pm +M lib/pf/web/wispr.pm + +commit fe813adc469088bc524fe5a29b5d429ed4fe1b33 +Author: James Rouzier +Date: Thu Oct 24 16:28:21 2013 -0400 + + Changed log level from error to debug + +M lib/pf/util.pm + +commit 0c169d02477558768ce2ab602a2a11ee081416fa +Author: Francis Lachapelle +Date: Mon Oct 21 14:05:23 2013 -0400 + + Set the redirect URL per portal profile + +M NEWS.asciidoc +M UPGRADE.asciidoc +M conf/documentation.conf +M conf/pf.conf.defaults +M conf/profiles.conf +M html/captive-portal/email_activation.cgi +M html/captive-portal/mobile-confirmation.cgi +M html/captive-portal/oauth2.cgi +M html/pfappserver/lib/pfappserver/Controller/Portal/Profile/Default.pm +M html/pfappserver/lib/pfappserver/Form/Portal/Common.pm +M html/pfappserver/lib/pfappserver/Form/Portal/Profile.pm +M html/pfappserver/lib/pfappserver/Form/Portal/Profile/Default.pm +M lib/pf/Portal/Profile.pm +M lib/pf/Portal/ProfileFactory.pm +M lib/pf/Portal/Session.pm +M lib/pf/web.pm + +commit 4ae1972167eefd7fbe0a2a9bceeb5791586101fd +Author: Loick Pelet +Date: Mon Oct 21 09:53:45 2013 -0400 + + modified way to chgrp for centos + +M docs/PacketFence_Administration_Guide.asciidoc + +commit fdd8bb79d3b3915dbb201ea7392b31847210b374 +Author: Francis Lachapelle +Date: Mon Oct 21 09:19:36 2013 -0400 + + Syntax cleanup + +M html/pfappserver/lib/pfappserver/Base/Model/Search.pm +M html/pfappserver/root/static/admin/searches.js + +commit 763b62c84dcfdf0a4c83fd141d5d95aba3612888 +Author: Francis Lachapelle +Date: Mon Oct 21 09:17:17 2013 -0400 + + Removed useless logging entries + +M html/captive-portal/guest-selfregistration.cgi +M html/captive-portal/register-gaming-device.cgi +M html/captive-portal/register.cgi + +commit 6b1e6417c634ce993507e306fc0efb54f089a8e9 +Author: Francis Lachapelle +Date: Fri Oct 18 16:48:11 2013 -0400 + + Allow nodes columns to be customizable + +M NEWS.asciidoc +M html/pfappserver/lib/pfappserver/Base/Action/SimpleSearch.pm +M html/pfappserver/lib/pfappserver/Base/Controller.pm +M html/pfappserver/lib/pfappserver/Controller/Node.pm +M html/pfappserver/lib/pfappserver/Model/Node.pm +M html/pfappserver/lib/pfappserver/Model/Search/Node.pm +M html/pfappserver/root/node/advanced_search.tt +M html/pfappserver/root/node/simple_search.tt +M html/pfappserver/root/static/admin/nodes.js +M html/pfappserver/root/static/app/application.js +M html/pfappserver/root/static/js/node.js +M lib/pf/node.pm + +commit 82003f61c6937613a061823481206dc98d1f673c +Author: Francis Lachapelle +Date: Fri Oct 18 15:42:59 2013 -0400 + + Update FontAwesome to version 3.2.1 + +M NEWS.asciidoc +M html/pfappserver/root/static/css/bootstrap.css +M html/pfappserver/root/static/css/bootstrap.min.css +M html/pfappserver/root/static/font/fontawesome-webfont.eot +M html/pfappserver/root/static/font/fontawesome-webfont.svg +M html/pfappserver/root/static/font/fontawesome-webfont.ttf +M html/pfappserver/root/static/font/fontawesome-webfont.woff + +commit 16e2aaae6089d8c1241927eb54d4ca61378e4a8b +Author: Francis Lachapelle +Date: Fri Oct 18 14:34:55 2013 -0400 + + Check mode parameter first in register.cgi + + The new Null authentication source needs to be considered only if no + 'mode' parameter is specified. + +M html/captive-portal/register.cgi + +commit 5ddb92d1cce25fc3b43c8f46644aa300532afca2 +Author: Francis Lachapelle +Date: Fri Oct 18 12:04:14 2013 -0400 + + Can't sort by phone nor nodes count + + Fixed sort by phone number and nodes count when performing an advanced + search on users. + Fixes #1738 + +M NEWS.asciidoc +M html/pfappserver/lib/pfappserver/Model/Search/User.pm +M html/pfappserver/lib/pfappserver/Model/User.pm +M html/pfappserver/root/user/advanced_search.tt + +commit d98d58a3591d0781c4ee83c345e02f151cf36935 +Author: Francis Lachapelle +Date: Fri Oct 18 11:37:33 2013 -0400 + + Improve error message when sending a mail + +M lib/pf/email_activation.pm +M lib/pf/sms_activation.pm + +commit 6b47384c3f273f96cabf8a8f7c78db35f03ee444 +Author: Francis Lachapelle +Date: Fri Oct 18 11:17:37 2013 -0400 + + LDAP regexp condition doesn't consider all values + + Also improved debugging output. + +M NEWS.asciidoc +M lib/pf/Authentication/Source/LDAPSource.pm +M lib/pf/authentication.pm + +commit b9393cf4b5515ff0ae70b9763012eb6d08142d3f +Author: Francis Lachapelle +Date: Fri Oct 18 07:27:42 2013 -0400 + + Wrap AUP checkbox with a