[apparmor] [patch] Update aa-mergeprof to use the NetworkRule(set) class layout

Christian Boltz apparmor at cboltz.de
Sun May 24 22:53:50 UTC 2015


Hello,

Am Sonntag, 17. Mai 2015 schrieb Christian Boltz:
> [ 08-mergeprof-network-rule.diff ]

While thinking about patch 26, I noticed that aa-mergeprof isn't a good
home for available_buttons(). Here's the updated patch that adds the
function to aa.py instead.

Besides moving the function (and adding an import to aa-mergeprof),
nothing was changed in the patch.



Update aa-mergeprof to use the NetworkRule(set) class layout

aa-mergeprof still used the old aa[profile][hat][allow]['netdomain']
which no longer gets populated. This resulted in not asking for merging
any network rules.

This patch changes ask_the_question() to the NetworkRule(set) layout.
Besides that,
- don't ask for network rules that are already covered.
  Using is_known_rule() also fixes
  https://bugs.launchpad.net/apparmor/+bug/1382241
- include the audit keyword in the "Network Family" headline
  (I'd prefer to just use the get_clean() rule, but that's another topic)
- hide "(A)llow" when merging a deny rule
- as a side effect of using NetworkRule, fix crashes for 'network,' and
  'network foo,' rules

To avoid having to repeat the list of available "buttons" and the logic
to update that list, add a available_buttons() function that returns the
list of available buttons depending on rule_obj.deny and rule_obj.audit
to aa.py, and import it into mergeprof.

I tested all changes manually.



[ 08-mergeprof-network-rule.diff ]

=== modified file utils/apparmor/aa.py
--- utils/apparmor/aa.py        2015-05-24 18:51:09.099789958 +0200
+++ utils/apparmor/aa.py        2015-05-25 00:41:35.163857383 +0200
@@ -2053,6 +2053,23 @@
                             else:
                                 done = False
 
+def available_buttons(rule_obj):
+    buttons = []
+
+    if not rule_obj.deny:
+        buttons += ['CMD_ALLOW']
+
+    buttons += ['CMD_DENY', 'CMD_IGNORE_ENTRY']
+
+    if rule_obj.audit:
+        buttons += ['CMD_AUDIT_OFF']
+    else:
+        buttons += ['CMD_AUDIT_NEW']
+
+    buttons += ['CMD_ABORT', 'CMD_FINISHED']
+
+    return buttons
+
 def add_to_options(options, newpath):
     if newpath not in options:
         options.append(newpath)=== modified file utils/aa-mergeprof
--- utils/aa-mergeprof  2015-05-17 18:54:52.750566063 +0200
+++ utils/aa-mergeprof  2015-05-17 19:07:35.296852571 +0200
@@ -17,6 +17,7 @@
 import os
 
 import apparmor.aa
+from apparmor.aa import available_buttons
 import apparmor.aamode
 from apparmor.common import AppArmorException
 import apparmor.severity
@@ -714,37 +715,45 @@
                             elif re.search('\d', ans):
                                 default_option = ans
 
-            #
-            for allow in ['allow', 'deny']:
-                for family in sorted(other.aa[profile][hat][allow]['netdomain']['rule'].keys()):
-                    # severity handling for net toggles goes here
+            if 1 == 1: # avoid whitespace change
+                if other.aa[profile][hat].get('network', False): # needed until we have proper profile initialization
+                    for net_obj in other.aa[profile][hat]['network'].rules:
+                        # severity handling for net toggles goes here
+
+                        if apparmor.aa.is_known_rule(self.user.aa[profile][hat], 'network', net_obj):
+                            continue
 
-                    for sock_type in sorted(other.aa[profile][hat][allow]['netdomain']['rule'][family].keys()):
-                        #if apparmor.aa.profile_known_network(self.user.aa[profile][hat], family, sock_type):
-                        #    continue
-                        # disabled for now because it crashes, for details and impact see
-                        # https://bugs.launchpad.net/apparmor/+bug/1382241
+                        if net_obj.all_domains:
+                            family = 'ALL'
+                        else:
+                            family = net_obj.domain
+
+                        if net_obj.all_type_or_protocols:
+                            sock_type = 'ALL'
+                        else:
+                            sock_type = net_obj.type_or_protocol
 
                         default_option = 1
                         options = []
