[apparmor] [patch] Add and use logprof_header() and logprof_header_localvars() in *Rule classes

Christian Boltz apparmor at cboltz.de
Sun May 24 20:45:43 UTC 2015


Hello,

this patch adds and uses logprof_header() and logprof_header_localvars()
in/to the *Rule classes

BaseRule:
- add logprof_header() - sets the 'Qualifier' (audit, allow/deny) header
  if a qualifier is specified, calls logprof_header_localvars() and then
  returns an array of headers to display in aa-logprof and aa-mergeprof
- add logprof_header_localvars() - dummy function that needs to be
  implemented in the child classes

NetworkRule: add logprof_header_localvars() - adds 'Network Family'
and 'Socket Type' to the headers

CapabilityRule: add logprof_header_localvars() - adds 'Capability' to
the headers

Also change aa-mergeprof to use rule_obj.logprof_header() for network
and capability rules. This means deleting lots of lines (that moved to
the *Rule classes) and also deleting the last differences between
capabiltiy and network rules.

Finally add tests for the newly added functions.



[ 23-mergeprof-move-headers-to-rule-classes.diff ]

=== modified file utils/aa-mergeprof
--- utils/aa-mergeprof  2015-05-24 21:14:09.298109240 +0200
+++ utils/aa-mergeprof  2015-05-24 22:24:24.061725816 +0200
@@ -328,22 +328,7 @@
                     q.selected = default_option - 1
 
                     q.headers = [_('Profile'), apparmor.aa.combine_name(profile, hat)]
-                    qualifier = ''
-                    if rule_obj.deny:
-                        qualifier = 'deny %s' % qualifier
-
-                    if rule_obj.audit:                                                                                                                                                                            
-                        qualifier = 'audit %s' % qualifier                                                                                                                                                        
-                                                                                                                                                                                                                  
-                    if qualifier:                                                                                                                                                                                 
-                        q.headers += [_('Qualifier'), qualifier]                                                                                                                                                  
-                                                                                                                                                                                                                  
-                    if rule_obj.all_caps:                                                                                                                                                                         
-                        cap_txt = 'ALL'                                                                                                                                                                           
-                    else:                                                                             
-                        cap_txt = ' '.join(rule_obj.capability)                                       
-                                                                                                      
-                    q.headers += [_('Capability'), cap_txt]                                           
+                    q.headers += rule_obj.logprof_header()                                            
                                                                                                       
                     severity = rule_obj.severity(sev_db)                                              
                     if severity != '--':                                                              
@@ -375,7 +360,7 @@                                                                                    
                             q.options = options                                                       
                                                                                                       
                             q.headers = [_('Profile'), apparmor.aa.combine_name(profile, hat)]        
-                            q.headers += [_('Capability'), cap_txt]
+                            q.headers += rule_obj.logprof_header()
 
                         elif ans == 'CMD_ALLOW':
                             done = True
@@ -742,29 +727,7 @@
                             q.selected = default_option - 1
 
                         q.headers = [_('Profile'), apparmor.aa.combine_name(profile, hat)]
-
-                        qualifier = ''
-                        if rule_obj.deny:
-                            qualifier = 'deny %s' % qualifier
-
-                        if rule_obj.audit:
-                            qualifier = 'audit %s' % qualifier
-
-                        if qualifier:
-                            q.headers += [_('Qualifier'), qualifier]
-
-                        if rule_obj.all_domains:
-                            family = 'ALL'
-                        else:
-                            family = rule_obj.domain
-
-                        if rule_obj.all_type_or_protocols:
-                            sock_type = 'ALL'
-                        else:
-                            sock_type = rule_obj.type_or_protocol
-
-                        q.headers += [_('Network Family'), family]
-                        q.headers += [_('Socket Type'), sock_type]
+                        q.headers += rule_obj.logprof_header()
 
                         severity = rule_obj.severity(sev_db)
                         if severity != '--':
@@ -796,8 +759,7 @@
                                 q.options = options
 
                                 q.headers = [_('Profile'), apparmor.aa.combine_name(profile, hat)]
