[apparmor] [patch] [19/38] Add support for editing paths to FileRule
Christian Boltz
apparmor at cboltz.de
Fri Aug 12 20:58:32 UTC 2016
Hello,
$subject.
This means adding
- self.can_edit - True if editing via '(N)ew' should be possible (will
be False for bare file rules)
- edit_header() - returns the prompt text and the current path
- validate_edit() - checks if the new path matches the original one
- store_edit() - changes the path to the new one (even if it doesn't
match the old one)
self.can_edit and the 3 functions are also added to BaseRule:
- can_edit is False by default
- the functions raise a NotImplementedError
Also add tests for the added code.
[ 19-add-support-for-editing-paths-to-FileRule.diff ]
=== modified file ./utils/apparmor/rule/file.py
--- utils/apparmor/rule/file.py 2016-03-28 19:08:25.211838730 +0200
+++ utils/apparmor/rule/file.py 2016-03-28 22:14:06.469847397 +0200
@@ -12,6 +12,7 @@
#
# ----------------------------------------------------------------------
+from apparmor.aare import AARE
from apparmor.regex import RE_PROFILE_FILE_ENTRY, strip_quotes
from apparmor.common import AppArmorBug, AppArmorException, type_is_str
from apparmor.rule import BaseRule, BaseRuleset, check_and_split_list, logprof_value_or_all, parse_modifiers, quote_if_needed
@@ -66,6 +67,7 @@
self.can_glob = not self.all_paths
self.can_glob_ext = not self.all_paths
+ self.can_edit = not self.all_paths
if type_is_str(perms):
perms, tmp_exec_perms = split_perms(perms, deny)
@@ -339,6 +341,26 @@
self.path = self.path.glob_path_withext()
self.raw_rule = None
+ def edit_header(self):
+ if self.all_paths:
+ raise AppArmorBug('Attemp to edit bare file rule')
+
+ return(_('Enter new path: '), self.path.regex)
+
+ def validate_edit(self, newpath):
+ if self.all_paths:
+ raise AppArmorBug('Attemp to edit bare file rule')
+
+ newpath = AARE(newpath, True) # might raise AppArmorException if the new path doesn't start with / or a variable
+ return newpath.match(self.path)
+
+ def store_edit(self, newpath):
+ if self.all_paths:
+ raise AppArmorBug('Attemp to edit bare file rule')
+
+ self.path = AARE(newpath, True) # might raise AppArmorException if the new path doesn't start with / or a variable
+ self.raw_rule = None
+
class FileRuleset(BaseRuleset):
'''Class to handle and store a collection of file rules'''
=== modified file ./utils/apparmor/rule/__init__.py
--- utils/apparmor/rule/__init__.py 2016-03-28 19:08:25.211838730 +0200
+++ utils/apparmor/rule/__init__.py 2016-03-28 22:13:01.022202835 +0200
@@ -43,6 +43,9 @@
can_glob = False
can_glob_ext = False
+ # defines if the (N)ew option is displayed
+ can_edit = False
+
def __init__(self, audit=False, deny=False, allow_keyword=False,
comment='', log_event=None):
'''initialize variables needed by all rule types'''
@@ -273,6 +276,23 @@
returns {'label1': 'value1', 'label2': 'value2'} '''
raise NotImplementedError("'%s' needs to implement logprof_header(), but didn't" % (str(self)))
+ # @abstractmethod FIXME - uncomment when python3 only
+ def edit_header(self):
+ '''return the prompt for, and the path to edit when using '(N)ew' '''
+ raise NotImplementedError("'%s' needs to implement edit_header(), but didn't" % (str(self)))
+
+ # @abstractmethod FIXME - uncomment when python3 only
+ def validate_edit(self, newpath):
+ '''validate the new path.
+ Returns True if it covers the previous path, False if it doesn't.'''
+ raise NotImplementedError("'%s' needs to implement validate_edit(), but didn't" % (str(self)))
+
+ # @abstractmethod FIXME - uncomment when python3 only
+ def store_edit(self, newpath):
+ '''store the changed path.
+ This is done even if the new path doesn't match the original one.'''
+ raise NotImplementedError("'%s' needs to implement store_edit(), but didn't" % (str(self)))
+
def modifiers_str(self):
'''return the allow/deny and audit keyword as string, including whitespace'''
=== modified file ./utils/test/test-baserule.py
--- utils/test/test-baserule.py 2016-03-28 19:08:25.195838799 +0200
+++ utils/test/test-baserule.py 2016-03-28 22:44:34.867670716 +0200
@@ -68,6 +68,21 @@
with self.assertRaises(NotImplementedError):
obj.logprof_header_localvars()
+ def test_edit_header_localvars(self):
+ obj = BaseRule()
+ with self.assertRaises(NotImplementedError):
+ obj.edit_header()
+
+ def test_validate_edit_localvars(self):
+ obj = BaseRule()
+ with self.assertRaises(NotImplementedError):
+ obj.validate_edit('/foo')
+
+ def test_store_edit_localvars(self):
+ obj = BaseRule()
+ with self.assertRaises(NotImplementedError):
+ obj.store_edit('/foo')
+
setup_all_loops(__name__)
if __name__ == '__main__':
=== modified file ./utils/test/test-file.py
--- utils/test/test-file.py 2016-03-28 19:08:25.211838730 +0200
+++ utils/test/test-file.py 2016-03-28 22:39:44.013280194 +0200
@@ -718,6 +718,63 @@
# obj = FileRule._parse(params)
# self.assertEqual(obj.logprof_header(), expected)
+class FileEditHeaderTest(AATest):
+ def _run_test(self, params, expected):
+ rule_obj = FileRule.parse(params)
+ self.assertEqual(rule_obj.can_edit, True)
+ prompt, path_to_edit = rule_obj.edit_header()
+ self.assertEqual(path_to_edit, expected)
+
+ tests = [
+ ('/foo/bar/baz r,', '/foo/bar/baz'),
+ ('/foo/**/baz r,', '/foo/**/baz'),
+ ]
+
+ def test_edit_header_bare_file(self):
+ rule_obj = FileRule.parse('file,')
+ self.assertEqual(rule_obj.can_edit, False)
+ with self.assertRaises(AppArmorBug):
+ rule_obj.edit_header()
+
+class FileValidateAndStoreEditTest(AATest):
+ def _run_test(self, params, expected):
+ rule_obj = FileRule('/foo/bar/baz', 'r', None, FileRule.ALL, False, False, False, log_event=True)
+
+ self.assertEqual(rule_obj.validate_edit(params), expected)
+
+ rule_obj.store_edit(params)
+ self.assertEqual(rule_obj.get_raw(), '%s r,' % params)
+
+ tests = [
+ # edited path match
+ ('/foo/bar/baz', True),
+ ('/foo/bar/*', True),
+ ('/foo/bar/???', True),
+ ('/foo/xy**', False),
+ ('/foo/bar/baz/', False),
+ ]
+
+ def test_validate_not_a_path(self):
+ rule_obj = FileRule.parse('/foo/bar/baz r,')
+
+ with self.assertRaises(AppArmorException):
+ rule_obj.validate_edit('foo/bar/baz')
+
+ with self.assertRaises(AppArmorException):
+ rule_obj.store_edit('foo/bar/baz')
+
+ def test_validate_edit_bare_file(self):
+ rule_obj = FileRule.parse('file,')
+ self.assertEqual(rule_obj.can_edit, False)
+
+ with self.assertRaises(AppArmorBug):
+ rule_obj.validate_edit('/foo/bar')
+
+ with self.assertRaises(AppArmorBug):
+ rule_obj.store_edit('/foo/bar')
+
+
+
## --- tests for FileRuleset --- #
class FileRulesTest(AATest):
Regards,
Christian Boltz
--
For the simple cases, the results would be easier studied by cause and
effect, rather than code. For complicated cases, the code will be
unreadable. (And I say that as a friend. :) [Seth Arnold in apparmor]
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part.
URL: <https://lists.ubuntu.com/archives/apparmor/attachments/20160812/0c16fffb/attachment-0001.pgp>
More information about the AppArmor
mailing list