From 2afae80dd8383cdafc7f968c0c94b3867f889421 Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa Date: Sat, 9 Jul 2016 22:34:12 +0530 Subject: [PATCH] security: Recommend/notify about restricted logins - Do stricter matches when editing configuration file. Earlier mechanism would match comments etc. - Move action methods to module core from views. - During first boot, notify users that console login is restricted and that they can changed that from security settings. - Recommend enabling conosle login restrictions. Add message about why console restrictions are important. - Show title in security module. --- actions/security | 4 +-- plinth/modules/first_boot/forms.py | 12 ++++++-- plinth/modules/security/__init__.py | 26 ++++++++++++++++ plinth/modules/security/forms.py | 7 +++-- .../modules/security/templates/security.html | 4 +-- plinth/modules/security/views.py | 30 ++----------------- 6 files changed, 47 insertions(+), 36 deletions(-) diff --git a/actions/security b/actions/security index 3567f9896..c08693263 100755 --- a/actions/security +++ b/actions/security @@ -49,7 +49,7 @@ def subcommand_enable_restricted_access(_): lines = conffile.readlines() for line in lines: - if ACCESS_CONF_SNIPPET in line: + if ACCESS_CONF_SNIPPET == line.strip(): return with open(ACCESS_CONF_FILE, 'a') as conffile: @@ -63,7 +63,7 @@ def subcommand_disable_restricted_access(_): with open(ACCESS_CONF_FILE, 'w') as conffile: for line in lines: - if ACCESS_CONF_SNIPPET not in line: + if ACCESS_CONF_SNIPPET != line.strip(): conffile.write(line) diff --git a/plinth/modules/first_boot/forms.py b/plinth/modules/first_boot/forms.py index 3dfc31a7a..759312813 100644 --- a/plinth/modules/first_boot/forms.py +++ b/plinth/modules/first_boot/forms.py @@ -33,7 +33,7 @@ from plinth import actions from plinth import cfg from plinth.errors import ActionError, DomainRegistrationError from plinth.modules.pagekite.utils import PREDEFINED_SERVICES, run -from plinth.modules.security.views import set_restricted_access +from plinth.modules.security import set_restricted_access from plinth.modules.users.forms import GROUP_CHOICES from plinth.utils import format_lazy @@ -78,7 +78,15 @@ class State1Form(auth.forms.UserCreationForm): self.cleaned_data['password1']) # Restrict console login to users in admin or sudo group - set_restricted_access(True) + try: + set_restricted_access(True) + message = _('Console login access restricted to users in ' + '"admin" group. This can be configured in ' + 'security settings.') + messages.success(self.request, message) + except Exception: + messages.error(self.request, + _('Failed to restrict console access.')) return user diff --git a/plinth/modules/security/__init__.py b/plinth/modules/security/__init__.py index 6eb292653..4cf43de06 100644 --- a/plinth/modules/security/__init__.py +++ b/plinth/modules/security/__init__.py @@ -22,6 +22,7 @@ Plinth module for security configuration from django.utils.translation import ugettext_lazy as _ from plinth import cfg +from plinth import actions version = 1 @@ -33,7 +34,32 @@ depends = ['system'] title = _('Security') +ACCESS_CONF_FILE = '/etc/security/access.conf' +ACCESS_CONF_SNIPPET = '-:ALL EXCEPT root fbx (admin) (sudo):ALL' + + def init(): """Initialize the module""" menu = cfg.main_menu.get('system:index') menu.add_urlname(title, 'glyphicon-lock', 'security:index') + + +def get_restricted_access_enabled(): + """Return whether restricted access is enabled""" + with open(ACCESS_CONF_FILE, 'r') as conffile: + lines = conffile.readlines() + + for line in lines: + if ACCESS_CONF_SNIPPET in line: + return True + + return False + + +def set_restricted_access(enabled): + """Enable or disable restricted access""" + action = 'disable-restricted-access' + if enabled: + action = 'enable-restricted-access' + + actions.superuser_run('security', [action]) diff --git a/plinth/modules/security/forms.py b/plinth/modules/security/forms.py index 44dbf49c8..58a6105e1 100644 --- a/plinth/modules/security/forms.py +++ b/plinth/modules/security/forms.py @@ -26,7 +26,8 @@ from django.utils.translation import ugettext_lazy as _ class SecurityForm(forms.Form): """Security configuration form""" restricted_access = forms.BooleanField( - label=_('Restrict console logins'), required=False, + label=_('Restrict console logins (recommended)'), required=False, help_text=_('When this option is enabled, only users in the "admin" ' - 'group will be able to login through an attached ' - 'keyboard/monitor or serial console.')) + 'group will be able to log in to console or via SSH. ' + 'Console users may be able to access some services ' + 'without further authorization.')) diff --git a/plinth/modules/security/templates/security.html b/plinth/modules/security/templates/security.html index 996f16704..7debd088a 100644 --- a/plinth/modules/security/templates/security.html +++ b/plinth/modules/security/templates/security.html @@ -1,4 +1,4 @@ -{% extends "base.html" %} +{% extends "simple_service.html" %} {% comment %} # # This file is part of Plinth. @@ -21,7 +21,7 @@ {% load bootstrap %} {% load i18n %} -{% block content %} +{% block configuration %}
{% csrf_token %} diff --git a/plinth/modules/security/views.py b/plinth/modules/security/views.py index affc29b66..8deb3792f 100644 --- a/plinth/modules/security/views.py +++ b/plinth/modules/security/views.py @@ -24,11 +24,7 @@ from django.template.response import TemplateResponse from django.utils.translation import ugettext as _ from .forms import SecurityForm -from plinth import actions - - -ACCESS_CONF_FILE = '/etc/security/access.conf' -ACCESS_CONF_SNIPPET = '-:ALL EXCEPT root fbx (admin) (sudo):ALL' +from plinth.modules import security def index(request): @@ -53,14 +49,14 @@ def index(request): def get_status(request): """Return the current status""" - return {'restricted_access': get_restricted_access_enabled()} + return {'restricted_access': security.get_restricted_access_enabled()} def _apply_changes(request, old_status, new_status): """Apply the form changes""" if old_status['restricted_access'] != new_status['restricted_access']: try: - set_restricted_access(new_status['restricted_access']) + security.set_restricted_access(new_status['restricted_access']) except Exception as exception: messages.error( request, @@ -68,23 +64,3 @@ def _apply_changes(request, old_status, new_status): .format(exception=exception)) else: messages.success(request, _('Updated security configuration')) - - -def get_restricted_access_enabled(): - """Return whether restricted access is enabled""" - with open(ACCESS_CONF_FILE, 'r') as conffile: - lines = conffile.readlines() - - for line in lines: - if ACCESS_CONF_SNIPPET in line: - return True - - return False - - -def set_restricted_access(enabled): - """Enable or disable restricted access""" - action = 'disable-restricted-access' - if enabled: - action = 'enable-restricted-access' - actions.superuser_run('security', [action])