[apparmor] [patch] Add match() and _match() class methods to rule classes
Christian Boltz
apparmor at cboltz.de
Tue Apr 21 21:47:03 UTC 2015
Hello,
this patch adds match() and _match() class methods to rule classes:
- _match() returns a regex match object for the given raw_rule
- match() converts the _match() result to True or False
The primary usage is to get an answer to the question "is this raw_rule
your job?". (For a moment, I thought about naming the function
*Rule.myjob() instead of *Rule.match() ;-)
My next patch will change aa.py to use *Rule.match() instead of directly
using RE_*, which will make the import list much shorter and hide
another implementation detail inside the rule classes.
Also change _parse() to use _match() instead of the regex, and add some
tests for match() and _match().
Note: This patch depends on all my pending patches (well, except the
.bzrignore patch ;-)
[ 48-add-rule-match.diff ]
=== modified file utils/apparmor/rule/capability.py
--- utils/apparmor/rule/capability.py 2015-04-17 22:44:58.568224878 +0200
+++ utils/apparmor/rule/capability.py 2015-04-21 23:22:21.695364126 +0200
@@ -61,10 +61,14 @@
raise AppArmorBug('Passed empty capability to CapabilityRule: %s' % str(cap_list))
@classmethod
+ def _match(cls, raw_rule):
+ return RE_PROFILE_CAP.search(raw_rule)
+
+ @classmethod
def _parse(cls, raw_rule):
'''parse raw_rule and return CapabilityRule'''
- matches = RE_PROFILE_CAP.search(raw_rule)
+ matches = cls._match(raw_rule)
if not matches:
raise AppArmorException(_("Invalid capability rule '%s'") % raw_rule)
=== modified file utils/apparmor/rule/__init__.py
--- utils/apparmor/rule/__init__.py 2015-04-16 02:18:03.865500000 +0200
+++ utils/apparmor/rule/__init__.py 2015-04-21 23:24:53.741276189 +0200
@@ -26,6 +26,8 @@
# type specific rules should inherit from this class.
# Methods that subclasses need to implement:
# __init__
+ # _match(cls, raw_rule) (as a class method)
+ # - parses a raw rule and returns a regex match object
# _parse(cls, raw_rule) (as a class method)
# - parses a raw rule and returns an object of the Rule subclass
# get_clean(depth)
@@ -49,7 +51,25 @@
self.raw_rule = None
@classmethod
+ def match(cls, raw_rule):
+ '''return True if raw_rule matches the class (main) regex, False otherwise
+ Note: This function just provides an answer to "is this your job?".
+ It does not guarantee that the rule is completely valid.'''
+
+ if cls._match(raw_rule):
+ return True
+ else:
+ return False
+
+ # @abstractmethod FIXME - uncomment when python3 only
+ @classmethod
+ def _match(cls, raw_rule):
+ '''parse raw_rule and return regex match object'''
+ raise AppArmorBug("'%s' needs to implement _match(), but didn't" % (str(cls)))
+
+ @classmethod
def parse(cls, raw_rule):
+ '''parse raw_rule and return a rule object'''
rule = cls._parse(raw_rule)
rule.raw_rule = raw_rule.strip()
return rule
=== modified file utils/apparmor/rule/network.py
--- utils/apparmor/rule/network.py 2015-04-17 23:10:00.147204258 +0200
+++ utils/apparmor/rule/network.py 2015-04-21 23:22:12.494914387 +0200
@@ -98,10 +98,14 @@
raise AppArmorBug('Passed unknown object to NetworkRule: %s' % str(type_or_protocol))
@classmethod
+ def _match(cls, raw_rule):
+ return RE_PROFILE_NETWORK.search(raw_rule)
+
+ @classmethod
def _parse(cls, raw_rule):
'''parse raw_rule and return NetworkRule'''
- matches = RE_PROFILE_NETWORK.search(raw_rule)
+ matches = cls._match(raw_rule)
if not matches:
raise AppArmorException(_("Invalid network rule '%s'") % raw_rule)
=== modified file utils/test/test-baserule.py
--- utils/test/test-baserule.py 2015-04-19 23:30:50.904564067 +0200
+++ utils/test/test-baserule.py 2015-04-21 23:21:41.578763715 +0200
@@ -22,6 +22,18 @@
with self.assertRaises(AppArmorBug):
BaseRule._parse('foo')
+ def test_abstract__parse_2(self):
+ with self.assertRaises(AppArmorBug):
+ BaseRule.parse('foo')
+
+ def test_abstract__match(self):
+ with self.assertRaises(AppArmorBug):
+ BaseRule._match('foo')
+
+ def test_abstract__match2(self):
+ with self.assertRaises(AppArmorBug):
+ BaseRule.match('foo')
+
def test_is_equal_localvars(self):
obj = BaseRule()
with self.assertRaises(AppArmorBug):
=== modified file utils/test/test-capability.py
--- utils/test/test-capability.py 2015-04-19 23:30:50.904564067 +0200
+++ utils/test/test-capability.py 2015-04-21 23:11:15.155343906 +0200
@@ -30,6 +30,7 @@
obj = CapabilityRule.parse(rawrule)
+ self.assertTrue(CapabilityRule.match(rawrule))
self.assertEqual(rawrule.strip(), obj.raw_rule)
self._compare_obj(obj, expected)
@@ -220,6 +221,7 @@
with self.assertRaises(AppArmorException):
obj = CapabilityRule(CapabilityRule.parse(rawrule))
+ self.assertFalse(CapabilityRule.match(rawrule))
self.assertIsNone(obj, 'CapbilityRule handed back an object unexpectedly')
def test_invalid_cap_missing_comma(self):
@@ -269,6 +271,7 @@
clean = obj.get_clean()
raw = obj.get_raw()
+ self.assertTrue(CapabilityRule.match(rawrule))
self.assertEqual(cleanrule.strip(), clean, 'unexpected clean rule')
self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule')
@@ -294,12 +297,15 @@
self.maxDiff = None
def _is_covered(self, obj, rule_to_test):
+ self.assertTrue(CapabilityRule.match(rule_to_test))
return obj.is_covered(CapabilityRule.parse(rule_to_test))
def _is_covered_exact(self, obj, rule_to_test):
+ self.assertTrue(CapabilityRule.match(rule_to_test))
return obj.is_covered(CapabilityRule.parse(rule_to_test), True, True)
def _is_equal(self, obj, rule_to_test, strict):
+ self.assertTrue(CapabilityRule.match(rule_to_test))
return obj.is_equal(CapabilityRule.parse(rule_to_test), strict)
def test_covered_single(self):
=== modified file utils/test/test-network.py
--- utils/test/test-network.py 2015-04-20 00:17:55.028303768 +0200
+++ utils/test/test-network.py 2015-04-21 23:04:14.672708712 +0200
@@ -49,6 +49,7 @@
]
def _run_test(self, rawrule, expected):
+ self.assertTrue(NetworkRule.match(rawrule))
obj = NetworkRule.parse(rawrule)
self.assertEqual(rawrule.strip(), obj.raw_rule)
self._compare_obj(obj, expected)
@@ -63,6 +64,7 @@
]
def _run_test(self, rawrule, expected):
+ self.assertTrue(NetworkRule.match(rawrule)) # the above invalid rules still match the main regex!
with self.assertRaises(expected):
NetworkRule.parse(rawrule)
@@ -152,6 +154,7 @@
class InvalidNetworkTest(AATest):
def _check_invalid_rawrule(self, rawrule):
obj = None
+ self.assertFalse(NetworkRule.match(rawrule))
with self.assertRaises(AppArmorException):
obj = NetworkRule(NetworkRule.parse(rawrule))
@@ -180,6 +183,7 @@
class WriteNetworkTestAATest(AATest):
def _run_test(self, rawrule, expected):
+ self.assertTrue(NetworkRule.match(rawrule))
obj = NetworkRule.parse(rawrule)
clean = obj.get_clean()
raw = obj.get_raw()
@@ -210,6 +214,8 @@
obj = NetworkRule.parse(self.rule)
check_obj = NetworkRule.parse(param)
+ self.assertTrue(NetworkRule.match(param))
+
self.assertEqual(obj.is_equal(check_obj), expected[0], 'Mismatch in is_equal, expected %s' % expected[0])
self.assertEqual(obj.is_equal(check_obj, True), expected[1], 'Mismatch in is_equal/strict, expected %s' % expected[1])
Regards,
Christian Boltz
--
> Und nun rate mal, warum ausgerechnet v.a. Vielschreiber mutt
> verwenden. Sicher nicht, weil KMail besser waere.
Weil eine Handvoll muttschisten die alle dazu gezwungen hat? ;)
[> David Haller und Manfred Misch in suse-linux]
More information about the AppArmor
mailing list