Hello,

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

Actually (and funnily),
-                if other.aa[profile][hat].get(allow, False):
-                    continue
resulted in never merging capability rules even before the change to
CapabilityRule(set) - this was meant as optimization, but a "not" was
missing in the condition ;-) so it always skipped capability rules.

The patch changes ask_the_question to the CapabilityRule(set) layout.
Besides that,
- include the audit and deny keywords in the "Capability" headline
  (I'd prefer to just use the get_clean() rule, but that's another topic)
- hide "(A)llow" when merging a deny rule
- don't ask for capabilities that are already covered

Also delete match_cap_includes() from aa.py, which is no longer used.


I tested all changes manually.


Note: getting the severity is a candidate to move into the *Rule
classes, but first we have to disentangle how sev_db gets filled (or
just pass the sev_db object as parameter?)

The whole handling of getting and handling the user response is also
a candidate for a function that can be used for more rule types.

Oh, and finally merging (most parts of) aa-logprof and aa-mergeprof
would be nice ;-)



[ 06-mergeprof-capability-rule.diff ]

=== modified file utils/aa-mergeprof
--- utils/aa-mergeprof  2015-01-30 21:07:51.234871116 +0100
+++ utils/aa-mergeprof  2015-05-14 01:54:03.572822464 +0200
@@ -308,32 +308,51 @@
                     return
 
             #Add the capabilities
-            for allow in ['allow', 'deny']:
-                if other.aa[profile][hat].get(allow, False):
-                    continue
-                for capability in 
sorted(other.aa[profile][hat][allow]['capability'].keys()):
-                    severity = sev_db.rank('CAP_%s' % capability)
+            if other.aa[profile][hat].get('capability', False): # (in theory) 
superflous check, but it avoids large whitespace changes ;-)
+                for cap_obj in other.aa[profile][hat]['capability'].rules:
+
+                    if 
self.user.aa[profile][hat]['capability'].is_covered(cap_obj):
+                        continue
+
+                    if cap_obj.all_caps:
+                        severity = 10
+                        cap_txt = 'ALL'
+                    else:
+                        cap_txt = ' '.join(cap_obj.capability)
+                        severity = 0
+                        for cap in cap_obj.capability:
+                            severity = max(severity, sev_db.rank('CAP_%s' % 
cap))
+
+                    if cap_obj.deny:
+                        cap_txt = 'deny %s' % cap_txt
+
+                    if cap_obj.audit:
+                        cap_txt = 'audit %s' % cap_txt
+
                     default_option = 1
                     options = []
-                    newincludes = 
apparmor.aa.match_cap_includes(self.user.aa[profile][hat], capability)
+                    newincludes = 
apparmor.aa.match_includes(self.user.aa[profile][hat], 'capability', cap_obj)
                     q = aaui.PromptQuestion()
                     if newincludes:
                         options += list(map(lambda inc: '#include <%s>' %inc, 
sorted(set(newincludes))))
 
                     if options:
-                        options.append('capability %s' % capability)
+                        options.append(cap_obj.get_clean())
                         q.options = options
                         q.selected = default_option - 1
 
                     q.headers = [_('Profile'), 
apparmor.aa.combine_name(profile, hat)]
-                    q.headers += [_('Capability'), capability]
+                    q.headers += [_('Capability'), cap_txt]
                     q.headers += [_('Severity'), severity]
 
                     audit_toggle = 0
 
-                    q.functions = ['CMD_ALLOW', 'CMD_DENY', 
'CMD_IGNORE_ENTRY', 'CMD_ABORT', 'CMD_FINISHED']
+                    q.functions = []
+                    if not cap_obj.deny:
+                        q.functions += ['CMD_ALLOW']
+                    q.functions += ['CMD_DENY', 'CMD_IGNORE_ENTRY', 
'CMD_ABORT', 'CMD_FINISHED']
 
-                    q.default = 'CMD_ALLOW'
+                    q.default = q.functions[0]
 
                     done = False
                     while not done:
@@ -361,19 +380,20 @@
                                 if deleted:
                                     aaui.UI_Info(_('Deleted %s previous 
matching profile entries.') % deleted)
 
-                            
self.user.aa[profile][hat]['allow']['capability'][capability]['set'] = True
-                            
self.user.aa[profile][hat]['allow']['capability'][capability]['audit'] = 
other.aa[profile][hat]['allow']['capability'][capability]['audit']
+                            
self.user.aa[profile][hat]['capability'].add(cap_obj)
 
                             apparmor.aa.changed[profile] = True
 
-                            aaui.UI_Info(_('Adding capability %s to 
profile.'), capability)
+                            aaui.UI_Info(_('Adding %s to profile.') % 
cap_obj.get_clean())
                             done = True
 
                         elif ans == 'CMD_DENY':
-                            
self.user.aa[profile][hat]['deny']['capability'][capability]['set'] = True
+                            cap_obj.deny = True
+                            cap_obj.raw_rule = None  # reset raw rule after 
manually modifying cap_obj
+                            
self.user.aa[profile][hat]['capability'].add(cap_obj)
                             apparmor.aa.changed[profile] = True
 
-                            aaui.UI_Info(_('Denying capability %s to 
profile.') % capability)
+                            aaui.UI_Info(_('Adding %s to profile.') % 
cap_obj.get_clean())
                             done = True
                         else:
                             done = False
=== modified file utils/apparmor/aa.py
--- utils/apparmor/aa.py        2015-05-13 23:15:05.146827969 +0200
+++ utils/apparmor/aa.py        2015-05-14 01:51:45.582085900 +0200
@@ -2154,11 +2154,6 @@
     return match_includes(incname, 'network', network_obj)
 
 
-def match_cap_includes(profile, capability):
-    # still used by aa-mergeprof
-    capability_obj = CapabilityRule(capability)
-    return match_includes(profile, 'capability', capability_obj)
-
 def match_includes(profile, rule_type, rule_obj):
     newincludes = []
     for incname in include.keys():


Regards,

Christian Boltz
-- 
> Rechte Maustaste auf den Mülleimer -> Mülleimer lehren
Also, wenn Du dem Muelleimer 'was lehren kannst, bist Du echt gut. Ich
hoffe, Du hast aber auch eine Lehrerausbildung, sonst kann das in die
Hose gehn... :-)   [> Manfred Tremmel und Thomas Hertweck in suse-linux]


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor

Reply via email to