-                                q.headers += [_('Network Family'), family]
-                                q.headers += [_('Socket Type'), sock_type]
+                                q.headers += rule_obj.logprof_header()
 
                             elif ans == 'CMD_ALLOW':
                                 done = True
=== modified file utils/apparmor/rule/capability.py
--- utils/apparmor/rule/capability.py   2015-05-24 18:20:13.869200190 +0200
+++ utils/apparmor/rule/capability.py   2015-05-24 22:30:05.976665006 +0200
@@ -141,6 +141,17 @@
 
         return severity
 
+    def logprof_header_localvars(self):
+        if self.all_caps:
+            cap_txt = _('ALL')
+        else:
+            cap_txt = ' '.join(sorted(self.capability))
+
+        return [
+            _('Capability'), cap_txt,
+        ]
+
+
 class CapabilityRuleset(BaseRuleset):
     '''Class to handle and store a collection of capability rules'''
 
=== modified file utils/apparmor/rule/__init__.py
--- utils/apparmor/rule/__init__.py     2015-05-24 17:54:24.654973154 +0200
+++ utils/apparmor/rule/__init__.py     2015-05-24 22:19:52.235670019 +0200
@@ -141,6 +141,34 @@
            sev_db must be an apparmor.severity.Severity object.'''
         return '--'
 
+    def logprof_header(self):
+        '''return the headers (human-readable version of the rule) to display in aa-logprof for this rule object
+           returns {'label1': 'value1', 'label2': 'value2'} '''
+
+        headers = []
+        qualifier = []
+
+        if self.audit:
+            qualifier += ['audit']
+
+        if self.deny:
+            qualifier += ['deny']
+        elif self.allow_keyword:
+            qualifier += ['allow']
+
+        if qualifier:
+            headers += [_('Qualifier'), ' '.join(qualifier)]
+
+        headers += self.logprof_header_localvars()
+
+        return headers
+
+    # @abstractmethod  FIXME - uncomment when python3 only
+    def logprof_header_localvars(self):
+        '''return the headers (human-readable version of the rule) to display in aa-logprof for this rule object
+           returns {'label1': 'value1', 'label2': 'value2'} '''
+        raise AppArmorBug("'%s' needs to implement logprof_header(), but didn't" % (str(self)))
+
     def modifiers_str(self):
         '''return the allow/deny and audit keyword as string, including whitespace'''
 
=== modified file utils/apparmor/rule/network.py
--- utils/apparmor/rule/network.py      2015-04-26 22:03:37.780997000 +0200
+++ utils/apparmor/rule/network.py      2015-05-24 22:20:53.400082789 +0200
@@ -199,6 +199,22 @@
 
         return True
 
+    def logprof_header_localvars(self):
+        if self.all_domains:
+            family = _('ALL')
+        else:
+            family = self.domain
+
+        if self.all_type_or_protocols:
+            sock_type = _('ALL')
+        else:
+            sock_type = self.type_or_protocol
+
+        return [
+            _('Network Family'), family,
+            _('Socket Type'),    sock_type,
+        ]
+
 
 class NetworkRuleset(BaseRuleset):
     '''Class to handle and store a collection of network rules'''
=== modified file utils/test/test-baserule.py
--- utils/test/test-baserule.py 2015-05-24 17:54:24.654973154 +0200
+++ utils/test/test-baserule.py 2015-05-24 22:28:51.423038881 +0200
@@ -56,6 +56,11 @@
         rank = obj.severity(None)
         self.assertEqual(rank, '--')
 
+    def test_logprof_header_localvars(self):
+        obj = BaseRule()
+        with self.assertRaises(AppArmorBug):
+            obj.logprof_header_localvars()
+
 
 setup_all_loops(__name__)
 if __name__ == '__main__':
=== modified file utils/test/test-capability.py
--- utils/test/test-capability.py       2015-05-24 18:20:13.870200131 +0200
+++ utils/test/test-capability.py       2015-05-24 22:21:32.287802119 +0200
@@ -21,6 +21,8 @@
 import apparmor.severity as severity
 from apparmor.common import AppArmorException, AppArmorBug, hasher
 from apparmor.logparser import ReadLog
+from apparmor.translations import init_translation
+_ = init_translation()
 
 # --- tests for single CapabilityRule --- #
 
@@ -434,6 +436,21 @@
         rank = obj.severity(sev_db)
         self.assertEqual(rank, expected)
 
+class CapabilityLogprofHeaderTest(AATest):
+    tests = [
+        ('capability,',                         [                               _('Capability'), _('ALL'),         ]),
+        ('capability chown,',                   [                               _('Capability'), 'chown',          ]),
+        ('capability chown fsetid,',            [                               _('Capability'), 'chown fsetid',   ]),
+        ('audit capability,',                   [_('Qualifier'), 'audit',       _('Capability'), _('ALL'),         ]),
+        ('deny capability chown,',              [_('Qualifier'), 'deny',        _('Capability'), 'chown',          ]),
+        ('allow capability chown fsetid,',      [_('Qualifier'), 'allow',       _('Capability'), 'chown fsetid',   ]),
+        ('audit deny capability,',              [_('Qualifier'), 'audit deny',  _('Capability'), _('ALL'),         ]),
+    ]
+
+    def _run_test(self, params, expected):
+        obj = CapabilityRule._parse(params)
+        self.assertEqual(obj.logprof_header(), expected)
+
 # --- tests for CapabilityRuleset --- #
 
 class CapabilityRulesTest(AATest):
=== modified file utils/test/test-network.py
--- utils/test/test-network.py  2015-04-26 22:03:37.780997000 +0200
+++ utils/test/test-network.py  2015-05-24 22:22:06.140816756 +0200
@@ -21,6 +21,8 @@
 from apparmor.rule import BaseRule
 from apparmor.common import AppArmorException, AppArmorBug
 from apparmor.logparser import ReadLog
+from apparmor.translations import init_translation
+_ = init_translation()
 
 exp = namedtuple('exp', ['audit', 'allow_keyword', 'deny', 'comment',
         'domain', 'all_domains', 'type_or_protocol', 'all_type_or_protocols'])
@@ -336,6 +338,21 @@
         with self.assertRaises(AppArmorBug):
             obj.is_equal(testobj)
 
+class NetworkLogprofHeaderTest(AATest):
+    tests = [
+        ('network,',                    [                               _('Network Family'), _('ALL'),     _('Socket Type'), _('ALL'),     ]),
+        ('network inet,',               [                               _('Network Family'), 'inet',       _('Socket Type'), _('ALL'),     ]),
+        ('network inet stream,',        [                               _('Network Family'), 'inet',       _('Socket Type'), 'stream',     ]),
+        ('deny network,',               [_('Qualifier'), 'deny',        _('Network Family'), _('ALL'),     _('Socket Type'), _('ALL'),     ]),
+        ('allow network inet,',         [_('Qualifier'), 'allow',       _('Network Family'), 'inet',       _('Socket Type'), _('ALL'),     ]),
+        ('audit network inet stream,',  [_('Qualifier'), 'audit',       _('Network Family'), 'inet',       _('Socket Type'), 'stream',     ]),
+        ('audit deny network inet,',    [_('Qualifier'), 'audit deny',  _('Network Family'), 'inet',       _('Socket Type'), _('ALL'),     ]),
+    ]
+
+    def _run_test(self, params, expected):
+        obj = NetworkRule._parse(params)
+        self.assertEqual(obj.logprof_header(), expected)
+
 ## --- tests for NetworkRuleset --- #
 
 class NetworkRulesTest(AATest):



Regards,

Christian Boltz
-- 
> sdfgsdfg
sind denn die Schreibmaschinenkurse an der VHS echt so
überbelegt, daß man die Liste damit behelligen muß?
[> Georg Poetting und Michael Schulz in suse-linux]




More information about the AppArmor mailing list