From 38bf4d4549d4fb1b24bb5816e63d0282dc93ab6b Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa Date: Fri, 12 Feb 2016 15:09:44 +0530 Subject: [PATCH] firewall: Use new setup mechanism - Also reorganize module to separate out views. --- plinth/modules/config/config.py | 2 +- plinth/modules/firewall/__init__.py | 116 ++++++++++++++- plinth/modules/firewall/firewall.py | 137 ------------------ .../modules/firewall/templates/firewall.html | 15 +- plinth/modules/firewall/urls.py | 2 +- plinth/modules/firewall/views.py | 45 ++++++ 6 files changed, 162 insertions(+), 155 deletions(-) delete mode 100644 plinth/modules/firewall/firewall.py create mode 100644 plinth/modules/firewall/views.py diff --git a/plinth/modules/config/config.py b/plinth/modules/config/config.py index f730f83d1..54c687c2b 100644 --- a/plinth/modules/config/config.py +++ b/plinth/modules/config/config.py @@ -33,7 +33,7 @@ import socket from plinth import actions from plinth import cfg -from plinth.modules.firewall import firewall +from plinth.modules import firewall from plinth.modules.names import SERVICES from plinth.signals import pre_hostname_change, post_hostname_change from plinth.signals import domainname_change diff --git a/plinth/modules/firewall/__init__.py b/plinth/modules/firewall/__init__.py index 3abc58c06..96cb449a1 100644 --- a/plinth/modules/firewall/__init__.py +++ b/plinth/modules/firewall/__init__.py @@ -19,9 +19,119 @@ Plinth module to configure a firewall """ -from . import firewall -from .firewall import init +from django.utils.translation import ugettext_lazy as _ +import logging -__all__ = ['firewall', 'init'] +from plinth import actions +from plinth import cfg +from plinth.signals import service_enabled +import plinth.service as service_module +from plinth.utils import format_lazy + +version = 1 + +is_essential = True depends = ['system'] + +title = _('Firewall') + +description = [ + format_lazy( + _('Firewall is a security system that controls the incoming and ' + 'outgoing network traffic on your {box_name}. Keeping a ' + 'firewall enabled and properly configured reduces risk of ' + 'security threat from the Internet.'), box_name=cfg.box_name) +] + +LOGGER = logging.getLogger(__name__) + + +def init(): + """Initailze firewall module""" + menu = cfg.main_menu.get('system:index') + menu.add_urlname(title, 'glyphicon-fire', 'firewall:index', 50) + + service_enabled.connect(on_service_enabled) + + +def setup(helper, old_version=None): + """Install and configure the module.""" + helper.install(['firewalld']) + + +def get_enabled_status(): + """Return whether firewall is enabled""" + output = _run(['get-status'], superuser=True) + return output.split()[0] == 'running' + + +def get_enabled_services(zone): + """Return the status of various services currently enabled""" + output = _run(['get-enabled-services', '--zone', zone], superuser=True) + return output.split() + + +def add_service(port, zone): + """Enable a service in firewall""" + _run(['add-service', port, '--zone', zone], superuser=True) + + +def remove_service(port, zone): + """Remove a service in firewall""" + _run(['remove-service', port, '--zone', zone], superuser=True) + + +def on_service_enabled(sender, service_id, enabled, **kwargs): + """ + Enable/disable firewall ports when a service is + enabled/disabled. + """ + del sender # Unused + del kwargs # Unused + + internal_enabled_services = get_enabled_services(zone='internal') + external_enabled_services = get_enabled_services(zone='external') + + LOGGER.info('Service enabled - %s, %s', service_id, enabled) + service = service_module.services[service_id] + for port in service.ports: + if enabled: + if port not in internal_enabled_services: + add_service(port, zone='internal') + + if (service.is_external and + port not in external_enabled_services): + add_service(port, zone='external') + else: + # service already configured. + pass + else: + if port in internal_enabled_services: + enabled_services_on_port = [ + service_.is_enabled() + for service_ in service_module.services.values() + if port in service_.ports and + service_id != service_.service_id] + if not any(enabled_services_on_port): + remove_service(port, zone='internal') + + if port in external_enabled_services: + enabled_services_on_port = [ + service_.is_enabled() + for service_ in service_module.services.values() + if port in service_.ports and + service_id != service_.service_id and + service_.is_external] + if not any(enabled_services_on_port): + remove_service(port, zone='external') + + +def _run(arguments, superuser=False): + """Run an given command and raise exception if there was an error""" + command = 'firewall' + + if superuser: + return actions.superuser_run(command, arguments) + else: + return actions.run(command, arguments) diff --git a/plinth/modules/firewall/firewall.py b/plinth/modules/firewall/firewall.py deleted file mode 100644 index dc693af90..000000000 --- a/plinth/modules/firewall/firewall.py +++ /dev/null @@ -1,137 +0,0 @@ -# -# This file is part of Plinth. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# - -""" -Plinth module to configure a firewall -""" - -from django.template.response import TemplateResponse -from django.utils.translation import ugettext_lazy as _ -import logging - -from plinth import actions -from plinth import cfg -from plinth import package -from plinth.signals import service_enabled -import plinth.service as service_module - - -LOGGER = logging.getLogger(__name__) - - -def init(): - """Initailze firewall module""" - menu = cfg.main_menu.get('system:index') - menu.add_urlname(_('Firewall'), 'glyphicon-fire', 'firewall:index', 50) - - service_enabled.connect(on_service_enabled) - - -@package.required(['firewalld']) -def index(request): - """Serve introcution page""" - if not get_enabled_status(): - return TemplateResponse(request, 'firewall.html', - {'title': _('Firewall'), - 'firewall_status': 'not_running'}) - - internal_enabled_services = get_enabled_services(zone='internal') - external_enabled_services = get_enabled_services(zone='external') - - return TemplateResponse( - request, 'firewall.html', - {'title': _('Firewall'), - 'services': list(service_module.services.values()), - 'internal_enabled_services': internal_enabled_services, - 'external_enabled_services': external_enabled_services}) - - -def get_enabled_status(): - """Return whether firewall is enabled""" - output = _run(['get-status'], superuser=True) - return output.split()[0] == 'running' - - -def get_enabled_services(zone): - """Return the status of various services currently enabled""" - output = _run(['get-enabled-services', '--zone', zone], superuser=True) - return output.split() - - -def add_service(port, zone): - """Enable a service in firewall""" - _run(['add-service', port, '--zone', zone], superuser=True) - - -def remove_service(port, zone): - """Remove a service in firewall""" - _run(['remove-service', port, '--zone', zone], superuser=True) - - -def on_service_enabled(sender, service_id, enabled, **kwargs): - """ - Enable/disable firewall ports when a service is - enabled/disabled. - """ - del sender # Unused - del kwargs # Unused - - internal_enabled_services = get_enabled_services(zone='internal') - external_enabled_services = get_enabled_services(zone='external') - - LOGGER.info('Service enabled - %s, %s', service_id, enabled) - service = service_module.services[service_id] - for port in service.ports: - if enabled: - if port not in internal_enabled_services: - add_service(port, zone='internal') - - if (service.is_external and - port not in external_enabled_services): - add_service(port, zone='external') - else: - # service already configured. - pass - else: - if port in internal_enabled_services: - enabled_services_on_port = [ - service_.is_enabled() - for service_ in service_module.services.values() - if port in service_.ports and - service_id != service_.service_id] - if not any(enabled_services_on_port): - remove_service(port, zone='internal') - - if port in external_enabled_services: - enabled_services_on_port = [ - service_.is_enabled() - for service_ in service_module.services.values() - if port in service_.ports and - service_id != service_.service_id and - service_.is_external] - if not any(enabled_services_on_port): - remove_service(port, zone='external') - - -def _run(arguments, superuser=False): - """Run an given command and raise exception if there was an error""" - command = 'firewall' - - if superuser: - return actions.superuser_run(command, arguments) - else: - return actions.run(command, arguments) diff --git a/plinth/modules/firewall/templates/firewall.html b/plinth/modules/firewall/templates/firewall.html index e59d4052d..ec2440702 100644 --- a/plinth/modules/firewall/templates/firewall.html +++ b/plinth/modules/firewall/templates/firewall.html @@ -1,4 +1,4 @@ -{% extends "base.html" %} +{% extends "app.html" %} {% comment %} # # This file is part of Plinth. @@ -20,18 +20,7 @@ {% load i18n %} -{% block content %} - -

{{ title }}

- -

- {% blocktrans trimmed %} - Firewall is a security system that controls the incoming and - outgoing network traffic on your {{ box_name }}. Keeping a - firewall enabled and properly configured reduces risk of - security threat from the Internet. - {% endblocktrans %} -

+{% block configuration %}

{% trans "Current status:" %}

diff --git a/plinth/modules/firewall/urls.py b/plinth/modules/firewall/urls.py index 6448e89f6..8c6765af9 100644 --- a/plinth/modules/firewall/urls.py +++ b/plinth/modules/firewall/urls.py @@ -21,7 +21,7 @@ URLs for the Firewall module from django.conf.urls import url -from . import firewall as views +from . import views urlpatterns = [ diff --git a/plinth/modules/firewall/views.py b/plinth/modules/firewall/views.py new file mode 100644 index 000000000..3dab988ab --- /dev/null +++ b/plinth/modules/firewall/views.py @@ -0,0 +1,45 @@ +# +# This file is part of Plinth. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +""" +Plinth module to configure a firewall +""" + +from django.template.response import TemplateResponse + +from plinth.modules import firewall +import plinth.service as service_module + + +def index(request): + """Serve introcution page""" + if not firewall.get_enabled_status(): + return TemplateResponse(request, 'firewall.html', + {'title': firewall.title, + 'description': firewall.description, + 'firewall_status': 'not_running'}) + + internal_enabled_services = firewall.get_enabled_services(zone='internal') + external_enabled_services = firewall.get_enabled_services(zone='external') + + return TemplateResponse( + request, 'firewall.html', + {'title': firewall.title, + 'description': firewall.description, + 'services': list(service_module.services.values()), + 'internal_enabled_services': internal_enabled_services, + 'external_enabled_services': external_enabled_services})