Hello,

Am Montag, 25. Mai 2015 schrieb Christian Boltz:
> [ 27-logprof-use-mergeprof-code-for-capability.diff ]

I should run "make check" more often :-/

I overlooked a "self.aa." (and didn't run into it in my manual tests), 
so here's v2 with this fixed.



This patch replaces the code in aa.py ask_the_questions() that handles 
capabilities with the ask_the_questions() code from aa-mergeprof.

This means to convert the capability log events to a CapabilityRuleset
stored in the (new) log_obj hasher, and then let the code from
aa-mergeprof operate on this hasher.

Most of the code after the "aa-mergeprof also has this code" comment is
a direct copy of the aa-mergeprof code, with the following changes:
- filter for profile mode (enforce/complain)
- set default button (allow or deny) based on profile mode
- keep seen_events counter happy (even if it isn't displayed anywhere)
- replace apparmor.aa.foo with just foo

The user interface is mostly unchanged, with two exceptions:
- options always displayed, even if there is only one option
- some slightly changed texts


BTW: I'm not sure if filtering and having different default buttons
based on the profile mode makes sense, except for "historical reasons".
Opinions?



[ 27-logprof-use-mergeprof-code-for-capability.diff ]

=== modified file utils/apparmor/aa.py
--- utils/apparmor/aa.py        2015-05-25 11:46:12.709387529 +0200
+++ utils/apparmor/aa.py        2015-05-25 11:46:08.085653465 +0200
@@ -1541,6 +1541,7 @@
 def ask_the_questions():
     found = 0
     global seen_events
+    log_obj = hasher()
     for aamode in sorted(log_dict.keys()):
         # Describe the type of changes
         if aamode == 'PERMITTING':
@@ -1564,106 +1565,107 @@
                 hats = [profile] + hats
 
             for hat in hats:
+                if not log_obj[profile][hat].get('capability', False):
+                    log_obj[profile][hat]['capability'] = CapabilityRuleset()
+
                 for capability in 
sorted(log_dict[aamode][profile][hat]['capability'].keys()):
-                    # skip if capability already in profile
-                    capability_obj = CapabilityRule(capability)
-                    if is_known_rule(aa[profile][hat], 'capability', 
capability_obj):
-                        continue
-                    # Load variables into sev_db? Not needed/used for 
capabilities.
-                    severity = capability_obj.severity(sev_db)
-                    default_option = 1
-                    options = []
-                    newincludes = match_includes(aa[profile][hat], 
'capability', capability_obj)
-                    q = aaui.PromptQuestion()
+                    capability_obj = CapabilityRule(capability, 
log_event=aamode)
+                    log_obj[profile][hat]['capability'].add(capability_obj)
 
-                    if newincludes:
-                        options += list(map(lambda inc: '#include <%s>' % inc, 
sorted(set(newincludes))))
+                for ruletype in ['capability']:
+                    # XXX aa-mergeprof also has this code - if you change it, 
keep aa-mergeprof in sync!
+                    for rule_obj in log_obj[profile][hat][ruletype].rules:
+
+                        if rule_obj.log_event != aamode:  # XXX does it really 
make sense to handle enforce and complain mode changes in different rounds?
+                            continue
+
+                        if is_known_rule(aa[profile][hat], ruletype, rule_obj):
+                            continue
+
+                        default_option = 1
+                        options = []
+                        newincludes = match_includes(aa[profile][hat], 
ruletype, rule_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(rule_obj.get_clean())
                         q.options = options
                         q.selected = default_option - 1
 
-                    q.headers = [_('Profile'), combine_name(profile, hat)]
-                    q.headers += [_('Capability'), capability]
-                    q.headers += [_('Severity'), severity]
-
-                    audit_toggle = 0
-                    audit = ''
-
-                    q.functions = ['CMD_ALLOW', 'CMD_DENY', 
'CMD_IGNORE_ENTRY', 'CMD_AUDIT_NEW',
-                                      'CMD_ABORT', 'CMD_FINISHED']
-
-                    # In complain mode: events default to allow
-                    # In enforce mode: events default to deny
-                    q.default = 'CMD_DENY'
-                    if aamode == 'PERMITTING':
-                        q.default = 'CMD_ALLOW'
-
-                    seen_events += 1
-
-                    done = False
-                    while not done:
-                        ans, selected = q.promptUser()
-
-                        if ans == 'CMD_FINISHED':
-                            save_profiles()
-                            return
-
-                        # Ignore the log entry
-                        if ans == 'CMD_IGNORE_ENTRY':
-                            done = True
-                            break
-
-                        if ans.startswith('CMD_AUDIT'):
-                            audit_toggle = not audit_toggle
-                            if audit_toggle:
-                                audit = 'audit '
-                                audit_cmd = 'CMD_AUDIT_OFF'
-                            else:
-                                audit = ''
-                                audit_cmd = 'CMD_AUDIT_NEW'
+                        seen_events += 1
 
-                            q.functions = ['CMD_ALLOW', 'CMD_DENY', 
'CMD_IGNORE_ENTRY', audit_cmd,
-                                              'CMD_ABORT', 'CMD_FINISHED', ]
+                        done = False
+                        while not done:
+                            q.headers = [_('Profile'), combine_name(profile, 
hat)]
+                            q.headers += rule_obj.logprof_header()
+
+                            # Load variables into sev_db? Not needed/used for 
capabilities.
+                            severity = rule_obj.severity(sev_db)
+                            if severity != '--':
+                                q.headers += [_('Severity'), severity]
+
+                            q.functions = available_buttons(rule_obj)
+
+                            # In complain mode: events default to allow
+                            # In enforce mode: events default to deny
+                            # XXX does this behaviour really make sense, 
except for "historical reasons"[tm]?
+                            q.default = 'CMD_DENY'
+                            if rule_obj.log_event == 'PERMITTING':
+                                q.default = 'CMD_ALLOW'
+
+                            ans, selected = q.promptUser()
+                            if ans == 'CMD_IGNORE_ENTRY':
+                                done = True
+                                break
+
+                            elif ans == 'CMD_FINISHED':
+                                return
+
+                            elif ans.startswith('CMD_AUDIT'):
+                                if ans == 'CMD_AUDIT_NEW':
+                                    rule_obj.audit = True
+                                    rule_obj.raw_rule = None
+                                else:
+                                    rule_obj.audit = False
+                                    rule_obj.raw_rule = None
+
+                                options[len(options) - 1] = 
rule_obj.get_clean()
+                                q.options = options
+
+                            elif ans == 'CMD_ALLOW':
+                                done = True
+                                changed[profile] = True
 
-                            q.headers = [_('Profile'), combine_name(profile, 
hat),
-                                            _('Capability'), audit + 
capability,
-                                            _('Severity'), severity]
-
-                        if ans == 'CMD_ALLOW':
-                            selection = ''
-                            if options:
                                 selection = options[selected]
-                            match = re_match_include(selection)
-                            if match:
-                                deleted = False
-                                inc = match  # .groups()[0]
-                                deleted = delete_duplicates(aa[profile][hat], 
inc)
-                                aa[profile][hat]['include'][inc] = True
-
-                                aaui.UI_Info(_('Adding %s to profile.') % 
selection)
-                                if deleted:
-                                    aaui.UI_Info(_('Deleted %s previous 
matching profile entries.') % deleted)
+
+                                inc = re_match_include(selection)
+                                if inc:
+                                    deleted = 
delete_duplicates(aa[profile][hat], inc)
+
+                                    aa[profile][hat]['include'][inc] = True
+
+                                    aaui.UI_Info(_('Adding %s to profile.') % 
selection)
+                                    if deleted:
+                                        aaui.UI_Info(_('Deleted %s previous 
matching profile entries.') % deleted)
+
+                                else:
+                                    aa[profile][hat][ruletype].add(rule_obj)
+
+                                    aaui.UI_Info(_('Adding %s to profile.') % 
rule_obj.get_clean())
+
+                            elif ans == 'CMD_DENY':
+                                done = True
+                                changed[profile] = True
+
+                                rule_obj.deny = True
+                                rule_obj.raw_rule = None  # reset raw rule 
after manually modifying rule_obj
+                                aa[profile][hat][ruletype].add(rule_obj)
+                                aaui.UI_Info(_('Adding %s to profile.') % 
rule_obj.get_clean())
 
                             else:
-                                capability_obj = CapabilityRule(capability, 
audit=audit)
-                                
aa[profile][hat]['capability'].add(capability_obj)
-                                aaui.UI_Info(_('Adding capability %s to 
profile.') % capability)
-
-                            changed[profile] = True
-
-                            done = True
-
-                        elif ans == 'CMD_DENY':
-                            capability_obj = CapabilityRule(capability, 
audit=audit, deny=True)
-                            aa[profile][hat]['capability'].add(capability_obj)
-                            changed[profile] = True
-
-                            aaui.UI_Info(_('Denying capability %s to 
profile.') % capability)
-                            done = True
-                        else:
-                            done = False
+                                done = False
+                    # END of code (mostly) shared with aa-mergeprof
 
                 # Process all the path entries.
                 for path in 
sorted(log_dict[aamode][profile][hat]['path'].keys()):




Regards,

Christian Boltz
-- 
When that limitation is removed, there might be a tendency that
for 12.2 the live image is 800MB, the next 1GB, next one 1.5GB.
If not careful we end up with a live-blu-ray, live-data-centre
or a live-cloud ;-))  [Hans Witvliet in opensuse-factory]


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

Reply via email to