From bc332b7a18480a7c8db34ba45bd9ecfc257eaf75 Mon Sep 17 00:00:00 2001 From: Matteo Pasotti Date: Sun, 4 Jan 2015 21:04:20 +0100 Subject: added basic modules for firewall configuration (still not working) --- lib/AdminPanel/Module/Firewall.pm | 461 ++++++++++++++++++++++++++++++++++++++ lib/AdminPanel/Shared/Firewall.pm | 37 +++ 2 files changed, 498 insertions(+) create mode 100644 lib/AdminPanel/Module/Firewall.pm create mode 100644 lib/AdminPanel/Shared/Firewall.pm diff --git a/lib/AdminPanel/Module/Firewall.pm b/lib/AdminPanel/Module/Firewall.pm new file mode 100644 index 0000000..94613c0 --- /dev/null +++ b/lib/AdminPanel/Module/Firewall.pm @@ -0,0 +1,461 @@ +# vim: set et ts=4 sw=4: +#***************************************************************************** +# +# Copyright (c) 2013-2015 Matteo Pasotti +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2, as +# published by the Free Software Foundation. +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +#***************************************************************************** + +package AdminPanel::Module::Firewall; + +use Modern::Perl '2011'; +use autodie; +use Moose; +use utf8; + +use yui; +use AdminPanel::Shared qw(trim); +use AdminPanel::Shared::GUI; +use AdminPanel::Shared::Firewall; + +extends qw( AdminPanel::Module ); + +has '+icon' => ( + default => "/usr/share/mcc/themes/default/firewall-mdk.png", +); + +has '+name' => ( + default => "Firewall Manager", +); + +=head1 VERSION + +Version 1.0.0 + +=cut + +our $VERSION = '1.0.0'; + +has 'dialog' => ( + is => 'rw', + init_arg => undef +); + +has 'sh_gui' => ( + is => 'rw', + init_arg => undef, + builder => '_SharedUGUIInitialize' +); + +has 'loc' => ( + is => 'rw', + init_arg => undef, + builder => '_localeInitialize', + required => 1, +); + +has 'all_servers' => ( + is => 'rw', + init_arg => undef, + isa => 'ArrayRef', +); + +sub _localeInitialize { + my $self = shift(); + + # TODO fix domain binding for translation + $self->loc(AdminPanel::Shared::Locales->new(domain_name => 'drakx-net') ); + # TODO if we want to give the opportunity to test locally add dir_name => 'path' +} + +sub _SharedUGUIInitialize { + my $self = shift(); + + $self->sh_gui(AdminPanel::Shared::GUI->new() ); +} + +sub _initAllServers { + my $self = shift(); + my @all_servers = ( + { + name => $self->loc->N("Web Server"), + pkg => 'apache apache-mod_perl boa lighttpd thttpd', + ports => '80/tcp 443/tcp', + }, + { + name => $self->loc->N("Domain Name Server"), + pkg => 'bind dnsmasq mydsn', + ports => '53/tcp 53/udp', + }, + { + name => $self->loc->N("SSH server"), + pkg => 'openssh-server', + ports => '22/tcp', + }, + { + name => $self->loc->N("FTP server"), + pkg => 'ftp-server-krb5 wu-ftpd proftpd pure-ftpd', + ports => '20/tcp 21/tcp', + }, + { + name => $self->loc->N("DHCP Server"), + pkg => 'dhcp-server udhcpd', + ports => '67/udp 68/udp', + hide => 1, + }, + { + name => $self->loc->N("Mail Server"), + pkg => 'sendmail postfix qmail exim', + ports => '25/tcp 465/tcp 587/tcp', + }, + { + name => $self->loc->N("POP and IMAP Server"), + pkg => 'imap courier-imap-pop', + ports => '109/tcp 110/tcp 143/tcp 993/tcp 995/tcp', + }, + { + name => $self->loc->N("Telnet server"), + pkg => 'telnet-server-krb5', + ports => '23/tcp', + hide => 1, + }, + { + name => $self->loc->N("NFS Server"), + pkg => 'nfs-utils nfs-utils-clients', + ports => '111/tcp 111/udp 2049/tcp 2049/udp ' . network::nfs::list_nfs_ports(), + hide => 1, + prepare => sub { network::nfs::write_nfs_ports(network::nfs::read_nfs_ports()) }, + restart => 'nfs-common nfs-server', + }, + { + name => $self->loc->N("Windows Files Sharing (SMB)"), + pkg => 'samba-server', + ports => '137/tcp 137/udp 138/tcp 138/udp 139/tcp 139/udp 445/tcp 445/udp 1024:1100/tcp 1024:1100/udp', + hide => 1, + }, + { + name => $self->loc->N("Bacula backup"), + pkg => 'bacula-fd bacula-sd bacula-dir-common', + ports => '9101:9103/tcp', + hide => 1, + }, + { + name => $self->loc->N("Syslog network logging"), + pkg => 'rsyslog syslog-ng', + ports => '514/udp', + hide => 1, + }, + { + name => $self->loc->N("CUPS server"), + pkg => 'cups', + ports => '631/tcp 631/udp', + hide => 1, + }, + { + name => $self->loc->N("MySQL server"), + pkg => 'mysql', + ports => '3306/tcp 3306/udp', + hide => 1, + }, + { + name => $self->loc->N("PostgreSQL server"), + pkg => 'postgresql8.2 postgresql8.3', + ports => '5432/tcp 5432/udp', + hide => 1, + }, + { + name => $self->loc->N("Echo request (ping)"), + ports => '8/icmp', + force_default_selection => 0, + }, + { + name => $self->loc->N("Network services autodiscovery (zeroconf and slp)"), + ports => '5353/udp 427/udp', + pkg => 'avahi cups openslp', + }, + { + name => $self->loc->N("BitTorrent"), + ports => '6881:6999/tcp 6881:6999/udp', + hide => 1, + pkg => 'bittorrent deluge ktorrent transmission vuze rtorrent ctorrent', + }, + { + name => $self->loc->N("Windows Mobile device synchronization"), + pkg => 'synce-hal', + ports => '990/tcp 999/tcp 5678/tcp 5679/udp 26675/tcp', + hide => 1, + }, + ); + return \@all_servers; +} + +#============================================================= + +=head2 port2server + +=head3 INPUT + + $self: this object + + $ports: port object + +=head3 DESCRIPTION + + This method retrieves the server from a given port + +=cut + +#============================================================= + +sub port2server { + my $self = shift(); + my ($port) = @_; + find { + any { $port eq $_ } split(' ', $_->{ports}); + } $self->all_servers(); +} + +#============================================================= + +=head2 from_ports + +=head3 INPUT + + $self: this object + + $ports: ports object + +=head3 DESCRIPTION + + This method does... + +=cut + +#============================================================= + +sub from_ports { + my $self = shift(); + my ($ports) = @_; + + my @l; + my @unlisted; + foreach (split ' ', $ports) { + if (my $s = $self->port2server($_)) { + push @l, $s; + } else { + push @unlisted, $_; + } + } + [ uniq(@l) ], join(' ', @unlisted); +} + +#============================================================= + +=head2 get_conf + +=head3 INPUT + + $self: this object + + $disabled: boolean + + $o_ports: object representing ports + +=head3 DESCRIPTION + + This method retrieves the configuration + +=cut + +#============================================================= + +sub get_conf { + my $self = shift(); + my ($disabled, $o_ports) = @_; + my $possible_servers = undef; + + if ($o_ports) { + return ($disabled, from_ports($o_ports)); + } elsif (my $shorewall = network::shorewall::read()) { + # WARNING: this condition fails (the method fails) + # if manawall runs as unprivileged user + # cause it can't read the interfaces file + return ($shorewall->{disabled}, $self->from_ports($shorewall->{ports}), $shorewall->{log_net_drop}); + } else { + $self->sh_gui->ask_OkCancel({title => $self->loc->N("Firewall configuration"), text => $self->loc->N("drakfirewall configurator + +This configures a personal firewall for this Mageia machine."), richtext => 1}) or return; + + $self->sh_gui->ask_OkCancel({title => $self->loc->N("Firewall configuration"), text => $self->loc->N("drakfirewall configurator + +Make sure you have configured your Network/Internet access with +drakconnect before going any further."), richtext => 1}) or return; + + return($disabled, $possible_servers, ''); + } +} + +#============================================================= + +=head2 start + +=head3 INPUT + + $self: this object + +=head3 DESCRIPTION + + This method extends Module::start and is invoked to + start host manager + +=cut + +#============================================================= + +sub start { + my $self = shift; + + $self->all_servers($self->_initAllServers()); + + my ($disabled, $servers, $unlisted, $log_net_drop) = $self->get_conf(undef) or return; + + $self->_manageFirewallDialog(); +}; + +#============================================================= + +sub _manageFirewallDialog { + my $self = shift; + + ## TODO fix for adminpanel + my $appTitle = yui::YUI::app()->applicationTitle(); + my $appIcon = yui::YUI::app()->applicationIcon(); + ## set new title to get it in dialog + my $newTitle = $self->loc->N("Manage firewall rules"); + yui::YUI::app()->setApplicationTitle($newTitle); + + my $factory = yui::YUI::widgetFactory; + my $optional = yui::YUI::optionalWidgetFactory; + + + $self->dialog($factory->createMainDialog()); + my $layout = $factory->createVBox($self->dialog); + + my $hbox_header = $factory->createHBox($layout); + my $headLeft = $factory->createHBox($factory->createLeft($hbox_header)); + my $headRight = $factory->createHBox($factory->createRight($hbox_header)); + + my $logoImage = $factory->createImage($headLeft, $appIcon); + my $labelAppDescription = $factory->createLabel($headRight,$newTitle); + $logoImage->setWeight($yui::YD_HORIZ,0); + $labelAppDescription->setWeight($yui::YD_HORIZ,3); + + my $hbox_content = $factory->createHBox($layout); + + my $leftContent = $factory->createLeft($hbox_content); + $leftContent->setWeight($yui::YD_HORIZ,45); + + for my $v(@{$self->all_servers()}) + { + #use Data::Dumper; + #print Dumper($v); + } + + my $rightContent = $factory->createRight($hbox_content); + $rightContent->setWeight($yui::YD_HORIZ,10); + my $topContent = $factory->createTop($rightContent); + my $vbox_commands = $factory->createVBox($topContent); + my $addButton = $factory->createPushButton($factory->createHBox($vbox_commands),$self->loc->N("Add")); + my $edtButton = $factory->createPushButton($factory->createHBox($vbox_commands),$self->loc->N("Edit")); + my $remButton = $factory->createPushButton($factory->createHBox($vbox_commands),$self->loc->N("Remove")); + my $hnButton = $factory->createPushButton($factory->createHBox($vbox_commands),$self->loc->N("Hostname")); + $addButton->setWeight($yui::YD_HORIZ,1); + $edtButton->setWeight($yui::YD_HORIZ,1); + $remButton->setWeight($yui::YD_HORIZ,1); + $hnButton->setWeight($yui::YD_HORIZ,1); + + my $hbox_foot = $factory->createHBox($layout); + my $vbox_foot_left = $factory->createVBox($factory->createLeft($hbox_foot)); + my $vbox_foot_right = $factory->createVBox($factory->createRight($hbox_foot)); + my $aboutButton = $factory->createPushButton($vbox_foot_left,$self->loc->N("About")); + my $cancelButton = $factory->createPushButton($vbox_foot_right,$self->loc->N("Cancel")); + my $okButton = $factory->createPushButton($vbox_foot_right,$self->loc->N("OK")); + + # main loop + while(1) { + my $event = $self->dialog->waitForEvent(); + my $eventType = $event->eventType(); + + #event type checking + if ($eventType == $yui::YEvent::CancelEvent) { + last; + } + elsif ($eventType == $yui::YEvent::WidgetEvent) { +### Buttons and widgets ### + my $widget = $event->widget(); + if ($widget == $cancelButton) { + last; + } + elsif ($widget == $addButton) { + $self->_addHostDialog(); + $self->setupTable(); + } + elsif ($widget == $edtButton) { + my $tblItem = yui::toYTableItem($self->table->selectedItem()); + if($tblItem->cellCount() >= 3){ + $self->_edtHostDialog($tblItem->cell(0)->label(),$tblItem->cell(1)->label(),$tblItem->cell(2)->label()); + }else{ + $self->_edtHostDialog($tblItem->cell(0)->label(),$tblItem->cell(1)->label(),""); + } + $self->setupTable(); + } + elsif ($widget == $remButton) { + # implement deletion dialog + if($self->sh_gui->ask_YesOrNo({title => $self->loc->N("Confirmation"), text => $self->loc->N("Are you sure to drop this host?")}) == 1){ + my $tblItem = yui::toYTableItem($self->table->selectedItem()); + # drop the host using the ip + $self->cfgHosts->_dropHost($tblItem->cell(0)->label()); + # write changes + $self->cfgHosts->_writeHosts(); + $self->setupTable(); + } + }elsif ($widget == $hnButton) { + $self->_changeHostNameDialog("Change the HostName FQDN"); + $self->setupTable(); + }elsif ($widget == $aboutButton) { + $self->sh_gui->AboutDialog({ + name => $appTitle, + version => $VERSION, + credits => "Copyright (c) 2013-2014 by Matteo Pasotti", + license => "GPLv2", + description => $self->loc->N("Graphical manager for hosts definitions"), + authors => "Matteo Pasotti <matteo.pasotti\@gmail.com>" + } + ); + }elsif ($widget == $okButton) { + # write changes + $self->cfgHosts->_writeHosts(); + last; + } + } + } + + $self->dialog->destroy() ; + + #restore old application title + yui::YUI::app()->setApplicationTitle($appTitle); +} + +1; diff --git a/lib/AdminPanel/Shared/Firewall.pm b/lib/AdminPanel/Shared/Firewall.pm new file mode 100644 index 0000000..2638ff8 --- /dev/null +++ b/lib/AdminPanel/Shared/Firewall.pm @@ -0,0 +1,37 @@ +# vim: set et ts=4 sw=4: +#***************************************************************************** +# +# Copyright (c) 2013-2014 Matteo Pasotti +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2, as +# published by the Free Software Foundation. +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +#***************************************************************************** +package AdminPanel::Shared::Firewall; + +use Moose; +use diagnostics; +use utf8; + +use lib qw(/usr/lib/libDrakX); +# WARNING: using common +use common; +use network::nfs; +use network::network; +use network::shorewall; + +sub _initialize { + my $self = shift(); +} + +1; -- cgit v1.2.1