-                        newincludes = apparmor.aa.match_net_includes(self.user.aa[profile][hat], family, sock_type)
+                        newincludes = apparmor.aa.match_includes(self.user.aa[profile][hat], 'network', net_obj)
                         q = aaui.PromptQuestion()
                         if newincludes:
                             options += list(map(lambda s: '#include <%s>'%s, sorted(set(newincludes))))
                         if True:#options:
-                            options.append('network %s %s' % (family, sock_type))
+                            options.append(net_obj.get_clean())
                             q.options = options
                             q.selected = default_option - 1
 
+                        audit = ''
+                        if net_obj.audit:
+                            audit = 'audit '
+
                         q.headers = [_('Profile'), apparmor.aa.combine_name(profile, hat)]
-                        q.headers += [_('Network Family'), family]
+                        q.headers += [_('Network Family'), audit + family]
                         q.headers += [_('Socket Type'), sock_type]
 
-                        audit_toggle = 0
-                        q.functions = ['CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_AUDIT_NEW',
-                                          'CMD_ABORT', 'CMD_FINISHED']
-
-                        q.default = 'CMD_ALLOW'
+                        q.functions = available_buttons(net_obj)
+                        q.default = q.functions[0]
 
                         done = False
                         while not done:
@@ -757,15 +766,19 @@
                                 return
 
                             if ans.startswith('CMD_AUDIT'):
-                                audit_toggle = not audit_toggle
-                                audit = ''
-                                if audit_toggle:
-                                    audit = 'audit'
-                                    q.functions = ['CMD_ALLOW', 'CMD_DENY', 'CMD_AUDIT_OFF',
-                                                      'CMD_ABORT', 'CMD_FINISHED']
+                                if ans == 'CMD_AUDIT_NEW':
+                                    net_obj.audit = True
+                                    net_obj.raw_rule = None
+                                    audit = 'audit '
                                 else:
-                                    q.functions = ['CMD_ALLOW', 'CMD_DENY', 'CMD_AUDIT_NEW',
-                                                      'CMD_ABORT', 'CMD_FINISHED']
+                                    net_obj.audit = False
+                                    net_obj.raw_rule = None
+                                    audit = ''
+
+                                q.functions = available_buttons(net_obj)
+                                options[len(options) - 1] = net_obj.get_clean()
+                                q.options = options
+
                                 q.headers = [_('Profile'), apparmor.aa.combine_name(profile, hat)]
                                 q.headers += [_('Network Family'), audit + family]
                                 q.headers += [_('Socket Type'), sock_type]
@@ -788,8 +801,7 @@
                                         aaui.UI_Info(_('Deleted %s previous matching profile entries.') % deleted)
 
                                 else:
-                                    self.user.aa[profile][hat]['allow']['netdomain']['audit'][family][sock_type] = audit_toggle
-                                    self.user.aa[profile][hat]['allow']['netdomain']['rule'][family][sock_type] = True
+                                    self.user.aa[profile][hat]['network'].add(net_obj)
 
                                     apparmor.aa.changed[profile] = True
 
@@ -797,7 +809,9 @@
 
                             elif ans == 'CMD_DENY':
                                 done = True
-                                self.user.aa[profile][hat]['deny']['netdomain']['rule'][family][sock_type] = True
+                                net_obj.deny = True
+                                net_obj.raw_rule = None
+                                self.user.aa[profile][hat]['network'].add(net_obj)
                                 apparmor.aa.changed[profile] = True
                                 aaui.UI_Info(_('Denying network access %(family)s %(type)s to profile') % { 'family': family, 'type': sock_type })
 





Regards,

Christian Boltz
-- 
> Status?
NEW
[Ihno Krumreich and Stephan Kulow on
 https://bugzilla.novell.com/show_bug.cgi?id=159223]




More information about the AppArmor mailing list