[apparmor] [patch] Add match() and _match() class methods to rule classes

Seth Arnold seth.arnold at canonical.com
Tue Apr 21 23:42:50 UTC 2015


On Tue, Apr 21, 2015 at 11:47:03PM +0200, Christian Boltz wrote:
> 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 ;-)

Acked-by: Seth Arnold <seth.arnold at canonical.com>

Thanks

> 
> 
> [ 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]
> 
> 
> -- 
> AppArmor mailing list
> AppArmor at lists.ubuntu.com
> Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <https://lists.ubuntu.com/archives/apparmor/attachments/20150421/af222e5b/attachment-0001.pgp>


More information about the AppArmor mailing list